#!/usr/bin/env node /* * Durable, single-instance project worker. It executes bounded checkpoints and * persists state. It never sends non-read-only MeshCentral operations. */ const fs = require('node:fs'); const path = require('node:path'); const { spawn } = require('node:child_process'); const root = path.resolve(__dirname, '..'); const statePath = path.join(root, 'PROJECT-PROGRESS.json'); const lockPath = path.join(root, '.worker.lock'); const implementation = path.join(root, 'implementation'); const maxLiveFailures = 3; const intervalMs = 15 * 60 * 1000; let lock; try { lock = fs.openSync(lockPath, 'wx'); fs.writeFileSync(lock, `${process.pid}\n`, 'utf8'); } catch { process.stderr.write('worker already running or lock unavailable\n'); process.exit(2); } function readState() { return JSON.parse(fs.readFileSync(statePath, 'utf8')); } function writeState(state) { state.worker = state.worker || {}; state.worker.pid = process.pid; state.worker.lastActivityAt = new Date().toISOString(); fs.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}\n`, 'utf8'); } function run(command, args) { return new Promise((resolve) => { const child = spawn(command, args, { cwd: implementation, stdio: ['ignore', 'pipe', 'pipe'] }); let output = ''; child.stdout.on('data', (chunk) => { output += chunk.toString(); }); child.stderr.on('data', (chunk) => { output += chunk.toString(); }); child.on('close', (code) => resolve({ code: code ?? 1, output: output.slice(-4000) })); child.on('error', () => resolve({ code: 1, output: '' })); }); } async function checkpoint() { const state = readState(); if (state.status === 'blocked' || state.status === 'completed') return false; state.status = 'working'; state.currentTask = 'Run local verification, then perform the bounded read-only compatibility probe.'; writeState(state); for (const [label, command, args] of [ ['tests', 'npm', ['test', '--', '--runInBand']], ['build', 'npm', ['run', 'build']], ['lint', 'npm', ['run', 'lint']], ]) { const result = await run(command, args); const latest = readState(); latest.lastVerification = latest.lastVerification || {}; latest.lastVerification[label] = result.code === 0 ? 'passed' : 'failed'; latest.lastVerificationAt = new Date().toISOString(); latest.nextAction = result.code === 0 ? 'Run the fixed-scope read-only live probe.' : `Fix local ${label} failure before live testing.`; writeState(latest); if (result.code !== 0) { latest.status = 'blocked'; latest.blocker = `Local ${label} verification failed.`; writeState(latest); return false; } } const latest = readState(); if ((latest.liveTestFailures || 0) >= maxLiveFailures) { latest.status = 'blocked'; latest.blocker = 'Maximum consecutive live-test failures reached; live testing stopped.'; latest.nextAction = 'Review sanitized protocol diagnostics manually; do not retry live testing.'; writeState(latest); return false; } const probe = await run('npm', ['run', 'live-test']); const afterProbe = readState(); if (probe.code === 0) { afterProbe.status = 'completed'; afterProbe.completedMilestones = afterProbe.completedMilestones || []; afterProbe.completedMilestones.push({ task: 'Fixed-scope read-only live compatibility probe passed', completedAt: new Date().toISOString() }); afterProbe.blocker = null; afterProbe.nextAction = 'Document live compatibility result and prepare the read-only MVP.'; } else { afterProbe.liveTestFailures = (afterProbe.liveTestFailures || 0) + 1; afterProbe.status = afterProbe.liveTestFailures >= maxLiveFailures ? 'blocked' : 'working'; afterProbe.blocker = `Read-only live probe failed at the known safe stage; consecutive failures: ${afterProbe.liveTestFailures}.`; afterProbe.nextAction = afterProbe.liveTestFailures >= maxLiveFailures ? 'Live testing stopped at the configured failure limit.' : 'Inspect the sanitized failure stage before any further live retry.'; } writeState(afterProbe); return afterProbe.status === 'working'; } async function main() { process.on('SIGTERM', () => { try { fs.closeSync(lock); fs.unlinkSync(lockPath); } catch {} process.exit(0); }); try { let keepGoing = await checkpoint(); while (keepGoing) { await new Promise((resolve) => setTimeout(resolve, intervalMs)); keepGoing = await checkpoint(); } } finally { try { fs.closeSync(lock); fs.unlinkSync(lockPath); } catch {} } } main().catch((error) => { try { const state = readState(); state.status = 'blocked'; state.blocker = 'Worker orchestration failed before completing its checkpoint.'; state.nextAction = 'Inspect worker error and restart only after confirming no worker is active.'; writeState(state); } catch {} process.stderr.write(`${error instanceof Error ? error.message : 'worker failed'}\n`); process.exit(1); });