Skip to main content
Glama

pleach

Branch tracking, visualization, and merging for Claude Code sessions.

Claude Code can fork a conversation (/branch, --fork-session) but keeps no record of what forked from what, shows no tree anywhere, and has no way to bring two divergent branches back together. pleach adds those three things.

Unofficial third-party tool. Not affiliated with or endorsed by Anthropic. It reads session transcripts already on your disk and shells out to your own claude binary. It never touches credentials and never bundles Claude Code source.

* 9703da58 (leaky-bucket) 2026-08-01
| * a7aa4a1d (sliding-window) 2026-08-01
|/
| * 36a05f40 (token-bucket) 2026-08-01
|/
* 97c6581b 2026-08-01

If you can read git log --graph, you already know how to read this.

Requirements

Python 3.9+ and an installed claude. No dependencies, no build step, no pip install — it runs from a checkout. (Claude Code 2.x ships as a native binary and brings no Node runtime, which is why this is Python.)

Related MCP server: Session Buddy

Learn it in five minutes

Three commands, modeled on git:

pleach log              # the session graph for this project — works instantly,
                        # even on history from before you installed pleach
pleach branch 9703da58  # fork a session; prints the `claude --resume` command
pleach merge a7aa a1d3  # reconcile two branches via a background agent

That's the whole core. Ids take any unambiguous prefix, like git SHAs. Typing bare pleach prints this cheatsheet.

Two optional extras that pay for themselves:

pleach name 9703da58 leaky-bucket   # labels show in the graph, like branch names
pleach init --write                 # install hooks: new forks tracked live
                                    # (backs up settings.json; --uninstall reverses)

There is no index to build and no scan step — every command refreshes lineage for the current project automatically, the way git just reads your repo.

The interactive graph

pleach ui

Full-screen interactive graph in the spirit of VS Code's git-graph panel, keys modeled on tig/lazygit: j/k move between nodes, enter toggles the detail panel, n names, b branches, s opens a branch summary in a pager, m marks a node and m on a second node merges the pair (dry-run or dispatch), r prints the resume command, a toggles all projects, q quits.

The VS Code extension takes the same keys, so the two surfaces are one set of muscle memory: j/k (or arrows) move, g/G jump to the ends, enter resumes, b branches, n renames, s summarizes, o opens the transcript, m pins a session as the other half of a merge, a toggles all projects, / focuses the filter, and ? lists the lot.

Claude Code's TUI has no extension point for custom panes, so ui can't render inside a session — run it in a terminal pane next to one, exactly how the VS Code git graph sits next to the editor. Inside a session, /pleach (from the plugin) is the same functionality with Claude as the interaction layer: it shows the graph and resolves "branch the top one as X" or "merge those two" into the right commands for you.

Commands

Command

What it does

ui

Interactive full-screen graph — navigate, name, branch, merge.

log (alias tree)

Git-style session graph. --all for every project.

branch <id>

Fork a session (a file copy — no API call).

merge <a> <b>

Reconcile two branches via a background agent. --dry-run first.

name <id> <label>

Label a session; labels show in the graph.

summary <id>

What happened in a branch, distilled. Cached.

grep <term>

Full-text search across transcripts. --all for every project.

export <id>

Render a transcript as readable markdown. Local, free.

show <id>

Parent, branch point, children, entry count.

merges

Merges run here, and whether the agent has finished.

status

What's tracked, what's live, what's configured.

list

Flat table of tracked sessions.

scan

Full rescan of every project (per-project refresh is automatic).

prune

Drop stale index entries; --snapshots also deletes merge bases.

doctor

Environment checks; --test-synthesis verifies merge-base support.

mcp

Run the MCP server (stdio) — see below.

Give Claude itself the graph (MCP)

pleach mcp is a zero-dependency MCP server over stdio. Register it once:

claude mcp add --scope user pleach -- python3 /path/to/checkout/bin/pleach mcp

From then on, Claude — in any terminal session and inside the official VS Code extension's panel — can query your session graph directly. Ask it "which of my branches dealt with the flux bug?" and it can call pleach_grep, read the graph with pleach_log, pull a branch digest with pleach_summary, or hand you the exact claude --resume command via pleach_show.

Tools exposed: pleach_log, pleach_show, pleach_grep, pleach_export, pleach_summary, pleach_branch, pleach_name, pleach_merge_plan, pleach_merge, pleach_status. Reads are free and local (summaries cost a cached haiku call). The only side-effectful tools are pleach_branch (copies a transcript, same as pleach branch) and pleach_merge (dispatches a background merge agent); pleach_merge_plan is the dry run and its tool description tells the model to use it first.

Remove with claude mcp remove pleach.

How merging works

A merge is not a replay of tool calls. It is:

  1. Reconstruct the shared context. Find the last entry both branches share — their branch point — and rebuild the conversation as it stood there.

  2. Summarize each branch separately. A cheap model reads each full branch and reports what was tried, what worked, what failed, what was decided.

  3. Seed a new agent from the shared context and hand it both summaries to reconcile.

