Commands

Every command and option, generated from ppd --help and ppd help <command> by a script. CI fails when this page and the CLI disagree.

CommandWhat it does
ppd create <dir>new plugin from a template (panel, agent-hook) that passes check
ppd daemon up|down|statusstart, stop or inspect an isolated dev daemon
ppd install [dir]install or reload a plugin in the dev daemon
ppd dev [dir]install, then reload on every change and stream plugin logs
ppd paseo -- <args...>run the Paseo CLI against the dev daemon
ppd webopen the web UI in Chrome, screenshot, click through
ppd android up|down|statusadb reverse to the dev daemon (read-only device checks)
ppd doctortoolchain report
ppd check [dir]compile, evaluate and lint a plugin against the host contract
ppd release <bump>bump, changelog, tag, push, GitHub release
ppd registry <sub>precheck, update or submit a registry listing

Start

ppd create <dir>

ppd create <dir> [--template panel|agent-hook] [--id ID] [--name NAME] [--devkit SPEC] [--paseo BIN] [--no-init]

Creates a plugin in dir (missing or empty) that passes `ppd check` and installs as is. The base comes from
`paseo plugin init` (SDK versions matching your Paseo), else a built-in copy of the same layout. Added on top:
tsconfig node types, an @types/node ~22 pin, .gitignore, vitest with a host-contract suite, npm scripts
(check, test, dev, typecheck) and a README.

  --template T  panel (default): workspace panel + Command Center item + one RPC (the devkit's hello-plugin)
                agent-hook: server.on("agent.turn_ended") appends a timeline card; client renderer + screen
  --id ID       manifest id (default: the directory name)
  --name NAME   display name (default: from the id)
  --devkit SPEC package.json spec for paseo-plugin-devkit (default: ^0.1.0, this release on npm;
                use file:/path/to/clone for a local checkout)
  --paseo BIN   Paseo CLI for `plugin init` (default: PASEO_BIN, PATH, the desktop app)
  --no-init     skip `paseo plugin init` and use the built-in base

Dev daemon

Isolated: temp home, never port 6767, never ~/.paseo.

ppd daemon up|down|status

ppd daemon up [--port N] [--name N] [--workspace DIR] [--fake-agent] [--web-dist DIR] [--caffeinate] [--paseo BIN]
ppd daemon down [--name N] [--keep-home]
ppd daemon status [--name N] [--json] [--all]

Starts a detached Paseo daemon in a fresh home under $TMPDIR on a free port (7800-7899), with plugins and the web
UI on and relay, MCP and speech off. State lives in ~/.local/state/paseo-plugin-devkit (PPD_STATE_DIR).

  --port N         port to listen on (6767 is refused)
  --name N         run several daemons side by side (default: "default")
  --workspace DIR  create a workspace for DIR after startup
  --fake-agent     install the credential-free "fake-agent" provider: each prompt that is a JSON script
                   ({"steps":[{"write":{...}},{"mcp":{...}},{"say":"..."}]}) runs as a deterministic turn
  --web-dist DIR   Paseo web UI build (default: the desktop app's app-dist)
  --caffeinate     keep a Mac awake while the daemon runs
  --paseo BIN      Paseo CLI to use (default: PASEO_BIN, PATH, the desktop app)
  --keep-home      down: keep the temp home for inspection
  --all            status: list every recorded daemon

ppd install [dir]

ppd install [dir] [--git] [--id ID] [--name N]

Installs the plugin in dir (default: cwd) into the dev daemon and prints its status and logs. An id that is
already configured is reloaded (same directory) or replaced, so rerun it after every edit. The client is
checked against the app's registration rules (icons, ids, contexts, cleanup): the app drops a client that
breaks them with only a console warning. Exits 1 unless the plugin is running and its client passes.

  --git     install the committed HEAD through the manifest build, like a registry install
  --id ID   plugin id to install as (default: manifest id, plus "-git" with --git)
  --name N  target dev daemon

ppd dev [dir]

ppd dev [dir] [--id ID] [--name N]

Installs the plugin in dir (default: cwd) into the dev daemon, then watches dir: every change reloads the
plugin (`paseo plugin reload`), re-checks the client against the app's registration rules and prints the
result. New plugin log lines stream as they appear. Ctrl+C stops watching; the plugin stays installed.
Changes under node_modules, dist and dot directories are ignored.

  --id ID   plugin id to install as (default: manifest id)
  --name N  target dev daemon

ppd paseo -- <args...>

ppd paseo [--name N] -- <args...>

Runs the Paseo CLI against the dev daemon. --home is always appended; --home and --host are refused.
Example: ppd paseo -- plugin logs hello-plugin

ppd web

ppd web [--shot FILE] [--viewport WxH] [--command TEXT] [--click LABEL]... [options]

Opens the dev daemon's web UI in Chrome (Playwright), opens the only workspace (or --workspace), runs the
steps in order and prints console errors.

  --shot FILE         save a screenshot
  --viewport WxH      e.g. 390x844; widths under 768 get the compact (phone) layout with touch
  --command TEXT      select a Command Center item by its exact title
  --click LABEL       click an element by its accessible name (repeatable)
  --workspace ID      workspace id, name or path
  --path /route       open an app route instead of a workspace
  --wait MS           settle time before the screenshot (default 1500)
  --full-page         full-page screenshot
  --headed            show the browser
  --name N            target dev daemon

ppd android up|down|status

ppd android up|down|status [--serial S] [--name N] [--port N]

up: adb reverse tcp:<port> so a phone running the Paseo app reaches the dev daemon as localhost:<port>.
down: removes the reverse rule. status: device state (screen, lock, foreground app) and reverse rules.
Never sends input or key events and never changes settings. Refuses to guess between several devices.

  --serial S  device serial (required when several are attached)
  --name N    dev daemon whose port to reverse
  --port N    reverse this port instead of a dev daemon's (6767 is refused)

ppd doctor

ppd doctor [--json]

Reports Node, the Paseo CLI, the web UI build, PASEO_SOURCE, a browser, Hermes, adb, Xcode, git, gh, free
disk and running dev daemons. Read-only. Exits 1 only when something required is missing.

Host contract

ppd check [dir]

ppd check [dir] [--json] [--paseo-app APP] [--paseo-source DIR] [--approx] [--max-client-kb N] [--max-server-kb N]

Host-contract checks on the plugin in dir (default: cwd): manifest, import boundaries, dependencies,
compile, server and client evaluation (in child processes, 30 s timeout), the app's registration rules,
Hermes, Lucide icon names, bundle size. Exits 1 on any FAIL.

The compiler and icon list come from, in order: --paseo-source / PASEO_SOURCE (a Paseo checkout), the
installed Paseo app (--paseo-app / PASEO_APP, the app behind `paseo` on PATH, /Applications/Paseo.app),
else an esbuild approximation, labeled APPROXIMATION in the output.

  --paseo-app APP     Paseo.app to compile with (default: discovered)
  --paseo-source DIR  Paseo checkout with node_modules (default: PASEO_SOURCE); wins over the app
  --approx            force the approximation (what CI without Paseo sees)
  --max-client-kb N   client bundle budget (default 2048)
  --max-server-kb N   server bundle budget (default 32768)
  --json              machine-readable results

Release and registry

User-run.

ppd release <bump>

ppd release <patch|minor|major|X.Y.Z> [--dry-run] [--yes] [--dir DIR] [--skip-precheck]

Bumps package.json, writes a CHANGELOG.md section (from commits if missing), commits, tags, pushes and
creates a GitHub release. Refuses without a TTY unless --yes.

  --dry-run        print the plan and commands, change nothing
  --yes            skip the confirmation prompt
  --dir DIR        plugin directory (default: cwd)
  --skip-precheck  do not block on registry precheck errors

ppd registry <sub>

ppd registry precheck [dir] [--json]
ppd registry update [dir] --registry DIR [--tag vX.Y.Z] [--id owner/slug] [--yes]
ppd registry submit [dir]

precheck  what the registry reviewer would bounce: OVERVIEW.md lint, media and icon, lockfile, build,
          listing files committed. Exits 1 on errors.
update    record-edit branch in your getpaseo/plugins fork for a Git release, runs the registry validator,
          prints push and PR commands (--yes runs them).
submit    prints the prefilled submission form URL. Submit it in a browser: CLI-created issues miss the
          submission label.

Exit codes

CodeMeaning
0Success. ppd check passes with warnings and skips.
1A failed check, a plugin that is not running or whose client the app would reject (install), a plugin client the app failed to evaluate (web), device warnings (android status), a missing tool (doctor), or a usage error.
3A safety refusal, printed as refused: ...: port 6767, a home overlapping ~/.paseo, --home or --host passed to ppd paseo. Nothing was started or changed.

ppd paseo exits with the Paseo CLI's own code.