# Commands

> Every droost command and what it does: knowing the code, the run, what the agent records, the intake, tickets, your own commands, setup, and ddev droost on DDEV.

Every command is `tools/droost/vendor/bin/droost <command>`. On DDEV it is
`ddev droost <command>`, once you have added [the DDEV command](#on-ddev-ddev-droost).

- `droost` on its own lists the commands; `droost workflow:help` lists every
  `workflow:` one.
- `droost <command> help` explains one.
- `--project=<path>` works on every `workflow:` command and names the project,
  when you are not in its root folder.

You rarely type most of these. In Claude Code, `/droost:workflow:start`,
`/droost:workflow:continue` and `/droost:workflow:status` drive a run, and the
agent calls the rest itself. They are here so you know what each one is when
you see it.

## On DDEV: `ddev droost`

droost runs inside the web container, where the site's PHP and tools are. Add
this file as `.ddev/commands/web/droost` and make it executable
(`chmod +x .ddev/commands/web/droost`):

```bash
#!/usr/bin/env bash

## Description: Run droost (tools/droost) inside the web container.
## Usage: droost [command] [arguments]
## Example: ddev droost workflow:status
## ExecRaw: true
## MutagenSync: true

bin="${DDEV_COMPOSER_ROOT:-/var/www/html}/tools/droost/vendor/bin/droost"
if [ ! -f "$bin" ]; then
  echo "droost is not installed: run composer install -d tools/droost" >&2
  exit 127
fi
exec php "$bin" "$@"
```

Then every command below is `ddev droost <command>`, for example
`ddev droost workflow:status`. Commit the file so the whole team has it.

The two `##` lines matter:

- **`ExecRaw: true`** passes your arguments exactly as typed. Without it, DDEV
  joins them into one line, and a quoted sentence such as
  `ddev droost workflow:bypass "fixing the footer"` reaches droost as separate
  words.
- **`MutagenSync: true`** syncs the files droost writes in the container back
  to your machine at once.

`ddev exec tools/droost/vendor/bin/droost <command>` also works for a
command with no quoted text.

## Knowing the code

These read your files only, and answer even when the site is broken.

| Command | What it does |
|---|---|
| `code:wiki [page]` | your project's notes, and a page for every installed module and theme: its version, what it needs, what it provides |
| `code:tree [module or path]` | your custom code: modules, files, classes, hooks, services, routes |
| `search:arch "<words>"` | searches all the documentation as plain text: the wiki and every module's README and docs |
| `code:symbol <name>` | where a class, interface, function or method is defined, by part of its name |
| `code:graph <symbol>` | what it calls, what calls it, what it injects. Also takes `service:<id>`, `route:<name>` and `hook:<name>` |
| `search:code "<query>"` | searches symbol names and the wiki; with embeddings set up, also the code nearest in meaning |
| `code:docs` | reads and searches module documentation (README, `*.md`, `*.api.php`) |
| `code:deprecations [symbol]` | Drupal core's deprecations, offline: an exact symbol, `search` for part of a name, or nothing for totals |
| `brief` | the whole project in one answer: Drupal and PHP versions, custom code, contrib count, house rules, whether the index and wiki are there |

## Keeping the map up to date

| Command | What it does |
|---|---|
| `code:index [--full]` | builds or refreshes the code index; `--full` rebuilds it from scratch. Run it after an upgrade or a big change |
| `code:wiki status [--json] [--strict]` | which wiki pages are out of date with the code they describe |
| `code:wiki stamp <page>` | marks a page as up to date once it has been re-read (`--all-stale` for every stale page, `--dry-run` to preview) |

## The run

| Command | What it does |
|---|---|
| `workflow:run` | opens a run, or runs the current step's checks and moves on. `--spec=<path>` names the spec; `--ticket=<id>` ties it to a ticket |
| `workflow:status` | where the run is, and what the project's settings resolve to |
| `workflow:report` | the run as a readable report: each step, each check's result and why, the requirements, the review |
| `workflow:answer "<answer>"` | answers the question the run is waiting on |
| `workflow:lead human-led` | makes the open run yours to finish (making it autonomous is your command, below) |
| `workflow:swap agentic` | stops holding at each step and lets the run go through to the end |
| `workflow:reset [--force]` | clears a finished run, keeping its record in `history/`; `--force` abandons one still open |
| `workflow:gate [--phase=code\|test\|complete]` | runs one step's checks now, with no run, recording nothing. `--base=<ref>` checks what changed since a commit; `--skip=<gate,…>` leaves checks out |
| `workflow:specs` | runs the browser tests now, as the test step would, and records the result |
| `workflow:criteria [--json]` | the requirements and what proved each one |
| `workflow:rules [--json]` | the house rules the run is held to |
| `workflow:evidence` | writes the run's evaluation from its record (`--run=<id>` for an old run, `--write` to save it, `--full` for every check's whole output) |
| `workflow:events [--after=<n>]` | the run's event log, one line per event |
| `workflow:panel [--json]` | the run as [the Claude Code plugin's](https://droost.org/docs/claude-plugin.md) panel shows it |

## What the agent records during a run

The agent calls these to put its plan on record. droost then checks the
work against them.

| Command | What it does |
|---|---|
| `workflow:declare-changes --files=<a,b> --tests=<X,Y>` | what the run will touch, before it touches it; a file it did not declare blocks the code step. `--type=` says what kind of change it is |
| `workflow:declare-route <path> "<what>"` | a page the change serves. `--status=403`, `303`, `404`, `410` or `405` for one that refuses, redirects, waits to be published, is gone, or takes only POST |
| `workflow:declare-criterion <id> "<requirement>"` | a requirement the change must meet. Rewording one drops its proof |
| `workflow:verify-criterion <id> "<proof>"` | the test that proves a requirement; `--outcome=partly` or `failed` when it did not fully hold |
| `workflow:declare-note <kind> "<what>" "<why>"` | anything else the spec would say, such as what a lookup found |
| `workflow:declare-browser <tier>` | which browser the session has (`playwright-mcp`, `native`, `none`) |
| `workflow:declare-tasks <host>` | which agent host the session runs in |
| `workflow:seeker-report [<file>]` | records the reviewing agent's findings |
| `workflow:say "<what>"` | tells the panel what the agent is doing now; its own words, never evidence |

## Designs: the intake

For [building a site from a design](https://droost.org/docs/site-from-a-design.md).

| Command | What it does |
|---|---|
| `workflow:intake start --request="<your words>" --source=<path or URL>` | opens an intake for a design |
| `workflow:intake audit --url=<served design>` | reads the design |
| `workflow:intake status` | where the intake is: the questions waiting and the answers so far |
| `workflow:intake ask --file=<questions.json>` | puts questions on record, for an agent with no question dialog |
| `workflow:intake check` | what approval still needs |
| `workflow:intake approve` | approves the plan, once your yes is on record |
| `workflow:intake routes <rung>` | the parity `routes:` value for one stage of the plan |

## Tickets

For [working from tickets](https://droost.org/docs/tickets.md).

| Command | What it does |
|---|---|
| `workflow:ticket list [--status=<state>]` | the project's tickets |
| `workflow:ticket show <id>` | one ticket |
| `workflow:ticket new --title="…"` | files a new ticket in the backlog |

## Yours: from your own terminal

These loosen what a run is held to, or decide what only a person decides. Each
one refuses to run without a real terminal, and the guard refuses them from the
agent. When the agent needs one, it gives you the exact command.

| Command | What it does |
|---|---|
| `workflow:effort [<level>]` | shows the level, or sets it: `low`, `medium`, `high`, `xhigh`, `max`, `custom`. `--preview` shows what a level would change and writes nothing (anyone may run that) |
| `workflow:lead autonomous` | lets the agent finish the open run itself |
| `workflow:gate-waive <gate> "<why>"` | lets one check through for the rest of this run; the report says "waived", never "passed" |
| `workflow:bypass "<why>"` | lets the agent edit custom code with no run open, until `workflow:bypass --off` |
| `workflow:baseline` | records the old code's problems ([On an existing site](https://droost.org/docs/existing-site.md)). `--measure` and `--status` only read, and anyone may run them; `--refresh` re-measures; `--grow --reason="…"` lets a refresh record more |
| `workflow:ticket move <id> <state>` | moves a ticket; only a person moves one to `done` |
| `workflow:intake answer "<question>" "<answer>"` | records your answer to an intake question asked outside the dialog |
| `workflow:intake abandon "<why>"` | closes an intake without approving it |

## Setup

| Command | What it does |
|---|---|
| `init` | installs droost into the project: the skills, the guard's hooks, droost's section of `AGENTS.md` and `CLAUDE.md`, and `droost/droost.yml` if there is none. Run it again after every upgrade |
| `doctor` | what droost can see of the project, line by line |
| `workflow:uninstall` | takes out what `init` installed, keeping `droost/droost.yml` and the run records |
| `migrate` | moves an old `droost.workflow.yml` to `droost/droost.yml` |
| `guard <verb>` | what the guard's hooks call; not for typing |
| `workflow:relay` | for Droost Cockpit (coming soon): sends run events to it |

## Other tools in the package

They are in `tools/droost/vendor/bin/` beside `droost`.

| Tool | What it does |
|---|---|
| `droost-parity capture` / `judge` | captures a design's pages, then compares the site with them ([Parity](https://droost.org/docs/parity.md)) |
| `droost-source` | reads a design for the intake |
| `droost-guard` | the guard on its own, the same as `droost guard` |
| `droost-workflow` | the `workflow:` commands on their own |
