/** Offline alignment regression: never starts a model service or Claude CLI. */ import { build } from 'esbuild' import { spawnSync } from 'node:child_process' import { createRequire } from 'node:module' const requireDom = process.argv.includes('--require-dom') || process.env.YCODE_TEST_REQUIRE_DOM === '1' const domModule = process.env.YCODE_TEST_DOM_MODULE if (requireDom && !domModule) { console.error('FAIL alignment DOM: set YCODE_TEST_DOM_MODULE to an installed jsdom module path; --require-dom / YCODE_TEST_REQUIRE_DOM=1 forbids skipping DOM tests.') process.exit(1) } if (domModule) { try { const { JSDOM } = createRequire(process.cwd() + '/package.json')(domModule) if (typeof JSDOM !== 'function') throw new Error('module does not export JSDOM') } catch (error) { console.error(`FAIL alignment DOM: cannot load YCODE_TEST_DOM_MODULE=${domModule}: ${error.message}`) process.exit(1) } } const tests = [ 'model-selection-alignment-regression.ts', 'model-settings-alignment-regression.ts', 'session-factory-alignment-regression.ts', 'session-composer-alignment-regression.tsx', 'alignment-conversation-regression.tsx', 'question-answer-shell-regression.tsx', 'runtime-authorization-regression.ts', 'permission-intercept-regression.tsx' ] for (const file of tests) { const format = file.endsWith('.tsx') ? 'cjs' : 'esm' const outfile = `.tmp/alignment-tests/${file.replace(/\.tsx?$/, format === 'cjs' ? '.cjs' : '.mjs')}` await build({ entryPoints: [`scripts/${file}`], outfile, bundle: true, platform: 'node', format, external: ['esbuild'], jsx: 'automatic', loader: { '.css': 'empty' }, logLevel: 'warning' }) const result = spawnSync(process.execPath, [outfile], { stdio: 'inherit', timeout: 120000 }) if (result.error) throw result.error if (result.status !== 0) process.exit(result.status ?? 1) } // Host/SDK-interface fixtures; these builders stub query and never launch the CLI. for (const file of ['scripts/build-runtime-regressions.mjs', '.tmp/claude-approval-policy-regression.mjs', '.tmp/claude-grant-replay-regression.mjs', 'scripts/build-b03-policy-regression.mjs', '.tmp/b03-policy-regression.mjs']) { const result = spawnSync(process.execPath, [file], { stdio: 'inherit', timeout: 120000 }) if (result.error) throw result.error if (result.status !== 0) process.exit(result.status ?? 1) } // Optional DOM tests use separately installed jsdom, not Electron/CLI or an upstream model. if (domModule) { for (const file of ['task-popconfirm-regression', 'question-interaction-regression', 'question-identity-regression', 'question-composer-dom-regression', 'completed-fold-nested-regression', 'completed-fold-native-identity-regression', 'permission-intercept-dom-regression', 'reasoning-follow-dom-regression']) { const outfile = `.tmp/alignment-tests/${file}.cjs` await build({ entryPoints: [`scripts/${file}.tsx`], outfile, bundle: true, platform: 'node', format: 'cjs', jsx: 'automatic', loader: { '.css': 'empty' }, logLevel: 'warning' }) const result = spawnSync(process.execPath, [outfile], { stdio: 'inherit', timeout: 120000 }) if (result.error) throw result.error if (result.status !== 0) process.exit(result.status ?? 1) } const modeChip = spawnSync(process.execPath, ['scripts/test-mode-chip.mjs'], { stdio: 'inherit', timeout: 120000 }) if (modeChip.error) throw modeChip.error if (modeChip.status !== 0) process.exit(modeChip.status ?? 1) } console.log(JSON.stringify({ result: 'PASS', phase: 'alignment-offline', suites: tests.length + 3 })) console.log(JSON.stringify(domModule ? { result: 'PASS', phase: 'alignment-dom', suites: 9 } : { result: 'SKIP', phase: 'alignment-dom', suites: 9, reason: 'YCODE_TEST_DOM_MODULE is not set; DOM coverage was not run. Use --require-dom to forbid this skip.' }))