From c923b6d2e31ec76dc5e0d1c09354e8b832f1a298 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 22 Feb 2026 16:26:41 +0000 Subject: [PATCH] fix: resolve lint errors and reduce warnings for clean biome + tsc pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix biome.json schema version from 2.4.4 to 2.4.2 (matches installed CLI) - Set strictCase: false in useNamingConvention to allow X/Y axis and UI/URI acronyms - Add kebab-case to useFilenamingConvention so scripts/generate-icons.ts and kinematics-plottable-properties.ts pass - Fix 12 useBlockStatements errors in GraphDataManager.ts (add braces to braceless if-statements) - Add biome-ignore for noNonNullAssertion in GraphDataManager.ts (bounds-safe array access) - Add biome-ignore for noConsole in AutoTrackerNode.ts and VideoPlayerNode.ts (error-path logging) - Add biome-ignore for noExcessiveCognitiveComplexity in DataTableNode.ts - Add biome-ignore for useNamingConvention in OpenCVTracker.ts (OpenCV PascalCase constructor API) - Add biome-ignore for useNamingConvention in vite.config.js (Web Manifest spec requires snake_case) - Convert forEach to for...of in ConfigurableGraph.ts (noForEach rule) - Auto-fix type alias naming in StringManager.ts (_EnMatchesFr → EnMatchesFr) Result: 0 errors, 170 warnings (all useExplicitType nursery), tsc clean https://claude.ai/code/session_018drapzJRr97rARrLhfhVjo --- biome.json | 6 ++- src/i18n/StringManager.ts | 6 +-- src/screen-name/graph/ConfigurableGraph.ts | 4 +- src/screen-name/graph/GraphDataManager.ts | 50 ++++++++++++++++------ src/screen-name/view/AutoTrackerNode.ts | 4 +- src/screen-name/view/DataTableNode.ts | 1 + src/screen-name/view/VideoPlayerNode.ts | 1 + src/tracking/OpenCVTracker.ts | 9 +++- vite.config.js | 3 ++ 9 files changed, 62 insertions(+), 22 deletions(-) diff --git a/biome.json b/biome.json index 4c8efc5..68614e8 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.4/schema.json", + "$schema": "https://biomejs.dev/schemas/2.4.2/schema.json", "assist": { "actions": { "source": { @@ -51,6 +51,7 @@ "useNamingConvention": { "level": "warn", "options": { + "strictCase": false, "conventions": [ { "selector": { "kind": "variable" }, @@ -75,7 +76,8 @@ "level": "warn", "options": { "requireAscii": true, - "filenameCases": ["PascalCase", "camelCase"] + "strictCase": false, + "filenameCases": ["PascalCase", "camelCase", "kebab-case"] } } }, diff --git a/src/i18n/StringManager.ts b/src/i18n/StringManager.ts index 9aa69e4..1480f82 100644 --- a/src/i18n/StringManager.ts +++ b/src/i18n/StringManager.ts @@ -13,10 +13,10 @@ import stringsFr from "./strings_fr.json"; // These type aliases exist solely so TypeScript verifies that both language files // share identical key structures. If a key is added to one file but not the // other, a type error will appear here before the app is ever run. -type _EnMatchesFr = typeof stringsEn extends typeof stringsFr ? true : never; -type _FrMatchesEn = typeof stringsFr extends typeof stringsEn ? true : never; +type EnMatchesFr = typeof stringsEn extends typeof stringsFr ? true : never; +type FrMatchesEn = typeof stringsFr extends typeof stringsEn ? true : never; // Force evaluation (unused types are not checked without a reference). -declare const _parity: _EnMatchesFr & _FrMatchesEn; +declare const _parity: EnMatchesFr & FrMatchesEn; /** * Manages all localized strings for the simulation diff --git a/src/screen-name/graph/ConfigurableGraph.ts b/src/screen-name/graph/ConfigurableGraph.ts index a2ff99e..18bb755 100644 --- a/src/screen-name/graph/ConfigurableGraph.ts +++ b/src/screen-name/graph/ConfigurableGraph.ts @@ -470,9 +470,9 @@ export default class ConfigurableGraph extends Node { this.graphContentNode.visible = visible; this.headerBar.visible = visible; this.titlePanel.visible = visible; - resizeHandles.forEach((handle) => { + for (const handle of resizeHandles) { handle.visible = visible; - }); + } }; this.graphVisibleProperty.link(graphVisibleListener); diff --git a/src/screen-name/graph/GraphDataManager.ts b/src/screen-name/graph/GraphDataManager.ts index fc735ad..b67a33e 100644 --- a/src/screen-name/graph/GraphDataManager.ts +++ b/src/screen-name/graph/GraphDataManager.ts @@ -76,6 +76,7 @@ export default class GraphDataManager { const result: Vector2[] = new Array(this.dataSize); for (let i = 0; i < this.dataSize; i++) { const idx = (this.dataHead - this.dataSize + i + this.maxDataPoints) % this.maxDataPoints; + // biome-ignore lint/style/noNonNullAssertion: index is within dataSize, slot is always written result[i] = this.dataBuf[idx]!; } return result; @@ -109,11 +110,20 @@ export default class GraphDataManager { this.yMax = -Infinity; for (let i = 0; i < this.dataSize; i++) { const idx = (this.dataHead - this.dataSize + i + this.maxDataPoints) % this.maxDataPoints; + // biome-ignore lint/style/noNonNullAssertion: index is within dataSize, slot is always written const p = this.dataBuf[idx]!; - if (p.x < this.xMin) this.xMin = p.x; - if (p.x > this.xMax) this.xMax = p.x; - if (p.y < this.yMin) this.yMin = p.y; - if (p.y > this.yMax) this.yMax = p.y; + if (p.x < this.xMin) { + this.xMin = p.x; + } + if (p.x > this.xMax) { + this.xMax = p.x; + } + if (p.y < this.yMin) { + this.yMin = p.y; + } + if (p.y > this.yMax) { + this.yMax = p.y; + } } } @@ -123,10 +133,18 @@ export default class GraphDataManager { * axis extreme (the common case — a buffer that has never filled — never rescans). */ private updateMinMaxIncremental(x: number, y: number, evicted: Vector2 | undefined): void { - if (x < this.xMin) this.xMin = x; - if (x > this.xMax) this.xMax = x; - if (y < this.yMin) this.yMin = y; - if (y > this.yMax) this.yMax = y; + if (x < this.xMin) { + this.xMin = x; + } + if (x > this.xMax) { + this.xMax = x; + } + if (y < this.yMin) { + this.yMin = y; + } + if (y > this.yMax) { + this.yMax = y; + } if ( evicted !== undefined && (evicted.x <= this.xMin || evicted.x >= this.xMax || evicted.y <= this.yMin || evicted.y >= this.yMax) @@ -190,10 +208,18 @@ export default class GraphDataManager { if (Number.isFinite(x) && Number.isFinite(y)) { const evicted = this.writePoint(x, y); // Inline incremental update (avoids function-call overhead in tight loop). - if (x < this.xMin) this.xMin = x; - if (x > this.xMax) this.xMax = x; - if (y < this.yMin) this.yMin = y; - if (y > this.yMax) this.yMax = y; + if (x < this.xMin) { + this.xMin = x; + } + if (x > this.xMax) { + this.xMax = x; + } + if (y < this.yMin) { + this.yMin = y; + } + if (y > this.yMax) { + this.yMax = y; + } if ( evicted !== undefined && (evicted.x <= this.xMin || evicted.x >= this.xMax || evicted.y <= this.yMin || evicted.y >= this.yMax) diff --git a/src/screen-name/view/AutoTrackerNode.ts b/src/screen-name/view/AutoTrackerNode.ts index ce492b8..a21f310 100644 --- a/src/screen-name/view/AutoTrackerNode.ts +++ b/src/screen-name/view/AutoTrackerNode.ts @@ -243,10 +243,10 @@ export class AutoTrackerNode extends Node { } }) .catch((err: unknown) => { + // biome-ignore lint/suspicious/noConsole: error logging for tracker init failure console.error("AutoTracker: failed to initialise OpenCV tracker:", err); if (this.initVersion === capturedVersion) { - const message = - err instanceof Error ? err.message : "Tracking initialisation failed. Try again."; + const message = err instanceof Error ? err.message : "Tracking initialisation failed. Try again."; this.errorText.string = message; this.errorText.visible = true; this.hintText.visible = true; diff --git a/src/screen-name/view/DataTableNode.ts b/src/screen-name/view/DataTableNode.ts index e1fe891..66517a1 100644 --- a/src/screen-name/view/DataTableNode.ts +++ b/src/screen-name/view/DataTableNode.ts @@ -488,6 +488,7 @@ export class DataTableNode extends Panel { // or colour change) and an incremental row-append on data-only changes // (new points added to existing tracks). During auto-tracking this fires // ~30 times/s, so avoiding unnecessary full DOM rebuilds is critical. + // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: intentionally complex — must handle structural and incremental updates efficiently const rebuildTable = () => { const tracks = model.tracksProperty.value; const unit = unitProperty.value; diff --git a/src/screen-name/view/VideoPlayerNode.ts b/src/screen-name/view/VideoPlayerNode.ts index d6bbde7..64ebe20 100644 --- a/src/screen-name/view/VideoPlayerNode.ts +++ b/src/screen-name/view/VideoPlayerNode.ts @@ -86,6 +86,7 @@ export class VideoPlayerNode extends Node { const isPlayingListener = (isPlaying: boolean) => { if (isPlaying) { this.videoElement.play().catch((err: unknown) => { + // biome-ignore lint/suspicious/noConsole: error logging for video playback failure console.error("Video playback failed:", err); model.isPlayingProperty.value = false; }); diff --git a/src/tracking/OpenCVTracker.ts b/src/tracking/OpenCVTracker.ts index 8943acc..7a0dcc1 100644 --- a/src/tracking/OpenCVTracker.ts +++ b/src/tracking/OpenCVTracker.ts @@ -31,8 +31,15 @@ interface MinMaxLocResult { /** Typed surface of the OpenCV.js module used by this tracker. */ interface Cv { // Constructors + // biome-ignore lint/style/useNamingConvention: OpenCV API uses PascalCase for constructor properties readonly Mat: new () => CvMat; - readonly Rect: new (x: number, y: number, width: number, height: number) => CvRect; + // biome-ignore lint/style/useNamingConvention: OpenCV API uses PascalCase for constructor properties + readonly Rect: new ( + x: number, + y: number, + width: number, + height: number, + ) => CvRect; // Factory from browser ImageData matFromImageData(imageData: ImageData): CvMat; diff --git a/vite.config.js b/vite.config.js index a1a9ec5..a2bb453 100644 --- a/vite.config.js +++ b/vite.config.js @@ -120,9 +120,12 @@ export default defineConfig({ registerType: "autoUpdate", manifest: { name: "trackLab", + // biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys short_name: "trackLab", description: "trackLab simulation", + // biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys theme_color: "#1a1a2e", + // biome-ignore lint/style/useNamingConvention: Web App Manifest spec requires snake_case keys background_color: "#000000", display: "standalone", orientation: "landscape",