diff --git a/src/hooks/bundled/boot-md/handler.test.ts b/src/hooks/bundled/boot-md/handler.test.ts index a07dfb1bc67..258a58b84e3 100644 --- a/src/hooks/bundled/boot-md/handler.test.ts +++ b/src/hooks/bundled/boot-md/handler.test.ts @@ -134,4 +134,18 @@ describe("boot-md handler", () => { reason: "missing", }); }); + + it("deduplicates agents sharing the same workspaceDir (#74072)", async () => { + const cfg = { agents: { list: [{ id: "main" }, { id: "alias" }] } }; + listAgentIds.mockReturnValue(["main", "alias"]); + resolveAgentWorkspaceDir.mockReturnValue(MAIN_WORKSPACE_DIR); + runBootOnce.mockResolvedValue({ status: "ran" }); + + await runBootChecklist(makeEvent({ context: { cfg } })); + + expect(runBootOnce).toHaveBeenCalledTimes(1); + expect(runBootOnce).toHaveBeenCalledWith( + expect.objectContaining({ cfg, workspaceDir: MAIN_WORKSPACE_DIR, agentId: "main" }), + ); + }); }); diff --git a/src/hooks/bundled/boot-md/handler.ts b/src/hooks/bundled/boot-md/handler.ts index 97aaa19c9e8..de46b6777fb 100644 --- a/src/hooks/bundled/boot-md/handler.ts +++ b/src/hooks/bundled/boot-md/handler.ts @@ -19,15 +19,25 @@ const runBootChecklist: HookHandler = async (event) => { const cfg = event.context.cfg; const deps = event.context.deps ?? createDefaultDeps(); - const tasks: StartupTask[] = listAgentIds(cfg).map((agentId) => { - const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId); - return { - source: "boot-md", + const seenWorkspaces = new Set(); + const tasks: StartupTask[] = listAgentIds(cfg) + .map((agentId) => { + const workspaceDir = resolveAgentWorkspaceDir(cfg, agentId); + return { agentId, workspaceDir }; + }) + .filter(({ workspaceDir }) => { + if (seenWorkspaces.has(workspaceDir)) { + return false; + } + seenWorkspaces.add(workspaceDir); + return true; + }) + .map(({ agentId, workspaceDir }) => ({ + source: "boot-md" as const, agentId, workspaceDir, run: () => runBootOnce({ cfg, deps, workspaceDir, agentId }), - }; - }); + })); await runStartupTasks({ tasks, log }); };