fixtures/image-tags/recorded: tag lists of 9 real repositories (Docker Hub with token, ghcr.io, quay.io) recorded with our
own client, reduced to the tags that match each skill pattern plus 50 others. cases.json now has 25 cases whose expected
values come from the old script's logic. The old script run live on the full lists gave byte-identical JSON to the
port for all 9 (checked once, not automated: it needs the network). tsconfig now covers fixtures/ so the recorder is
type-checked and linted.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
typescript ~6.0.3 (not 7.x): typescript-eslint 8.70 peers typescript <6.1.0, so 7.x would break lint.
eslint + typescript-eslint: strict type-checked lint; @eslint/js: base rules.
vitest: tests next to code; vite + @preact/preset-vite: frontend bundle; preact: UI.
fastify + @fastify/static: HTTP API/SSE and serving the built UI; zod: validation at boundaries.
@types/node: Node 24 typings. SQLite uses the built-in node:sqlite, so no native dependency.
Layer rule domain -> app -> infra -> http/web lives in tools/layer-rules.ts and is tested.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>