---
title: CLI reference
description: Every `ao` command, every flag, drawn from the source.
---

import { Callout } from "fumadocs-ui/components/callout";

All commands support `--help`. Use that in place of re-reading this page.

## Command tree

```
ao
├── start [project]             Start orchestrator + dashboard (auto-creates config on first run)
├── stop [project]              Stop orchestrator + dashboard
├── status                      Show all sessions with PR and CI status
├── spawn [issue]               Spawn a single agent session
├── batch-spawn <issues...>     Spawn sessions for multiple issues, with duplicate detection
├── send <session> [message…]   Send a message to a session with busy detection
├── review-check [project]      Check PRs for review comments and trigger agents
├── dashboard                   Start the web dashboard on its own
├── open [target]               Open session(s) in terminal tabs
├── verify [issue]              Mark an issue as verified (or failed) after staging check
├── doctor                      Run install, environment, and runtime health checks
├── update                      Check for updates and upgrade AO
├── init                        (deprecated — use ao start)
├── config-help                 Print the config schema and a guide
├── notify                      test
├── session                     ls, attach, kill, cleanup, restore, claim-pr, remap
├── setup                       dashboard, desktop, webhook, slack, discord, composio, openclaw
└── plugin                      list, search, create, install, update, uninstall
```

## Core commands

### `ao start [project]`

> Start orchestrator agent and dashboard (auto-creates config on first run, adds projects by path/URL)

| Flag | Default | Purpose |
|---|---|---|
| `--no-dashboard` | — | Skip starting the dashboard server |
| `--no-orchestrator` | — | Skip starting the orchestrator agent |
| `--rebuild` | — | Clean and rebuild the dashboard before starting |
| `--dev` | — | Use Next.js dev server with hot reload (monorepo only; ignored in npm installs) |
| `--interactive` | — | Prompt to configure config settings |

Positional `[project]` — project id, local path, or repo URL. If omitted and no config exists in `cwd`, AO creates `agent-orchestrator.yaml`.

If AO is already running, you'll get an interactive prompt to open/restart/spawn-new/quit. Non-TTY callers get info + `process.exit(0)`.

### `ao stop [project]`

> Stop orchestrator agent and dashboard

| Flag | Default | Purpose |
|---|---|---|
| `--purge-session` | — | Delete the mapped OpenCode session when stopping |
| `--all` | — | Stop all running AO instances on this machine |

### `ao status`

> Show all sessions with branch, activity, PR, and CI status

| Flag | Default | Purpose |
|---|---|---|
| `-p, --project <id>` | — | Filter to one project |
| `--json` | — | Output JSON |
| `-w, --watch` | — | Refresh continuously |
| `--interval <seconds>` | `5` | Refresh interval |

`--watch` and `--json` are mutually exclusive. Falls back to tmux session discovery if no config is found.

### `ao spawn [issue]`

> Spawn a single agent session

| Flag | Default | Purpose |
|---|---|---|
| `--open` | — | Open the session in a terminal tab |
| `--agent <name>` | config default | Override the agent plugin (`claude-code`, `codex`, `cursor`, `aider`, `opencode`) |
| `--claim-pr <pr>` | — | Immediately claim an existing PR for the spawned session |
| `--assign-on-github` | — | Assign the claimed PR to the authenticated GitHub user |
| `--prompt <text>` | — | Use an inline prompt instead of an issue (max 4096 chars, newlines stripped) |

Positional `[first]` — issue identifier. The project is auto-detected from `cwd`.

<Callout type="warn">
  The old two-arg form `ao spawn &lt;project&gt; &lt;issue&gt;` is rejected with an error. Use `-p` or run from inside a worktree.
</Callout>

### `ao batch-spawn <issues...>`

> Spawn sessions for multiple issues with duplicate detection

| Flag | Default | Purpose |
|---|---|---|
| `--open` | — | Open sessions in terminal tabs |

Skips duplicates within the batch and any issues that already have an active session.

### `ao send <session> [message...]`

> Send a message to a session with busy detection and retry

| Flag | Default | Purpose |
|---|---|---|
| `-f, --file <path>` | — | Send contents of a file instead of an inline message |
| `--no-wait` | — | Don't wait for the session to become idle before sending |
| `--timeout <seconds>` | `600` | Max seconds to wait for idle |

Positional: `<session>` required, `[message...]` variadic. One of inline message or `--file` is required. Long messages (>200 chars or multiline) go via tmux paste-buffer + temp file.

### `ao review-check [project]`

> Check PRs for review comments and trigger agents to address them

| Flag | Default | Purpose |
|---|---|---|
| `--dry-run` | — | Show what would happen; don't nudge agents |

Checks all projects if `[project]` is omitted.

### `ao dashboard`

