Feature: CLI-invocable session branch (claude branch <id> --name <n>) / make --fork-session safe for live sessions

Open 💬 0 comments Opened Jul 2, 2026 by matthewfrazier

Use case

I run long-lived orchestration sessions in my homelab, one tmux window per Claude Code session. A recurring need: take a LIVE session that has accumulated a lot of useful context and branch it into a new terminal — carry the full context into a sub-project session, guide that branch independently, and eventually merge a summary back into the parent (the workflow sketched in #32631 and #69712).

/branch has exactly the right semantics for this — it snapshots the current conversation into a new session and leaves the original untouched. But it is only invocable from inside the running session's UI. There is no way to trigger it from a script or another terminal, which is where orchestration tooling lives.

Current behavior

  • claude --resume <id> --fork-session works fine when <id> is not open anywhere. But when the session is currently open in another terminal, the new process exits almost immediately — in my repro the tmux window closes in under 4 seconds (interactive mode, v2026.x). No error I can capture, just gone.
  • There is no lock or coordination between processes: #19364 (session lock file) was closed not-planned, and #48270 documents that concurrently resuming the same id fragments the transcript. #69364 notes the live-session registry (~/.claude/sessions/<pid>.json) now exists but resume doesn't consult it.
  • Even when the fork doesn't die, #44684 showed --fork-session reads the last-flushed JSONL rather than the live in-memory conversation, so forking a live session from outside is unreliable by design today.

My workaround is cp of the transcript .jsonl to a new uuid and claude --resume <new-uuid>. It works, but it depends on the internal file layout that the docs explicitly warn changes between releases — not something I want load-bearing in my orchestration scripts.

Proposed behavior

Either of these would solve it:

  1. A claude branch <session-id> [--name <name>] subcommand that snapshots the target session's transcript to a new session id and prints it (or opens it). This is what /branch already does internally; done as copy-on-branch it is inherently safe against a live holder because nothing writes to the original.
  2. Make claude --resume <live-id> --fork-session detect the live holder (the ~/.claude/sessions/ registry already has pid + sessionId) and fork from its current state — ideally asking the live process to flush first — instead of silently exiting.

Option 1 also composes nicely with the SessionStart source:"branch" hook I filed separately (#73053), giving scripted branches the same observability as interactive ones.

Related issues

  • #32631 — conversation branching spec (/merge, /tree); this is the CLI entry point for that model
  • #69712 — branches in agent view + merge-back path
  • #19364 — session lock file (closed not-planned)
  • #48270 — concurrent resume of one session id fragments the transcript
  • #69364 — resume doesn't check the live-session registry
  • #44684 — --fork-session forks last-flushed JSONL, not live state
  • #67870 — fork-as-new-session from a checkpoint (in-session ask; this issue is the from-outside counterpart)

Environment

Claude Code CLI on Linux, interactive tmux-based workflow, v2.x current.

View original on GitHub ↗