feat(server): browser status dashboard at /teamclaude/dashboard - #188
Open
Frozen666 wants to merge 2 commits into
Open
feat(server): browser status dashboard at /teamclaude/dashboard#188Frozen666 wants to merge 2 commits into
Frozen666 wants to merge 2 commits into
Conversation
A self-contained HTML page rendering the same data as `teamclaude status`: per-account quota bars (session/weekly + Sonnet/Fable buckets), rotation state, active sessions, auto-refreshing. The asset is served without the key on purpose — it contains no data; its script fetches the gated /teamclaude/status with the proxy key (asked once, kept in localStorage, re-prompted on 401). No external scripts/styles/fonts; all rendering via textContent. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L7DVJAvCRWgtw1TvNgsq4b
Quota resets and account lastUsed arrive as epoch milliseconds, which
Date.parse() cannot read — the reset countdown silently never rendered.
Parse both shapes (ms numbers and ISO strings), and show the wall-clock
reset time next to the countdown: "93% · 2.1h · 17:30" ("Wed 09:00"
beyond 24h).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L7DVJAvCRWgtw1TvNgsq4b
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
The existing read surfaces — the TUI,
teamclaude status,teamclaude attach— all require shell access to the machine running the proxy. For a proxy shared by several key holders, a URL anyone with a key can open is the friendlier way to check quota and rotation state.What this adds
GET /teamclaude/dashboard— one self-contained HTML page rendering whatteamclaude statusshows: per-account cards with quota bars (session 5h / weekly 7d, plus Sonnet/Fable buckets when present, with countdown and absolute reset time), status badges, current-account marker, usage totals, active-session counts. Auto-refreshes every 5s.If the status payload carries a
clientssection (#186), a per-client usage table renders too — without it the section simply stays hidden, so this PR is independent of #186.Design notes
/teamclaude/status, which stays gated and is fetched by the page's script with the key (asked once, kept in localStorage, re-prompted on 401). A browser address bar cannot sendx-api-key, so gating the asset would 401 every remote browser without protecting anything. The route is exact-path GET only; a POST to the same path flows down the normal pipeline (covered by test).textContent, so account/client names never reach innerHTML.Tests
test/dashboard.test.js: the page is self-contained (no external src/href/@import) and fetches the gated status endpoint; GET serves HTML without a key while a POST to the same path is proxied normally. Full suite passes, lint clean.🤖 Generated with Claude Code