* chore(cli): remove deprecated 'ao init' command
Delete the `init` command and its deprecation shim. `ao start` already
auto-creates the config on first run in an unconfigured repo, so the
separate entry point is redundant.
- Remove `packages/cli/src/commands/init.ts` and its test.
- Remove `registerInit` call from the CLI program.
- Drop `createConfigOnly()` from start.ts (only the init shim used it);
export `autoCreateConfig` so the existing default-config test can
invoke it directly.
- Update user-facing "Run `ao init` first" messages in `verify`/`status`
to point to `ao start`.
- Refresh stale `ao init` references in ao-doctor, onboarding test,
openclaw setup doc, and the config/types doc comments.
Closes#1420
* docs: remove ao init website docs
Agent-Logs-Url: https://github.com/ComposioHQ/agent-orchestrator/sessions/41663963-ca49-4673-982f-ca10dee68d31
Co-authored-by: miniMaddy <77185670+miniMaddy@users.noreply.github.com>
---------
Co-authored-by: Prateek <karnalprateek@gmail.com>
Co-authored-by: iamasx <adilshaikh4064@gmail.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: miniMaddy <77185670+miniMaddy@users.noreply.github.com>
Renames all npm package scopes from @composio/* to @aoagents/* and
updates GitHub repo references from ComposioHQ/agent-orchestrator
to aoagents/ao throughout the codebase.
- All package.json names and dependencies
- README badges, links, and install instructions
- Documentation references
- Changeset config
- Source code imports and test files
Users can now install with:
npm install -g @composio/ao
Instead of the longer:
npm install -g @composio/agent-orchestrator
- Rename packages/agent-orchestrator → packages/ao
- Update package.json name and directory field
- Update all references in README, SETUP.md, changeset config, and CLI error messages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Publish @composio/ao-web dashboard as npm package (removed private flag,
added files field, production entry point, node-pty made optional)
- CLI auto-detects dev vs production mode for dashboard startup
- Use local next binary instead of npx in production start-all.ts
- findWebDir() throws with install-specific guidance instead of returning
broken path
- Fix CI-silent failure: setup.sh and ao-update.sh exit 1 on non-interactive
npm link failure
- Deduplicate detectDefaultBranch into shared cli/lib/git-utils.ts
- Add EACCES permission guidance to README.md and SETUP.md
- Move resolveProjectIdForSessionId to @composio/ao-core
- Update design doc with problems #8-13, changes #9-12, known limitations
section, and expanded test plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: auto-detect free port in ao start <url> config generation
When generating a new config via `ao start <url>`, auto-detect a free
port instead of hardcoding 3000. Reuses `findFreePort` (extracted to
shared web-dir.ts from init.ts). When port was auto-selected, skip the
strict preflight port check and silently find another free port if
needed (race condition).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add polling to listIssues integration test for Linear API consistency
The listIssues test was failing because Linear's API has eventual
consistency — a just-created issue may not appear in list queries
immediately. Other tests in this file already use pollUntilEqual for
the same reason. Use pollUntil to retry until the issue appears.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: restore coupling between MAX_PORT_SCAN and findFreePort
MAX_PORT_SCAN was decoupled from findFreePort after extraction to
web-dir.ts — init.ts kept a local constant only used in messages while
findFreePort had its own default, and start.ts hardcoded 99. Export
MAX_PORT_SCAN from web-dir.ts as the single source of truth, use it as
findFreePort's default parameter, and import it in both callers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: URL start handles multi-project configs and cross-platform browser open
When `ao start <url>` loads an existing config with multiple projects,
resolve the correct project by matching the URL's owner/repo against
each project's `repo` field instead of failing with "Multiple projects".
Also fix browser open to use platform-appropriate command (open/xdg-open/start)
instead of hardcoded macOS `open`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use shallow clone (--depth 1) for faster repo onboarding
Full clones of large repos can take minutes. Shallow clone with
depth 1 fetches only the latest commit, making `ao start <url>`
near-instant for any repo size.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use cmd.exe /c start for Windows browser open
`start` is a cmd.exe builtin, not a standalone executable — spawn
would fail with ENOENT. Run via cmd.exe /c with empty title arg.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add `ao start <url>` one-command project onboarding
When `ao start` receives a repo URL instead of a project ID, it now:
1. Parses the URL (supports GitHub, GitLab, Bitbucket — HTTPS and SSH)
2. Clones the repo (or reuses if already present with matching remote)
3. Auto-generates agent-orchestrator.yaml with sensible defaults:
- SCM/tracker plugins inferred from URL host
- Default branch detected from local refs
- Project type detected (language, package manager)
- Post-create install commands set based on package manager
4. Starts the orchestrator + dashboard as usual
New core module `config-generator.ts` handles URL parsing, SCM detection,
project info detection, and config generation. All logic is in core (not
CLI) for reusability. 36 unit tests cover URL parsing, SCM detection,
default branch detection, project info, config generation, and clone
target resolution.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address bugbot review feedback
1. Non-JS postCreate fix: Only set postCreate install commands for JS
package managers (pnpm/yarn/bun/npm). Rust/Go/Python projects no
longer get an incorrect "npm install" command.
2. Deduplicate startup logic: Extract shared `runStartup()` helper used
by both URL-mode and normal-mode start flows. Eliminates ~100 lines
of duplicated dashboard+orchestrator startup code.
3. SSH URL matching: Normalize SSH URLs to HTTPS format in
`isRepoAlreadyCloned()` so repos cloned via SSH
(git@github.com:owner/repo) are correctly detected as matching.
4. SCM/tracker always explicit: Always set scm and tracker fields in
generated config so `applyProjectDefaults()` doesn't silently
override with github defaults for non-GitHub repos.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: sanitize repo names for project IDs and session prefixes
Address remaining bugbot comments:
- Add sanitizeProjectId() to handle dots/special chars in repo names
(e.g. "my.app" → "my-app" instead of failing Zod validation)
- Preserve original case for generateSessionPrefix() so CamelCase
detection works (e.g. "DevOS" → prefix "dos", not "dev")
- Strip invalid chars before prefix generation to prevent dots
leaking into sessionPrefix
Also update README and SETUP docs with `ao start <url>` quick
onboarding flow.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: auto-open browser to orchestrator page on `ao start`
Opens the orchestrator session page (/sessions/{id}) instead of the
root dashboard, since the Kanban board is empty on first startup
with no worker sessions yet.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace fixed 3s delay with port polling for browser open
Poll the dashboard port via TCP connection attempts (300ms intervals,
30s timeout) instead of a hardcoded setTimeout. Opens the browser only
once the server is actually accepting connections — deterministic
regardless of how long Next.js takes to compile.
Applied to both `ao start` and `ao dashboard` commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* test: add CLI tests for start/stop commands
12 new tests covering:
- Project resolution: single project, explicit arg, missing project,
multi-project ambiguity, empty config
- URL argument: reuse existing clone, git clone flow, existing config
detection, clone failure error handling
- Port polling: waitForPortAndOpen polls isPortAvailable before opening
browser (proves deterministic behavior vs fixed delay)
- Stop command: session kill + dashboard stop, graceful missing session
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: deduplicate waitForPortAndOpen into shared utility
Move waitForPortAndOpen to lib/web-dir.ts (alongside isPortAvailable)
so both start.ts and dashboard.ts share a single cancellation-aware
implementation. start.ts now uses AbortSignal like dashboard.ts —
polling stops immediately if the dashboard process exits early.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Adds scripts/try-pr.sh — a helper to switch the global 'ao' command to
any session's worktree for manual testing, then restore back to main.
Usage:
bash scripts/try-pr.sh <session-id> # CLI/core/plugins only
bash scripts/try-pr.sh <session-id> --with-web # also builds + starts dashboard
bash scripts/try-pr.sh --restore # switch back to main
Also fixes isPortAvailable() to use a connect-based probe instead of
bind-based. The old approach had false positives on macOS when Next.js
listens on :: (IPv6 wildcard) — binding 127.0.0.1 succeeded even though
the port was taken. A TCP connect correctly detects any listener
regardless of which address it's bound to.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The comment claimed connect-based detection works for IPv6 listeners,
but the probe only connects to 127.0.0.1 (IPv4). Updated the comment
to accurately document this limitation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused `createServer` import from web-dir.ts (only `Socket`
is used) — fixes the lint error in CI
- Mock `isPortAvailable` in the "uses port 3000" test so it doesn't
depend on port 3000 actually being free on the host machine
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pnpm dev and Next.js listen on :: (dual-stack IPv6) which doesn't conflict
with a 127.0.0.1-only bind check, causing isPortAvailable to return true
even when the port is in use. Now checks both 127.0.0.1 and ::1.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When port 3000 is occupied, `ao init` now scans upward (3001, 3002, ...)
until a free port is found. Applies to both interactive and --auto modes.
Uses the existing isPortAvailable() from web-dir.ts (now exported).
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: make terminal server ports configurable to fix multi-dashboard EADDRINUSE
When multiple ao dashboards run simultaneously (e.g., ao on port 3000,
integrator on port 3002), both try to start terminal WebSocket servers
on hardcoded ports 3001/3003, causing EADDRINUSE. Add terminalPort and
directTerminalPort to config schema so each instance can use unique ports.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use optional() instead of default() for terminal port schema
Zod .default() always fills in the value, making config.terminalPort
never undefined and the env var fallback in buildDashboardEnv dead code.
Switch to .optional() so the priority chain works correctly:
config value > TERMINAL_PORT env var > hardcoded default.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: move terminal server defaults from 3001/3003 to 14800/14801
The 3000-3009 range is the most contested in dev tooling (Next.js
auto-increments, BrowserSync, Grafana, Rails, Express all default to
3000+). Port 14800-14899 has zero IANA registrations, zero known dev
tool conflicts, and is safely below OS ephemeral ranges.
Updated all hardcoded fallbacks, .env.local.example, docker-compose
port mappings, and documentation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: auto-detect available terminal ports for zero-config multi-dashboard
When no terminal ports are configured (no config, no env vars),
buildDashboardEnv now probes for an available port pair starting at
14800. The second `ao start` automatically gets 14802/14803 (or the
next free pair), eliminating EADDRINUSE without any user configuration.
Port detection scans in steps of 2 to keep the pair consecutive.
Explicit config/env values bypass auto-detection entirely.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: update onboarding test to use new default terminal port (14801)
The onboarding integration test had port 3003 hardcoded for the
WebSocket health check. Updated to read from DIRECT_TERMINAL_PORT
env var with 14801 as the default, matching the new port defaults.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: config discovery, activity detection, and metadata port storage
- findConfigFile() checks AO_CONFIG_PATH env var (resolved to absolute path)
- loadConfig() delegates to findConfigFile() for consistent validation
- Pure Node.js readLastJsonlEntry (no external tail binary), safe for
multi-byte UTF-8 at chunk boundaries
- Added "ready" activity state to agent plugins
- Store dashboardPort, terminalWsPort, directTerminalWsPort in session
metadata so ao stop targets the correct processes
- Zod schema port default aligned with TypeScript interface
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: dashboard config discovery + CLI service layer refactoring
- Config discovery via AO_CONFIG_PATH env var
- Auto port detection with PortManager
- Activity detection with ready state, pure Node.js readLastLine
- 5 CLI services: ConfigService, PortManager, DashboardManager, MetadataService, ProcessManager
- Store all service ports in metadata for ao stop
- Set NEXT_PUBLIC_ env vars for frontend terminal components
- Multi-byte UTF-8 safe readLastJsonlEntry
- Tests for all new services and utils
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: address bugbot review comments (port fallback + systemPrompt)
1. Align port fallback to 3000 everywhere (matching Zod schema default):
- start.ts: config.port ?? 3000
- dashboard.ts: config.port ?? 3000
- types.ts JSDoc: "defaults to 3000"
- orchestrator-prompt.ts: already correct at 3000
2. Add --append-system-prompt to Claude Code plugin's getLaunchCommand
so orchestrator context is actually passed to the Claude agent.
Previously systemPrompt was generated but silently dropped.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove dead ConfigService mock from status test
The vi.mock for ConfigService.js referenced a deleted module.
Config mocking is already handled by the @composio/ao-core mock.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: extract shared buildDashboardEnv to eliminate duplication
Dashboard env construction (AO_CONFIG_PATH, PORT, NEXT_PUBLIC_*) was
duplicated between start.ts and dashboard.ts. Extracted into
buildDashboardEnv() in web-dir.ts (already shared by both commands).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: implement ao start command for unified orchestrator startup
Adds `ao start` and `ao stop` commands to unify orchestrator and
dashboard startup. Key features:
- Generates CLAUDE.orchestrator.md with project-specific context
- Auto-imports orchestrator prompt via CLAUDE.local.md
- Creates orchestrator tmux session with agent
- Starts Next.js dashboard server
- Supports --no-dashboard, --no-orchestrator, --regenerate flags
- Idempotent operation (safe to run multiple times)
- Computes orchestrator ID from config (not session search)
- Dashboard button always visible for orchestrator terminal
Components:
- packages/core/src/orchestrator-prompt.ts: Prompt generator
- packages/cli/src/commands/start.ts: Start/stop commands
- Modified exports and dashboard UI for orchestrator support
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* feat: add automatic metadata updates via Claude Code hooks
CRITICAL: This makes the dashboard work by auto-updating metadata when
agents run git/gh commands. Without this, PRs created by agents never
appear on the dashboard.
Changes:
- packages/core/src/claude-hooks.ts: Setup Claude hooks (settings.json + metadata-updater.sh)
- ao start: Automatically configures Claude hooks in project directory
- ao spawn: Sets AO_SESSION and AO_DATA_DIR env vars for hook script
- metadata-updater.sh: Detects gh pr create, git checkout -b, gh pr merge
How it works:
1. PostToolUse hook fires after every Bash command
2. metadata-updater.sh receives JSON with command and output
3. Pattern matches git/gh commands and updates flat metadata files
4. Dashboard reads metadata files to show PR/branch/status
The .claude directory is symlinked from main repo to worktrees so all
sessions share the same hook config.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* refactor: move hook setup to Agent plugin interface
ARCHITECTURE: Hooks setup must go through the Agent plugin interface,
not be hardcoded for Claude Code. This allows other agents (Codex,
Aider, OpenCode) to implement their own metadata update mechanisms.
Changes:
- Added Agent.setupWorkspaceHooks() method to types.ts
- Added WorkspaceHooksConfig interface
- Implemented setupWorkspaceHooks() in Claude Code plugin
- ao start: calls agent.setupWorkspaceHooks() instead of direct setup
- ao spawn: calls agent.setupWorkspaceHooks() for new worktrees
- Uses $CLAUDE_PROJECT_DIR variable for hook path (works with symlinked .claude)
Each agent plugin now implements its own hook mechanism:
- Claude Code: .claude/settings.json with PostToolUse hook
- Future: Codex, Aider, OpenCode with their own config formats
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: address Cursor Bugbot review comments
Fixes 3 issues identified by Cursor Bugbot:
1. HIGH: ao start is now truly idempotent - if orchestrator session exists,
it skips creating the session but still proceeds with dashboard startup
and hook configuration. This allows `ao start` to recover from dashboard
crashes without failing.
2. MEDIUM: Dashboard orchestrator button now finds the actual running
orchestrator session instead of always using the first project. Fallback
to first project ID if no orchestrator is running.
3. LOW: Deduplicated findWebDir() function by moving it to shared utility
lib/web-dir.ts. Now used by both dashboard.ts and start.ts.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: resolve ESLint errors
Fixes 4 ESLint errors identified in CI:
- Added { cause: err } to Error constructors (preserve-caught-error rule)
- Prefixed unused parameter 'config' with underscore in setupWorkspaceHooks
- Prefixed unused variable 'projectId' with underscore in stop command
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: address bugbot review comments - markdown escaping and unused module
- Fix markdown code fence escaping in orchestrator-prompt.ts (change
`\\\`` to `\`` for proper markdown rendering)
- Remove unused claude-hooks.ts module (functionality moved to plugin)
- Clean up exports from core/src/index.ts
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: address remaining bugbot issues - metadata path, duplication, summary
HIGH severity - Fix metadata path mismatch for worker sessions:
- Add AO_PROJECT_ID environment variable in spawn.ts
- Update metadata-updater hook script to construct correct path:
* Worker sessions: $AO_DATA_DIR/${AO_PROJECT_ID}-sessions/$AO_SESSION
* Orchestrator: $AO_DATA_DIR/$AO_SESSION (no project ID)
- Fixes silent hook failures where PRs/branches never appeared on dashboard
LOW severity - Remove code duplication in hook setup:
- Extract setupHookInWorkspace() helper function (90 lines)
- Refactor setupWorkspaceHooks() to use helper (from 80 lines to 4)
- Refactor postLaunchSetup() to use helper (from 82 lines to 6)
- Eliminates risk of methods drifting out of sync
LOW severity - Fix misleading summary output:
- Change "Orchestrator started" to "Startup complete" when components skipped
- Only show dashboard URL when --no-dashboard NOT used
- Only show session info when --no-orchestrator NOT used
- Show "already running" status when orchestrator exists
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: address new bugbot issues - hook quoting, orchestrator link, pkill scope
HIGH severity - Fix Claude hook command quoting:
- Remove embedded double quotes from $CLAUDE_PROJECT_DIR path
- Change from '"$CLAUDE_PROJECT_DIR"/.claude/...' to '$CLAUDE_PROJECT_DIR/.claude/...'
- Prevents hook execution failures if runner treats command as literal path
MEDIUM severity - Fix orchestrator link pointing to nowhere:
- Only show "orchestrator terminal" link when session actually exists
- Remove fallback to computed/hardcoded "ao-orchestrator" ID
- Prevents 404s when user clicks link before starting orchestrator
MEDIUM severity - Fix stop command killing unrelated processes:
- Replace broad `pkill -f "next dev -p ${port}"` with targeted approach
- Use `lsof -ti :${port}` to find exact PID listening on port
- Only kill the specific process, not any process mentioning "next dev"
- Prevents accidentally killing unrelated Next.js dev servers
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: orchestrator metadata path and multi-pid dashboard stop
HIGH severity - Fix orchestrator AO_PROJECT_ID pollution:
- Orchestrator intentionally omits AO_PROJECT_ID (uses flat metadata path)
- agent.getEnvironment() adds AO_PROJECT_ID=project.name
- Object.assign() merged this in, breaking metadata hook path lookup
- Fix: delete environment.AO_PROJECT_ID after merge
- Ensures orchestrator metadata updates work correctly
MEDIUM severity - Fix stopDashboard with multiple PIDs:
- lsof -ti :PORT returns multiple PIDs (one per line) for parent+children
- Passing entire multi-line string to kill fails (can't parse newlines)
- Fix: split stdout by newlines, filter empty, pass PIDs as separate args
- Now correctly stops dashboard even when multiple Node processes exist
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: remove AO_PROJECT_ID from agent plugins to fix metadata path mismatch
The agent.getEnvironment() method was setting AO_PROJECT_ID to
config.projectConfig.name, but different callers have different metadata
path schemes:
- spawn.ts writes to project-specific directories (dataDir/{projectId}-sessions/)
- start.ts writes to flat directories for orchestrator (dataDir/)
- session-manager writes to flat directories (dataDir/)
Setting AO_PROJECT_ID in getEnvironment() caused the metadata updater hook
to look for files in the wrong location for orchestrator and session-manager
flows, breaking automatic metadata updates.
Fix: Remove AO_PROJECT_ID from all agent plugins' getEnvironment() methods
and make it the caller's responsibility to set when using project-specific
directories. Only spawn.ts sets it now.
Changes:
- Remove AO_PROJECT_ID assignment from getEnvironment() in all 4 agent plugins
(claude-code, aider, codex, opencode)
- Update corresponding tests to expect AO_PROJECT_ID to be undefined
- Remove delete environment.AO_PROJECT_ID statement from start.ts (no longer needed)
- Add comments explaining the metadata path scheme contract
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 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 <noreply@anthropic.com>
* fix: eliminate redundant getAgent call by hoisting agent declaration
The agent instance was being created twice in the orchestrator setup block:
- Once at line 237 inside the hook setup try block
- Again at line 253 for getting the launch command
This creates duplicate agent instances unnecessarily. Fixed by declaring
the agent variable before the hook setup try block, allowing it to be
reused for both hook setup and launch command generation.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* fix: address resource leaks and undefined env variable
Fixed 4 Bugbot issues:
1. HIGH: Undefined $CLAUDE_PROJECT_DIR in hook script path
- Changed setupWorkspaceHooks to use absolute path instead of undefined
env variable
- Matches approach used in postLaunchSetup for consistency
2. HIGH: Orchestrator session leaks when metadata write fails
- Added try-catch around tmux session launch and metadata write
- Kills tmux session if metadata write or agent launch fails
- Prevents orphaned sessions from consuming resources
3. MEDIUM: Dashboard process leaks when orchestrator setup fails
- Wrapped orchestrator setup in try-catch block
- Kills dashboard child process if orchestrator setup fails
- Prevents orphaned Next.js server from blocking future starts
4. LOW: Inconsistent indentation (fixed as side effect of restructuring)
- Refactored error handling simplified indentation structure
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>