Changelog

Nov 8, 2026 · 45 changes · page 1 of 2

coding.sh v0.1.3

Sessions read back from Claude Code and Codex transcripts keep more of what the agent recorded.

Docs 1

  • # Added Two guides for one agent each. coding.sh with T3 Code covers what is read from T3 Code's local store for each agent it runs, and how to turn a thread into an eval run by Codex or Claude Code. coding.sh with Pi covers the Pi extension, Pi's own cost per model call, and evals with --agent pi. T3 Code, Pi.

Workflows 8

  • # Added workflows stats --json gives each per-agent row the agent id, the attempt (a label run again after a resume is attempt 2) and how it ended (endReason: ok, failed, cancelled, superseded, null, schema-retry, …), so two agents with the same label can be told apart. The text table adds #2 to a re-run label. Workflows.
  • # Fixed A Claude Code workflow agent you stopped is cancelled, and one a resume re-ran under the same label is superseded, instead of failed with "no result recorded". workflows show and stats list them apart from failures and leave them out of the failure rate (cancelledAgents, supersededAgents in --json). On a run stopped and resumed twice, all 7 "failures" were these. Workflows.
  • # Fixed The wall time of a Claude Code workflow stopped and resumed in the same run dir runs from the first launch to the last result. Before, it covered only the last segment (4h43m of a 6h43m run), so the critical path came out longer than the wall and parallelism and utilization were off. workflows show and stats add the active time without the gaps between segments (activeMs, segments), and parallelism and utilization use it. Workflows.
  • # Fixed workflows import, and the import workflows list runs first, skip an unchanged run dir before reading its agent transcripts, and write each run's events to the index in a few large batches. On 16 synthetic runs with 470 MB of agent transcripts, a repeat import took 0.3 s instead of 13.6 s and a first import 19.5 s instead of 26.7 s. The host session's transcript is never read. Workflows guide.
  • # Fixed Cache hits on a Claude Code workflow resumed in the same run dir are read from the run's persisted record, since the journal writes no cache lines there. workflows stats showed 0 cache hits and no resume savings for a run whose record marks 11 agents cached; it now counts them and sums what they took when they ran as "resume saved", and show marks them "replayed on resume". Workflows.
  • # Fixed workflows show, stats and the Gantt list a run's phases in the same order, by when each phase first started. Before, stats put phases the script dropped before a resume (such as Review and Verify) last. Workflows.
  • # Fixed workflows import redacts Claude Code workflow agent transcripts before it stores them, with the same capture settings as ingest and backfill (redaction, [capture] redactPatterns, metadata mode). Before, agent prompts, replies and tool output went into the index and blob store unredacted. Re-import earlier runs with --force to redact them. Privacy.
  • # Fixed coding.sh workflows import|show|stats now shows cost for Claude Code Workflow runs. Claude Code transcripts carry tokens but no per-call cost, so each agent's model calls are priced from their tokens and the configured prices (as everywhere else in coding.sh), filling per-agent, per-phase and whole-run cost and costShareByPhase. Before, every captured workflow showed a dash for cost, hiding which stage spent the tokens. Re-import a run with --force to price one captured earlier. Workflows.

Improve 4

  • # Added improve and the MCP improve tool list what lost prompt cache cost, from the cache breaks ingest already stored: the extra dollars, their share of the spend, which sets the severity so the item ranks against the others by cost, and a fix per cause, costliest first. Improve.
  • # Changed improve and the MCP improve tool leave out headless sessions (claude -p, an Agent SDK, codex exec: stats.launch is "headless"), say how many they left out, and count them with --headless (headless: true). Before, one-shot scripts, judges and evals filled the report with issues an AGENTS.md line does not change. Improve.
  • # Fixed A failed compound shell line counts against the part that failed: the one its error names, the tool whose error it is, the part timeout stopped, or the last part of a pipeline, and "compound command" when nothing singles one out. Before, it went under its first word, so cat, for, sed, export and even --session (from a line continuation) filled the list with errors from other tools, and a cat of a test log got the broken-setup verdict. Improve.
  • # Fixed improve, improve check and the MCP improve and harness_changes tools redact secrets and email addresses in the prompts, error lines, commands and session titles they show. Before, an email address in a prompt or an error printed as is, because capture redaction covers secrets only. capture.redact takes email to keep addresses out of the store too. Improve.

Sessions 3

  • # Added A new coding.sh tree <session|run> command shows a whole multi-agent run as one tree: the top-level agent, every subagent it spawned, and their subagents, with per-node model, cost, tokens, duration and tool calls, the run's rolled-up totals, the worst flag across the loop, and which subagent to fix first. A fan-out of separate agent processes groups into one run when they share CODING_SH_RUN_ID. The viewer serves it at /api/sessions/{id}/tree and the MCP session_tree tool returns it for your agent. It is built from the parent links capture already records, so no session re-folds. Explore.
  • # Changed model:switch fires on every mid-session model change the agent recorded as a fallback, a switch and back included, and on any model change inside a subagent; before, only a main-thread hand-over for good counted. stats.modelSwitch adds the fallback reason, subagent, count, switchedCalls and extraUsd: what the calls on the other model cost over the first model's list prices. Concepts.
  • # Fixed A session that ran in the macOS temp dir (/var/folders/<xx>/<yyy>/T, where claude -p from a script often runs) has the repo name tmp in repo: queries and the repo facet, in SQLite and the Postgres and ClickHouse stores, instead of T. Query.

