Repository navigation
fix(dashboard): poll status before asking for a key - #381
Merged
MagicalTux merged 2 commits intoSep 15, 2026
Merged
Conversation
The page showed the key prompt whenever localStorage held no key, before it ever asked the server. A loopback browser is key-exempt, so the operator on the proxy's own machine was prompted for a key the server would not have checked. Poll /teamclaude/status on load and show the prompt only when the server refuses the request: a 401, or a 403 from the key-less loopback gate (a Host that does not name this machine). A first poll that fails for any other reason now shows its error instead of a blank page, since the error banner sits inside the still-hidden app. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rikbrown
added a commit
to rikbrown/teamclaude
that referenced
this pull request
Sep 15, 2026
Rebases the fork onto upstream master 1779db6 (1.1.20 plus KarpelesLab#374-KarpelesLab#403). No new fork feature of its own: this ships upstream's 13 commits and the reshaping the rebase required. Upstream brings a version label in the dashboard header, provider names on the account rows of a mixed pool, Codex quota fixes across the 5h and weekly windows, spreading for requests that carry no session id, and outcome accounting on the same classification path every routing decision already read. Two fork commits dissolved into upstream, both merged there today: the dashboard key prompt (KarpelesLab#381), and the expiring Codex header fixture, which upstream fixed independently as KarpelesLab#402. The locally-served account ordering went up as KarpelesLab#376, so only its fork-only documentation remains here; and the header commit keeps the branding alone, now that upstream resolves and draws the version itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
rikbrown
added a commit
to rikbrown/teamclaude
that referenced
this pull request
Sep 19, 2026
Rebases the fork onto upstream master 1779db6 (1.1.20 plus KarpelesLab#374-KarpelesLab#403). No new fork feature of its own: this ships upstream's 13 commits and the reshaping the rebase required. Upstream brings a version label in the dashboard header, provider names on the account rows of a mixed pool, Codex quota fixes across the 5h and weekly windows, spreading for requests that carry no session id, and outcome accounting on the same classification path every routing decision already read. Two fork commits dissolved into upstream, both merged there today: the dashboard key prompt (KarpelesLab#381), and the expiring Codex header fixture, which upstream fixed independently as KarpelesLab#402. The locally-served account ordering went up as KarpelesLab#376, so only its fork-only documentation remains here; and the header commit keeps the branding alone, now that upstream resolves and draws the version itself. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
MagicalTux
added a commit
that referenced
this pull request
Sep 20, 2026
Thirty-six commits since 1.1.20. Several change what a client sees on a failure, so read the first section before upgrading a shared deployment. Behaviour changes #439 a 401 from upstream is no longer relayed to the client: the request fails over like a 403, and an API-key account or an OAuth account with no refresh token leaves rotation (it used to be picked again on every request). With nothing left the client gets the proxy's own error #439 a path under /teamclaude/ that no control route claims — a typo, or the wrong verb — answers 404 locally instead of being forwarded upstream under a fleet credential #429 the synthetic 429's retry-after is the real reset of the windows blocking the request's candidate accounts, not a flat 60s, and the message counts only those candidates; #408 names accounts that need a re-login instead of calling them "at quota" #438 session pins are per conversation (session id plus a digest of the first message), so a session's subagents spread across accounts. `sessions.items[].id` in status is the composite key, load is counted per conversation, and a persisted concurrency cap re-learns #378 a `thread: continue` bound for a per-account third-party upstream is refused with the 400 Anthropic gives, so the client resends the whole conversation; `messageThreads: true` opts a relay out #434 a 429 whose x-codex-* headers show a spent account-wide window holds the account like an Anthropic rejection; a spent model-scoped bucket only moves the request #437 a Codex response head is awaited for five minutes (Anthropic unchanged) #411 idle keep-alive connections are held 120s on both listeners #389 with session distribution on, requests carrying no session id rotate on a cursor of their own instead of all resting on the current account #405 `defaultClientMode` ("mitm" | "base-url") sets what `run` and `env` do without a flag; `--mitm` / `--no-mitm` decide per launch, and in base-URL mode `env` unsets a stale proxy export naming this proxy #439 route `--bucket` is validated; an array `switchThreshold` reads as the default with one line saying so Features #419 an MCP management endpoint at POST /teamclaude/mcp, off unless `proxy.mcp` is "read" or "full"; a named client key is read-only even in full mode, and with no proxy key it serves only this machine #428 per-account `switchThreshold`, a number or a per-bucket table #406 a Claude+Codex pool is drawn as two panes on a wide terminal, each with its own current marker; #392 names the provider in a mixed list; #418 lets the operator arrange the list (`displayOrder`); #376 draws loopback-served accounts last; #435 shows the percentage beside a bar's countdown; #394 shows the running version in the header #430 free Codex rate-limit reset credits in status, the TUI and the dashboard #385 `proxy.terminalOnly` tunnels chatgpt.com so ChatGPT Desktop stays out Fixes #404 a TUI paint can no longer block the proxy (stdout non-blocking, frames dropped while the terminal is behind); #410 a dead terminal no longer takes the proxy with it, and SIGHUP shuts down cleanly #433 token usage is booked from Codex Responses streams #386 #387 #388 the Codex five-hour window is read from the model-scoped family and the usage probe, and extra limits are named from their entries #431 a headerless 429 that follows the request is retried once #432 #439 startup and collaborator log lines reach the TUI's activity pane and log file instead of the covered terminal #415 #403 #439 reload mirrors `priority`, `disabled`, `stripRequestFields` onto the config entry, and a reload during a removal does not re-add it #439 the Host check uses the address actually bound; sx.org calls time out #381 the dashboard polls status before asking for a key #403 session outcome accounting classifies the decoded path; account names in daemon log lines are sanitised Tooling #371 #372 #373 `npm run typecheck` (tsc over the JS sources) in CI, with a strict-mode ratchet: per-file strict diagnostics may not grow past the pre-merge commit (2006 at introduction, 1735 now) #401 docker workflow actions bumped Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
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.
Opening
teamclaude dashboardon the proxy's own machine shows "Enter your proxy key to view status." The page decides this on load from localStorage alone (if (localStorage.getItem(KEY)) start(); else showKeybox();), before it has asked the server anything. But a loopback browser is key-exempt, so the operator is prompted for a key the server would not check.docs/usage.mdalready says "Loopback browsers are key-exempt as everywhere else", and the page does not act that way.This change:
/teamclaude/statuson load and shows the prompt only when the server refuses the request. A remote browser still gets the prompt after its first poll, as before;tui-remote.jsalready reads 401/403 as "needs a key";#app, which stays hidden until a status lands, so an unreachable server or a 500 used to leave a blank page.Tests run the page's full inline script against a stub DOM, localStorage and fetch. They check that the page polls before any prompt, that a 401 or 403 brings the prompt up and drops the stored key, and that a failed first poll shows its error. The 401 case already passed before this change; the other three fail without it. Docs: the key paragraph under "Status dashboard (browser)" in
docs/usage.md.🤖 Generated with Claude Code