mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-31 16:33:34 +08:00
Claude Code writes an assistant message as one JSONL line per content block — thinking, text, and each tool_use separately — and every one of those lines repeats the same complete `usage` object. Both stats paths summed them, so a reply cost as many times as it had blocks. One real message in this repo's own transcripts spans 52 lines carrying 50.8K tokens, and was counted as 2.65M. Scanning ~/.claude/projects with 1927 sources: the total drops from 9.76B to 4.59B tokens, and the busiest day from 2.60B to 1.46B. 39,290 of 69,306 usage lines were repeats. Usage records now deduplicate on (message.id, requestId), scoped per transcript, and survive an incremental read. Lines with no message id are still counted, matching ccusage. Two paths compute these stats — the local index reducer and the direct scan in stats.ts — and a parity test pins them to identical output. Both carried the bug, so the rules that decide what counts now live in one module, `utils/usageAccounting.ts`, rather than being written twice and drifting. Also fixed, all surfaced while verifying the above: Cost was dead code. `costUSD` and `webSearchRequests` were initialized to 0 in the reducer and never assigned, so 0 travelled to SQLite and out again. Now estimated from the rates in modelCost.ts — but with an unknown model returning null instead of falling back to the default model's rates, because 12.7% of the tokens here come from third-party providers (k3, glm, MiniMax, deepseek, grok) that would otherwise be billed at Claude prices. Those models keep their tokens in the activity totals and are named in `unpricedModels` so the UI can say the dollar figure is a floor. `MODEL_COSTS` has no entry for claude-opus-5 — the canonical-name resolver maps it to `claude-opus`, which isn't a key either — so the largest model by usage priced through the unknown-model fallback. The new module handles it explicitly. The CLI's own calculateUSDCost still takes that fallback; left alone here, it reaches well beyond activity stats. "Longest task" measured `last - first`, a calendar span rather than a duration: a session resumed the next morning reported the whole night as time on task. The panel read 436 hours for a 17-message session, and the worst case on this machine was 1137 hours. Sessions now accumulate working time across gaps under 30 minutes, stored in a new `active_duration_ms` column. Workflow subagent transcripts were never indexed. Discovery read one level of `subagents/`, but workflow agents nest a group deeper at `subagents/workflows/<id>/`; 79 files here were invisible to both the index and the direct scan, which additionally attributed them to a session named "workflows". Ties in "longest session" now break on session id. The two paths iterate sessions in different orders, and ties became reachable once an out-of-order session scored 0 rather than a distinct negative span. The parser version bump is what makes any of this reach an existing install: `detectSourceChange` rebuilds a source only when its stored version differs.
Claude Code Haha Desktop
基于 Tauri 2 + React 的桌面客户端。
开发
bun install
bun run tauri dev
构建
# macOS (Apple Silicon)
./scripts/build-macos-arm64.sh
# Windows (x64, MSI only)
.\scripts\build-windows-x64.ps1
构建产物位于 build-artifacts/ 目录,文件名会显式包含平台、架构和包类型。
常见问题
macOS 提示"已损坏,无法打开"
xattr -cr /Applications/Claude\ Code\ Haha.app