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
1279x690atdeviceScaleFactor 2); its WebP thumbnail is1600x864. - The current Web set is derived from the
shots/web/*.webpreferences indocs/index.htmlanddocs/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/agentor 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.tsxauto-creates a new chat session and redirects to/configwhen/api/configreports no usable provider.saveConfigreads the API key from the top-levelapiKeyfield:{ "provider": "openai", "model": "gpt-5", "apiKey": "sk-demo", "defaultProvider": "openai", "defaultModel": "gpt-5" }Setting
configured: trueinside aprovidersarray is ignored.Empty sessions need a transcript file.
POST /api/sessionsonly 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>.jsonlin the agentsessions/dir containing thesessionheader plus onesession_infoentry.Session transcripts use pi v3 JSONL. Events chain with
id/parentId; assistant content blocks usethinking+texttypes. Completed thinking renders collapsed by default in the UI (correct behavior).The browser must block provider discovery. Route-intercept
**/api/providers/discoverywith{"providers":[],"errors":[]}so the isolated instance never scans real Codex/Claude config files.Hash router. Routes are
/#/chat,/#/config, etc.Dock split uses real UI. The split layout cannot be reliably injected via localStorage. Open
pisper-tiled-sessionswith two session ids, then right-click the second tab (.dv-tab) and click the.dv-context-menu-itemlabeled拆分到右侧.localStorage presets (set before first navigation):
pisper-ui= Zustand persist payload withstate.themeset tolight,state.sidebarCollapsedset tofalse, andstate.densityset tocomfortablepisper-theme= the same theme for legacy migration compatibilitypisper-language=zh-CNpisper-sidebar-collapsed=falsepisper-active-session= the session to openpisper-tiled-sessions=[](or the two ids for the split)- remove
pisper-chat-dock-layout-v1 - reload after changing the theme because hash navigation alone does not recreate the persisted UI store
Browser discovery. Playwright tries installed Edge and Chrome channels, then bundled Chromium. Set
SCREENSHOT_BROWSER_PATHfor an explicit executable orSCREENSHOT_BROWSER_CHANNELfor another Chromium channel; never add a machine-specific executable path to the script.Portable configuration.
screenshot-config.mjsowns all paths and network defaults. Optional overrides areSCREENSHOT_PORT,SCREENSHOT_HOST,SCREENSHOT_BASE_URL,SCREENSHOT_AGENT_DIR,SCREENSHOT_RUN_DIR,SCREENSHOT_SHOTS_DIR, andSCREENSHOT_WORKSPACE_DIR. Relative path overrides resolve from the repository root.Viewport math.
1279x690×deviceScaleFactor 2=2558x1380, matching every current Web asset and thewidth/heightattributes indocs/index.html.
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.pngshows the real desktop terminal panel bound to the active chat session, with only fictional output and repository-relative labels.git statusshows 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.