import fs from 'node:fs'; import path from 'node:path'; import { spawnSync } from 'node:child_process'; const output = path.resolve('_local/quality-20261010'); fs.mkdirSync(output, { recursive: true }); const storybookBin = JSON.parse(fs.readFileSync('node_modules/storybook/package.json')).bin; const jobs = [ ['THEME_DEFAULTS', 'scripts/theme-defaults.mjs', ['--check']], ['TYPECHECK', 'node_modules/typescript/bin/tsc', ['-b']], ['UI_TYPECHECK', 'node_modules/typescript/bin/tsc', ['-p', 'packages/ui/tsconfig.json']], ['CENTER_TYPECHECK', 'node_modules/typescript/bin/tsc', ['-p', 'packages/center-graphic/tsconfig.json']], ['GENERATED_TYPECHECK', 'node_modules/typescript/bin/tsc', ['-p', 'examples/ai-quality/tsconfig.json']], ['PRODUCTION_BUILD', 'node_modules/vite/bin/vite.js', ['build']], ['DASHBOARD_BUILD', 'node_modules/vite/bin/vite.js', ['build', '--config', 'vite.dashboard-export.config.ts']], ['DASHBOARD_FINALIZE', 'scripts/finalize-dashboard-export.mjs', []], ['RECRUIT_BUILD', 'node_modules/vite/bin/vite.js', ['build', '--config', 'vite.recruit-export.config.ts']], ['PUBLISHER_BUILD', 'node_modules/vite/bin/vite.js', ['build', '--config', 'examples/publisher-list/vite.config.ts']], ['STORYBOOK_BUILD', path.join('node_modules/storybook', typeof storybookBin === 'string' ? storybookBin : storybookBin.storybook), ['build', '-o', 'storybook-static', '--disable-telemetry']], ['GUARD_TEST', null, ['--test', 'scripts/ai-generation-guard.test.mjs']], ['EVIDENCE_TEST', null, ['--test', 'scripts/guard-evidence.test.mjs']], ['COMPONENT_TEST', null, ['--test', 'scripts/publisher-components.test.mjs']], ['THEME_TEST', null, ['--test', 'scripts/theme-verification.test.mjs']], ['DOC_LINKS', 'scripts/check-doc-links.mjs', []], ['TOKEN_INVENTORY', 'scripts/public-theme-tokens.mjs', []], ['GUARD_FULL_SCREEN', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'FULL_SCREEN', '--mode', 'GNB_ONLY', '--result', 'index.html', '--json']], ['GUARD_PARTIAL', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'PARTIAL', '--mode', 'GNB_ONLY', '--files', 'src/index.css,tailwind.css', '--result', 'index.html', '--json']], ['GUARD_GENERATED_PARTIAL', 'scripts/ai-generation-guard.mjs', ['--target', 'examples/ai-quality/01', '--scope', 'PARTIAL', '--mode', 'GNB_ONLY', '--files', '../shared/SearchList.tsx', '--result', 'index.html', '--json']], ['GUARD_STORYBOOK', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'FULL_SCREEN', '--profile', 'STORYBOOK', '--json']], ['GUARD_STORYBOOK_PARTIAL', 'scripts/ai-generation-guard.mjs', ['--target', '.', '--scope', 'PARTIAL', '--profile', 'STORYBOOK', '--files', 'src/patterns/filter-bar.stories.tsx', '--json']], ]; const selected = process.argv.slice(2); const results = []; for (const [name, script, args] of jobs.filter(j => !selected.length || selected.includes(j[0]))) { const begin = Date.now(); const r = spawnSync(process.execPath, [...(script ? [script] : []), ...args], { encoding: 'utf8', maxBuffer: 25 * 1024 * 1024 }); fs.writeFileSync(path.join(output, `${name}.stdout.log`), r.stdout ?? ''); fs.writeFileSync(path.join(output, `${name}.stderr.log`), r.stderr ?? ''); let report; if (name.startsWith('GUARD_') && name !== 'GUARD_TEST') { try { report = JSON.parse(r.stdout); } catch {} } const item = { name, command: [process.execPath, ...(script ? [script] : []), ...args], exit: r.status, result: report?.status ?? (r.status === 0 ? 'PASS' : 'FAIL'), ...(report ? { staticStatus: report.staticStatus, issueCounts: Object.fromEntries([...new Set(report.issues.map(i => i.code))].map(code => [code, report.issues.filter(i => i.code === code).length])) } : {}), durationMs: Date.now() - begin, error: r.error?.message }; results.push(item); console.log(JSON.stringify(item)); } fs.writeFileSync(path.join(output, selected.length ? `regression-${selected.join('-')}.json` : 'regression.json'), JSON.stringify(results, null, 2)); if (results.some(r => r.exit !== 0)) process.exitCode = 1;