MCP create_worktree: parity with the human New Worktree flow (PRs, prompts, agent, model) - #64
Merged
Merged
Conversation
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>
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #74.
Summary
Brings the MCP
create_worktreetool 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_worktreecan check out a PR — same path as the UI's "Open PR as worktree" flow.prNumberparam. When set, Harness fetchesrefs/pull/<n>/headinto a local branch named after the PR head (with-pr-<n>suffix if taken locally) and routes throughWorktreesFSM.runPendingPR.branchNameandprNumberare now alternatives — pick one.prNumberwins when both are set.prNumber, 422 for PR-not-found, 502 for other GitHub/git failures.2. Configurable PR review prompt — surfaced in three places.
prReviewPromptsetting with a sensible default (full settings slice + reducer test + persistence).create_worktreewithprNumberand no explicitinitialPromptfalls back to the configured default. Pass an empty string to suppress.3. Per-creation agent + model overrides (closes #74).
agentKind(claude|codex) andmodel(free text) params oncreate_worktree.modelis persisted as a new optional field onTerminalTab, so a pinned model survives reloads. Both xterm tabs (agent:buildSpawnArgs) and json-claude tabs (viabuildClaudeLaunchSettings+ manager lookup on wake) honor it.Test plan
npm run typecheckcleannpx electron-vite buildcleannpx 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):
#99999) → error surfaces cleanly through the MCP response, no stuck pending entrycreate_worktree { agentKind: "codex", model: "gpt-5" }→ tab spawns codex with--model gpt-5Out of scope
teleportSessionIdfor MCPcreate_worktree— last remaining gap with the human UI. Deferred.🤖 Generated with Claude Code