stepwise

Terminal-native tooling for the AI-agent session lifecycle.

Four tools: ccr finds the session, agx walks through what happened, sift snapshots what the agent did in each turn — and holdout verifies the change is actually correct. Shared design, narrow scope, zero hosted components.

The gap

An AI-assisted workflow leaves three artifacts behind on your disk, and no terminal-native tool to walk through any of them. The session files pile up across ~/.claude, ~/.codex, ~/.gemini and you lose track of which one has the thread you were on. Inside any given session, thousands of JSONL entries record user turns, tool calls, tool results — scroll them by hand and you miss the turn where the assistant silently changed strategy. The same session writes dozens of files, and git only shows you the commit-grain summary after everything has landed.

Stepwise is three narrow walkers over this lifecycle in the terminal — plus holdout, a verifier that checks the change the agent landed is actually correct. Both you and the agent reach for them: the human opens the TUI, the agent reaches for the same tools’ CLIs over subprocess to answer questions about — and check — its own work.

Why walk through

A session list sorted by recency surfaces the one thread worth resuming — and prevents you from starting a fresh session every time because the old ones are too hard to find. An agent session that ran fifty tool calls looks correct until you scrub to the one turn where the assistant changed direction. A green build looks correct until you walk the AI’s writes and find user_auth_v2.rs sitting next to user_auth.rs because the assistant created a sibling instead of editing the original.

These failures live below the grain where existing tools look. The patterns that surface them are recognizable — but only if the substrate is visible. A session walker, a turn walker, and a per-write walker make the substrate visible, one layer per tool.

Human judgment catches these — not because AI review is bad, but because recognizing them is what human judgment is for. Stepwise does not try to automate the recognition. It exposes the granular substrate cleanly enough that you can do it yourself — or ask the assistant to do it for you. Every stepwise tool is designed to be dual-addressed: a human-facing TUI and a scriptable CLI / JSON surface. When you ask “what did you change between turn 5 and turn 8?”, the agent shells out to sift state (planned), parses the diff, and answers in-line. The agent doesn’t have to scroll its own transcript; it has a walker too.

The trial Stepwise is running: can humans and agents keep control over an automated agentic workflow without paying its efficiency for it? Every design choice in these tools is a bet that the answer is yes — by putting the same review surface in reach of whichever principal is driving, at the grain where the failures actually live.

The tools

ccr

Walk through your CLI code session files — find the right one to resume, manage the rest.

ccr demo
  • Scans the session stores of Claude Code, Codex, and Gemini CLI and shows every session in a shared TUI ranked by last activity. Enter resumes the selected session in its original working directory, via the right CLI, with its original session id
  • Live-session detection via pgrep -f <session-id> before resume; a confirmation modal warns before spawning a second attachment that would interleave JSONL writes and corrupt the session
  • Press n to give any session a yellow nickname and b to bookmark it (★); both persist as sidecar files and are searched by / alongside title, cwd, tool, and content
  • Read-only at rest. ccr never modifies your session files; the only writes are the bookmark and nickname sidecars under ~/.ccr/
  • Unix-composable CLI surface for scripts and agents: ccr list, ccr path <id>, ccr show <id>, ccr export <id> --format json, and ccr stats (per-tool / per-project / 30-day histogram)
  • Cross-tool integration shipped today: press v on any session to open it in agx for step-through inspection. Feature-detected: missing agx → status-bar hint, not a failure
  • Pluggable backend trait (scan, resume, running, all_turns). New CLIs add as a backend module, not a rewrite

cargo install ccr · repo · crates.io

agx

Step through agent sessions — user turns, tool calls, tool results on a navigable timeline.

