/** * The generate command's fast lane through the live boot: `--allow-missing-context` * boots a project that has no PRODUCT.md / DESIGN.md (naming what is missing * instead of refusing), and the boot reports `devUrl`, the dev server that is * serving the injected page right now, so the agent never reads terminals. */ import { describe, it, before, after } from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from 'node:fs'; import { join } from 'node:path'; import { tmpdir } from 'node:os'; import { createServer } from 'node:http'; import { execFile } from 'node:child_process'; import { ENGINE_MISSING_MESSAGE, engineEnv, findEngineBinary } from './lib/engine-bin.mjs'; const ENGINE_BIN = findEngineBinary(); // Async on purpose: the stand-in dev server below lives in this process, so // a blocking exec would freeze the event loop while the boot probes it. function run(cwd, args, env = {}) { return new Promise((resolve) => { execFile(ENGINE_BIN, args, { cwd, encoding: 'utf-8', env: engineEnv(ENGINE_BIN, env) }, (err, stdout) => { const text = (stdout || err?.stdout || '').trim(); if (!text) return resolve({ ok: false, error: 'no_output', detail: String(err) }); // `live-server stop` answers in prose ("Stopped live server on port N."). try { resolve(JSON.parse(text)); } catch { resolve({ ok: !err, raw: text }); } }); }); } describe('live boot fast lane', { skip: ENGINE_BIN ? false : ENGINE_MISSING_MESSAGE }, () => { let tmp; let server; let devUrl; before(async () => { tmp = mkdtempSync(join(tmpdir(), 'impeccable-boot-fastlane-')); writeFileSync(join(tmp, 'package.json'), JSON.stringify({ name: 'fastlane', scripts: { dev: 'vite' } })); writeFileSync(join(tmp, 'vite.config.js'), 'export default {}\n'); writeFileSync(join(tmp, 'index.html'), '