diff --git a/.claude/commands/screenshot.md b/.claude/commands/screenshot.md new file mode 100644 index 0000000..58abf9f --- /dev/null +++ b/.claude/commands/screenshot.md @@ -0,0 +1,84 @@ +--- +description: Screenshot the routes affected by the current PR's diff and upload them for the PR body +--- + +# PR Preview Screenshots + +Take screenshots of pages affected by the current PR's changes using `agent-browser`. + +## Instructions + +1. **Identify affected routes** by looking at the diff against the base branch: + + ```bash + git merge-base HEAD origin/main + git diff $(git merge-base HEAD origin/main)...HEAD --name-only + ``` + + | Changed files | Routes to screenshot | + |---|---| + | `app/page.tsx` | `/` | + | `app/snapshots/**` | `/snapshots` | + | `app/upgrades/**` (not `changelog/`) | `/upgrades` | + | `app/upgrades/changelog/**` | `/upgrades/changelog` | + | `app/vibenet/demos/**` | `/vibenet/demos/account`, `/vibenet/demos/b20`, `/vibenet/demos/validity` | + | `app/vibenet/**` (not `demos/`) | `/vibenet`, `/vibenet/explorer` | + | `app/internal-explorer/**` (internal-only, see below) | `/internal-explorer`, `/internal-explorer/txs`, `/internal-explorer/blocks` | + | `app/benchmark/**` (internal-only, see below) | `/benchmark`, `/benchmark/run`, `/benchmark/load-tests` | + | `app/components/**`, `app/globals.css`, `tailwind.config.ts` | One representative external route (`/`) plus whichever of the above sections the component is actually used in — check imports, don't screenshot everything | + | `app/api/**`, `app/analytics/**`, `lib/**`-equivalents (data/hooks with no UI) | No screenshots needed (backend-only) | + + If no visual files changed, say so and skip screenshots. + +2. **Start the dev server** if one isn't already running. `internal-explorer` and + `benchmark` are internal-only surfaces (see `deploy.config.mjs`) — they 404 on + the plain dev server, so use `npm run dev:internal` if any affected route falls + under either prefix; otherwise `npm run dev` is enough: + ```bash + npm run dev & # or: npm run dev:internal & + ``` + Wait for it to be ready by polling `http://localhost:3000` with `agent-browser`. + Do NOT run `npm run build` while the dev server is up — it 500s a running + `next dev` (see project memory `next-build-clobbers-dev-server`). + +3. **Take screenshots** using `agent-browser`. For each affected route: + ```bash + mkdir -p screenshots + agent-browser open http://localhost:3000/ && agent-browser wait --load networkidle && agent-browser screenshot --full screenshots/.png + ``` + + Use descriptive filenames, e.g. `home.png`, `vibenet-explorer.png`, + `internal-explorer-txs.png`, `benchmark-run.png`. + +4. **Close the browser** when done: + ```bash + agent-browser close + ``` + +5. **Review screenshots**: Read each screenshot file to visually inspect the + pages. Describe what you see and confirm the visual changes look correct. + +6. **Upload screenshots** to GitHub as prerelease assets so they can be + embedded in the PR (use the PR number). This must be a published prerelease, + not a draft: this repo is public and PR images are fetched anonymously by + GitHub's Camo proxy, which 404s on draft-release assets. + ```bash + gh release create screenshots-pr- --prerelease --latest=false --title "PR # Screenshots" --notes "Screenshots for PR review" screenshots/*.png + gh release view screenshots-pr- --json assets --jq '.assets[] | "\(.name): \(.url)"' + ``` + +7. **Report results**: Return the image markdown for each screenshot so it can + be added to the PR body's **Screenshots** section (the PR template, + `.github/PULL_REQUEST_TEMPLATE.md`, has a slot for it), using the URLs from + step 6. + +## Notes + +- Screenshots are saved locally (gitignored) — do NOT commit them to the repo. + They're uploaded via GitHub prereleases instead. +- Use `agent-browser set viewport 1280 800` before capturing for consistent + dimensions. +- If the dev server is already running, skip starting a new one — but check + whether it needs to be the `:internal` variant for the routes you need. +- After a PR is merged (or closed), clean up its release and tag: + `gh release delete screenshots-pr- --cleanup-tag --yes`. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..a349a70 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,14 @@ +## Summary + + + +## Screenshots + + + +## Test plan + + diff --git a/.gitignore b/.gitignore index fa6719c..f0442ad 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,9 @@ yarn-error.log* *.tsbuildinfo next-env.d.ts +# local PR screenshots (uploaded as release assets, never committed) +/screenshots/ + # playwright /test-results/ /playwright-report/ diff --git a/AGENTS.md b/AGENTS.md index 6971364..8f17fb0 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -176,3 +176,9 @@ The matrix logic is covered by `deploy.config.test.mjs`. - Keep the generated-file commit separate from your own work — the hook already does this for you. Do not squash it away; it is what makes the generated diff reviewable. +- **Visual changes need screenshots.** If the diff touches `app/**` (pages or + components), `app/globals.css`, or `tailwind.config.ts`, run `/screenshot` to + capture the affected routes and upload them as GitHub release assets, + then include a **Screenshots** section in the PR body with the embedded + images. Skip for backend-only changes (`app/api/**`, `app/analytics/**`) or + when no visual file changed.