#!/usr/bin/env bun import { mkdirSync, writeFileSync } from 'fs' import { join } from 'path' const root = process.cwd() const outRoot = join(root, 'content_population_exports') mkdirSync(outRoot, { recursive: true }) const steps = [ { name: 'source_acquisition_plan', command: ['bun', 'run', 'source:acquisition'], requiredForPacket: true }, { name: 'dataforseo_pilot_intake', command: ['bun', 'run', 'dataforseo:pilot'], requiredForPacket: true }, { name: 'dataforseo_products_live_guard', command: ['bun', 'run', 'dataforseo:products-live'], requiredForPacket: true }, { name: 'dataforseo_live_connection_evidence', command: ['bun', 'run', 'dataforseo:live-asin-evidence'], requiredForPacket: true }, { name: 'dataforseo_asin_candidates', command: ['bun', 'run', 'dataforseo:asin-candidates'], requiredForPacket: true }, { name: 'dataforseo_asin_web_evidence', command: ['bun', 'run', 'dataforseo:asin-web-evidence'], requiredForPacket: true }, { name: 'dataforseo_unresolved_asin_evidence', command: ['bun', 'run', 'dataforseo:unresolved-asins'], requiredForPacket: true }, { name: 'dataforseo_asin_confirmations', command: ['bun', 'run', 'dataforseo:asin-confirmations'], requiredForPacket: true }, { name: 'dataforseo_asin_promotion', command: ['bun', 'run', 'dataforseo:promote-asins'], requiredForPacket: true }, { name: 'dataforseo_pilot_packet', command: ['bun', 'run', 'dataforseo:pilot'], requiredForPacket: true }, { name: 'dataforseo_asin_lookup', command: ['bun', 'run', 'dataforseo:asin-lookup'], requiredForPacket: true }, { name: 'dataforseo_reviews_docs_status', command: ['bun', 'run', 'dataforseo:reviews-docs-status'], requiredForPacket: true }, { name: 'dataforseo_task_preflight', command: ['bun', 'run', 'dataforseo:task-preflight'], requiredForPacket: true }, { name: 'dataforseo_reviews_live_guard', command: ['bun', 'run', 'dataforseo:reviews-live'], requiredForPacket: true }, { name: 'dataforseo_support_escalation', command: ['bun', 'run', 'dataforseo:support-escalation'], requiredForPacket: true }, { name: 'dataforseo_support_response_gate', command: ['bun', 'run', 'dataforseo:support-response'], requiredForPacket: true }, { name: 'dataforseo_approval_request', command: ['bun', 'run', 'dataforseo:approval-request'], requiredForPacket: true }, { name: 'manual_amazon_review_capture', command: ['bun', 'run', 'amazon:manual-capture'], requiredForPacket: true }, { name: 'manual_amazon_review_capture_validation', command: ['bun', 'run', 'amazon:manual-capture-validate'], requiredForPacket: true }, { name: 'dataforseo_ingest_waiting_room', command: ['bun', 'run', 'dataforseo:ingest'], requiredForPacket: true }, { name: 'dataforseo_pilot_review_gate', command: ['bun', 'run', 'dataforseo:review'], requiredForPacket: true }, { name: 'apify_gapfill_packet', command: ['bun', 'run', 'apify:gapfill'], requiredForPacket: true }, { name: 'apify_task_preflight', command: ['bun', 'run', 'apify:task-preflight'], requiredForPacket: true }, { name: 'source_pricing_references', command: ['bun', 'run', 'source:pricing-refs'], requiredForPacket: true }, { name: 'source_cost_scenarios', command: ['bun', 'run', 'source:cost-scenarios'], requiredForPacket: true }, { name: 'source_budget_gate', command: ['bun', 'run', 'source:budget'], requiredForPacket: true }, { name: 'source_cost_plan', command: ['bun', 'run', 'source:cost-plan'], requiredForPacket: true }, { name: 'source_approval_gate', command: ['bun', 'run', 'source:approvals'], requiredForPacket: true }, { name: 'source_spend_gate', command: ['bun', 'run', 'source:spend-gate'], requiredForPacket: true }, { name: 'dataforseo_task_preflight_final', command: ['bun', 'run', 'dataforseo:task-preflight'], requiredForPacket: true }, { name: 'source_subscription_decision', command: ['bun', 'run', 'source:subscription-decision'], requiredForPacket: true }, { name: 'source_next_actions', command: ['bun', 'run', 'source:next-actions'], requiredForPacket: true } ] function csv(rows: any[], headers: string[]) { const esc = (value: any) => { if (value === undefined || value === null) value = '' if (Array.isArray(value)) value = value.join(' | ') value = String(value) return /[",\n\r]/.test(value) ? `"${value.replace(/"/g, '""')}"` : value } return [headers.join(','), ...rows.map(row => headers.map(header => esc(row[header])).join(','))].join('\n') + '\n' } const generatedAt = new Date().toISOString() const results: any[] = [] for (const step of steps) { const startedAt = new Date().toISOString() const proc = Bun.spawnSync({ cmd: step.command, cwd: root, stdout: 'pipe', stderr: 'pipe' }) const stdout = proc.stdout ? new TextDecoder().decode(proc.stdout).trim() : '' const stderr = proc.stderr ? new TextDecoder().decode(proc.stderr).trim() : '' const status = proc.exitCode === 0 ? 'pass' : 'blocked' results.push({ Name: step.name, Command: step.command.join(' '), Status: status, ExitCode: proc.exitCode, RequiredForPacket: step.requiredForPacket ? 'yes' : 'no', StartedAt: startedAt, FinishedAt: new Date().toISOString(), Stdout: stdout, Stderr: stderr }) console.log(`${step.name}: ${status} (${proc.exitCode})`) } const packetReady = results.filter(row => row.RequiredForPacket === 'yes').every(row => row.ExitCode === 0) const manifest = { generatedAt, ready: packetReady, note: 'This proves the staged source-acquisition packet can be regenerated. Run delivery:index after this control run to refresh the overall handoff packet index. It does not mean provider spend or final handoff is allowed.', counts: { steps: results.length, passing: results.filter(row => row.ExitCode === 0).length, blocked: results.filter(row => row.ExitCode !== 0).length, required: results.filter(row => row.RequiredForPacket === 'yes').length, requiredPassing: results.filter(row => row.RequiredForPacket === 'yes' && row.ExitCode === 0).length }, steps: results, blockedSteps: results.filter(row => row.ExitCode !== 0).map(row => row.Name) } writeFileSync(join(outRoot, 'source_acquisition_control_run.json'), JSON.stringify(manifest, null, 2) + '\n', 'utf8') writeFileSync(join(outRoot, 'source_acquisition_control_run.csv'), csv(results.map(row => ({ Name: row.Name, Command: row.Command, Status: row.Status, ExitCode: row.ExitCode, RequiredForPacket: row.RequiredForPacket, Stdout: row.Stdout.split('\n').slice(0, 4).join(' | '), Stderr: row.Stderr.split('\n').slice(0, 4).join(' | ') })), ['Name', 'Command', 'Status', 'ExitCode', 'RequiredForPacket', 'Stdout', 'Stderr']), 'utf8') writeFileSync(join(outRoot, 'source_acquisition_control_run.md'), [ '# Source acquisition control run', '', `Generated: ${generatedAt}`, '', `Packet regenerated: ${packetReady ? 'YES' : 'NO'}`, '', manifest.note, '', `Steps passing: ${manifest.counts.passing}/${manifest.counts.steps}`, `Required packet steps passing: ${manifest.counts.requiredPassing}/${manifest.counts.required}`, '', '## Steps', ...results.map(row => `- ${row.Status === 'pass' ? '[pass]' : '[blocked]'} ${row.Name}: \`${row.Command}\` exit=${row.ExitCode}`), '' ].join('\n'), 'utf8') console.log(`Source acquisition control ready: ${manifest.ready}`) console.log(`Steps passing: ${manifest.counts.passing}/${manifest.counts.steps}`)