agx demo
  • Reads Claude Code, Codex CLI, Gemini CLI, OpenAI-compatible conversations, LangChain / LangSmith exports, Vercel AI SDK traces, and OpenTelemetry GenAI (JSON + binary protobuf) — zero instrumentation, format auto-detected
  • Bidirectional tool pairing: selecting a result shows the originating call input in one view. Branch / fork detection on resumed Claude Code sessions
  • Per-step token usage and USD cost estimation (hand-curated pricing table); side-by-side session diff (--diff-tui); corpus analytics across thousands of sessions with trajectory percentiles
  • Time-travel scrub bar, filter, search, bookmarks, per-step annotations (a / A), vim count prefixes, heatmap mode, opt-in semantic search (//query, embedding-search feature)
  • --live watches a session as it's written, with optional desktop notifications on error or idle (notifications feature); --scan-pii flags credentials/PII heuristically; --redact masks secrets before publishing
  • --diff compares two sessions; --summary prints a non-interactive digest; --export md|html|json|trajectory-openai for transcripts and RL / fine-tuning datasets
  • agx-core workspace crate factors the pure parsers / timeline / corpus / pricing out of the TUI; agx-py (pyo3) and agx-wasm workspace members target Python and WASM consumers. Not yet published — PyPI / npm wheel matrix is Phase 7.4b; today these build locally via maturin / wasm-pack

cargo install agx-tui · repo · crates.io

sift

Snapshots what the agent did in each turn — a queryable per-turn ledger for you and the assistant.

sift demo
  • Proposed: agent as primary user. Hooks silently record every Write / Edit / MultiEdit and Bash-tool mutation, keyed by the conversation turn that caused it. The design intent is that when you ask the assistant “what did you change in turn 7?” or “revert the third edit to src/auth.rs,” it runs the matching sift command and answers. The reframe is recent (April 2026); validation that assistants reflexively reach for these commands is pending dogfood (sift ROADMAP Phase 1.4).
  • Hook-integrated with Claude Code, Gemini CLI, and Cline. Content-addressed SHA-1 snapshots under .sift/sessions/<id>/. Current surface: sift list, sift log, sift d <id>, sift ok / sift undo, sift sweep, sift review TUI, sift state --at-turn N (reconstruct the file world at any point), and sift export --format json (the ledger as a versioned schema, sift_export_version: 1; sift/docs/export-schema.md).
  • sift accept --by-commit HEAD closes the git/sift grain gap — every pending entry whose post-state matches the commit auto-accepts, so you don’t approve twice.
  • Policy rules (.sift/policy.yml, glob today; regex planned Phase 2); strict mode blocks the next prompt until pending is cleared; sift sweep detects junk (duplicates, slop filenames, orphan markdown).
  • sift doctor (agx sibling detection) and sift fsck (ledger integrity + repair) ship today. An agent-facing command cookbook lives at sift/docs/agent-guide.md.

cargo install sift-tui · repo · crates.io — binary is sift (the sift crate name is taken, so it publishes as sift-tui)

holdout

Verifies the change is actually correct — an agent-facing oracle the candidate cannot read, edit, or memorize against.

holdout demo
  • The other three make the substrate visible; holdout makes correctness checkable. Grade a candidate (a refactor, an optimization, an agent’s edit) against a trusted reference on held-out or freshly-generated inputs it never saw — passing the visible examples isn’t enough. Reports a held-out score, the first divergence, and a scalar reward via exit codes + JSON, so an agent reads it back in-loop.
  • Surfaces: holdout recordgrade (sealed reference-capture refactor loop), verify (live differential over generator-produced inputs), properties (greenfield invariants, no reference needed), watch (a drift digest a human can interrupt mid-loop), procedure-aware gating, and a per-run wall-clock budget so a non-terminating candidate can’t hang the grader.
  • A verifier you cannot game. The oracle is held out-of-band (--seal / HOLDOUT_SEAL) so a workspace-writable agent can’t forge it; record --hash-expected stores only BLAKE3 hashes of the held-out answers, so reading the oracle reveals nothing. Honest threat model: robust against a non-adversarial-but-sometimes-wrong agent, not a determined adversary with full workspace access.
  • Validated on real bugs. 28/29 = 97% on the QuixBugs corpus. And on a real SWE-bench Verified instance (django__django-16485), holdout flags a patch SWE-bench’s own official oracle marks resolved — caught via a held-out UTBoost test the metric never ran. cargo install holdout; Unix-only candidate execution.

cargo install holdout · repo · crates.io

How they compose

Each tool is standalone. The utility compounds when they're used together on the same workflow — and, crucially, when different principals (you, the assistant, another agent) are coordinating over the same artifacts.

1. Walk through your sessions — ccr

You come back to work with 200+ old sessions scattered across ~/.claude, ~/.codex, and ~/.gemini. ccr lists them in one TUI, ranked by recency, with a preview of the last few turns. Enter resumes the selected session in its original cwd with its original session id (and warns first if pgrep finds the session already running). Nickname (n) and bookmark (b) the threads you keep returning to. Before the agent does anything: find the right session.

2. Run the agent

Claude Code / Codex / Gemini writes a JSONL session file as it works. Sift's hooks intercept each write and append to the .sift/ ledger with pre-snapshots, keyed by the turn that caused them.

3. Walk through the session — agx

You scrub the timeline in the TUI; or a reviewer agent runs agx --summary / agx --export json and reports which turn errored, where the assistant changed direction, and what it cost. From ccr’s session list, press v to hand the selected session straight to agx — no copy-pasting paths. Same tool, two entry points.

4. Snapshot what the agent did in each turn — sift

As the agent writes, sift records a pre/post snapshot per file per turn, keyed by the conversation turn that caused it. Today: walk the ledger in sift review, or query it via sift list / sift log / sift d <id> and accept / revert via sift ok / sift undo. sift sweep flags junk before the next commit. The commands ship today — sift list --path src/auth.rs --json + sift undo <id> back a request like “revert the third edit to src/auth.rs,” and after git commit, sift accept --by-commit HEAD settles the ledger against what was approved. What’s unvalidated is whether assistants reflexively reach for them (dogfood, ROADMAP Phase 1.4).

5. Verify the change is correct — holdout

Reviewing what the agent did tells you what changed; holdout tells you whether it’s right. Capture a trusted reference’s behavior (holdout record), then grade the agent’s version on held-out or freshly-generated inputs it never saw (holdout grade / verify) — a refactor that passes the visible examples but breaks behavior elsewhere is caught, with the first divergence localized and a reward the loop can act on. The oracle is held out-of-band, so the agent can’t read or forge it. On a real SWE-bench Verified instance, holdout flags a patch the official metric marked “resolved.”

Communication surfaces — how principals could talk through the tools

The design intent is that every stepwise tool is dual-addressed: a human-facing TUI and a scriptable CLI / JSON surface, so the same substrate supports three directions of communication. Ship status below each bullet distinguishes what works today from what’s still aspirational. Current gaps are tracked in docs/gaps.md.

human → agent
You ask in natural language; the assistant shells out to (today) sift list / sift log / agx --summary, and (planned) sift state --at-turn, and answers with grounded, byte-precise results. Depends on the assistant knowing to reach for these commands — agent-guides land as docs/agent-guide.md in each repo (shipped for agx and sift, pending for ccr) plus project-CLAUDE.md injection via each tool’s init (pending). Reflex-use by real assistants is unvalidated — dogfood pending.
agent → human
When the assistant reports “I changed 3 files in turn 7”, the claim should be backed by sift list --turn 7 rather than recollection. Today sift list + sift d + agx --summary / --export md|html|json all exist and return byte-precise results. What’s missing: structured error shapes at parity with text output ({"error": "no_entries_for_turn", "turn": 99}), so consumers never have to scrape human prose. Partially shipped.
agent → agent
A downstream review agent would consume agx --export json / trajectory-openai and sift export --format json — versioned schemas, zero instrumentation. Current status: agx JSON schema is documented with SemVer commitments (agx/docs/stability.md). sift’s schema is drafted but ships with Phase 1.7. No known downstream consumer exists yet — the stability commitment hasn’t been stress-tested. Kill criterion: sift drops the commitment if no consumer materializes in 6 months. agx-core is a workspace crate; agx-py / agx-wasm members exist but are not yet published to PyPI / npm (wheel matrix is Phase 7.4b).

Named integrations — when multiple tools are installed

Session hand-off (shipped — ccr v0.1.0, 2026-04-20)
Press v on any session in ccr to open it in agx for step-through inspection — the session file path and backend are passed through automatically. Feature-detected: missing agx → status-bar hint, not a failure. The first cross-tool integration in the suite that’s actually end-to-end working today; the others below are still planned.
Timeline jump (planned — sift Phase 1.3; session-level only until agx ships --jump-to <session>:<step>)
Press t on any entry in sift review to hand off to agx on the session’s transcript. Missing agx → install hint, not a failure. Blocker: agx does not yet serialize tool_use_id on StepKind::ToolUse, so step-level attribution has no join key.
Sift overlay in agx (planned — sift Phase 1.7 publishes the contract, agx downstream consumes)
agx consumes sift export --format json to decorate timeline steps with their accept / revert / edited status, and to diff the file world between any two agx-selected turns via sift state. Schema draft: sift/docs/export-schema.md.

Each integration is feature-detected at runtime. Missing sibling → status-bar install hint, not a hard failure. Install any subset; integrations light up for the ones you have. Subprocess boundary only — no shared Rust crate, no coordinated release train.

Shared principles

Terminal-native
No browser, no hosted dashboard, no web UI. Works over SSH, in containers, in air-gapped environments. Rust + ratatui + crossterm.
Dual-addressed (goal; partially implemented)
The intent is that every tool is reachable two ways — a human-facing TUI for walkthrough exploration, and a scriptable CLI with --json / --export so an agent can query it on your behalf. Today: ccr ships the TUI plus a scriptable CLI (ccr list / path / show / stats, and ccr export --format json); agx has --summary / --export / corpus --jsonl; sift has --json on several subcommands. Gaps: a versioned, stability-committed schema for ccr’s export, --json parity across all sift subcommands, structured error shapes, and an --ai-help flag per tool.
Zero instrumentation
Each tool reads artifacts that already exist. ccr reads the session stores your CLIs already write to. agx reads the JSONL your agent CLI already writes. sift reads file state the OS already tracks. No SDK changes, no wrappers, no proxies.
Zero telemetry
Nothing is sent anywhere. Sessions, snapshots, everything stays on disk.
Versioned export schemas (committed for agx; drafted for sift)
Anything meant to be consumed by a sibling or downstream agent is intended to be versioned. agx documents SemVer commitments for its JSON export, trajectory-openai export, and agx-core public API in docs/stability.md. sift’s sift_export_version: 1 schema is drafted but ships with Phase 1.7 / v0.5. ccr ships ccr export --format json but has not yet committed a versioned schema for it.
Cross-CLI
ccr resumes Claude Code, Codex, and Gemini CLI from a shared picker. agx supports Claude Code, Codex CLI, Gemini CLI, generic OpenAI-compatible, LangChain / LangSmith, Vercel AI SDK, and OpenTelemetry GenAI (JSON + binary protobuf) out of the box. sift supports Claude Code, Gemini CLI, and Cline via hooks. New CLIs add as a backend module (ccr) or parser module (agx, sift), not a rewrite.
Narrow scope, deep engineering
Each tool does one thing. ccr doesn’t try to replace your assistant’s own --resume; it just lists what’s resumable across tools. agx doesn’t try to replace Langfuse’s team analytics. sift doesn’t try to replace git. Where the scope ends, the tool stops.
Sub-grain
They operate below the layer where existing tools stop. Per-CLI session finders work one tool at a time; ccr walks across them at the session-store grain. Git works at commit grain; sift at per-turn sub-commit grain. Dashboards work at session grain; agx at step grain.

Install

cargo install ccr        # Claude Code · Codex · Gemini session picker
cargo install agx-tui    # agent-session timeline viewer (binary: agx)
cargo install sift-tui   # per-turn file-write snapshot oracle (binary: sift)
cargo install holdout    # agent-facing verification oracle (binary: holdout)

Each binary keeps its short name (ccr, agx, sift, holdout); agx and sift publish under -tui suffixes because the bare crate names were taken, while ccr and holdout publish under their own names. Rust toolchain: 1.88+ for ccr, 1.85+ (edition 2024) for agx, 1.75+ for sift, 1.74+ for holdout. Platform coverage: Linux, macOS, Windows (ccr); Linux, macOS (agx, sift, holdout).

Status