Skip to content

fix: scaffold and pipeline follow-through from the screenshot run - #151

Merged
PAMulligan merged 5 commits into
mainfrom
fix/screenshot-run-followups-145
Nov 9, 2026
Merged

PAMulligan merged 5 commits into
mainfrom
fix/screenshot-run-followups-145

Conversation

@PAMulligan

Copy link
Copy Markdown
Collaborator

Description

Follow-through on the seven findings from the /build-from-screenshot run on a fresh --vite scaffold (#145). PR #146 already covered item 2 and the workspace half of item 1; this PR takes the rest. The issue left the option choices to me, so each row names the decision.

# Finding What this PR does Decision
1 Scripts act on the repo root; check-responsive.sh would have installed Playwright there common_app_root() in scripts/lib/common.sh: the current directory when it holds a package.json, else the repo root. check-responsive.sh installs @playwright/test there, resolves it from the app's package.json (a script in /tmp cannot import it on its own), uses pnpm exec instead of npx, and keeps its screenshots under the Aurelius checkout's .claude/visual-qa/. parallel-orchestration says to run the Bash dispatches from the app directory. The other visual-QA scripts (check-dark-mode.sh, regression-test.sh, capture-baselines.sh, cross-browser-baseline.sh) still cd to the repo root; untouched here.
2 Coverage reads 0% Done in #146 (coverage provider pinned to vitest's major). Nothing here.
3 Storybook phase skipped; template targets Storybook 8 The shared, Vue and SvelteKit .storybook templates move to Storybook 10, which supports Vite 8 since 10.3: addon-docs and addon-a11y only, since essentials and interactions are core since 9. generate-stories.js imports from the framework package named in .storybook/main.ts (@storybook/react-vite by default) and from @storybook/addon-docs/blocks; when package.json lists no Storybook package it exits 0 with status: skipped and the install command instead of writing stories that break tsc and the build. The pipelines record the phase as skipped. Storybook is still not installed by the scaffold: it is heavy and optional. The config is in place and the install command is printed at the end.
4 Playwright config: port 3000 and pnpm dev from the wrong root; @playwright/test and browsers missing One PORT constant (E2E_PORT, with a fallback the scaffold sets per framework: Vite, Vue and SvelteKit 5173, Astro 4321). @playwright/test is installed with the tooling. Browsers stay a one-time pnpm exec playwright install chromium, printed at the end, rather than a download during every scaffold.
5 The component-lanes visual stage cannot crop visual-diff.js --crop x,y,w,h; a reference in the component-lanes args may be { path, renderWidth, crop }; the intake records reference for a partial or odd-width screenshot and build-from-screenshot passes it through. Explicit crop and render width, as the issue suggested. crop.y can be measured in visual round 1 when the intake does not know it.
6 Lighthouse SEO needs a meta description and a robots.txt The scaffold ships public/robots.txt; the intake asks for a title and a one-line description per page (Q7, defaults from the vision pass, written to pages[].seo); Phase 4 writes them and the report lists them as additions. The SEO floor stays for screenshot builds: both inputs are cheap and the gate is about the built app.
7 Test requests never reach test-writer-fixer The agent description names the plain request and says it must be used instead of writing tests in the main session. README, quickstart and the agents guide now say delegation is Claude's call and that naming the agent makes it certain. Both halves of the issue's option.

Related Issue

Closes #145. Refs #141, #146.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Documentation update
  • Chore (dependency updates, CI changes, refactoring)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)

Verification

Repo checks

Check Result
pnpm vitest run --config scripts/__tests__/vitest.config.js scripts/__tests__/ 43 files, 646 passed, 2 skipped
./scripts/lint-and-format.sh --check clean, 0 errors
node scripts/claude-code-conformance.js 0 errors; the 10 warnings are pre-existing SKILL.md lengths
./scripts/check-doc-counts.sh counts match

New tests, each watched failing before the change: --crop and its bounds in visual-diff.test.js; render width and crop in the visual-check prompt in component-lanes.test.js; framework and blocks imports plus the skip without Storybook in generate-stories.test.js; Playwright installed in the app directory, with a fake pnpm, in check-responsive.test.js; @playwright/test in the tooling, the port function on a copy of the template, the Storybook 10 package names and the robots.txt copy in setup-project.test.js. One existing assertion changed: the MDX test asserted the old four separate @storybook/blocks import lines and now checks the blocks come from @storybook/addon-docs/blocks.

A real scaffold, ./scripts/setup-project.sh my-app --vite in a scratch directory (exit 0):

  • playwright.config.ts has const PORT = Number(process.env.E2E_PORT) || 5173; and no .bak file; pnpm exec playwright test --list loads the config ("No tests found", as there is no e2e/ yet).
  • public/robots.txt present; @playwright/test ^1.65.0 in devDependencies; .storybook/main.ts is the Storybook 10 config; no Storybook package installed.
  • ../scripts/check-types.sh from the app: "No type errors found."
  • ../scripts/check-responsive.sh http://localhost:5173 from the app: Playwright is resolved from the app's package.json and the run fails only on the missing browser binary, pointing at the app directory for the install.
  • ../scripts/generate-stories.sh --json from the app: nothing to generate yet (the scaffold has no src/components), so the Storybook check is reached only once components exist; the unit tests cover that path.

