From eed906f45b64541e2aa4aa39e724674cdc2a3c99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Tue, 18 Aug 2026 10:07:01 +0000 Subject: [PATCH] command hq: show token totals alongside cost, not just dollars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both the grid card and the detail meta bar now read "N turns · 12.3k tok · $0.20" — tokens first, since that's what was actually asked to be primary, dollars kept alongside rather than dropped. formatTokens abbreviates past 1000 (12.3k, 1.2M) the same way a long-running watcher's cost already reads at a glance; the raw sum stops being readable well before the dollar figure does. Co-Authored-By: Claude Opus 5 --- .../officerdev/src/apps/CommandHQ/CommandHqDetail.tsx | 3 ++- .../officerdev/src/apps/CommandHQ/CommandHqGrid.tsx | 3 ++- src/workspaces/officerdev/src/apps/CommandHQ/format.ts | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx b/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx index 7451f588..dd98ee51 100644 --- a/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx +++ b/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqDetail.tsx @@ -10,7 +10,7 @@ import { useChat, EmbeddableChat } from '../Chat'; import type { ChatMessage } from '../Chat/types'; import { categoryFromParam, commandHqSessionPath } from './command-hq-routes'; import { useCommandHqCategories, useCommandHqCommander, useCommandHqCommanderActions } from './useCommandHq'; -import { formatCommanderCost } from './format'; +import { formatCommanderCost, formatTokens } from './format'; // Right panel of the /command-hq workspace. Three states, chosen by the URL alone (no channel — panels // read the route directly, per `docs/navigation-audit.md`): @@ -139,6 +139,7 @@ function MetaBar({ sessionId, title, isConnected, isGenerating, onDisconnect }: <> {commander.cost.turnCount} turn{commander.cost.turnCount === 1 ? '' : 's'} ·{' '} + {formatTokens(commander.cost.inputTokens + commander.cost.outputTokens)} tok ·{' '} {formatCommanderCost(commander.cost.totalUsd)} {commander.watcherArmed ? ( diff --git a/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqGrid.tsx b/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqGrid.tsx index 6688ce6d..c92ce5fe 100644 --- a/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqGrid.tsx +++ b/src/workspaces/officerdev/src/apps/CommandHQ/CommandHqGrid.tsx @@ -3,7 +3,7 @@ import { formatDistanceToNowStrict } from 'date-fns'; import { Plus } from 'lucide-react'; import { categoryFromParam, commandHqNewPath, commandHqSessionPath } from './command-hq-routes'; import { useCommandHqCommanders } from './useCommandHq'; -import { formatCommanderCost } from './format'; +import { formatCommanderCost, formatTokens } from './format'; import type { CommandHqCommander } from './types'; // Right-middle panel of the /command-hq workspace — one card per commander in the selected category. @@ -38,6 +38,7 @@ const Card = ({ commander, to, selected }: CardProps) => (
{commander.cost.turnCount} turn{commander.cost.turnCount === 1 ? '' : 's'} ·{' '} + {formatTokens(commander.cost.inputTokens + commander.cost.outputTokens)} tok ·{' '} {formatCommanderCost(commander.cost.totalUsd)} {commander.watcherLastFiredAt ? ( diff --git a/src/workspaces/officerdev/src/apps/CommandHQ/format.ts b/src/workspaces/officerdev/src/apps/CommandHQ/format.ts index 93d4596b..130a973d 100644 --- a/src/workspaces/officerdev/src/apps/CommandHQ/format.ts +++ b/src/workspaces/officerdev/src/apps/CommandHQ/format.ts @@ -4,3 +4,11 @@ export function formatCommanderCost(usd: number): string { if (usd < 0.01) return `$${usd.toFixed(4)}`; return `$${usd.toFixed(2)}`; } + +/** `342`, `12.3k`, `1.2M` — a watcher that has fired for months accumulates enough tokens that the raw + * count stops being readable at a glance, which a dollar figure never does at this scale. */ +export function formatTokens(count: number): string { + if (count < 1000) return `${count}`; + if (count < 1_000_000) return `${(count / 1000).toFixed(1)}k`; + return `${(count / 1_000_000).toFixed(1)}M`; +}