From 31cdb936918d034cd93c160259e364ef96858e63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 21 Aug 2026 20:56:45 +0000 Subject: [PATCH] usage shows the signed-in account only, and says which one it is MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase one of answering a question the panel could not answer: whose numbers am I looking at. This machine's owner has two Anthropic accounts, personal and work, and both had stored snapshots — so both appeared as tabs. After signing in there was no way to tell from a glance which one was now being spent. The panel was answering "here is usage for two accounts" while the question was "which am I on". So the hook filters to the account marked `current`, and the absence of one now MEANS something: no current row renders as "Not signed in" rather than as whichever tab happened to be selected first. The email also gets its own line instead of sharing one with the plan. Joined as `Team · a@b.c` in a 320px popover, the email is the half that truncates — and it is the half being read. The other accounts are said out loud rather than silently dropped: "1 other account not shown". Knowing one exists and is hidden deliberately is a different thing from wondering where it went. Temporary and a one-line revert by construction: delete `onlyCurrent` in useClaudeUsage and return `all`. The server still serves every account, the tab strip is still in the file, and nothing was deleted — the stored snapshots are a real feature, they were simply drowning the question being asked. Co-Authored-By: Claude Opus 5 --- .../src/apps/Chat/components/UsagePopover.tsx | 30 ++++++++++++++----- .../src/apps/Chat/useClaudeUsage.ts | 21 ++++++++++++- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/src/workspaces/officerdev/src/apps/Chat/components/UsagePopover.tsx b/src/workspaces/officerdev/src/apps/Chat/components/UsagePopover.tsx index d5388436..941da781 100644 --- a/src/workspaces/officerdev/src/apps/Chat/components/UsagePopover.tsx +++ b/src/workspaces/officerdev/src/apps/Chat/components/UsagePopover.tsx @@ -193,7 +193,7 @@ export function UsagePopover({ label, harness }: UsagePopoverProps) { const enabled = isOwner && harness === 'claude-code'; const [open, setOpen] = useState(false); - const { accounts, isLoading, isRefreshing, isError } = useClaudeUsage(enabled && open); + const { accounts, allAccounts, isLoading, isRefreshing, isError } = useClaudeUsage(enabled && open); /* Which tab is showing. @@ -206,6 +206,7 @@ export function UsagePopover({ label, harness }: UsagePopoverProps) { */ const [selectedEmail, setSelectedEmail] = useState(null); const selected = accounts.find((a) => a.email === selectedEmail) ?? accounts[0] ?? null; + const hidden = Math.max(0, allAccounts.length - accounts.length); // The countdowns tick. Only while the panel is open — an interval running behind a closed popover is a // re-render a minute for something nobody is looking at. @@ -234,13 +235,26 @@ export function UsagePopover({ label, harness }: UsagePopoverProps) { {/* Plan and account in the accent rather than muted: this line is the ANSWER to "whose numbers am I looking at", which matters more the moment there is a second tab, and it was reading as chrome under the title. */} -
- {selected - ? [selected.plan, selected.email].filter(Boolean).join(' · ') - : isLoading - ? 'Reading usage…' - : 'Not signed in'} -
+ {/* The email on its own line, unshared. It is the answer to the only question this panel is + being opened to settle — which account am I spending — and joined with the plan it was the + half that got truncated first in a 320px popover. */} + {selected ? ( + <> +
+ {selected.email} +
+ {selected.plan &&
{selected.plan}
} + + ) : ( +
{isLoading ? 'Reading usage…' : 'Not signed in'}
+ )} + {/* Said out loud rather than silently dropped. Phase one shows one account; knowing another + exists and is hidden on purpose is different from wondering where it went. */} + {hidden > 0 && ( +
+ {hidden} other account{hidden === 1 ? '' : 's'} not shown +
+ )} {/* How old this reading is, and it earns its line only when it is not live. diff --git a/src/workspaces/officerdev/src/apps/Chat/useClaudeUsage.ts b/src/workspaces/officerdev/src/apps/Chat/useClaudeUsage.ts index a61d0578..c96f9385 100644 --- a/src/workspaces/officerdev/src/apps/Chat/useClaudeUsage.ts +++ b/src/workspaces/officerdev/src/apps/Chat/useClaudeUsage.ts @@ -76,8 +76,27 @@ export function useClaudeUsage(enabled: boolean) { if (fresh.data) queryClient.setQueryData(KEY, fresh.data); }, [fresh.data, queryClient]); + const all = fresh.data?.accounts ?? cached.data?.accounts ?? []; + + /* + PHASE ONE — the signed-in account only. Temporary, and a one-line revert: delete `onlyCurrent` and + return `all`. + + The stored snapshots for other accounts are a real feature and the server still serves them. The problem + is what they do to the question being asked. This machine's owner has a personal account and a + work one, both appear as tabs, and after signing in you cannot tell from a glance WHICH tab you are + now spending — the panel answers "here is usage for two accounts" when the question is "whose am I on". + + So while that is the question, show one account and let its absence mean something: no row marked + `current` renders as "Not signed in", which is a true and useful answer rather than a tab that happens + to be selected. + */ + const onlyCurrent = all.filter((a) => a.current); + return { - accounts: fresh.data?.accounts ?? cached.data?.accounts ?? [], + accounts: onlyCurrent, + /** Every account the server knows about — kept so a caller can say how many are being hidden. */ + allAccounts: all, /** Only true when there is nothing at all to show. A stale list is not a loading state. */ isLoading: cached.isLoading && fresh.isLoading, /** A refresh in flight over an already-painted panel. Worth a hint, never a spinner over the numbers. */