> Start the web dashboard

| Flag | Default | Purpose |
|---|---|---|
| `-p, --port <port>` | config `port` or `3000` | Port to listen on |
| `--no-open` | — | Don't open the browser |
| `--rebuild` | — | Clean stale Next.js artifacts and rebuild |

If the build looks stale you'll see a suggestion to run `ao dashboard --rebuild`.

### `ao open [target]`

> Open session(s) in terminal tabs

| Flag | Default | Purpose |
|---|---|---|
| `-w, --new-window` | — | Open in a new terminal window instead of a tab |

Positional `[target]` — session name, project id, or `"all"`. Defaults to all sessions. Falls back to printing the dashboard URL when the native terminal helper isn't available (anywhere but macOS + iTerm2).

### `ao verify [issue]`

> Mark an issue as verified (or failed) after checking the fix on staging

| Flag | Default | Purpose |
|---|---|---|
| `-p, --project <id>` | — | Required if multiple projects |
| `--fail` | — | Mark as failed instead of passing |
| `-c, --comment <msg>` | — | Custom comment to add |
| `-l, --list` | — | List all issues with the merged-unverified label |

`[issue]` is required unless `--list` is passed.

### `ao doctor`

> Run install, environment, and runtime health checks

| Flag | Default | Purpose |
|---|---|---|
| `--fix` | — | Apply safe fixes for launcher and stale-temp issues |
| `--test-notify` | — | Send a test notification through each configured notifier |

Runs `ao-doctor.sh` for shell-level checks, then TypeScript checks (version freshness, plugin resolution, notifier connectivity). OpenClaw is the only notifier probed without side effects.

### `ao update`

> Check for updates and upgrade AO to the latest version

| Flag | Default | Purpose |
|---|---|---|
| `--skip-smoke` | — | Skip smoke tests after rebuilding (git installs only) |
| `--smoke-only` | — | Run smoke tests without fetching or rebuilding (git installs only) |
| `--check` | — | Print version info as JSON; don't upgrade |

Behavior depends on how AO was installed — git, npm-global, pnpm-global, or unknown (manual instructions printed).

### `ao config-help`

> Show config schema and guide for creating `agent-orchestrator.yaml`

No flags.

## Notify subcommands

### `ao notify test`

> Send a manual demo notification without spawning sessions

| Flag | Default | Purpose |
|---|---|---|
| `--template <name>` | `basic` | Demo template to send |
| `--to <refs>` | — | Comma-separated notifier refs to target |
| `--all` | — | Send to all configured, default, and routed notifier refs |
| `--route <priority>` | — | Send through `urgent`, `action`, `warning`, or `info` routing |
| `--actions` | — | Include demo actions when supported |
| `--message <text>` | — | Override the notification message |
| `--dry-run` | — | Resolve targets without sending |
| `--json` | — | Print structured JSON output |
| `--sink [port]` | — | Add a local webhook target named `sink` |

## Session subcommands

### `ao session ls`

> List all sessions

| Flag | Default | Purpose |
|---|---|---|
| `-p, --project <id>` | — | Filter to one project |
| `-a, --all` | — | Include orchestrator sessions |
| `--json` | — | Output JSON |

### `ao session attach <session>`

> Attach to a session's tmux window

No flags. Attaches via `tmux attach-session`. Only meaningful with `runtime: tmux`.

### `ao session kill <session>`

> Kill a session and remove its worktree

| Flag | Default | Purpose |
|---|---|---|
| `--purge-session` | — | Delete the mapped OpenCode session |

### `ao session cleanup`

> Kill sessions where PR is merged or issue is closed

| Flag | Default | Purpose |
|---|---|---|
| `-p, --project <id>` | — | Filter to one project |
| `--dry-run` | — | Show what would be cleaned up |

### `ao session claim-pr <pr> [session]`

> Attach an existing PR to a session

| Flag | Default | Purpose |
|---|---|---|
| `--assign-on-github` | — | Assign the PR to the authenticated user on GitHub |

If `[session]` is omitted, falls back to `AO_SESSION_NAME` / `AO_SESSION` env vars.

### `ao session restore <session>`

> Restore a terminated or crashed session in-place

No flags. Relaunches the agent inside the same worktree and rewires session metadata.

### `ao session remap <session>`

> Re-discover and persist OpenCode session mapping for an AO session

| Flag | Default | Purpose |
|---|---|---|
| `-f, --force` | — | Override a stale mapping |

## Setup subcommands

Notifier setup commands that write AO config support `--routing-preset <preset>`.
Valid presets are `urgent-only`, `urgent-action`, and `all`. In interactive
mode, AO asks which notification priorities the notifier should receive before
writing `notificationRouting`.

