Capture deterministic PNGs of AGH runtime UI surfaces (Storybook isolation iframes, the proposal mock at docs/design/new-proposal/agh-refined-7.html, or any local dev-server URL) via the Chrome DevTools Protocol. Chrome's built-in --screenshot flag hangs on Storybook iframes and races font loading; this skill avoids both by driving Chrome explicitly through chrome-launcher + chrome-remote-interface.
Procedures
Step 1: Confirm dev servers are reachable.
- Run
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:6006/for theweb/Storybook andhttp://localhost:6007/for thepackages/ui/Storybook. Expect200. - If a server is down, start it from its workspace:
cd web && bun run storybook(defaults to 6006) orcd packages/ui && bun run storybook(defaults to 6007). Wait for the "Storybook started" banner before proceeding. - Read
references/storybook-urls.mdfor the canonical port table, iframe URL grammar, and story-id naming patterns.
Step 2: Prepare the capture workdir.
- Execute the bootstrap helper:
bash .agents/skills/agh-ui-screenshot/scripts/setup-workdir.sh /tmp/agh-ui-screenshot. This is a bootstrap helper — it creates the directory and installschrome-launcher+chrome-remote-interfacevia bun. It is idempotent; re-running on an existing workdir is a no-op. - Capture its stdout — the printed path is the workdir to
cdinto for every laterbun runinvocation.
Step 3: Resolve the story ids to capture.
- Skip this step when capturing a non-Storybook URL (e.g., the proposal mock).
- For Storybook captures, run the read-only helper
bun run .agents/skills/agh-ui-screenshot/scripts/list-stories.mjs http://localhost:6006 [--filter <substring>]. The script fetchesindex.jsonand emits one story id per line, optionally filtered. - Confirm each story id intended for capture appears in the output. A missing id will land on Storybook's "Couldn't find story" fallback and produce a tiny (under 20 KB) PNG. If unsure of the naming pattern, read
references/storybook-urls.md.
Step 4: Capture screenshots via the CDP helper.
- From the workdir created in Step 2, run the mutating helper
bun run .agents/skills/agh-ui-screenshot/scripts/cap.mjs --out <output-dir> --width <W> --height <H> --wait <ms> --shot <name> <url> [--shot <name> <url> ...]. Each--shotpair writes<output-dir>/<name>.png. - Use
1440 × 900for full-route surfaces,1680 × 1050for wide-breakpoint validation,1100 × 700for primitive previews,320 × 800for collapsed sidebar. Defaults documented inreferences/cdp-flow.md. - Use
--wait 2200as the empirical floor for AGH'sroutes-app-stories-*surfaces. Bump to4000if any capture shows fallback fonts. - Verify the helper's stdout: each successful capture prints
saved <name>; failures printFAIL <name> <message>and the script exits 0 — scan forFAILlines. - Inspect output PNG sizes. Anything under 20 KB is suspicious — see
references/troubleshooting.md.
Step 5 (conditional): Capture the new-proposal mock.
- Only run this step when the audit needs proposal-side screenshots beyond what
docs/design/new-proposal/agh-refined-7.htmlrenders by default. - Read
references/proposal-mock-capture.mdfor the clone-and-patch wrapper that exposes view state via URL query params, the recommended view matrix, and the cleanup step. - Boot a static server:
cd docs/design/new-proposal && python3 -m http.server 8765(background it). - Capture via the same
scripts/cap.mjshelper, pointing each--shotathttp://localhost:8765/_proposal-capture.html?view=….
Step 6: Confirm captures land where intended.
- List the output dir and verify every expected PNG exists with a plausible size (typically 80 KB – 250 KB for full-route surfaces).
- Spot-check at least one capture by reading the PNG (an image-aware tool or visual diff) to confirm the rendered viewport matches the expected surface.
Error Handling
- If a capture hangs longer than 90 s, the Storybook story is likely throwing inside React and never firing
load. Readreferences/troubleshooting.md"Symptom: capture hangs indefinitely on a specific story" for recovery. - If every PNG renders in fallback system fonts, bump
--waitand re-readreferences/troubleshooting.md"Symptom: PNGs render in fallback system fonts". - If the bootstrap helper fails on
bun add, the workdir cache may be corrupted — delete<workdir>/node_modulesand<workdir>/bun.lock, then re-runscripts/setup-workdir.sh. - If Chrome zombies pile up after a SIGKILL, run
pkill -9 -f "Google Chrome.*headless" && pkill -9 -f "Chrome Helper.*headless"and retry. - For any other symptom, consult
references/troubleshooting.mdbefore re-implementing the capture pipeline by hand.