Capture 9

  • # Added A tool output the agent cut before the model saw it is marked on its tool.end as payload.cut: Codex's head-and-tail cut of a long command or code-mode result (with the original token count, and jsonBroken when cut JSON no longer parses), and Claude Code's <persisted-output> preview of a result saved to a file (with its size and path). Backfilled sessions only for now; a hook-captured call keeps the hook's copy. Adapters.
  • # Added API errors Claude Code retried keep what the transcript says about them: the HTTP status, the error type and class (rate_limit, overloaded, …), the rate limit that was hit (seven_day, five_hour), when it resets, how long Claude Code waited and which attempt it was. Before, every one was a bare "api error", so a three-day weekly-limit stall looked like one transient error. Read API.
  • # Added The hook records the repo root, HEAD commit and branch on session-start and prompt events, read from .git files without running git (worktrees, submodules, packed refs, detached and unborn heads). A hook session's start commit, which eval new starts from, is now the HEAD when the session started. Before, ingest looked it up in the reflog and, when the reflog had nothing, took the HEAD at ingest time. CODING_SH_NO_GIT_HEAD=1 turns it off. Configuration.
  • # Added Before coding.sh init, a read now works with no setup: usage, sessions, show and the viewer import the Claude Code transcripts already on disk, so coding.sh usage shows your history straight away. Once the hooks are installed, live capture takes over and the transcripts are not re-read on every read. Adapters.
  • # Added coding.sh statusline prints a Claude Code status line — model, this session's cost, today's cost and the worst failure flag — from your stored sessions. statusline install wires it into the Claude Code settings.json and statusline uninstall restores the previous one byte-for-byte. Status line how-to.
  • # Added Claude Code's model_fallback and model_refusal_fallback transcript records (the main model was overloaded and Claude Code moved to --fallback-model, or a refusal went to another model) become a model.fallback notification with both models and the trigger, and tag the session model:fallback. Adapters.
  • # Changed Hooks append to one spool file per agent per UTC day (spool/<agent>/<day>.jsonl, continued in <day>.1.jsonl past 64 MB) instead of one file per hook call. A busy day used to leave about 11,000 files, each with an ingest cursor that every ingest and gc looked up. gc keeps the current day's file, and removes a deleted file's cursor instead of setting it to 0. Architecture.
  • # Fixed ingest and ingest --backfill no longer print a bare event count after their summary. ingest --json still carries the counts. CLI reference.
  • # Fixed A vendor-shaped key whose value is plainly made up, such as AKIAIOSFODNN7EXAMPLE, sk-ant-test-…, csh_ik_aaaa… or SECRETSECRETSECRET, is still redacted but counts as placeholder-key and no longer tags the session secret:exposed. Before, working on code with test fixtures, coding.sh's own included, flagged sessions as leaking credentials. Random-looking keys count as before. coding.sh ingest --rebuild re-counts sessions already stored. Privacy.

Cost 2

  • # Added A Claude Code backfill keeps Claude Code's own cost tally (the transcript's cost-state line: total cost, API time and cost per model) on the session's session.end as payload.reportedUsage, so you can check the computed cost against it. It is never added to the session's cost. Where cost comes from.
  • # Fixed usage TOK/TURN (tokensPerTurn) divides only top-level sessions' tokens by their turns. Before, subagents' tokens were divided by their parents' turns, so a row with heavy subagents, or a model only subagents ran, showed an inflated or impossible tokens per turn. Expensive sessions.

CI 1

  • # Added A GitHub Action in this repo (uses: jackulau/coding.sh@<ref>) installs coding.sh, runs one command such as eval run triage --yes or exp compare base head --margin 0.05, writes the report to the step summary and to one pull request comment that later runs edit, and fails the job when the command fails. eval run --summary <file> appends the report as Markdown, and the workflow eval init prints uses the action. Catch a regression in CI.

MCP 1

  • # Added A harness_audit tool and a trim prompt let your agent audit your setup and trim what goes unused: each memory file, AGENTS.md, rule and skill with the sessions that loaded and read it and its load tokens per session, unused ones first. With check: true it runs refine check on your uncommitted edits, and it returns the refine run command instead of running it. Shorter shared argument descriptions keep the tool list within its byte budget. Memory and instruction files.

Harness 1

  • # Added harness audit warns about Claude Code subagent files whose tools: frontmatter is a map such as edit: false, which leaves the subagent with no tools, and gives the disallowedTools: line to use instead. --json lists them under agentFiles. Explore guide.

