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

@@ -3,18 +3,20 @@ import assert from "node:assert/strict";
import os from "node:os";
import path from "node:path";
import { mkdtemp, rm } from "node:fs/promises";
import type { BossState, Project, ThreadProgressEvent, ThreadStatusDocument } from "../src/lib/boss-data.ts";
import type { BossState, MasterAgentTask, Project, ThreadProgressEvent, ThreadStatusDocument } from "../src/lib/boss-data.ts";
let runtimeRoot = "";
let readState: (typeof import("../src/lib/boss-data"))["readState"];
let writeState: (typeof import("../src/lib/boss-data"))["writeState"];
let appendProjectMessage: (typeof import("../src/lib/boss-data"))["appendProjectMessage"];
let updateProjectAgentControls: (typeof import("../src/lib/boss-data"))["updateProjectAgentControls"];
type MutableBossState = BossState & {
threadStatusDocuments: ThreadStatusDocument[];
threadProgressEvents: ThreadProgressEvent[];
projects: Project[];
};
threadStatusDocuments: ThreadStatusDocument[];
threadProgressEvents: ThreadProgressEvent[];
masterAgentTasks: MasterAgentTask[];
projects: Project[];
};
async function setup() {
if (runtimeRoot) return;
@@ -27,6 +29,7 @@ async function setup() {
readState = data.readState;
writeState = data.writeState;
appendProjectMessage = data.appendProjectMessage;
updateProjectAgentControls = data.updateProjectAgentControls;
}
test.after(async () => {
@@ -208,3 +211,149 @@ test("thread replies append lightweight progress events and skip redundant under
false,
);
});
test("turning off single-thread takeover clears pending project understanding sync tasks for that thread", async () => {
await setup();
const projectId = "thread-sync-takeover-clear";
const state = (await readState()) as MutableBossState;
state.projects = state.projects.filter((project) => project.id !== projectId);
state.userProjectAgentControls = state.userProjectAgentControls.filter(
(item) => item.projectId !== projectId,
);
state.masterAgentTasks = state.masterAgentTasks.filter(
(task) => task.projectUnderstandingTargetProjectId !== projectId,
);
state.projects.push({
id: projectId,
name: "接管关闭清理演示",
pinned: false,
deviceIds: ["mac-studio"],
preview: "等待同步",
updatedAt: "2026-04-04T18:00:00+08:00",
lastMessageAt: "2026-04-04T18:00:00+08:00",
isGroup: false,
threadMeta: {
projectId,
threadId: "thread-sync-takeover-clear-thread",
threadDisplayName: "接管关闭清理演示",
folderName: "演示文件夹",
activityIconCount: 1,
updatedAt: "2026-04-04T18:00:00+08:00",
codexThreadRef: "thread-sync-takeover-clear-thread",
codexFolderRef: "thread-sync-takeover-clear-folder",
},
groupMembers: [],
createdByAgent: false,
collaborationMode: "development",
approvalState: "not_required",
unreadCount: 0,
riskLevel: "low",
messages: [],
goals: [],
versions: [],
} as Project);
state.userProjectAgentControls.push({
account: "krisolo",
projectId,
controls: {
takeoverEnabled: true,
updatedAt: "2026-04-04T18:00:00+08:00",
},
});
state.masterAgentTasks.unshift(
{
taskId: "queued-understanding-clear",
projectId: "master-agent",
taskType: "conversation_reply",
requestMessageId: "message-understanding-clear",
requestText: "请同步项目状态",
executionPrompt: "你正在向主 Agent 同步当前项目状态。",
requestedBy: "krisolo",
requestedByAccount: "krisolo",
deviceId: "mac-studio",
targetProjectId: projectId,
targetThreadId: "thread-sync-takeover-clear-thread",
targetThreadDisplayName: "接管关闭清理演示",
projectUnderstandingTargetProjectId: projectId,
projectUnderstandingReason: "heartbeat_activity",
status: "queued",
requestedAt: "2026-04-04T18:01:00+08:00",
},
{
taskId: "completed-understanding-kept",
projectId: "master-agent",
taskType: "conversation_reply",
requestMessageId: "message-understanding-completed",
requestText: "请同步项目状态",
executionPrompt: "你正在向主 Agent 同步当前项目状态。",
requestedBy: "krisolo",
requestedByAccount: "krisolo",
deviceId: "mac-studio",
targetProjectId: projectId,
targetThreadId: "thread-sync-takeover-clear-thread",
targetThreadDisplayName: "接管关闭清理演示",
projectUnderstandingTargetProjectId: projectId,
projectUnderstandingReason: "heartbeat_activity",
status: "completed",
requestedAt: "2026-04-04T18:00:30+08:00",
completedAt: "2026-04-04T18:00:45+08:00",
replyBody: "{}",
},
);
await writeState(state);
const controls = await updateProjectAgentControls(projectId, { takeoverEnabled: false }, "krisolo");
assert.equal(controls?.effectiveTakeoverEnabled, false);
const after = (await readState()) as MutableBossState;
assert.equal(
after.masterAgentTasks.some((task) => task.taskId === "queued-understanding-clear"),
false,
);
assert.equal(
after.masterAgentTasks.some((task) => task.taskId === "completed-understanding-kept"),
true,
);
});
test("turning off global takeover clears pending project understanding sync tasks", async () => {
await setup();
const projectId = "thread-sync-global-clear";
const state = (await readState()) as MutableBossState;
state.masterAgentTasks = state.masterAgentTasks.filter(
(task) => task.projectUnderstandingTargetProjectId !== projectId,
);
state.masterAgentTasks.unshift({
taskId: "running-global-understanding-clear",
projectId: "master-agent",
taskType: "conversation_reply",
requestMessageId: "message-global-understanding-clear",
requestText: "请同步项目状态",
executionPrompt: "你正在向主 Agent 同步当前项目状态。",
requestedBy: "krisolo",
requestedByAccount: "krisolo",
deviceId: "mac-studio",
targetProjectId: projectId,
targetThreadId: "thread-sync-global-clear-thread",
targetThreadDisplayName: "全局接管清理演示",
projectUnderstandingTargetProjectId: projectId,
projectUnderstandingReason: "heartbeat_activity",
status: "running",
requestedAt: "2026-04-04T18:02:00+08:00",
claimedAt: "2026-04-04T18:02:05+08:00",
});
await writeState(state);
await updateProjectAgentControls("master-agent", { globalTakeoverEnabled: true }, "krisolo");
const controls = await updateProjectAgentControls("master-agent", { globalTakeoverEnabled: false }, "krisolo");
assert.equal(controls?.globalTakeoverEnabled, false);
const after = (await readState()) as MutableBossState;
assert.equal(
after.masterAgentTasks.some((task) => task.taskId === "running-global-understanding-clear"),
false,
);
});