# Examples

Worked transcripts of every flow — cold start, the orchestrator loop, the worker side, fan-out, and the rails you will hit.

Every flow below ran against a real deck (2026-09-01, v0.1.3 tree) and behaved
exactly as shown. Routes and params are canonical in `AGENTS.md`; this file is
the *doing* companion. `$M` is the CLI (`mandeck` on PATH, or fetch it:
`curl -so /tmp/mandeck http://127.0.0.1:7717/cli/mandeck && chmod +x /tmp/mandeck`).

## 0. Cold start — you know only a port

```bash
curl -s http://127.0.0.1:7717/v1/health
# {"ok":true,"app":"mandeck","docs":"/agents.md","state":"dev.mandeck.native", ...}
#                                  └── read this      └── token lives at
#                                                        ~/Library/Application Support/<state>/cli-token
curl -s http://127.0.0.1:7717/agents.md          # the full contract, port-corrected
TOKEN=$(cat "$HOME/Library/Application Support/dev.mandeck.native/cli-token")
```

## 1. The orchestrator loop — spawn, wait, report

```bash
JOB=$(mandeck job spawn claude-code --dir ~/myrepo -p "fix the failing test" \
        --check-after 30 | cut -f1)         # job-id \t session \t pane
mandeck job wait "$JOB" --timeout 1200      # blocks; exit 0=done 2=failed 3=waiting-you 4=timeout
case $? in
  0) mandeck job report "$JOB" ;;           # transcript + screen — summarize this to your user
  3) mandeck screen "$JOB" 30               # it asked a question — read it,
     mandeck job send "$JOB" "yes, use bun" ;;  # answer it, wait again
  4) mandeck screen "$JOB" 30 ;;            # still running — honest timeout, look before deciding
esac
```

Rules that make this work (all enforced, all verified):

- `done`/`failed` come ONLY from explicit signals. Silence, an idle prompt,
  `live:false`, unfocus, pane close — none of them finish a job.
- Mentioning `[mandeck job-done]` mid-sentence does NOT finish a job; the token
  must start its own line.
- Set `--check-after` longer than your wait timeout, or the follow-up contract
  reminds you mid-wait (by design; `job report` settles it).

## 2. The worker side — you are the spawned agent

Every API-spawned pane exports `MANDECK_PANE` (your identity) and `MANDECK_JOB`
(the job you owe). Finish honestly:

```bash
mandeck job done          # no id needed — $MANDECK_JOB is read
mandeck job fail          # the work errored; say so, don't fake done
echo "[mandeck job-done]" # equivalent: the token alone on its own line
```

Hand work onward and the follow-up contract makes you own it: spawn with
`--spawner "$MANDECK_PANE"` (the CLI sends it automatically) and the deck will
type a `[mandeck follow-up]` reminder into YOUR pane if you never check the
result.

## 3. Fan out — one task, every repo

```bash
mandeck fanout claude-code "bump deps and run tests" ~/api ~/web ~/cli
# one pane per repo, all in one tab, each with the follow-up contract
mandeck waiting            # which panes need an answer
```

`--force` spawns even where a live pane already holds that agent+cwd; without
it you get `already live` plus the existing session to reuse (409).

## 4. MCP instead of shell

```json
{ "mcpServers": { "mandeck": { "command": "node",
    "args": ["/path/to/mandeck-mcp.mjs"] } } }
```

Fetch the server from a running deck: `GET /cli/mandeck-mcp.mjs`. 23 tools,
1:1 with the routes — `deck_spawn`, `deck_job_wait`, `deck_job_report`,
`deck_screen`, `deck_send`, `deck_key`, `deck_events`, … Same token file, same
loopback-only reach.

## 5. Safety rails you will hit (by design)

```bash
mandeck job spawn shell                    # ✗ job spawn requires --dir (no default $HOME/$PWD)
mandeck job spawn shell --dir ~/x          # second time: ✗ 409 "already live" + existing session
mandeck job done                           # outside a tasked pane: ✗ usage (no $MANDECK_JOB)
curl -X POST .../v1/jobs/<done-job> -d '{"state":"failed"}'   # ✗ 409 "job already done"
```

## 6. Testing without touching the live deck

```bash
./scripts/devtest.sh up      # own state dir, own port (7729), own ~/.mandeck
MANDECK_API_PORT=7729 MANDECK_STATE_DIR=dev.mandeck.native.devtest mandeck ps
./scripts/devtest.sh down    # quits and wipes its state
```

The served `/agents.md` on a test instance rewrites its examples to the test
port, so nothing you copy-paste from it reaches the live deck.
