chore: one-command dev stack for screenshots in cloud sessions (#2902) master
* chore: one-command dev stack for screenshots in cloud sessions Taking a dashboard screenshot from a bare clone meant hunting for a toolchain (deno and sqld are not on the sandbox image and their download hosts are blocked), hand-running env copy, sqld, migrate, seed and the dev server, aliasing Playwright's pinned Chromium build, and hand-writing a gallery page to share the PNGs. - scripts/dev-stack.mjs: `up` fetches the devbox-pinned deno and sqld from npm when missing, creates the .env files, starts sqld, migrates, seeds once, starts the dashboard, warms routes and records PIDs; `down` stops only what it started; `status` and `tools` for the hook. - scripts/screenshot.mjs: falls back to a preinstalled Chromium (PLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH or /opt/pw-browsers/chromium), warms each route with the session cookies before navigating and allows 120s for the first compile, hides the dev-only Tailwind badge and Next indicator, and writes .screenshots/index.html as a publishable gallery. - Tailwind breakpoint indicator gets data-slot="tailwind-indicator" in the three apps so the script can hide it. - .claude/hooks/session-start.sh (cloud only): links .claude/skills, pnpm install, prefetches the tools, and compiles the dashboard once so the cached container starts warm. - Docs: screenshot skill, dashboard AGENTS.md and README, skills README. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0181yZ69zwxbheB2q2C7Zoo9 * chore: capture screenshots with agent-browser scripts/screenshot.mjs drove Playwright borrowed from apps/screenshot-service and carried browser-path fallbacks for the cloud sandbox. It now drives agent-browser (vercel-labs) over its CLI with the same flags and conventions: seeded-session cookies, light and dark at 2x, dev chrome hidden, element shots, the gallery. Element shots pin the match to the viewport's top-left at its own size since agent-browser shoots viewports. `--state` (an agent-browser state file) replaces the magic-link `--login` flow. dev-stack `tools` fetches the pinned agent-browser alongside deno, from one package.json in the cache so installs stay additive. The session-start hook exports AGENT_BROWSER_EXECUTABLE_PATH for the sandbox's Chromium. The screenshot skill is rewritten around agent-browser, with a recipe for interactive states the script cannot reach. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0181yZ69zwxbheB2q2C7Zoo9 * fix: address review findings on the dev stack and screenshot script - `up` seeds only a database it created; a reused server with no seeded session gets a hint to pass --reseed instead of being wiped. - `down` decides by the recorded process group's members (pgrep -g), so an orphaned next-server is still stopped and a reused pid is never signalled. A reusing `up` keeps the pid only when the group is still ours. - `up` also fetches agent-browser, so a clean session can shoot right after. - `--selector` skips visibility:hidden matches, which the isolation style would otherwise reveal. - Gallery heading is neutral and names the app in its facts. - README documents the stack database path and how to reset it. - Hook command quotes CLAUDE_PROJECT_DIR. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0181yZ69zwxbheB2q2C7Zoo9 * fix: fail `down` when pgrep cannot answer; keep the commit in the gallery title A missing or broken pgrep read as "no group members", so `down` stopped nothing and dropped the state while the stack kept running. Only exit 1 (no match) is an empty group now; anything else aborts before the state is removed. The gallery title read the facts by index and picked up the branch once the App row was added. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0181yZ69zwxbheB2q2C7Zoo9 --------- Co-authored-by: Claude <noreply@anthropic.com>