feat: ship enterprise control and desktop governance
This commit is contained in:
@@ -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,
|
||||
);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user