# CLI reference

> Every dobby command and what it does.

Run `dobby help` for the short list and `dobby help --all` for everything below. `dobby <command> --help` prints that command's line and never runs it.

## Getting started

| Command | What it does |
| --- | --- |
| `init [--ui] [--projects a,b]` | set up Dobby on this machine, with no name: checks, sign-ins, your repos, settings, background jobs (asks first); --ui does it in your browser |
| `add <project> "<title>" ["<done when>"] [S\|M\|L] [priority]` | write a ticket |
| `status` | the plan limits line, then what is building, shipped today and stuck |
| `limits` | how much of the 5-hour and weekly plan is used, and when paused work resumes |
| `list [--all]` | open tickets by stage (Building, Ready, Waiting, Failed), 10 per stage; --all = every open ticket (adds backlog), old format; shipped and declined are left out |
| `docs [topic]` | the manual: list the pages, or print one (works offline) |
| `--version` | print the version (the jobs run it once at install to prove node and the path work) |
| `doctor [--json]` | checks tools, sign-ins, background jobs and the pipeline (exit 1 on any failure) |
| `uninstall [--dry]` | stop and remove the background jobs; your data, config and secrets stay |

## Everyday

| Command | What it does |
| --- | --- |
| `cancel <id>` | stop the ticket: kill its build, remove its worktree, close its own PR and branch, mark it declined |
| `pause \| resume` | stop / allow builders claiming new tickets (running ones finish their step, nothing is killed) |
| `queue <id>` | move a backlog ticket to ready |
| `run <id>` | build this ticket now, in this process (no worker cap, budget gate or tick lock; a new project is onboarded first; exit 1 if nothing was built) |
| `show <id>` | every step the ticket's graph took, with tokens and cost |
| `cost <id>` | what the ticket's PR cost, by stage (the same table Dobby posts on the PR) |
| `receipt [days]` | "Shipped N PRs on your plan, $0 extra" for the last 7 days, and the card at <data>/receipt.svg |
| `approve <id> \| decline <id>` | answer a ticket waiting for you (decline on any other ticket = cancel) |
| `merge <id>` | merge a waiting ticket's PR now (a ticket at its gate is approved) |
| `deploy <project>` | the Deploy tap from the terminal (a migration that changes data still waits for its own tap) |
| `answer <id> <words>` | answer a ticket's question: your words join its done rule and it is queued again |
| `hint <id> <words>` | add a hint for the ticket's next build |
| `retry <id>` | a ticket stuck in fixing starts over (its PR is closed); a failed one is queued again |
| `done <id> [--pr N]` | work finished outside Dobby: mark the ticket shipped (and note its PR); nothing is closed, merged or posted |
| `takeover <id>` | pause one ticket and leave its branch to you |
| `allowround <id>` | one more automatic fix round on the ticket's PR |
| `unqueue <id>` | a queued ticket goes back to the backlog |
| `reorder <id> [before]` | move a queued ticket above another (or last) |
| `applyfinding <id>` | a fix ticket on the PR's branch for one review finding |
| `dismissfinding <id>` | a review finding is intentional (later reviews leave it out) |
| `findingrule <id> [words]` | a review finding becomes a rule for the repo |
| `ideaticket <id>` | an idea becomes a ticket and is queued |
| `ideadrop <id>` | drop an idea |
| `dashboard [--port 4710] [--host 127.0.0.1]` | local web dashboard (auto-refresh); makes DASHBOARD_TOKEN in secrets.env on first start |
| `add discord\|dashboard\|jobs` | switch on an add-on: Discord buttons, the local dashboard job, or all six background jobs |
| `add skill [--yes]` | copy the dobby-setup skill into ~/.claude/skills (asks first), for fixing a setup problem in your own Claude Code |
| `mcp` | the MCP server on stdio, so Claude can read status and file tickets; asks you before it merges, deploys or cancels. dobby add mcp [--yes] connects it to Claude Code; --http prints the command for the dashboard's /mcp instead |
| `jobs install\|uninstall\|status [--dry]` | the six background jobs (launchd on macOS, systemd --user on Linux) |
| `config [show\|path]` | the merged config (secrets redacted) / where the private config file lives |
| `stats [on\|off [crashes\|usage]]` | opt-in crash reports and usage stats: status, or turn them on or off (both are off until you say yes) |
| `config set <key> <value>` | change one setting in your private config, checked against the schema (config unset <key> puts it back to the default) |
| `start` | run Dobby in this terminal: the Discord listener and the queue loop (Ctrl-C stops it) |

## More commands

