Add worktree handoff and status tools to the t3-code MCP server#3754
Conversation
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
One convention issue: WorktreeOperationError copies the underlying cause.message into a detail field and builds its message from it, instead of preserving the real failure as cause and deriving the message from structural attributes. The sibling previewAutomation.ts errors already follow the expected pattern (cause: Schema.Defect() plus bounded diagnostics). See inline comment.
Posted via Macroscope — Effect Service Conventions
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a7bf0f58f3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. This PR introduces new worktree handoff and status MCP tools with significant new capability, complex concurrency handling, and modifications to credential/session lifecycle. Two unresolved review comments identify potential race conditions in the binding logic that warrant human review. You can customize Macroscope's approvability policy. Learn more. |
There was a problem hiding this comment.
One finding on the new worktree handlers: WorktreeOperationError requires a cause, but the project-not-found path has no underlying failure and fabricates an Error only to satisfy that field.
Posted via Macroscope — Effect Service Conventions
juliusmarminge
left a comment
There was a problem hiding this comment.
please target against #2829 which introduces and reworks the MCP services a bit
769a4e7 to
5c63efe
Compare
5c63efe to
633ba7a
Compare
There was a problem hiding this comment.
One Effect service-convention violation: the new WorktreeMcpService retains a standalone WorktreeMcpServiceShape interface instead of defining the service interface inline in the Context.Service declaration. See details inline.
Posted via Macroscope — Effect Service Conventions
633ba7a to
a3cf90a
Compare
a3cf90a to
ee25215
Compare
Status update: I am working on this and have a test article. It is a might bit more difficult in v2 than v1 due to some issues I will enumerate when ready for review. |
0ca5533 to
a85b089
Compare
fc7b7a4 to
9dbf702
Compare
There was a problem hiding this comment.
One Effect service-convention finding on the new WorktreeMcpService. This was raised on an earlier revision of this PR; the file has since been rewritten (squashed into a single commit) but the same violation persists, so I'm re-surfacing it on the current diff.
Posted via Macroscope — Effect Service Conventions
9dbf702 to
4e26d31
Compare
|
@juliusmarminge Retargeting is complete: the PR is rebuilt on #2829, based on Three things to know when reviewing:
CI: Check is green. The 4 Test failures are pre-existing on the base branch (the userdata-v2 config tests and two claude replay fixtures). Smaller notes are in the updated PR description. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4e26d31738
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
189c4c7 to
0a22804
Compare
1e58e65 to
a286c60
Compare
0a22804 to
4e87631
Compare
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want fixes drafted automatically? Bugbot Autofix can create code changes for findings. A team admin can enable Autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 4e87631. Configure here.
| resolved.threadId === threadId && | ||
| resolved.providerInstanceId === providerInstanceId | ||
| ) { | ||
| return { mcpCredentialId: existing.providerSessionId, issued: false }; |
There was a problem hiding this comment.
Reused tokens lack worktree capability
Medium Severity
The prepareMcpSession logic reuses existing MCP credentials, but capabilities are fixed at issuance. This means sessions reusing older credentials will lack newly introduced capabilities (e.g., worktree), resulting in capability_denied errors during operations like workspace handoffs.
Reviewed by Cursor Bugbot for commit 4e87631. Configure here.
| ); | ||
| return heldElsewhere | ||
| ? Effect.void | ||
| : clearMcpSession(threadId, mcpCredentialId); |
There was a problem hiding this comment.
Stale map blocks credential revocation
Medium Severity
On session release, heldElsewhere skips revoking an MCP credential when any other live session entry maps the same thread to the same credential id, even if that thread is detached everywhere. After a workspace handoff, an older and a newer provider session can each retain that stale map entry; when both release, each side skips revocation and the bearer token can remain valid in the registry indefinitely.
Reviewed by Cursor Bugbot for commit 4e87631. Configure here.
| commandId: CommandId.make(part("command", "worktree-handoff")), | ||
| continuationCommandId: CommandId.make(part("command", "worktree-continuation")), | ||
| continuationMessageId: MessageId.make(part("message", "worktree-continuation")), | ||
| }; |
There was a problem hiding this comment.
Handoff command IDs not stable
Medium Severity
Worktree handoff mints fresh random UUIDs for the metadata-update and continuation commandId/messageId on every call instead of a session-scoped stable id derived from the handoff inputs. Orchestrator command receipts dedupe by commandId, so a retried MCP handoff after a successful bind cannot replay the prior receipt and surfaces already_in_worktree rather than an idempotent success.
Triggered by learned rule: Scope idempotency keys by session and operation type
Reviewed by Cursor Bugbot for commit 4e87631. Configure here.
4e87631 to
f0589f4
Compare
4dffcad
into
pingdotgg:t3code/codex-turn-mapping


