fix: defer worktree git watch subscription until after worktree exists

registerPendingWorktreeWorkspace was subscribing the WorkspaceGitService
before the worktree directory existed on disk, caching a stale isGit:false
snapshot. When background reconciliation ran, it consumed the stale cache,
overwrote the correct workspace record with a wrong projectId, and briefly
showed the worktree as a standalone project in the sidebar.

Move syncWorkspaceGitWatchTarget from registerPendingWorktreeWorkspace into
handleCreatePaseoWorktreeRequest, called after createAgentWorktree, so the
first snapshot sees the real worktree — one subscribe, one load, no stale
cache to race against.
This commit is contained in:
Mohamed Boudra
2026-04-14 19:38:47 +07:00
parent 80eb5dbe83
commit d1702e8a40
2 changed files with 5 additions and 6 deletions
+2 -2
View File
@@ -5880,8 +5880,6 @@ export class Session {
buildPersistedWorkspaceRecord: (input) => this.buildPersistedWorkspaceRecord(input), buildPersistedWorkspaceRecord: (input) => this.buildPersistedWorkspaceRecord(input),
buildProjectPlacement: (cwd) => this.buildProjectPlacement(cwd), buildProjectPlacement: (cwd) => this.buildProjectPlacement(cwd),
projectRegistry: this.projectRegistry, projectRegistry: this.projectRegistry,
syncWorkspaceGitWatchTarget: (cwd, syncOptions) =>
this.syncWorkspaceGitWatchTarget(cwd, syncOptions),
workspaceRegistry: this.workspaceRegistry, workspaceRegistry: this.workspaceRegistry,
archiveProjectRecordIfEmpty: (projectId, archivedAt) => archiveProjectRecordIfEmpty: (projectId, archivedAt) =>
this.archiveProjectRecordIfEmpty(projectId, archivedAt), this.archiveProjectRecordIfEmpty(projectId, archivedAt),
@@ -6269,6 +6267,8 @@ export class Session {
emit: (message) => this.emit(message), emit: (message) => this.emit(message),
registerPendingWorktreeWorkspace: (options) => registerPendingWorktreeWorkspace: (options) =>
this.registerPendingWorktreeWorkspace(options), this.registerPendingWorktreeWorkspace(options),
syncWorkspaceGitWatchTarget: (cwd, syncOptions) =>
this.syncWorkspaceGitWatchTarget(cwd, syncOptions),
sessionLogger: this.sessionLogger, sessionLogger: this.sessionLogger,
runWorktreeSetupInBackground: (options) => this.runWorktreeSetupInBackground(options), runWorktreeSetupInBackground: (options) => this.runWorktreeSetupInBackground(options),
}, },
@@ -87,7 +87,6 @@ type RegisterPendingWorktreeWorkspaceDependencies = {
}) => PersistedWorkspaceRecord; }) => PersistedWorkspaceRecord;
buildProjectPlacement: (cwd: string) => Promise<ProjectPlacementPayload>; buildProjectPlacement: (cwd: string) => Promise<ProjectPlacementPayload>;
projectRegistry: Pick<ProjectRegistry, "get" | "upsert">; projectRegistry: Pick<ProjectRegistry, "get" | "upsert">;
syncWorkspaceGitWatchTarget: (cwd: string, options: { isGit: boolean }) => Promise<void>;
workspaceRegistry: Pick<WorkspaceRegistry, "get" | "upsert">; workspaceRegistry: Pick<WorkspaceRegistry, "get" | "upsert">;
archiveProjectRecordIfEmpty: (projectId: string, archivedAt: string) => Promise<void>; archiveProjectRecordIfEmpty: (projectId: string, archivedAt: string) => Promise<void>;
}; };
@@ -111,6 +110,7 @@ type HandleCreatePaseoWorktreeRequestDependencies = {
worktreePath: string; worktreePath: string;
branchName: string; branchName: string;
}) => Promise<PersistedWorkspaceRecord>; }) => Promise<PersistedWorkspaceRecord>;
syncWorkspaceGitWatchTarget: (cwd: string, options: { isGit: boolean }) => Promise<void>;
sessionLogger: Logger; sessionLogger: Logger;
runWorktreeSetupInBackground: (options: { runWorktreeSetupInBackground: (options: {
requestCwd: string; requestCwd: string;
@@ -535,9 +535,6 @@ export async function registerPendingWorktreeWorkspace(
await dependencies.projectRegistry.upsert(nextProjectRecord); await dependencies.projectRegistry.upsert(nextProjectRecord);
await dependencies.workspaceRegistry.upsert(nextWorkspaceRecord); await dependencies.workspaceRegistry.upsert(nextWorkspaceRecord);
await dependencies.syncWorkspaceGitWatchTarget(workspaceId, {
isGit: placement.checkout.isGit,
});
if ( if (
existingWorkspace && existingWorkspace &&
@@ -593,6 +590,8 @@ export async function handleCreatePaseoWorktreeRequest(
paseoHome: dependencies.paseoHome, paseoHome: dependencies.paseoHome,
}); });
await dependencies.syncWorkspaceGitWatchTarget(worktreePath, { isGit: true });
const descriptor = await dependencies.describeWorkspaceRecord(workspace); const descriptor = await dependencies.describeWorkspaceRecord(workspace);
dependencies.emit({ dependencies.emit({
type: "create_paseo_worktree_response", type: "create_paseo_worktree_response",