Skip to content

feat(native): fork a session, here or into a worktree - #801

Merged
omartelo merged 1 commit into
mainfrom
feat/native-fork
Oct 17, 2026
Merged

omartelo merged 1 commit into
mainfrom
feat/native-fork

Conversation

@omartelo

Copy link
Copy Markdown
Collaborator

Brings fork to the native window, redesigned rather than ported: the web's "Fork to worktree…" always made a worktree, and forking in the same checkout did not exist.

What changes

  • Card menu: Fork ▸ Here / Worktree…, for the providers whose CLI branches a conversation (Claude Code, Codex, opencode). The other five keep a disabled row reading "resume only"; a shell, or a card with no conversation yet, gets no row.
  • Here adds a card right under the original, in its checkout, whose first start is terminal.Start with fork (--fork-session, codex fork, opencode --fork). A one-shot queue in terminals carries the parent conversation to that start, as the web's fork queue did.
  • Worktree… opens the existing worktree dialog in a fork mode: titled "Fork X to a worktree", based on the original's branch, carrying its uncommitted work by default, with no worktree rows to reopen (that would open their session, not fork) and no confinement box (a fork follows its provider's rung, like a delegated session).
  • Naming: the original's label without its trailing number, then the first free number above the original's own (auth-refactor → auth-refactor 2; auth-refactor 2 → auth-refactor 3, or 4 if 3 exists).
  • Lineage: a fork mark in the title row and "Forked from X" in the card tooltip, from a new sessions.forked column (schema version 10). The origin columns could not tell a fork from a delegate or a subagent card. The window writes the mark with the row, so the card draws it on its first frame. Carried through park/reopen. api-types.ts mirrors it as optional; the web does not read it.
  • Before forking, the conversation is checked with ResumeAvailable, so a pruned one is refused with a sentence instead of dying in a new card or worktree.

Strings in all seven native locales; CHANGELOG entry; README provider row updated in every language.

Verification

  • New tests: store (forked round-trips and survives a reopen, delegates and subagents stay unmarked), native (forkLabel, canFork, placedAfter, the menu entry per provider, takeCard keeping fork requests).
  • Backend go vet / go test ./..., native gofmt / go vet / go test ./... green. Frontend not run locally (only an optional field in api-types.ts; no node_modules in this worktree).
  • Real native window on Xvfb with Claude Code, backend and window built from this branch: Here spawned claude --resume <id> --fork-session under the original with the mark and tooltip; Worktree… created the worktree, carried the uncommitted file and spawned the fork inside it. The rig caught two bugs fixed here: takeCard dropped the new fields, and the mark landed only after a reload when written at spawn.

The card menu gains Fork > Here and Fork > Worktree... for the providers
whose CLI branches a conversation (Claude Code, Codex, opencode); the
others keep a dead row saying they only resume. Here opens the copy in a
new card right under the original, in its checkout; Worktree... opens the
worktree dialog in a fork mode, on the original's branch with its
uncommitted work coming along. The copy is named after the original with
the next free number above its own, and wears a fork mark with "Forked
from" in its tooltip.

A new sessions.forked column (schema version 10) tells a fork apart from a
delegate or a subagent card, which carry an origin too; the window writes
it with the row.
@omartelo
omartelo merged commit 8dafa93 into main Oct 17, 2026
10 checks passed
@omartelo
omartelo deleted the feat/native-fork branch October 17, 2026 17:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant