Example

Branch the session tree

Decide between /tree, /fork and /clone, and see a session as a tree where an abandoned branch is never sent and never gone.

A stored session is a tree of entries linked by id and parentId, and the current position is the leaf. /tree moves inside that tree, /fork starts a new session from an earlier prompt, and /clone copies the active branch into a new session. The trace below is illustrative; the claims it draws are the ones branching.test.ts asserts on 1.0.4, with /fork and /clone on the shipped binary.

Choose the command

Action Result Use it when
/tree moves within the current session file related alternatives belong together
/fork new session from an earlier user prompt the alternative becomes separate work
/clone copy of the active branch in a new session you want a separate copy of current state

A tiny branch, as entries

The shared history is linear until question B is edited. Submitting the edited prompt creates a sibling — two children of the same parent, one session file. The abandoned branch is not sent, and is not gone:

{"type":"session","version":3,"id":"sess-a1","timestamp":"2026-10-01T09:00:00.000Z"}
{"type":"message","id":"a-user","parentId":null,"timestamp":"2026-10-01T09:00:01.000Z","message":{"role":"user","content":"question A"}}
{"type":"message","id":"a-bot","parentId":"a-user","timestamp":"2026-10-01T09:00:02.000Z","message":{"role":"assistant","content":"answer A"}}
{"type":"message","id":"b-user","parentId":"a-bot","timestamp":"2026-10-01T09:00:03.000Z","message":{"role":"user","content":"question B"}}
{"type":"message","id":"b-bot","parentId":"b-user","timestamp":"2026-10-01T09:00:04.000Z","message":{"role":"assistant","content":"answer B"}}
{"type":"message","id":"b-edit","parentId":"a-bot","timestamp":"2026-10-01T09:00:05.000Z","message":{"role":"user","content":"question B, edited"}}
{"type":"branch_summary","id":"sum-1","parentId":"a-bot","timestamp":"2026-10-01T09:00:06.000Z","summary":"Summary of the abandoned path: asked B and C.","fromId":"b-bot"}

b-user and b-edit hang from the same parent, a-bot. A navigation with summarize enabled wrote the branch_summary entry just below them — the trace compresses two of the test’s interactions into one file. parentId is where you land, fromId is the leaf you left, the abandoned entries stay in the tree, and getTree() reports both branches under their shared parent. Labels are bookmarks: appendLabelChange puts a label on an entry, getTree() shows it, and setting the label to undefined clears it.

What /tree does to a selection

You select Result
a user message its text returns to the editor; the leaf moves to that message’s parent
an assistant response (or other entry) Pi continues after it with an empty editor

Mechanism and limitations

Documented: the entry tree (id/parentId — the shared session-file format is Chapter 27’s declaration), the /tree selection rules, labels, and get_fork_messages / fork / clone as RPC commands. Observed: branching.test.ts runs the harness and the shipped binary with the faux provider — navigateTree moves the leaf, edited prompts make siblings in one file, abandoned branches are absent from requests but present in session entries, the summary entry’s fromId/parentId point to the right ends, getTree() has two children, and over RPC a fork starts a new session file whose session header carries parentSession — the only durable record of where it came from — while clone copies the active branch.

The trace is a drawing, not a transcript: ids are shortened and fields trimmed. A /fork’s new file has no record of what it left — no branch summary exists there — so only /tree can hand you a summary of the abandoned path. This page shows the storage model around a model, not a real model choosing a branch.

Full source and test .

Understand this example

Copy this prompt into your AI tool. No code runs here.

Apply this example

Copy this prompt into your AI tool. No code runs here.