Persist terminal launch context for worktree drafts#1518
Persist terminal launch context for worktree drafts#1518juliusmarminge wants to merge 2 commits intomainfrom
Conversation
- keep terminal drawer attached to the created worktree for first-send draft setup scripts - flush local thread and draft state updates before opening terminals
|
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 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)
Comment |
- launch project setup scripts from the server after worktree prep - keep setup terminal state tied to the thread and surface activity events - add coverage for setup runner and bootstrap turn flow
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix prepared a fix for the issue found in the latest run.
- ✅ Fixed: Stale "preparing-worktree" phase shows misleading UI state
- Removed the stale 'preparing-worktree' send phase, its derived
isPreparingWorktreeflag, and all UI references since worktree preparation now happens server-side and the phase no longer corresponds to any client-side work.
- Removed the stale 'preparing-worktree' send phase, its derived
Or push these changes by commenting:
@cursor push 88bafdb9f0
Preview (88bafdb9f0)
diff --git a/apps/web/src/components/ChatView.logic.ts b/apps/web/src/components/ChatView.logic.ts
--- a/apps/web/src/components/ChatView.logic.ts
+++ b/apps/web/src/components/ChatView.logic.ts
@@ -75,7 +75,7 @@
return previewUrls;
}
-export type SendPhase = "idle" | "preparing-worktree" | "sending-turn";
+export type SendPhase = "idle" | "sending-turn";
export interface PullRequestDialogState {
initialReference: string | null;
diff --git a/apps/web/src/components/ChatView.tsx b/apps/web/src/components/ChatView.tsx
--- a/apps/web/src/components/ChatView.tsx
+++ b/apps/web/src/components/ChatView.tsx
@@ -658,7 +658,6 @@
const selectedModelForPicker = selectedModel;
const phase = derivePhase(activeThread?.session ?? null);
const isSendBusy = sendPhase !== "idle";
- const isPreparingWorktree = sendPhase === "preparing-worktree";
const isWorking = phase === "running" || isSendBusy || isConnecting || isRevertingCheckpoint;
const nowIso = new Date(nowTick).toISOString();
const activeWorkStartedAt = deriveActiveWorkStartedAt(
@@ -2573,7 +2572,7 @@
}
sendInFlightRef.current = true;
- beginSendPhase(baseBranchForWorktree ? "preparing-worktree" : "sending-turn");
+ beginSendPhase("sending-turn");
const composerImagesSnapshot = [...composerImages];
const composerTerminalContextsSnapshot = [...sendableComposerTerminalContexts];
@@ -4006,11 +4005,6 @@
{activeContextWindow ? (
<ContextWindowMeter usage={activeContextWindow} />
) : null}
- {isPreparingWorktree ? (
- <span className="text-muted-foreground/70 text-xs">
- Preparing worktree...
- </span>
- ) : null}
{activePendingProgress ? (
<div className="flex items-center gap-2">
{activePendingProgress.questionIndex > 0 ? (
@@ -4115,11 +4109,9 @@
aria-label={
isConnecting
? "Connecting"
- : isPreparingWorktree
- ? "Preparing worktree"
- : isSendBusy
- ? "Sending"
- : "Send message"
+ : isSendBusy
+ ? "Sending"
+ : "Send message"
}
>
{isConnecting || isSendBusy ? (| setComposerCursor(0); | ||
| setComposerTrigger(null); | ||
|
|
||
| let createdServerThreadForLocalDraft = false; |
There was a problem hiding this comment.
Stale "preparing-worktree" phase shows misleading UI state
Low Severity
beginSendPhase("preparing-worktree") is still called on line 2576 when baseBranchForWorktree is truthy, but the actual worktree preparation was moved to the server (as part of the bootstrap payload). The derived isPreparingWorktree flag (line 661) gates UI elements like a spinner (lines ~4009, ~4118). For server threads needing a worktree, this phase persists through the async auto-title and persistThreadSettingsForNextTurn calls before being overwritten by beginSendPhase("sending-turn") on line 2692, showing a "preparing worktree" indicator when the client is actually doing unrelated work.



Summary
Note
Medium Risk
Changes the thread start flow to allow server-side bootstrapping (thread create/worktree create/setup script launch), which affects orchestration dispatch ordering and terminal/script side effects. Risk is mitigated by added unit/integration tests, but failures could impact first-send behavior for worktree/local drafts and PR worktree prep.
Overview
Server now owns first-send bootstrapping for worktree/local drafts.
thread.turn.startaccepts an optionalbootstrappayload (create thread, create worktree, run setup script), andwsServerexecutes these steps before dispatching the real turn-start, recording setup-script activities and cleaning up the thread on bootstrap failure.Setup scripts are centralized and triggered from backend worktree creation paths. Adds
ProjectSetupScriptRunner(reads project scripts from orchestration snapshot, opens a deterministicsetup-*terminal withT3CODE_PROJECT_ROOT/T3CODE_WORKTREE_PATH, writes the setup command) and wires it into server layers;GitManager.preparePullRequestThreadcan now accept an optionalthreadIdto launch setup when a new PR worktree is created (and logs/continues on setup launch failure).Web client stops creating worktrees/running setup locally and preserves terminal context.
ChatViewreplaces client-side worktree creation + setup execution withbootstrapturn-starts, adds a per-thread terminal launch context (persisted interminalStateStore) so the terminal drawer uses the intended cwd/worktree env, and updates PR worktree prep to passthreadIdwhile leaving setup execution to the server; tests were updated/added to cover these flows.Written by Cursor Bugbot for commit 2535cf1. This will update automatically on new commits. Configure here.
Note
Move worktree creation and setup script execution from client to server on first message send
thread.turn.startcommand with an optionalbootstrappayload containingcreateThread,prepareWorktree, andrunSetupScriptfields.git.createWorktree, updating thread metadata, running the project setup script via a newProjectSetupScriptRunnerservice, and emittingsetup-script.*activities before dispatching the turn.terminalLaunchContextByThreadIdmap in the terminal state store persists terminal CWD and worktree path received from server-emitted terminal events, so the terminal drawer opens with the correct context after server-side setup.GitPreparePullRequestThreadInputandgitPreparePullRequestThreadMutationOptionsnow accept an optionalthreadId, whichGitManager.preparePullRequestThreaduses to trigger setup script execution when creating a new PR worktree.preparePullRequestThreadare swallowed (logged as warnings only), and bootstrap failures cause newly created threads to be deleted server-side.Macroscope summarized 2535cf1.