| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #!/usr/bin/env node
- const fs = require('fs');
- const path = require('path');
- const { spawnSync } = require('child_process');
- const ROOT = path.resolve(__dirname, '..');
- function main() {
- const args = parseArgs(process.argv.slice(2));
- const outputRoot = path.resolve(args.outputRoot || path.join(ROOT, 'outputs'));
- const strict = args.strict !== false;
- fs.mkdirSync(outputRoot, { recursive: true });
- const steps = [
- {
- id: 'proof-gap-software-form',
- command: ['node', ['scripts/export-proof-gap-software-form.js', '--output', path.join(outputRoot, 'tihao-proof-gap-software-form-latest'), '--strict']]
- },
- {
- id: 'proof-gap-request',
- command: ['node', ['scripts/generate-proof-gap-request.js', '--output', path.join(outputRoot, 'proof-gap-request-latest')]]
- },
- {
- id: 'proof-gap-closure',
- command: ['node', ['scripts/proof-gap-closure-audit.js', '--output', path.join(outputRoot, 'proof-gap-closure-latest')]]
- },
- {
- id: 'feedback-loop-closure',
- command: ['node', ['scripts/feedback-loop-closure-audit.js', '--output', path.join(outputRoot, 'feedback-loop-closure-latest')]]
- },
- {
- id: 'homepage-evidence-readiness',
- command: ['node', ['scripts/homepage-evidence-readiness-audit.js', '--output', path.join(outputRoot, 'homepage-evidence-readiness-latest')]]
- },
- {
- id: 'intake-readiness',
- command: ['node', [
- 'scripts/intake-readiness-audit.js',
- '--data-pack',
- path.join(outputRoot, 'data-intake-pack-latest'),
- '--video-pack',
- path.join(outputRoot, 'video-intake-pack-latest'),
- '--output',
- path.join(outputRoot, 'intake-readiness-latest')
- ]]
- },
- {
- id: 'video-resource-readiness',
- command: ['node', [
- 'scripts/video-resource-readiness-audit.js',
- '--input',
- path.join(outputRoot, 'video-intake-pack-latest', 'video-resource-template.csv'),
- '--output',
- path.join(outputRoot, 'video-resource-readiness-latest')
- ]]
- },
- {
- id: 'live-preflight',
- command: ['node', [
- 'scripts/live-preflight.js',
- '--output',
- path.join(outputRoot, 'live-preflight-latest'),
- '--strict',
- '--allow-failure'
- ]]
- },
- {
- id: 'longrun-readiness',
- command: ['node', [
- 'scripts/long-run-readiness-audit.js',
- '--mode',
- 'full-matrix',
- '--intake-readiness',
- path.join(outputRoot, 'intake-readiness-latest', 'intake-readiness-summary.json'),
- '--proof-gap',
- path.join(outputRoot, 'proof-gap-request-latest', 'proof-gap-request-summary.json'),
- '--proof-gap-closure',
- path.join(outputRoot, 'proof-gap-closure-latest', 'proof-gap-closure-summary.json'),
- '--output',
- path.join(outputRoot, 'long-run-readiness-latest')
- ]]
- },
- {
- id: 'intake-field-checklist',
- command: ['node', [
- 'scripts/intake-field-checklist.js',
- '--data-pack',
- path.join(outputRoot, 'data-intake-pack-latest'),
- '--video-pack',
- path.join(outputRoot, 'video-intake-pack-latest'),
- '--output',
- path.join(outputRoot, 'intake-field-checklist-latest')
- ]]
- },
- {
- id: 'manual-review-label-guide',
- command: ['node', ['scripts/manual-review-label-guide.js', '--output', path.join(outputRoot, 'manual-review-label-guide-latest'), '--strict']]
- },
- {
- id: 'proof-gap-operator-pack',
- command: ['node', ['scripts/proof-gap-operator-pack.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'proof-gap-operator-pack-latest'), '--strict']]
- },
- {
- id: 'business-proof-progress',
- command: ['node', ['scripts/business-proof-progress.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'business-proof-progress-latest')]]
- },
- {
- id: 'business-proof-next-actions',
- command: ['node', ['scripts/business-proof-next-actions.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'business-proof-next-actions-latest')]]
- },
- {
- id: 'optimization-completion',
- command: ['node', ['scripts/optimization-completion-audit.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'optimization-completion-latest')]]
- },
- {
- id: 'business-execution-index',
- command: ['node', ['scripts/business-execution-index.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'business-execution-index-latest'), '--strict']]
- },
- {
- id: 'optimization-status',
- command: ['node', ['scripts/optimization-status-audit.js', '--output', path.join(outputRoot, 'optimization-status-latest')]]
- },
- {
- id: 'plan-execution-status',
- command: ['node', ['scripts/plan-execution-status.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'plan-execution-status-latest'), '--strict']]
- },
- {
- id: 'real-proof-intake-bundle',
- command: ['node', ['scripts/real-proof-intake-bundle.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'real-proof-intake-bundle-latest'), '--strict']]
- },
- {
- id: 'software-client-list',
- command: ['node', ['scripts/refresh-software-client-list.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'software-client-latest')]]
- },
- {
- id: 'local-seed-material-index',
- command: ['node', ['scripts/local-seed-material-index.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'local-seed-material-index-latest')]]
- },
- {
- id: 'local-seed-to-intake-worklist',
- command: ['node', ['scripts/local-seed-to-intake-worklist.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'local-seed-to-intake-worklist-latest')]]
- },
- {
- id: 'real-gap-material-audit',
- command: ['node', ['scripts/real-gap-material-audit.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'real-gap-material-audit-latest'), '--strict']]
- },
- {
- id: 'real-proof-closure-work-order',
- command: ['node', ['scripts/real-proof-closure-work-order.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'real-proof-closure-work-order-latest'), '--strict']]
- },
- {
- id: 'latest-form-index',
- command: ['node', ['scripts/latest-form-index.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'latest-form-index-latest'), '--strict']]
- },
- {
- id: 'optimization-handoff',
- command: ['node', ['scripts/generate-optimization-handoff.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'optimization-handoff-latest')]]
- },
- {
- id: 'experience-transcript-index',
- command: ['node', ['scripts/experience-transcript-index.js', '--output', path.join(outputRoot, 'experience-transcript-index-latest')]]
- },
- {
- id: 'evidence-index',
- command: ['node', ['scripts/evidence-index.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'evidence-index-latest')]]
- },
- {
- id: 'round-deposition',
- command: ['node', ['scripts/round-deposition-audit.js', '--outputs', outputRoot, '--output', path.join(outputRoot, 'round-deposition-latest'), '--strict']]
- }
- ];
- const results = steps.map(step => runStep(step, strict));
- const summary = {
- generatedAt: new Date().toISOString(),
- outputRoot,
- strict,
- passed: results.every(item => item.status === 'pass'),
- steps: results,
- artifacts: {
- proofGapSoftwareForm: rel(path.join(outputRoot, 'tihao-proof-gap-software-form-latest', 'tihao-proof-gap-software-form-summary.json')),
- proofGapRequest: rel(path.join(outputRoot, 'proof-gap-request-latest', 'proof-gap-request-summary.json')),
- proofGapClosure: rel(path.join(outputRoot, 'proof-gap-closure-latest', 'proof-gap-closure-summary.json')),
- feedbackLoopClosure: rel(path.join(outputRoot, 'feedback-loop-closure-latest', 'feedback-loop-closure-summary.json')),
- homepageEvidenceReadiness: rel(path.join(outputRoot, 'homepage-evidence-readiness-latest', 'homepage-evidence-readiness-summary.json')),
- intakeReadiness: rel(path.join(outputRoot, 'intake-readiness-latest', 'intake-readiness-summary.json')),
- videoResourceReadiness: rel(path.join(outputRoot, 'video-resource-readiness-latest', 'video-resource-readiness-summary.json')),
- livePreflight: rel(path.join(outputRoot, 'live-preflight-latest', 'live-preflight-summary.json')),
- longRunReadiness: rel(path.join(outputRoot, 'long-run-readiness-latest', 'long-run-readiness-summary.json')),
- intakeFieldChecklist: rel(path.join(outputRoot, 'intake-field-checklist-latest', 'intake-field-checklist-summary.json')),
- manualReviewLabelGuide: rel(path.join(outputRoot, 'manual-review-label-guide-latest', 'manual-review-label-guide-summary.json')),
- businessProofProgress: rel(path.join(outputRoot, 'business-proof-progress-latest', 'business-proof-progress-summary.json')),
- businessProofNextActions: rel(path.join(outputRoot, 'business-proof-next-actions-latest', 'business-proof-next-actions-summary.json')),
- businessExecutionIndex: rel(path.join(outputRoot, 'business-execution-index-latest', 'business-execution-index-summary.json')),
- optimizationStatus: rel(path.join(outputRoot, 'optimization-status-latest', 'optimization-status-summary.json')),
- evidenceIndex: rel(path.join(outputRoot, 'evidence-index-latest', 'evidence-index-summary.json')),
- handoffSummary: rel(path.join(outputRoot, 'optimization-handoff-latest', 'optimization-handoff-summary.json')),
- planExecutionStatus: rel(path.join(outputRoot, 'plan-execution-status-latest', 'plan-execution-status-summary.json')),
- proofGapOperatorPack: rel(path.join(outputRoot, 'proof-gap-operator-pack-latest', 'proof-gap-operator-pack-summary.json')),
- realProofIntakeBundle: rel(path.join(outputRoot, 'real-proof-intake-bundle-latest', 'real-proof-intake-bundle-summary.json')),
- softwareClientList: rel(path.join(outputRoot, 'software-client-latest', 'software-client-refresh-summary.json')),
- latestFormIndex: rel(path.join(outputRoot, 'latest-form-index-latest', 'latest-form-index-summary.json')),
- optimizationCompletion: rel(path.join(outputRoot, 'optimization-completion-latest', 'optimization-completion-summary.json')),
- localSeedMaterialIndex: rel(path.join(outputRoot, 'local-seed-material-index-latest', 'local-seed-material-index-summary.json')),
- localSeedToIntakeWorklist: rel(path.join(outputRoot, 'local-seed-to-intake-worklist-latest', 'local-seed-to-intake-worklist-summary.json')),
- realGapMaterialAudit: rel(path.join(outputRoot, 'real-gap-material-audit-latest', 'real-gap-material-audit-summary.json')),
- realProofClosureWorkOrder: rel(path.join(outputRoot, 'real-proof-closure-work-order-latest', 'real-proof-closure-work-order-summary.json')),
- experienceTranscriptIndex: rel(path.join(outputRoot, 'experience-transcript-index-latest', 'experience-transcript-index-summary.json')),
- roundDeposition: rel(path.join(outputRoot, 'round-deposition-latest', 'round-deposition-summary.json'))
- }
- };
- const summaryPath = path.join(outputRoot, 'round-refresh-summary.json');
- fs.writeFileSync(summaryPath, JSON.stringify(summary, null, 2), 'utf8');
- console.log(JSON.stringify({
- outputRoot,
- summary: summaryPath,
- passed: summary.passed,
- steps: summary.steps.map(item => `${item.id}:${item.status}`)
- }, null, 2));
- if (!summary.passed && strict) process.exitCode = 1;
- }
- function runStep(step, strict) {
- const [command, args] = step.command;
- const resolvedCommand = command === 'node' ? process.execPath : command;
- const startedAt = new Date().toISOString();
- const result = spawnSync(resolvedCommand, args, {
- cwd: ROOT,
- encoding: 'utf8',
- shell: false
- });
- const status = result.status === 0 ? 'pass' : 'fail';
- if (result.stdout) process.stdout.write(result.stdout);
- if (result.stderr) process.stderr.write(result.stderr);
- if (status === 'fail' && strict) {
- return {
- id: step.id,
- status,
- startedAt,
- finishedAt: new Date().toISOString(),
- exitCode: result.status,
- error: `${command} ${args.join(' ')} failed`
- };
- }
- return {
- id: step.id,
- status,
- startedAt,
- finishedAt: new Date().toISOString(),
- exitCode: result.status
- };
- }
- function parseArgs(argv) {
- const result = {};
- for (let index = 0; index < argv.length; index += 1) {
- const arg = argv[index];
- if (!arg.startsWith('--')) continue;
- const key = arg.slice(2).replace(/-([a-z])/g, (_, char) => char.toUpperCase());
- const next = argv[index + 1];
- if (!next || next.startsWith('--')) result[key] = true;
- else {
- result[key] = next;
- index += 1;
- }
- }
- return result;
- }
- function rel(file) {
- return path.relative(ROOT, file).replace(/\\/g, '/');
- }
- if (require.main === module) main();
|