Skip to content

Session status card: show the usage limits acpmux reports instead of Not reported - #27762

Merged
cmux-bot[bot] merged 12 commits into
feat-cmux-nextfrom
lane/fix-onboarding-b-usage-limits
Oct 31, 2026
Merged

cmux-bot[bot] merged 12 commits into
feat-cmux-nextfrom
lane/fix-onboarding-b-usage-limits

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Oct 30, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes an internal report: "First display structured provider-reported window/reset information ... Unknown reset time ... no guessed countdown ... shows the timestamp/time zone clearly".

Problem

acpmux sends a Claude Code chat's plan usage limits as an object in the session detail (claude_stdio/usage_limits.rs, hub/views.rs sets usageLimits, from #24293): { windows: [{ id: "session" | "weekly" | "weekly_opus" | "weekly_sonnet", usedPercent: 0-100, resetsAt?: unix seconds }] }. The pane dropped it: direct.ts built the summary with usageLimits: text(summary.usageLimits), which keeps only strings, and model.ts typed it string. So /status always showed "Usage limits: Not reported" for a Claude chat whose limits acpmux did report. The gallery hid this with a made-up string ("Weekly: 62% remaining").

What changes

  • model.ts: a typed AcpmuxUsageLimits; the summary field is AcpmuxUsageLimits | string.
  • usageLimits.ts (new): usageLimitsOf keeps a valid object and drops windows without a string id or a finite usedPercent. A non-array windows, or no window left, is undefined, so the card still says Not reported. A resetsAt is kept only when it is a finite positive number. usageLimitsLabel formats the card value.
  • direct.ts: usageLimits: usageLimitsOf(summary.usageLimits) ?? text(summary.usageLimits). A harness that sends plain text keeps it.
  • HarnessStatusCard.tsx: the Usage limits row shows each window as "Session (5 hours): 38% used, resets Oct 31, 10:00 PM UTC · Weekly: 12.5% used". The reset time uses Intl.DateTimeFormat in the pane's language (usePaneLanguage) with timeZoneName: "short". A window with no resetsAt gets no reset text and no guessed time. An unknown window id shows the raw id. Copy all and the per-value copy use the same rendered string.
  • Gallery agent-pane.harness-status: Claude now uses acpmux's real object shape (a session window with a reset time, a weekly window without one). Codex has no usage limits, because acpmux doesn't map Codex's yet, so it reads Not reported. OpenCode keeps its "Not reported by ACP" string.
  • Six new pane strings in acpmux/Localizable.xcstrings (21 locales: en and ja translated, the rest needs_review with real translations): the four window names, "{name}: {percent}% used" and "{name}: {percent}% used, resets {time}".

Out of scope: the rate-limited error card, retry and auto-resume are unchanged (failureCopy.ts untouched).

Tests

Red first: test-only commit 968cdbe, then the fix.

  • HarnessStatusCard.dom.test.tsx: the object renders the window names and percents, never "Not reported". The time zone is shown when resetsAt is present, with exactly one "resets", and the weekly window gets none. Copy all's line equals the rendered value. An unknown id shows raw. Four malformed shapes read Not reported, and a plain string shows as it is.
  • test/agent-pane-session-start.test.ts: the attach detail's usageLimits reaches the summary. Bad windows are dropped. Malformed values (windows not an array, no valid window, null, a number) become undefined. A string is kept.

Command (from webviews/, Blacksmith Linux through cmux-ci test/lane-gh ci and again locally):
bun test src/agent-session/acpmux/HarnessStatusCard.dom.test.tsx test/agent-pane-session-start.test.ts src/agent-session/acpmux/HarnessStatusCard.test.ts

  • Red at the test-only commit 968cdbe9d17538911d6b530b4fd4e34d21889696, with the fix files checked back to that commit (run 40980663198): 17 pass, 3 fail. "the usage limits acpmux reports show each window's use..." fails with Expected to not contain: "Not reported", "a usage limit window the card does not know shows its raw id" fails with Received: "Not reported", and the summary plumbing test fails because acpmux's object was dropped.
  • Green at 9979e4dea7df (run 40981080457): 20 pass, 0 fail. Green again locally at the final head 16235be2680e: 20 pass, 0 fail, 65 expect() calls. The final head adds only a formatting change to the test file.

Observed / Not run

  • Observed: scripts/web-lint.sh passes at the final head (Oxfmt, Oxlint, type check, layer and catalog-key checks; "web lint passed in 31.3s (webviews)"). The new xcstrings JSON parses, and each key carries all 21 locales.
  • ./scripts/localize-changes --base origin/feat-cmux-next ran: "Prepared 0 new macOS key(s) ... Changed web English message keys: 0". The pane catalog is not one of its macOS targets, so I added the six keys by hand. Its "parity errors over the debt baseline" note comes from base's macOS catalogs; this PR touches none of them.
  • Not run: the full webviews suite (CI runs it), and a live Claude Code chat on a subscription account. The input shape comes from acpmux's usage_limits.rs and acpmux: forward a Claude Code chat's plan usage limits to clients #24293's hub tests.

