# ai-cli-dispatch Dispatch AI CLI coding tasks to available clients (Codex, Claude Code, OpenCode) with automatic discovery, version checking, and execution. ## Scope - discover installed AI CLI clients on the host - report client versions and availability - dispatch a prompt to a specific client by name - auto-resolve the best client from prompt keywords - forward arguments natively to each client The tool is a lightweight sync-only dispatcher. It does not implement streaming, chat sessions, or ACP orchestration. For ACP-based harnesses, see `docs/openclaw-acp-orchestration.md`. ## Setup From the repo or installed skill directory: ```bash cd tools/ai-cli-dispatch npm install ``` The dispatcher itself requires only Node.js 20+ and `npm`. The actual AI CLI clients (`codex`, `claude`, `opencode`) are discovered from the host `PATH`; they are not bundled. ## Commands ```bash ai-cli-dispatch list [--json|--text] ai-cli-dispatch run --client --prompt [--json|--text] ai-cli-dispatch dispatch [--client ] [--json|--text] ai-cli-dispatch --help ``` ### `list` Discover and report all supported clients. ```bash ai-cli-dispatch list --json ``` Example JSON output: ```json [ { "name": "codex", "path": "/usr/local/bin/codex", "version": "1.2.3", "found": true }, { "name": "claude", "found": false }, { "name": "opencode", "path": "/opt/homebrew/bin/opencode", "version": "0.5.1", "found": true } ] ``` Use `--text` for human-readable checkmarks: ```bash ai-cli-dispatch list --text ``` ### `run` Execute a prompt directly through a named client. ```bash ai-cli-dispatch run --client codex --prompt "refactor this function" ai-cli-dispatch run --client claude --prompt "add tests for auth middleware" ai-cli-dispatch run --client opencode --prompt "migrate to ESM" ``` The prompt is forwarded with each client’s native argument shape: | Client | Arguments passed | |---|---| | `codex` | `exec ""` | | `claude` | `-p ""` | | `opencode` | `""` | ### `dispatch` Auto-resolve the client from prompt keywords, then execute. ```bash ai-cli-dispatch dispatch "use claude to write tests" ai-cli-dispatch dispatch "codex refactor auth module" ai-cli-dispatch dispatch "opencode migrate to ESM" ``` Keyword matching is case-insensitive and ordered: 1. `--client` flag (highest precedence) 2. `"open code"` (spaced variant) → `opencode` 3. `"claude"` → `claude` 4. `"codex"` → `codex` 5. `"opencode"` → `opencode` 6. `defaultClient` from config (lowest precedence) Override auto-resolution explicitly: ```bash ai-cli-dispatch dispatch "fix the bug" --client claude ``` ## Client Discovery Discovery searches `PATH` in this order for each client name: 1. `codex` — OpenAI Codex CLI 2. `claude` — Anthropic Claude Code 3. `opencode` — OpenCode CLI The search uses `which` (or `where` on Windows) first, then falls back to a manual `PATH` directory scan. If a binary is found, `--version` is invoked to extract a semver string. ## Configuration Optional config file: ```text ~/.openclaw/ai-cli-dispatch.json ``` Example: ```json { "paths": { "codex": "/usr/local/bin/codex", "claude": "/opt/homebrew/bin/claude" }, "defaultClient": "claude" } ``` Resolution priority for paths and default client (highest to lowest): 1. CLI flag (`--client`, `--codex-path`, etc.) 2. Environment variable (`AI_CLI_CODEX_PATH`, `AI_CLI_DEFAULT_CLIENT`, etc.) 3. Config file (`paths`, `defaultClient`) 4. `which` / `where` discovery Supported env vars: | Variable | Purpose | |---|---| | `AI_CLI_CODEX_PATH` | Override `codex` binary path | | `AI_CLI_CLAUDE_PATH` | Override `claude` binary path | | `AI_CLI_OPENCODE_PATH` | Override `opencode` binary path | | `AI_CLI_DEFAULT_CLIENT` | Override default client (`codex`, `claude`, or `opencode`) | ## Output Model Default output is JSON. Use `--text` to stream raw `stdout`/`stderr` directly. JSON success shape (`run` and `dispatch`): ```json { "stdout": "...", "stderr": "...", "exitCode": 0 } ``` JSON error shape: ```json { "error": "..." } ``` Exit codes: | Code | Meaning | |---|---| | `0` | Success | | `1` | Missing/unknown command, missing argument, unknown client, resolution failure, or execution error | ## Error Handling Guidance ### `Client "" not found or not installed` Meaning: the requested client binary is not on `PATH` and not overridden by config. Actions: 1. Confirm the client is installed (`codex --version`, `claude --version`, etc.) 2. Check that its directory is on `PATH` 3. Or override the path in `~/.openclaw/ai-cli-dispatch.json` ### `Prompt cannot be empty` Meaning: the prompt string was empty or whitespace-only. Action: supply a non-empty `--prompt` or positional prompt argument. ### `Execution timed out after 300000ms` Meaning: the client subprocess did not finish within the default 5-minute timeout. Action: the client may be waiting for interactive input or the task is too large. Break the prompt into smaller pieces, or run the client directly to diagnose. ### `Could not resolve client from prompt` Meaning: `dispatch` found no matching keyword and no `defaultClient` is configured. Action: include a client name in the prompt (e.g., `"use claude to ..."`) or set `defaultClient` in config. ## Common Flows ### Check what is installed ```bash ai-cli-dispatch list --json ``` ### Run a quick task through a specific client ```bash ai-cli-dispatch run --client codex --prompt "fix lint errors in src/app.ts" ``` ### Let the tool pick the client from the prompt ```bash ai-cli-dispatch dispatch "claude: add unit tests for utils.ts" ``` ### Force a client when the prompt is ambiguous ```bash ai-cli-dispatch dispatch "review this PR" --client claude ``` ## Coexistence with ACP `ai-cli-dispatch` is a direct subprocess dispatcher. It runs the client binary synchronously and returns its output. It is not an ACP agent and does not participate in ACP orchestration. - Use `ai-cli-dispatch` when you need a quick, local, one-shot CLI execution. - Use ACP (`docs/openclaw-acp-orchestration.md`) when you need session-bound coding harnesses with thread context, multi-turn review, or orchestrator-managed verification gates. ## Implementation Notes - The dispatcher is TypeScript/Node.js with a single external dependency (`minimist`). - Client arguments are hardcoded per tool to match each client’s stable CLI contract. - The default timeout is 5 minutes (`300_000` ms). - On Windows, discovery uses `where` instead of `which` and `.exe` extensions are assumed.