Overview
ppd is a CLI, a set of vitest helpers and a Claude Code skill for people who write Paseo plugins. It gives you a dev daemon
you can break, checks your plugin against what the host really accepts, and drives the web UI and a phone, without
ever touching the Paseo you use every day.
A community project, not affiliated with or endorsed by the Paseo team. It relies on parts of Paseo that are not a public API and was verified on Paseo 0.11.4. See Compatibility.
Why it exists
It was built while shipping a real plugin (a PDF and Office viewer). Each of these cost days, and each is now a check, a guard or one command:
- Hand-built isolated daemons. Testing a plugin means a temp home, a free port, plugins and the web UI on, relay
off. One wrong flag and you restart or reconfigure your real daemon on port 6767.
ppd daemon updoes it safely in one line. - Host-contract surprises found late. An icon name the app's Lucide build lacks makes the button silently vanish.
classsyntax in a dependency passes on web and crashes on phones (Hermes). A module the host does not provide throws only at load.ppd checkfinds these before install. - No agent to test against. Hooks, timeline cards and injected MCP tools need agent turns. The fake agent runs scripted turns with no credentials.
- Registry submission gotchas. Issues filed with
gh issue createmiss thesubmissionlabel and are ignored. Git listings never get automatic update PRs. The validator fails on macOS temp paths.ppd registryhandles all three. - Device testing friction.
adb reverse, which device, is the phone unlocked, and never pressing keys on someone else's phone.ppd android upconnects it and reports state, read-only.
What you get
| Piece | What it is |
|---|---|
ppd CLI | create, daemon, install, dev, paseo, web, android, doctor, check, registry, release. See Commands. |
paseo-plugin-devkit/vitest | describeHostContract(dir): one vitest test per host-contract check. |
paseo-plugin-devkit/testing | runChecks, assertWithinRpcBudget and the pieces behind ppd check. |
paseo-plugin-devkit | Daemon, install and fake agent helpers for tests: runFakeAgentTurn, sendFakeAgentTurn, agentTimeline, pluginRows. |
paseo-plugin-devkit/web | PaseoWeb, the Playwright page object behind ppd web. |
| Claude Code skill | skills/paseo-plugin-dev: the isolated-daemon loop, the safety rules, the host-contract table and device testing, for an agent working on your plugin. |
Requirements
| For | You need |
|---|---|
| Everything | Node >=22.18, macOS or Linux. |
daemon, install, dev, web, fake agent | The Paseo CLI. The desktop app ships it; ppd also finds it inside /Applications/Paseo.app. |
check with the real compiler | The Paseo desktop app, or a getpaseo/paseo checkout in PASEO_SOURCE. Without either, check runs a labeled approximation. |
web | Google Chrome, or a Playwright Chromium matching playwright-core. |
| Hermes checks | react-native as a devDependency of the plugin (it ships hermesc and the Hermes VM), or HERMESC and HERMES. |
android | adb (Android platform-tools) and the Paseo app on the phone. |
ppd doctor reports most of these in one go. It does not look for the Hermes VM, and it warns about a missing
Chrome even when a Playwright Chromium is installed.
Install
In a plugin:
npm install -D paseo-plugin-devkit
npx ppd doctor Outside a project, name the package: the npm name ppd belongs to an unrelated package.
npx --package paseo-plugin-devkit ppd create ~/code/my-plugin Next
- Getting started: create a plugin, run it on a dev daemon, screenshot it.
- Host-contract checks: what
ppd checkverifies and how to read its output. - Fake agent: scripted agent turns for hooks, timeline cards and MCP tools.
- Safety model: why
ppdcannot reach your real daemon.