chore: checkpoint Boss app v2.5.11

This commit is contained in:
AI Bot
2026-06-08 12:22:50 +08:00
parent bddbe8b5ba
commit 3b51641d99
78 changed files with 5706 additions and 954 deletions

View File

@@ -28,7 +28,7 @@ test.after(async () => {
}
});
test("device heartbeat mirrors recent codex desktop replies into the matching thread conversation once", async () => {
test("device heartbeat records recent codex desktop activity without mirroring reply text", async () => {
await setup();
const seedHeartbeat = {
@@ -70,6 +70,7 @@ test("device heartbeat mirrors recent codex desktop replies into the matching th
projectCandidates: [
{
...seedHeartbeat.projectCandidates[0],
lastActiveAt: "2026-04-20T10:02:10.000Z",
recentAssistantMessages: [
{
messageId: "codex-thread:thread-boss-main:2026-04-20T10:02:10.000Z:reply-1",
@@ -87,13 +88,10 @@ test("device heartbeat mirrors recent codex desktop replies into the matching th
(message) => message.externalMessageId === "codex-thread:thread-boss-main:2026-04-20T10:02:10.000Z:reply-1",
);
assert.ok(mirroredMessage);
assert.equal(mirroredMessage?.sender, "device");
assert.equal(mirroredMessage?.senderLabel, "Boss开发主线程");
assert.equal(mirroredMessage?.body, "桌面 Codex 已经把会话实时同步链路修好了。");
assert.equal(nextProject?.lastMessageAt, "2026-04-20T10:02:10.000Z");
assert.equal(nextProject?.preview, "桌面 Codex 已经把会话实时同步链路修好了。");
assert.equal(nextProject?.unreadCount, 1);
assert.equal(mirroredMessage, undefined);
assert.equal(nextProject?.messages.some((message) => message.externalMessageId), false);
assert.equal(nextProject?.threadMeta.lastObservedCodexActivityAt, "2026-04-20T10:02:10.000Z");
assert.equal(nextProject?.unreadCount, 0);
await upsertDeviceHeartbeat({
...seedHeartbeat,
@@ -116,8 +114,86 @@ test("device heartbeat mirrors recent codex desktop replies into the matching th
const mirroredCopies = nextProject?.messages.filter(
(message) => message.externalMessageId === "codex-thread:thread-boss-main:2026-04-20T10:02:10.000Z:reply-1",
);
assert.equal(mirroredCopies?.length, 1);
assert.equal(nextProject?.unreadCount, 1);
assert.equal(mirroredCopies?.length, 0);
assert.equal(nextProject?.unreadCount, 0);
});
test("device heartbeat records codex activity without appending uncorrelated desktop replies", async () => {
await setup();
const seedHeartbeat = {
deviceId: "device-message-activity-only",
token: "device-message-activity-only-token",
name: "Mac Studio",
avatar: "M",
account: "krisolo",
status: "online" as const,
quota5h: 76,
quota7d: 85,
projects: [],
endpoint: "mac://kris.local",
projectCandidates: [
{
folderName: "juyuwan",
folderRef: "/Users/kris/Documents/juyuwan",
threadId: "thread-juyuwan-activity-only",
threadDisplayName: "juyuwan",
codexFolderRef: "/Users/kris/Documents/juyuwan",
codexThreadRef: "thread-juyuwan-activity-only",
lastActiveAt: "2026-06-07T16:30:00.000Z",
suggestedImport: true,
},
],
};
await upsertDeviceHeartbeat(seedHeartbeat);
await upsertDeviceHeartbeat(seedHeartbeat);
const initialState = await readState();
const importedProject = initialState.projects.find(
(project) => project.threadMeta.codexThreadRef === "thread-juyuwan-activity-only",
);
assert.ok(importedProject, "expected heartbeat auto-import to create the thread conversation");
importedProject!.messages = [];
importedProject!.preview = "";
importedProject!.unreadCount = 0;
await writeState(initialState);
await upsertDeviceHeartbeat({
...seedHeartbeat,
projectCandidates: [
{
...seedHeartbeat.projectCandidates[0],
lastActiveAt: "2026-06-07T16:34:15.000Z",
recentAssistantMessages: [
{
messageId: "codex-thread:thread-juyuwan-activity-only:2026-06-07T16:34:15.000Z:final-1",
body: "已完成下一步并实机验证了。APK 已安装到 K30 Ultra。",
sentAt: "2026-06-07T16:34:15.000Z",
phase: "final_answer",
},
],
},
],
});
const nextState = await readState();
const nextProject = nextState.projects.find((project) => project.id === importedProject?.id);
const mirroredMessage = nextProject?.messages.find(
(message) =>
message.externalMessageId ===
"codex-thread:thread-juyuwan-activity-only:2026-06-07T16:34:15.000Z:final-1",
);
const progressEvent = nextState.threadProgressEvents.find(
(event) => event.projectId === importedProject?.id && event.createdAt === "2026-06-07T16:34:15.000Z",
);
assert.equal(mirroredMessage, undefined);
assert.equal(nextProject?.messages.length, 0);
assert.equal(nextProject?.preview, "");
assert.equal(nextProject?.unreadCount, 0);
assert.equal(nextProject?.threadMeta.lastObservedCodexActivityAt, "2026-06-07T16:34:15.000Z");
assert.ok(progressEvent, "expected heartbeat activity to remain visible as a thread progress event");
});
test("device heartbeat does not duplicate a reply already written by task completion", async () => {
@@ -283,7 +359,7 @@ test("device heartbeat does not duplicate a takeover reply already written by ma
assert.equal(nextProject?.preview, replyBody);
});
test("device heartbeat does not count commentary replies as unread and keeps only the final result unread", async () => {
test("device heartbeat ignores commentary and final assistant text as chat messages", async () => {
await setup();
const seedHeartbeat = {
@@ -314,11 +390,22 @@ test("device heartbeat does not count commentary replies as unread and keeps onl
await upsertDeviceHeartbeat(seedHeartbeat);
await upsertDeviceHeartbeat(seedHeartbeat);
const initialState = await readState();
const importedProject = initialState.projects.find(
(project) => project.threadMeta.codexThreadRef === "thread-boss-phase",
);
assert.ok(importedProject);
importedProject!.messages = [];
importedProject!.preview = "";
importedProject!.unreadCount = 0;
await writeState(initialState);
await upsertDeviceHeartbeat({
...seedHeartbeat,
projectCandidates: [
{
...seedHeartbeat.projectCandidates[0],
lastActiveAt: "2026-04-20T10:05:00.000Z",
recentAssistantMessages: [
{
messageId: "codex-thread:thread-boss-phase:2026-04-20T10:03:00.000Z:commentary-1",
@@ -351,10 +438,12 @@ test("device heartbeat does not count commentary replies as unread and keeps onl
);
assert.ok(nextProject);
assert.equal(processMessage?.kind, "thread_process");
assert.equal(finalMessage?.kind, "text");
assert.equal(nextProject?.preview, "这轮已经完成折叠修复,未读现在只会算最终结果。");
assert.equal(nextProject?.unreadCount, 1);
assert.equal(processMessage, undefined);
assert.equal(finalMessage, undefined);
assert.equal(nextProject?.messages.length, 0);
assert.equal(nextProject?.preview, "");
assert.equal(nextProject?.unreadCount, 0);
assert.equal(nextProject?.threadMeta.lastObservedCodexActivityAt, "2026-04-20T10:05:00.000Z");
});
test("device heartbeat does not replay old desktop replies after conversation history is cleared", async () => {
@@ -441,13 +530,14 @@ test("device heartbeat does not replay old desktop replies after conversation hi
(message) =>
message.externalMessageId === "codex-thread:thread-boss-reset:2026-04-20T10:11:00.000Z:new-final",
),
true,
false,
);
assert.equal(nextProject?.preview, "这条新回复应该继续同步回来。");
assert.equal(nextProject?.unreadCount, 1);
assert.equal(nextProject?.preview, "");
assert.equal(nextProject?.unreadCount, 0);
assert.equal(nextProject?.threadMeta.lastObservedCodexActivityAt, "2026-04-20T10:12:00.000Z");
});
test("device heartbeat legacy process text is normalized to thread_process and does not become preview", async () => {
test("device heartbeat process text is kept out of the chat transcript", async () => {
await setup();
const seedHeartbeat = {
@@ -480,6 +570,13 @@ test("device heartbeat legacy process text is normalized to thread_process and d
const resetState = await readState();
resetState.conversationHistoryClearedAt = undefined;
const importedProject = resetState.projects.find(
(project) => project.threadMeta.codexThreadRef === "thread-boss-legacy-process",
);
assert.ok(importedProject);
importedProject!.messages = [];
importedProject!.preview = "";
importedProject!.unreadCount = 0;
await writeState(resetState);
await upsertDeviceHeartbeat({
@@ -487,6 +584,7 @@ test("device heartbeat legacy process text is normalized to thread_process and d
projectCandidates: [
{
...seedHeartbeat.projectCandidates[0],
lastActiveAt: "2026-04-20T10:05:00.000Z",
recentAssistantMessages: [
{
messageId: "codex-thread:thread-boss-legacy-process:2026-04-20T10:03:00.000Z:commentary-legacy",
@@ -516,7 +614,9 @@ test("device heartbeat legacy process text is normalized to thread_process and d
);
assert.ok(nextProject);
assert.equal(legacyProcessMessage?.kind, "thread_process");
assert.equal(nextProject?.preview, "这轮已经完成折叠修复,未读现在只会算最终结果。");
assert.equal(nextProject?.unreadCount, 1);
assert.equal(legacyProcessMessage, undefined);
assert.equal(nextProject?.messages.length, 0);
assert.equal(nextProject?.preview, "");
assert.equal(nextProject?.unreadCount, 0);
assert.equal(nextProject?.threadMeta.lastObservedCodexActivityAt, "2026-04-20T10:05:00.000Z");
});