New users hitting Agent Orchestrator for the first time faced multiple friction points that could cause them to abandon setup before ever spawning an agent. The goal of this PR is to make the path from npm install or git clone to ao spawn as smooth as possible — ideally zero interruptions. Fixes cover both the npm install path and the source/contributor path.
| # | Problem | Severity | Who it affects |
|---|---|---|---|
| 1 | setup.sh crashes with EACCES on npm link |
Blocking | Every macOS user |
| 2 | ao init asks 13 prompts before generating config |
High friction | Every new user |
| 3 | Adding a second project requires editing YAML by hand | High friction | Multi-project users |
| 4 | ao start crashes if configured port is busy |
Medium friction | Users running other dev servers |
| 5 | --smart flag shows "coming soon" placeholder |
Low friction | Users exploring CLI flags |
| 6 | Same npm link bug in ao update and ao doctor --fix |
Blocking | Users updating or diagnosing |
| 7 | No "what's next" guidance — user doesn't know what to run or where | Medium friction | Every new user |
| 8 | ao start crashes for npm users — @composio/ao-web (dashboard) was never published |
Blocking | Every npm user |
| 9 | npm install -g fails with EACCES on default macOS Node — no guidance provided |
High friction | npm users on macOS |
| 10 | Dashboard production server uses npx next start — slow global lookup, may download Next.js at runtime |
Medium friction | npm users |
| 11 | findWebDir() returns a nonexistent path instead of throwing — error message says "Run: pnpm install" (wrong for npm users) |
Medium friction | npm users when package resolution fails |
| 12 | setup.sh / ao-update.sh — non-interactive npm link failure exits 0 (CI sees green, ao not linked) |
Medium friction | CI pipelines |
| 13 | detectDefaultBranch duplicated in init.ts and add-project.ts — bug fixes won't propagate |
Low friction | Maintainers |
npm link permission errornpm link fails with EACCES on macOS. Script exits. User is stuck with no ao command and no guidance.
Tries npm link first. If it fails and terminal is interactive, auto-retries with sudo. If non-interactive (CI), prints the manual command and exits with code 1.
npm linksudo npm linkao init default to auto-detectionao init → 13 interactive promptsao init --auto → zero prompts
Most users should use --auto but it wasn't the default.
ao init → auto-detects everything, zero promptsao init --interactive → full wizard for manual control
ao init--interactive flag?agent-orchestrator.yamlagent-orchestrator.yamlao add-project <path> commandAdding a project meant opening agent-orchestrator.yaml and manually writing YAML with the correct structure, session prefix, and repo format.
One command: ao add-project ~/Desktop/mono
The command automatically:
owner/repo)ao startPort 3000 is already in use.
Free it or change 'port' in agent-orchestrator.yaml.
Port 3000 is busy — using 3001 instead.
--smart placeholderao init --auto --smart showed "AI-powered rule generation not yet implemented". A dead feature flag.
Removed entirely. Template-based rules are the default and work well.
After each command completes, user gets either no guidance or a generic message like "Next: ao start". No indication of where to run the next command — users frequently ran ao init inside the agent-orchestrator repo instead of their project.
Every command prints a clear "what's next" block that tells the user exactly what to run and from which directory. Each step chains into the next, creating a guided path through the entire flow.
setup.sh completescd ~/your-projectao init
ao init completesao startao add-project ~/other-repo
ao start completesao spawn my-project <issue-number>
Example output after setup.sh:
Setup complete!
What's next:
Navigate to your project directory and initialize:
cd ~/your-project
ao init # auto-detects everything, zero prompts
Then start the orchestrator + dashboard:
ao start # run this from your project directory
Want to add more projects later?
ao add-project ~/path/to/another-repo
@composio/ao-web dashboard on npmThis was the single biggest blocker for npm users. Every other AO package was published on npm, but the dashboard — the package that ao start needs to launch the web UI — was never published. npm users hit an immediate fatal crash.
| # | Blocker | Why it existed | Fix |
|---|---|---|---|
| 1 | "private": true in package.json |
Dashboard was never intended as a standalone npm package | Removed the flag |
| 2 | In changeset ignore list |
Excluded from versioning/publishing pipeline | Moved to linked array so it versions with other packages |
| 3 | Dev-only server (pnpm run dev via concurrently) |
Used tsx watch for TypeScript — doesn't work outside monorepo |
Created production entry point (start-all.ts → compiled to dist-server/) |
| 4 | node-pty as hard dependency |
Native C++ addon — fails to compile without build tools (Python, make, gcc) | Moved to optionalDependencies with dynamic import + graceful fallback |
| 5 | Cross-boundary imports | server/terminal-observability.ts imported from ../src/lib/ — breaks when compiled |
Moved resolveProjectIdForSessionId to @composio/ao-core |
$ npm install -g @composio/agent-orchestrator
$ ao start
Error: Could not find @composio/ao-web package.
Run: pnpm install
Fatal crash. The suggested fix (pnpm install) doesn't work for npm users. Complete dead end — dashboard was simply not available outside the monorepo.
$ npm install -g @composio/agent-orchestrator
$ ao start
✓ Dashboard starting on http://localhost:3000
✓ Lifecycle worker started
✓ Orchestrator session created
Next step:
ao spawn my-project <issue-number>
The initial npm pack of @composio/ao-web was 67 MB — Next.js dumps build cache, trace files, and source maps into .next/. We optimized the files field to include only what's needed at runtime:
The optimized files field includes only:
"files": [
".next/server", // compiled server pages + API routes
".next/static", // client-side JS/CSS bundles
".next/*.json", // build manifest, routes manifest
".next/BUILD_ID", // build identifier
"dist-server", // compiled terminal WebSocket servers
"next.config.js" // Next.js configuration
]
Excluded: .next/cache/ (build cache, 60+ MB), .next/trace (webpack trace files), source TypeScript files.
In the monorepo, the dashboard runs via concurrently with tsx watch (hot reloading). On npm, we need pre-compiled servers. start-all.ts is the production entry point that spawns 3 processes:
node dist-server/start-all.jsnode_modules/.bin/next startterminal-websocket.jsdirect-terminal-ws.jsThe CLI needs to work in both the monorepo (for contributors) and as an npm package (for users). It detects the mode by checking whether the server/ source directory exists — present in the monorepo, absent in the published npm package (only dist-server/ ships).
ao start@composio/ao-web via require.resolve or monorepo fallbackserver/ source dir exists?pnpm run devnode dist-server/start-all.jsnpm install -g @composio/agent-orchestrator@composio/ao-cli + all plugin deps + @composio/ao-webworkspace:* auto-converted to real versions by pnpm publishao start https://github.com/org/repofindWebDir() resolves @composio/ao-web from node_modulesserver/ exists?node dist-server/start-all.jsao start for npm usersprivate: true, added files field, made node-pty optionaltranspilePackagesnode-pty import with graceful fallbackfindWebDir() throws with install-specific guidance@composio/ao-web dependencyresolveProjectIdForSessionId here@composio/ao-core@composio/ao-corenpm install -g @composio/agent-orchestrator fails with EACCES on macOS default Node installs. User gets a wall of error text with no actionable fix.
README and SETUP.md document 3 options: sudo npm install -g (quick fix), npx @composio/agent-orchestrator (no install), or fix the npm prefix directory (permanent). npm is now listed as Option A (recommended) in README.
start-all.ts launched the dashboard with npx next start. npx does a global PATH lookup and, if next isn't found, tries to download it at runtime — adding 30+ seconds or failing on slow/offline networks.
Uses the local binary directly: node_modules/.bin/next. Instant startup, no network dependency.
findWebDir() error handlingfindWebDir() silently returned a nonexistent path when all resolution methods failed. The caller then showed "Could not find @composio/ao-web. Run: pnpm install" — wrong advice for npm users.
findWebDir() throws with install-specific guidance: npm install -g for npm users, pnpm install && pnpm build for source users. Redundant checks in start.ts and dashboard.ts removed.
existsSync checkIn non-interactive mode, npm link failure printed a message but the script continued with exit code 0. CI pipelines saw green while ao was not actually linked.
Non-interactive npm link failure now calls exit 1, making CI pipelines correctly report the failure.
detectDefaultBranchThe same 30-line function (3-method fallback: symbolic-ref → GitHub API → local refs) was copy-pasted in both init.ts and add-project.ts. Bug fixes to one wouldn't propagate to the other.
Single implementation in packages/cli/src/lib/git-utils.ts, imported by both commands.
The following issues were investigated and determined to not need fixes:
| Issue | Verdict | Reason |
|---|---|---|
node-pty optional — terminal panels broken? |
Not an issue | Main terminal view uses ttyd (iframe), not node-pty. Direct terminal is a separate feature that degrades gracefully with a server-side log. |
| Git remote regex is GitHub-only | By design | AO only ships GitHub SCM/tracker plugins. Non-GitHub repos would fail at ao spawn anyway. A warning could be added later. |
start-all.ts cleanup doesn't wait for children |
Not an issue | Children are independent OS processes that handle SIGTERM on their own. next start is read-only (no cache writes). On Ctrl+C, the terminal sends SIGINT to the entire process group regardless. |
ao add-project crashes on malformed YAML |
Acceptable | The yaml library produces readable errors with line/column numbers. Same pattern as loadConfig() in core. Not worth a special wrapper. |
ao add-project non-atomic write |
Not an issue | writeFileSync is effectively atomic for small files (config is well under the OS block size). Same pattern used everywhere in the codebase. |
EACCES on npm install -g is docs-only |
Unfixable | The error happens inside npm before any of our code runs. A postinstall script only executes after successful install. Documentation is the correct mitigation. |
git clone ...bash scripts/setup.shcd ~/my-project && ao initnano agent-orchestrator.yamlao startao spawn my-project 123npm install -g @composio/agent-orchestratorao start https://github.com/org/repoao spawn my-project 123bash scripts/setup.shcd ~/my-projectao initao startbash scripts/setup.shcd ~/my-project && ao initao startao spawn my-project 123ao initao spawn (npm)| Metric | Before | After |
|---|---|---|
Steps to first ao spawn | 6+ (with manual edits) | 3 via npm, 4 from source |
Interactive prompts in ao init | 13 | 0 |
| Permission errors during setup | Fatal crash | Auto-handled |
Port conflicts on ao start | Fatal crash | Auto-resolved |
| Adding a second project | Manual YAML editing | ao add-project <path> |
| Dead CLI flags | --smart shows "coming soon" | Removed |
| "What's next" guidance | None — user guesses | Every command prints the next step + directory |
| Dashboard for npm users | Fatal crash (@composio/ao-web not published) | Published + production entry point |
| Dashboard startup speed (npm) | npx next start (slow global lookup) | Direct node_modules/.bin/next binary |
| Error messages for missing packages | Generic "Run: pnpm install" for all users | Install-specific guidance (npm vs source) |
| CI reliability | Scripts exit 0 on npm link failure | Non-interactive failures exit 1 |
| Code duplication | detectDefaultBranch copied in 2 files | Single shared implementation |
ao init --auto still works (now equivalent to ao init)ao init --interactiveao start auto-port was already the behavior for URL-based starts — now default for all
#454 — Codex plugin stability improvements (spawned as a parallel agent session)
#456 — Dashboard shows orchestrator as "Exited" due to startup race condition
bash scripts/setup.sh on macOS without sudo permissions pre-grantedao init in a git repo with GitHub remote → generates correct config with zero promptsao init --interactive → shows full 13-prompt wizardao add-project ~/some-repo → appends project with correct detectionao add-project on already-added project → shows clear errorao start with port 3000 busy → auto-finds 3001 and startsao update with permission issue → auto-retries with sudoao doctor --fix with permission issue → auto-retries with sudosetup.sh completion → prints cd ~/your-project && ao initao init completion → prints ao start with directory contextao start completion → prints ao spawn <project> <issue>ao add-project completion → prints ao start and ao spawnnpm install -g @composio/agent-orchestrator → ao start finds and launches dashboard (no "Could not find @composio/ao-web" error)ao start launches via dist-server/start-all.js (production mode), not pnpm run dev.next/cache bloat)node-pty is unavailablenode_modules/.bin/next, not npx (check start-all.ts)findWebDir() throws with install-specific message when package is missing (not a silent broken path)setup.sh in non-interactive mode (e.g. bash setup.sh < /dev/null) exits 1 on npm link failureao-update.sh in non-interactive mode exits 1 on npm link failuredetectDefaultBranch is imported from lib/git-utils.ts in both init.ts and add-project.ts (no duplication)