Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 100 additions & 95 deletions apps/server/src/server.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7766,108 +7766,113 @@ it.layer(NodeServices.layer)("server router seam", (it) => {
}).pipe(Effect.provide(NodeHttpServer.layerTest)),
);

it.effect(
"falls back to the local base branch when startFromOrigin is set but no origin remote exists",
() =>
Effect.gen(function* () {
const dispatchedCommands: Array<OrchestrationCommand> = [];
const remoteExists = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["remoteExists"]>[0]) =>
Effect.succeed(false),
);
const fetchRemote = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["fetchRemote"]>[0]) => Effect.void,
);
const resolveRemoteTrackingCommit = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["resolveRemoteTrackingCommit"]>[0]) =>
Effect.succeed({
commitSha: "0123456789abcdef0123456789abcdef01234567",
remoteRefName: "origin/main",
}),
);
const createWorktree = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["createWorktree"]>[0]) =>
Effect.succeed({
worktree: {
refName: "t3code/bootstrap-refName",
path: "/tmp/bootstrap-worktree",
},
it.effect.each([
{ label: "origin does not exist", originExists: false },
{ label: "the branch does not exist on origin", originExists: true },
])("falls back to the local base branch when $label", ({ originExists }) =>
Effect.gen(function* () {
const dispatchedCommands: Array<OrchestrationCommand> = [];
const remoteExists = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["remoteExists"]>[0]) =>
Effect.succeed(originExists),
);
const fetchRemote = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["fetchRemote"]>[0]) => Effect.void,
);
const resolveRemoteTrackingCommit = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["resolveRemoteTrackingCommit"]>[0]) =>
Effect.fail(
new GitCommandError({
operation: "GitVcsDriver.resolveRemoteTrackingCommit",
command: "git rev-parse --verify refs/remotes/origin/main^{commit}",
cwd: "/tmp/project",
detail: "Git command exited with a non-zero status.",
}),
);

yield* buildAppUnderTest({
layers: {
gitVcsDriver: {
remoteExists,
fetchRemote,
resolveRemoteTrackingCommit,
createWorktree,
},
orchestrationEngine: {
dispatch: (command) =>
Effect.sync(() => {
dispatchedCommands.push(command);
return { sequence: dispatchedCommands.length };
}),
readEvents: () => Stream.empty,
),
);
const createWorktree = vi.fn(
(_: Parameters<GitVcsDriver.GitVcsDriver["Service"]["createWorktree"]>[0]) =>
Effect.succeed({
worktree: {
refName: "t3code/bootstrap-refName",
path: "/tmp/bootstrap-worktree",
},
}),
);

yield* buildAppUnderTest({
layers: {
gitVcsDriver: {
remoteExists,
fetchRemote,
resolveRemoteTrackingCommit,
createWorktree,
},
});
orchestrationEngine: {
dispatch: (command) =>
Effect.sync(() => {
dispatchedCommands.push(command);
return { sequence: dispatchedCommands.length };
}),
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-no-origin"),
threadId: ThreadId.make("thread-bootstrap-no-origin"),
message: {
messageId: MessageId.make("msg-bootstrap-no-origin"),
role: "user",
text: "hello",
attachments: [],
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-no-origin"),
threadId: ThreadId.make("thread-bootstrap-no-origin"),
message: {
messageId: MessageId.make("msg-bootstrap-no-origin"),
role: "user",
text: "hello",
attachments: [],
},
modelSelection: defaultModelSelection,
runtimeMode: "full-access",
interactionMode: "default",
bootstrap: {
createThread: {
projectId: defaultProjectId,
title: "Bootstrap Thread",
modelSelection: defaultModelSelection,
runtimeMode: "full-access",
interactionMode: "default",
branch: "main",
worktreePath: null,
createdAt,
},
modelSelection: defaultModelSelection,
runtimeMode: "full-access",
interactionMode: "default",
bootstrap: {
createThread: {
projectId: defaultProjectId,
title: "Bootstrap Thread",
modelSelection: defaultModelSelection,
runtimeMode: "full-access",
interactionMode: "default",
branch: "main",
worktreePath: null,
createdAt,
},
prepareWorktree: {
projectCwd: "/tmp/project",
baseBranch: "main",
branch: "t3code/bootstrap-refName",
startFromOrigin: true,
},
prepareWorktree: {
projectCwd: "/tmp/project",
baseBranch: "main",
branch: "t3code/bootstrap-refName",
startFromOrigin: true,
},
createdAt,
}),
),
);
},
createdAt,
}),
),
);

assert.deepEqual(remoteExists.mock.calls[0]?.[0], {
cwd: "/tmp/project",
remoteName: "origin",
});
assert.equal(fetchRemote.mock.calls.length, 0);
assert.equal(resolveRemoteTrackingCommit.mock.calls.length, 0);
assert.deepEqual(createWorktree.mock.calls[0]?.[0], {
cwd: "/tmp/project",
refName: "main",
newRefName: "t3code/bootstrap-refName",
baseRefName: "main",
path: null,
});
}).pipe(Effect.provide(NodeHttpServer.layerTest)),
assert.deepEqual(remoteExists.mock.calls[0]?.[0], {
cwd: "/tmp/project",
remoteName: "origin",
});
assert.equal(fetchRemote.mock.calls.length, originExists ? 1 : 0);
assert.equal(resolveRemoteTrackingCommit.mock.calls.length, originExists ? 1 : 0);
assert.deepEqual(createWorktree.mock.calls[0]?.[0], {
cwd: "/tmp/project",
refName: "main",
newRefName: "t3code/bootstrap-refName",
baseRefName: "main",
path: null,
});
}).pipe(Effect.provide(NodeHttpServer.layerTest)),
);

it.effect("records setup-script failures without aborting bootstrap turn start", () =>
Expand Down
23 changes: 14 additions & 9 deletions apps/server/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1016,9 +1016,10 @@ const makeWsRpcLayer = (

if (bootstrap?.prepareWorktree) {
let worktreeBaseRef = bootstrap.prepareWorktree.baseBranch;
// "Start from origin" is a stored default; repos without an
// origin remote fall back to the local base branch instead of
// failing the whole bootstrap on `git fetch origin`.
// "Start from origin" is a stored default. Repos without an
// origin remote, or whose selected base branch only exists
// locally, fall back to the local branch instead of failing the
// whole bootstrap.
const startFromOrigin =
bootstrap.prepareWorktree.startFromOrigin === true &&
(yield* gitWorkflow.remoteExists({
Expand All @@ -1030,12 +1031,16 @@ const makeWsRpcLayer = (
cwd: bootstrap.prepareWorktree.projectCwd,
remoteName: "origin",
});
const resolvedRemoteBase = yield* gitWorkflow.resolveRemoteTrackingCommit({
cwd: bootstrap.prepareWorktree.projectCwd,
refName: bootstrap.prepareWorktree.baseBranch,
fallbackRemoteName: "origin",
});
worktreeBaseRef = resolvedRemoteBase.commitSha;
const resolvedRemoteBase = yield* gitWorkflow
.resolveRemoteTrackingCommit({
cwd: bootstrap.prepareWorktree.projectCwd,
refName: bootstrap.prepareWorktree.baseBranch,
fallbackRemoteName: "origin",
})
.pipe(Effect.orElseSucceed(() => null));
if (resolvedRemoteBase) {
worktreeBaseRef = resolvedRemoteBase.commitSha;
}
}
const worktree = yield* gitWorkflow.createWorktree({
cwd: bootstrap.prepareWorktree.projectCwd,
Expand Down
Loading