feat: continue a terminal session with another agent, or fork it
Move a session's work to a different agent, or clone it, without retyping the context.
Two actions behind the fork icon in a terminal pane header, and the same two on the CLI:
- Continue with another agent starts a fresh session of a different harness seeded with the source terminal's recent output. For a session that is wedged, out of context, or turned out to be the wrong tool for the job.
- Fork session asks the provider for a native clone of its own session and leaves the original running.
superset agents create --workspace W --agent codex --from-terminal T
superset agents create --workspace W --agent claude --fork-session S
Where the context comes from
The obvious source is terminal.snapshot, and it is the wrong one. It reads term.buffer.active, and the alternate screen every TUI agent renders to keeps no scrollback, so maxLines is inert there and anything the program has already drawn over is unrecoverable.
Measured against a real pager paging 300 known lines:
| source | alt-screen terminal | normal-buffer shell |
|---|---|---|
terminal.snapshot(800) | 392 chars, 23 history lines | 4991 chars, 300 lines |
terminal.transcript | 4478 chars, 253 history lines | 4993 chars, 300 lines |
Worse than truncation: once the pager exited and restored the normal screen, the snapshot held none of the 300 lines while every byte had already gone down the pty.
So terminal.transcript reads session.retained instead, the 2 MB ring of raw pty output the host already keeps for every session whether or not a client is attached. It sanitizes and bounds host-side, so the dialog and --from-terminal hand over identical bytes for a terminal by construction rather than by two copies of a budget. It falls back to the visible screen only when the ring is empty, and reports which it used. terminal.snapshot keeps its "current screen" meaning for superset terminals read.
Where a harness keeps its own conversation store, that is preferred over the pty replay: structured turns beat a reconstructed screen. Lookups resolve against the agent's pinned CLAUDE_CONFIG_DIR / CODEX_HOME rather than the default, so an agent on a second provider account is not mistaken for a missing session.
Forking
forkArgs on host agent configs (migration 0028_funny_gideon.sql) plus forkSessionId on agents.run. The CLIs disagree on where the id goes, so FORK_SESSION_ID_TOKEN marks the position; absent the token the id is appended. Settings gains a Fork args field per agent, and installs predating the migration are backfilled on read, but only for configs still identical to their preset.
Six presets ship native fork commands. Each was read out of that CLI's own docs, then run: a codeword said to the source session, the fork launched, the fork asked what the codeword was.
| harness | fork command | verified |
|---|---|---|
| claude | --resume {sessionId} --fork-session | KESTREL-8801 |
| codex | fork {sessionId} | MARLINSPIKE-4417 |
| opencode | --session {sessionId} --fork | HALYARD-2290, new session titled "(fork #1)" |
| grok | --resume {sessionId} --fork-session | BOWSPRIT-6135 |
| pi | --fork {sessionId} | TILLERMAN-7756 |
| droid | --fork {sessionId} | not verified, see gaps |
A fork is refused up front only when the harness's own session store says the source session is gone. "Unknown" still launches: only a project directory that exists and lacks the file is evidence of absence, and harnesses that keep sessions server-side always answer unknown.
Verified in the running app
Full journey filmed over CDP with real mouse and key input, in the workspace under test: a codeword said on camera, scrolled off screen on camera, then repeated by the target agent after the handoff. 4712 frames, 2m39s, zero console errors. Evidence lives in artifacts/cdp/terminal-session-handoff-e2e.{mp4,png,json} locally and is deliberately not committed.
An earlier 45s film was cut and kept under artifacts/cdp/superseded/: it showed the menu working but never proved context actually crossed, which is the only claim worth filming.
Process-level proof, all with cwd inside the worktree under test:
- the handoff launched
codex … -- Continue the work from a previous Claude terminal session.carrying the seeded exchange - the fork launched
claude --resume 7457e428-… --fork-session, where that id is the source session - the source
claudeprocess kept running on its original argv throughout
The CLI path was exercised against the same host with a scoped dev key (since revoked), including its error paths, and terminal.transcript was driven through the desktop renderer's own client stack.
Known gaps
- droid fork is unverified. Its docs and
--helpboth carry--fork, and the arg is wired the same as the five that were proven, but the account'sdroid whoamireturns 401 here so no fork was ever launched. Treat that row as read from docs, not tested. - Committing with New tab placement is untested; the toggle is.
- Terminals with no agent binding still get no menu. #7010 (already merged, and in this branch) makes harnesses bind at launch rather than on their first native session event, which is what left Codex without a fork icon; a plain shell still has nothing to fork, though its transcript would hand off fine.
For anyone who ran this branch before today
The migration was renumbered from 0026 to 0028 when main claimed those numbers. A dev host DB that applied the old 0026 already has fork_args_json and will fail 0028 with duplicate column name. Drop the column, or delete the dev host DB and let it rebuild.
https://claude.ai/code/session_01BBtBeYRY9H5dPCbcfW5yTD
Summary by cubic
Lets you move a terminal session's work to another agent, or clone it, without retyping the context. Adds Continue with another agent and Fork session actions behind the fork icon in the terminal pane header, plus matching CLI flags (--from-terminal, --fork-session, --context-chars) for unattended runs.
Terminal context
- New
terminal.transcriptendpoint replays the host's retained PTY ring through an emulator so redraw-heavy TUI streams recover as readable text, preferring the harness's own conversation store where one exists. Harness lookups resolve against the agent's pinned env and answer "unknown" for uninspectable config dirs. - The host sanitizes and bounds text so desktop and CLI hand over identical bytes; the plan window widens until the budget fills, cuts land at line boundaries with a notice, and the daemon's replay buffer (512 KB) survives self-upgrades. Sampling copes with wrapped double-width text.
- Falls back to the visible screen only when the ring is empty;
terminal.snapshotkeeps its "current screen" meaning. - The handoff dialog fetches the transcript on open, treats failed/empty/loading as distinct states, and keeps Continue disabled until real context is in hand. CLI can cap with
--context-chars.
Forking
- Adds
forkArgsto host agent configs (migration 0026) andforkSessionIdtoagents.run;{sessionId}marks the id's position (now substituted within arguments), appended when absent. - Presets ship native fork args for six harnesses; installs predating the migration get them backfilled on read only when configs are untouched.
- Passing both
resumeSessionIdandforkSessionIdis an explicit conflict. Settings gains a Fork args field. - Forks are refused up front when the harness's own session store reports the source session is gone; only a visible project directory makes an absent session file evidence, otherwise "unknown" still launches. The opencode lookup uses better-sqlite3, which runs under Electron's Node.
- CLI rejects combining
--from-terminalwith--promptor another session operation; the pane menu renders only for agent-bound terminals.
Summary by CodeRabbit
-
New Features
- Continue terminal sessions with another agent or fork them into a new session.
- Open handoffs and forked sessions in a split pane or new tab.
- Capture recent terminal context with configurable size limits.
- Configure fork arguments for built-in and custom agents.
- Use CLI support for terminal handoffs, session forks, and context limits.
-
Bug Fixes
- Improved validation for conflicting resume, handoff, and fork options.
- Improved transcript handling for alternate-screen applications and agent history.
- Clearly distinguish empty or unavailable terminal context before continuing.