Skip to content

MCP create_worktree: parity with the human New Worktree flow (PRs, prompts, agent, model) - #64

Merged
frenchie4111 merged 7 commits into
mainfrom
mcp-create-worktree-from-pr
May 25, 2026
Merged

MCP create_worktree: parity with the human New Worktree flow (PRs, prompts, agent, model)#64
frenchie4111 merged 7 commits into
mainfrom
mcp-create-worktree-from-pr

Conversation

@frenchie4111

@frenchie4111 frenchie4111 commented May 23, 2026

Copy link
Copy Markdown
Collaborator

Closes #74.

Summary

Brings the MCP create_worktree tool to parity with the human New Worktree screen and adds two knobs to both surfaces: agent kind and per-tab model override.

What changes

1. MCP create_worktree can check out a PR — same path as the UI's "Open PR as worktree" flow.

  • New prNumber param. When set, Harness fetches refs/pull/<n>/head into a local branch named after the PR head (with -pr-<n> suffix if taken locally) and routes through WorktreesFSM.runPendingPR.
  • branchName and prNumber are now alternatives — pick one. prNumber wins when both are set.
  • Server-side validation: positive-integer prNumber, 422 for PR-not-found, 502 for other GitHub/git failures.

2. Configurable PR review prompt — surfaced in three places.

  • New prReviewPrompt setting with a sensible default (full settings slice + reducer test + persistence).
  • Settings → Worktrees → "PR review prompt": editable global default.
  • New Worktree screen → "Open PR" section: textarea pre-filled with the default; edits are one-shot for that creation.
  • MCP create_worktree with prNumber and no explicit initialPrompt falls back to the configured default. Pass an empty string to suppress.

3. Per-creation agent + model overrides (closes #74).

  • New agentKind (claude|codex) and model (free text) params on create_worktree.
  • New Worktree screen gets a compact "Agent / Model" row under the per-mode input. Teleport mode pins to Claude (codex has no resume-by-session-id today).
  • model is persisted as a new optional field on TerminalTab, so a pinned model survives reloads. Both xterm tabs (agent:buildSpawnArgs) and json-claude tabs (via buildClaudeLaunchSettings + manager lookup on wake) honor it.

Test plan

  • npm run typecheck clean
  • npx electron-vite build clean
  • npx vitest run — 1163 tests pass (added: 4 MCP bridge tests for the new params, 2 launch-settings tests for modelOverride, 1 reducer test for prReviewPromptChanged)

Manual smoke (each verified in dev or pending):

  • "Create a worktree to review PR #N" via MCP → lands on the PR head branch, PR review prompt is sent to Claude
  • "Create a worktree on a new branch X" via MCP → still works
  • Bad PR number (#99999) → error surfaces cleanly through the MCP response, no stuck pending entry
  • New Worktree → Open PR: review-prompt textarea is editable, agent + model row visible
  • New Worktree → Fresh: agent + model row visible; flipping to Codex changes the spawned tab
  • MCP create_worktree { agentKind: "codex", model: "gpt-5" } → tab spawns codex with --model gpt-5
  • Settings → Worktrees → "PR review prompt": editing the textarea + Save persists across restart

Out of scope

  • teleportSessionId for MCP create_worktree — last remaining gap with the human UI. Deferred.
  • Letting the MCP swap agent/model on an existing worktree's tab. This PR only covers the create-time override.

🤖 Generated with Claude Code

frenchie4111 and others added 4 commits May 22, 2026 17:00
Lets an agent spin up a worktree checked out at a PR's head in one tool
call — same path as the UI's "Open PR as worktree" flow. The control
server's POST /worktrees handler now accepts `prNumber` and routes to
WorktreesFSM.runPendingPR, which fetches refs/pull/<n>/head into a local
branch named after the PR head (with -pr-<n> suffix if taken). The MCP
tool schema documents both paths; either branchName OR prNumber is
required, and prNumber wins when both are set.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a `prReviewPrompt` setting (default ships with a sensible review
prompt) and exposes it three ways:

- Settings → Worktrees → PR review prompt: textarea + save/reset to
  manage the global default.
- New Worktree → Open PR section: textarea pre-filled with the default;
  edits are one-shot for that creation and don't affect the global value.
- MCP `create_worktree` with `prNumber`: an omitted `initialPrompt`
  falls back to the configured default. Pass an empty string to
  explicitly suppress.

Threading: extends `runPendingPR` (FSM) + `runPendingPRWorktree`
(renderer-facing backend method) with `initialPrompt?`, persists the
setting in `config.json`, seeds it through `buildInitialAppState`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tucks the textarea in next to "Share Claude Code permissions" — both
are global "default behavior" settings most users won't touch, so the
section now leads with the per-creation knobs (merge strategy, scripts)
and ends with the defaults.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Closes #74.

A worktree's first agent tab now picks up two overrides set at creation
time:

- **agentKind**: claude or codex. Defaults to settings.defaultAgent.
- **model**: free-text string passed as --model. Defaults to
  settings.claudeModel / settings.codexModel.

Both surface through:

- **New Worktree screen** — a compact "Agent / Model" row sits under
  the per-mode input area. Teleport mode pins to Claude since codex
  has no resume-by-session-id analog today.
- **MCP create_worktree** — new `agentKind` and `model` params.
  Both validated server-side; agentKind must be claude|codex.

Persistence: model lives on TerminalTab as a new optional field so it
survives reload — agent:buildSpawnArgs honors tab.model over settings,
and the json-claude path threads the override through
buildClaudeLaunchSettings → --model.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@frenchie4111 frenchie4111 changed the title create_worktree MCP tool supports prNumber for PR-review worktrees MCP create_worktree: parity with the human New Worktree flow (PRs, prompts, agent, model) May 25, 2026
frenchie4111 and others added 3 commits May 25, 2026 08:54
Auto-expands when either field has a non-default value (so a typed
model or a Codex pick isn't hidden), and shows a compact
"(Claude · sonnet)" hint next to the collapsed header.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the Current/Legacy optgroup pattern from Settings → Agent →
Claude/Codex so the per-creation override picks from the same list of
known models the rest of the app uses (no more free-typing a string
that might not even exist). Switching agent kind also clears the model
so a stale Claude id can't be sent as Codex's --model flag.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Self-review caught that TerminalTab.model was being dropped on every
persistence cycle:

- PersistedTab schema didn't list it, so the type system silently
  accepted serializers that omitted it.
- treeToPersistedNode (src/main/index.ts) built the persisted object
  from an explicit field list — model wasn't there.
- hydratePersistedTree (src/main/panes-fsm.ts) rebuilt TerminalTab
  from the same explicit list, so even a model that made it to disk
  would be dropped on read.

Adding model to all three closes the loop. The pattern matches every
other persistent tab field (agentKind, sessionId, cwd, command — none
of which have round-trip tests either, so this follows existing
conventions: the type system + explicit field lists are the contract).

Also:

- Trimmed duplicate "override the default…" comments that just
  restated the field types. Kept the canonical one on the
  TerminalTab.model slice field.
- Threaded agentKind + model through the host's runPendingPRWorktree
  broadcast payload so its shape stays in sync with the new-branch
  path's deps.broadcast call. Today the FSM already applies them via
  onWorktreeCreated, but a future consolidation refactor would
  silently lose data otherwise.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@frenchie4111
frenchie4111 merged commit c41cf6f into main May 25, 2026
1 check passed
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.

[Feature] MCP doesnt support passing a model or agent

1 participant