import test from 'node:test'; import assert from 'node:assert/strict'; import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; import { setTimeout as delay } from 'node:timers/promises'; import { Script, runInNewContext } from 'node:vm'; import { versionPlan, recordPlanDecision, waitForPlanDecision, readPlanJson } from '../src/team/plan-confirmation.js'; import { TeamOrchestrator } from '../src/team/orchestrate.js'; import { TeamPanelServer } from '../src/team/panel-server.js'; const planData = () => ({ subtasks: [{ id: 'st-1', title: 'Project report', goal: 'Summarize progress', acceptance: ['Include risks and next steps'], expectedFile: 'report.md', expectedArtifact: 'Project report', capabilities: ['writing'] }] }); const save = (dir, name, data) => writeFileSync(join(dir, name), JSON.stringify(data)); function temp(t) { const root = mkdtempSync(join(tmpdir(), 'gateway-plan-test-')); t.after(() => rmSync(root, { recursive: true, force: true })); return root; } async function until(fn) { for (let i = 0; i < 200; i++) { const value = fn(); if (value) return value; await delay(10); } throw new Error('Timed out waiting for fixture'); } function waiting(dir, version = 1) { const plan = versionPlan(planData(), 'A simple goal', version); save(dir, 'plan.json', plan); save(dir, 'live-state.json', { stage: 'await-confirm' }); return plan; } test('actual R7 page compiles and has one implementation per function', () => { const html = readFileSync(new URL('../AI团队协作台-统一面板-R7.html', import.meta.url), 'utf8'); const source = [...html.matchAll(/