Refine 2

  • # Added refine test --suite and refine run --suite take --reuse baseline (or both), copying an earlier round's finished runs of the unchanged base arm instead of running the agent again, so a long climb spends roughly half the agent sessions. Reuse is keyed by content like compare --reuse, copies count $0 toward --max-cost, and the round warns that the reused arm did not run interleaved; the verdict is unchanged because the copied runs are identical. Climbing on an eval suite.
  • # Fixed When a refine run --suite climb holds a cheaper or faster candidate whose quality is even on average but whose interval is too wide to confirm within --margin, the round now says the hold is a sample-size problem ("the quality interval is too wide to adopt it within the margin at N tasks: add tasks or trials") instead of implying the gain cost quality, and carries a warning that names the quality lower bound against the margin and the fix. The verdict is unchanged; only the explanation is clearer. How good is the hill-climb, really?.

Cache 2

  • # Added coding.sh usage --cache turns the cache rate into advice: per agent, model, day or repo it shows the hit rate, cache-read vs cache-write tokens, the read-to-write ratio (below 1:1 you wrote more cache than you read back), the prompt-cache breaks and what they cost, and names the break causes to change — compaction, a mid-session model switch, or an idle gap past the cache lifetime. Every number is a captured token count or the per-call-priced extra the breaks cost; there is no blended-rate guess. A session that wrote a cache of at least one block over three or more turns but read back fewer tokens than it wrote is tagged cache:low, and --where cache.breaks>0, cache.lost and cache.cost query and sort on the breaks (coding.sh sessions --where 'cache.breaks>0 sort:-cache.cost'). exp compare gains cache breaks / run and cache waste / run metrics so an A/B shows whether a setup change reused the cache better, and the viewer shows the read-to-write ratio next to a session's cache rate. Explore.
  • # Added Idle cache breaks say where the wait was, in stats.cacheBreaks.byIdle and as one usage --cache line each: a foreground tool call that ran past the cache lifetime (wait: keep foreground waits under the 5-minute subagent cache lifetime and poll in chunks), a subagent idle between turns (subagent), or the main session idle between turns (away: unavoidable while you are away; the 1-hour cache helps if you return often). Read API.

Site 1

  • # Changed The top bar links only Docs and Changelog. The comparison pages stay in the docs sidebar and the blog stays in the footer. Site.

Setup 4

  • # Changed coding.sh init ends by saying that recording starts with the next agent session, since an agent loads hooks when a session starts. Once capture is set up, an empty store no longer sends you back to init: show latest, sessions, status, improve, the MCP status and session_current tools, and the viewer ("Waiting for your first session") say to start a new agent session and to run coding.sh doctor if none shows up. Install
  • # Changed The installer run without a terminal (an agent's shell, CI) and without CODING_SH_YES=1 says no agent was set up and names coding.sh init --dry-run and coding.sh init --yes, instead of coding.sh, which only prints help there. Install
  • # Fixed coding.sh init started with npx coding.sh ends with npx coding.sh ui and npx coding.sh improve as the next commands. Before, it named coding.sh ui, which is not on your PATH until you install it. Install
  • # Fixed doctor no longer reports an agent as hooked while it also says the hook is missing. Each agent row names the settings file it read, and says when that file's hooks run another coding.sh home's hook.mjs (another HOME or CODING_SH_HOME); doctor --json lists the files under hookFiles. init no longer skips an agent's hooks because a project already holds hooks for another home. Troubleshooting.

Evals 2

  • # Changed compare --reuse baseline says in its help and docs that it copies the runs of an eval run too, so a suite's baseline from eval run is not paid for again in each comparison. Evals.
  • # Fixed exp show <id> takes the experiment id that eval run prints for a tasks suite and lists its runs per task with the agent's cost at API prices. Before, it said the experiment was not found. Evals.

Storage 1

  • # Fixed An ingest or transcript import that stores more than 10,000 events empties the index's write-ahead log before it returns, and so does every command when it closes the index. Before, with the viewer or another command holding the index open, a full import left index.db-wal as large as the data it wrote (3.8 GB next to a 1.5 GB index) until a later command happened to close it last. Architecture.

Proxy 2

  • # Fixed A model call that both coding.sh proxy and the agent's hooks or transcript logged shows once in show, show --follow, the viewer's timeline and the MCP session_get and session_current tools, as the proxy's copy with its call id, filled in with what only the other copy has. Before, each call printed twice, and MCP latency counted it twice. Capture with the proxy.
  • # Fixed Storing a call no longer slows down as the session grows. The proxy folds only the new events into the session row, instead of every event in the session, and writes the call's blobs in one batch. Late in a 1,000-call session a call now takes 9 ms to store instead of 26 ms. A call stored as message blocks reads back in about 2 ms instead of 9 ms. bench.mjs proxy-session measures the write against an older build. Capture with the proxy.

From CHANGELOG.md · RSS · All releases