Verify GooeyPi
GooeyPi is a desktop Electron app — that window is the only surface a user
touches (there is no user-facing web page, CLI, or API). This skill launches the
built app in an isolated, disposable profile, drives one user-facing feature the
way a person would, and captures evidence. The driver mirrors the repo's own
Playwright Electron harness (tests/e2e/app.spec.ts) but runs as a standalone
controller you can invoke directly.
The maintained feature list lives in features/; read
its index before driving, then use the matching feature file as the recipe.
Launch
- Build once. The driver launches the built bundle (
package.json main →
out/main/index.js). If it is missing, build it: npm run build. The driver
aborts with a clear message when the bundle is absent.
- Toolchain.
node/npm come from nvm (pinned 24.15.0 / 12.0.2). If
node -v is not v24.15.0, select it first:
export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"; nvm use >/dev/null.
- Display. The app needs an X display. On a headless machine prefix every
command with
xvfb-run -a (e.g. xvfb-run -a --server-args="-screen 0 1600x1000x24" ...).
- Isolation. Every drive launches its own app instance with a throwaway
HOME and Electron --user-data-dir, so it never reads or writes your real
~/.prime / ~/.omp / ~/.pi state and never drives an instance it did not
start. Readiness is .app-shell[data-ready="true"]. A fresh HOME has no
harness installed, so the driver first dismisses the No Pi family harness detected modal (that modal makes the shell inert).
- Command.
xvfb-run -a node .cursor/skills/verify-gooeypi/control.mjs drive <scenario> --out <dir>
Doctor
Answer "is this instance worth driving?" before anything else, or whenever the
app looks wrong:
xvfb-run -a node .cursor/skills/verify-gooeypi/control.mjs doctor --out /tmp/gooeypi-verify/doctor
It launches the app, asserts .app-shell[data-ready="true"], prints the window
title (expect GooeyPi), and screenshots. A non-zero exit means the build is
broken or the app never became ready — fix that before driving features.
Drive
- Harness: Playwright's
_electron driving the built app. Prefer stable
handles over coordinates: sidebar items are buttons with accessible names
New session, Search, Projects, Activity, Scheduled, Capabilities;
each page asserts its level-1 heading; Settings opens from the
.sidebar__footer Settings button and lands on the General heading, with
sections as buttons named Appearance, Pets, Harness, etc.
- Scenarios:
node .cursor/skills/verify-gooeypi/control.mjs list →
navigation, settings, capabilities. Each is one self-contained
launch → drive → capture → teardown. The feature map
documents these plus features (session messaging) that need the repo's
hermetic fixture rather than this driver.
Evidence
- Each scenario writes PNG screenshots and
.aria.txt ARIA snapshots to
--out DIR (default /tmp/gooeypi-verify/<scenario>-<timestamp>) and prints a
PROVEN: list of the assertions it checked.
- Proof standard: drive the real user path and capture both the action and
the resulting page state (heading + ARIA), not just a final screen. For a
mutation (creating a schedule or sending a message), also verify the side
effect — a file written under the harness
HOME, or a second read-only view —
not just a toast. Record the feature ID and the entry point used.
- Artifacts survive teardown. Copy any you want to keep into
/opt/cursor/artifacts for a PR walkthrough.
Cleanup
- The driver closes only the app instance it launched and removes only the
throwaway fixture
HOME/user-data-dir it created. It never deletes evidence
dirs. Never kill Electron by name (pkill electron); the driver owns its
own child process and tears it down.
Helpers
control.mjs (executable). Subcommands: doctor,
drive <scenario>, list. Invoke exactly as shown above; run under
xvfb-run on headless machines.
1---2name: verify-gooeypi3description: Launch and drive the GooeyPi desktop (Electron) app to prove user-facing behavior — sidebar navigation, Settings, and Capabilities — capturing screenshots and ARIA snapshots. Reach for this when verifying a GooeyPi UI change or confirming the app still works end to end.4---56# Verify GooeyPi78GooeyPi is a **desktop Electron app** — that window is the only surface a user9touches (there is no user-facing web page, CLI, or API). This skill launches the10built app in an isolated, disposable profile, drives one user-facing feature the11way a person would, and captures evidence. The driver mirrors the repo's own12Playwright Electron harness (`tests/e2e/app.spec.ts`) but runs as a standalone13controller you can invoke directly.1415The maintained feature list lives in [`features/`](./features/README.md); read16its index before driving, then use the matching feature file as the recipe.1718## Launch1920- **Build once.** The driver launches the built bundle (`package.json` `main` →21 `out/main/index.js`). If it is missing, build it: `npm run build`. The driver22 aborts with a clear message when the bundle is absent.23- **Toolchain.** `node`/`npm` come from `nvm` (pinned `24.15.0` / `12.0.2`). If24 `node -v` is not `v24.15.0`, select it first:25 `export NVM_DIR="$HOME/.nvm"; . "$NVM_DIR/nvm.sh"; nvm use >/dev/null`.26- **Display.** The app needs an X display. On a headless machine prefix every27 command with `xvfb-run -a` (e.g. `xvfb-run -a --server-args="-screen 0 1600x1000x24" ...`).28- **Isolation.** Every drive launches its own app instance with a throwaway29 `HOME` and Electron `--user-data-dir`, so it never reads or writes your real30 `~/.prime` / `~/.omp` / `~/.pi` state and never drives an instance it did not31 start. Readiness is `.app-shell[data-ready="true"]`. A fresh `HOME` has no32 harness installed, so the driver first dismisses the `No Pi family harness33 detected` modal (that modal makes the shell `inert`).34- **Command.** `xvfb-run -a node .cursor/skills/verify-gooeypi/control.mjs drive <scenario> --out <dir>`3536## Doctor3738Answer "is this instance worth driving?" before anything else, or whenever the39app looks wrong:4041```42xvfb-run -a node .cursor/skills/verify-gooeypi/control.mjs doctor --out /tmp/gooeypi-verify/doctor43```4445It launches the app, asserts `.app-shell[data-ready="true"]`, prints the window46title (expect `GooeyPi`), and screenshots. A non-zero exit means the build is47broken or the app never became ready — fix that before driving features.4849## Drive5051- **Harness:** Playwright's `_electron` driving the built app. Prefer stable52 handles over coordinates: sidebar items are buttons with accessible names53 `New session`, `Search`, `Projects`, `Activity`, `Scheduled`, `Capabilities`;54 each page asserts its level-1 heading; Settings opens from the55 `.sidebar__footer` `Settings` button and lands on the `General` heading, with56 sections as buttons named `Appearance`, `Pets`, `Harness`, etc.57- **Scenarios:** `node .cursor/skills/verify-gooeypi/control.mjs list` →58 `navigation`, `settings`, `capabilities`. Each is one self-contained59 launch → drive → capture → teardown. The [feature map](./features/README.md)60 documents these plus features (session messaging) that need the repo's61 hermetic fixture rather than this driver.6263## Evidence6465- Each scenario writes PNG screenshots and `.aria.txt` ARIA snapshots to66 `--out DIR` (default `/tmp/gooeypi-verify/<scenario>-<timestamp>`) and prints a67 `PROVEN:` list of the assertions it checked.68- **Proof standard:** drive the real user path and capture both the action and69 the resulting page state (heading + ARIA), not just a final screen. For a70 mutation (creating a schedule or sending a message), also verify the side71 effect — a file written under the harness `HOME`, or a second read-only view —72 not just a toast. Record the feature ID and the entry point used.73- Artifacts survive teardown. Copy any you want to keep into74 `/opt/cursor/artifacts` for a PR walkthrough.7576## Cleanup7778- The driver closes only the app instance it launched and removes only the79 throwaway fixture `HOME`/`user-data-dir` it created. It never deletes evidence80 dirs. **Never** kill Electron by name (`pkill electron`); the driver owns its81 own child process and tears it down.8283## Helpers8485- [`control.mjs`](./control.mjs) (executable). Subcommands: `doctor`,86 `drive <scenario>`, `list`. Invoke exactly as shown above; run under87 `xvfb-run` on headless machines.