| Command | What it does |
| --- | --- |
| `goals [app] \| goals import <app>` | the goals in rank order; import turns the project file's goals into GitHub milestones |
| `stats show\|log\|reset-id\|report [--days 30]` | usage stats: the next payload exactly as it would be sent / every payload sent so far / a new random install id / the report from your own Worker (needs DOBBY_STATS_REPORT_TOKEN) |
| `tick` | one scheduler step: run the top ticket if the budget allows (the background job calls this) |
| `pause [all\|builders\|reviews\|merges\|deploys\|planning\|scout\|notify\|project <name>\|ticket <id>] [for 30m\|2h\|1d]` | one pause system with levels; resume takes the same target; all also kills the running builds; "for" auto-resumes |
| `pause status` | what is paused, since when, until when |
| `graph` | the ticket graph as a Mermaid diagram |
| `idea <project> "<idea>"` | drop a seed idea for the Product Manager |
| `ideas [project]` | idea cards, best first |
| `pm <project> [--area]` | Product Manager now: ranked problems by goal, PRDs for L, idea cards (--area: today's Area PM) |
| `dedupe <project>` | merge tickets and ideas that are the same work (Haiku); run after onboard |
| `tools [on\|off <name>]` | agent tools (graphify, rtk, caveman, ponytail, jev): on/off, found or not, install command; on/off edits your config |
| `company` | distil your global Claude memory into company.md (work rules only) |
| `init <project>` | add one repo by name or path, without the machine setup: draft its dobby.md, then onboard it and ask which of the first backlog tickets to queue (also runs by itself before a project's first ticket; with --yes or no terminal nothing is queued) |
| `onboard <project>` | read all the project's docs and skills into Dobby (rules draft, backlog tickets, ideas, knowledge map) |
| `lead [project] [--dry]` | the Lead plans: promotes up to 3 backlog tickets, writes up to 3 new ones (all active projects if none given) |
| `cos [--dry]` | the Chief of Staff's morning summary (Discord #daily-update), plus Approve/Decline for waiting tickets |
| `brief [YYYY-MM-DD] [--dry]` | print a day's sent summary (<data>/briefs/<day>.md); --dry builds today's from live facts, sends nothing |
| `ask <message>` | talk to the front desk from the terminal ("status" answers at once, no AI) |
| `listen` | always-on Discord listener (the listener background job); also runs the telemetry receiver |
| `telemetry-serve [port]` | only the Claude Code telemetry receiver (127.0.0.1, default 4711 or DOBBY_OTEL_PORT), for testing |
| `service install\|uninstall [--dry]` | run `start` as a background service (launchd on macOS, systemd --user on Linux); refuses while the tick/listener background jobs exist |
| `discord invite\|setup\|test` | the bot invite link; create channels + webhooks (idempotent); one hello per channel |
| `review <owner/repo> <pr> [--full]` | the Reviewer on one PR by hand (a draft too): PR comment + "Claude Review" status; --full = the whole PR |
| `review-scan [--dry]` | review new heads of open PRs on the repos that matter (the listener runs this every 15 min; the tick job does when Discord is off) |
| `usage [days]` | Claude usage report: API-$ by model, cache hit, $ per 1% of each limit (reads this computer's ~/.claude logs, whatever DOBBY_DIR is) |
| `scoreboard [days]` | PRs opened, needed changes, merged (default 7 days) |
| `usage-log` | usage reading stored every 10 min by the listener: 5h %, weekly %, API-$ by model and token kind |
| `capacity` | how full the 5-hour windows got this week, and what to change |
| `touch <ticket\|-> <decision\|broke\|unclear\|permission> [note]` | log a fix you made by hand (counted in the autonomy line) |
| `api [on\|off\|status]` | Max plan API credits for text-only jobs |
| `health` | the hourly self-check |
| `graphify` | refresh every project's code graph (daily 05:30) |
| `scout` | Talent Scout now (normally once a night) |
| `safety explain "<ticket text>"\|<pr>` | categories, rule, action and why from the safety config |
| `policy explain "<text or path>"` | which of your rules match, per kind, and which one wins |
| `migrate [--dry-run]` | move an older setup into the new config (never overwrites) |
| `providers [detect\|models\|explain]` | read-only: agent CLIs, API key env var NAMES and local servers found; live model lists; planned routing per role |
| `role show\|save\|reset <name> [text]` | read a role (your edit, else the built-in), save your edit into the config folder (text as an argument, or on stdin; without a --- block at the top it keeps the role's model line), or reset puts the built-in back |
| `dashboard link [--host <name>] [--port 4710]` | print the sign-in link for another device (a tunnel or Tailscale name with --host); no QR code |
| `dashboard --tunnel [--port 4710]` | for a phone behind an HTTPS tunnel: every request needs the token. Port 4710 is the job's, so use --port 4711 beside it |
| `dashboard open [--port 4710]` | open the running dashboard in your browser, signed in (the token goes in an HttpOnly cookie; this command does not print it) |
