Skip to content

feat(cli): make /fork spawn a background fork agent (separate from /branch session copy) #4757

@qqqys

Description

@qqqys

What would you like to be added?

Today /fork is just an alias of /branch — it copies the transcript into a new session that the user switches into (the classic session-fork delivered in #4158). Meanwhile the engine for a background fork agent already exists in the codebase but has no user-facing slash command.

I'd like a dedicated /fork <directive> command that spawns a background agent inheriting the full current conversation (system prompt, complete history, exact tool set, model, and prompt-cache parity) to work the directive, while the main conversation keeps going. When it finishes, its result is reported back into the current session.

This mirrors the behavior Claude Code shipped: /fork = background agent inheriting the conversation, /branch = copy-to-new-session. In our code that split would be:

  • branchCommand (packages/cli/src/ui/commands/branchCommand.ts) keeps the "copy into a new session" behavior, and drops altNames: ['fork'] so /fork is freed up.
  • A new forkCommand takes a <directive> and launches a full-tool background fork, parallel to how /btw already fires runForkedAgent in the background today.

Why is this needed?

The hard part is already built and tested — only the user-facing entry point is missing:

  • packages/core/src/tools/agent/fork-subagent.tsFORK_AGENT (tools: ['*'], session-level, "inherits full conversation context"), buildForkedMessages(), FORK_PLACEHOLDER_RESULT, and the isInForkExecution() recursive-fork guard.
  • packages/core/src/utils/forkedAgent.tsrunForkedAgent with a dual path: cache path (GeminiChat, single-turn, no tools — used by /btw) and full-tool path (AgentHeadless, multi-turn), plus CacheSafeParams for prompt-cache reuse.
  • packages/core/src/agents/background-tasks.tsBackgroundTaskRegistry (concurrency cap, lifecycle, task-notification reporting) and background-agent-resume.ts for re-attach across restarts.
  • packages/cli/src/ui/commands/btwCommand.ts — an existing precedent of a slash command that fires a background fork (fire-and-forget, non-blocking) and reuses CacheSafeParams so the fork sees the full system prompt + history.

So /fork would not introduce a new engine — it would expose the existing background-fork engine through a dedicated command, complementing the session-copy /branch (#4158) and the fork-subagent work (#3016).

Concretely it lets a user, mid-conversation, hand an independent task to a background worker (refactor, batch edit, investigate a bug) without interrupting the main thread or losing accumulated context.

Additional context

  • Suggested UX: /fork <directive> → returns immediately with a short fork name + id; the worker runs in the background and reports its result/summary back into the session on completion.
  • Suggested guards (mostly already present in the engine): refuse to fork before the first conversation turn; refuse while a response/tool call is in flight; bubble permission prompts back to the parent; recursive-fork rejection via isInForkExecution().
  • Suggested rollout: gate the new command behind a feature flag while it stabilizes.
  • Related (both closed): [P0] Fork Subagent / Fork Subagent #3016 (fork subagent engine), Add a user-facing way to fork from an existing session #4158 (session-copy fork, now /branch).

Metadata

Metadata

Assignees

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions