# Commands

Catalogue of every user-facing command shipped by `dowel`. Twenty-two commands, grouped by intent.

Every command is invoked as `dart run dowel <name>`, or as `./bin/dowel <name>` once the project has run `install` (the fast wrapper). Commands are auto-discovered through the registered providers list; nothing wires by hand.

Need a quick reminder of what a command does without leaving the terminal? Run `dart run dowel list` for the full registry grouped by namespace, or `dart run dowel help <name>` for the per-command flag surface. This page exists for the deeper view: the boot mode, the MCP exposure, and the grouping rationale.

- [How to read this page](#how-to-read-this-page)
- [Naming conventions](#naming-conventions)
- [Lifecycle](#lifecycle)
- [Scaffolding](#scaffolding)
- [Plugin management](#plugin-management)
- [MCP](#mcp)
- [Introspection](#introspection)
- [Code generation](#code-generation)
- [Featured deep-dives](#featured-deep-dives)
- [Boot mode at a glance](#boot-mode-at-a-glance)
- [Related Documentation](#related-documentation)

## How to read this page

Each group section ships a single table with four columns:

- **Command** is the canonical name you type after `dart run dowel` (or `./bin/dowel`).
- **Description** is a one-line summary of the command, drawn from the `description` getter that `dart run dowel list` prints (reworded here where the getter's wording has fallen behind the behaviour, for example the `~/.dowel/state.json` path it still names for `start` and `stop`).
- **Boot Mode** is the `CommandBoot` value the dispatcher reads before invoking `handle()` (see `lib/src/console/command_boot.dart`). `none` means pure CLI: no Flutter binding, no VM Service connection. `connected` means the command dials this project's session and fails fast if no app is running.
- **MCP Tool** is the canonical `dowel_*` tool name surfaced over stdio JSON-RPC by `mcp:serve`, or the literal `no` when the command is not in the substrate allowlist. The allowlist lives in `lib/src/mcp/mcp_server.dart` (`_safeDowelCommandNames`, ten commands) and intentionally omits `help`, codegen, installer, and MCP-meta commands.

## Naming conventions

Two shapes appear in the catalogue:

- Single word (`start`, `stop`, `status`, `logs`, `restart`, `reload`, `hot-restart`, `doctor`, `tinker`, `help`, `list`, `install`) for top-level actions on the substrate.
- Namespaced `<group>:<verb>` (`make:plugin`, `make:command`, `make:fast-cli`, `plugin:install`, `plugin:uninstall`, `plugins:refresh`, `mcp:serve`, `mcp:install`, `mcp:uninstall`, `commands:refresh`) for actions scoped to a subsystem.

`hot-restart` is a single word that happens to contain a hyphen: it lives in the lifecycle group and is not namespaced, so `list` prints it among the commands without a heading. It sends the `R` keypress to `flutter run`.

## Lifecycle

Seven commands that own the running Flutter process: spawn, stop, query, tail, restart, reload, hot-restart. All run pure CLI; none of them boot Flutter or Magic in the dowel process. State lives in a per-project session directory under `~/.dowel/sessions/`, written by `start` and consumed by everything that needs the VM Service URI. `~/.dowel/state.json` remains a pointer to whichever session started last. Any command that acts on the recorded app refuses when the session belongs to another project, so a `stop` from the wrong checkout cannot kill a sibling's run.

All seven are also surfaced as MCP tools. Together with `list`, `doctor` and `tinker` from the [Introspection](#introspection) group they make up the ten MCP tools, the agent-facing surface area of the substrate.

| Command | Description | Boot Mode | MCP Tool |
|:---|:---|:---|:---|
| `start` | Boot `flutter run -d <device>` detached and record the VM Service URI to this project's session. | none | dowel_start |
| `stop` | Stop the running flutter app's whole process group, wait until it and its web port are gone, and delete this project's session. | none | dowel_stop |
| `status` | Print JSON status of the recorded flutter app. | none | dowel_status |
| `logs` | Print or `--follow` the captured flutter run log. | none | dowel_logs |
| `restart` | Stop and start the running flutter app; carries the prior session's device, web port, VM Service port, CDP port, `--flutter-arg` values and profile build mode across. | none | dowel_restart |
| `reload` | Hot reload the running app (sends `r` to flutter run's stdin). State preserved. | none | dowel_reload |
| `hot-restart` | Hot restart the running app (sends `R` to flutter run's stdin). Drops Dart state, keeps process. | none | dowel_hot_restart |

## Scaffolding

Four commands that write source files into the consumer project. They are deliberately excluded from the MCP allowlist: source mutation is better routed through the client's own file tools, and the stub system uses placeholder substitution (`{{ name }}`, `{{ pascalName }}`, `{{ commandPrefix }}`) that benefits from interactive prompts.

| Command | Description | Boot Mode | MCP Tool |
|:---|:---|:---|:---|
| `make:plugin` | Scaffold a new dowel plugin skeleton. | none | no |
| `make:command` | Scaffold a new DowelCommand subclass under `lib/app/commands/` (or `lib/src/commands/` when run inside a plugin). | none | no |
| `make:fast-cli` | Scaffold the POSIX `bin/dowel` wrapper and pre-compile the AOT cache under `.dowel/cli-bundle/` for about 100 ms startup. | none | no |
| `install` | Scaffold the canonical native Flutter consumer wrapper (`bin/dispatcher.dart` plus `lib/app/_plugins.g.dart` plus `lib/app/commands/_index.g.dart`) and chain `make:fast-cli` in-process. | none | no |

## Plugin management

Three commands that maintain the `.dowel/plugins.json` registry and its generated barrel `lib/app/_plugins.g.dart`. Atomic writes (`.tmp` plus rename) across every mutation, so concurrent readers (editors, lint daemons) never observe partial state. `plugin:install` routes through two modes (manifest, direct registration) depending on whether the plugin ships an `install.yaml`.

| Command | Description | Boot Mode | MCP Tool |
|:---|:---|:---|:---|
| `plugin:install` | Register a third-party dowel plugin (`install.yaml` manifest preferred; direct registration into the dowel scaffold otherwise). | none | no |
| `plugin:uninstall` | Uninstall a third-party dowel plugin (reverses the install manifest). | none | no |
| `plugins:refresh` | Regenerate `lib/app/_plugins.g.dart` from `.dowel/plugins.json` registry. | none | no |

## MCP

Three commands: `mcp:serve` runs the dowel MCP server, and `mcp:install` and `mcp:uninstall` wire it into a host like Claude Code, Cursor, or Windsurf. The `mcp:*` meta commands recurse into the server and are intentionally excluded from the allowlist. Per-tool visibility is configured via `.dowel/mcp.json`, environment variables, and CLI flags (the three layers compose Cargo-style: file plus env plus flags, with deny rules always winning).

| Command | Description | Boot Mode | MCP Tool |
|:---|:---|:---|:---|
| `mcp:serve` | Run the dowel MCP server (stdio JSON-RPC) for Claude Code, Cursor, Windsurf. | none | no |
| `mcp:install` | Add the dowel MCP server entry to `.mcp.json` (idempotent; preserves other server entries). | none | no |
| `mcp:uninstall` | Remove the dowel MCP server entry from `.mcp.json` (preserves other entries). | none | no |

## Introspection

Four commands that observe the substrate or its host. `tinker` is the only command in the catalogue with `CommandBoot.connected`: it dials the running app's VM Service. It is still exposed as `dowel_tinker` (its `--eval` one-shot path drives the MCP tool); `help` is the one command here outside the MCP allowlist.

| Command | Description | Boot Mode | MCP Tool |
|:---|:---|:---|:---|
| `help` | Show detailed help for a single command. | none | no |
| `list` | List every registered command grouped by namespace. | none | dowel_list |
| `doctor` | Run environment preflight checks (flutter, dart, port availability). | none | dowel_doctor |
| `tinker` | Connected REPL into the running Flutter app (Dart expression evaluation via VM Service). | connected | dowel_tinker |

## Code generation

One command that rewrites the `lib/app/commands/_index.g.dart` barrel. Codegen sits in its own bucket because the consumer rarely runs it by hand: `make:command` and `plugin:install` invoke it as a follow-up step. The generated barrel is never edited manually; the source of truth is the set of `*_command.dart` files under `lib/app/commands/`.

| Command | Description | Boot Mode | MCP Tool |
|:---|:---|:---|:---|
| `commands:refresh` | Rescan `lib/app/commands/` and rewrite the auto-discovery index. | none | no |

## Boot mode at a glance

Twenty-one of the twenty-two commands run with `CommandBoot.none`. Only `tinker` is `CommandBoot.connected`, because its job is to evaluate Dart expressions against a live VM Service isolate. Everything else (lifecycle commands included) shells out to `flutter run` or operates on disk; the dowel process itself never depends on a Flutter binding.

This separation is what lets the substrate ship as a pure-Dart package: the consumer wrapper supplies the optional Magic / Flutter context, while the framework itself stays runtime-free.

A third boot mode, `headless`, is reserved for a V1.x release that will let Magic-bound commands (think `migrate`, `db:seed`) boot just enough of the host to read `Magic.Config` without spinning up a UI.

## Featured deep-dives

Seven commands earn their own pages because their flags, modes, or composition rules outgrow a single table row:

- [start](https://anilcancakir.com/dowel/docs/v0.0/commands/start.md)
- [plugin:install](https://anilcancakir.com/dowel/docs/v0.0/commands/plugin-install.md)
- [mcp:serve](https://anilcancakir.com/dowel/docs/v0.0/commands/mcp-serve.md)
- [make:plugin](https://anilcancakir.com/dowel/docs/v0.0/commands/make-plugin.md)
- [make:fast-cli](https://anilcancakir.com/dowel/docs/v0.0/commands/make-fast-cli.md)
- [install](https://anilcancakir.com/dowel/docs/v0.0/commands/install.md)
- [tinker](https://anilcancakir.com/dowel/docs/v0.0/commands/tinker.md)

Slug rule: the deep-dive URL drops the `:` separator in favour of `-`, so `plugin:install` lives at `commands/plugin-install/`, `mcp:serve` at `commands/mcp-serve/` and `make:fast-cli` at `commands/make-fast-cli/`. The remaining fifteen commands share this index page; reach for `dart run dowel help <name>` for their full flag surface.

## Related Documentation

- [Getting Started](https://anilcancakir.com/dowel/docs/v0.0/getting-started/index.md): what dowel is and how the pieces fit.
- [MCP Tool Reference](https://anilcancakir.com/dowel/docs/v0.0/mcp/tool-reference.md): the ten substrate tools these commands map to.
- [Signature DSL](https://anilcancakir.com/dowel/docs/v0.0/reference/signature-dsl.md): how a command declares its arguments and flags.