Before / after

Not captured. scripts/gallery-compare.sh --entry agent-pane.harness-status cannot run from the lane VM that built this PR: it needs to reach the gallery host, and this VM cannot. Run it from an origin host to get a live before/after. The gallery entry is agent-pane.harness-status, variant claude.

  • Before: the Claude variant's Usage limits row showed a made-up string ("Weekly: 62% remaining"). The real app showed "Not reported" for every Claude chat.
  • After (the formatter's text output for the gallery's fixed input in an en / UTC run): Session (5 hours): 38% used, resets Oct 31, 10:00 PM UTC · Weekly: 12.5% used. The weekly window carries no reset text. Codex reads "Not reported". OpenCode keeps "Not reported by ACP".

Changelog

Fixed: the Session status card (/status) shows a Claude chat's plan usage limits (each window's share used, and its reset time with time zone when reported) instead of "Not reported".

Risk: risk:normal. Webview-only display change in one card plus a defensive parse; no protocol change.

Agent session: agent session

🤖 Generated with Claude Code

teamleaderleo and others added 3 commits October 30, 2026 00:31
Red: the session detail's usageLimits object is dropped (direct.ts keeps
only strings), so the Session status card says Not reported.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a5a07bf12356d9e39ea0
…x reports

acpmux sends a Claude Code chat's plan limits as
{windows: [{id, usedPercent, resetsAt?}]}; the pane kept only strings, so
/status always said "Usage limits: Not reported". Parse the object
(usageLimitsOf), keep a harness's plain text, and show each window's share
used plus its reset time with time zone only when acpmux reported one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a5a07bf12356d9e39ea0
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review e686ec9: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr27762 -f ref=lane/fix-onboarding-b-usage-limits -f platform=macos -f backend_mode=local

Gallery before/after for 7fb4054: 16 states rendered, 14 images differ, 2687 more touched states not rendered. Images are in the run's artifact, not on this public PR; the independent review of this head reads them on its own, so the PR needs no hand-made screenshots of these states.

gh run download 41231400315 -R manaflow-ai/cmux -n gallery-advisory-27762-7fb4054290caff4bc61fa3ec529fc62db09621a9 (then read gallery-review.json)

States
State Theme Status Diff Picked by
agent-pane.harness-status/claude Apple System Colors Light changed 2.33% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/claude Apple System Colors changed 2.32% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/codex Apple System Colors changed 0.433% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/codex Apple System Colors Light changed 0.432% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/opencode Apple System Colors Light unchanged 0% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/opencode Apple System Colors unchanged 0% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/copy-and-escape Apple System Colors Light changed 0% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/copy-and-escape Apple System Colors changed 0% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/copy-value Apple System Colors Light changed 2.33% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/copy-value Apple System Colors changed 2.32% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/header-action-alignment Apple System Colors Light changed 2.33% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/header-action-alignment Apple System Colors changed 2.32% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/overlay-escape-priority Apple System Colors Light changed 0% own HarnessStatusCard.gallery.tsx
agent-pane.harness-status/overlay-escape-priority Apple System Colors changed 0% own HarnessStatusCard.gallery.tsx
agent-pane.live-chat-watch/choice-alone Apple System Colors Light unchanged 0% own direct.ts
agent-pane.live-chat-watch/choice-alone Apple System Colors unchanged 0% own direct.ts
agent-pane.live-chat-watch/view-only Apple System Colors Light unchanged 0% own direct.ts
agent-pane.live-chat-watch/view-only Apple System Colors unchanged 0% own direct.ts
agent-pane.harnesses/this-mac Apple System Colors changed 0.0106% names HarnessStatusCard.tsx
agent-pane.harnesses/this-mac Apple System Colors Light changed 0.0099% names HarnessStatusCard.tsx
agent-pane.harnesses/sign-in-expired Apple System Colors Light unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/sign-in-expired Apple System Colors unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/hover Apple System Colors Light unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/hover Apple System Colors unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/sign-in-launch-failed Apple System Colors Light unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/sign-in-launch-failed Apple System Colors unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/signed-out-no-login Apple System Colors Light unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/signed-out-no-login Apple System Colors unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/health-failed Apple System Colors Light unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/health-failed Apple System Colors unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/auth-unknown Apple System Colors Light unchanged 0% names HarnessStatusCard.tsx
agent-pane.harnesses/auth-unknown Apple System Colors unchanged 0% names HarnessStatusCard.tsx

