203 lines
6.8 KiB
Markdown
203 lines
6.8 KiB
Markdown
---
|
|
name: ai-cli-dispatch
|
|
description: Dispatch AI CLI coding tasks to available clients (Codex, Claude Code, OpenCode) with automatic discovery, version checking, and execution.
|
|
metadata: {"clawdbot":{"emoji":"robot","requires":{"bins":["node"]}}}
|
|
---
|
|
|
|
# AI CLI Dispatch
|
|
|
|
Use this skill when the user wants to run a coding task through an AI CLI client such as Codex, Claude Code, or OpenCode.
|
|
|
|
The skill discovers installed clients, resolves versions, selects the best available tool, and forwards the task with arguments intact.
|
|
|
|
Use the local helper from the installed skill directory:
|
|
|
|
```bash
|
|
cd ~/.openclaw/workspace/skills/ai-cli-dispatch
|
|
scripts/ai-cli-dispatch --help
|
|
```
|
|
|
|
## Setup
|
|
|
|
```bash
|
|
cd ~/.openclaw/workspace/skills/ai-cli-dispatch
|
|
npm install
|
|
```
|
|
|
|
## Commands
|
|
|
|
### `list`
|
|
|
|
Discover and report all supported clients.
|
|
|
|
```bash
|
|
scripts/ai-cli-dispatch list --json
|
|
scripts/ai-cli-dispatch list --text
|
|
```
|
|
|
|
### `start` — start a background job
|
|
|
|
Starts a detached background job and returns immediately with a job ID.
|
|
|
|
```bash
|
|
scripts/ai-cli-dispatch start --client codex --prompt "refactor this function"
|
|
scripts/ai-cli-dispatch start --client claude --prompt "add tests for auth middleware"
|
|
```
|
|
|
|
### `run` — run a task (async by default)
|
|
|
|
Runs a prompt through a named client. By default this is **async**: it starts a background job and returns the job ID immediately. Use `--sync` to block until the client finishes and return the full result.
|
|
|
|
```bash
|
|
# Async (default) — returns job ID immediately
|
|
scripts/ai-cli-dispatch run --client codex --prompt "refactor this function"
|
|
scripts/ai-cli-dispatch run --client claude --prompt "add tests for auth middleware"
|
|
scripts/ai-cli-dispatch run --client opencode --prompt "migrate to ESM"
|
|
|
|
# Sync — blocks until completion and returns stdout/stderr/exitCode
|
|
scripts/ai-cli-dispatch run --client codex --prompt "fix lint errors" --sync
|
|
```
|
|
|
|
### `dispatch` — auto-resolve client and run (async by default)
|
|
|
|
Auto-resolves the client from prompt keywords, then executes. By default this is **async**. Use `--sync` to block until completion.
|
|
|
|
```bash
|
|
# Async (default)
|
|
scripts/ai-cli-dispatch dispatch "use codex to write tests"
|
|
scripts/ai-cli-dispatch dispatch "claude: add unit tests for utils.ts"
|
|
scripts/ai-cli-dispatch dispatch "opencode migrate to ESM"
|
|
|
|
# Sync
|
|
scripts/ai-cli-dispatch dispatch "review this PR" --client claude --sync
|
|
```
|
|
|
|
### Job lifecycle commands
|
|
|
|
After starting an async job, manage it with these subcommands:
|
|
|
|
```bash
|
|
# Check job status
|
|
scripts/ai-cli-dispatch status <job-id>
|
|
|
|
# Get results (only when status is completed)
|
|
scripts/ai-cli-dispatch results <job-id>
|
|
|
|
# Cancel a running job
|
|
scripts/ai-cli-dispatch cancel <job-id>
|
|
|
|
# List all jobs, newest first
|
|
scripts/ai-cli-dispatch list-jobs --json
|
|
scripts/ai-cli-dispatch list-jobs --status running --json
|
|
|
|
# Clean up old job files
|
|
scripts/ai-cli-dispatch cleanup-jobs --max-age 24h
|
|
```
|
|
|
|
## Async vs Sync Mode
|
|
|
|
The dispatcher is **async-first**: `run` and `dispatch` start a detached background job unless you pass `--sync`.
|
|
|
|
| Mode | Behavior | When to use |
|
|
|---|---|---|
|
|
| **Async** (default) | Starts a detached process, returns a `jobId` immediately, and stores output on disk. | Fire-and-forget tasks, long-running jobs, parallel dispatches, or when you need to poll/check results later. |
|
|
| **Sync** (`--sync`) | Blocks until the client subprocess exits, then returns `stdout`, `stderr`, and `exitCode` directly. | Short, interactive tasks where you need the result in the same turn. |
|
|
|
|
Use `--timeout <ms>` to control how long a job may run before it is terminated (default: 10 minutes for async, 5 minutes for sync). Use `--debug` to emit diagnostic metadata to stderr.
|
|
|
|
## Flags
|
|
|
|
| Flag | Description |
|
|
|---|---|
|
|
| `--sync` | Run synchronously and block until the client returns. Default is async (starts a background job). |
|
|
| `--timeout <ms>` | Timeout in milliseconds. Overrides the default and any config value. |
|
|
| `--debug` | Emit diagnostic JSON to stderr (command, args, PID, duration, exit signal). |
|
|
| `--json` | Output JSON (default). |
|
|
| `--text` | Output plain text instead of JSON. |
|
|
| `--client <name>` | Explicitly set the client (`codex`, `claude`, `opencode`). |
|
|
| `--prompt <text>` | The prompt to send to the client. |
|
|
| `--status <status>` | Filter `list-jobs` by status (`running`, `completed`, `failed`). |
|
|
| `--max-age <number>[h\|m\|s\|d]` | Maximum age for `cleanup-jobs` (default unit: hours). |
|
|
|
|
## Client Discovery
|
|
|
|
The skill searches for the following clients in order:
|
|
|
|
- `codex` — OpenAI Codex CLI
|
|
- `claude` — Anthropic Claude Code
|
|
- `opencode` — OpenCode CLI
|
|
|
|
Run `list` to see which clients are installed and their resolved versions.
|
|
|
|
## Job Lifecycle & Storage
|
|
|
|
Async jobs run as detached child processes. Each job writes a record to disk at:
|
|
|
|
```text
|
|
~/.openclaw/ai-cli-dispatch/jobs/<jobId>.json
|
|
```
|
|
|
|
A job moves through the following statuses:
|
|
|
|
| Status | Meaning |
|
|
|---|---|
|
|
| `running` | The client subprocess is active. |
|
|
| `completed` | The subprocess exited with code 0. |
|
|
| `failed` | The subprocess exited with a non-zero code. |
|
|
| `timed_out` | The job exceeded `--timeout` and was terminated. |
|
|
| `cancelled` | The job was cancelled via `cancel <job-id>`. |
|
|
|
|
Example async workflow:
|
|
|
|
```bash
|
|
# 1. Start a job
|
|
scripts/ai-cli-dispatch run --client codex --prompt "refactor auth module"
|
|
# → { "jobId": "a1b2c3d4...", "client": "codex", "status": "running" }
|
|
|
|
# 2. Poll status
|
|
scripts/ai-cli-dispatch status a1b2c3d4...
|
|
# → { "id": "a1b2c3d4...", "status": "running", ... }
|
|
|
|
# 3. Get results when done
|
|
scripts/ai-cli-dispatch results a1b2c3d4...
|
|
# → { "stdout": "...", "stderr": "...", "exitCode": 0, "client": "codex", "durationMs": 42000 }
|
|
```
|
|
|
|
## Background Jobs (Programmatic API)
|
|
|
|
For long-running or fire-and-forget tasks, use the programmatic job API:
|
|
|
|
```typescript
|
|
import { startJob, getJob, getJobResult, cancelJob, listJobs, cleanupJobs } from "./src/jobs.js";
|
|
|
|
// Start a detached job
|
|
const job = await startJob("codex", "refactor auth module", { timeoutMs: 300_000 });
|
|
console.log(job.id); // e.g. "a1b2c3d4..."
|
|
console.log(job.status); // "running"
|
|
|
|
// Poll for completion
|
|
const latest = getJob(job.id);
|
|
console.log(latest.status); // "running" | "completed" | "failed" | "timed_out" | "cancelled"
|
|
|
|
// Get result (throws if not completed)
|
|
const result = getJobResult(job.id);
|
|
console.log(result.stdout, result.exitCode);
|
|
|
|
// Cancel a running job
|
|
cancelJob(job.id);
|
|
|
|
// List all jobs (newest first)
|
|
const jobs = listJobs(); // Job[]
|
|
const running = listJobs({ filter: "running" });
|
|
|
|
// Clean up job files older than 24 hours (default)
|
|
cleanupJobs({ maxAgeMs: 24 * 60 * 60 * 1000 });
|
|
```
|
|
|
|
Job files include stdout, stderr, exit code, timing, and error state.
|
|
|
|
## Output Rules
|
|
|
|
- Normal JSON output redacts local file paths and credential metadata.
|
|
- Use `--debug` only when deeper troubleshooting requires internal paths and resolved config metadata.
|