fix(server): await git worktree creation before responding to client

Move createAgentWorktree() from the fire-and-forget background function
into handleCreatePaseoWorktreeRequest so the worktree directory exists
on disk before the client receives the response and navigates. Fixes
ENOENT race when the app queries checkout status on a path that hasn't
been created yet. Setup commands (npm install, etc.) remain background.
This commit is contained in:
Mohamed Boudra
2026-04-13 14:55:59 +07:00
parent b3d5401295
commit 8aa1833e2b
2 changed files with 17 additions and 20 deletions
+4 -5
View File
@@ -173,7 +173,7 @@ import { ScheduleService } from "./schedule/service.js";
import {
assertSafeGitRef as assertWorktreeSafeGitRef,
buildAgentSessionConfig as buildWorktreeAgentSessionConfig,
createPaseoWorktreeInBackground as createWorktreeInBackgroundSession,
runWorktreeSetupInBackground as runWorktreeSetupInBackgroundSession,
handleCreatePaseoWorktreeRequest as handleCreateWorktreeRequest,
handlePaseoWorktreeArchiveRequest as handleWorktreeArchiveRequest,
handlePaseoWorktreeListRequest as handleWorktreeListRequest,
@@ -6157,20 +6157,19 @@ export class Session {
registerPendingWorktreeWorkspace: (options) =>
this.registerPendingWorktreeWorkspace(options),
sessionLogger: this.sessionLogger,
createPaseoWorktreeInBackground: (options) => this.createPaseoWorktreeInBackground(options),
runWorktreeSetupInBackground: (options) => this.runWorktreeSetupInBackground(options),
},
request,
);
}
private async createPaseoWorktreeInBackground(options: {
private async runWorktreeSetupInBackground(options: {
requestCwd: string;
repoRoot: string;
baseBranch: string;
slug: string;
worktreePath: string;
}): Promise<void> {
return createWorktreeInBackgroundSession(
return runWorktreeSetupInBackgroundSession(
{
paseoHome: this.paseoHome,
emitWorkspaceUpdateForCwd: (cwd) => this.emitWorkspaceUpdateForCwd(cwd),
+13 -15
View File
@@ -109,10 +109,9 @@ type HandleCreatePaseoWorktreeRequestDependencies = {
branchName: string;
}) => Promise<PersistedWorkspaceRecord>;
sessionLogger: Logger;
createPaseoWorktreeInBackground: (options: {
runWorktreeSetupInBackground: (options: {
requestCwd: string;
repoRoot: string;
baseBranch: string;
slug: string;
worktreePath: string;
}) => Promise<void>;
@@ -575,6 +574,15 @@ export async function handleCreatePaseoWorktreeRequest(
worktreePath,
branchName: normalizedSlug,
});
await createAgentWorktree({
cwd: repoRoot,
branchName: normalizedSlug,
baseBranch,
worktreeSlug: normalizedSlug,
paseoHome: dependencies.paseoHome,
});
const descriptor = await dependencies.describeWorkspaceRecord(workspace);
dependencies.emit({
type: "create_paseo_worktree_response",
@@ -586,10 +594,9 @@ export async function handleCreatePaseoWorktreeRequest(
},
});
void dependencies.createPaseoWorktreeInBackground({
void dependencies.runWorktreeSetupInBackground({
requestCwd: request.cwd,
repoRoot,
baseBranch,
slug: normalizedSlug,
worktreePath,
});
@@ -611,12 +618,11 @@ export async function handleCreatePaseoWorktreeRequest(
}
}
export async function createPaseoWorktreeInBackground(
export async function runWorktreeSetupInBackground(
dependencies: CreatePaseoWorktreeInBackgroundDependencies,
options: {
requestCwd: string;
repoRoot: string;
baseBranch: string;
slug: string;
worktreePath: string;
},
@@ -624,14 +630,6 @@ export async function createPaseoWorktreeInBackground(
let setupTerminalId: string | null = null;
try {
await createAgentWorktree({
cwd: options.repoRoot,
branchName: options.slug,
baseBranch: options.baseBranch,
worktreeSlug: options.slug,
paseoHome: dependencies.paseoHome,
});
const setupCommands = getWorktreeSetupCommands(options.worktreePath);
if (setupCommands.length > 0 && dependencies.terminalManager) {
const runtimeEnv = await resolveWorktreeRuntimeEnv({
@@ -667,7 +665,7 @@ export async function createPaseoWorktreeInBackground(
worktreePath: options.worktreePath,
setupTerminalId,
},
"Background worktree creation failed",
"Background worktree setup failed",
);
} finally {
await dependencies.emitWorkspaceUpdateForCwd(options.worktreePath);