Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Forking and Switching Conversations

A conversation is a UUID-identified ref with an optional name and turn tip, and its own history, draft, and worktree. /refs lists live refs with their full UUID, activity, tip, and branch (or (base main) before the first commit). Unnamed refs display as <unnamed>; select them with /switch FULL-UUID. /switch NAME resolves exact names case-insensitively before exact full UUIDs. It opens the target while idle; missing or locked targets error.

/fork <initial prompt> branches from the current turn. /new <initial prompt> starts a root conversation without inherited history. Neither takes a name: Heph sends the prompt to the title role (the default fast tier), requires a one-to-three word result (ASCII letters or digits, separated by whitespace or hyphens), lowercases and hyphenates it, and adds -2, -3, and so on if needed. Invalid output, including more than three words or a generic placeholder, falls back to a bounded prompt-derived name. The title call is recorded on the new first turn. Both start from the current conversation's base branch (Branches).

The new ref becomes active and its initial prompt starts immediately. /fork waits for naming before creation. /new saves a prompt-derived name before starting its first turn, without waiting for the title provider. A failed or cancelled title request keeps that name; improvement retries once on resume. Explicit naming wins over a late automatic result. Naming changes no UUID, lease, worktree, history, routing, or publication branch.

Forking into another terminal

Start a separate process manually with an existing name or full UUID:

heph -C /path/to/project --fork SOURCE-UUID 'try another approach'

The child starts at the source's latest completed accepted checkpoint. A running turn or pending review is excluded; its live files are never copied. No safe checkpoint means refusal, not a new root as a fallback. The child inherits context, accepted private work, base, routing, and task settings, but not the source's publication branch, draft, jobs, pending review, or session approvals. Startup flags can override inherited routing and mode.

Omit the prompt to wait for input. The first submission names the child locally from its own prompt, not inherited prompts, before background title improvement. Its title request is recorded on that child's turn. The source remains running, and tmux is not required. Interactive recovery runs only for the selected leased conversation. Automatic tmux creation and a dedicated session switcher are not yet available.

Renaming the active conversation

/rename fix-flaky-tests
/rename

The first sets the active conversation's name explicitly; the second asks the title role (the default fast tier) for a 1-4 word kebab-case slug. It sees only the most recent 3,000 characters of your prompts, in chronological order, not assistant responses, tool results, skill payloads, or shell output before the prompt. The goal is to name what you want to accomplish.

An explicit name must match [a-z0-9][a-z0-9-]* and be unused by any other conversation, including archived ones. For automatic names, a conflict goes back to the model with a request to distinguish the name. Heph makes at most three requests, then adds -2, -3, and so on as a last resort. Each completed naming request is recorded on the latest turn. Missing user prompts, unusable model output, or a provider failure leaves the old name intact; use an explicit name or retry.

An explicit rename can also name an empty ref; bare /rename needs stored user prompts. An explicitly named empty ref keeps its name on first submission.

Rename affects only the active conversation. It waits for the turn and any pending review to finish. While naming, input remains editable and the conversation scrollable, but sending prompts and other session commands wait; help, sidebar controls, and quitting remain available. History, draft, armed skills, worktree path, and publication branch stay unchanged. The status bar, /refs, and the existing worktree's .heph-ref marker reflect the new name.

Naming a turn

The commands below name turns three ways: by place, #12, counting from the conversation's first turn as #1; by id; or by the first six or more characters of an id, as long as they name only one turn. A prefix that names two is refused with both listed. Ids and prefixes can name discarded turns from this conversation; #N names only its current or forward chain.

What /commit would publish: /diff

/diff

shows the difference /commit would publish now, against the conversation's branch (or its base branch before the first commit), open in the conversation like the model's diff tool. It starts with the turns it spans:

3 turns since heph/wrap-lines was last advanced (3f2a9c1)
  #12 01a0efa6  wrap the input prompt at word boundaries
  #13 01a0f201  the pager still splits mid-word
  #14 01a0f9b3  add the tests

/diff --stat shows that and the summary only. /diff #13 shows what one turn accepted, and /diff #13 src/pager.rs that turn's change to those paths. Where the branch changed the same lines as the conversation, /diff shows the paths and the conversation's displaced text instead of refusing. Work the worktree holds that no review has decided is not in /diff; /review shows that, and /diff says when there is some.

Going back: /back and /forward

/back        # one turn
/back 3      # three

moves the conversation back and puts the worktree's files back to the accepted files of the turn it lands on. The next turn is told which turns were rolled back, and the model is sent nothing of them. Your repository and checkout do not change; nothing private had reached them. If a turn you went back over was already published with /commit, heph says so: /back changes the conversation, not the branch, and reverting that commit is yours to do with git.

/back 3 --keep-code moves only the conversation. The worktree keeps the newer files, and /review (or the next turn) offers the difference as hunks, so you can undo the conversation and keep some of the code.

/forward undoes a /back: all the way, or /forward 1 one turn at a time, with the same --keep-code. Once a new turn starts, the conversation has forked there and /forward has nowhere to go; the rolled-back turns are still there by id for /diff and /restore.

Getting files back: /restore

/restore #12
/restore #12 src/pager.rs

puts the files as they stood after turn 12, all of them or the paths named, back in the conversation's worktree without moving the conversation. Then /review shows the difference as hunks: what you accept becomes the conversation's accepted state, which the next turn and the next /commit see.

/back, /forward, and /restore wait while a turn runs or a review is pending, and save the worktree's files before replacing any of them. Nothing they do loses work.

Background multi-ref runners, arbitrary-turn forks, archive, and /tree are still to come (What Is Not Here Yet).