Make the screenshot registry self-indexing

Previously sync-registry only *updated* existing registry entries, so a newly
introduced screenshot target was captured but never indexed — and the
/sync-docs staleness check only flags entries it can see, so such a shot would
silently drift out of date (exactly what happened to issues/inbox-unread).

sync-registry now appends a registry entry (file, theme, viewport, route,
depends_on) for any CAPTURE_TARGET that has none, and sorts entries for stable
diffs. run.mjs runs sync-registry on every capture, so the index now stays
complete automatically. Audit: 0 target files missing from the registry, 0
without depends_on — every documented screenshot is tracked for staleness.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
Aron PrinsandClaude Opus 4.8 committed 2026-05-30 14:40:58 +02:00
1 parent 38608f7fb7
commit 9ad25322b5
2 files changed
+47 -1

No files matched your search

@@ -873,6 +873,17 @@
"ui/src/pages/Inbox.tsx"
]
},
{
"file": "dark/issues/inbox-unread.png",
"theme": "dark",
"viewport": "1440x900",
"route": "/ACME/inbox/unread",
"captured_against": "HEAD",
"captured_sha": "911a1e8b0d24205acd5006e837a5c5e8c4bfb447",
"depends_on": [
"ui/src/pages/Inbox.tsx"
]
},
{
"file": "dark/issues/inbox.png",
"theme": "dark",
@@ -2369,6 +2380,17 @@
"ui/src/pages/Inbox.tsx"
]
},
{
"file": "light/issues/inbox-unread.png",
"theme": "light",
"viewport": "1440x900",
"route": "/ACME/inbox/unread",
"captured_against": "HEAD",
"captured_sha": "911a1e8b0d24205acd5006e837a5c5e8c4bfb447",
"depends_on": [
"ui/src/pages/Inbox.tsx"
]
},
{
"file": "light/issues/inbox.png",
"theme": "light",
+25 -1
View File
@@ -33,6 +33,7 @@ function buildLookup() {
// Substitute the static prefix token only; leave id tokens as-is.
const routeTemplate = target.route.replaceAll("{prefix}", COMPANY_PREFIX);
map.set(fileKey, {
theme,
route: routeTemplate,
depends_on: target.dependsOn ?? [],
});
@@ -65,6 +66,8 @@ async function main() {
let updated = 0;
let skipped = 0;
const present = new Set(registry.entries.map((e) => e.file));
registry.entries = registry.entries.map((entry) => {
const match = lookup.get(entry.file);
if (!match) {
@@ -83,9 +86,30 @@ async function main() {
};
});
// Self-index: append entries for any CAPTURE_TARGET file that has no registry
// entry yet. Without this a newly-added target would be captured but never
// tracked for staleness — the /sync-docs skill only flags entries it can see.
let added = 0;
for (const [file, match] of lookup) {
if (present.has(file)) continue;
registry.entries.push({
file,
theme: match.theme,
viewport: registry.viewports?.default ?? "1440x900",
route: match.route,
captured_against: null,
captured_sha: null,
depends_on: match.depends_on,
});
added++;
}
// Keep the file deterministic and easy to diff.
registry.entries.sort((a, b) => a.file.localeCompare(b.file));
await writeFile(REGISTRY_PATH, JSON.stringify(registry, null, 2) + "\n", "utf8");
console.log(
`sync-registry: updated ${updated} entries, skipped ${skipped} (no matching target).`,
`sync-registry: updated ${updated}, added ${added}, skipped ${skipped} (no matching target).`,
);
}