Repository navigation
fix(usage): label provider readings with their reporting Claude account - #355
Merged
Merged
Conversation
Two Claude accounts on one machine rendered as one client's contradictory meters: the Usage page joined provider-limit readings by client only, so the CLI statusLine stream and the desktop plan-usage stream stacked unlabeled under `claude-code`. - The statusLine stream is attributed at import time to the account its config home is signed in as: email/account/org uuid only, read from that home's user-level `.claude.json` oauthAccount; credentials are never opened. Relocated spools (explicit path or AGENTACCT_STATUSLINE_SPOOL) claim no account rather than a guessed one. - Snapshot signatures fold identity in only when present (an account switch records a fresh reading; codex and pre-enrichment streams keep their signatures), and run ids are unchanged so no existing stream forks. - `ClientLimit.account_label` composes "CLI · you@example.com" / "desktop app · org 07c55a50"; the glance payload carries it additively next to stream_id, `agentacct limits` prints the account, and the TUI and macOS Usage page render it above each reading. `limits --json` keeps its byte-stable shape; identity-less readings render exactly as before.
Merged
mikehasa
added a commit
that referenced
this pull request
Oct 3, 2026
Releases the Usage-page account attribution from #355 as **0.12.11**. Two Claude accounts on one machine (e.g. the terminal CLI signed into one, the desktop app into another) now render as two labeled provider-limit readings — `CLI · you@example.com`, `desktop app · org 07c55a50` — in the macOS app, the TUI, and `agentacct limits`, instead of four unlabeled meters under one client row. This PR changes only `pyproject.toml` and `CHANGELOG.md`: release version, dated notes, and release links. App bundle versions derive from `pyproject.toml`. ### Validation - Metadata, compatibility, and packaging guards: **66 passed** (`test_publish_workflow.py`, `test_rename_compat.py`, `test_packaging_release_guards.py`). - Wheel builds as `agentacct-0.12.11-py3-none-any.whl` (`pip wheel --no-deps .`). - `git diff --check` passed. - Merge waits for pytest 3.11/3.12/3.13 and macOS app/UI CI on this exact head. ### DMG preflight **Rebuild required.** Since v0.12.10, both `src/agentacct/` (account attribution and labels) and `apps/agentacct/` (the Usage-page reading labels) changed, and the DMG embeds the frozen Python CLI. Build a fresh signed, notarized, stapled DMG from this release PR's exact squash commit, embedding the matching 0.12.11 CLI. Verify the selected artifact and its independent public download before calling publication complete. Additive-only on the wire: one new glance field (`account_label`) and rate-limit event metadata (`account_email` / `account_uuid` / `account_org`); `limits --json` is unchanged; no configuration, permission, or store-migration changes.
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.
Two Claude accounts on one machine — the terminal CLI signed into one, the Claude desktop app into another — rendered as one client's contradictory meters on the Usage page. Readings were joined by
clientonly, and the CLI statusLine stream carried no account identity, so a 7-day "100% · limit reached" from the desktop account sat unlabeled under the sameclaude-coderow as the CLI's live 5-hour window.What changed
.claude.jsonoauthAccount. Identity only; credentials are never opened. A relocated spool (explicit path, orAGENTACCT_STATUSLINE_SPOOL) claims no account rather than a guessed one.run_ids are unchanged, and the snapshot signature folds identity in only when present, so an account switch on the same spool records a fresh reading while codex / pre-enrichment streams keep their historical signatures (pinned by a test).ClientLimit.account_labelcomposesCLI · you@example.com/desktop app · org 07c55a50(the same short-org form the limits header prints). The glance payload carries it additively besidestream_id; the macOS Usage page renders it above each reading's windows; the TUI prints it under the client name;agentacct limitsaddsaccount: …to the header.limits --jsonkeeps its byte-stable shape, and readings with no provable identity render exactly as before (the committed fixtures carry no account data, so the visual references are untouched).Validation
pytest -q -n 4 --dist loadfile); the same matrix runs on 3.11/3.12/3.13 in CI.swift test -c release);UsageCapacityTests17/17 including the new two-account and no-invented-label cases..claude.json): the recorded streams are now attributed —agentacct limitsprintsclaude-code (desktop app) org: 07c55a50andclaude-code (CLI) account: huyx1325@gmail.com— the glance payload carriesaccount_labelfor both, and the rendered Usage page shows the two labeled readings instead of four unlabeled meters.limits --jsonemits no new keys.CLI · huyx1325@gmail.comanddesktop app · org 07c55a50each label their own Weekly / 5-hour rows.The 0.12.11 version bump and rebuilt signed/notarized DMG follow in the separate release PR after this fix merges — the DMG embeds the frozen Python CLI, so this CLI-side change requires a rebuild.