feat: ship enterprise control and desktop governance

This commit is contained in:
AI Bot
2026-05-11 14:59:26 +08:00
parent 0757d07521
commit a311280238
285 changed files with 48574 additions and 2428 deletions

View File

@@ -103,7 +103,7 @@ function buildDispatchableThreadProject({
async function createAuthedRequest(projectId: string, body: { body: string; kind?: string }) {
const session = await createAuthSession({
account: "17600003315",
account: "krisolo",
role: "highest_admin",
displayName: "Boss 超级管理员",
loginMethod: "password",
@@ -156,7 +156,7 @@ test("POST /api/v1/projects/[projectId]/messages returns a dispatch plan for gro
const groupProject = await createIndependentGroupChat({
memberProjectIds: [memberProjects[0].id, memberProjects[1].id],
createdBy: "17600003315",
createdBy: "krisolo",
});
const response = await POST(await createAuthedRequest(groupProject.id, { body: "请大家汇总今天的阻塞点" }), {
@@ -275,6 +275,57 @@ test("POST /api/v1/projects/master-agent/messages returns a dispatch plan for th
assert.ok(queuedDispatchTask, "expected master-agent thread-op request to enqueue a dispatch recommendation task");
});
test("POST /api/v1/projects/master-agent/messages routes named project summary sync to the target thread understanding task", async () => {
await setup();
const [primaryProject] = await ensureTwoSingleThreadProjects();
assert.ok(primaryProject, "expected seeded single-thread project");
const response = await POST(
await createAuthedRequest("master-agent", {
body: "请同步一下北区试产线回归当前项目目标和版本记录",
}),
{ params: Promise.resolve({ projectId: "master-agent" }) },
);
assert.equal(response.status, 200);
const payload = (await response.json()) as {
ok: boolean;
message: { id: string; body: string };
replyMessage?: { body: string };
task?: { taskId: string; taskType: string; status: string } | null;
dispatchPlan: null | { planId: string };
masterReply?: { ok: boolean; masterReplyState?: string };
};
assert.equal(payload.ok, true);
assert.equal(payload.dispatchPlan, null);
assert.equal(payload.masterReply?.masterReplyState, "queued");
assert.ok(payload.replyMessage?.body.includes("北区试产线回归"));
assert.ok(payload.replyMessage?.body.includes("项目目标"));
assert.ok(payload.replyMessage?.body.includes("版本记录"));
assert.ok(!/OTA|MVP|设备在线|运行时/.test(payload.replyMessage?.body ?? ""));
const nextState = await readState();
const syncTask = nextState.masterAgentTasks.find(
(task) =>
task.projectId === "master-agent" &&
task.projectUnderstandingTargetProjectId === primaryProject.id &&
task.requestText.includes(primaryProject.name),
);
assert.ok(syncTask, "expected target project understanding sync task");
assert.equal(payload.task?.taskId, syncTask?.taskId);
assert.match(syncTask!.executionPrompt, /只输出 JSON/);
assert.match(syncTask!.executionPrompt, /不要把全局 OTA 可用状态/);
const genericDispatchTask = nextState.masterAgentTasks.find(
(task) =>
task.projectId === "master-agent" &&
task.requestMessageId === payload.message.id &&
task.taskType === "group_dispatch_plan",
);
assert.equal(genericDispatchTask, undefined, "summary sync should not create a generic dispatch plan");
});
test("POST /api/v1/projects/[projectId]/messages marks approval_required groups as pending user approval", async () => {
await setup();
const memberProjects = await ensureTwoSingleThreadProjects();
@@ -282,7 +333,7 @@ test("POST /api/v1/projects/[projectId]/messages marks approval_required groups
const groupProject = await createIndependentGroupChat({
memberProjectIds: [memberProjects[0].id, memberProjects[1].id],
createdBy: "17600003315",
createdBy: "krisolo",
});
const state = await readState();
@@ -343,7 +394,7 @@ test("POST /api/v1/projects/[projectId]/messages blocks new approval_required re
const groupProject = await createIndependentGroupChat({
memberProjectIds: [memberProjects[0].id, memberProjects[1].id],
createdBy: "17600003315",
createdBy: "krisolo",
});
const state = await readState();
@@ -413,7 +464,7 @@ test("POST /api/v1/projects/[projectId]/messages keeps message success when grou
const groupProject = await createIndependentGroupChat({
memberProjectIds: [memberProjects[0].id, memberProjects[1].id],
createdBy: "17600003315",
createdBy: "krisolo",
});
const state = await readState();
@@ -495,7 +546,7 @@ test("POST /api/v1/projects/[projectId]/messages excludes master-agent from grou
const groupProject = await createIndependentGroupChat({
memberProjectIds: [memberProjects[0].id, memberProjects[1].id],
createdBy: "17600003315",
createdBy: "krisolo",
});
const state = await readState();
@@ -552,7 +603,7 @@ test("createIndependentGroupChat rejects non-thread members like master-agent",
() =>
createIndependentGroupChat({
memberProjectIds: ["master-agent", realThread.id],
createdBy: "17600003315",
createdBy: "krisolo",
}),
/GROUP_CHAT_MEMBER_NOT_THREAD/,
);