Skip to content

v1.6.0 — a screenshot is read against its design board, down to the design token

Choose a tag to compare

@climaa climaa released this 18 Oct 10:37
· 68 commits to main since this release
3268227

Sixty-five PRs since v1.5.0 (#469 → #552), telling one story: a screenshot is read against its design board, down to the design token.

What earns the minor

Layer PRs
A comparison is a link you can send, and opens beside the design board it was drawn from #500, #502, #503
The token ledger: every console capture records the spacing it measured, each value classified against the design-token scale, and the design view lists those readings in design-token terms — a focused reading lights its box, and a report records which readings changed #506, #507, #510, #515, #522, #523, #527, #528, #530, #532, #534, #535, #536
The shot view: a screenshot in a set opens beside its design board, and PanZoom learns to draw marks, follow another view, take a crop, and magnify past an image's own pixels #525, #541, #542, #543, #544, #545, #546, #548, #549
The boards drew each of those before the code did: PanZoom's marks, the design view's readings, the set shot view and decision D7 #524, #526, #537
The blog's index is paged four posts at a time, each page at its own address, through a new Pagination molecule that speaks the caller's language #485, #486, #487, #488, #491, #492, #494
Every page on all four surfaces previews as itself — its own card, its own canonical address #493, #495, #496, #511, #512, #513
The console: compare A ⇄ B starts the comparison, set-row badges sit under the values they qualify, run parameters open folded, and the sample console shows the corpus's latest movement #480, #482, #501, #514
The footer ends its copyright line with the release it was built from #483
Production ships from a production branch, and since #552 no other branch creates a deployment #518, #519, #550, #552
A capture never reads a Storybook build older than the components; a bucket-count scenario that could never fail is gone #477, #478, #551
Sandcastle: the merger runs on Sonnet 5.5 and merges a CLEAN PR whose auto-merge never armed; sandbox git setup waits 60 s; turbo's cache lives in /tmp for the whole sandbox #474, #475, #476, #479
The index lists the child projects that carry copies of the shared tooling #481
Dependencies, among them Sentry 10 → 11, Storybook's warnings under Vite 8.3.1, and the vulnerable transitives that fit their ranges #469, #470, #471, #472, #473, #484, #516

The two big threads answer one question: when a screenshot moved, did it move toward the design or away from it? A pixel diff says only that something changed. The design board says what the screenshot was meant to look like, and the token ledger says whether the spacing it measured is a step of the scale or an off-scale value. Neither of them is a side of a comparison or carries a bucket. The differ still detects change rather than correctness, and the ledger is reference beside it. #523 renamed a reading's verdict to a classification so that the code stopped implying otherwise.

The deploy rows are the cost side of the same cycle. Building production on every merge took the Hobby plan's deployment storage to 75% in a fortnight, and preview builds spent its daily cap. #518 moved production to its own branch and #550 opted every other branch out in vercel.json. That opt-out held in the private child projects but not here: pushes to this public repository still created a deployment per project. #552 turned Git deployments off on all four projects. Its own push and merge created none, and moving production still deploys, as this release did.

Eleven manifests

The same eleven as v1.5.0 move to 1.6.0 together. Nothing publishes to npm and every workspace is private, so the version is a coherence marker rather than a distribution fact. Every internal dependency is workspace:*, and pnpm install --frozen-lockfile resolves with pnpm-lock.yaml untouched, verified rather than assumed.

The index, measured rather than adjusted

PROJECT_INDEX.md was stamped 2026-09-26. Every count was measured again with the turbo cache forced off (0 of 8 test tasks cached):

Claim Corrected to
Orchestrator suite 39 files / 656 tests 41 / 680
packages/ui 35 / 512, 28 components (16 · 6 · 4 · 2) 38 / 630, 30 components (16 atoms, 7 molecules, 5 organisms, 2 templates)
apps/blog 26 / 514 (511 passed, 3 skipped) 28 / 563 (560 passed, 3 skipped)
packages/visual-diff 10 / 327 11 / 458
apps/storybook 6 / 186 7 / 200
apps/visual-diff-ui 56 / 938 74 / 1242 (1 skipped)
apps/manual 7 / 92 10 / 117
53 acceptance scenarios 87 (162 tests)
27 stories 29
next ^16.3.5, turbo ^2.11.2 (and ^2.10.11 in the configuration section) ^16.4.0, ^2.11.7 in both

The structure tree also lacked this cycle's features: the console's comparison links, design-board reading and shot view, the differ's token ledger, and the blog's paged index. It now describes them, and README's component row moved from 28 to 30. Unchanged, and measured: packages/logger 2 / 20, packages/links 1 / 10, the two-scenario local lane, 200 committed baselines, 19 docs pages and 27 orchestrator modules.

Known gaps

The ledger reads spacing only. Colour, type and radius are not measured. It is reference beside a comparison and never decides a bucket or an exit code, so a capture full of off-scale values still passes.

The pixelmatch 7 → 8 bump waits. #517 is a major version of the differ's comparison library, so it can move pixel results. It needs a session that reviews the baselines rather than an auto-merge.

The Git setting does less, and more, than its name says. With createDeployments disabled, a push to any branch but production creates nothing, yet a move of production still deploys. #552 assumed the opposite and added a deploy-hook step to RELEASING.md. Shipping this release fired both, so each project built twice. The hook step is being removed, and the blog keeps its hook only for the /changelog refresh.

Upstream and unchanged: #68 ESLint 10 is unreachable, and #47 TypeScript 7 is blocked. Dependabot ignores both majors on purpose.

Full changelog: v1.5.0...v1.6.0