From 5e069413e3080d0ab71c55da17669e5aee299ee6 Mon Sep 17 00:00:00 2001 From: Sharada Mohanty Date: Wed, 6 May 2026 06:53:37 +0200 Subject: [PATCH 1/2] fix(website): regen package-lock.json so npm ci resolves typescript@5.9.3 The merge of #88 auto-resolved package-lock.json without re-running `npm install`, leaving a transitive `typescript@5.9.3` requirement unpinned in the lockfile. CI on main fails at the `npm ci` step: npm error Missing: typescript@5.9.3 from lock file npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Regenerate via `npm install` on top of origin/main; only the lockfile changes (60 insertions, 1 deletion). `npm ci` succeeds end-to-end locally, npm test (1034/1034) and npm run build both green. --- website/package-lock.json | 61 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/website/package-lock.json b/website/package-lock.json index 27df094e7..d87a5dd5b 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -974,6 +974,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -995,6 +996,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -2263,6 +2265,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3358,6 +3361,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3374,6 +3378,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3390,6 +3395,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3406,6 +3412,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3422,6 +3429,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3438,6 +3446,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3454,6 +3463,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3470,6 +3480,7 @@ "cpu": [ "ppc64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3486,6 +3497,7 @@ "cpu": [ "s390x" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3502,6 +3514,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3518,6 +3531,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3534,6 +3548,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3550,6 +3565,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -3568,6 +3584,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3584,6 +3601,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4088,6 +4106,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4104,6 +4123,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4120,6 +4140,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4136,6 +4157,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4152,6 +4174,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4168,6 +4191,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4184,6 +4208,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4200,6 +4225,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4216,6 +4242,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4240,6 +4267,7 @@ "cpu": [ "wasm32" ], + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -4261,6 +4289,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4277,6 +4306,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -4377,6 +4407,7 @@ "version": "0.10.1", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { @@ -8881,7 +8912,7 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==", - "devOptional": true, + "dev": true, "license": "MIT", "bin": { "jiti": "lib/jiti-cli.mjs" @@ -9098,6 +9129,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9118,6 +9150,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9138,6 +9171,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9158,6 +9192,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9178,6 +9213,7 @@ "cpu": [ "arm" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9198,6 +9234,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9218,6 +9255,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9238,6 +9276,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9258,6 +9297,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9278,6 +9318,7 @@ "cpu": [ "arm64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -9298,6 +9339,7 @@ "cpu": [ "x64" ], + "dev": true, "license": "MPL-2.0", "optional": true, "os": [ @@ -14338,10 +14380,27 @@ } } }, + "node_modules/vite-tsconfig-paths/node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "node_modules/vite/node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, "hasInstallScript": true, "license": "MIT", "optional": true, From 3b31546ed5af23d4c670cece89514b4577fc4bcd Mon Sep 17 00:00:00 2001 From: Sharada Mohanty Date: Wed, 6 May 2026 06:58:00 +0200 Subject: [PATCH 2/2] fix(website-tests): skip C50 DoD test when .aicrowd/ is gitignored The closing test in symmetry-explorer.accessibility-c50.test.mjs reads `.aicrowd/v3/accessibility-checklist.md` to verify the DoD reference stays intact. But `.aicrowd/` is gitignored (project rule: "specs stay out of git"), so the file is present in local worktrees but absent from fresh CI checkouts. The test was failing on main with: ENOENT: no such file or directory, open '.../.aicrowd/v3/accessibility-checklist.md' Make the test skip cleanly on CI (file absent) and continue running locally (file present). The DoD assertion stays intact as a local-dev guardrail; CI no longer fails on a gitignored fixture. Implementation: `node:test`'s `{ skip: !checklistAvailable() }` form, where `checklistAvailable()` is a tiny helper that returns false on ENOENT. No copy or assertion changes; just gates the test on file presence. Verified locally: 1034/1034 (test still runs, file is present in the worktree). --- ...symmetry-explorer.accessibility-c50.test.mjs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/website/symmetry-explorer.accessibility-c50.test.mjs b/website/symmetry-explorer.accessibility-c50.test.mjs index 7c94dd50c..c48bc102d 100644 --- a/website/symmetry-explorer.accessibility-c50.test.mjs +++ b/website/symmetry-explorer.accessibility-c50.test.mjs @@ -147,10 +147,16 @@ test('C50 Gap 4 — TotalCostView aria-live announcer template uses the canonica // ─── Closing — verify accessibility-checklist DoD remains intact ────────── -test('C50 — accessibility-checklist.md remains the canonical DoD reference', () => { +test('C50 — accessibility-checklist.md remains the canonical DoD reference', { skip: !checklistAvailable() }, () => { // The audit-cited gaps reference the cross-cutting checklist, not a // per-component spec. This test asserts the checklist file is still // present so future edits keep the DoD source-of-truth path stable. + // + // The checklist lives under `.aicrowd/`, which is in the project's + // .gitignore ("specs stay out of git" — see project memory), so it is + // present in local worktrees but absent from fresh CI checkouts. We + // skip the test there rather than fail; the DoD assertion is a + // local-dev guardrail, not a CI gate. const path = resolve(__dirname, '../.aicrowd/v3/accessibility-checklist.md'); const md = readFileSync(path, 'utf-8'); assert.match(md, /V3\.1 §C50/); @@ -158,3 +164,12 @@ test('C50 — accessibility-checklist.md remains the canonical DoD reference', ( assert.match(md, /aria-live/); assert.match(md, /prefers-reduced-motion/); }); + +function checklistAvailable() { + try { + readFileSync(resolve(__dirname, '../.aicrowd/v3/accessibility-checklist.md'), 'utf-8'); + return true; + } catch { + return false; + } +}