import test from "node:test"; import assert from "node:assert/strict"; import os from "node:os"; import path from "node:path"; import { mkdtemp, rm } from "node:fs/promises"; let runtimeRoot = ""; let readState: (typeof import("../src/lib/boss-data"))["readState"]; let writeState: (typeof import("../src/lib/boss-data"))["writeState"]; let approveRepairTicket: (typeof import("../src/lib/boss-data"))["approveRepairTicket"]; let verifyRepairTicket: (typeof import("../src/lib/boss-data"))["verifyRepairTicket"]; let subscribeBossEvents: (typeof import("../src/lib/boss-events"))["subscribeBossEvents"]; async function setup() { if (runtimeRoot) return; runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-ops-events-")); process.env.BOSS_RUNTIME_ROOT = runtimeRoot; process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json"); const data = await import("../src/lib/boss-data.ts"); const events = await import("../src/lib/boss-events.ts"); readState = data.readState; writeState = data.writeState; approveRepairTicket = data.approveRepairTicket; verifyRepairTicket = data.verifyRepairTicket; subscribeBossEvents = events.subscribeBossEvents; } async function resetOpsState() { const state = await readState(); state.opsFaults = [ { faultId: "fault-win-camera", faultKey: "WIN_CAMERA_UPLOAD_DELAY", severity: "high", status: "open", nodeId: "mac-studio", serviceName: "boss-local-agent", projectId: "master-agent", threadRef: "thread-ops-1", traceId: "trace-ops-1", runbookId: "runbook-camera-sync", firstSeenAt: "2026-03-25T11:34:00+08:00", lastSeenAt: "2026-03-25T11:58:00+08:00", summary: "摄像头证据上传延迟。", suggestedNextAction: "重试本地 agent 上传。", autoRepairable: true, }, ]; state.opsRepairTickets = [ { ticketId: "ticket-win-camera", faultId: "fault-win-camera", title: "重试摄像头证据上传", approvalStatus: "approved", executionStatus: "running", requestedBy: "运维 Agent", approvedBy: "主 Agent", targetNodeId: "mac-studio", actionSummary: "重新触发本地 agent 心跳和摄像头证据上传。", resultSummary: "等待复验中。", createdAt: "2026-03-25T11:42:00+08:00", updatedAt: "2026-03-25T11:57:00+08:00", }, ]; state.opsRepairVerifications = [ { verificationId: "verify-win-camera", ticketId: "ticket-win-camera", verifier: "运维审计 Agent", status: "watching", summary: "等待关键帧落库后关闭工单。", verifiedAt: "2026-03-25T11:58:00+08:00", }, ]; await writeState(state); } test.beforeEach(async () => { await setup(); await resetOpsState(); }); test.after(async () => { if (runtimeRoot) { await rm(runtimeRoot, { recursive: true, force: true }); } }); test("approve repair ticket publishes project context risk event", async () => { const events: Array<{ event: string; payload: { status?: string; note?: string } }> = []; const unsubscribe = subscribeBossEvents((event, payload) => { events.push({ event, payload }); }); await approveRepairTicket("ticket-win-camera"); unsubscribe(); const latest = events.at(-1); assert.ok(latest); assert.equal(latest.event, "project.context_risk.updated"); assert.equal(latest.payload.status, "approved"); assert.equal(latest.payload.note, "ticket-win-camera"); }); test("verify repair ticket publishes project context risk event", async () => { const events: Array<{ event: string; payload: { status?: string; note?: string } }> = []; const unsubscribe = subscribeBossEvents((event, payload) => { events.push({ event, payload }); }); await verifyRepairTicket("ticket-win-camera"); unsubscribe(); const latest = events.at(-1); assert.ok(latest); assert.equal(latest.event, "project.context_risk.updated"); assert.equal(latest.payload.status, "verified"); assert.equal(latest.payload.note, "ticket-win-camera"); });