Problem
The lifetime number has two problems: it is incomplete, and what it shows talks like an accountant.
History has one writer: main() in src/hooks/caveman-stats.js (append at :495-506), and it runs only when the user types /caveman-stats (skills/caveman-stats/SKILL.md: "Triggers on /caveman-stats"). Forget the command → session never counted. --all, --since 7d, and the ⛏ statusline badge undercount forever. Verified on main @ 0d95a81.
Before: 10 caveman sessions, /caveman-stats typed in 2
Caveman Stats — Lifetime
──────────────────────────
Sessions: 2 ← 8 sessions gone. pile has hole.
Output tokens: 81,340
Est. tokens saved: 151,060
Est. saved (USD): ~$2.27
Request
-
SessionEnd hook auto-records a snapshot. New --record flag on caveman-stats.js: same parse → attribute → append path, no stdout. Safe by design — aggregateHistory keeps only the latest row per session_id (:492-494), so extra appends fold away. Verified end-to-end on Claude Code v2.1.212: SessionEnd delivers {session_id, transcript_path, reason} on stdin, and the unmodified script already appends the correct row from transcript_path (622 output tokens / 2 turns; est_saved_tokens: 0 with caveman off — no savings invented). A hard-killed session gets no SessionEnd; the dedup above means a per-turn upgrade can close that gap later.
-
--all grunts like caveman. Same numbers, same honesty rules (est. labels, output-only, never call it "usage" — per the outputReductionPct comment), caveman voice:
After:
🪨 caveman pile
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
sessions 10
mouth say 412,680 token
mouth not say 766,406 token ⛏
pile meter █████████████░░░░░░░ 65% of would-be output (est.)
~$11.50 stay in cave
numbers est. — output only. input not touched.
why use many token when few do trick
Two PRs if preferred — record first, grunt second. One concern per PR.
Why good
Number only honest if complete. The repo already treats invented savings as a bug (#601, docs/HONEST-NUMBERS.md) — undercounting is the same sickness in the other direction. #703's rolling statusline window only means something over dense history. And the pile view makes the user smile on every --all. Small mouth, big pile.
Related
Happy to PR the SessionEnd --record first if that's the preferred direction.
Problem
The lifetime number has two problems: it is incomplete, and what it shows talks like an accountant.
History has one writer:
main()insrc/hooks/caveman-stats.js(append at:495-506), and it runs only when the user types/caveman-stats(skills/caveman-stats/SKILL.md: "Triggers on /caveman-stats"). Forget the command → session never counted.--all,--since 7d, and the⛏statusline badge undercount forever. Verified on main @ 0d95a81.Request
SessionEnd hook auto-records a snapshot. New
--recordflag oncaveman-stats.js: same parse → attribute → append path, no stdout. Safe by design —aggregateHistorykeeps only the latest row persession_id(:492-494), so extra appends fold away. Verified end-to-end on Claude Code v2.1.212:SessionEnddelivers{session_id, transcript_path, reason}on stdin, and the unmodified script already appends the correct row fromtranscript_path(622 output tokens / 2 turns;est_saved_tokens: 0with caveman off — no savings invented). A hard-killed session gets noSessionEnd; the dedup above means a per-turn upgrade can close that gap later.--allgrunts like caveman. Same numbers, same honesty rules (est.labels, output-only, never call it "usage" — per theoutputReductionPctcomment), caveman voice:Two PRs if preferred — record first, grunt second. One concern per PR.
Why good
Number only honest if complete. The repo already treats invented savings as a bug (#601, docs/HONEST-NUMBERS.md) — undercounting is the same sickness in the other direction. #703's rolling statusline window only means something over dense history. And the pile view makes the user smile on every
--all. Small mouth, big pile.Related
Happy to PR the SessionEnd
--recordfirst if that's the preferred direction.