What Changed
Closes #3753. Reworked on top of #2829 per review: the tools are implemented against the orchestration-v2 services and this PR now targets
t3code/codex-turn-mapping.Adds two tools to the
t3-codeMCP server, following the conventions of the v2 orchestrator toolkit (a service behind thin handlers, one tagged failure with acodeunion,failureMode: "return",t3_-prefixed names, branded timeline labels):t3_worktree_handoffcreates a worktree and re-points the calling thread at it.branchis required;baseRef,startFromOrigin,path(absolute only), andrunSetupScriptbehave as before. New:continuationPromptqueues a message as the thread's next turn, because on v2 aworktreePathchange detaches the live provider session and ends the current turn. The queued run is promoted when the detached run terminates and starts inside the worktree with the conversation preserved. The handoff pre-checks branch existence so the common collision fails with an actionableinvalid_requestinstead of an opaque git error, and rolls back the created worktree on any failure before the binding commits.t3_worktree_statusreports the thread's binding (attached or not, worktree path, branch, workspace root, the server's startFromOrigin default).The last commit is a
ProviderSessionManagerchange this feature exposed (details in Notes): per-thread MCP credentials are now stable across detach and re-attach, with revocation moved to session release and to a new terminal-detach path for thread archive/delete.Tested with unit tests over
WorktreeMcpService(49) andProviderSessionManager(25), an HTTP-level test driving the production MCP layer end to end, and manually on Windows: full ClickUp task workflow with handoff from origin, automatic continuation in the worktree, and working MCP tools in the resumed session.Notes for reviewers
The
ProviderSessionManagercommit deserves close review: long-lived provider processes (the codex app-server) build their MCP client once per conversation and keep the credential they started with, so the previous revoke-on-detach broke tool auth for any thread that detached and re-attached (workspace handoff, and plausibly runtime-mode changes on shared sessions). Credentials are now reused while they resolve, revoked at session release with a guard for live replacements, and revoked immediately on archive/delete via arevokeMcpCredentialflag on the detach effect.The handoff-induced run interruption surfaces in the UI as "Run interrupted by user". A distinct label for server-initiated interruptions ("workspace changed") would read better; that attribution lives in the UI/orchestrator layering, so it is not touched here.
thread.metadata.updatehas no conditional form, so a binding committed concurrently from the UI between the handoff's recheck and its dispatch is overwritten (last write wins). The recheck plus per-thread serialization narrows this to a very small window; closing it needs aworktreePathprecondition at the dispatch layer. One Macroscope thread tracks this and is left open deliberately.v2 has no worktree cleanup on thread delete (the v1 reactor's equivalent does not exist), so the tool description states worktrees are not removed automatically.
CI: Check is green. The 4 Test failures are pre-existing on the base branch (
config.test.tsexpects pre-userdata-v2paths at lines 128/198, and thetool_call_read_only_on_request/tool_call_restricted_granularclaudeAgent replay fixtures drifted); none of the failing files are in this diff.Why
See #3753: an agent can create a worktree from its shell, but the thread binding lives in T3 Code's orchestration state and nothing agent-reachable can update it, so agent-driven worktree setup dead-ends. The MCP server is the only channel T3 Code exposes to the agent, so this is the only place the capability can live.
Checklist
Note
High Risk
Large changes to MCP authentication and credential revocation on detach/re-attach, plus git worktree creation and thread metadata updates that can leave disk state if rollback paths fail.
Overview
Agents can move a thread into a new git worktree via
t3_worktree_handoffand read binding state witht3_worktree_status, registered on the MCP HTTP server behind a newworktreecapability (included on newly issued MCP sessions).WorktreeMcpServicedrives handoff: validates repo/branch, optionally bases the branch from origin, creates the worktree, updates thread metadata, optionally runs the project setup script, and can queue acontinuationPromptfor the next turn after the workspace change detaches the live session. Failed pre-bind steps roll back the worktree; concurrent handoffs per thread are serialized.ProviderSessionManagerno longer revokes MCP credentials on every detach. Credentials are reused across re-attach when still valid, revocation is scoped per credential id (with reservations for in-flight opens), workspace-change detaches keep tokens alive, and archive/delete detaches setrevokeMcpCredentialso tokens are revoked immediately.Reviewed by Cursor Bugbot for commit f0589f4. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Add worktree handoff and status tools to the t3-code MCP server
t3_worktree_handoff,t3_worktree_status) that let agents hand a thread off to a git worktree and query its attachment state via the MCP HTTP server.WorktreeMcpServicewhich orchestrates worktree creation, thread binding, optional setup script execution, and continuation message scheduling; concurrent handoffs for the same thread fail with a typedhandoff_in_progresserror.worktreeMCP capability derived from the newALL_MCP_CAPABILITIESconstant inMcpInvocationContext; all newly issued sessions include it automatically.ProviderSessionManager: credentials are now reused across attaches when still valid, revocation is scoped to specific credential ids, andthread.archive/thread.deletedetaches now carryrevokeMcpCredential: trueto trigger immediate revocation.Macroscope summarized f0589f4.