Make conversation forking one step across entry points
Fork now runs immediately from the message footer, message or empty-space context menu, chat header, /fork, command palette and ⌥⌘Y. Every entry uses AgentForkDestination.default (currently Right); Option-click and the separate Fork to… item expose the seven existing destinations. A refused host open selects and focuses the fork. Hand off to… has its own menu group and explicitly retains its existing tab placement.
And then forking. Man, there's too many fucking steps here. We need to make it nicer, more ergonomic, more intuitive. There's too many steps to, like, go through it. It's too much of a hassle. We don't like it.
The fork request still uses the parent's harness, model, mode and working directory. The single default remains .right pending #26582's session placement rule. AgentTabs+Fork.swift is unchanged, preserving #26093's subagent placement work.
| Entry | Before (reported steps) | After |
|---|---|---|
| Hover Fork | 2 | 1 |
| Right-click Fork | 2 | 1 |
| Header ⋯ Fork | 2–3 | 1 |
/fork | 2 | 1 |
| Palette | 4 | 1 |
| ⌥⌘Y | 1 | 1 |
After counts mean one activation of the exposed Fork command, excluding opening the surrounding menu/palette. Before counts are from the approved request, not instrumented timing.
Validation: the default-placement regression fails on the original base with eight expected assertions (receipt 603d4530b51c3e4aea0f6cc1). The original implementation passed six native suites (receipt a469aea5b93c51ad0b292eba). Final verification and the repaired crash regression are recorded below.
Real-app captures use the same completed fake-harness conversation on base and head. They run through WebKit's native click path because the capture driver's Chromium click did not supply the gesture ticket needed for folder trust. The product's engine default is unchanged. Reference: Claude desktop session overflow menu, using separate command groups; private reference imagery is not attached.
| Before | After |
|---|---|
![]() | ![]() |
![]() | ![]() |
The context-menu test budget changes from 12 to 13 only for agent-chat and terminal-selection menus, accommodating the separately exposed Fork and Fork to… commands; all other menus retain 12.
A real header click created a distinct right-side session and the debug readback reported composer_focused: true and focus: composer. Result capture.
Risk: changes default fork placement from a tab to the shared right destination. No new timers, observers or animation loops; the weak-self destination-menu task finishes when its native menu closes. No per-token transcript work added.
Current verification:
- Full web checks, native static delta gate with full ancestry, popup suite, both Fork browser regressions, and fork unit tests pass after integrating the current footer layout. The four previously failing gallery states also pass, as do the three header states.
- App compile at final head
5af5233f9cc56c41b2200b6b216550dbbdcd7725passes (receiptc55c15744a991c241575dfd4, 82 seconds). Final integrated web, static and browser checks also pass. Independent Astra review returned SHIP at that exact head. - Independent review found two modifier-loss paths. Press-drag-release fails in Chromium and WebKit before and passes after. The escaped native popup regression fails before and passes after. Both paths now preserve the release modifiers.
- Native receipt
1aa9603a0419e35c2b19348fat exact final head5af5233f9cc56c41b2200b6b216550dbbdcd7725passed all four focused suites: AgentForkMenuTests (1), AgentPaneForkOwnTabTests (5), ForkConversationTests (10), and ActionSurfaceParityTests (12 reported, 2 skipped). Process exited 0. The earlier signal 11 is repaired by merged #27385, integrated at this head. - The remaining native static CI red is the unchanged HomeChatColorsPanel.swift and HomeChatColorsView.swift SwiftUI imports, reproduced identically on base in comparison run. The final head's static job has only those two findings; its other checks and the changed-file static gate pass.
The fork request and default destinations were verified through real-app interaction above. The modifier repairs have remote browser regressions; they have not yet been recaptured in the native app. The diff stays below 800 changed lines.
Agent session: agent session