Step 3 runs as a background session (claude agents to watch it), so it doesn't disturb the session you're in. The merge agent is read-only by default: it is given no tools at all, since it is pure synthesis over two summaries already in its prompt. Pass --allow-writes if you actually want it editing files.

Merge bases are reused when the branch point hasn't moved, so re-merging the same pair doesn't accumulate transcripts. pleach prune --snapshots --yes removes the ones pleach created.

Use --dry-run to see the merge base, its confidence, and the exact prompt without dispatching anything.

Because the agent runs in the background, pleach merges says which merges have finished, and pleach export <merge-session> reads the reconciliation. The extension does both for you: the sidebar tracks a dispatched merge from "running" to "ready" and offers a Read the merge button.

What's verified

Built against measured behaviour, not assumptions. The experiments and results are in PLAN.md §8, and the whole pipeline has been run end to end against real sessions:

  • Fork copying (§8.2). Forks preserve entry uuids exactly while rewriting the sessionId field — the property that makes retroactive inference work.

  • Inference (§8.9). 19 edges inferred from real history, each re-derived independently from the raw transcripts: 19/19 correct parent and exact branch point.

  • Live fork detection (§8.10). Confirmed against a real fork with hooks installed.

  • Merge-base synthesis (§8.6). Confirmed: Claude Code resumes a transcript pleach wrote. Merge bases are exact, and pleach branch costs no API calls.

  • The merge pipeline. Dispatched, ran, and produced a real reconciliation seeded from the correct shared context.

pleach doctor --test-synthesis re-checks the synthesis property on your machine. If a future release breaks it, merges fall back to forking the live parent and say so with a drifted warning rather than silently using a wrong base.

Still untested: the interactive /branch and /fork TUI commands. All fork testing used the --fork-session CLI flag. scan catches those either way.

What it refuses to do

The lineage index is the only place fork edges, names, and merge history live — none of it can be rebuilt by rescanning transcripts. So pleach never replaces a file it could not read:

  • An unreadable ~/.pleach/lineage.json is recovered from lineage.json.bak (written before every change) or, failing that, left exactly as it is while the command exits 3. It is never overwritten with an empty index.

  • An unreadable ~/.claude/settings.json stops pleach init entirely, with the same exit code. --write and --uninstall both back it up first, and --uninstall leaves the file alone if none of pleach's hooks are in it. (A UTF-8 BOM counts as readable — it used to count as "empty".)

Transcript text is untrusted input: it is whatever a session contained, including anything an agent quoted from a web page. Text sent to a model is fenced with a per-call nonce and the rules are restated after the content, so a transcript that contains instructions gets reported rather than obeyed — verified end to end against a deliberately poisoned transcript. Merge agents still run with no tools unless you pass --allow-writes.

How branch detection works

Claude Code has no fork hook, and it signals forks differently across versions — pleach handles both.

On recent versions (measured on 2.1.219), SessionStart announces the fork explicitly with source: "fork", but reports the child id and never names the parent. The parent is recovered by prefix-matching the child's transcript against its siblings, which is exact because a fork's transcript literally begins with its parent's.

On older versions (2.1.207), SessionStart instead reports the parent with source: "resume" — indistinguishable from a plain resume — and the child only appears on UserPromptSubmit. There the signal is the mismatch between the two events.

This is why init installs three hooks rather than one: on both paths a single SessionStart hook detects nothing. Details in pleach/track.py.

One consequence worth knowing: the child's transcript is not on disk when SessionStart fires, so parent resolution is retried on later events and falls back to scan. A missed hook degrades to inference, never to a lost branch.

Edges found live are marked observed. Edges reconstructed by scan are marked inferred — those pick the closest plausible ancestor, so in rare cases (a branch taken immediately, before the parent did further work) they may attribute to a grandparent rather than a parent. A shallower tree, not a wrong one.

Layout

bin/pleach            entry point
pleach/track.py       hook handler — the fork-detection state machine
pleach/infer.py       retroactive lineage inference
pleach/transcript.py  JSONL parsing, prefix comparison, branch points
pleach/mergebase.py   shared-context reconstruction
pleach/merge.py       the merge pipeline
pleach/graph.py       tree building and rendering
test/smoke.py         offline end-to-end tests

Run the tests with python3 test/smoke.py. They use a throwaway config dir and never touch your real ~/.claude.

Storage

Everything pleach records lives in ~/.pleach/ (override with PLEACH_HOME). The only thing it ever writes into ~/.claude/projects/ is a reconstructed merge base, which is tagged and removable with pleach prune --snapshots --yes. It never modifies an existing transcript.

License

MIT.

Install Server
A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
2Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Cross-agent artifact workspace with provenance across Claude Code, Codex, Cursor, LangGraph.

  • Give your AI agent a persistent map of your project's structure, dependencies, and bugs.

  • Persistent context for Claude. Your AI always knows your projects and next actions across sessions.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/foudrayelias-ALPHA/pleach'

If you have feedback or need assistance with the MCP directory API, please join our Discord server