| Command | Purpose |
|---|---|
| `ao setup dashboard` | Configure dashboard notification retention and routing |
| `ao setup desktop` | Configure native desktop notifications |
| `ao setup webhook` | Configure a generic HTTP webhook |
| `ao setup slack` | Configure a Slack incoming webhook |
| `ao setup discord` | Configure a Discord incoming webhook |
| `ao setup composio` | Open the interactive Composio setup hub |
| `ao setup composio-slack` | Configure Slack through Composio |
| `ao setup composio-discord` | Configure Discord webhook mode through Composio |
| `ao setup composio-discord-bot` | Configure Discord bot mode through Composio |
| `ao setup composio-mail` | Configure Gmail through Composio |
| `ao setup openclaw` | Configure OpenClaw gateway notifications |

### `ao setup openclaw`

> Connect AO notifications to an OpenClaw gateway

| Flag | Default | Purpose |
|---|---|---|
| `--url <url>` | — | OpenClaw webhook URL |
| `--token <token>` | — | Remote/manual fallback; local setup should read `hooks.token` from OpenClaw config |
| `--openclaw-config-path <path>` | `~/.openclaw/openclaw.json` | OpenClaw config path that contains `hooks.token` |
| `--routing-preset <preset>` | — | `urgent-only` · `urgent-action` · `all` |
| `--refresh` | — | Reuse existing values and rewrite AO config |
| `--no-test` | — | Skip the setup token probe |
| `--force` | — | Replace a conflicting `notifiers.openclaw` entry |
| `--status` | — | Show OpenClaw config, gateway state, and token probe status |
| `--non-interactive` | — | Skip prompts — auto-detect OpenClaw on localhost |

Interactive mode (TTY) uses `@clack/prompts` with review/change steps for the gateway URL, OpenClaw config path, and routing preset. OpenClaw owns the token in `hooks.token`; AO does not generate it or write shell-profile exports.

## Plugin subcommands

### `ao plugin list`

> List bundled marketplace plugins

| Flag | Default | Purpose |
|---|---|---|
| `--installed` | — | Only show plugins present in your current config |
| `--type <slot>` | — | Filter by slot: `agent`, `runtime`, `tracker`, `scm`, `notifier`, `workspace`, `terminal` |
| `--refresh` | — | Re-fetch the marketplace catalog |

### `ao plugin search <query>`

> Search the bundled marketplace catalog

No flags.

### `ao plugin create [directory]`

> Scaffold a new AO plugin package

| Flag | Default | Purpose |
|---|---|---|
| `--name <name>` | prompt | Plugin name |
| `--slot <slot>` | prompt | Which slot it implements |
| `--description <text>` | prompt | Manifest description |
| `--author <name>` | prompt | Package author |
| `--package-name <name>` | derived | npm package name |
| `--non-interactive` | — | Use all flags without prompting |

### `ao plugin install <reference>`

> Install a plugin into the current config

| Flag | Default | Purpose |
|---|---|---|
| `--url <url>` | — | Passed to `ao setup openclaw` when installing `notifier-openclaw` |
| `--token <token>` | — | Remote/manual OpenClaw token fallback |
| `--openclaw-config-path <path>` | `~/.openclaw/openclaw.json` | OpenClaw config path that contains `hooks.token` |

`<reference>` is a marketplace id, npm package name, or local path.

### `ao plugin update [reference]`

> Update installer-managed plugins in the current config

| Flag | Default | Purpose |
|---|---|---|
| `--all` | — | Update all managed plugins |

Requires either `[reference]` or `--all`.

### `ao plugin uninstall <reference>`

> Remove a plugin from the current config

No flags.

## Environment

A few env vars affect every command:

| Variable | Purpose |
|---|---|
| `AO_DATA_DIR` | Override the `~/.agent-orchestrator` base directory. |
| `AO_LOG_LEVEL` | `error` · `warn` · `info` · `debug` · `trace` |
| `AO_CONFIG_PATH` | Absolute path to a specific `agent-orchestrator.yaml`. Overrides CWD-based search. |
| `AO_SESSION_ID` · `AO_SESSION_NAME` | Auto-set inside spawned sessions; used by `claim-pr` default |
| `AO_PROJECT_ID` | Set by AO inside spawned sessions. Used by `ao spawn` to resolve the active project. |
| `PORT` | Next.js dashboard port. Overrides `config.port`. |
| `TERMINAL_PORT` | WebSocket mux server port (default 14800). |
| `DIRECT_TERMINAL_PORT` | Direct PTY WebSocket port (default 14801). |
| `NEXT_PUBLIC_TERMINAL_WS_PATH` | Override the WebSocket path used by the terminal client (for reverse-proxy setups). |

Agent-specific env vars are documented on each [agent plugin's page](/docs/plugins/agents).
