Add usage tracking, goreleaser, and rewrite SKILL.md - #3
Merged
Conversation
- New `sessions usage` subcommand shows which sessions invoked the CLI - Every invocation logs to ~/.claude/skills/sessions/usage.jsonl with timestamp, command, target, cwd, and best-effort caller session ID - Rewrite SKILL.md: remove install instruction (redundant when skill is loaded), add pagination docs, per-tool stats, usage tracking reference - Apply Anthropic prompt-writing principles: Why→What→How rhythm, descriptive headers, grouped flags Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Push to main triggers auto-tag (vX.Y.Z), which triggers goreleaser to build static binaries for darwin/linux x amd64/arm64 and publish as a GitHub Release. Users download the binary directly — no Go compiler needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add sync.WaitGroup to ensure LogUsage goroutine completes before process exit (blocker: short-lived commands could exit before the log write finished, silently dropping usage records) - Validate sessions usage -n >= 1, consistent with list -n validation Found by Codex review (GPT-5.5). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Mapleeeeeeeeeee
added a commit
that referenced
this pull request
Sep 1, 2026
#3) Two changes that pay for each other. The Bash summary printed only the description Claude wrote for itself, so 78% of a session's tool calls could not be checked against what actually ran. And "-> ok" annotated 1,550 of 1,604 calls with the state a reader already assumes. The verb is not a prefix of the command. Real commands open with `cd <absolute path> &&`, an env assignment, a shell keyword, or an echoed heading, so a 20-character prefix reads "cd /Users/maple/Desk" and names nothing; a 60-character one costs +9.8% tokens for the same reason. Stepping over those to the first real program name reaches one on 1,258 of 1,258 Bash calls in the measured session at +2.0%, which the -2.0% from the dropped marker cancels. Measured together over 5 sessions: -0.0%. Success now renders its excerpt or diff stat alone, still introduced by "->" so the call stays separable from its result. FAILED keeps its marker, and with it formatRetryCollapse's insertion point for "×N". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8xGh8fwz3YjLhFTMYqvXB
Mapleeeeeeeeeee
added a commit
that referenced
this pull request
Sep 1, 2026
… (ADR-007, ADR-008) (#9) * feat: filter noise from successful tool result excerpts (ADR-007 #1) The success path took the first non-empty line with no filtering, so a script's own "--- HEAD ---" was reported as the state of a working tree and a test runner's "RUN v4.0.18" as the result of a test run. Failures already skipped known-noise shapes; this gives success its own set (echoed section headings, progress lines, version banners) and strips ANSI escapes on both paths. Section headings are recognized only when the same rule closes the line, so a diff's "--- a/file.go" survives as an excerpt. The success-only shapes are deliberately not applied to failures: a banner-shaped line can be the error itself when the call failed. Measured on a 1,258-Bash-call session: 292 lines (23%) now carry a better excerpt, none lost one, and ANSI escapes drop from 95 lines to zero. A prose usage banner (gh's "Work seamlessly with GitHub from the command line.") has no shape to key on and is not covered; a test pins that limit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8xGh8fwz3YjLhFTMYqvXB * feat: carry the Bash command verb, drop the success marker (ADR-007 #2, #3) Two changes that pay for each other. The Bash summary printed only the description Claude wrote for itself, so 78% of a session's tool calls could not be checked against what actually ran. And "-> ok" annotated 1,550 of 1,604 calls with the state a reader already assumes. The verb is not a prefix of the command. Real commands open with `cd <absolute path> &&`, an env assignment, a shell keyword, or an echoed heading, so a 20-character prefix reads "cd /Users/maple/Desk" and names nothing; a 60-character one costs +9.8% tokens for the same reason. Stepping over those to the first real program name reaches one on 1,258 of 1,258 Bash calls in the measured session at +2.0%, which the -2.0% from the dropped marker cancels. Measured together over 5 sessions: -0.0%. Success now renders its excerpt or diff stat alone, still introduced by "->" so the call stays separable from its result. FAILED keeps its marker, and with it formatRetryCollapse's insertion point for "×N". Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8xGh8fwz3YjLhFTMYqvXB * feat: move the date out of every message header (ADR-007 #4) "[08-06 03:06]" repeated a date identical on every message of a day and had no year at all, so a read output gave no way to place a session in time (context could fall back to its session header; read has none). The date moves to a "--- 2026-08-06 ---" marker emitted when it rolls over, and the space it freed buys second precision. Measured over 5 sessions this is -0.4% tokens while carrying strictly more than the old format: seconds and the year. Sessions really do span days in the sample (2 and 3), but sparsely: the marker fired twice across a 1,808-event session. An unparseable timestamp renders a placeholder and leaves the day state alone, so a malformed event cannot invent a date boundary. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8xGh8fwz3YjLhFTMYqvXB * feat: raise the inherit page size to 28,000 bytes (ADR-007 #5) The 20,000 limit existed to keep a page inside the harness's Bash stdout cap, but that cap was never measured. Binary search on 2026-08-29 put it at 30,000 characters: 30,000 came back inline, 31,000 was persisted to a file with a 2KB preview. 28,000 leaves headroom for the page marker and footer; the largest real page now renders at 28,073 bytes. A 871KB session drops from 44 pages to 32, so inheriting it costs 12 fewer Bash round-trips, each of which was a separate API request paying cache read on the whole prefix. The constant is exported so the boundary tests derive their cases from it instead of restating 20,000, which had already stopped describing the real boundary in three of them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8xGh8fwz3YjLhFTMYqvXB * docs: record ADR-007's as-built numbers The set lands at +0.3% tokens rather than the predicted -0.4%. The gap is decision 1 doing its job: skipping a noise line reaches a longer, more informative one. Also records the two rules the implementation tightened (symmetric section headings only, indented code not skipped) and the shell control keywords the verb extraction had to step over. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8xGh8fwz3YjLhFTMYqvXB * feat: classify harness-injected events and count turns by policy (ADR-008) Reader now recognizes eight entry types the CLI added after the noise whitelist was written, classifies six harness-injected user messages in the parser layer and renders them under a `harness:` role label, detects teammate messages by a set of markers instead of a disclaimer string that no longer matches, and resolves skill-body injections through the sourceToolUseID link to the Skill tool_use so bundled skills without a base-directory line compact to `[skill: name]`. Turn counting moves out of the character-accounting loop into UserMessage.CountsAsTurn(), calibrated against transcripts: teammate messages, task notifications, and compaction summaries start a round and count; interrupts and agents-stopped notices do not. Docs: SKILL.md and README record the 28K page size and the harness role. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TcvWErnKnuADJsomnZfwFr --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
~/.claude/skills/sessions/usage.jsonl; newsessions usagesubcommand to review-nvalidation on usage subcommandTest plan
sessions usagedisplays entries in reverse chronological ordersessions usage -n 3 -cmd listfilters correctly🤖 Generated with Claude Code