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"; import { NextRequest } from "next/server"; let runtimeRoot = ""; let data: typeof import("../src/lib/boss-data.ts"); let postProgress: (typeof import("../src/app/api/v1/master-agent/tasks/[taskId]/progress/route.ts"))["POST"]; async function setup() { if (runtimeRoot) return; runtimeRoot = await mkdtemp(path.join(os.tmpdir(), "boss-master-task-progress-route-")); process.env.BOSS_RUNTIME_ROOT = runtimeRoot; process.env.BOSS_STATE_FILE = path.join(runtimeRoot, "boss-state.json"); const [dataModule, routeModule] = await Promise.all([ import("../src/lib/boss-data.ts"), import("../src/app/api/v1/master-agent/tasks/[taskId]/progress/route.ts"), ]); data = dataModule; postProgress = routeModule.POST; } test.beforeEach(async () => { await setup(); await rm(runtimeRoot, { recursive: true, force: true }); }); test.after(async () => { if (runtimeRoot) await rm(runtimeRoot, { recursive: true, force: true }); }); test("POST task progress accepts device-token updates and keeps task running", async () => { const task = await data.queueMasterAgentTask({ taskId: "route-progress-task", projectId: "group-progress-test", taskType: "dispatch_execution", requestMessageId: "msg-route-progress", requestText: "让目标线程继续开发", executionPrompt: "让目标线程继续开发", requestedBy: "krisolo", requestedByAccount: "krisolo", deviceId: "mac-studio", targetProjectId: "master-agent", targetThreadId: "master-agent-thread", }); await data.claimNextMasterAgentTask("mac-studio"); const response = await postProgress( new NextRequest(`http://127.0.0.1:3000/api/v1/master-agent/tasks/${task.taskId}/progress`, { method: "POST", headers: { "content-type": "application/json", "x-boss-device-token": "boss-mac-studio-token", }, body: JSON.stringify({ deviceId: "mac-studio", status: "running", executionProgress: { steps: [ { text: "连接 Codex App Server", status: "done" }, { text: "启动目标线程 turn", status: "running" }, ], branch: { additions: 12, deletions: 1 }, }, }), }), { params: Promise.resolve({ taskId: task.taskId }) }, ); assert.equal(response.status, 200); const payload = await response.json(); assert.equal(payload.ok, true); assert.equal(payload.task.status, "running"); assert.equal(payload.task.completedAt, undefined); const state = await data.readState(); const progressMessage = state.projects .find((project) => project.id === "master-agent") ?.messages.find((message) => message.executionProgress?.taskId === task.taskId); assert.equal(progressMessage?.executionProgress?.status, "running"); assert.equal(progressMessage?.executionProgress?.steps[0]?.text, "连接 Codex App Server"); assert.equal(progressMessage?.executionProgress?.branch?.additions, 12); });