Skip to content

Add usage tracking, goreleaser, and rewrite SKILL.md - #3

Merged
Mapleeeeeeeeeee merged 4 commits into
mainfrom
feat/usage-tracking
Jun 15, 2026
Merged

Add usage tracking, goreleaser, and rewrite SKILL.md#3
Mapleeeeeeeeeee merged 4 commits into
mainfrom
feat/usage-tracking

Conversation

@Mapleeeeeeeeeee

Copy link
Copy Markdown
Owner

Summary

  • Usage tracking: every CLI invocation logs to ~/.claude/skills/sessions/usage.jsonl; new sessions usage subcommand to review
  • Goreleaser: push to main triggers cross-platform binary release (darwin/linux × amd64/arm64)
  • SKILL.md rewrite: removed redundant install instruction, added pagination/per-tool/usage docs, applied Anthropic prompt-writing principles
  • Review fixes: WaitGroup ensures log goroutine completes before exit; -n validation on usage subcommand

Test plan

  • 10 packages all tests pass (including 9 new tracker tests)
  • sessions usage displays entries in reverse chronological order
  • sessions usage -n 3 -cmd list filters correctly
  • Caller session ID auto-detected from cwd
  • Codex review (GPT-5.5) — blocker and should-fix addressed

🤖 Generated with Claude Code

Mapleeeeeeeeeee and others added 4 commits June 15, 2026 11:06
- 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
Mapleeeeeeeeeee merged commit a818faf into main Jun 15, 2026
@Mapleeeeeeeeeee
Mapleeeeeeeeeee deleted the feat/usage-tracking branch June 15, 2026 03:35
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant