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).