Merge branch 'merge/1829-master' into merge/1990-1829

# Conflicts:
#	vitest.config.ts
This commit is contained in:
Huanqi Cao
2026-08-10 11:24:58 +08:00
86 changed files with 1031 additions and 367 deletions
+14 -18
View File
@@ -57,16 +57,13 @@ const windowsOnlyCoverageExclusions = process.platform !== 'win32'
]
: []
// Mirrors windowsCoverageExclusions: pwsh-local's and pwsh-sandbox's
// run/start/lifecycle suites self-skip without a real pwsh (executor.spec.ts
// hasPwsh, sandbox.spec.ts pwshAvailable). pwsh-local keeps the bar on its
// pwsh-independent modules and exempts only the executor file; pwsh-sandbox's
// remaining helpers branch (classifyDenial) and its invariant companion both
// ride the executor suites' real pwsh runs, so on a pwsh-less host (the
// self-hosted Linux runners ship no pwsh) every source file would sit below
// the per-file bar — exempt the whole package src there, mirroring
// windowsOnlyCoverageExclusions. The probe runs the suites' own resolution
// (resolvePwshPath), so the exemption is active exactly when the suites skip.
// pwsh-local's run/start/lifecycle suites self-skip without a real pwsh
// (executor.spec.ts hasPwsh), leaving this file
// far below per-file 100% on pwsh-less hosts; the exemption keeps those hosts
// green while CI runners ship pwsh and still enforce the full bar. The probe
// runs the suites' own resolution (the dependency-free resolve.ts module),
// so the exemption is active exactly when the suites skip — a mismatched
// narrower probe could exempt the file on hosts whose suites actually run.
const pwshCoverageExclusions = spawnSync(resolvePwshPath(), ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', '$true'], { encoding: 'utf8' }).status === 0
? []
: [
@@ -96,6 +93,8 @@ const coverageExemptExcludes = coverageExemptRaw === '1'
// that worker threads cannot isolate reliably under aggregate gate contention.
// Keep the narrow exception in forks while the rest of the inventory avoids per-file processes.
const processBoundTests = [
'packages/session/session-persistence-jsonl/tests/jsonl.spec.ts',
'packages/subagent/subagent-acp/tests/subagent-acp.spec.ts',
'packages/subprocess/subprocess-local/tests/spawn.spec.ts',
'packages/context/time-context/tests/time-context.spec.ts',
'packages/llm/llm-pi-ai/tests/adapter.spec.ts',
@@ -110,9 +109,8 @@ export default defineConfig({
// .tsx: client component specs (jsdom via per-file @vitest-environment pragma).
include: testIncludes,
exclude: windowsUnsupportedPackages.map(path => `${path}/tests/**/*.spec.ts`),
// One coverage invocation aggregates both projects. Regular suites fork on
// POSIX for Node stability and use threads on Windows; process-bound suites
// always fork.
// One coverage invocation aggregates both projects. Every suite forks for
// Node stability; process-bound suites stay separate for inventory control.
projects: [
{
plugins: [pathsPlugin(), standardDecoratorPlugin()],
@@ -120,11 +118,9 @@ export default defineConfig({
name: 'thread-safe',
execArgv: vitestExecArgv,
// Node 24 has aborted in its CJS lexer (v8::ToLocalChecked Empty
// MaybeLocal in cjs_lexer::Parse) from worker threads on macOS
// arm64 and later on Linux. A fork contains that external runtime
// failure to the test process; Windows keeps the thread pool, where
// the abort has not reproduced and process spawn is costlier.
pool: process.platform === 'win32' ? 'threads' : 'forks',
// MaybeLocal in cjs_lexer::Parse) from worker threads on macOS,
// Linux, and Windows. Forked workers avoid that shared thread path.
pool: 'forks',
setupFiles: ['./scripts/test-invariants.ts'],
include: testIncludes,
exclude: [