Leg

History: every conversation on this machine

leg history lists the coding-agent conversations on this machine in one place: the sessions Leg started itself, and the ones Claude Code, Codex, Grok, Antigravity and GitHub Copilot CLI keep in their own stores, whether or not Leg was involved. leg worktrees does the same for checkouts. The board's fourth ledger cell, Conversations, is the same index with a search box.

Nothing moves. Claude keeps Claude's history where it always was, Codex keeps Codex's, and so on. Leg reads those stores, writes one index file of its own, and points back.

What you get

leg history                          newest first, every agent, 50 rows
leg history --provider codex,grok    one or more agents
leg history --repo leg               a repository by name, or by path
leg history --search "drainer"       title, repo, branch, folder or id
leg history --managed | --external   only what Leg started, or only what it found
leg history --live                   only conversations with a process still on them
leg history --all --json             everything, as JSON
leg history show <id>                one conversation: where, when, its last messages, whether it can continue
leg history continue <id>            start leg <agent> on it, in its folder, supervised like any other session
leg history refresh [--full]         re-stat every store now; --full drops the index and re-reads everything
leg history providers                the support matrix below, from the code that implements it
leg worktrees [--repo <path>] [--json] [--no-dirty]

An id is <provider>:<the agent's own id>, for example claude:0fc54b51-6cfa-40cf-9823-a5a36d1ca3f3. A unique prefix of the agent's id, four characters or more, is enough: leg history show 0fc5. A Leg session id (s-2026…) works too.

A row says which agent, whether the conversation is leg (Leg started it, its session id follows) or external (found in the agent's store), whether it is live (a process is still on it, where the agent leaves a marker), the repository and branch, when it was last active, and its title.

Support matrix

Verified against the stores on a real machine on 2026-09-16 (Claude Code 2.1.273, codex-cli 0.154.0, Grok CLI with chat_format_version 1, Antigravity 1.2.0, Copilot CLI 1.0.80). Each provider's file header in src/history/providers/ names the exact files and fields it reads.

provider list title branch live marker transcript continue store read
Claude Code yes custom title, else the AI title, else the first prompt yes sessions/<pid>.json, pid checked yes claude --resume <id> ~/.claude/projects/*/<id>.jsonl, history.jsonl, sessions/
Codex yes session_index.jsonl, else the first prompt yes (the git block) no yes codex resume <id> ~/.codex/sessions/YYYY/MM/DD/rollout-*.jsonl, session_index.jsonl, history.jsonl
Grok yes generated_title, else the summary, else the first prompt yes active_sessions.json yes grok --resume <id> ~/.grok/sessions/<cwd>/<id>/summary.json, chat_history.jsonl, prompt_history.jsonl
Antigravity yes annotations/<id>.pbtxt, else the first prompt no no no (SQLite) agy --conversation <id> ~/.gemini/antigravity-cli/history.jsonl, annotations/, presence/
Copilot CLI yes the session name yes no yes no ~/.copilot/session-state/<id>/workspace.yaml, events.jsonl

Extra logins made with leg accounts add are scanned too (their CLAUDE_CONFIG_DIR, CODEX_HOME or GROK_HOME directory); a row from one carries the account name.

Continue is offered only where the installed CLI's own help documents resume-by-id, quoted in the provider file. Antigravity keeps its transcripts in SQLite, which Leg does not open, so it lists and continues but cannot show messages. Copilot is discoverable without being an agent Leg supervises, so it lists and shows messages but cannot be continued through Leg; that split (a provider Leg can find versus an agent Leg can run) is deliberate, and the registry in src/history/index.mjs is separate from src/adapters/.

Looked at and left unsupported, each for one reason: Cursor (its chat lives in state.vscdb, SQLite), opencode (opencode.db, SQLite), Pi (documented under ~/.pi/agent/sessions/, not present on the verification machine, the cwd encoding undocumented), Hermes, aider and Windsurf (no session store).

How discovery works

Worktrees

leg worktrees merges three sources into one list: what git worktree list says for every repository Leg knows (from its sessions, its cards and the discovered conversations), the worktrees Leg's sessions and cards recorded (even when git no longer lists them), and the worktrees discovered conversations ran in. Each row carries the repository, branch, whether the directory exists, how many files are uncommitted (git status, on up to 40 checkouts per call; null past that or when --no-dirty), who owns it (the checkout itself, a Leg session, a Leg card, or nobody Leg knows), which conversations point at it and when the last one was active, orphaned (a .leg-worktrees/ directory no session or card records), stale (exists, no live owner, nothing touched it in 14 days) and missing (git or a record names it, the directory is gone).

It is a view. Removing a worktree is still leg sessions rm, leg card rm or the board's Remove, which keep their guards.

Privacy

Adding a provider

One file in src/history/providers/, registered in src/history/index.mjs:

test/history-fixture.mjs shows the shapes each existing provider expects; a new provider gets a builder there and a row in the matrix above.


Leg is commercial, source-available software by Wes Sander. The source you run ships in the npm package. Questions or a refund: legcli@practicalsystems.io.