Summary
Grok token totals never reach Usage & Spend or the shareable usage card, even with a fully populated local session history. On this machine ~/.grok/sessions/**/signals.json holds 88 sessions inside the 30-day window totalling ~18.3M tokens by GrokLocalSessionScanner's own formula, and the emitted snapshot contains no costUsage key at all — so grokLocalTokenSnapshot returns nil, Grok is placed in confirmedEmptySourceIDs, and it is absent from the spend dashboard and from every shared card.
Environment
- CodexBar 0.60.3 (146), Homebrew cask, macOS 26
grok CLI 1.0.25 at ~/.npm-global/bin/grok
- Grok enabled in
~/.config/codexbar/config.json; tokenCostUsageEnabled = 1
Observed
codexbar usage --provider grok --json returns only identity plus a quota percentage — no token fields:
{ "source": "grok-cli-proxy", "provider": "grok", "version": "1.0.25",
"usage": { "primary": { "usedPercent": 100, "resetsAt": "2026-09-18T17:06:33Z" },
"secondary": null, "tertiary": null, "loginMethod": "X Premium+" } }
--log-level debug shows the RPC billing method is gone from this CLI version:
grok rpc -> {"jsonrpc":"2.0","id":2,"params":{},"method":"x.ai/billing"}
grok rpc <- {"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"Method not found"}}
Grok RPC stopping
== Grok 1.0.25 (grok-cli-proxy) ==
So x.ai/billing returns -32601 Method not found on grok 1.0.25, the probe falls back to a quota-only snapshot, and the local session tokens are not attached to it.
Local data that should have been surfaced
files matched ~/.grok/sessions/*/*/signals.json : 88
files with mtime inside 30 days : 88
files with non-zero tokens : 88
sum of (totalTokensBeforeCompaction + contextTokensUsed) : > 18,339,779
Those are exactly the two fields GrokLocalSessionScanner reads (GrokLocalSessionScanner.swift:123-126), and every file carries primaryModelId, so models would populate too.
Where it goes wrong
GrokStatusProbe.toUsageSnapshot() (GrokStatusProbe.swift:69) sets costUsage: self.localSummary?.toCostUsageTokenSnapshot(...), so a nil localSummary silently yields a snapshot with no token history. Both strategies appear to intend to supply it — GrokWebFetchStrategy passes localSummary: self.localSummary(context.env) (GrokProviderDescriptor.swift:427, :454) and GrokStatusProbe.fetch computes it at :139 — yet the snapshot produced on the grok-cli-proxy path (GrokProviderDescriptor.swift:311, :313, :491) arrives without it. I could not pin the exact line by reading alone and did not want to guess; the observable contract is that a -32601 billing failure returns a snapshot whose costUsage is nil despite a populated local summary being available.
Downstream consequences, for completeness:
UsageStore+TokenCost.swift:517 → grokLocalTokenSnapshot returns nil
SpendDashboardController.swift:295-308 → Grok added to confirmedEmptySourceIDs, continue
ShareStatsPayload.swift:258 → no Grok provider row, so nothing to share
Suggested direction
Treat a missing/renamed RPC billing method as "quota unavailable" rather than "no usage data": keep returning the local GrokLocalSessionSummary on that path so token totals survive even when x.ai/billing is absent. Separately, x.ai/billing disappearing in grok 1.0.25 may warrant a version probe or a fallback method name.
Also worth noting for expectations: Grok can never contribute a per-model breakdown, since toCostUsageTokenSnapshot hardcodes modelBreakdowns: nil (GrokLocalSessionScanner.swift:58) while the card's model list is built from modelBreakdowns. Token totals are achievable; per-model rows are not, by construction.
Summary
Grok token totals never reach Usage & Spend or the shareable usage card, even with a fully populated local session history. On this machine
~/.grok/sessions/**/signals.jsonholds 88 sessions inside the 30-day window totalling ~18.3M tokens byGrokLocalSessionScanner's own formula, and the emitted snapshot contains nocostUsagekey at all — sogrokLocalTokenSnapshotreturns nil, Grok is placed inconfirmedEmptySourceIDs, and it is absent from the spend dashboard and from every shared card.Environment
grokCLI 1.0.25 at~/.npm-global/bin/grok~/.config/codexbar/config.json;tokenCostUsageEnabled = 1Observed
codexbar usage --provider grok --jsonreturns only identity plus a quota percentage — no token fields:{ "source": "grok-cli-proxy", "provider": "grok", "version": "1.0.25", "usage": { "primary": { "usedPercent": 100, "resetsAt": "2026-09-18T17:06:33Z" }, "secondary": null, "tertiary": null, "loginMethod": "X Premium+" } }--log-level debugshows the RPC billing method is gone from this CLI version:So
x.ai/billingreturns -32601 Method not found on grok 1.0.25, the probe falls back to a quota-only snapshot, and the local session tokens are not attached to it.Local data that should have been surfaced
Those are exactly the two fields
GrokLocalSessionScannerreads (GrokLocalSessionScanner.swift:123-126), and every file carriesprimaryModelId, somodelswould populate too.Where it goes wrong
GrokStatusProbe.toUsageSnapshot()(GrokStatusProbe.swift:69) setscostUsage: self.localSummary?.toCostUsageTokenSnapshot(...), so a nillocalSummarysilently yields a snapshot with no token history. Both strategies appear to intend to supply it —GrokWebFetchStrategypasseslocalSummary: self.localSummary(context.env)(GrokProviderDescriptor.swift:427,:454) andGrokStatusProbe.fetchcomputes it at:139— yet the snapshot produced on thegrok-cli-proxypath (GrokProviderDescriptor.swift:311,:313,:491) arrives without it. I could not pin the exact line by reading alone and did not want to guess; the observable contract is that a-32601billing failure returns a snapshot whosecostUsageis nil despite a populated local summary being available.Downstream consequences, for completeness:
UsageStore+TokenCost.swift:517→grokLocalTokenSnapshotreturns nilSpendDashboardController.swift:295-308→ Grok added toconfirmedEmptySourceIDs,continueShareStatsPayload.swift:258→ no Grok provider row, so nothing to shareSuggested direction
Treat a missing/renamed RPC billing method as "quota unavailable" rather than "no usage data": keep returning the local
GrokLocalSessionSummaryon that path so token totals survive even whenx.ai/billingis absent. Separately,x.ai/billingdisappearing in grok 1.0.25 may warrant a version probe or a fallback method name.Also worth noting for expectations: Grok can never contribute a per-model breakdown, since
toCostUsageTokenSnapshothardcodesmodelBreakdowns: nil(GrokLocalSessionScanner.swift:58) while the card's model list is built frommodelBreakdowns. Token totals are achievable; per-model rows are not, by construction.