From 3942455122b28274cfc38ef0e6543406ebb25a2d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Oct 2026 15:33:35 +0000 Subject: [PATCH 1/2] test(vitest): one shared preset for the 18 configs that set only the disarm The 18 byte-identical package vitest configs re-export vitest.preset.mts at the repo root, which carries disableConsoleIntercept: true and its rationale once. check-console-intercept-disarm judges a bare re-export of the root preset by the preset's own source, so the gate stays and still reds every re-exporter by name if the preset loses the setting. turbo's test task takes the preset as an input so an edit to it reruns the suites. Claude-Session: https://claude.ai/code/session_01EaorEqkvnJBed5uX9BjSUG Co-authored-by: Claude --- examples/app-todo/vitest.config.ts | 19 +--- examples/embed-objectql/vitest.config.ts | 19 +--- .../connector-imap/vitest.config.ts | 19 +--- .../connectors/connector-mcp/vitest.config.ts | 19 +--- .../connector-rest/vitest.config.ts | 19 +--- .../connector-slack/vitest.config.ts | 19 +--- .../driver-sqlite-wasm/vitest.config.ts | 19 +--- .../drivers/driver-turso/vitest.config.ts | 19 +--- packages/formula/vitest.config.ts | 19 +--- packages/observability/vitest.config.ts | 19 +--- .../plugins/plugin-email/vitest.config.ts | 19 +--- packages/sdui-parser/vitest.config.ts | 19 +--- .../services/service-cache/vitest.config.ts | 19 +--- .../service-cluster-redis/vitest.config.ts | 19 +--- .../services/service-i18n/vitest.config.ts | 19 +--- .../services/service-job/vitest.config.ts | 19 +--- .../service-realtime/vitest.config.ts | 19 +--- .../services/service-sms/vitest.config.ts | 19 +--- scripts/check-console-intercept-disarm.mjs | 86 +++++++++++++++++-- scripts/check-cross-package-test-inputs.mjs | 8 +- turbo.json | 2 +- vitest.preset.mts | 26 ++++++ 22 files changed, 147 insertions(+), 317 deletions(-) create mode 100644 vitest.preset.mts diff --git a/examples/app-todo/vitest.config.ts b/examples/app-todo/vitest.config.ts index 5e0591efc44..1579376748b 100644 --- a/examples/app-todo/vitest.config.ts +++ b/examples/app-todo/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../vitest.preset.mts'; diff --git a/examples/embed-objectql/vitest.config.ts b/examples/embed-objectql/vitest.config.ts index 5e0591efc44..1579376748b 100644 --- a/examples/embed-objectql/vitest.config.ts +++ b/examples/embed-objectql/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../vitest.preset.mts'; diff --git a/packages/connectors/connector-imap/vitest.config.ts b/packages/connectors/connector-imap/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/connectors/connector-imap/vitest.config.ts +++ b/packages/connectors/connector-imap/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/connectors/connector-mcp/vitest.config.ts b/packages/connectors/connector-mcp/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/connectors/connector-mcp/vitest.config.ts +++ b/packages/connectors/connector-mcp/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/connectors/connector-rest/vitest.config.ts b/packages/connectors/connector-rest/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/connectors/connector-rest/vitest.config.ts +++ b/packages/connectors/connector-rest/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/connectors/connector-slack/vitest.config.ts b/packages/connectors/connector-slack/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/connectors/connector-slack/vitest.config.ts +++ b/packages/connectors/connector-slack/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/drivers/driver-sqlite-wasm/vitest.config.ts b/packages/drivers/driver-sqlite-wasm/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/drivers/driver-sqlite-wasm/vitest.config.ts +++ b/packages/drivers/driver-sqlite-wasm/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/drivers/driver-turso/vitest.config.ts b/packages/drivers/driver-turso/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/drivers/driver-turso/vitest.config.ts +++ b/packages/drivers/driver-turso/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/formula/vitest.config.ts b/packages/formula/vitest.config.ts index 5e0591efc44..1579376748b 100644 --- a/packages/formula/vitest.config.ts +++ b/packages/formula/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../vitest.preset.mts'; diff --git a/packages/observability/vitest.config.ts b/packages/observability/vitest.config.ts index 5e0591efc44..1579376748b 100644 --- a/packages/observability/vitest.config.ts +++ b/packages/observability/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../vitest.preset.mts'; diff --git a/packages/plugins/plugin-email/vitest.config.ts b/packages/plugins/plugin-email/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/plugins/plugin-email/vitest.config.ts +++ b/packages/plugins/plugin-email/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/sdui-parser/vitest.config.ts b/packages/sdui-parser/vitest.config.ts index 5e0591efc44..1579376748b 100644 --- a/packages/sdui-parser/vitest.config.ts +++ b/packages/sdui-parser/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../vitest.preset.mts'; diff --git a/packages/services/service-cache/vitest.config.ts b/packages/services/service-cache/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/services/service-cache/vitest.config.ts +++ b/packages/services/service-cache/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/services/service-cluster-redis/vitest.config.ts b/packages/services/service-cluster-redis/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/services/service-cluster-redis/vitest.config.ts +++ b/packages/services/service-cluster-redis/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/services/service-i18n/vitest.config.ts b/packages/services/service-i18n/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/services/service-i18n/vitest.config.ts +++ b/packages/services/service-i18n/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/services/service-job/vitest.config.ts b/packages/services/service-job/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/services/service-job/vitest.config.ts +++ b/packages/services/service-job/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/services/service-realtime/vitest.config.ts b/packages/services/service-realtime/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/services/service-realtime/vitest.config.ts +++ b/packages/services/service-realtime/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/packages/services/service-sms/vitest.config.ts b/packages/services/service-sms/vitest.config.ts index 5e0591efc44..092f3349553 100644 --- a/packages/services/service-sms/vitest.config.ts +++ b/packages/services/service-sms/vitest.config.ts @@ -1,19 +1,4 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. -// This config exists for exactly one setting; everything else stays on -// vitest's defaults, deliberately — a key added here re-specifies behaviour -// for every test file in the package (packages/cli/vitest.config.ts's header -// records the incident that taught that). -import { defineConfig } from 'vitest/config'; - -export default defineConfig({ - test: { - // A late console.* must not redden a green suite (#10374): vitest's worker - // forwards console output over RPC and discards the promise, and a write - // landing after teardown's rpcDone() snapshot is rejected into an unhandled - // error — a fully green run that exits 1. Disarming removes the mechanism. - // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. - // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. - disableConsoleIntercept: true, - }, -}); +// This package needs nothing beyond the shared preset; see its header. +export { default } from '../../../vitest.preset.mts'; diff --git a/scripts/check-console-intercept-disarm.mjs b/scripts/check-console-intercept-disarm.mjs index d718a448a89..41a54894b94 100644 --- a/scripts/check-console-intercept-disarm.mjs +++ b/scripts/check-console-intercept-disarm.mjs @@ -89,7 +89,7 @@ import { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, import { dirname, join, resolve } from 'node:path'; import { tmpdir } from 'node:os'; import { fileURLToPath } from 'node:url'; -import { maskCommentsAndLiterals } from './js-comment-mask.mjs'; +import { maskComments, maskCommentsAndLiterals } from './js-comment-mask.mjs'; import { isEntrypoint } from './invoked-as.mjs'; // Why this gate reads `maskCommentsAndLiterals` — the tree's one @@ -171,6 +171,27 @@ function projectTestBlocks(masked) { } return blocks; } +// The shared preset at the repo root. A package-root config whose ONLY +// statement re-exports it (`export { default } from '/vitest.preset.mts'`) +// takes its whole effective config from the preset, so the gate judges the +// preset's source in that config's place: one disarm, read once, covering every +// re-exporter, and a preset that loses it reds every one of them by name. +// Deliberately narrow: a config that imports the preset and merges or wraps it +// is NOT recognised (what it exports is no longer the preset's object), so it +// carries the setting itself, as before. +const PRESET_NAME = 'vitest.preset.mts'; +const PRESET_REEXPORT_RE = /^\s*export\s*\{\s*default\s*\}\s*from\s*(['"])([^'"]+)\1\s*;?\s*$/; + +/** + * @returns {string | null} the repo-relative preset path when `source` is the + * bare re-export of THIS workspace's root preset, else null. + */ +function presetReexport(root, dir, source) { + const m = PRESET_REEXPORT_RE.exec(maskComments(source)); + if (!m) return null; + return resolve(dir, m[2]) === join(root, PRESET_NAME) ? PRESET_NAME : null; +} + /** A script that runs vitest — `vitest run`, `vitest --coverage`, a bare `vitest`. */ const VITEST_SCRIPT_RE = /(?:^|\s|&&|;)vitest(?:\s|$)/; @@ -254,10 +275,13 @@ export function scan(root) { ); continue; } - const masked = maskCommentsAndLiterals(readFileSync(join(dir, configName), 'utf8')); + const source = readFileSync(join(dir, configName), 'utf8'); + const preset = presetReexport(root, dir, source); + const masked = maskCommentsAndLiterals(preset ? readFileSync(join(root, preset), 'utf8') : source); + const via = preset ? ` (via its re-export of ${preset}, which the gate judges in its place)` : ''; if (REARM_RE.test(masked)) { findings.push( - `${rel(root, dir)}/${configName}: sets disableConsoleIntercept: FALSE — this ` + + `${rel(root, dir)}/${configName}${via}: sets disableConsoleIntercept: FALSE — this ` + `re-arms the #10374 teardown race at the package root. The only sanctioned ` + `home for that value is a fixture config BELOW the package root (the ` + `teardown-race pin's positive control). Set it to true, or move the config ` + @@ -267,7 +291,7 @@ export function scan(root) { } if (!DISARM_RE.test(masked)) { findings.push( - `${rel(root, dir)}/${configName}: does not set disableConsoleIntercept: true ` + + `${rel(root, dir)}/${configName}${via}: does not set disableConsoleIntercept: true ` + `(a comment about it does not count) — this suite pays a console RPC per ` + `write and any late console.log can fail its fully green run ` + `(EnvironmentTeardownError: [vitest-worker]: Closing rpc while ` + @@ -280,7 +304,7 @@ export function scan(root) { const undisarmed = blocks.filter((b) => !DISARM_RE.test(b)); if (blocks.length === 0 || undisarmed.length > 0) { findings.push( - `${rel(root, dir)}/${configName}: defines inline projects, and ` + + `${rel(root, dir)}/${configName}${via}: defines inline projects, and ` + `${blocks.length === 0 ? 'no project test block could be read' : `${undisarmed.length} of ${blocks.length} project test block(s) lack the setting`} ` + `— a ROOT-level disableConsoleIntercept is INERT for project runs ` + `(measured on vitest 4.1.10: a probe project's console write still ` + @@ -335,9 +359,10 @@ function main() { // invisible (case 6): those are the two silent-in-the-green-direction bugs a // textual gate can grow. -function buildWorkspace(caseDir, packages) { +function buildWorkspace(caseDir, packages, rootFiles = {}) { mkdirSync(join(caseDir, 'packages'), { recursive: true }); writeFileSync(join(caseDir, 'pnpm-workspace.yaml'), 'packages:\n - packages/*\n'); + for (const [file, content] of Object.entries(rootFiles)) writeFileSync(join(caseDir, file), content); for (const [name, files] of Object.entries(packages)) { const dir = join(caseDir, 'packages', name); mkdirSync(dir, { recursive: true }); @@ -353,6 +378,7 @@ const QUIET_MANIFEST = JSON.stringify({ name: 'x', scripts: { build: 'tsup' } }) const DISARMED = `import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { disableConsoleIntercept: true } }); `; +const REEXPORT = `// nothing of its own\nexport { default } from '../../vitest.preset.mts';\n`; // Returned by `selfTest()` only after its verdict is printed. The dispatch // refuses anything else: a `return` that leaves the function above that line @@ -382,7 +408,7 @@ const SELF_TEST_VERDICT = 'check-console-intercept-disarm self-test reached its // not red. A battery BELOW its floor means cases stopped running; the remedy is // to find what stopped registering. const SELF_TEST_BATTERIES = Object.freeze({ - 'check-console-intercept-disarm self-test': 11, + 'check-console-intercept-disarm self-test': 16, }); // DELETING an entry silences that battery's floor exactly as effectively as @@ -528,13 +554,57 @@ function selfTest() { expectFindings: 1, expectText: 'does not set disableConsoleIntercept', }, + { + name: 'a bare re-export of a disarmed root preset passes', + rootFiles: { 'vitest.preset.mts': DISARMED }, + packages: { a: { 'package.json': TEST_MANIFEST, 'vitest.config.ts': REEXPORT } }, + expectFindings: 0, + }, + { + name: 'a re-export of a preset that does not disarm fails, naming the preset', + rootFiles: { 'vitest.preset.mts': `export default { test: { globals: true } };\n` }, + packages: { a: { 'package.json': TEST_MANIFEST, 'vitest.config.ts': REEXPORT } }, + expectFindings: 1, + expectText: 'via its re-export of vitest.preset.mts', + }, + { + name: 'a re-export of a preset that re-arms fails', + rootFiles: { 'vitest.preset.mts': `export default { test: { disableConsoleIntercept: false } };\n` }, + packages: { a: { 'package.json': TEST_MANIFEST, 'vitest.config.ts': REEXPORT } }, + expectFindings: 1, + expectText: 'FALSE', + }, + { + name: 'a re-export of some OTHER file is judged as the config itself (fails)', + rootFiles: { 'vitest.preset.mts': DISARMED, 'other.mts': DISARMED }, + packages: { + a: { 'package.json': TEST_MANIFEST, 'vitest.config.ts': `export { default } from '../../other.mts';\n` }, + }, + expectFindings: 1, + expectText: 'does not set disableConsoleIntercept', + }, + { + name: 'a config that imports the preset and wraps it is not the preset (fails without its own setting)', + rootFiles: { 'vitest.preset.mts': DISARMED }, + packages: { + a: { + 'package.json': TEST_MANIFEST, + 'vitest.config.ts': + `import preset from '../../vitest.preset.mts';\n` + + `export { default } from '../../vitest.preset.mts';\n` + + `export const extra = { test: { globals: true }, preset };\n`, + }, + }, + expectFindings: 1, + expectText: 'does not set disableConsoleIntercept', + }, ]; let failures = 0; for (const testCase of cases) { const caseDir = mkdtempSync(join(tmpdir(), 'ci-disarm-')); try { - buildWorkspace(caseDir, testCase.packages); + buildWorkspace(caseDir, testCase.packages, testCase.rootFiles); const { findings, vitestPackages } = scan(caseDir); const problems = []; if (findings.length !== testCase.expectFindings) { diff --git a/scripts/check-cross-package-test-inputs.mjs b/scripts/check-cross-package-test-inputs.mjs index c2a193b8695..1ef216f5cb7 100644 --- a/scripts/check-cross-package-test-inputs.mjs +++ b/scripts/check-cross-package-test-inputs.mjs @@ -1454,8 +1454,12 @@ export const TOP_LEVEL_DIRECTORIES_PENDING = Object.freeze({ */ export const TOP_LEVEL_DIRECTORIES_AWAITING_IMPORT = Object.freeze({}); -/** Repo-root FILES declared as `$TURBO_ROOT$` inputs -- the fourth shape, pinned, not collected. */ -export const TURBO_ROOT_FILE_INPUTS = Object.freeze(['sdui.manifest.json']); +/** + * Repo-root FILES declared as `$TURBO_ROOT$` inputs -- the fourth shape, pinned, not collected. + * `vitest.preset.mts` is the shared vitest preset the package configs re-export by + * relative import; it is the `test` task's input so an edit to it reruns their suites. + */ +export const TURBO_ROOT_FILE_INPUTS = Object.freeze(['sdui.manifest.json', 'vitest.preset.mts']); /** `.` is the only regex metacharacter these names carry today; escape the class anyway. */ const TOP_LEVEL_ALTERNATION = RECOGNISED_TOP_LEVEL_DIRECTORIES diff --git a/turbo.json b/turbo.json index ad87228534c..c3a91cad383 100644 --- a/turbo.json +++ b/turbo.json @@ -22,7 +22,7 @@ "dependsOn": ["^build"], "outputs": [], "env": ["OS_TEST_TIERS", "OS_TEST_SHARD"], - "inputs": ["$TURBO_DEFAULT$", "!dist/**", "!coverage/**", "!.turbo/**"] + "inputs": ["$TURBO_DEFAULT$", "!dist/**", "!coverage/**", "!.turbo/**", "$TURBO_ROOT$/vitest.preset.mts"] }, "test:repo": { "dependsOn": ["^build"], diff --git a/vitest.preset.mts b/vitest.preset.mts new file mode 100644 index 00000000000..09d4a7590c3 --- /dev/null +++ b/vitest.preset.mts @@ -0,0 +1,26 @@ +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. + +// The shared vitest preset. A package whose vitest config needs nothing of its +// own re-exports this file (`export { default } from '/vitest.preset.mts'`); +// one that does need something merges it (`mergeConfig(preset, { ... })`). +// +// It carries exactly one setting; everything else stays on vitest's defaults, +// deliberately — a key added here re-specifies behaviour for every test file in +// every package that re-exports it (packages/cli/vitest.config.ts's header +// records the incident that taught that). +// +// A plain object, not `defineConfig(...)` (an identity helper): this file sits +// at the repo root, whose package declares no vitest dependency, so an import +// of `vitest/config` here would resolve only through pnpm's hoisting and would +// not type-check in the root program. +export default { + test: { + // A late console.* must not redden a green suite (#10374): vitest's worker + // forwards console output over RPC and discards the promise, and a write + // landing after teardown's rpcDone() snapshot is rejected into an unhandled + // error — a fully green run that exits 1. Disarming removes the mechanism. + // Mechanism + measured costs: examples/app-showcase/vitest.config.ts. + // Enforced repo-wide by scripts/check-console-intercept-disarm.mjs. + disableConsoleIntercept: true, + }, +}; From c3829861f6573486a48edd7a8ac555cfca335960 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 26 Oct 2026 16:33:19 +0000 Subject: [PATCH 2/2] ci: start the core pipeline on an edit to the root vitest preset vitest.preset.mts (arriving with the vitest half of the base split) is a test input outside every package; list it in the core filter beside the two tsconfig bases so a diff confined to it still runs Test Core. Claude-Session: https://claude.ai/code/session_01EaorEqkvnJBed5uX9BjSUG Co-authored-by: Claude --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1ddfc7d30c4..34a88e46e12 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -279,6 +279,7 @@ jobs: - 'tsconfig.json' - 'tsconfig.base.json' - 'tsconfig.test.base.json' + - 'vitest.preset.mts' - '.github/workflows/ci.yml' # BUILD INPUTS outside every package (#21202): turbo.json itself, # its `globalDependencies`, and each `$TURBO_ROOT$/…` input of a