@kafca/agentdock 0.1.56 → 0.1.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/dist/renderer/assets/{Badge-DjcoXx2J.js → Badge-CDTbmw1h.js} +1 -1
- package/dist/renderer/assets/Card-DayUo35w.js +1 -0
- package/dist/renderer/assets/Config-ByGMQuzR.js +21 -0
- package/dist/renderer/assets/CronList-XqHdVlgu.js +1 -0
- package/dist/renderer/assets/Dashboard-CZj-oANw.js +41 -0
- package/dist/renderer/assets/{EmptyState-DIZLiccW.js → EmptyState-EFMkOjZO.js} +1 -1
- package/dist/renderer/assets/HighlightedMarkdown-DyvF3DHK.js +12 -0
- package/dist/renderer/assets/Input-DxoWVc9d.js +1 -0
- package/dist/renderer/assets/{KnowledgeDetail-CJ9IYOsa.js → KnowledgeDetail-CbUb2tG7.js} +2 -2
- package/dist/renderer/assets/{KnowledgeHome-BLGPwnBO.js → KnowledgeHome-BWV1gz4f.js} +3 -3
- package/dist/renderer/assets/Logs-DqnanQTc.js +6 -0
- package/dist/renderer/assets/{Modal-CQiUpfl4.js → Modal-yY7TzR0x.js} +3 -3
- package/dist/renderer/assets/MonitorList-CIjGQkFs.js +1 -0
- package/dist/renderer/assets/Page-vwHNUdoj.js +1 -0
- package/dist/renderer/assets/{Select-D6z65IT3.js → Select-CmbK36pN.js} +2 -2
- package/dist/renderer/assets/ThreadChat-4OceMgM4.js +86 -0
- package/dist/renderer/assets/Workspace-DplPJOjJ.js +19 -0
- package/dist/renderer/assets/{arrow-left-CV5cL3f4.js → arrow-left-C8HfBt2K.js} +1 -1
- package/dist/renderer/assets/{book-open-DThvB7pj.js → book-open-BCdZWncQ.js} +1 -1
- package/dist/renderer/assets/channels-hgO3cAIx.js +6 -0
- package/dist/renderer/assets/chevron-down-BPk77tqY.js +11 -0
- package/dist/renderer/assets/index-BIKL3fTP.css +11 -0
- package/dist/renderer/assets/index-BlA4xPdd.js +41 -0
- package/dist/renderer/assets/index-wYpjqVqC.js +167 -0
- package/dist/renderer/assets/knowledge-7pl06KuH.js +1 -0
- package/dist/renderer/assets/{pencil-Dv5WxhdC.js → pencil-CB1SWZ9A.js} +1 -1
- package/dist/renderer/assets/{play-DnCnft83.js → play-BvsoXUrM.js} +1 -1
- package/dist/renderer/assets/{plus-DsxIagzS.js → plus-CokBDnaL.js} +1 -1
- package/dist/renderer/assets/{save-CST01lIc.js → save-D-w4kATO.js} +1 -1
- package/dist/renderer/assets/{search-B_bqy6Wd.js → search-Cnsn6i4Q.js} +1 -1
- package/dist/renderer/assets/{shield-check-D6lG5Aoc.js → shield-check-Cjja2Gh6.js} +1 -1
- package/dist/renderer/assets/threads-BCm6j4eI.js +1 -0
- package/dist/renderer/assets/{trash-2-Cefngb6Q.js → trash-2-CIxz9qYY.js} +1 -1
- package/dist/renderer/index.html +2 -2
- package/dist-electron/packages/contracts/src/automation.js +2 -0
- package/dist-electron/packages/contracts/src/channels.js +2 -0
- package/dist-electron/packages/contracts/src/knowledge.js +2 -0
- package/dist-electron/packages/contracts/src/local-core.js +15 -0
- package/dist-electron/packages/contracts/src/runtime.js +2 -0
- package/dist-electron/packages/contracts/src/scheduler.js +2 -0
- package/dist-electron/packages/contracts/src/threads.js +2 -0
- package/dist-electron/packages/core-sdk/src/automation.js +32 -0
- package/dist-electron/packages/core-sdk/src/channels.js +121 -0
- package/dist-electron/packages/core-sdk/src/client.js +455 -0
- package/dist-electron/packages/core-sdk/src/index.js +43 -607
- package/dist-electron/packages/core-sdk/src/knowledge.js +85 -0
- package/dist-electron/packages/core-sdk/src/request.js +22 -0
- package/dist-electron/packages/core-sdk/src/runtime.js +214 -0
- package/dist-electron/packages/core-sdk/src/scheduler.js +32 -0
- package/dist-electron/packages/core-sdk/src/threads.js +67 -0
- package/dist-electron/packages/plugin-sdk/src/agents.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/automation.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/channels.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/index.js +21 -0
- package/dist-electron/packages/plugin-sdk/src/knowledge.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/runtime.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/scheduler.js +2 -0
- package/dist-electron/packages/plugin-sdk/src/threads.js +2 -0
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +5 -8
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +2 -2
- package/dist-electron/services/local-ai-core/src/acp/local-core-acp-turn-coordinator.js +3 -3
- package/dist-electron/services/local-ai-core/src/acp/store/agent-task-store.js +5 -5
- package/dist-electron/services/local-ai-core/src/acp/store/automation-monitor-store.js +12 -12
- package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +2 -2
- package/dist-electron/services/local-ai-core/src/acp/store/scheduler-store.js +11 -11
- package/dist-electron/services/local-ai-core/src/acp/store/security-store.js +3 -3
- package/dist-electron/services/local-ai-core/src/acp/store/thread-store.js +7 -7
- package/dist-electron/services/local-ai-core/src/acp/workspace-acp-permissions.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/claudecode/definition.js +3 -3
- package/dist-electron/services/local-ai-core/src/agents/codex/definition.js +3 -3
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/definition.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/localcore-acp/index.js +4 -4
- package/dist-electron/services/local-ai-core/src/agents/opencode/launch.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/pi/definition.js +2 -2
- package/dist-electron/services/local-ai-core/src/agents/pi/launch.js +3 -3
- package/dist-electron/services/local-ai-core/src/agents/pi/provider-materializer.js +1 -1
- package/dist-electron/services/local-ai-core/src/agents/shared/agent-plugin.js +4 -4
- package/dist-electron/services/local-ai-core/src/channel/lark/cards.js +33 -18
- package/dist-electron/services/local-ai-core/src/channel/lark/config.js +2 -2
- package/dist-electron/services/local-ai-core/src/channel/lark/gateway-utils.js +91 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/inbound-handler.js +180 -0
- package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +52 -486
- package/dist-electron/services/local-ai-core/src/channel/lark/outbound-transport.js +124 -0
- package/dist-electron/services/local-ai-core/src/channel/shared/inbound-authorization.js +54 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/config.js +2 -2
- package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-media.js +21 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/inbound-poller.js +167 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +50 -469
- package/dist-electron/services/local-ai-core/src/channel/weixin/runtime-state.js +156 -0
- package/dist-electron/services/local-ai-core/src/channel/weixin/text-utils.js +100 -0
- package/dist-electron/services/local-ai-core/src/cli/lac.js +6 -6
- package/dist-electron/services/local-ai-core/src/cli/monitor-cli-parsers.js +2 -2
- package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +28 -70
- package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-ai-vector-plugin.js +2 -2
- package/dist-electron/services/local-ai-core/src/plugins/builtin/knowledge-noop-plugin.js +2 -2
- package/dist-electron/services/local-ai-core/src/router/workspace-bridge-event-stream.js +29 -0
- package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +5 -5
- package/dist-electron/services/local-ai-core/src/router/workspace-router.js +47 -60
- package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +5 -5
- package/dist-electron/services/local-ai-core/src/runtime/config-migration.js +6 -6
- package/dist-electron/services/local-ai-core/src/runtime/deployment-diagnostics.js +3 -3
- package/dist-electron/services/local-ai-core/src/runtime/external-service.js +3 -1
- package/dist-electron/services/local-ai-core/src/runtime/handlers/automation-handler.js +11 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/channel-handler.js +12 -6
- package/dist-electron/services/local-ai-core/src/runtime/handlers/external-handler.js +10 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/knowledge-handler.js +18 -6
- package/dist-electron/services/local-ai-core/src/runtime/handlers/provider-handler.js +7 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +28 -3
- package/dist-electron/services/local-ai-core/src/runtime/handlers/scheduler-handler.js +10 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/security-handler.js +18 -5
- package/dist-electron/services/local-ai-core/src/runtime/handlers/task-handler.js +14 -2
- package/dist-electron/services/local-ai-core/src/runtime/handlers/thread-handler.js +18 -15
- package/dist-electron/services/local-ai-core/src/runtime/handlers/workspace-handler.js +13 -2
- package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +35 -8
- package/dist-electron/services/local-ai-core/src/runtime/request-validation.js +79 -0
- package/dist-electron/services/local-ai-core/src/runtime/runtime-detection-service.js +9 -9
- package/dist-electron/services/local-ai-core/src/runtime/server-helpers.js +10 -1
- package/dist-electron/services/local-ai-core/src/runtime/server.js +2 -1
- package/dist-electron/services/local-ai-core/src/runtime/workspace-project-registry.js +76 -0
- package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +8 -8
- package/dist-electron/services/local-ai-core/src/thread/agent-message-policy.js +75 -0
- package/dist-electron/shared/desktop.js +1 -64
- package/dist-electron/src/components/chat/chat-controller-state.js +60 -0
- package/dist-electron/src/components/chat/chat-event-gate.js +146 -0
- package/dist-electron/src/components/chat/markdown-code-block.js +8 -0
- package/dist-electron/src/pages/Desktop/workspace-model.js +212 -0
- package/dist-electron/src/pages/Threads/thread-chat-model.js +50 -51
- package/dist-electron/tests/contracts/agent-message-policy.test.js +21 -0
- package/dist-electron/tests/contracts/architecture-docs.test.js +56 -33
- package/dist-electron/tests/contracts/chat-event-gate.test.js +114 -0
- package/dist-electron/tests/contracts/chat-markdown.test.js +16 -0
- package/dist-electron/tests/contracts/thread-task-state.test.js +32 -0
- package/dist-electron/tests/contracts/workspace-identity.test.js +23 -0
- package/dist-electron/tests/electron/core-client.test.js +284 -0
- package/dist-electron/tests/electron/plugin-kernel.test.js +54 -0
- package/dist-electron/tests/electron/renderer-packaging.test.js +9 -0
- package/dist-electron/tests/electron/workspace-task-store.test.js +31 -0
- package/dist-electron/tests/integration/channel-inbound-authorization.test.js +80 -0
- package/dist-electron/tests/integration/lark-gateway-utils.test.js +13 -0
- package/dist-electron/tests/integration/lark-gateway.test.js +4 -4
- package/dist-electron/tests/integration/weixin-runtime-state.test.js +32 -0
- package/dist-electron/tests/integration/weixin-text-utils.test.js +15 -0
- package/package.json +9 -4
- package/dist/renderer/assets/Chat-C5Bkm9-M.js +0 -2
- package/dist/renderer/assets/ChatMarkdown-uc36EzyD.js +0 -45
- package/dist/renderer/assets/Config-DHtQuuLy.js +0 -21
- package/dist/renderer/assets/CronList-BYUnhzSC.js +0 -1
- package/dist/renderer/assets/Dashboard-BPnGMDg3.js +0 -26
- package/dist/renderer/assets/Logs-Dyd2Uwlt.js +0 -1
- package/dist/renderer/assets/MonitorList-Byg3E3Gt.js +0 -1
- package/dist/renderer/assets/Page-7DxXvTMm.js +0 -1
- package/dist/renderer/assets/ProjectDetail-Dfr5s0Ja.js +0 -11
- package/dist/renderer/assets/ProjectList-CDDQjAQ_.js +0 -1
- package/dist/renderer/assets/SessionChat-s7CAaCPL.js +0 -1
- package/dist/renderer/assets/SessionList-D-OycKKS.js +0 -1
- package/dist/renderer/assets/ThreadChat-CLdFynB5.js +0 -28
- package/dist/renderer/assets/Workspace-xfT5z4j_.js +0 -19
- package/dist/renderer/assets/bot-CWQ5-ovl.js +0 -6
- package/dist/renderer/assets/check-DKM7zfWG.js +0 -6
- package/dist/renderer/assets/chevron-down-Dfw2KU87.js +0 -6
- package/dist/renderer/assets/circle-CoP4RA4s.js +0 -6
- package/dist/renderer/assets/desktop-CsDYrOOU.js +0 -1
- package/dist/renderer/assets/desktop-JQkhNOF4.js +0 -5
- package/dist/renderer/assets/funnel-DpVLlG3g.js +0 -6
- package/dist/renderer/assets/heart-BMD36ejP.js +0 -6
- package/dist/renderer/assets/index-COxSYBjE.js +0 -182
- package/dist/renderer/assets/index-CTGTI-cm.js +0 -41
- package/dist/renderer/assets/index-CjCuR6DI.css +0 -11
- package/dist/renderer/assets/projects-DgjHcNgt.js +0 -1
- package/dist/renderer/assets/server-ecH4GNwa.js +0 -11
- package/dist/renderer/assets/session-utils-Dd_WKMYW.js +0 -6
- package/dist/renderer/assets/sessions-BQ33Mv4k.js +0 -1
- package/dist/renderer/assets/user-D_8RSH-T.js +0 -6
- package/dist/renderer/assets/wifi-off-DB9D-pOu.js +0 -11
- package/dist-electron/src/api/client.js +0 -73
- package/dist-electron/src/api/sessions.js +0 -21
- package/dist-electron/src/lib/session-utils.js +0 -51
- package/dist-electron/src/pages/Projects/project-provider-config.js +0 -75
- package/dist-electron/tests/electron/project-provider-config.test.js +0 -71
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.upsertSessionGroup = exports.ASSISTANT_REPLY_TIMEOUT_MS = void 0;
|
|
4
|
+
exports.chatControllerActionForTaskState = chatControllerActionForTaskState;
|
|
5
|
+
exports.taskStateFromControllerStatus = taskStateFromControllerStatus;
|
|
4
6
|
exports.isInternalProgressBridgeKind = isInternalProgressBridgeKind;
|
|
5
7
|
exports.isAwaitingInputBridgeStatus = isAwaitingInputBridgeStatus;
|
|
6
8
|
exports.findStreamingPreviewMessage = findStreamingPreviewMessage;
|
|
@@ -9,10 +11,7 @@ exports.shouldAcceptLiveBridgeEvent = shouldAcceptLiveBridgeEvent;
|
|
|
9
11
|
exports.settlePreviewMessages = settlePreviewMessages;
|
|
10
12
|
exports.finalizeTurnMessageKinds = finalizeTurnMessageKinds;
|
|
11
13
|
exports.extractVisibleMessageContent = extractVisibleMessageContent;
|
|
12
|
-
exports.sessionMatchesDesktop = sessionMatchesDesktop;
|
|
13
|
-
exports.toMessages = toMessages;
|
|
14
14
|
exports.toMessagesFromThread = toMessagesFromThread;
|
|
15
|
-
exports.toChatThreadSummary = toChatThreadSummary;
|
|
16
15
|
exports.toCoreChatThreadSummary = toCoreChatThreadSummary;
|
|
17
16
|
exports.sortChatThreadsByLiveAndUpdated = sortChatThreadsByLiveAndUpdated;
|
|
18
17
|
exports.chatThreadMatchesSearch = chatThreadMatchesSearch;
|
|
@@ -28,9 +27,49 @@ exports.formatTaskHint = formatTaskHint;
|
|
|
28
27
|
exports.isTaskRunningState = isTaskRunningState;
|
|
29
28
|
exports.isTaskInputLocked = isTaskInputLocked;
|
|
30
29
|
exports.canStreamingPromoteTaskState = canStreamingPromoteTaskState;
|
|
31
|
-
const
|
|
32
|
-
const
|
|
30
|
+
const chat_event_gate_1 = require("../../components/chat/chat-event-gate");
|
|
31
|
+
const superai_contracts_1 = require("../../../packages/contracts/src/index.js");
|
|
33
32
|
exports.ASSISTANT_REPLY_TIMEOUT_MS = 90000;
|
|
33
|
+
// Threads drives the shared chat controller through these mappers instead of the
|
|
34
|
+
// reducer's `transition` escape hatch so its task state stays inside ChatTaskState
|
|
35
|
+
// and the reducer's named-action guards remain meaningful.
|
|
36
|
+
function chatControllerActionForTaskState(next) {
|
|
37
|
+
switch (next) {
|
|
38
|
+
case 'idle':
|
|
39
|
+
return { type: 'settled' };
|
|
40
|
+
case 'running':
|
|
41
|
+
return { type: 'stream_started' };
|
|
42
|
+
case 'awaiting_input':
|
|
43
|
+
return { type: 'input_requested' };
|
|
44
|
+
case 'awaiting_permission':
|
|
45
|
+
return { type: 'permission_requested' };
|
|
46
|
+
case 'permission_submitted':
|
|
47
|
+
return { type: 'permission_submitted' };
|
|
48
|
+
case 'stopping':
|
|
49
|
+
return { type: 'stop_started' };
|
|
50
|
+
case 'error':
|
|
51
|
+
return { type: 'failed' };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function taskStateFromControllerStatus(status) {
|
|
55
|
+
switch (status) {
|
|
56
|
+
case 'idle':
|
|
57
|
+
case 'running':
|
|
58
|
+
case 'awaiting_input':
|
|
59
|
+
case 'awaiting_permission':
|
|
60
|
+
case 'permission_submitted':
|
|
61
|
+
case 'error':
|
|
62
|
+
case 'stopping':
|
|
63
|
+
return status;
|
|
64
|
+
case 'failed':
|
|
65
|
+
case 'timed_out':
|
|
66
|
+
return 'error';
|
|
67
|
+
default:
|
|
68
|
+
// sending/waiting/polling/activating are Session/Web-only statuses the
|
|
69
|
+
// Threads surface never holds; map them defensively to 'running'.
|
|
70
|
+
return 'running';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
34
73
|
function isInternalProgressBridgeKind(bridgeKind) {
|
|
35
74
|
return bridgeKind === 'thought' ||
|
|
36
75
|
bridgeKind === 'plan' ||
|
|
@@ -64,23 +103,10 @@ function shouldReplacePreviewWithReply(message, replyContent, replyCtx, replyBri
|
|
|
64
103
|
message.bridgeKind === 'assistant'));
|
|
65
104
|
}
|
|
66
105
|
function shouldAcceptLiveBridgeEvent(input) {
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
const activeRunId = String(input.activeRunId || '').trim();
|
|
72
|
-
const pendingTurn = input.pendingTurn;
|
|
73
|
-
if (pendingTurn && pendingTurn.sessionKey === input.event.sessionKey) {
|
|
74
|
-
const pendingRunId = String(pendingTurn.runId || '').trim();
|
|
75
|
-
if (pendingRunId) {
|
|
76
|
-
return replyCtx === pendingRunId;
|
|
77
|
-
}
|
|
78
|
-
const supersededRunId = String(pendingTurn.supersededRunId || '').trim();
|
|
79
|
-
if (supersededRunId && replyCtx === supersededRunId) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return !activeRunId || replyCtx === activeRunId;
|
|
106
|
+
return (0, chat_event_gate_1.shouldAcceptRunScopedEvent)(input.event, {
|
|
107
|
+
activeRunId: input.activeRunId,
|
|
108
|
+
pendingTurn: input.pendingTurn,
|
|
109
|
+
});
|
|
84
110
|
}
|
|
85
111
|
function settlePreviewMessages(messages, turnKey) {
|
|
86
112
|
let changed = false;
|
|
@@ -130,19 +156,6 @@ function extractVisibleMessageContent(content) {
|
|
|
130
156
|
}
|
|
131
157
|
return match[1] || '';
|
|
132
158
|
}
|
|
133
|
-
function sessionMatchesDesktop(session) {
|
|
134
|
-
return session.platform === 'desktop' || session.session_key.startsWith('desktop:');
|
|
135
|
-
}
|
|
136
|
-
function toMessages(history) {
|
|
137
|
-
return history.map((message, index) => ({
|
|
138
|
-
id: `${index}-${message.timestamp || message.role}`,
|
|
139
|
-
role: message.role === 'user' ? 'user' : message.role === 'system' ? 'system' : 'assistant',
|
|
140
|
-
content: message.role === 'user' ? extractVisibleMessageContent(message.content) : message.content,
|
|
141
|
-
kind: message.kind === 'progress' ? 'progress' : 'final',
|
|
142
|
-
order: index,
|
|
143
|
-
timestamp: message.timestamp,
|
|
144
|
-
}));
|
|
145
|
-
}
|
|
146
159
|
function toMessagesFromThread(history) {
|
|
147
160
|
return history.map((message, index) => ({
|
|
148
161
|
id: message.id || `${index}-${message.timestamp || message.role}`,
|
|
@@ -160,20 +173,6 @@ function toMessagesFromThread(history) {
|
|
|
160
173
|
timestamp: message.timestamp,
|
|
161
174
|
}));
|
|
162
175
|
}
|
|
163
|
-
function toChatThreadSummary(project, session) {
|
|
164
|
-
return {
|
|
165
|
-
id: session.id,
|
|
166
|
-
project,
|
|
167
|
-
name: (0, session_utils_1.sessionLabel)(session),
|
|
168
|
-
live: session.live,
|
|
169
|
-
createdAt: session.created_at,
|
|
170
|
-
updatedAt: session.updated_at,
|
|
171
|
-
excerpt: extractVisibleMessageContent(session.last_message?.content || ''),
|
|
172
|
-
agentType: session.agent_type,
|
|
173
|
-
agentMode: undefined,
|
|
174
|
-
bridgeSessionKey: session.session_key,
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
176
|
function toCoreChatThreadSummary(thread) {
|
|
178
177
|
return {
|
|
179
178
|
id: thread.id,
|
|
@@ -261,7 +260,7 @@ function normalizeBridgeActionRows(input) {
|
|
|
261
260
|
return [];
|
|
262
261
|
}
|
|
263
262
|
return row
|
|
264
|
-
.map((button) => (0,
|
|
263
|
+
.map((button) => (0, superai_contracts_1.normalizeDesktopBridgeButtonOption)(button))
|
|
265
264
|
.filter((button) => Boolean(button));
|
|
266
265
|
})
|
|
267
266
|
.filter((row) => row.length > 0);
|
|
@@ -281,7 +280,7 @@ function upsertThreadInGroup(groups, project, thread) {
|
|
|
281
280
|
return upsertThreadGroup(groups, project, nextSessions);
|
|
282
281
|
}
|
|
283
282
|
function isPermissionActionRow(rows) {
|
|
284
|
-
return rows.some((row) => row.some((action) => (0,
|
|
283
|
+
return rows.some((row) => row.some((action) => (0, superai_contracts_1.isPermissionButtonOption)(action)));
|
|
285
284
|
}
|
|
286
285
|
function formatTaskHint(taskState, typing) {
|
|
287
286
|
if (taskState === 'stopping') {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const agent_message_policy_js_1 = require("../../services/local-ai-core/src/thread/agent-message-policy.js");
|
|
9
|
+
(0, node_test_1.default)('agent message policy is owned by Local Core and includes selected knowledge context', () => {
|
|
10
|
+
const message = (0, agent_message_policy_js_1.composeAgentMessage)('Summarize the design', [
|
|
11
|
+
{ id: 'kb-1', name: 'Architecture notes' },
|
|
12
|
+
]);
|
|
13
|
+
strict_1.default.match(message, /\[Scheduler Tools\]/);
|
|
14
|
+
strict_1.default.match(message, /\[Monitor Tools\]/);
|
|
15
|
+
strict_1.default.match(message, /\[Channel Tools\]/);
|
|
16
|
+
strict_1.default.match(message, /id: kb-1 \| name: Architecture notes/);
|
|
17
|
+
strict_1.default.match(message, /\[User Message\]\nSummarize the design\n\[\/User Message\]/);
|
|
18
|
+
});
|
|
19
|
+
(0, node_test_1.default)('agent message policy leaves slash commands untouched', () => {
|
|
20
|
+
strict_1.default.equal((0, agent_message_policy_js_1.composeAgentMessage)('/agent use pi'), '/agent use pi');
|
|
21
|
+
});
|
|
@@ -39,33 +39,6 @@ function readSourceFiles(scope) {
|
|
|
39
39
|
content: (0, node_fs_1.readFileSync)(path, 'utf8'),
|
|
40
40
|
}));
|
|
41
41
|
}
|
|
42
|
-
const rendererPackageSourceImportAllowlist = new Set([
|
|
43
|
-
'src/api/cron.ts',
|
|
44
|
-
'src/api/desktop.ts',
|
|
45
|
-
'src/api/knowledge.ts',
|
|
46
|
-
'src/api/monitors.ts',
|
|
47
|
-
'src/api/runtime-bootstrap.ts',
|
|
48
|
-
'src/app/runtime.ts',
|
|
49
|
-
'src/pages/Automation/MonitorList.tsx',
|
|
50
|
-
'src/pages/Cron/CronList.tsx',
|
|
51
|
-
'src/pages/Dashboard.tsx',
|
|
52
|
-
'src/pages/Knowledge/KnowledgeDetail.tsx',
|
|
53
|
-
'src/pages/Knowledge/KnowledgeHome.tsx',
|
|
54
|
-
'src/pages/System/Config.tsx',
|
|
55
|
-
'src/pages/Threads/thread-chat-action-types.ts',
|
|
56
|
-
'src/pages/Threads/thread-chat-model.ts',
|
|
57
|
-
'src/pages/Threads/thread-chat-page-state.ts',
|
|
58
|
-
'src/pages/Threads/thread-chat-permission.test.ts',
|
|
59
|
-
'src/pages/Threads/thread-chat-permission.ts',
|
|
60
|
-
'src/pages/Threads/useThreadChatActions.ts',
|
|
61
|
-
'src/pages/Threads/useThreadChatController.ts',
|
|
62
|
-
'src/pages/Threads/useThreadChatConversationState.ts',
|
|
63
|
-
'src/pages/Threads/useThreadChatSendingActions.ts',
|
|
64
|
-
'src/pages/Threads/useThreadChatSessionBrowser.ts',
|
|
65
|
-
'src/pages/Threads/ThreadChatComposer.tsx',
|
|
66
|
-
'src/pages/Threads/useThreadChatThreadActions.ts',
|
|
67
|
-
'src/types/window.d.ts',
|
|
68
|
-
]);
|
|
69
42
|
(0, node_test_1.default)('state ownership docs identify Local AI Core owners for durable chat and channel state', () => {
|
|
70
43
|
const content = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'docs', 'architecture', 'state-ownership.md'), 'utf8');
|
|
71
44
|
for (const state of [
|
|
@@ -111,12 +84,13 @@ const rendererPackageSourceImportAllowlist = new Set([
|
|
|
111
84
|
strict_1.default.match(permissionSource, /export type PendingPermissionRequest = ThreadPendingPermissionRequest;/, 'renderer pending permission state must alias the shared thread permission contract');
|
|
112
85
|
strict_1.default.doesNotMatch(permissionSource, /type PermissionTaskState\s*=/, 'permission helpers must not carry a second task-state union');
|
|
113
86
|
});
|
|
114
|
-
(0, node_test_1.default)('
|
|
115
|
-
const offenders =
|
|
116
|
-
.
|
|
117
|
-
.
|
|
118
|
-
.filter((
|
|
119
|
-
|
|
87
|
+
(0, node_test_1.default)('production code imports workspace packages through public package names', () => {
|
|
88
|
+
const offenders = ['src', 'services', 'packages']
|
|
89
|
+
.flatMap(readSourceFiles)
|
|
90
|
+
.filter(({ relativePath }) => !relativePath.startsWith('packages/contracts/src/'))
|
|
91
|
+
.filter(({ content }) => /(?:packages\/(?:contracts|core-sdk|plugin-sdk|knowledge-api)|(?:contracts|core-sdk|plugin-sdk))\/src/.test(content))
|
|
92
|
+
.map(({ relativePath }) => relativePath);
|
|
93
|
+
strict_1.default.deepEqual(offenders, [], 'production code must import workspace dependencies through @cc/* public entrypoints');
|
|
120
94
|
});
|
|
121
95
|
(0, node_test_1.default)('renderer does not import Electron or Local AI Core internals', () => {
|
|
122
96
|
const offenders = readSourceFiles('src')
|
|
@@ -137,4 +111,53 @@ const rendererPackageSourceImportAllowlist = new Set([
|
|
|
137
111
|
const packageJson = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, packagePath), 'utf8'));
|
|
138
112
|
strict_1.default.equal(packageJson.exports?.['.'], './src/index.ts', `${packagePath} must expose its public source entrypoint for workspace consumers`);
|
|
139
113
|
}
|
|
114
|
+
const contracts = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'packages/contracts/package.json'), 'utf8'));
|
|
115
|
+
const domains = ['runtime', 'threads', 'channels', 'scheduler', 'automation', 'knowledge'];
|
|
116
|
+
for (const domain of domains) {
|
|
117
|
+
strict_1.default.ok(contracts.exports?.[`./${domain}`], `contracts must expose the ${domain} domain entrypoint`);
|
|
118
|
+
}
|
|
119
|
+
for (const packageName of ['contracts', 'core-sdk', 'plugin-sdk']) {
|
|
120
|
+
const packageJson = JSON.parse((0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, `packages/${packageName}/package.json`), 'utf8'));
|
|
121
|
+
for (const domain of domains) {
|
|
122
|
+
strict_1.default.equal(packageJson.exports?.[`./${domain}`], `./src/${domain}.ts`, `${packageName} must expose the ${domain} domain through its dedicated entrypoint`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
(0, node_test_1.default)('core sdk domain entrypoints do not re-export the top-level sdk', () => {
|
|
127
|
+
for (const domain of ['runtime', 'threads', 'channels', 'scheduler', 'automation', 'knowledge']) {
|
|
128
|
+
const source = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, `packages/core-sdk/src/${domain}.ts`), 'utf8');
|
|
129
|
+
strict_1.default.doesNotMatch(source, /(?:from|import\s*\()\s*['"]\.\/index\.js['"]/, `core-sdk/${domain} must own its implementation without depending on the aggregate entrypoint`);
|
|
130
|
+
strict_1.default.match(source, /coreRequest|coreClient/, `core-sdk/${domain} must own executable domain behavior`);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
(0, node_test_1.default)('package domain modules do not depend on aggregate entrypoints', () => {
|
|
134
|
+
for (const packageName of ['contracts', 'core-sdk', 'plugin-sdk']) {
|
|
135
|
+
for (const domain of ['runtime', 'threads', 'channels', 'scheduler', 'automation', 'knowledge']) {
|
|
136
|
+
const source = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, `packages/${packageName}/src/${domain}.ts`), 'utf8');
|
|
137
|
+
strict_1.default.doesNotMatch(source, /(?:from|import\s*\()\s*['"]\.\/index(?:\.js)?['"]/, `${packageName}/${domain} must not reach back through its aggregate entrypoint`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
(0, node_test_1.default)('desktop contracts are consumed through the contracts package outside their owner', () => {
|
|
142
|
+
const offenders = ['src', 'services', 'packages']
|
|
143
|
+
.flatMap(readSourceFiles)
|
|
144
|
+
.filter(({ relativePath }) => !relativePath.startsWith('packages/contracts/src/'))
|
|
145
|
+
.filter(({ content }) => /shared\/desktop/.test(content))
|
|
146
|
+
.map(({ relativePath }) => relativePath);
|
|
147
|
+
strict_1.default.deepEqual(offenders, [], 'business code must consume shared desktop contracts through @cc/superai-contracts');
|
|
148
|
+
});
|
|
149
|
+
(0, node_test_1.default)('renderer does not branch features through the retired runtime provider string', () => {
|
|
150
|
+
const offenders = readSourceFiles('src')
|
|
151
|
+
.filter(({ content }) => /RuntimeProvider|getRuntimeProvider|runtimeProvider\s*(?:===|!==)/.test(content))
|
|
152
|
+
.map(({ relativePath }) => relativePath);
|
|
153
|
+
strict_1.default.deepEqual(offenders, [], 'renderer features must use capabilities or the Local Core contract directly');
|
|
154
|
+
});
|
|
155
|
+
(0, node_test_1.default)('chat syntax highlighting stays behind a lazy code-block boundary', () => {
|
|
156
|
+
const markdown = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'src/components/chat/ChatMarkdown.tsx'), 'utf8');
|
|
157
|
+
const highlighted = (0, node_fs_1.readFileSync)((0, node_path_1.join)(rootDir, 'src/components/chat/HighlightedMarkdown.tsx'), 'utf8');
|
|
158
|
+
strict_1.default.doesNotMatch(markdown, /from ['"]rehype-highlight['"]/, 'base chat markdown must not eagerly load highlighting');
|
|
159
|
+
strict_1.default.match(markdown, /lazy\(\(\) =>\s*import\('\.\/HighlightedMarkdown'\)/, 'highlighting must use a lazy chunk');
|
|
160
|
+
for (const language of ['typescript', 'javascript', 'json', 'bash', 'python', 'xml', 'css', 'sql', 'yaml']) {
|
|
161
|
+
strict_1.default.match(highlighted, new RegExp(`highlight\\.js/lib/languages/${language}`), `${language} must remain in the supported subset`);
|
|
162
|
+
}
|
|
140
163
|
});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
8
|
+
const chat_event_gate_js_1 = require("../../src/components/chat/chat-event-gate.js");
|
|
9
|
+
(0, node_test_1.default)('chat event gate rejects duplicate bridge events', () => {
|
|
10
|
+
const gate = (0, chat_event_gate_js_1.createChatEventGate)();
|
|
11
|
+
const event = {
|
|
12
|
+
type: 'update_message',
|
|
13
|
+
sessionKey: 'workspace:thread-1',
|
|
14
|
+
replyCtx: 'run-1',
|
|
15
|
+
previewHandle: 'preview-1',
|
|
16
|
+
content: 'working',
|
|
17
|
+
};
|
|
18
|
+
strict_1.default.equal(gate.acceptBridgeEvent(event, { activeRunId: 'run-1' }), true);
|
|
19
|
+
strict_1.default.equal(gate.acceptBridgeEvent(event, { activeRunId: 'run-1' }), false);
|
|
20
|
+
});
|
|
21
|
+
(0, node_test_1.default)('chat event gate rejects late streaming updates after a turn settles', () => {
|
|
22
|
+
const gate = (0, chat_event_gate_js_1.createChatEventGate)();
|
|
23
|
+
const context = { activeRunId: 'run-1' };
|
|
24
|
+
strict_1.default.equal(gate.acceptBridgeEvent({
|
|
25
|
+
type: 'typing_stop',
|
|
26
|
+
sessionKey: 'workspace:thread-1',
|
|
27
|
+
replyCtx: 'run-1',
|
|
28
|
+
}, context), true);
|
|
29
|
+
strict_1.default.equal(gate.acceptBridgeEvent({
|
|
30
|
+
type: 'update_message',
|
|
31
|
+
sessionKey: 'workspace:thread-1',
|
|
32
|
+
replyCtx: 'run-1',
|
|
33
|
+
content: 'late preview',
|
|
34
|
+
}, context), false);
|
|
35
|
+
});
|
|
36
|
+
(0, node_test_1.default)('chat event gate rejects events from a superseded run', () => {
|
|
37
|
+
const gate = (0, chat_event_gate_js_1.createChatEventGate)();
|
|
38
|
+
strict_1.default.equal(gate.acceptBridgeEvent({
|
|
39
|
+
type: 'reply',
|
|
40
|
+
sessionKey: 'workspace:thread-1',
|
|
41
|
+
replyCtx: 'run-old',
|
|
42
|
+
content: 'late answer',
|
|
43
|
+
}, {
|
|
44
|
+
activeRunId: 'run-old',
|
|
45
|
+
pendingTurn: {
|
|
46
|
+
sessionKey: 'workspace:thread-1',
|
|
47
|
+
supersededRunId: 'run-old',
|
|
48
|
+
},
|
|
49
|
+
}), false);
|
|
50
|
+
});
|
|
51
|
+
(0, node_test_1.default)('chat event gate deduplicates core refresh events while allowing changed payloads', () => {
|
|
52
|
+
const gate = (0, chat_event_gate_js_1.createChatEventGate)();
|
|
53
|
+
const first = {
|
|
54
|
+
type: 'message.updated',
|
|
55
|
+
threadId: 'thread-1',
|
|
56
|
+
message: { id: 'message-1', content: 'one' },
|
|
57
|
+
};
|
|
58
|
+
const second = {
|
|
59
|
+
...first,
|
|
60
|
+
message: { id: 'message-1', content: 'two' },
|
|
61
|
+
};
|
|
62
|
+
strict_1.default.equal(gate.acceptCoreEvent(first), true);
|
|
63
|
+
strict_1.default.equal(gate.acceptCoreEvent(first), false);
|
|
64
|
+
strict_1.default.equal(gate.acceptCoreEvent(second), true);
|
|
65
|
+
});
|
|
66
|
+
(0, node_test_1.default)('chat event gate rejects late Core stream updates after the run settles', () => {
|
|
67
|
+
const gate = (0, chat_event_gate_js_1.createChatEventGate)();
|
|
68
|
+
const terminal = {
|
|
69
|
+
type: 'stream.updated',
|
|
70
|
+
stream: {
|
|
71
|
+
type: 'typing_stop',
|
|
72
|
+
sessionKey: 'workspace:thread-1',
|
|
73
|
+
replyCtx: 'run-1',
|
|
74
|
+
},
|
|
75
|
+
};
|
|
76
|
+
const lateUpdate = {
|
|
77
|
+
type: 'presence.updated',
|
|
78
|
+
live: true,
|
|
79
|
+
stream: {
|
|
80
|
+
type: 'update_message',
|
|
81
|
+
sessionKey: 'workspace:thread-1',
|
|
82
|
+
replyCtx: 'run-1',
|
|
83
|
+
content: 'late preview',
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
strict_1.default.equal(gate.acceptCoreEvent(terminal), true);
|
|
87
|
+
strict_1.default.equal(gate.acceptCoreEvent(lateUpdate), false);
|
|
88
|
+
strict_1.default.equal(gate.acceptCoreEvent({
|
|
89
|
+
type: 'stream.updated',
|
|
90
|
+
stream: {
|
|
91
|
+
type: 'reply',
|
|
92
|
+
sessionKey: 'workspace:thread-1',
|
|
93
|
+
replyCtx: 'run-1',
|
|
94
|
+
content: 'late final',
|
|
95
|
+
},
|
|
96
|
+
}), false);
|
|
97
|
+
});
|
|
98
|
+
(0, node_test_1.default)('chat event gate rejects late running state after a Core run completes', () => {
|
|
99
|
+
const gate = (0, chat_event_gate_js_1.createChatEventGate)();
|
|
100
|
+
const run = {
|
|
101
|
+
id: 'run-1',
|
|
102
|
+
threadId: 'thread-1',
|
|
103
|
+
startedAt: '',
|
|
104
|
+
updatedAt: '',
|
|
105
|
+
};
|
|
106
|
+
strict_1.default.equal(gate.acceptCoreEvent({
|
|
107
|
+
type: 'run.updated',
|
|
108
|
+
run: { ...run, status: 'completed' },
|
|
109
|
+
}), true);
|
|
110
|
+
strict_1.default.equal(gate.acceptCoreEvent({
|
|
111
|
+
type: 'run.updated',
|
|
112
|
+
run: { ...run, status: 'running' },
|
|
113
|
+
}), false);
|
|
114
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
8
|
+
const markdown_code_block_js_1 = require("../../src/components/chat/markdown-code-block.js");
|
|
9
|
+
(0, node_test_1.default)('markdown code block detection covers fenced and indented code blocks', () => {
|
|
10
|
+
strict_1.default.equal((0, markdown_code_block_js_1.hasMarkdownCodeBlock)('```ts\nconst value = 1;\n```'), true);
|
|
11
|
+
strict_1.default.equal((0, markdown_code_block_js_1.hasMarkdownCodeBlock)('~~~python\nprint("hi")\n~~~'), true);
|
|
12
|
+
strict_1.default.equal((0, markdown_code_block_js_1.hasMarkdownCodeBlock)(' ````ts\nconst value = 1;\n`````'), true);
|
|
13
|
+
strict_1.default.equal((0, markdown_code_block_js_1.hasMarkdownCodeBlock)('```ts\nconst unfinished = true;'), true);
|
|
14
|
+
strict_1.default.equal((0, markdown_code_block_js_1.hasMarkdownCodeBlock)('Paragraph\n\n pnpm test'), true);
|
|
15
|
+
strict_1.default.equal((0, markdown_code_block_js_1.hasMarkdownCodeBlock)('Use `inline code` only'), false);
|
|
16
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
7
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
8
|
+
const thread_chat_model_js_1 = require("../../src/pages/Threads/thread-chat-model.js");
|
|
9
|
+
(0, node_test_1.default)('chatControllerActionForTaskState maps each chat task state to a named controller action', () => {
|
|
10
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('idle'), { type: 'settled' });
|
|
11
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('running'), { type: 'stream_started' });
|
|
12
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('awaiting_input'), { type: 'input_requested' });
|
|
13
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('awaiting_permission'), { type: 'permission_requested' });
|
|
14
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('permission_submitted'), { type: 'permission_submitted' });
|
|
15
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('stopping'), { type: 'stop_started' });
|
|
16
|
+
strict_1.default.deepEqual((0, thread_chat_model_js_1.chatControllerActionForTaskState)('error'), { type: 'failed' });
|
|
17
|
+
});
|
|
18
|
+
(0, node_test_1.default)('taskStateFromControllerStatus narrows the controller status without a cast', () => {
|
|
19
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('idle'), 'idle');
|
|
20
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('running'), 'running');
|
|
21
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('awaiting_input'), 'awaiting_input');
|
|
22
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('error'), 'error');
|
|
23
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('stopping'), 'stopping');
|
|
24
|
+
// Terminal controller statuses Threads never dispatches map back to 'error'.
|
|
25
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('failed'), 'error');
|
|
26
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('timed_out'), 'error');
|
|
27
|
+
// Session/Web-only statuses map defensively to 'running'.
|
|
28
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('sending'), 'running');
|
|
29
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('waiting'), 'running');
|
|
30
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('polling'), 'running');
|
|
31
|
+
strict_1.default.equal((0, thread_chat_model_js_1.taskStateFromControllerStatus)('activating'), 'running');
|
|
32
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_test_1 = __importDefault(require("node:test"));
|
|
7
|
+
const strict_1 = __importDefault(require("node:assert/strict"));
|
|
8
|
+
const workspace_model_js_1 = require("../../src/pages/Desktop/workspace-model.js");
|
|
9
|
+
(0, node_test_1.default)('desktop workspace operations keep using stable identity after a display-name change', () => {
|
|
10
|
+
strict_1.default.equal((0, workspace_model_js_1.desktopProjectWorkspaceId)({
|
|
11
|
+
workspace_id: 'workspace-stable',
|
|
12
|
+
name: 'Renamed workspace',
|
|
13
|
+
agent: { type: 'pi' },
|
|
14
|
+
platforms: [],
|
|
15
|
+
}), 'workspace-stable');
|
|
16
|
+
});
|
|
17
|
+
(0, node_test_1.default)('desktop workspace identity falls back to legacy project names', () => {
|
|
18
|
+
strict_1.default.equal((0, workspace_model_js_1.desktopProjectWorkspaceId)({
|
|
19
|
+
name: 'Legacy workspace',
|
|
20
|
+
agent: { type: 'pi' },
|
|
21
|
+
platforms: [],
|
|
22
|
+
}), 'Legacy workspace');
|
|
23
|
+
});
|