feat(S-401): Update SKILL.md for async-first usage

This commit is contained in:
2026-05-19 22:42:16 -05:00
parent bd88df7dd2
commit 6655e2e1e8
+127 -6
View File
@@ -26,15 +26,98 @@ npm install
## Commands ## Commands
### `list`
Discover and report all supported clients.
```bash ```bash
scripts/ai-cli-dispatch list --json 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 codex --prompt "refactor this function"
scripts/ai-cli-dispatch run --client claude --prompt "add tests for auth middleware" scripts/ai-cli-dispatch run --client claude --prompt "add tests for auth middleware"
scripts/ai-cli-dispatch run --client opencode --prompt "migrate to ESM" scripts/ai-cli-dispatch run --client opencode --prompt "migrate to ESM"
scripts/ai-cli-dispatch dispatch "use codex to write tests"
# Sync — blocks until completion and returns stdout/stderr/exitCode
scripts/ai-cli-dispatch run --client codex --prompt "fix lint errors" --sync
``` ```
Use `--json` for machine-readable command output. Use `--sync` with `run` or `dispatch` to block until the client returns; the default is async (starts a background job and returns the job ID immediately). ### `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 ## Client Discovery
@@ -46,12 +129,46 @@ The skill searches for the following clients in order:
Run `list` to see which clients are installed and their resolved versions. Run `list` to see which clients are installed and their resolved versions.
## Background Jobs ## Job Lifecycle & Storage
For long-running or fire-and-forget tasks, use the programmatic job API or invoke `run` / `dispatch` without `--sync`: 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 ```typescript
import { startJob, getJob, cancelJob, listJobs, cleanupJobs } from "./src/jobs.js"; import { startJob, getJob, getJobResult, cancelJob, listJobs, cleanupJobs } from "./src/jobs.js";
// Start a detached job // Start a detached job
const job = await startJob("codex", "refactor auth module", { timeoutMs: 300_000 }); const job = await startJob("codex", "refactor auth module", { timeoutMs: 300_000 });
@@ -62,6 +179,10 @@ console.log(job.status); // "running"
const latest = getJob(job.id); const latest = getJob(job.id);
console.log(latest.status); // "running" | "completed" | "failed" | "timed_out" | "cancelled" 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 // Cancel a running job
cancelJob(job.id); cancelJob(job.id);
@@ -73,7 +194,7 @@ const running = listJobs({ filter: "running" });
cleanupJobs({ maxAgeMs: 24 * 60 * 60 * 1000 }); cleanupJobs({ maxAgeMs: 24 * 60 * 60 * 1000 });
``` ```
Job files are stored under `~/.openclaw/ai-cli-dispatch/jobs/<jobId>.json` and include stdout, stderr, exit code, and timing. Job files include stdout, stderr, exit code, timing, and error state.
## Output Rules ## Output Rules