Skip to content

feat(cli): add built-in web dashboard to codexbar serve - #2715

Merged
steipete merged 1 commit into
mainfrom
steipete/web-dashboard-sidebar-477a03
Aug 6, 2026
Merged

feat(cli): add built-in web dashboard to codexbar serve#2715
steipete merged 1 commit into
mainfrom
steipete/web-dashboard-sidebar-477a03

Conversation

@steipete

@steipete steipete commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

codexbar serve now ships a built-in web dashboard: GET / returns a single self-contained HTML page (inline CSS/JS, zero external requests) that polls the existing /dashboard/v1/snapshot route and renders provider cards — usage windows as progress bars with reset countdowns, credits, today/30-day cost, status dots, per-provider accent colors, light/dark via prefers-color-scheme.

Auth model is unchanged and matches the documented threat model:

  • The static page is always unauthenticated, including off-loopback (like /health, it carries no account data).
  • Data still flows only through the token-gated snapshot route. On a 401 the page shows an inline token prompt; the token lives in localStorage (codexbar.dashboardToken) and is sent as a bearer header, never in the URL.
  • All payload-derived strings enter the DOM via textContent; the snapshot's identity redaction is preserved as-is.

Design note: polling is intentionally not gated on document.hidden — embedded panes and sidebars often report hidden permanently (verified during development), and browsers already throttle background-tab timers.

Docs (docs/dashboard-api.md, docs/cli.md), serve help text, and the changelog are updated.

Commands run

  • swift build
  • swift test --filter CLIServe — 92 tests, 4 suites, all passing
  • make test — full sharded suite
  • make check — 0 violations
  • End-to-end in a browser against a live serve on a tokened bind: initial 401 → token prompt → cards render with real provider data; 504 error state and retry verified.

Screenshots

Omitted deliberately: the dashboard renders live personal account and spend data, and a sanitized capture was not available at land time. To see it: codexbar serve then open http://127.0.0.1:8080/.

GET / now serves a self-contained HTML page that polls
/dashboard/v1/snapshot and renders provider cards with usage windows,
credits, and cost. The static UI stays unauthenticated (it carries no
account data); tokens are entered in-browser, kept in localStorage, and
sent as a bearer header. No visibility gating on polling so embedded
panes that report document.hidden permanently still refresh.
@steipete
steipete merged commit e795d34 into main Aug 6, 2026
1 check passed
@steipete
steipete deleted the steipete/web-dashboard-sidebar-477a03 branch August 6, 2026 18:38

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ddf754f66

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +649 to +651
const windows = node("div", "windows");
for (const window of provider.windows || []) windows.append(renderWindow(window));
card.append(windows);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Render dashboard account rows

When the snapshot includes multi-account data (providers[].accounts, e.g. claude-swap), this renderer only walks provider.windows and then returns the provider card without ever visiting provider.accounts or accountsError. In that context the new web dashboard hides every account's windows/errors/active state even though the dashboard API supplies them, so Claude multi-account users see an incomplete dashboard.

Useful? React with 👍 / 👎.

x0mh0x added a commit to x0mh0x/CodexBar that referenced this pull request Aug 6, 2026
steipete added a commit that referenced this pull request Aug 7, 2026
The serve dashboard PRs (#2715-#2723) merged during the GitHub Actions
outage without CI lint validation. Mechanical, behavior-preserving fixes:

- CLIServeProviderIcons.swift: generator now emits scoped
  swiftlint:disable/enable line_length around the base64 data (icon
  payload is byte-identical after regeneration)
- CLIServeWebUI.swift: moved the html template constant to
  CLIServeWebUI+HTML.swift (enum body 1093 -> under 800 lines); the
  string literal content is verbatim-identical
- Data->String conversions switched to failable String(bytes:encoding:)
  with fallbacks, matching repo convention
- Long @option help strings wrapped via adjacent + concatenation
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.

1 participant