| name | screenshot-studio |
| description | Regenerate the Pisper product screenshots under docs/shots/ against the current UI. Starts an isolated dev instance, seeds fictional demo data through the real runtime APIs, captures every referenced page at the exact 2558x1380 asset size, and replaces the files. Use only when the user asks to refresh product screenshots or when the docs gallery no longer matches the UI. |
| disable-model-invocation | true |
| allowed-tools | read grep find ls edit write bash |
Screenshot Studio
Refresh the screenshots in docs/shots/ so the product site and README previews match the current UI. Do not change product code; only capture and replace images (and the references that name them, when needed).
When to use
Invoke only when the user explicitly asks:
/skill:screenshot-studio
This skill is for screenshot refresh work only. Do not run it during ordinary implementation or review.
Output invariants
- Every current Web screenshot PNG is exactly 2558x1380 (viewport
1279x690 at deviceScaleFactor 2); its WebP thumbnail is 1600x864.
- The current Web set is derived from the
shots/web/*.webp references in docs/index.html and docs/show.html; deleted scenes are not recreated.
cli.png, cli-chat.png, the mobile assets, and other non-Web/demo assets are left untouched.
- No real user data, provider keys, or machine paths may appear. Use only fictional demo content and repository-relative paths.
- The isolated instance must never read the user's
~/.pisper/agent or the port-5173 dev server state.
Workflow
1. Start an isolated dev instance
node .pisper/skills/screenshot-studio/scripts/start-isolated-server.mjs --reset
This stops any prior Skill-owned process, clears only the configured screenshot agent/run directories, starts runtime/index.mjs, and waits for /api/health. Defaults are port 5180 and repository-relative directories under generated/; no project path is hard-coded.
2. Seed fictional demo data
node .pisper/skills/screenshot-studio/scripts/seed-demo-data.mjs
Creates through the real runtime APIs (never by editing the UI): six sessions, three with injected conversation transcripts, three empty; link, Markdown, and generated-image assets; a memory space with nodes; schedules; workflows (one published); and a configured OpenAI-compatible provider. Writes the created ids to generated/screenshot-run/state.json.
2b. Restart the isolated instance
node .pisper/skills/screenshot-studio/scripts/start-isolated-server.mjs
Run it again after seeding. API-created sessions live in memory only; restarting drops the pending entries so the JSONL transcripts become the single source of truth (message counts and conversation text).
3. Capture every page
node .pisper/skills/screenshot-studio/scripts/capture-screenshots.mjs
Visits every current Web route referenced by docs/index.html and docs/show.html, resets the isolated Runtime Dock layout for each chat scene, opens the split dock via the real tab context menu, opens the seeded Markdown asset preview, selects the memory space, and saves the PNGs plus 1600x864 WebP thumbnails to the configured run directory. The desktop terminal shot uses the real TerminalPanel with a screenshot-only bridge and deterministic fictional output; it never starts a host shell.
4. Verify and replace
node .pisper/skills/screenshot-studio/scripts/verify-screenshots.mjs
Parses each PNG's IHDR directly in Node, asserts every expected shot exists at 2558x1380, and copies nothing until the full set passes. It then replaces the configured docs shot directory. Confirm docs/index.html width/height attributes still match. Do not commit without the user's request.
5. Stop the isolated instance
node .pisper/skills/screenshot-studio/scripts/start-isolated-server.mjs --stop
The PID file belongs only to this Skill. Do not kill unrelated processes by port.
Hard-won constraints
-
Provider must be configured first. App.tsx auto-creates a new chat session and redirects to /config when /api/config reports no usable provider. saveConfig reads the API key from the top-level apiKey field:
{ "provider": "openai", "model": "gpt-5", "apiKey": "sk-demo", "defaultProvider": "openai", "defaultModel": "gpt-5" }
Setting configured: true inside a providers array is ignored.
-
Empty sessions need a transcript file. POST /api/sessions only keeps the session in memory; the JSONL file is written on the first message. After a restart, sessions without a JSONL disappear from the list. For empty demo sessions, write a minimal file <iso-timestamp>_<sessionId>.jsonl in the agent sessions/ dir containing the session header plus one session_info entry.
-
Session transcripts use pi v3 JSONL. Events chain with id/parentId; assistant content blocks use thinking + text types. Completed thinking renders collapsed by default in the UI (correct behavior).
-
The browser must block provider discovery. Route-intercept **/api/providers/discovery with {"providers":[],"errors":[]} so the isolated instance never scans real Codex/Claude config files.
-
Hash router. Routes are , , etc.
Verification expectations
- Every current Web shot is replaced; TUI, mobile, and other non-Web/demo assets are untouched.
- Every Web PNG is exactly
2558x1380, and each referenced WebP thumbnail has a valid WebP container.
terminal.png shows the real desktop terminal panel bound to the active chat session, with only fictional output and repository-relative labels.
git status shows screenshot assets, intentional docs references, and Skill maintenance changes only; configured run/agent directories remain gitignored.
- Product source remains unchanged. Report changed references in
docs/index.html / docs/show.html.