Skip to content

feat: zero-API-key panel degradation (#58, #56)#101

Merged
alohays merged 3 commits intomainfrom
feat/zero-key-experience
Mar 19, 2026
Merged

feat: zero-API-key panel degradation (#58, #56)#101
alohays merged 3 commits intomainfrom
feat/zero-key-experience

Conversation

@alohays
Copy link
Owner

@alohays alohays commented Mar 19, 2026

Summary

  • Add renderDegraded()/clearDegraded() primitives to PanelBase for graceful panel degradation with styled messages and actionable CLI hints
  • Wire degraded payload detection into AIBriefPanel so it shows a configure message when AI generation fails, and add missing skeleton lifecycle to EntityTrackerPanel
  • Add App-level 15s initial-load timeout that degrades all panels with no data, plus CSS for .panel-degraded and .panel-configure-hint states
  • Real data always wins: markDataReceived() automatically clears any degraded state

Test plan

  • renderDegraded() creates .panel-degraded element in container
  • clearDegraded() removes the degraded element
  • markDataReceived() calls clearDegraded() (data arrival clears degradation)
  • Calling renderDegraded() then sending data restores normal panel state
  • Backtick commands in degraded messages get .panel-configure-hint styling
  • npx tsc --noEmit passes with zero errors
  • npx vitest run passes all 752 tests (39 test files, 7 new)

Closes #58, closes #56

🤖 Generated with Claude Code

alohays and others added 3 commits March 20, 2026 03:05
Add renderDegraded()/clearDegraded() primitives to PanelBase so panels
can show styled configuration hints when data sources are unavailable.
Wire degraded payloads into AIBriefPanel, add skeleton lifecycle to
EntityTrackerPanel, and introduce an App-level 15s initial-load timeout
that degrades all panels with no data. Real data always wins --
markDataReceived() clears any degraded state automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- PanelBase.renderDegraded: sanitize innerHTML via DOMPurify to prevent XSS
- ServiceStatusPanel: add markDataReceived() in renderStatus(), cleanupTimers() in destroy()
- AIBriefPanel: set hasReceivedData on degraded path to prevent timeout overwrite
- App: remove hasAnyDataReceived() guard so degradeUnreceivedPanels runs unconditionally

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
updateAll() pushes source items to all panels including AIBriefPanel.
Without a shape check, the panel called markDataReceived() on source
item arrays, preventing the 15s degradation timeout from firing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@alohays alohays force-pushed the feat/zero-key-experience branch from 7e663ac to 381d33d Compare March 19, 2026 18:13
@alohays alohays merged commit 9058a70 into main Mar 19, 2026
1 check passed
@alohays alohays deleted the feat/zero-key-experience branch March 19, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: ensure all non-AI panels work without API keys feat: graceful AI degradation when no API keys configured

1 participant