Every command is tools/droost/vendor/bin/droost <command>. On DDEV it is
ddev droost <command>, once you have added the DDEV command.
drooston its own lists the commands;droost workflow:helplists everyworkflow:one.droost <command> helpexplains one.--project=<path>works on everyworkflow: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):
#!/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: truepasses your arguments exactly as typed. Without it, DDEV joins them into one line, and a quoted sentence such asddev droost workflow:bypass "fixing the footer"reaches droost as separate words.MutagenSync: truesyncs 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 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.
| 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.
| 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). --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) |
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 |