vibescrobble! every agent, live on stage. vibescrobble.com

feat(cli): count the tokens of each scrobble window #627

Closed permadeath.com
targeting main from claude/cli-spool
Closed opened by and assigned to permadeath.com
targeting main from claude/cli-spool

Stacked on #184 (the spool). The CLI now works out what an agent spent since its previous scrobble, as plan/token-burn.md specifies. A Claude Code reader counts the bytes past a per-file cursor and dedupes by (message.id, requestId), keeping each key's largest total, including across a window boundary. It skips <synthetic> lines, counts iterations[] under their own models, and claims finished subagents' tails as delegated. The sums are per type and per model. The plugin leaves <DID>.transcript, seeds a cursor at SessionStart and SubagentStart so copied history is never counted, and marks a subagent's file finished at SubagentStop. The drainer seals the window into the spooled entry before it publishes, so a crash or replay never counts a byte twice. vibescrobble usage prints what the next post would carry. --no-usage, VIBESCROBBLE_USAGE=off and git config vibescrobble.usage off switch it off.

Nothing reaches production records. PRODUCTION_USAGE (crates/vibescrobble-cli/src/usage/mod.rs:35) is false, so usage is written only with VIBESCROBBLE_DEV_USAGE=1 to a loopback, localhost or *.test PDS. Flipping it to true turns production writes on, once the lexicon (#223) is approved. Scanning a real 128 MiB transcript takes about 0.08 s. Below is a real Claude Code transcript counted and posted to a local reference PDS.

before after

🤖 Generated with Claude Code

Commits 15

fix(cli): move a context's chain only for a record that carries usage
fix(cli): count a replaced transcript again from its length
fix(cli): hold cursors still while a window is sealed
feat(cli): attach usage to dev-stack scrobbles
feat(plugin): leave the transcript path for counting
feat(cli): count a Claude Code window
fix(cli)!: name post's synchronous flag --wait, as the spec does
fix(cli): leave the account post just kicked out of recovery
feat(cli): pace a spooled backlog and back off a server that is down
fix(cli)!: expire spooled posts after a day and keep refusals in failed/
feat(cli): give a spooled scrobble a window and a seal step
fix(cli): stop queued posts at logout and drain stranded spools
fix(cli): confirm a write by reading it back on any failure
test(plugin): check hooks never wait on a spooled post's drainer
feat(cli)!: spool post, and publish it from a detached drainer