* perf(vishot-runner-electron): compress and downscale AVIF screenshots The capture pipeline was emitting AVIF at default quality with no resolution cap, so 4K displays produced ~800KB per screenshot (~42MB total for the tamagotchi manual). Add quality 50, speed 6, and a 1920px max-width downscale — expected output drops to ~20-40KB each with no visible quality loss for UI documentation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * perf(docs): regenerate manual screenshots with compression Re-capture all 27 tamagotchi manual screenshots using the new AVIF pipeline settings (quality 50, max-width 1920px, speed 6). Before: ~800KB per image, ~42MB total (4K @ default quality) After: ~15-38KB per image, ~1MB total (1920px @ quality 50) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-Authored-By-Agent: Claude Opus 4.6 <noreply@anthropic.com>
Vishot Runner - Electron
Capture raw screenshots from the built stage-tamagotchi Electron app with TypeScript scenarios.
Purpose
This package is the Electron capture runner. It provides:
- a runtime surface in
src/index.ts - the
captureCLI insrc/cli/capture.ts - the
defineScenario()authoring helper for scenario modules - a typed raw-artifact surface for screenshot outputs
- reusable helpers for the controls island, settings window, dialogs, drawers, and stage windows
This package stops at raw business screenshots. It does not own the scenario modules themselves; those live in @proj-airi/scenarios-stage-tamagotchi-electron.
Workflow
pnpm -F @proj-airi/stage-tamagotchi build
pnpm -F @proj-airi/vishot-runner-electron capture -- ../../packages/scenarios-stage-tamagotchi-electron/src/scenarios/demo-controls-settings-chat-websocket.ts --output-dir ../../packages/scenarios-stage-tamagotchi-browser/artifacts/raw
To emit AVIF files instead of PNG files:
pnpm -F @proj-airi/vishot-runner-electron capture -- ../../packages/scenarios-stage-tamagotchi-electron/src/scenarios/demo-controls-settings-chat-websocket.ts --output-dir ../../packages/scenarios-stage-tamagotchi-browser/artifacts/raw --format avif
This writes the raw inputs consumed by the browser scene package:
packages/scenarios-stage-tamagotchi-browser/artifacts/raw/00-stage-tamagotchi.pngpackages/scenarios-stage-tamagotchi-browser/artifacts/raw/01-controls-island-expanded.pngpackages/scenarios-stage-tamagotchi-browser/artifacts/raw/02-settings-window.pngpackages/scenarios-stage-tamagotchi-browser/artifacts/raw/03-websocket-settings.png
If you pass --format avif, the same capture names are emitted as .avif files instead.
Then export the composed browser assets:
pnpm -F @proj-airi/scenarios-stage-tamagotchi-browser capture
In this environment, the raw capture command worked end-to-end after running outside the sandbox because tsx pipe creation was denied inside the sandbox (listen EPERM on the temporary tsx IPC pipe).
Additional Examples
To verify the controls-island hearing button specifically:
pnpm -F @proj-airi/stage-tamagotchi build
pnpm -F @proj-airi/vishot-runner-electron capture -- ../../packages/scenarios-stage-tamagotchi-electron/src/scenarios/demo-hearing-dialog.ts --output-dir ./artifacts/hearing-demo
Expected file:
packages/vishot-runner-electron/artifacts/hearing-demo/hearing-dialog.png
Scenario Authoring
import { defineScenario } from '@proj-airi/vishot-runner-electron'
export default defineScenario({
id: 'settings-connection',
async run({ controlsIsland, settingsWindow, stageWindows, capture }) {
const main = await stageWindows.waitFor('main')
await controlsIsland.expand(main.page)
const settings = await controlsIsland.openSettings(main.page)
const page = await settingsWindow.goToConnection(settings.page)
await capture('connection-settings', page)
},
})
For the controls-island hearing trigger, the runtime also provides:
controlsIsland.openHearing(page)
Dialog And Drawer Helpers
For surfaces built with DialogRoot or DrawerRoot, the runtime now exposes:
dialogs.dismiss(page)drawers.swipeDown(page)drawers.dismiss(page)
Example:
import { defineScenario } from '@proj-airi/vishot-runner-electron'
export default defineScenario({
id: 'dismiss-helpers',
async run({ dialogs, drawers, stageWindows }) {
const main = await stageWindows.waitFor('main')
await dialogs.dismiss(main.page)
await drawers.swipeDown(main.page)
await drawers.dismiss(main.page)
},
})
These are best-effort automation helpers. The current behavior is:
- dialog dismiss:
Escape, then overlay-corner click fallback - drawer dismiss: swipe down, then
Escape, then overlay-corner click fallback
They are intended for scenarios where you already opened the dialog or drawer and need a reusable close step.
Settings Window Helpers
The settingsWindow surface is navigation-only:
settingsWindow.waitFor(timeout?)settingsWindow.goToConnection(page)
It does not open the settings window from the main window for you. The intended flow is:
stageWindows.waitFor('main')controlsIsland.expand(main.page)controlsIsland.openSettings(main.page)settingsWindow.goToConnection(settings.page)
Notes
- Importing
@proj-airi/vishot-runner-electronresolves tosrc/index.tsvia the package export surface. - The package is no longer a Playwright test suite package.
- Final composed exports live in
packages/scenarios-stage-tamagotchi-browser/artifacts/final, not this package. - Screenshot capture now returns typed
imageartifacts and can run transformer hooks before those raw files are handed to downstream consumers. - The CLI supports
--format png|avif; AVIF remains an opt-in post-processing step on top of the raw PNG screenshot primitive.