From c4ba35363eafc2dfe4ac7e5f49c82be2a40937c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 26 Jul 2026 17:43:39 +0000 Subject: [PATCH 1/3] build(deps-dev): bump @biomejs/biome from 2.4.16 to 2.5.4 Bumps [@biomejs/biome](https://github.com/biomejs/biome/tree/HEAD/packages/@biomejs/biome) from 2.4.16 to 2.5.4. - [Release notes](https://github.com/biomejs/biome/releases) - [Changelog](https://github.com/biomejs/biome/blob/main/packages/@biomejs/biome/CHANGELOG.md) - [Commits](https://github.com/biomejs/biome/commits/@biomejs/biome@2.5.4/packages/@biomejs/biome) --- updated-dependencies: - dependency-name: "@biomejs/biome" dependency-version: 2.5.0 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package.json | 2 +- pnpm-lock.yaml | 74 +++++++++++++++++++++++++------------------------- 2 files changed, 38 insertions(+), 38 deletions(-) diff --git a/package.json b/package.json index 0e64656e..7879d7c7 100644 --- a/package.json +++ b/package.json @@ -148,7 +148,7 @@ }, "devDependencies": { "@axe-core/playwright": "^4.11.0", - "@biomejs/biome": "^2.4.16", + "@biomejs/biome": "^2.5.4", "@lhci/cli": "^0.15.1", "@playwright/test": "^1.61.0", "@storybook/addon-a11y": "^10.4.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 476e664b..18bbc64b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -192,8 +192,8 @@ importers: specifier: ^4.11.0 version: 4.11.3(playwright-core@1.61.0) '@biomejs/biome': - specifier: ^2.4.16 - version: 2.4.16 + specifier: ^2.5.4 + version: 2.5.4 '@lhci/cli': specifier: ^0.15.1 version: 0.15.1(supports-color@10.2.2) @@ -1185,59 +1185,59 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@2.4.16': - resolution: {integrity: sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA==} + '@biomejs/biome@2.5.4': + resolution: {integrity: sha512-xy5FNE5kQJKyK5MR1gJy6ztXYx4WBAbYGlK04lMEgmyPRWKybY9NFwiG9yo0XdzOU8Xvhj41u034J1ywfoWfMw==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.4.16': - resolution: {integrity: sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A==} + '@biomejs/cli-darwin-arm64@2.5.4': + resolution: {integrity: sha512-4o3NFRobXHynkgcFVrlZsoDAFtF2ldlEGN8sORSws5ZQqyY4PXnPUIylu4ksfyHuwkfvDREuWh3JK+niRwGq3w==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.4.16': - resolution: {integrity: sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw==} + '@biomejs/cli-darwin-x64@2.5.4': + resolution: {integrity: sha512-D32P5HkU2Y6PySuC/WsVDTOgsDwVFmujzhhhOQjajtATpVWFDXuVd3oRbsWNSEA+aaFzyzZm22szsyydBYlSyQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.4.16': - resolution: {integrity: sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg==} + '@biomejs/cli-linux-arm64-musl@2.5.4': + resolution: {integrity: sha512-Rpm5/AT1m+DlJmUoYvS4/vXc+0tXJPJ2NQz25TGPyHVF5JrWy75PE0GH6kVxsKtQDuCH4OgzquZq0R4kj/wCVg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.4.16': - resolution: {integrity: sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ==} + '@biomejs/cli-linux-arm64@2.5.4': + resolution: {integrity: sha512-pSEfW7B8kTsXUjUxC1xVVK+y85Ht3C5XxZ9gclmC7/3Ku9Vqz8jmI7k0p/BNIjQ6t4sFERI2sFeH73ybiZl6YQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.4.16': - resolution: {integrity: sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg==} + '@biomejs/cli-linux-x64-musl@2.5.4': + resolution: {integrity: sha512-aby/PohmmgbShcHqFsZVzG8H6D98+P+A6xRWRrQcLW1pCjabcov5UUlke4UqNQBYTkDQav+jB4zyyDDeKB2GaA==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.4.16': - resolution: {integrity: sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ==} + '@biomejs/cli-linux-x64@2.5.4': + resolution: {integrity: sha512-FNxojWJkL7EajAuzBgoLe0T2G0y112M4lBrDIFl/DomFTx8yqenYOIdsRLNXvOvBBofE8hJi85LjzLmBDpY7/Q==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.4.16': - resolution: {integrity: sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A==} + '@biomejs/cli-win32-arm64@2.5.4': + resolution: {integrity: sha512-emoXexPZIPAZkz2RKmA95WJUqK3I5MJNYtwEbL5ESciRzhmFMMyekDhNG8hpeOaK+ZGRDxAU4wvGuA5IHQ0h0w==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.4.16': - resolution: {integrity: sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw==} + '@biomejs/cli-win32-x64@2.5.4': + resolution: {integrity: sha512-U1jaluLw1qQc2Tx7/CeSoL9N5XcqIH+GWjpUAy1ouB5nVjSCMNO+NNHdY3RAs8zxNurLWAdj6pehQdCA2zyU+Q==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] @@ -8862,39 +8862,39 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@2.4.16': + '@biomejs/biome@2.5.4': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.4.16 - '@biomejs/cli-darwin-x64': 2.4.16 - '@biomejs/cli-linux-arm64': 2.4.16 - '@biomejs/cli-linux-arm64-musl': 2.4.16 - '@biomejs/cli-linux-x64': 2.4.16 - '@biomejs/cli-linux-x64-musl': 2.4.16 - '@biomejs/cli-win32-arm64': 2.4.16 - '@biomejs/cli-win32-x64': 2.4.16 + '@biomejs/cli-darwin-arm64': 2.5.4 + '@biomejs/cli-darwin-x64': 2.5.4 + '@biomejs/cli-linux-arm64': 2.5.4 + '@biomejs/cli-linux-arm64-musl': 2.5.4 + '@biomejs/cli-linux-x64': 2.5.4 + '@biomejs/cli-linux-x64-musl': 2.5.4 + '@biomejs/cli-win32-arm64': 2.5.4 + '@biomejs/cli-win32-x64': 2.5.4 - '@biomejs/cli-darwin-arm64@2.4.16': + '@biomejs/cli-darwin-arm64@2.5.4': optional: true - '@biomejs/cli-darwin-x64@2.4.16': + '@biomejs/cli-darwin-x64@2.5.4': optional: true - '@biomejs/cli-linux-arm64-musl@2.4.16': + '@biomejs/cli-linux-arm64-musl@2.5.4': optional: true - '@biomejs/cli-linux-arm64@2.4.16': + '@biomejs/cli-linux-arm64@2.5.4': optional: true - '@biomejs/cli-linux-x64-musl@2.4.16': + '@biomejs/cli-linux-x64-musl@2.5.4': optional: true - '@biomejs/cli-linux-x64@2.4.16': + '@biomejs/cli-linux-x64@2.5.4': optional: true - '@biomejs/cli-win32-arm64@2.4.16': + '@biomejs/cli-win32-arm64@2.5.4': optional: true - '@biomejs/cli-win32-x64@2.4.16': + '@biomejs/cli-win32-x64@2.5.4': optional: true '@bramus/specificity@2.4.2': From f5c67ffa1e78a83581a36b2d8aec94da292d9b72 Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Tue, 28 Jul 2026 07:20:25 +0200 Subject: [PATCH 2/3] chore(biome): sync biome.json \$schema to 2.5.4 Dependabot's version bump didn't update the config schema reference, which biome's own parser flags as a warning -- escalated to a hard lint failure by --error-on-warnings. Co-Authored-By: Claude Sonnet 5 --- biome.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/biome.json b/biome.json index d785dc12..71a1e544 100644 --- a/biome.json +++ b/biome.json @@ -1,5 +1,5 @@ { - "$schema": "https://biomejs.dev/schemas/2.4.16/schema.json", + "$schema": "https://biomejs.dev/schemas/2.5.4/schema.json", "vcs": { "enabled": true, "clientKind": "git", From 297a104a72e570db5856049ee9d2a5065efc2efc Mon Sep 17 00:00:00 2001 From: qnbs <155236708+qnbs@users.noreply.github.com> Date: Tue, 28 Jul 2026 08:51:04 +0200 Subject: [PATCH 3/3] fix(quality): resolve biome 2.5.x lint findings (real fixes, no suppressions) Biome 2.5.4 (bumped from 2.4.16 by Dependabot) enables two rules the codebase didn't yet satisfy: - lint/correctness/noUnsafeOptionalChaining (4 errors): each was the pattern `(x?.[n] as T).prop` / `(x?.[n] as (...) => T)()` -- optional chaining protects the property access but not the subsequent cast + call/access, which throws at runtime if the chain short-circuits. Fixed by extracting the optional-chain result into its own variable first (a separate statement), which is both safe and satisfies the rule, in tests/unit/collaborationService.test.ts, tests/unit/hooks/useManuscriptView.test.ts (x2), and tests/unit/ragVectorMigration.test.ts. - lint/suspicious/noUndeclaredEnvVars (16 warnings, escalated to failures by --error-on-warnings): env vars used across scripts, config files, and tests weren't declared in turbo.json's globalEnv, so Turborepo's cache correctness couldn't account for them. Declared all 16 (ANALYZE, BASE_URL, CF_PAGES*, CLOUDFLARE_*, DEPLOY_TARGET, DEV, GRAPHIFY_SKIP, PLAYWRIGHT_*, RUN_*_E2E, SMOKE_PORT). Also ran `biome migrate` for the linter.rules.recommended -> linter.rules.preset config rename (deprecation notice, not error-level, but biome's own suggested fix and trivial). Verified: pnpm run lint (clean), pnpm run typecheck (clean), pnpm run suppressions:check (52/52, no new suppressions), and the 3 affected test files (81 tests passing). Co-Authored-By: Claude Sonnet 5 --- CHANGELOG.md | 8 ++++++++ biome.json | 2 +- tests/unit/collaborationService.test.ts | 3 ++- tests/unit/hooks/useManuscriptView.test.ts | 6 ++++-- tests/unit/ragVectorMigration.test.ts | 3 ++- turbo.json | 18 ++++++++++++++++++ 6 files changed, 35 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebc2e142..0b8ddad3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -84,6 +84,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 `services/ai/worldScriptCompletionFetch.ts` and `createLanguageModelForWorldScript`'s `LanguageModel` return type in `services/ai/providerFactory.ts` are unaffected. Verified with `pnpm run typecheck`, `pnpm run lint`, and the full AI-provider/completion-fetch test suites (all passing). +- **Biome upgraded to 2.5.4** (from 2.4.16), migrated cleanly. Two new rules the version enables + required real fixes, not suppressions: `lint/correctness/noUnsafeOptionalChaining` (4 test files — + `(x?.[n] as T).prop`-style patterns split into a separate variable assignment so an optional-chain + short-circuit can no longer throw at the point of use) and `lint/suspicious/noUndeclaredEnvVars` + (16 environment variables used across scripts/config/tests weren't declared in `turbo.json`'s + `globalEnv`, so Turborepo's cache correctness couldn't account for them — now declared). Also ran + `biome migrate` for the `linter.rules.recommended` → `linter.rules.preset` config rename ahead of + Biome's next major version. - **Settings hygiene.** Removed stale Experimental-category search hints (`plot board`, `codex`, `cross project` — retired/promoted flags) in favor of current features; `ProForgeDashboard` now diff --git a/biome.json b/biome.json index 71a1e544..6c8879d4 100644 --- a/biome.json +++ b/biome.json @@ -37,7 +37,7 @@ "linter": { "enabled": true, "rules": { - "recommended": true, + "preset": "recommended", "style": { "noNonNullAssertion": "off", "useImportType": "error" diff --git a/tests/unit/collaborationService.test.ts b/tests/unit/collaborationService.test.ts index fe5fda73..066230d5 100644 --- a/tests/unit/collaborationService.test.ts +++ b/tests/unit/collaborationService.test.ts @@ -482,7 +482,8 @@ describe('collaborationService encryption', () => { // The call from _setAwarenessUser in connect() should pass an __enc object, not a plain user const awarenessCall = calls.find((c: unknown[]) => c[0] === 'user'); expect(awarenessCall?.[1]).toHaveProperty('__enc'); - expect(typeof (awarenessCall?.[1] as Record)['__enc']).toBe('string'); + const awarenessPayload = awarenessCall?.[1]; + expect(typeof (awarenessPayload as Record)['__enc']).toBe('string'); }); // QNBS-v3: Plaintext mode — awareness is stored as plain CollaborationUser object. diff --git a/tests/unit/hooks/useManuscriptView.test.ts b/tests/unit/hooks/useManuscriptView.test.ts index 3c2807be..88389af3 100644 --- a/tests/unit/hooks/useManuscriptView.test.ts +++ b/tests/unit/hooks/useManuscriptView.test.ts @@ -212,7 +212,8 @@ describe('handleMoveSection', () => { const call = mockDispatch.mock.calls.find((c) => c[0]?.type === 'project/setManuscript'); expect(call).toBeDefined(); - const newOrder = (call?.[0] as { payload: StorySection[] }).payload; + const action = call?.[0]; + const newOrder = (action as { payload: StorySection[] }).payload; expect(newOrder[0]?.id).toBe('s2'); expect(newOrder[1]?.id).toBe('s1'); }); @@ -257,7 +258,8 @@ describe('handleDragSort', () => { const call = mockDispatch.mock.calls.find((c) => c[0]?.type === 'project/setManuscript'); expect(call).toBeDefined(); - const newOrder = (call?.[0] as { payload: StorySection[] }).payload; + const action = call?.[0]; + const newOrder = (action as { payload: StorySection[] }).payload; expect(newOrder[0]?.id).toBe('s2'); expect(newOrder[2]?.id).toBe('s1'); }); diff --git a/tests/unit/ragVectorMigration.test.ts b/tests/unit/ragVectorMigration.test.ts index 80af5728..7f74be9a 100644 --- a/tests/unit/ragVectorMigration.test.ts +++ b/tests/unit/ragVectorMigration.test.ts @@ -126,7 +126,8 @@ describe('runRagVectorMigration', () => { expect(ragCall?.[0]).toBe('proj-1'); expect(ragCall?.[1]).toBe(manuscript); expect(typeof ragCall?.[2]).toBe('function'); - expect((ragCall?.[2] as () => boolean)()).toBe(true); + const migrateGate = ragCall?.[2]; + expect((migrateGate as () => boolean)()).toBe(true); expect(mockExec).toHaveBeenCalledWith(expect.stringContaining('rag_vectors_v2_migrated')); }); diff --git a/turbo.json b/turbo.json index 9fcf45b3..d96041cb 100644 --- a/turbo.json +++ b/turbo.json @@ -1,5 +1,23 @@ { "$schema": "https://turbo.build/schema.json", + "globalEnv": [ + "ANALYZE", + "BASE_URL", + "CF_PAGES", + "CF_PAGES_BRANCH", + "CF_PAGES_SKIP_WRANGLER", + "CLOUDFLARE_MANUAL_DEPLOY", + "CLOUDFLARE_PAGES_PROJECT", + "DEPLOY_TARGET", + "DEV", + "GRAPHIFY_SKIP", + "PLAYWRIGHT_REUSE_SERVER", + "PLAYWRIGHT_SKIP_VRT", + "RUN_DEEP_E2E", + "RUN_MOBILE_E2E", + "RUN_REAL_VOICE_E2E", + "SMOKE_PORT" + ], "tasks": { "build": { "dependsOn": ["^build"],