From 5e3417a1c76dcee85a79d27e2b4ce39b0b6272a4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 07:45:53 +0000 Subject: [PATCH 1/2] Fix template review findings: cruft, locale guard, docs, lint, config type-checking - Remove stray "// hook test" / "// test" comments left in main.ts - Extend the compile-time locale key-parity guard in StringManager to cover es (and document adding one line per new locale); previously only en<->fr were checked, so a missing key in es (or any future locale) passed tsc - Drop the non-existent model.timer.timeSpeedProperty from TimeModel's doc example so the snippet compiles as written - Add a tests/** biome override for useExplicitType so the template lints clean out of the box (matching the src/** and scripts/** overrides) - Type-check the root *.config.ts files via tsconfig.scripts.json and switch playwright.config.ts to bracket access for process.env["CI"] to satisfy noPropertyAccessFromIndexSignature Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Hy8jfGtbrvpNDRxFfFx6ZA --- biome.json | 10 ++++++++++ playwright.config.ts | 4 ++-- src/common/TimeModel.ts | 1 - src/i18n/StringManager.ts | 10 ++++++++-- src/main.ts | 3 --- tsconfig.scripts.json | 2 +- 6 files changed, 21 insertions(+), 9 deletions(-) diff --git a/biome.json b/biome.json index 92cd200..52c4f60 100644 --- a/biome.json +++ b/biome.json @@ -183,6 +183,16 @@ } } } + }, + { + "includes": ["tests/**"], + "linter": { + "rules": { + "nursery": { + "useExplicitType": "off" + } + } + } } ], "javascript": { diff --git a/playwright.config.ts b/playwright.config.ts index dffd571..66c95b7 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -11,7 +11,7 @@ export default defineConfig({ timeout: 10_000, }, fullyParallel: false, - forbidOnly: !!process.env.CI, + forbidOnly: !!process.env["CI"], retries: 0, workers: 1, reporter: [["list"], ["html", { open: "never" }]], @@ -24,7 +24,7 @@ export default defineConfig({ webServer: { command: "npm run start", url: "http://localhost:5173", - reuseExistingServer: !process.env.CI, + reuseExistingServer: !process.env["CI"], timeout: 120_000, }, projects: [ diff --git a/src/common/TimeModel.ts b/src/common/TimeModel.ts index a29ce9f..e8671c2 100644 --- a/src/common/TimeModel.ts +++ b/src/common/TimeModel.ts @@ -31,7 +31,6 @@ * import { TimeControlNode } from "scenerystack/scenery-phet"; * * const timeControl = new TimeControlNode( model.timer.isPlayingProperty, { - * timeSpeedProperty: model.timer.timeSpeedProperty, // optional * playPauseStepButtonOptions: { * stepForwardButtonOptions: { * listener: () => model.step( 1 / 60 ), diff --git a/src/i18n/StringManager.ts b/src/i18n/StringManager.ts index 627d9e4..fc9412c 100644 --- a/src/i18n/StringManager.ts +++ b/src/i18n/StringManager.ts @@ -26,11 +26,17 @@ import stringsEs from "./strings_es.json"; import stringsFr from "./strings_fr.json"; // ── Compile-time key-parity check ───────────────────────────────────────────── -// TypeScript errors here if any locale file is missing a key from English. +// English is the canonical shape; every other locale must match it exactly. +// TypeScript errors here if any locale file is missing (or adds) a key relative to +// English. Add one `satisfies` line per new locale so the check stays exhaustive. +// biome-ignore lint/complexity/noVoid: intentional compile-time type assertion +void (stringsFr satisfies typeof stringsEn); // biome-ignore lint/complexity/noVoid: intentional compile-time type assertion void (stringsEn satisfies typeof stringsFr); // biome-ignore lint/complexity/noVoid: intentional compile-time type assertion -void (stringsFr satisfies typeof stringsEn); +void (stringsEs satisfies typeof stringsEn); +// biome-ignore lint/complexity/noVoid: intentional compile-time type assertion +void (stringsEn satisfies typeof stringsEs); // ── Build the reactive string property tree ─────────────────────────────────── const stringProperties = LocalizedString.getNestedStringProperties({ diff --git a/src/main.ts b/src/main.ts index f3858ca..540572a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -74,6 +74,3 @@ onReadyToLaunch(() => { sim.start(); }); -// hook test -// test -// test diff --git a/tsconfig.scripts.json b/tsconfig.scripts.json index 526c16e..6e0601b 100644 --- a/tsconfig.scripts.json +++ b/tsconfig.scripts.json @@ -4,5 +4,5 @@ "noEmit": true, "types": ["node"] }, - "include": ["scripts"] + "include": ["scripts", "*.config.ts"] } From 8dfc2ed65e98e3a6ed1187893fac192cc24b8bd5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 22 Jul 2026 07:48:09 +0000 Subject: [PATCH 2/2] Patch transitive high-severity advisories in build deps npm audit fix bumps three transitive dev dependencies (all reachable only via vite-plugin-pwa -> workbox-build, i.e. build-time only, not shipped in the sim bundle): - brace-expansion 2.1.1 -> 2.1.2 and 5.0.6 -> 5.0.7 (GHSA-3jxr-9vmj-r5cp, DoS via exponential-time expansion) - fast-uri 3.1.2 -> 3.1.4 (GHSA-4c8g-83qw-93j6, GHSA-v2hh-gcrm-f6hx, host confusion via IDN canonicalization / backslash authority delimiter) Lockfile-only, patch-level bumps; package.json unchanged. npm audit now reports 0 vulnerabilities; check/lint/test/build all pass. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Hy8jfGtbrvpNDRxFfFx6ZA --- package-lock.json | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 269fa57..f1edadb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4681,9 +4681,9 @@ } }, "node_modules/brace-expansion": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz", - "integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==", + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", "dev": true, "license": "MIT", "dependencies": { @@ -5403,9 +5403,9 @@ "license": "MIT" }, "node_modules/fast-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", - "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.4.tgz", + "integrity": "sha512-8JnbkQ4juDyvYs4mgFGQqg4yCYtFDtUtmp2QIQq11ZZe5CFQ5wcqm1rqDgAh/QdMySuBnPzMUiJUNZG5N/AiQw==", "dev": true, "funding": [ { @@ -5461,9 +5461,9 @@ "license": "MIT" }, "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz", - "integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", + "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "dev": true, "license": "MIT", "dependencies": {