From d09af86ea72683d46db6942316a5869382702828 Mon Sep 17 00:00:00 2001 From: MoerAI Date: Fri, 27 Mar 2026 21:13:44 +0900 Subject: [PATCH] fix(start-work): gracefully handle missing Atlas agent (fixes #2132) --- src/features/claude-code-session-state/state.ts | 11 +++++++++++ src/hooks/start-work/start-work-hook.ts | 13 +++++++++---- src/plugin-handlers/agent-config-handler.ts | 4 ++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/features/claude-code-session-state/state.ts b/src/features/claude-code-session-state/state.ts index 60a8f8a84..d8f3298cf 100644 --- a/src/features/claude-code-session-state/state.ts +++ b/src/features/claude-code-session-state/state.ts @@ -11,12 +11,23 @@ export function getMainSessionID(): string | undefined { return _mainSessionID } +const registeredAgentNames = new Set() + +export function registerAgentName(name: string): void { + registeredAgentNames.add(name.toLowerCase()) +} + +export function isAgentRegistered(name: string): boolean { + return registeredAgentNames.has(name.toLowerCase()) +} + /** @internal For testing only */ export function _resetForTesting(): void { _mainSessionID = undefined subagentSessions.clear() syncSubagentSessions.clear() sessionAgentMap.clear() + registeredAgentNames.clear() } const sessionAgentMap = new Map() diff --git a/src/hooks/start-work/start-work-hook.ts b/src/hooks/start-work/start-work-hook.ts index 47c3889ed..8eb58d2fa 100644 --- a/src/hooks/start-work/start-work-hook.ts +++ b/src/hooks/start-work/start-work-hook.ts @@ -12,7 +12,7 @@ import { } from "../../features/boulder-state" import { log } from "../../shared/logger" import { getAgentDisplayName } from "../../shared/agent-display-names" -import { updateSessionAgent } from "../../features/claude-code-session-state" +import { updateSessionAgent, isAgentRegistered } from "../../features/claude-code-session-state" import { detectWorktreePath } from "./worktree-detector" import { parseUserRequest } from "./parse-user-request" @@ -80,9 +80,14 @@ export function createStartWorkHook(ctx: PluginInput) { if (!promptText.includes("")) return log(`[${HOOK_NAME}] Processing start-work command`, { sessionID: input.sessionID }) - updateSessionAgent(input.sessionID, "atlas") - if (output.message) { - output.message["agent"] = getAgentDisplayName("atlas") + const atlasDisplayName = getAgentDisplayName("atlas") + if (isAgentRegistered("atlas") || isAgentRegistered(atlasDisplayName)) { + updateSessionAgent(input.sessionID, "atlas") + if (output.message) { + output.message["agent"] = atlasDisplayName + } + } else { + log(`[${HOOK_NAME}] Atlas agent not available, continuing with current agent`, { sessionID: input.sessionID }) } const existingState = readBoulderState(ctx.directory) diff --git a/src/plugin-handlers/agent-config-handler.ts b/src/plugin-handlers/agent-config-handler.ts index 539fa6bb0..14993cda3 100644 --- a/src/plugin-handlers/agent-config-handler.ts +++ b/src/plugin-handlers/agent-config-handler.ts @@ -4,6 +4,7 @@ import type { OhMyOpenCodeConfig } from "../config"; import { log, migrateAgentConfig } from "../shared"; import { AGENT_NAME_MAP } from "../shared/migration"; import { getAgentDisplayName } from "../shared/agent-display-names"; +import { registerAgentName } from "../features/claude-code-session-state"; import { discoverConfigSourceSkills, discoverGlobalAgentsSkills, @@ -292,6 +293,9 @@ export async function applyAgentConfig(params: { } const agentResult = params.config.agent as Record; + for (const name of Object.keys(agentResult)) { + registerAgentName(name); + } log("[config-handler] agents loaded", { agentKeys: Object.keys(agentResult) }); return agentResult; }