Command Book for AI Agents (Claude Code, Codex, Cursor)

AI coding agents are great at writing code, but they're notoriously bad at managing the long-running processes that code needs: dev servers, databases, workers, and build watchers. Command Book's CLI gives any agent a reliable, machine-readable way to launch a process, poll whether it's actually up, and stop it cleanly when the work is done.

This page is the human-facing setup guide. For the terse, copy-into-your-agent reference, see the raw AI Agent CLI Reference — it's written specifically for LLMs to load into their instructions.

Why agents + Command Book

When an agent starts a server with a bare background shell (python app.py &), it has no dependable way to answer two simple questions later: Is it still running? and How do I stop it? The result is the failure mode every developer has seen an agent fall into:

  • Orphaned servers that keep running after the task is "done," holding onto ports and memory.
  • Port conflicts when the agent starts a second copy because it lost track of the first.
  • Guessed sleep timers (sleep 5 && curl ...) that are either too short (server isn't up yet) or wastefully long.

Command Book fixes this by being the front door for long-running processes. Every process started through Command Book — whether from the GUI or from commandbook run — is tracked in a runtime registry. So when the agent asks commandbook status, there is always a truthful answer, and when it asks commandbook stop, there is always a real handle to act on. No PID bookkeeping, no leaked processes.

Only processes Command Book launched are visible to status and stop. If your agent needs to manage a process, it must start it through commandbook run.

The loop: launch → poll → act → stop

This is the entire pattern Command Book is built around. An agent should follow these four steps for any long-running process:

  1. Launch the saved command with commandbook run <slug>. Because run is a long-running foreground process, the agent backgrounds it (or runs it with a timeout) so it can keep working.
  2. Wait for it with commandbook wait <slug> — one call that blocks until the process is up and returns the instant it is. Add --http <url> or --port <n> to wait until the server actually accepts connections, not just until the process exists. No guessed sleep timers, and a built-in timeout so a failed boot can't hang the agent.
  3. Act against the now-running process: hit its port, run a test suite, scrape a page, whatever the task requires.
  4. Stop it with commandbook stop <slug> when finished. This also suppresses auto-restart, so the process stays down.
# 1. Launch (background the long-running foreground process)
commandbook run api-server &

# 2. Block until the port answers — returns the moment it's ready, or fails fast on a bad boot.
commandbook wait api-server --http http://127.0.0.1:5000

# 3. Do the work against the running server here...

# 4. Stop cleanly when done (also suppresses auto-restart)
commandbook stop api-server

The CLI in 60 seconds

These are the commands an agent needs. The full reference, with every flag and example, lives on the CLI page.

commandbook list                          # Discover exact slugs — never guess them
commandbook details <slug> --json         # Full config + status for one command
commandbook run <slug>                    # Run a saved command (long-running, foreground)
commandbook run --command "<cmd>" --name <handle>   # Run an arbitrary command ad-hoc (not saved)
commandbook status <slug> --json          # Is it running? Machine-readable snapshot.
commandbook wait <slug> --http <url>      # Block until up & the port answers (timeout ceiling)
commandbook stop <slug> --json            # Stop gracefully (machine-readable result)
commandbook stop <slug> --force           # Stop immediately (SIGKILL)

status --json

Prefer the --json form when you want to parse state instead of branching on exit codes:

{
  "slug": "talk-python-dev",
  "state": "running",
  "instances": [
    { "pid": 81234, "startedAt": "2026-06-17T10:02:00Z", "source": "app", "uptimeSeconds": 720 }
  ]
}
  • state is "running", "stopped" (known but nothing live), or "not_found".
  • source is "cli" (started via commandbook run) or "app" (started in the GUI). status sees both.
  • The no-arg commandbook status --json returns a JSON array, one entry per running command.

Exit codes (scriptable, HTTP-flavored)

status, stop, and details share the same exit-code vocabulary, which makes them easy to script:

Code Meaning
0 Running / stopped at least one instance / command exists (details)
1 stop matched live processes but none could be killed
204 Known but not running
44 Slug not found (shown as 404 in the message/JSON)
244 Runtime registry error (shown as 500)

Because exit code 0 means "running," commandbook status is pollable in a loop — but prefer commandbook wait (below), which does the polling for you with a timeout and an optional readiness probe.

Waiting for a command: commandbook wait

commandbook wait <slug> blocks until a condition is met and returns the instant it is — the timeout is only a ceiling, never a fixed delay. It replaces hand-rolled until commandbook status …; do sleep 1; done loops, which have no timeout and can't tell "still booting" from "already crashed."

commandbook wait <slug>                                # until the process is registered and alive
commandbook wait <slug> --http http://127.0.0.1:5000   # until that URL returns 2xx/3xx
commandbook wait <slug> --port 5000                    # until that TCP port accepts a connection
commandbook wait <slug> --for stopped                  # until it is no longer running
commandbook wait <slug> --timeout 60 --json            # raise the ceiling; emit JSON
  • Readiness, not just liveness. With --http/--port, wait returns only once the server actually answers — so you can drop the separate curl-retry loop. A server is "running" for a moment before its port binds; this closes that gap.
  • Fail-fast. If the process exits before becoming ready, wait returns immediately (exit 205) instead of burning the whole timeout.
  • Short commands. A plain wait <slug> (no probe) also succeeds if the command has already exited cleanly (exit 0); a non-zero exit is propagated as wait's own exit code. Use --for stopped to block until a one-shot command finishes and get its exit code back.
Code Meaning
0 Condition met (running / ready / clean exit / stopped)
124 Timed out before the condition was met
205 --http/--port target exited before becoming ready
44 Slug not found (shown as 404)
244 Runtime registry error (shown as 500)

The --json output carries state (running · ready · exited · stopped · timeout), waitedSeconds, an exitCode once the command has ended, and the live instances:

{ "slug": "talk-python-dev", "state": "ready", "waitedSeconds": 0.34,
  "instances": [ { "pid": 81234, "source": "cli", "uptimeSeconds": 0 } ] }

Set up your agent

There are two ways to give your agent the Command Book workflow: install the ready-made skill (the fastest path — see below), or paste a per-tool instruction block into your tool's config (Claude Code, Codex, and Cursor blocks are further down). Either way, the source of truth is the AI Agent CLI Reference — it spells out the commands, the loop, and the gotchas.

Install the Command Book bundle (skill + agent)

The same setup is packaged as a ready-made Command Book bundle so you don't have to hand-write instructions. It's two pieces: the ask-commandbook skill (the launch → wait → stop loop your main agent follows inline) and a commandbook operator agent (for multi-process orchestration). There are three ways to get it in place, from easiest to most manual.

Install from the app (easiest)

In Command Book, open Settings → AI Agents → "Install Claude Code Skill & Agent". One click installs the skill to ~/.claude/skills/ask-commandbook/ and the agent to ~/.claude/agents/commandbook.md, where Claude Code picks them up automatically across all your projects. This is the recommended path — no download, no unzip — and it keeps itself up to date: when a newer Command Book ships an updated bundle, the app refreshes your installed copy on launch.

Download the bundle

Prefer to do it by hand, or installing for a tool other than Claude Code? Download the bundle and drop it where your tool looks for instructions:

  • commandbook-skill.zip — contains skills/ask-commandbook/ (with SKILL.md + reference/cli-reference.md) and agents/commandbook.md.

Then put it in place per tool:

  • Claude Code — unzip into ~/.claude/ for a personal install (all projects), or into <project>/.claude/ for a single project. Either way you'll end up with …/.claude/skills/ask-commandbook/SKILL.md and …/.claude/agents/commandbook.md. The exact command for a personal install:

    unzip commandbook-skill.zip -d ~/.claude/
    

    Verify it loaded by asking Claude to "start X with Command Book," or by running /skills if your version supports it.

  • Codex — Codex can't load a SKILL.md directly, so add the instruction block to your project's AGENTS.md instead — see the Codex block under "Per-tool setup" below.

  • Cursor — add the instruction block to .cursorrules (or a project rule) — see the Cursor block under "Per-tool setup" below.

Manual copy (no download)

If you'd rather not download anything, the raw skill is viewable at /static/downloads/SKILL.md and the full CLI reference at /docs/ai-guide.md. Paste the relevant block straight into your tool's instruction file.

Per-tool setup

Copy-paste instruction blocks for each tool. If you installed the skill above, Claude Code is already set up — these are the manual equivalents.

Claude Code

The skill above packages this automatically. To set it up by hand instead, add the reference URL to your project's CLAUDE.md:

## Long-running processes

Use the Command Book CLI to start, check, and stop long-running processes
(dev servers, databases, workers). Full reference:
https://commandbookapp.com/docs/ai-guide.md

The loop: `commandbook run <slug> &`, poll `commandbook status <slug>` until
it exits 0 (running), do the work, then `commandbook stop <slug>`.
Use `commandbook list` to discover exact slugs.

Codex

Add the same instruction block to your project's AGENTS.md:

## Long-running processes (Command Book)

Start dev servers and other long-running processes with the Command Book CLI
instead of bare background shells, so they can be monitored and stopped cleanly.
Reference: https://commandbookapp.com/docs/ai-guide.md

Loop: `commandbook run <slug> &` → poll `commandbook status <slug>` until it
exits 0 → do the work → `commandbook stop <slug>`.

Cursor

Add to your project's .cursorrules (or a project rule):

When you need a long-running process (dev server, database, worker), use the
Command Book CLI so it can be monitored and stopped reliably:
- Discover slugs with `commandbook list`
- Start with `commandbook run <slug> &`
- Poll `commandbook status <slug>` until it exits 0 (running)
- Stop with `commandbook stop <slug>` when done
Full reference: https://commandbookapp.com/docs/ai-guide.md

Generic / any agent

Any agent that can load a URL or a markdown file can use Command Book. Point it at:

Both are plain text written for machine consumption.

Worked example: run a dev server, test it, stop it

Suppose you have a Flask app saved in Command Book as talk-python-dev. Here's how an agent would start it, wait for it to come up, run work against it, and tear it down — all with real commandbook commands.

# Confirm the slug exists (don't guess it).
commandbook list

# Launch the dev server. It's a long-running foreground process, so background it.
commandbook run talk-python-dev &

# Wait until the server actually accepts connections. Returns the instant it's ready,
# fails fast (exit 205) if the process dies during boot, and gives up after --timeout.
commandbook wait talk-python-dev --http http://127.0.0.1:5000/health --timeout 30

# The server is up — now do the work against it.
curl -fsS http://127.0.0.1:5000/health
python -m pytest tests/integration/

# Stop the server cleanly. This also suppresses auto-restart.
commandbook stop talk-python-dev

If you'd rather inspect the result yourself, add --json and branch on state:

commandbook wait talk-python-dev --http http://127.0.0.1:5000 --json
# {"slug":"talk-python-dev","state":"ready","waitedSeconds":0.3, ... }

Gotchas

A few behaviors are worth teaching your agent up front:

  • stop blocks during graceful shutdown. It escalates SIGINT → SIGTERM → SIGKILL to the process group, which can take up to ~12s per instance (5s SIGINT + 5s SIGTERM + 2s SIGKILL). When a graceful shutdown isn't needed, use commandbook stop <slug> --force to skip straight to SIGKILL (~2s).
  • Auto-restart retry caveat. If a command has auto-restart enabled and you stop it during its brief restart-delay countdown, the stop can be a silent no-op while the pending restart still fires. If stop unexpectedly returns 204 for an auto-restart command, poll status and retry stop once it shows running.
  • Only Command Book–launched processes are visible. status and stop can only see processes started through commandbook run or the GUI. The CLI cannot find or kill arbitrary processes started elsewhere — so start everything you want to manage through Command Book.
  • Run unsaved commands ad-hoc. To launch something that isn't a saved slug, use commandbook run --command "<cmd>" --name <handle> — it's fully managed by status/stop but isn't added to the user's command list. new and edit are interactive (they read stdin) and create saved commands; prefer ad-hoc runs for one-off agent processes so you don't clutter the user's sidebar.
  • Inspect before you run. commandbook details <slug> --json returns a command's full configuration (command, working directory, env var names, auto-restart) plus its current status — so you can verify exactly what a slug will do before launching it. Environment variable values are never printed.
  • Always pass the slug explicitly. commandbook run with no slug launches an interactive picker, which an agent can't drive.

Learn more