Pick other states with a Gallery: entry.id, entry.id/variant line in the PR body.

web and size checks: green

Shipped in:

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 30, 2026
@blacksmith-sh

blacksmith-sh Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Found 3 test failures on Blacksmith runners:

Failures

Test View Logs
test_a_picked_signing_label_has_a_rerun_alternative (main.RunsOnFallbackTests.test_
a_picked_signing_label_has_a_rerun_alternative)/
test_a_picked_signing_label_has_a_rerun_alternative (main.RunsOnFallbackTests.test_
a_picked_signing_label_has_a_rerun_alternative)
View Logs
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)/
test_every_listed_hook_is_one_glaeda_released_with_the_check (main.SigningHooksInSt
epWithGlaedaTests.test_every_listed_hook_is_one_glaeda_released_with_the_check)
View Logs
test_no_runs_on_chain_ends_on_the_reserved_side_label (main.RunsOnFallbackTests.tes
t_no_runs_on_chain_ends_on_the_reserved_side_label)/
test_no_runs_on_chain_ends_on_the_reserved_side_label (main.RunsOnFallbackTests.tes
t_no_runs_on_chain_ends_on_the_reserved_side_label)
View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

…ing-b-usage-limits

# Conflicts:
#	webviews/src/agent-session/acpmux/Localizable.xcstrings
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra high, next-review): BLOCK at 537ac72

  • webviews/src/agent-session/acpmux/usageLimits.ts:21,51-54 — Any finite positive resetsAt is accepted, but timestamps outside JavaScript’s valid Date range make both Intl.DateTimeFormat().format() calls throw RangeError. A malformed/provider-supplied value can therefore crash HarnessStatusCard rendering instead of being ignored.

teamleaderleo and others added 3 commits October 31, 2026 07:41
…ing-b-usage-limits

# Conflicts:
#	webviews/src/agent-session/acpmux/Localizable.xcstrings
…he status card

Red: usageLimitsOf keeps any finite positive resetsAt, and
Intl.DateTimeFormat().format() throws RangeError for one past
8.64e15 ms, which takes down HarnessStatusCard.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a5a07bf12356d9e39ea0
usageLimitsOf kept any finite positive resetsAt; one past the Date range
made Intl.DateTimeFormat().format() throw RangeError and crash the Session
status card. Such a time is now dropped like a missing one, so the window
shows its use with no reset.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-a5a07bf12356d9e39ea0
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6-astra): SHIP at e686ec9

Independent Astra review (high, fast) of the PR at this exact head: no P1/P2/P3 findings. It checked the wire shape against the daemon's usage_limits.rs (ids, unix seconds), confirmed an invalid date is rejected before Intl formats it (the earlier BLOCK's RangeError), that plain strings still pass through and that Copy all matches the rendered text, and that nothing outside the status card's display changed.

Red/green for the RangeError fix, cd webviews && bun test src/agent-session/acpmux/HarnessStatusCard.dom.test.tsx:

  • at e905dae (test only): 13 pass, 1 fail, RangeError: date value is not finite in DateTimeFormat format()
  • at e686ec9: 14 pass, 0 fail; 21/21 across the three usage-limits test files; scripts/web-lint.sh passes.

@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent October 31, 2026 08:36 Inactive
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent October 31, 2026 08:43 Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (next-review patch-id; carried): SHIP at 350b69a

The independent SHIP at e686ec9 carries to this head: the PR's own change (git diff $(git merge-base feat-cmux-next HEAD) HEAD) has the same git patch-id --verbatim (5ee9ca2182ea882f) at both heads, and no merge between them was resolved by hand. Nothing new to review. A newer BLOCK, or any change to the PR's own diff, ends the carry.

@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@cmux-bot
cmux-bot Bot temporarily deployed to ci-routing-agent October 31, 2026 18:51 Inactive
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (next-review patch-id; carried): SHIP at 7fb4054

The independent SHIP at e686ec9 carries to this head: the PR's own change (git diff $(git merge-base feat-cmux-next HEAD) HEAD) has the same git patch-id --verbatim (5ee9ca2182ea882f) at both heads, and no merge between them was resolved by hand. Nothing new to review. A newer BLOCK, or any change to the PR's own diff, ends the carry.

@teamleaderleo teamleaderleo removed the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Oct 31, 2026
@cmux-bot
cmux-bot Bot merged commit 896cfb6 into feat-cmux-next Oct 31, 2026
214 of 215 checks passed
@cmux-bot
cmux-bot Bot deleted the lane/fix-onboarding-b-usage-limits branch October 31, 2026 20:07

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 7fb40542 Deployed Oct 31, 2026 by cmux-bot[bot] via cmux-tui tree preflight #91020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant