Skip to content

feat(examples): claude-loaded, a session context inspector - #8

Merged
joepetjr merged 2 commits into
mainfrom
feat/claude-loaded
Aug 9, 2026
Merged

joepetjr merged 2 commits into
mainfrom
feat/claude-loaded

Conversation

@joepetjr

@joepetjr joepetjr commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds claude-loaded under examples/, alongside health-check, agents and workflows. It reports which files are loaded into a Claude Code session's context with per-file token counts, plus a budget mode (--budget N, exit 1 on breach) and --prune.

It lands here rather than in its own repository because its prerequisite is Claude Code itself — the same prerequisite this repo already has — and this repo already hosts adjacent Claude Code tooling under examples/. One 540-line script does not warrant its own README, LICENSE, CI and release process.

Diff cap

793 insertions / 2 deletions, over the 300 cap, pushed with a documented DIFF_CAP_OVERRIDE=1 and explicit owner approval. 540 of those lines are the tool imported byte-identical with zero deletions; roughly 253 are authored (README, changelog, index wiring, and the fixes below). There is no honest trim: the overage is the script, and splitting a single executable across PRs is not a real option.

Three defects fixed before this shipped

Found by running the tool, not by reading it. Publishing a tool whose headline feature is broken, and then listing it as a working thing, is the failure this project's fact gates exist to prevent — so they were fixed first rather than documented as known issues.

  1. Per-file read accounting was wrong. The jq invocation passed --arg p "$path" and never referenced $p in the filter, so it summed every tool_result in the transcript once per file. Symptom: ten rows all reporting an identical 19.0K, totalling 189.9K against a real 128.4K, which clamped "Everything else" to 0. Replaced with a two-pass jq + awk join keyed on tool_use_id (verified that tool_use.id correlates 1:1 with tool_result.tool_use_id in a real transcript before relying on it). Same transcript now reports 9.1K static + 9.1K read + 110.2K other = 128.4K, and the rescan loop is gone — a 4.3 MB transcript reports in 0.39s.
  2. fmt_cost was dead code while --help advertised "steady-state cost per turn". Wired up rather than deleted, since COST_RATE_USD_M is already a documented interface. Wiring it up exposed an awk injection — $RATE was interpolated into awk "BEGIN{...}", so COST_RATE_USD_M='1;system("...")' would have executed. Unreachable while the function was dead; guarded in the same commit.
  3. --all's STARTED column printed raw epoch-millis — cut -dT -f2 is a no-op on a numeric startedAt. Now handles ISO-with-millis, ISO-plain, epoch-millis and epoch-seconds.

Test plan

  • Clean venv built the way CI does (pip install -e ".[dev]"), python -m pytest -q → 75 passed
  • bash -n clean
  • Every mode regression-checked: --help, --budget under and over (exit 0 / exit 1), --prune, --json, --all, unknown arg (exit 1), unresolvable session, empty transcript
  • Defect 1 verified against a real transcript before and after; per-file rows now sum to the reported total

Joe Petrucelli added 2 commits August 9, 2026 10:13
Adds examples/claude-loaded/ — one bash script that lists the files loaded
into a Claude Code session's context (the CLAUDE.md chain, the auto-memory
index, and every file a Read pulled in) with a per-file token estimate, plus
a --budget mode that checks only the re-sent-every-turn set against a ceiling
and needs no session or transcript, so it can run from a SessionStart hook.

It does not import claude_batch_runner. It sits in examples/ as a peer of
health-check/ and workflows/ because a campaign inherits whatever CLAUDE.md
and auto-memory bloat a session already carries and pays for it once per unit.

The new README documents three things the script reports badly, all verified
against a live run rather than assumed: every "read" row carries the same
whole-session size instead of a per-file one, token counts are a
3.6-chars-per-token estimate, and the "cost per turn" its --help advertises
is never printed.

Script is byte-identical to its source; only docs are authored here.
…t, format STARTED

The per-file "read" accounting passed --arg p "$path" into a jq filter that
never referenced $p, so it summed every tool_result in the transcript once per
path. Every read row printed the same number -- the whole session's tool output
-- and their sum overshot the real total, clamping "Everything else" to 0. A
tool_result carries only its tool_use_id, so the path has to come from the
matching tool_use in the preceding assistant message: pass 1 maps id -> path
for Read calls, pass 2 maps id -> result size, awk joins them and keeps the
largest result per path. It also drops the per-path re-scan of the whole
transcript, so a 4.3MB transcript now reports in 0.4s.

fmt_cost was defined and never called, so COST_RATE_USD_M changed no output
while --help advertised "steady-state cost per turn". Wired it up rather than
deleting it: the whole window is re-sent as a cache read every turn, so
TOTAL at the cache-read rate is a well-defined per-turn floor, and the env var
is already documented. The rate is now validated, because it is interpolated
into an awk program and a non-numeric value is injected awk code.

--all printed startedAt raw: the harness writes epoch milliseconds and
cut -dT is a no-op on a number. Both shapes are handled now.

README and CHANGELOG drop the three known-issue entries and keep the honest
residue: the estimate is 3.6 chars/token, a read row measures the tool result
rather than the file on disk, and the cost line is an estimate at one rate.
@joepetjr
joepetjr merged commit fcd5d89 into main Aug 9, 2026
3 checks passed
@joepetjr
joepetjr deleted the feat/claude-loaded branch August 9, 2026 22:59
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