From a81f93aa05159523a9ab0b3214b1e75723045643 Mon Sep 17 00:00:00 2001 From: Imamuzzaki Abu Salam Date: Thu, 3 Sep 2026 04:13:10 +0000 Subject: [PATCH] fix(server): fetch worktree base branch's own remote during bootstrap --- apps/server/src/server.test.ts | 119 +++++++++++++++++++++++++++++++++ apps/server/src/ws.ts | 53 +++++++++++---- 2 files changed, 159 insertions(+), 13 deletions(-) diff --git a/apps/server/src/server.test.ts b/apps/server/src/server.test.ts index d3e94e4eea44..24836b10283a 100644 --- a/apps/server/src/server.test.ts +++ b/apps/server/src/server.test.ts @@ -8675,6 +8675,125 @@ it.layer(NodeServices.layer)("server router seam", (it) => { }).pipe(Effect.provide(NodeHttpServer.layerTest)), ); + it.effect.each([ + { + caseName: "a non-origin remote base", + baseBranch: "upstream/main", + fetchRemoteName: "upstream", + lookupRefName: "main", + remoteRefName: "upstream/main", + }, + { + caseName: "an origin-prefixed base", + baseBranch: "origin/main", + fetchRemoteName: "origin", + lookupRefName: "main", + remoteRefName: "origin/main", + }, + ])( + "fetches the base branch's own remote for $caseName", + ({ baseBranch, fetchRemoteName, lookupRefName, remoteRefName }) => + Effect.gen(function* () { + const fetchedCommit = "abcdef0123456789abcdef0123456789abcdef01"; + const remoteExists = vi.fn( + (_: Parameters[0]) => + Effect.succeed(true), + ); + const fetchRemote = vi.fn( + (_: Parameters[0]) => Effect.void, + ); + const remoteBranchExists = vi.fn( + (_: Parameters[0]) => + Effect.succeed(true), + ); + const resolveRemoteTrackingCommit = vi.fn( + (_: Parameters[0]) => + Effect.succeed({ + commitSha: fetchedCommit, + remoteRefName, + }), + ); + const createWorktree = vi.fn( + (_: Parameters[0]) => + Effect.succeed({ + worktree: { + refName: "t3code/bootstrap-refName", + path: "/tmp/bootstrap-worktree", + }, + }), + ); + + yield* buildAppUnderTest({ + layers: { + gitVcsDriver: { + remoteExists, + fetchRemote, + remoteBranchExists, + resolveRemoteTrackingCommit, + createWorktree, + }, + orchestrationEngine: { + dispatch: (command: OrchestrationCommand) => + Effect.sync(() => ({ sequence: 1 })), + readEvents: () => Stream.empty, + }, + }, + }); + + const createdAt = "2026-01-01T00:00:00.000Z"; + const wsUrl = yield* getWsServerUrl("/ws"); + yield* Effect.scoped( + withWsRpcClient(wsUrl, (client) => + client[ORCHESTRATION_WS_METHODS.dispatchCommand]({ + type: "thread.turn.start", + commandId: CommandId.make("cmd-bootstrap-turn-start-remote-base"), + threadId: ThreadId.make("thread-bootstrap-remote-base"), + message: { + messageId: MessageId.make("msg-bootstrap-remote-base"), + role: "user", + text: "hello", + attachments: [], + }, + modelSelection: defaultModelSelection, + runtimeMode: "full-access", + interactionMode: "default", + bootstrap: { + prepareWorktree: { + projectCwd: "/tmp/project", + baseBranch, + branch: "t3code/bootstrap-refName", + startFromOrigin: true, + }, + }, + createdAt, + }), + ), + ); + + assert.deepEqual(fetchRemote.mock.calls[0]?.[0], { + cwd: "/tmp/project", + remoteName: fetchRemoteName, + }); + assert.deepEqual(remoteBranchExists.mock.calls[0]?.[0], { + cwd: "/tmp/project", + remoteName: fetchRemoteName, + refName: lookupRefName, + }); + assert.deepEqual(resolveRemoteTrackingCommit.mock.calls[0]?.[0], { + cwd: "/tmp/project", + refName: baseBranch, + fallbackRemoteName: fetchRemoteName, + }); + assert.deepEqual(createWorktree.mock.calls[0]?.[0], { + cwd: "/tmp/project", + refName: fetchedCommit, + newRefName: "t3code/bootstrap-refName", + baseRefName: baseBranch, + path: null, + }); + }).pipe(Effect.provide(NodeHttpServer.layerTest)), + ); + it.effect("records setup-script failures without aborting bootstrap turn start", () => Effect.gen(function* () { const dispatchedCommands: Array = []; diff --git a/apps/server/src/ws.ts b/apps/server/src/ws.ts index 28ade015f8b6..346bfbbcc099 100644 --- a/apps/server/src/ws.ts +++ b/apps/server/src/ws.ts @@ -1091,30 +1091,57 @@ const makeWsRpcLayer = ( } if (bootstrap?.prepareWorktree) { - let worktreeBaseRef = bootstrap.prepareWorktree.baseBranch; + const baseBranch = bootstrap.prepareWorktree.baseBranch; + let worktreeBaseRef = baseBranch; // "Start from origin" is a stored default; repos without the // requested remote branch fall back to the local base branch. - const startFromOrigin = - bootstrap.prepareWorktree.startFromOrigin === true && - (yield* gitWorkflow.remoteExists({ - cwd: bootstrap.prepareWorktree.projectCwd, - remoteName: "origin", - })); - if (startFromOrigin) { + // The base may track a remote other than `origin` (e.g. `upstream/main`), + // so resolve the fetch target from the base ref instead of assuming `origin`. + // Otherwise we pay for a useless `fetch origin` and base the worktree + // on a stale ref while the real remote is never fetched. + const remotePrefix = baseBranch.includes("/") + ? baseBranch.slice(0, baseBranch.indexOf("/")) + : null; + let fetchRemoteName: string | null = null; + if (bootstrap.prepareWorktree.startFromOrigin === true) { + if ( + remotePrefix !== null && + (yield* gitWorkflow.remoteExists({ + cwd: bootstrap.prepareWorktree.projectCwd, + remoteName: remotePrefix, + })) + ) { + fetchRemoteName = remotePrefix; + } else if ( + yield* gitWorkflow.remoteExists({ + cwd: bootstrap.prepareWorktree.projectCwd, + remoteName: "origin", + }) + ) { + fetchRemoteName = "origin"; + } + } + if (fetchRemoteName !== null) { yield* gitWorkflow.fetchRemote({ cwd: bootstrap.prepareWorktree.projectCwd, - remoteName: "origin", + remoteName: fetchRemoteName, }); + // remoteBranchExists concatenates refs/remotes//, + // so strip the remote prefix when the base already carries it + // (`upstream/main` on `upstream` must look up `main`, not `upstream/main`). + const remoteRefName = baseBranch.startsWith(`${fetchRemoteName}/`) + ? baseBranch.slice(fetchRemoteName.length + 1) + : baseBranch; const remoteBaseExists = yield* gitWorkflow.remoteBranchExists({ cwd: bootstrap.prepareWorktree.projectCwd, - refName: bootstrap.prepareWorktree.baseBranch, - remoteName: "origin", + refName: remoteRefName, + remoteName: fetchRemoteName, }); if (remoteBaseExists) { const resolvedRemoteBase = yield* gitWorkflow.resolveRemoteTrackingCommit({ cwd: bootstrap.prepareWorktree.projectCwd, - refName: bootstrap.prepareWorktree.baseBranch, - fallbackRemoteName: "origin", + refName: baseBranch, + fallbackRemoteName: fetchRemoteName, }); worktreeBaseRef = resolvedRemoteBase.commitSha; }