Not run here: the --vue, --svelte, --astro and --next scaffolds (their Storybook templates and the port fallback changed too), and a full pipeline run.

Left for later: the visual-QA scripts listed in row 1 still act on the repo root, and check-dark-mode.sh imports playwright from a /tmp script, which Node's ESM resolution cannot satisfy. packages/pipeline/src/react/emit.ts (the InDesign pipeline) and the react-testing-workflows skill example still import from @storybook/react.

Checklist

  • Tests pass (pnpm vitest run --config scripts/__tests__/vitest.config.js scripts/__tests__/)
  • Linting passes (./scripts/lint-and-format.sh --check)
  • Types check (pnpm tsc --noEmit): not applicable, the TypeScript changed lives in templates/, which the repo's type check does not cover; the scaffolded app type-checks
  • Documentation updated (scripts/README.md, templates/README.md, CLAUDE.md, the pipeline skills, README, quickstart, agents guide)

🤖 Generated with Claude Code

Paul Mulligan and others added 5 commits November 8, 2026 19:27
The /build-from-screenshot run in issue #145 had to leave the documented path
on a fresh `setup-project.sh my-app --vite` scaffold. PR #146 already made the
app its own pnpm root and pinned the coverage provider (items 1 and 2). This
takes the rest of the scaffold's share:

- Playwright (item 4): the shared config derives baseURL and webServer.url
  from one PORT constant (E2E_PORT, falling back to 3000), and the scaffold
  sets that fallback per framework (Vite, Vue and SvelteKit 5173, Astro 4321).
  `@playwright/test` is installed with the other tooling; the browsers stay a
  one-time `pnpm exec playwright install chromium`, printed at the end.
- Storybook (item 3): the shared, Vue and SvelteKit .storybook templates move
  to Storybook 10, which supports the scaffold's Vite 8 since 10.3: docs and
  a11y addons only (essentials and interactions are in core since 9), Preview
  typed from the framework package. generate-stories.js imports Meta and
  StoryObj from the framework package named in .storybook/main.ts
  (@storybook/react-vite when none is found) and the MDX blocks from
  @storybook/addon-docs/blocks. When the app's package.json lists no Storybook
  package it exits 0 with `status: skipped` and the install command instead
  of writing stories that break tsc and the build. The scaffold still copies
  the config and prints the install command rather than installing Storybook.
- SEO (item 6): the scaffold ships public/robots.txt, which Lighthouse's SEO
  audit wants and no design supplies.
- App root (item 1): common_app_root() in lib/common.sh is the current
  directory when it holds a package.json, else the repo root.
  check-responsive.sh installs @playwright/test there, resolves it from the
  app's package.json (a /tmp script cannot import it on its own), uses
  `pnpm exec` instead of npx, and keeps its screenshots under the Aurelius
  checkout's .claude/visual-qa/. mktemp --suffix is GNU-only; mktemp -d is not.

Tests run the scaffold's port function on a copy of the template, check the
dry-run tooling list, the Storybook 10 package names and the install hint,
run the generator with and without a Storybook dependency, and run
check-responsive.sh with a fake pnpm from a sibling app directory.

Refs #145

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The screenshot in issue #145 was a crop starting about 180 px below the top
of the page, 1265 px wide (a 1280 px window minus a scrollbar), so the
component-lanes visual stage could only fail by construction and the run had
to redo the bounded loop by hand with a cropped capture (item 5).

visual-diff.js takes `--crop x,y,w,h`, compares only that region of the
actual capture and reports `crop` with the capture's full size; a box that
reaches outside the capture is a usage error (exit 2). A page reference in
the component-lanes workflow may now be `{ path, renderWidth, crop }` as well
as a path: the visual check captures at renderWidth and passes --crop, so a
partial screenshot is diffed inside the workflow. Plain path references work
as before.

Refs #145

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The pipeline skills describe what the scripts now do (issue #145):

- screenshot-intake asks for a page title and a one-line description (Q7,
  with defaults from the vision pass) and writes them to pages[].seo; a
  screenshot taken at a non-standard width or covering part of the page gets
  a `reference` with renderWidth and crop.
- build-from-screenshot passes `reference` into the component-lanes args as
  an object reference, writes the title, meta description and robots.txt in
  Phase 4 (the SEO floor applies to a screenshot build too; the report lists
  them as additions), and records Phase 4.5 as skipped when Storybook is not
  installed.
- build-from-figma documents the object form of a reference and the
  Storybook skip; parallel-orchestration says to run Bash dispatches from the
  app directory when the app lives beside the framework.
- storybook-story-generation and the skills README say Storybook 10 and the
  framework-package imports; e2e-test-generator explains the E2E_PORT fallback
  instead of hand-editing baseURL per framework.

Refs #145

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Two plain "write tests for the X component" requests in issue #145 (item 7)
were handled by the main session; no agent ran. The README, the quickstart
and the agents guide promised automatic selection.

The test-writer-fixer description now names the plain request, covers unit,
integration and E2E tests, and says it must be used instead of writing tests
in the main session. The three docs say that Claude Code delegates when a
request matches an agent's description, may handle a small task itself, and
that naming the agent makes the delegation certain; the quickstart example
names it.

Refs #145

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@PAMulligan
PAMulligan merged commit d1fba46 into main Nov 9, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant