Skip to content

feat: lifetime stats that count every session — and grunt like caveman (pile view for --all) #716

Description

@Hiro-Chiba

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

  1. 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.

  2. --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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions