From c8defcfc77cbeda51a3f6fc251369a288af865c2 Mon Sep 17 00:00:00 2001 From: Prateek Date: Sun, 15 Feb 2026 14:02:03 +0530 Subject: [PATCH] fix: only run orchestrator setup when actually starting orchestrator The orchestrator-specific setup steps (generating CLAUDE.orchestrator.md, configuring CLAUDE.local.md, and setting up agent hooks) were executing unconditionally, even when --no-orchestrator was passed. This caused `ao start --no-dashboard` to fail if hook setup had errors, because the hook setup was fatal and blocked the dashboard from starting. Fix: Move all orchestrator setup steps inside the `if (opts?.orchestrator !== false)` guard, and specifically inside the `else` branch (when session doesn't already exist). Now these steps only run when we're actually creating a new orchestrator session. This allows: - `ao start --no-orchestrator` to start only the dashboard - Skipping setup when orchestrator session already exists - Setup to be non-blocking for dashboard-only mode Co-Authored-By: Claude Sonnet 4.5 --- packages/cli/src/commands/start.ts | 93 +++++++++++++++--------------- 1 file changed, 48 insertions(+), 45 deletions(-) diff --git a/packages/cli/src/commands/start.ts b/packages/cli/src/commands/start.ts index c6c3e90d5..45d757751 100644 --- a/packages/cli/src/commands/start.ts +++ b/packages/cli/src/commands/start.ts @@ -179,51 +179,11 @@ export function registerStart(program: Command): void { console.log(chalk.bold(`\nStarting orchestrator for ${chalk.cyan(project.name)}\n`)); - // Check if orchestrator session already exists - const exists = await hasTmuxSession(sessionId); - - // Ensure CLAUDE.orchestrator.md exists - const spinner = ora("Generating orchestrator prompt").start(); - ensureOrchestratorPrompt( - project.path, - config, - projectId, - project, - opts?.regenerate ?? false, - ); - spinner.succeed("Orchestrator prompt ready"); - - // Ensure CLAUDE.local.md imports CLAUDE.orchestrator.md - spinner.start("Configuring CLAUDE.local.md"); - try { - ensureOrchestratorImport(project.path); - spinner.succeed("CLAUDE.local.md configured"); - } catch (err) { - spinner.fail("Could not write CLAUDE.local.md"); - throw new Error( - `Failed to update CLAUDE.local.md: ${err instanceof Error ? err.message : String(err)}`, - { cause: err }, - ); - } - - // Setup agent hooks for automatic metadata updates - spinner.start("Configuring agent hooks"); - try { - const agent = getAgent(config, projectId); - if (agent.setupWorkspaceHooks) { - await agent.setupWorkspaceHooks(project.path, { dataDir: config.dataDir }); - } - spinner.succeed("Agent hooks configured"); - } catch (err) { - spinner.fail("Could not setup agent hooks"); - throw new Error( - `Failed to setup agent hooks: ${err instanceof Error ? err.message : String(err)}`, - { cause: err }, - ); - } - // Start dashboard (unless --no-dashboard) + const spinner = ora(); let dashboardProcess: ChildProcess | null = null; + let exists = false; // Track whether orchestrator session already exists + if (opts?.dashboard !== false) { spinner.start("Starting dashboard"); const webDir = findWebDir(); @@ -241,13 +201,56 @@ export function registerStart(program: Command): void { // Create orchestrator tmux session (unless --no-orchestrator or already exists) if (opts?.orchestrator !== false) { + // Check if orchestrator session already exists + exists = await hasTmuxSession(sessionId); + if (exists) { console.log(chalk.yellow(`Orchestrator session "${sessionId}" is already running (skipping creation)`)); } else { + // Ensure CLAUDE.orchestrator.md exists + spinner.start("Generating orchestrator prompt"); + ensureOrchestratorPrompt( + project.path, + config, + projectId, + project, + opts?.regenerate ?? false, + ); + spinner.succeed("Orchestrator prompt ready"); + + // Ensure CLAUDE.local.md imports CLAUDE.orchestrator.md + spinner.start("Configuring CLAUDE.local.md"); + try { + ensureOrchestratorImport(project.path); + spinner.succeed("CLAUDE.local.md configured"); + } catch (err) { + spinner.fail("Could not write CLAUDE.local.md"); + throw new Error( + `Failed to update CLAUDE.local.md: ${err instanceof Error ? err.message : String(err)}`, + { cause: err }, + ); + } + + // Setup agent hooks for automatic metadata updates + spinner.start("Configuring agent hooks"); + try { + const agent = getAgent(config, projectId); + if (agent.setupWorkspaceHooks) { + await agent.setupWorkspaceHooks(project.path, { dataDir: config.dataDir }); + } + spinner.succeed("Agent hooks configured"); + } catch (err) { + spinner.fail("Could not setup agent hooks"); + throw new Error( + `Failed to setup agent hooks: ${err instanceof Error ? err.message : String(err)}`, + { cause: err }, + ); + } + spinner.start("Creating orchestrator session"); - // Get agent launch command - const agent = getAgent(config, projectId); + // Get agent launch command + const agent = getAgent(config, projectId); const launchCmd = agent.getLaunchCommand({ sessionId, projectConfig: project,