@kafca/agentdock 0.1.53 → 0.1.55

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.
Files changed (65) hide show
  1. package/README.md +5 -0
  2. package/dist/renderer/assets/{Badge-pBiMqECO.js → Badge-Bg_nNvBL.js} +1 -1
  3. package/dist/renderer/assets/{Chat-pQVBr82B.js → Chat-BJveQQKu.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-SCxRo6-e.js → ChatMarkdown-Bqn2HJ6f.js} +1 -1
  5. package/dist/renderer/assets/{Config-DRtyF20X.js → Config-CMtZDRAE.js} +1 -1
  6. package/dist/renderer/assets/{CronList-BA5hVrYp.js → CronList-C-ILB_Ae.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-p3yI0Fck.js → Dashboard-CsKBSQIe.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-Dgh25c2x.js → EmptyState-C60g3RMj.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-CuC3Cjg1.js → KnowledgeDetail-CC5C7JYe.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeHome-CH4GqtEZ.js → KnowledgeHome-3rlvxgWf.js} +1 -1
  11. package/dist/renderer/assets/{Logs-BQrm2cq-.js → Logs-CktemGN0.js} +1 -1
  12. package/dist/renderer/assets/{Modal-DfZsUS3Q.js → Modal-BQUW9LSf.js} +1 -1
  13. package/dist/renderer/assets/{MonitorList-CDWGIf1Q.js → MonitorList-B0hxjuOZ.js} +1 -1
  14. package/dist/renderer/assets/{Page-CpmZ134Z.js → Page-DL_Nv2i5.js} +1 -1
  15. package/dist/renderer/assets/{ProjectDetail-B-Kwqodz.js → ProjectDetail-Djr9-MyT.js} +1 -1
  16. package/dist/renderer/assets/{ProjectList-DtNT6dv-.js → ProjectList-BKl4eW7q.js} +1 -1
  17. package/dist/renderer/assets/{Select--_s_a1uj.js → Select-CfRkos3z.js} +1 -1
  18. package/dist/renderer/assets/{SessionChat-BHfKpufe.js → SessionChat-Dxv8D5DW.js} +1 -1
  19. package/dist/renderer/assets/{SessionList-B0kQz-Ms.js → SessionList-BJ2GjXvR.js} +1 -1
  20. package/dist/renderer/assets/{ThreadChat-CRb6Z42k.js → ThreadChat-CAsIl9qf.js} +1 -1
  21. package/dist/renderer/assets/Workspace-CaUhiGBX.js +19 -0
  22. package/dist/renderer/assets/{arrow-left-DnhnG-Tj.js → arrow-left-D1DbXrLA.js} +1 -1
  23. package/dist/renderer/assets/{book-open-Dgp3xcUz.js → book-open-BxC1z1C1.js} +1 -1
  24. package/dist/renderer/assets/{bot-BollztzX.js → bot-Fw3IzhJA.js} +1 -1
  25. package/dist/renderer/assets/{check-BHj-iSsR.js → check-5zCTgp3A.js} +1 -1
  26. package/dist/renderer/assets/{chevron-down-CeXCREMg.js → chevron-down-N3PxTNxH.js} +1 -1
  27. package/dist/renderer/assets/{circle-B3eGQ-H3.js → circle-C_chUflo.js} +1 -1
  28. package/dist/renderer/assets/{desktop-B5cYIqJH.js → desktop-DkQTZNhe.js} +1 -1
  29. package/dist/renderer/assets/{funnel-BkgiQrZC.js → funnel-B8ZAv6I7.js} +1 -1
  30. package/dist/renderer/assets/{heart-C-H_BPOT.js → heart-M9A3E4Ed.js} +1 -1
  31. package/dist/renderer/assets/{index-C97cND_H.js → index-Bwv855ID.js} +1 -1
  32. package/dist/renderer/assets/{index-CYaol0bB.js → index-DJ8w4e0l.js} +2 -2
  33. package/dist/renderer/assets/{pencil-DBHjVmSd.js → pencil-X44UaxwR.js} +1 -1
  34. package/dist/renderer/assets/{play-Cu9TIeSO.js → play-ujo-De38.js} +1 -1
  35. package/dist/renderer/assets/{plus-PaUGBkMK.js → plus-BHgVdG_A.js} +1 -1
  36. package/dist/renderer/assets/projects-DB1FLZ3A.js +1 -0
  37. package/dist/renderer/assets/{save-dm5NifZE.js → save-Cz6giKrE.js} +1 -1
  38. package/dist/renderer/assets/{search-Cq8cwrp6.js → search-DKWvTqi5.js} +1 -1
  39. package/dist/renderer/assets/{server-DwiMsKFq.js → server-BsuHcYl4.js} +1 -1
  40. package/dist/renderer/assets/{session-utils-CD2tqK35.js → session-utils-DnAWL3eo.js} +1 -1
  41. package/dist/renderer/assets/{sessions-quZ-oFVW.js → sessions-DptxO_BE.js} +1 -1
  42. package/dist/renderer/assets/{shield-check-B9UsjycW.js → shield-check-V82O8AC1.js} +1 -1
  43. package/dist/renderer/assets/{trash-2-CitZGPQS.js → trash-2-_Fgwk8mc.js} +1 -1
  44. package/dist/renderer/assets/{user-BgVotGiF.js → user-DQKTaUcR.js} +1 -1
  45. package/dist/renderer/assets/{wifi-off-CMgxdgfX.js → wifi-off-vjH-MD2w.js} +1 -1
  46. package/dist/renderer/index.html +1 -1
  47. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +1 -1
  48. package/dist-electron/services/local-ai-core/src/acp/store/runtime-config-store.js +39 -28
  49. package/dist-electron/services/local-ai-core/src/channel/lark/config.js +4 -16
  50. package/dist-electron/services/local-ai-core/src/channel/lark/local-core-lark-gateway.js +72 -13
  51. package/dist-electron/services/local-ai-core/src/channel/shared/channel-keys.js +16 -0
  52. package/dist-electron/services/local-ai-core/src/channel/weixin/config.js +3 -16
  53. package/dist-electron/services/local-ai-core/src/channel/weixin/local-core-weixin-gateway.js +12 -11
  54. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +1 -1
  55. package/dist-electron/services/local-ai-core/src/runtime/channel-service.js +0 -40
  56. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +1 -14
  57. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +1 -14
  58. package/dist-electron/services/local-ai-core/src/runtime/provider-config-migration.js +16 -0
  59. package/dist-electron/services/local-ai-core/src/scheduler/channel-execution-policy.js +12 -10
  60. package/dist-electron/tests/electron/sandbox-config.test.js +5 -0
  61. package/dist-electron/tests/integration/lark-gateway.test.js +27 -1
  62. package/dist-electron/tests/integration/local-core-refactor.test.js +51 -2
  63. package/package.json +1 -1
  64. package/dist/renderer/assets/Workspace-j-O-14yC.js +0 -19
  65. package/dist/renderer/assets/projects-BmW4zbEE.js +0 -1
@@ -12,7 +12,7 @@ function detectInstalledAgentRuntimes(options = {}) {
12
12
  const env = options.env || process.env;
13
13
  const configuredCommands = collectConfiguredAgentCommands(options.config);
14
14
  const detectedAt = (options.now || new Date()).toISOString();
15
- const versionTimeoutMs = options.versionTimeoutMs ?? 1500;
15
+ const versionTimeoutMs = options.versionTimeoutMs ?? 3000;
16
16
  const agentTypes = options.runtimeId
17
17
  ? desktop_js_1.DESKTOP_AGENT_TYPE_OPTIONS.filter((agentType) => agentType === options.runtimeId)
18
18
  : desktop_js_1.DESKTOP_AGENT_TYPE_OPTIONS;
@@ -93,46 +93,6 @@ class ChannelService {
93
93
  }
94
94
  return runtime.checkQrCodeStatus(workspaceId, ticket, instanceId);
95
95
  }
96
- async getWeixinQrCode(workspaceId, instanceId) {
97
- return this.getQrCode('weixin', workspaceId, instanceId);
98
- }
99
- async checkWeixinQrCodeStatus(workspaceId, ticket, instanceId) {
100
- return this.checkQrCodeStatus('weixin', workspaceId, ticket, instanceId);
101
- }
102
- // Lark convenience wrappers
103
- async listLarkStatuses() {
104
- return this.listStatuses('lark');
105
- }
106
- async getLarkStatus(workspaceId, instanceId) {
107
- return this.getStatus('lark', workspaceId, instanceId);
108
- }
109
- async testLarkConnection(workspaceId, instanceId) {
110
- return this.testConnection('lark', workspaceId, instanceId);
111
- }
112
- async enableLark(workspaceId, instanceId) {
113
- return this.enable('lark', workspaceId, instanceId);
114
- }
115
- async disableLark(workspaceId, instanceId) {
116
- return this.disable('lark', workspaceId, instanceId);
117
- }
118
- async listLarkPendingPairings(workspaceId) {
119
- return this.listPendingPairings('lark', workspaceId);
120
- }
121
- async approveLarkPairing(code) {
122
- return this.approvePairing('lark', code);
123
- }
124
- async rejectLarkPairing(code) {
125
- return this.rejectPairing('lark', code);
126
- }
127
- async listLarkAuthorizedUsers(workspaceId) {
128
- return this.listAuthorizedUsers('lark', workspaceId);
129
- }
130
- async getLarkQrCode(workspaceId, instanceId) {
131
- return this.getQrCode('lark', workspaceId, instanceId);
132
- }
133
- async checkLarkQrCodeStatus(workspaceId, ticket, instanceId) {
134
- return this.checkQrCodeStatus('lark', workspaceId, ticket, instanceId);
135
- }
136
96
  async refreshBindings() {
137
97
  await Promise.all([...this.runtimes.values()].map((runtime) => runtime.refreshBindings?.()));
138
98
  }
@@ -175,20 +175,7 @@ class ExternalService {
175
175
  });
176
176
  }
177
177
  async readAndMigrateConfigFile() {
178
- const current = await this.deps.readRuntimeConfig();
179
- const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(current.config, this.store);
180
- if (!migrated.changed) {
181
- return current;
182
- }
183
- const saved = await this.deps.saveRuntimeConfig(migrated.config);
184
- return {
185
- ...saved,
186
- warnings: [
187
- ...(current.warnings || []),
188
- ...(saved.warnings || []),
189
- ...migrated.warnings,
190
- ],
191
- };
178
+ return (0, provider_config_migration_js_1.applyLegacyProviderMigration)(await this.deps.readRuntimeConfig(), this.store, (config) => this.deps.saveRuntimeConfig(config));
192
179
  }
193
180
  projectBasePath(userId, externalProjectId) {
194
181
  return (0, node_path_1.join)(this.workspaceRoot(), 'users', normalizeExternalSegment(userId, 'user'), 'projects', normalizeExternalSegment(externalProjectId, 'project'));
@@ -284,20 +284,7 @@ class LocalCoreController extends node_events_1.EventEmitter {
284
284
  }
285
285
  }
286
286
  async readAndMigrateRuntimeConfig() {
287
- const current = this.store.readRuntimeConfig();
288
- const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(current.config, this.store);
289
- if (!migrated.changed) {
290
- return current;
291
- }
292
- const saved = this.store.saveRuntimeConfig(migrated.config);
293
- return {
294
- ...saved,
295
- warnings: [
296
- ...(current.warnings || []),
297
- ...(saved.warnings || []),
298
- ...migrated.warnings,
299
- ],
300
- };
287
+ return (0, provider_config_migration_js_1.applyLegacyProviderMigration)(this.store.readRuntimeConfig(), this.store, (config) => this.store.saveRuntimeConfig(config));
301
288
  }
302
289
  }
303
290
  exports.LocalCoreController = LocalCoreController;
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.migrateLegacyProjectProvidersToStore = migrateLegacyProjectProvidersToStore;
4
+ exports.applyLegacyProviderMigration = applyLegacyProviderMigration;
4
5
  const config_migration_js_1 = require("./config-migration.js");
5
6
  function migrateLegacyProjectProvidersToStore(input, store) {
6
7
  const config = cloneConfig(input);
@@ -27,6 +28,21 @@ function migrateLegacyProjectProvidersToStore(input, store) {
27
28
  }
28
29
  return { config, changed, warnings };
29
30
  }
31
+ async function applyLegacyProviderMigration(current, store, save) {
32
+ const migrated = migrateLegacyProjectProvidersToStore(current.config, store);
33
+ if (!migrated.changed) {
34
+ return current;
35
+ }
36
+ const saved = await save(migrated.config);
37
+ return {
38
+ ...saved,
39
+ warnings: [
40
+ ...(current.warnings || []),
41
+ ...(saved.warnings || []),
42
+ ...migrated.warnings,
43
+ ],
44
+ };
45
+ }
30
46
  function cloneConfig(input) {
31
47
  return JSON.parse(JSON.stringify(input || {}));
32
48
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createChannelExecutionPolicy = createChannelExecutionPolicy;
4
+ const definition_js_1 = require("../agents/shared/definition.js");
4
5
  const scheduled_bridge_session_js_1 = require("./scheduled-bridge-session.js");
5
6
  function createChannelExecutionPolicy(job, options, config) {
6
7
  if (job.executionMode === 'side-thread') {
@@ -53,11 +54,11 @@ class SideThreadChannelExecutionPolicy {
53
54
  title,
54
55
  ...(this.config.legacySideThreadTitles?.(job) || []),
55
56
  ]);
56
- const preferredAgent = normalizeAgentType(this.config.preferredAgentType?.(job));
57
+ const targetAgent = await this.resolveTargetAgent(job);
57
58
  const existing = (await this.options.workspaceRouter.listThreads(job.workspaceId))
58
- .find((thread) => reusableTitles.has(thread.title) && this.threadMatchesPreferredAgent(thread, preferredAgent));
59
+ .find((thread) => reusableTitles.has(thread.title) && this.threadMatchesTargetAgent(thread, targetAgent));
59
60
  const threadId = existing?.id
60
- || (await this.options.workspaceRouter.createThread(job.workspaceId, title, preferredAgent || undefined)).id;
61
+ || (await this.options.workspaceRouter.createThread(job.workspaceId, title, targetAgent || undefined)).id;
61
62
  return {
62
63
  kind: `${this.config.platformBase}:side-thread`,
63
64
  threadId,
@@ -78,13 +79,14 @@ class SideThreadChannelExecutionPolicy {
78
79
  await this.bridgeSession?.close();
79
80
  this.bridgeSession = undefined;
80
81
  }
81
- threadMatchesPreferredAgent(thread, preferredAgent) {
82
- if (!preferredAgent) {
83
- return true;
82
+ async resolveTargetAgent(job) {
83
+ const preferredAgent = (0, definition_js_1.normalizeAgentType)(this.config.preferredAgentType?.(job));
84
+ if (preferredAgent) {
85
+ return preferredAgent;
84
86
  }
85
- return normalizeAgentType(thread.agentType) === preferredAgent;
87
+ return (0, definition_js_1.normalizeAgentType)(await this.options.workspaceRouter.getWorkspaceDefaultAgentType(job.workspaceId));
88
+ }
89
+ threadMatchesTargetAgent(thread, targetAgent) {
90
+ return (0, definition_js_1.normalizeAgentType)(thread.agentType) === targetAgent;
86
91
  }
87
- }
88
- function normalizeAgentType(value) {
89
- return String(value || '').trim().toLowerCase();
90
92
  }
@@ -168,7 +168,9 @@ function launchConfig() {
168
168
  });
169
169
  (0, node_test_1.default)('workspace route launches sandbox proxy when sandbox is enabled', () => {
170
170
  const root = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'agentdock-sandbox-'));
171
+ const previousUserDataDir = process.env.AI_WORKSTATION_USER_DATA_DIR;
171
172
  try {
173
+ delete process.env.AI_WORKSTATION_USER_DATA_DIR;
172
174
  (0, node_fs_1.mkdirSync)((0, node_path_1.join)(root, 'runtime'), { recursive: true });
173
175
  const route = (0, workspace_route_config_js_1.toLocalCoreProjectConfig)(configState((0, node_path_1.join)(root, 'runtime', 'config.toml')), project({
174
176
  enabled: true,
@@ -186,6 +188,9 @@ function launchConfig() {
186
188
  strict_1.default.equal(JSON.parse(route.env.AGENTDOCK_SANDBOX_CONFIG).image, 'agentdock/pi-acp:local');
187
189
  }
188
190
  finally {
191
+ if (previousUserDataDir !== undefined) {
192
+ process.env.AI_WORKSTATION_USER_DATA_DIR = previousUserDataDir;
193
+ }
189
194
  (0, node_fs_1.rmSync)(root, { recursive: true, force: true });
190
195
  }
191
196
  });
@@ -1269,6 +1269,7 @@ function findLarkPostMdText(content) {
1269
1269
  });
1270
1270
  (0, node_test_1.default)('lark file messages are downloaded and forwarded as generic channel file parts', async () => {
1271
1271
  const sentMessages = [];
1272
+ const tempDir = (0, node_fs_1.mkdtempSync)((0, node_path_1.join)((0, node_os_1.tmpdir)(), 'lark-file-receive-'));
1272
1273
  const fileBytes = Buffer.from('file content');
1273
1274
  const client = {
1274
1275
  im: {
@@ -1325,6 +1326,7 @@ function findLarkPostMdText(content) {
1325
1326
  }],
1326
1327
  }),
1327
1328
  getWorkspaceRouter: () => ({
1329
+ getWorkspaceRegistryEntry: async () => ({ path: tempDir }),
1328
1330
  getThreadSessionKey: (threadId) => `session:${threadId}`,
1329
1331
  sendThreadMessage: async (threadId, content) => {
1330
1332
  sentMessages.push({ threadId, content });
@@ -1360,8 +1362,11 @@ function findLarkPostMdText(content) {
1360
1362
  strict_1.default.match(sentMessages[0]?.content?.displayText, /\[User Message\]\n\[File: report\.pdf\]\n\[\/User Message\]/);
1361
1363
  strict_1.default.deepEqual(sentMessages[0]?.content?.contentParts?.map((part) => part.type), ['text', 'file']);
1362
1364
  strict_1.default.equal(sentMessages[0]?.content?.contentParts?.[1]?.mimeType, 'application/pdf');
1363
- strict_1.default.equal(sentMessages[0]?.content?.contentParts?.[1]?.data, fileBytes.toString('base64'));
1365
+ strict_1.default.equal(sentMessages[0]?.content?.contentParts?.[1]?.data, undefined);
1364
1366
  strict_1.default.equal(sentMessages[0]?.content?.contentParts?.[1]?.fileName, 'report.pdf');
1367
+ strict_1.default.equal(sentMessages[0]?.content?.contentParts?.[1]?.path, (0, node_path_1.join)(tempDir, '.agentdock', 'channel-uploads', 'lark', 'default', 'msg-file-in-1-report.pdf'));
1368
+ strict_1.default.deepEqual((0, node_fs_1.readFileSync)(sentMessages[0]?.content?.contentParts?.[1]?.path), fileBytes);
1369
+ (0, node_fs_1.rmSync)(tempDir, { recursive: true, force: true });
1365
1370
  });
1366
1371
  (0, node_test_1.default)('lark group text messages strip the bot mention before dispatching', async () => {
1367
1372
  const sentMessages = [];
@@ -2055,3 +2060,24 @@ function findLarkPostMdText(content) {
2055
2060
  ['default', 'bot-b', 'cli_b', 'running'],
2056
2061
  ]);
2057
2062
  });
2063
+ (0, node_test_1.default)('lark gateway samples empty-render log per session/type within the dedup window', () => {
2064
+ const logs = [];
2065
+ const gateway = new local_core_lark_gateway_js_1.LocalCoreLarkGateway({
2066
+ store: {},
2067
+ readConfig: async () => null,
2068
+ getWorkspaceRouter: () => ({}),
2069
+ eventBus: { emit: () => { }, on: () => () => { } },
2070
+ log: (message) => logs.push(message),
2071
+ });
2072
+ const internals = gateway;
2073
+ for (let i = 0; i < 5; i += 1) {
2074
+ internals.logEmptyRender('session:thread-1', 'update_message');
2075
+ }
2076
+ internals.logEmptyRender('session:thread-1', 'preview_start');
2077
+ internals.logEmptyRender('session:thread-2', 'update_message');
2078
+ const emptyRenderLogs = logs.filter((line) => line.includes('produced empty render'));
2079
+ strict_1.default.equal(emptyRenderLogs.length, 3);
2080
+ strict_1.default.ok(emptyRenderLogs[0].includes('session:thread-1') && emptyRenderLogs[0].includes('type=update_message'));
2081
+ strict_1.default.ok(emptyRenderLogs[1].includes('type=preview_start'));
2082
+ strict_1.default.ok(emptyRenderLogs[2].includes('session:thread-2'));
2083
+ });
@@ -824,7 +824,8 @@ const thread_slash_command_dispatcher_js_1 = require("../../services/local-ai-co
824
824
  store: {},
825
825
  workspaceRouter: {
826
826
  getThreadSessionKey: (threadId) => `session:${threadId}`,
827
- listThreads: async () => [{ id: 'thread-scheduled', title: '[Scheduled] two-minute ping' }],
827
+ getWorkspaceDefaultAgentType: async () => 'claudecode',
828
+ listThreads: async () => [{ id: 'thread-scheduled', title: '[Scheduled] two-minute ping', agentType: 'claudecode' }],
828
829
  createThread: async () => ({ id: 'thread-new' }),
829
830
  },
830
831
  getChannelRuntime: () => ({
@@ -998,6 +999,7 @@ const thread_slash_command_dispatcher_js_1 = require("../../services/local-ai-co
998
999
  store: {},
999
1000
  workspaceRouter: {
1000
1001
  getThreadSessionKey: (threadId) => `session:${threadId}`,
1002
+ getWorkspaceDefaultAgentType: async () => 'pi',
1001
1003
  listThreads: async () => [],
1002
1004
  createThread: async (workspaceId, title, agentType) => {
1003
1005
  createThreadCalls.push({ workspaceId, title: title || '', agentType });
@@ -1011,7 +1013,54 @@ const thread_slash_command_dispatcher_js_1 = require("../../services/local-ai-co
1011
1013
  const target = await policy.resolveTarget(job);
1012
1014
  strict_1.default.equal(target.threadId, 'thread-new');
1013
1015
  strict_1.default.equal(createThreadCalls.length, 1);
1014
- strict_1.default.equal(createThreadCalls[0].agentType, undefined);
1016
+ strict_1.default.deepEqual(createThreadCalls[0], {
1017
+ workspaceId: '知识库',
1018
+ title: '[Scheduled:Lark] two-minute ping',
1019
+ agentType: 'pi',
1020
+ });
1021
+ });
1022
+ (0, node_test_1.default)('lark side-thread execution policy skips reusable threads with a different workspace default agent', async () => {
1023
+ const job = {
1024
+ id: 'job-1',
1025
+ workspaceId: '知识库',
1026
+ platform: 'lark',
1027
+ route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1', threadId: 'thread-origin' },
1028
+ executionMode: 'side-thread',
1029
+ triggerType: 'cron',
1030
+ cronExpr: '*/2 * * * *',
1031
+ promptTemplate: 'ping',
1032
+ description: 'two-minute ping',
1033
+ enabled: true,
1034
+ concurrencyPolicy: 'skip_if_running',
1035
+ createdAt: '2026-04-22T06:00:00.000Z',
1036
+ updatedAt: '2026-04-22T06:00:00.000Z',
1037
+ };
1038
+ const createThreadCalls = [];
1039
+ const policy = (0, lark_execution_policies_js_1.createLarkExecutionPolicy)(job, {
1040
+ store: {},
1041
+ workspaceRouter: {
1042
+ getThreadSessionKey: (threadId) => `session:${threadId}`,
1043
+ getWorkspaceDefaultAgentType: async () => 'claudecode',
1044
+ listThreads: async () => [
1045
+ { id: 'thread-old-codex', title: '[Scheduled:Lark] two-minute ping', agentType: 'codex' },
1046
+ ],
1047
+ createThread: async (workspaceId, title, agentType) => {
1048
+ createThreadCalls.push({ workspaceId, title: title || '', agentType });
1049
+ return { id: 'thread-new-claudecode' };
1050
+ },
1051
+ },
1052
+ getChannelRuntime: () => ({
1053
+ registerScheduledThreadBridge: () => () => { },
1054
+ }),
1055
+ }, async () => 'thread-origin', () => '');
1056
+ const target = await policy.resolveTarget(job);
1057
+ strict_1.default.equal(target.threadId, 'thread-new-claudecode');
1058
+ strict_1.default.equal(createThreadCalls.length, 1);
1059
+ strict_1.default.deepEqual(createThreadCalls[0], {
1060
+ workspaceId: '知识库',
1061
+ title: '[Scheduled:Lark] two-minute ping',
1062
+ agentType: 'claudecode',
1063
+ });
1015
1064
  });
1016
1065
  (0, node_test_1.default)('lark same-thread execution policy keeps the original thread target', async () => {
1017
1066
  const job = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.53",
3
+ "version": "0.1.55",
4
4
  "license": "PolyForm-Noncommercial-1.0.0",
5
5
  "type": "module",
6
6
  "main": "dist-electron/electron/main.js",
@@ -1,19 +0,0 @@
1
- import{c as ft,A as D,j as t,B as T,F as Wt,I as L,S as Kt,y as Xt,r as S}from"./index-CYaol0bB.js";import{M as it}from"./Modal-DfZsUS3Q.js";import{S as Z}from"./Select--_s_a1uj.js";import{E as Oe}from"./EmptyState-Dgh25c2x.js";import{S as gt,a as Pe,P as qt}from"./Page-CpmZ134Z.js";import{c as Jt,d as Zt,e as es,t as ts,f as Ne,h as ss,i as as,j as ns,k as rs,m as os,n as is,p as lt}from"./desktop-B5cYIqJH.js";import{c as pt,D as ze,d as ls,e as De,f as Me,g as Ae,h as cs,j as ct,k as dt,l as ds}from"./desktop-JQkhNOF4.js";import{T as Te}from"./trash-2-CitZGPQS.js";import{P as Ce}from"./plus-PaUGBkMK.js";import{B as ms}from"./bot-BollztzX.js";import{P as us,S as we}from"./save-dm5NifZE.js";import"./index-C97cND_H.js";import"./chevron-down-CeXCREMg.js";import"./check-BHj-iSsR.js";/**
2
- * @license lucide-react v0.487.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const hs=[["path",{d:"M17.5 19H9a7 7 0 1 1 6.71-9h1.79a4.5 4.5 0 1 1 0 9Z",key:"p7xjir"}]],fs=ft("cloud",hs);/**
7
- * @license lucide-react v0.487.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const gs=[["rect",{width:"5",height:"5",x:"3",y:"3",rx:"1",key:"1tu5fj"}],["rect",{width:"5",height:"5",x:"16",y:"3",rx:"1",key:"1v8r4q"}],["rect",{width:"5",height:"5",x:"3",y:"16",rx:"1",key:"1x03jg"}],["path",{d:"M21 16h-3a2 2 0 0 0-2 2v3",key:"177gqh"}],["path",{d:"M21 21v.01",key:"ents32"}],["path",{d:"M12 7v3a2 2 0 0 1-2 2H7",key:"8crl2c"}],["path",{d:"M3 12h.01",key:"nlz23k"}],["path",{d:"M12 3h.01",key:"n36tog"}],["path",{d:"M12 16v.01",key:"133mhm"}],["path",{d:"M16 12h1",key:"1slzba"}],["path",{d:"M21 12v.01",key:"1lwtk9"}],["path",{d:"M12 21v-1",key:"1880an"}]],mt=ft("qr-code",gs);var ps=Object.defineProperty,_e=Object.getOwnPropertySymbols,xt=Object.prototype.hasOwnProperty,vt=Object.prototype.propertyIsEnumerable,ut=(s,l,o)=>l in s?ps(s,l,{enumerable:!0,configurable:!0,writable:!0,value:o}):s[l]=o,Re=(s,l)=>{for(var o in l||(l={}))xt.call(l,o)&&ut(s,o,l[o]);if(_e)for(var o of _e(l))vt.call(l,o)&&ut(s,o,l[o]);return s},Ie=(s,l)=>{var o={};for(var m in s)xt.call(s,m)&&l.indexOf(m)<0&&(o[m]=s[m]);if(s!=null&&_e)for(var m of _e(s))l.indexOf(m)<0&&vt.call(s,m)&&(o[m]=s[m]);return o};/**
12
- * @license QR Code generator library (TypeScript)
13
- * Copyright (c) Project Nayuki.
14
- * SPDX-License-Identifier: MIT
15
- */var oe;(s=>{const l=class N{constructor(e,a,n,i){if(this.version=e,this.errorCorrectionLevel=a,this.modules=[],this.isFunction=[],e<N.MIN_VERSION||e>N.MAX_VERSION)throw new RangeError("Version value out of range");if(i<-1||i>7)throw new RangeError("Mask value out of range");this.size=e*4+17;let c=[];for(let u=0;u<this.size;u++)c.push(!1);for(let u=0;u<this.size;u++)this.modules.push(c.slice()),this.isFunction.push(c.slice());this.drawFunctionPatterns();const h=this.addEccAndInterleave(n);if(this.drawCodewords(h),i==-1){let u=1e9;for(let v=0;v<8;v++){this.applyMask(v),this.drawFormatBits(v);const _=this.getPenaltyScore();_<u&&(i=v,u=_),this.applyMask(v)}}g(0<=i&&i<=7),this.mask=i,this.applyMask(i),this.drawFormatBits(i),this.isFunction=[]}static encodeText(e,a){const n=s.QrSegment.makeSegments(e);return N.encodeSegments(n,a)}static encodeBinary(e,a){const n=s.QrSegment.makeBytes(e);return N.encodeSegments([n],a)}static encodeSegments(e,a,n=1,i=40,c=-1,h=!0){if(!(N.MIN_VERSION<=n&&n<=i&&i<=N.MAX_VERSION)||c<-1||c>7)throw new RangeError("Invalid value");let u,v;for(u=n;;u++){const w=N.getNumDataCodewords(u,a)*8,A=j.getTotalBits(e,u);if(A<=w){v=A;break}if(u>=i)throw new RangeError("Data too long")}for(const w of[N.Ecc.MEDIUM,N.Ecc.QUARTILE,N.Ecc.HIGH])h&&v<=N.getNumDataCodewords(u,w)*8&&(a=w);let _=[];for(const w of e){o(w.mode.modeBits,4,_),o(w.numChars,w.mode.numCharCountBits(u),_);for(const A of w.getData())_.push(A)}g(_.length==v);const p=N.getNumDataCodewords(u,a)*8;g(_.length<=p),o(0,Math.min(4,p-_.length),_),o(0,(8-_.length%8)%8,_),g(_.length%8==0);for(let w=236;_.length<p;w^=253)o(w,8,_);let P=[];for(;P.length*8<_.length;)P.push(0);return _.forEach((w,A)=>P[A>>>3]|=w<<7-(A&7)),new N(u,a,P,c)}getModule(e,a){return 0<=e&&e<this.size&&0<=a&&a<this.size&&this.modules[a][e]}getModules(){return this.modules}drawFunctionPatterns(){for(let n=0;n<this.size;n++)this.setFunctionModule(6,n,n%2==0),this.setFunctionModule(n,6,n%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);const e=this.getAlignmentPatternPositions(),a=e.length;for(let n=0;n<a;n++)for(let i=0;i<a;i++)n==0&&i==0||n==0&&i==a-1||n==a-1&&i==0||this.drawAlignmentPattern(e[n],e[i]);this.drawFormatBits(0),this.drawVersion()}drawFormatBits(e){const a=this.errorCorrectionLevel.formatBits<<3|e;let n=a;for(let c=0;c<10;c++)n=n<<1^(n>>>9)*1335;const i=(a<<10|n)^21522;g(i>>>15==0);for(let c=0;c<=5;c++)this.setFunctionModule(8,c,m(i,c));this.setFunctionModule(8,7,m(i,6)),this.setFunctionModule(8,8,m(i,7)),this.setFunctionModule(7,8,m(i,8));for(let c=9;c<15;c++)this.setFunctionModule(14-c,8,m(i,c));for(let c=0;c<8;c++)this.setFunctionModule(this.size-1-c,8,m(i,c));for(let c=8;c<15;c++)this.setFunctionModule(8,this.size-15+c,m(i,c));this.setFunctionModule(8,this.size-8,!0)}drawVersion(){if(this.version<7)return;let e=this.version;for(let n=0;n<12;n++)e=e<<1^(e>>>11)*7973;const a=this.version<<12|e;g(a>>>18==0);for(let n=0;n<18;n++){const i=m(a,n),c=this.size-11+n%3,h=Math.floor(n/3);this.setFunctionModule(c,h,i),this.setFunctionModule(h,c,i)}}drawFinderPattern(e,a){for(let n=-4;n<=4;n++)for(let i=-4;i<=4;i++){const c=Math.max(Math.abs(i),Math.abs(n)),h=e+i,u=a+n;0<=h&&h<this.size&&0<=u&&u<this.size&&this.setFunctionModule(h,u,c!=2&&c!=4)}}drawAlignmentPattern(e,a){for(let n=-2;n<=2;n++)for(let i=-2;i<=2;i++)this.setFunctionModule(e+i,a+n,Math.max(Math.abs(i),Math.abs(n))!=1)}setFunctionModule(e,a,n){this.modules[a][e]=n,this.isFunction[a][e]=!0}addEccAndInterleave(e){const a=this.version,n=this.errorCorrectionLevel;if(e.length!=N.getNumDataCodewords(a,n))throw new RangeError("Invalid argument");const i=N.NUM_ERROR_CORRECTION_BLOCKS[n.ordinal][a],c=N.ECC_CODEWORDS_PER_BLOCK[n.ordinal][a],h=Math.floor(N.getNumRawDataModules(a)/8),u=i-h%i,v=Math.floor(h/i);let _=[];const p=N.reedSolomonComputeDivisor(c);for(let w=0,A=0;w<i;w++){let $=e.slice(A,A+v-c+(w<u?0:1));A+=$.length;const W=N.reedSolomonComputeRemainder($,p);w<u&&$.push(0),_.push($.concat(W))}let P=[];for(let w=0;w<_[0].length;w++)_.forEach((A,$)=>{(w!=v-c||$>=u)&&P.push(A[w])});return g(P.length==h),P}drawCodewords(e){if(e.length!=Math.floor(N.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");let a=0;for(let n=this.size-1;n>=1;n-=2){n==6&&(n=5);for(let i=0;i<this.size;i++)for(let c=0;c<2;c++){const h=n-c,v=(n+1&2)==0?this.size-1-i:i;!this.isFunction[v][h]&&a<e.length*8&&(this.modules[v][h]=m(e[a>>>3],7-(a&7)),a++)}}g(a==e.length*8)}applyMask(e){if(e<0||e>7)throw new RangeError("Mask value out of range");for(let a=0;a<this.size;a++)for(let n=0;n<this.size;n++){let i;switch(e){case 0:i=(n+a)%2==0;break;case 1:i=a%2==0;break;case 2:i=n%3==0;break;case 3:i=(n+a)%3==0;break;case 4:i=(Math.floor(n/3)+Math.floor(a/2))%2==0;break;case 5:i=n*a%2+n*a%3==0;break;case 6:i=(n*a%2+n*a%3)%2==0;break;case 7:i=((n+a)%2+n*a%3)%2==0;break;default:throw new Error("Unreachable")}!this.isFunction[a][n]&&i&&(this.modules[a][n]=!this.modules[a][n])}}getPenaltyScore(){let e=0;for(let c=0;c<this.size;c++){let h=!1,u=0,v=[0,0,0,0,0,0,0];for(let _=0;_<this.size;_++)this.modules[c][_]==h?(u++,u==5?e+=N.PENALTY_N1:u>5&&e++):(this.finderPenaltyAddHistory(u,v),h||(e+=this.finderPenaltyCountPatterns(v)*N.PENALTY_N3),h=this.modules[c][_],u=1);e+=this.finderPenaltyTerminateAndCount(h,u,v)*N.PENALTY_N3}for(let c=0;c<this.size;c++){let h=!1,u=0,v=[0,0,0,0,0,0,0];for(let _=0;_<this.size;_++)this.modules[_][c]==h?(u++,u==5?e+=N.PENALTY_N1:u>5&&e++):(this.finderPenaltyAddHistory(u,v),h||(e+=this.finderPenaltyCountPatterns(v)*N.PENALTY_N3),h=this.modules[_][c],u=1);e+=this.finderPenaltyTerminateAndCount(h,u,v)*N.PENALTY_N3}for(let c=0;c<this.size-1;c++)for(let h=0;h<this.size-1;h++){const u=this.modules[c][h];u==this.modules[c][h+1]&&u==this.modules[c+1][h]&&u==this.modules[c+1][h+1]&&(e+=N.PENALTY_N2)}let a=0;for(const c of this.modules)a=c.reduce((h,u)=>h+(u?1:0),a);const n=this.size*this.size,i=Math.ceil(Math.abs(a*20-n*10)/n)-1;return g(0<=i&&i<=9),e+=i*N.PENALTY_N4,g(0<=e&&e<=2568888),e}getAlignmentPatternPositions(){if(this.version==1)return[];{const e=Math.floor(this.version/7)+2,a=this.version==32?26:Math.ceil((this.version*4+4)/(e*2-2))*2;let n=[6];for(let i=this.size-7;n.length<e;i-=a)n.splice(1,0,i);return n}}static getNumRawDataModules(e){if(e<N.MIN_VERSION||e>N.MAX_VERSION)throw new RangeError("Version number out of range");let a=(16*e+128)*e+64;if(e>=2){const n=Math.floor(e/7)+2;a-=(25*n-10)*n-55,e>=7&&(a-=36)}return g(208<=a&&a<=29648),a}static getNumDataCodewords(e,a){return Math.floor(N.getNumRawDataModules(e)/8)-N.ECC_CODEWORDS_PER_BLOCK[a.ordinal][e]*N.NUM_ERROR_CORRECTION_BLOCKS[a.ordinal][e]}static reedSolomonComputeDivisor(e){if(e<1||e>255)throw new RangeError("Degree out of range");let a=[];for(let i=0;i<e-1;i++)a.push(0);a.push(1);let n=1;for(let i=0;i<e;i++){for(let c=0;c<a.length;c++)a[c]=N.reedSolomonMultiply(a[c],n),c+1<a.length&&(a[c]^=a[c+1]);n=N.reedSolomonMultiply(n,2)}return a}static reedSolomonComputeRemainder(e,a){let n=a.map(i=>0);for(const i of e){const c=i^n.shift();n.push(0),a.forEach((h,u)=>n[u]^=N.reedSolomonMultiply(h,c))}return n}static reedSolomonMultiply(e,a){if(e>>>8||a>>>8)throw new RangeError("Byte out of range");let n=0;for(let i=7;i>=0;i--)n=n<<1^(n>>>7)*285,n^=(a>>>i&1)*e;return g(n>>>8==0),n}finderPenaltyCountPatterns(e){const a=e[1];g(a<=this.size*3);const n=a>0&&e[2]==a&&e[3]==a*3&&e[4]==a&&e[5]==a;return(n&&e[0]>=a*4&&e[6]>=a?1:0)+(n&&e[6]>=a*4&&e[0]>=a?1:0)}finderPenaltyTerminateAndCount(e,a,n){return e&&(this.finderPenaltyAddHistory(a,n),a=0),a+=this.size,this.finderPenaltyAddHistory(a,n),this.finderPenaltyCountPatterns(n)}finderPenaltyAddHistory(e,a){a[0]==0&&(e+=this.size),a.pop(),a.unshift(e)}};l.MIN_VERSION=1,l.MAX_VERSION=40,l.PENALTY_N1=3,l.PENALTY_N2=3,l.PENALTY_N3=40,l.PENALTY_N4=10,l.ECC_CODEWORDS_PER_BLOCK=[[-1,7,10,15,20,26,18,20,24,30,18,20,24,26,30,22,24,28,30,28,28,28,28,30,30,26,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,10,16,26,18,24,16,18,22,22,26,30,22,22,24,24,28,28,26,26,26,26,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28,28],[-1,13,22,18,26,18,24,18,22,20,24,28,26,24,20,30,24,28,28,26,30,28,30,30,30,30,28,30,30,30,30,30,30,30,30,30,30,30,30,30,30],[-1,17,28,22,16,22,28,26,26,24,28,24,28,22,24,24,30,28,28,26,28,30,24,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30,30]],l.NUM_ERROR_CORRECTION_BLOCKS=[[-1,1,1,1,1,1,2,2,2,2,4,4,4,4,4,6,6,6,6,7,8,8,9,9,10,12,12,12,13,14,15,16,17,18,19,19,20,21,22,24,25],[-1,1,1,1,2,2,4,4,4,5,5,5,8,9,9,10,10,11,13,14,16,17,17,18,20,21,23,25,26,28,29,31,33,35,37,38,40,43,45,47,49],[-1,1,1,2,2,4,4,6,6,8,8,8,10,12,16,12,17,16,18,21,20,23,23,25,27,29,34,34,35,38,40,43,45,48,51,53,56,59,62,65,68],[-1,1,1,2,4,4,4,5,6,8,8,11,11,16,16,18,16,19,21,25,25,25,34,30,32,35,37,40,42,45,48,51,54,57,60,63,66,70,74,77,81]],s.QrCode=l;function o(b,e,a){if(e<0||e>31||b>>>e)throw new RangeError("Value out of range");for(let n=e-1;n>=0;n--)a.push(b>>>n&1)}function m(b,e){return(b>>>e&1)!=0}function g(b){if(!b)throw new Error("Assertion error")}const f=class I{constructor(e,a,n){if(this.mode=e,this.numChars=a,this.bitData=n,a<0)throw new RangeError("Invalid argument");this.bitData=n.slice()}static makeBytes(e){let a=[];for(const n of e)o(n,8,a);return new I(I.Mode.BYTE,e.length,a)}static makeNumeric(e){if(!I.isNumeric(e))throw new RangeError("String contains non-numeric characters");let a=[];for(let n=0;n<e.length;){const i=Math.min(e.length-n,3);o(parseInt(e.substring(n,n+i),10),i*3+1,a),n+=i}return new I(I.Mode.NUMERIC,e.length,a)}static makeAlphanumeric(e){if(!I.isAlphanumeric(e))throw new RangeError("String contains unencodable characters in alphanumeric mode");let a=[],n;for(n=0;n+2<=e.length;n+=2){let i=I.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n))*45;i+=I.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n+1)),o(i,11,a)}return n<e.length&&o(I.ALPHANUMERIC_CHARSET.indexOf(e.charAt(n)),6,a),new I(I.Mode.ALPHANUMERIC,e.length,a)}static makeSegments(e){return e==""?[]:I.isNumeric(e)?[I.makeNumeric(e)]:I.isAlphanumeric(e)?[I.makeAlphanumeric(e)]:[I.makeBytes(I.toUtf8ByteArray(e))]}static makeEci(e){let a=[];if(e<0)throw new RangeError("ECI assignment value out of range");if(e<128)o(e,8,a);else if(e<16384)o(2,2,a),o(e,14,a);else if(e<1e6)o(6,3,a),o(e,21,a);else throw new RangeError("ECI assignment value out of range");return new I(I.Mode.ECI,0,a)}static isNumeric(e){return I.NUMERIC_REGEX.test(e)}static isAlphanumeric(e){return I.ALPHANUMERIC_REGEX.test(e)}getData(){return this.bitData.slice()}static getTotalBits(e,a){let n=0;for(const i of e){const c=i.mode.numCharCountBits(a);if(i.numChars>=1<<c)return 1/0;n+=4+c+i.bitData.length}return n}static toUtf8ByteArray(e){e=encodeURI(e);let a=[];for(let n=0;n<e.length;n++)e.charAt(n)!="%"?a.push(e.charCodeAt(n)):(a.push(parseInt(e.substring(n+1,n+3),16)),n+=2);return a}};f.NUMERIC_REGEX=/^[0-9]*$/,f.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,f.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";let j=f;s.QrSegment=f})(oe||(oe={}));(s=>{(l=>{const o=class{constructor(g,f){this.ordinal=g,this.formatBits=f}};o.LOW=new o(0,1),o.MEDIUM=new o(1,0),o.QUARTILE=new o(2,3),o.HIGH=new o(3,2),l.Ecc=o})(s.QrCode||(s.QrCode={}))})(oe||(oe={}));(s=>{(l=>{const o=class{constructor(g,f){this.modeBits=g,this.numBitsCharCount=f}numCharCountBits(g){return this.numBitsCharCount[Math.floor((g+7)/17)]}};o.NUMERIC=new o(1,[10,12,14]),o.ALPHANUMERIC=new o(2,[9,11,13]),o.BYTE=new o(4,[8,16,16]),o.KANJI=new o(8,[8,10,12]),o.ECI=new o(7,[0,0,0]),l.Mode=o})(s.QrSegment||(s.QrSegment={}))})(oe||(oe={}));var ue=oe;/**
16
- * @license qrcode.react
17
- * Copyright (c) Paul O'Shannessy
18
- * SPDX-License-Identifier: ISC
19
- */var xs={L:ue.QrCode.Ecc.LOW,M:ue.QrCode.Ecc.MEDIUM,Q:ue.QrCode.Ecc.QUARTILE,H:ue.QrCode.Ecc.HIGH},bt=128,wt="L",yt="#FFFFFF",_t="#000000",Ct=!1,kt=1,vs=4,bs=0,ws=.1;function jt(s,l=0){const o=[];return s.forEach(function(m,g){let f=null;m.forEach(function(j,b){if(!j&&f!==null){o.push(`M${f+l} ${g+l}h${b-f}v1H${f+l}z`),f=null;return}if(b===m.length-1){if(!j)return;f===null?o.push(`M${b+l},${g+l} h1v1H${b+l}z`):o.push(`M${f+l},${g+l} h${b+1-f}v1H${f+l}z`);return}j&&f===null&&(f=b)})}),o.join("")}function Nt(s,l){return s.slice().map((o,m)=>m<l.y||m>=l.y+l.h?o:o.map((g,f)=>f<l.x||f>=l.x+l.w?g:!1))}function ys(s,l,o,m){if(m==null)return null;const g=s.length+o*2,f=Math.floor(l*ws),j=g/l,b=(m.width||f)*j,e=(m.height||f)*j,a=m.x==null?s.length/2-b/2:m.x*j,n=m.y==null?s.length/2-e/2:m.y*j,i=m.opacity==null?1:m.opacity;let c=null;if(m.excavate){let u=Math.floor(a),v=Math.floor(n),_=Math.ceil(b+a-u),p=Math.ceil(e+n-v);c={x:u,y:v,w:_,h:p}}const h=m.crossOrigin;return{x:a,y:n,h:e,w:b,excavation:c,opacity:i,crossOrigin:h}}function _s(s,l){return l!=null?Math.max(Math.floor(l),0):s?vs:bs}function Et({value:s,level:l,minVersion:o,includeMargin:m,marginSize:g,imageSettings:f,size:j,boostLevel:b}){let e=D.useMemo(()=>{const u=(Array.isArray(s)?s:[s]).reduce((v,_)=>(v.push(...ue.QrSegment.makeSegments(_)),v),[]);return ue.QrCode.encodeSegments(u,xs[l],o,void 0,void 0,b)},[s,l,o,b]);const{cells:a,margin:n,numCells:i,calculatedImageSettings:c}=D.useMemo(()=>{let h=e.getModules();const u=_s(m,g),v=h.length+u*2,_=ys(h,j,u,f);return{cells:h,margin:u,numCells:v,calculatedImageSettings:_}},[e,j,f,m,g]);return{qrcode:e,margin:n,cells:a,numCells:i,calculatedImageSettings:c}}var Cs=(function(){try{new Path2D().addPath(new Path2D)}catch{return!1}return!0})(),ks=D.forwardRef(function(l,o){const m=l,{value:g,size:f=bt,level:j=wt,bgColor:b=yt,fgColor:e=_t,includeMargin:a=Ct,minVersion:n=kt,boostLevel:i,marginSize:c,imageSettings:h}=m,v=Ie(m,["value","size","level","bgColor","fgColor","includeMargin","minVersion","boostLevel","marginSize","imageSettings"]),{style:_}=v,p=Ie(v,["style"]),P=h==null?void 0:h.src,w=D.useRef(null),A=D.useRef(null),$=D.useCallback(V=>{w.current=V,typeof o=="function"?o(V):o&&(o.current=V)},[o]),[W,C]=D.useState(!1),{margin:Q,cells:ie,numCells:q,calculatedImageSettings:G}=Et({value:g,level:j,minVersion:n,boostLevel:i,includeMargin:a,marginSize:c,imageSettings:h,size:f});D.useEffect(()=>{if(w.current!=null){const V=w.current,H=V.getContext("2d");if(!H)return;let M=ie;const J=A.current,te=G!=null&&J!==null&&J.complete&&J.naturalHeight!==0&&J.naturalWidth!==0;te&&G.excavation!=null&&(M=Nt(ie,G.excavation));const he=window.devicePixelRatio||1;V.height=V.width=f*he;const fe=f/q*he;H.scale(fe,fe),H.fillStyle=b,H.fillRect(0,0,q,q),H.fillStyle=e,Cs?H.fill(new Path2D(jt(M,Q))):ie.forEach(function(se,K){se.forEach(function(y,ce){y&&H.fillRect(ce+Q,K+Q,1,1)})}),G&&(H.globalAlpha=G.opacity),te&&H.drawImage(J,G.x+Q,G.y+Q,G.w,G.h)}}),D.useEffect(()=>{C(!1)},[P]);const pe=Re({height:f,width:f},_);let le=null;return P!=null&&(le=D.createElement("img",{src:P,key:P,style:{display:"none"},onLoad:()=>{C(!0)},ref:A,crossOrigin:G==null?void 0:G.crossOrigin})),D.createElement(D.Fragment,null,D.createElement("canvas",Re({style:pe,height:f,width:f,ref:$,role:"img"},p)),le)});ks.displayName="QRCodeCanvas";var Le=D.forwardRef(function(l,o){const m=l,{value:g,size:f=bt,level:j=wt,bgColor:b=yt,fgColor:e=_t,includeMargin:a=Ct,minVersion:n=kt,boostLevel:i,title:c,marginSize:h,imageSettings:u}=m,v=Ie(m,["value","size","level","bgColor","fgColor","includeMargin","minVersion","boostLevel","title","marginSize","imageSettings"]),{margin:_,cells:p,numCells:P,calculatedImageSettings:w}=Et({value:g,level:j,minVersion:n,boostLevel:i,includeMargin:a,marginSize:h,imageSettings:u,size:f});let A=p,$=null;u!=null&&w!=null&&(w.excavation!=null&&(A=Nt(p,w.excavation)),$=D.createElement("image",{href:u.src,height:w.h,width:w.w,x:w.x+_,y:w.y+_,preserveAspectRatio:"none",opacity:w.opacity,crossOrigin:w.crossOrigin}));const W=jt(A,_);return D.createElement("svg",Re({height:f,width:f,viewBox:`0 0 ${P} ${P}`,ref:o,role:"img"},v),!!c&&D.createElement("title",null,c),D.createElement("path",{fill:b,d:`M0,0 h${P}v${P}H0z`,shapeRendering:"crispEdges"}),D.createElement("path",{fill:e,d:W,shapeRendering:"crispEdges"}),$)});Le.displayName="QRCodeSVG";const ee="__custom__",Ee=["weixin","lark"],Fe=[{id:"openai",label:"OpenAI",name:"openai",base_url:"https://api.openai.com/v1",model:"gpt-4.1-mini"},{id:"openrouter",label:"OpenRouter",name:"openrouter",base_url:"https://openrouter.ai/api/v1",model:"openai/gpt-4.1-mini"},{id:"anthropic",label:"Anthropic",name:"anthropic",base_url:"https://api.anthropic.com/v1",model:"claude-3-5-haiku-latest"},{id:"deepseek",label:"DeepSeek",name:"deepseek",base_url:"https://api.deepseek.com",model:"deepseek-v4-flash"},{id:"minimax",label:"Minimax",name:"minimax",base_url:"https://api.minimax.chat/v1",model:"MiniMax-M2.5"},{id:"ollama",label:"Ollama",name:"ollama",base_url:"http://127.0.0.1:11434/v1",model:"qwen2.5-coder:7b"}],z={runtime_image_id:De("pi").id,server_url:"http://127.0.0.1:8080",image:"agentdock/pi-acp:local",api_key_env:"OPEN_SANDBOX_API_KEY",acp_port:"8080",state_scope:"project",timeout_seconds:"7200",sandbox_lifecycle:"per_thread",idle_seconds:"900",warm_pool_size:"0",cpu:"1000m",memory:"2Gi",workspace_mount_path:"/workspace",state_mount_path:"/agent-state"};function U(s){return JSON.parse(JSON.stringify(s))}function me(s){return Array.isArray(s.projects)||(s.projects=[]),s.projects}function js(s){const l=new Set(s.map(m=>m.name).filter(Boolean));let o=s.length+1;for(;l.has(`project-${o}`);)o+=1;return{name:`project-${o}`,agentType:ls,workDir:"",model:""}}function ge(s){var l,o,m,g;return{...s,agent:{...s.agent,options:{...((l=s.agent)==null?void 0:l.options)||{},model:pt((o=s.agent)==null?void 0:o.type,String(((g=(m=s.agent)==null?void 0:m.options)==null?void 0:g.model)||""))}},platforms:s.platforms||[]}}function ye(s){return{id:s.id,name:s.name,api_key:s.api_key||"",base_url:s.base_url||"",model:s.model||"",models:s.models||[],thinking:s.thinking||"",env:s.env||{}}}function St(s,l){return l.includes(s)?s:ee}function Ns(s){var l;return((l=Fe.find(o=>s.name===o.name||o.base_url&&s.base_url===o.base_url||o.model&&s.model===o.model&&s.name===o.name))==null?void 0:l.id)||ee}function Es(s,l){const o=Fe.find(m=>m.id===l);return o?{...s,name:o.name,base_url:o.base_url,model:o.model}:s}function Se(s="weixin"){var l;return{type:s,options:{instance_id:`${s}-${((l=crypto.randomUUID)==null?void 0:l.call(crypto))||Date.now().toString(36)}`}}}function re(s){var l;return String(((l=s==null?void 0:s.options)==null?void 0:l.instance_id)||"").trim()||"default"}function be(s){const l=s.type==="feishu"?"lark":s.type,o=s.options&&typeof s.options=="object"?{...s.options}:{};return l==="weixin"?{type:l,options:{...o,instance_id:String(o.instance_id||"").trim()}}:l==="lark"?{type:l,options:{...o,instance_id:String(o.instance_id||"").trim(),app_id:String(o.app_id||"").trim(),app_secret:String(o.app_secret||"").trim(),card_actions:o.card_actions===!0}}:{type:l,options:o}}function Ss(s){var l;if(s.type==="weixin")return"WeChat QR login";if(s.type==="lark"){const o=String(((l=s.options)==null?void 0:l.app_id)||"").trim();return o?`App ID ${o}`:"App ID and secret required"}return"Custom platform"}function Pt(s){var m,g;const l=String(((g=(m=s.agent)==null?void 0:m.options)==null?void 0:g.work_dir)||"").trim();return l?l.replace(/\/+$/,"").split("/").filter(Boolean).pop()||l:"No work directory"}function Ps(s){return s==="success"?"border-primary/20 bg-primary/10 text-primary dark:border-primary/25 dark:bg-primary/10 dark:text-blue-200":s==="warning"?"border-amber-200 bg-amber-50 text-amber-700 dark:border-amber-400/20 dark:bg-amber-500/10 dark:text-amber-200":"border-red-200 bg-red-50 text-red-700 dark:border-red-400/20 dark:bg-red-500/10 dark:text-red-200"}function ht(s){return{enabled:!!(s!=null&&s.enabled),provider_id:(s==null?void 0:s.provider_id)||ze,runtime_image_id:(s==null?void 0:s.runtime_image_id)||z.runtime_image_id,server_url:(s==null?void 0:s.server_url)||z.server_url,image:(s==null?void 0:s.image)||z.image,api_key_env:(s==null?void 0:s.api_key_env)||z.api_key_env,acp_port:String((s==null?void 0:s.acp_port)||z.acp_port),state_scope:(s==null?void 0:s.state_scope)||z.state_scope,timeout_seconds:String((s==null?void 0:s.timeout_seconds)||z.timeout_seconds),sandbox_lifecycle:(s==null?void 0:s.sandbox_lifecycle)||z.sandbox_lifecycle,idle_seconds:String((s==null?void 0:s.idle_seconds)||z.idle_seconds),warm_pool_size:String((s==null?void 0:s.warm_pool_size)??z.warm_pool_size),cpu:(s==null?void 0:s.cpu)||z.cpu,memory:(s==null?void 0:s.memory)||z.memory,workspace_mount_path:(s==null?void 0:s.workspace_mount_path)||z.workspace_mount_path,state_mount_path:(s==null?void 0:s.state_mount_path)||z.state_mount_path}}function Ms(s){return{enabled:s.enabled,provider_id:s.provider_id.trim()||ze,runtime_image_id:s.runtime_image_id.trim()||z.runtime_image_id,state_scope:s.state_scope,timeout_seconds:Number(s.timeout_seconds)||Number(z.timeout_seconds),sandbox_lifecycle:s.sandbox_lifecycle,idle_seconds:Number(s.idle_seconds)||Number(z.idle_seconds),warm_pool_size:Math.max(0,Number(s.warm_pool_size)||0),cpu:s.cpu.trim()||z.cpu,memory:s.memory.trim()||z.memory}}function As({projects:s,selectedIndex:l,onAddProject:o,onSelectProject:m,onRemoveProject:g}){return t.jsx(gt,{title:"项目",actions:t.jsxs(T,{size:"sm",onClick:o,children:[t.jsx(Ce,{size:14})," 新建项目"]}),className:"app-panel lg:self-start",children:s.length===0?t.jsx(Oe,{message:"还没有项目。"}):t.jsx("div",{className:"space-y-2",children:s.map((f,j)=>{var b,e;return t.jsxs("div",{className:`flex items-center justify-between gap-2 ${j===l?"app-list-row app-list-row-active":"app-list-row"}`,children:[t.jsxs("button",{type:"button",onClick:()=>m(j,f),className:"min-w-0 flex-1 text-left",children:[t.jsx("p",{className:"truncate text-sm font-medium text-slate-950 dark:text-white",children:f.name||`Project ${j+1}`}),t.jsxs("p",{className:"mt-0.5 truncate text-xs text-muted-foreground",children:[((b=f.agent)==null?void 0:b.type)||"unknown"," · ",Pt(f)," · ",((e=f.platforms)==null?void 0:e.length)||0," platforms"]})]}),t.jsx(T,{variant:"ghost",size:"sm",className:"app-icon-button shrink-0",onClick:()=>g(j,f),"aria-label":`Remove ${f.name}`,children:t.jsx(Te,{size:14})})]},`${f.name}-${j}`)})})})}function Rs({project:s,sandbox:l}){var o,m;return t.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-4",children:[t.jsxs("div",{className:"app-surface p-4",children:[t.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[t.jsx(ms,{size:14})," Agent"]}),t.jsx("p",{className:"mt-2 truncate text-sm font-semibold text-foreground",children:((o=s.agent)==null?void 0:o.type)||"unknown"})]}),t.jsxs("div",{className:"app-surface p-4",children:[t.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[t.jsx(Wt,{size:14})," Workspace"]}),t.jsx("p",{className:"mt-2 truncate text-sm font-semibold text-foreground",children:Pt(s)})]}),t.jsxs("div",{className:"app-surface p-4",children:[t.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[t.jsx(us,{size:14})," Platforms"]}),t.jsxs("p",{className:"mt-2 truncate text-sm font-semibold text-foreground",children:[((m=s.platforms)==null?void 0:m.length)||0," configured"]})]}),t.jsxs("div",{className:"app-surface p-4",children:[t.jsxs("div",{className:"flex items-center gap-2 text-xs text-muted-foreground",children:[t.jsx(fs,{size:14})," Sandbox"]}),t.jsx("p",{className:"mt-2 truncate text-sm font-semibold text-foreground",children:l.enabled?"Cloud enabled":"Local runtime"})]})]})}function Is({project:s,updateProject:l}){var o,m,g,f,j,b;return t.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[t.jsx(L,{label:"Project name",value:s.name,onChange:e=>l(a=>({...a,name:e.target.value}))}),t.jsxs(Z,{label:"Agent type",value:St(((o=s.agent)==null?void 0:o.type)||"",Me),onChange:e=>l(a=>{var i;const n=e.target.value===ee?a.agent.type:e.target.value;return{...a,agent:{...a.agent,type:n,options:{...a.agent.options||{},model:pt(n,String(((i=a.agent.options)==null?void 0:i.model)||""))}}}}),children:[Me.map(e=>t.jsx("option",{value:e,children:e},e)),t.jsx("option",{value:ee,children:"custom"})]}),t.jsx(L,{label:"Host workspace path",value:String(((g=(m=s.agent)==null?void 0:m.options)==null?void 0:g.work_dir)||""),onChange:e=>l(a=>({...a,agent:{...a.agent,options:{...a.agent.options||{},work_dir:e.target.value}}}))}),t.jsx(L,{label:"Default model",value:String(((j=(f=s.agent)==null?void 0:f.options)==null?void 0:j.model)||""),onChange:e=>l(a=>({...a,agent:{...a.agent,options:{...a.agent.options||{},model:e.target.value}}})),placeholder:Ae((b=s.agent)==null?void 0:b.type)||"Use agent default model"})]})}function Ls({project:s,modelProviders:l,providerDrafts:o,updateProject:m,updateProviderDraft:g,onAddProvider:f,onSaveProvider:j,onDeleteProvider:b}){var e,a,n,i;return t.jsxs("section",{className:"space-y-3",children:[t.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:[t.jsxs(Z,{label:"Project provider",value:String(((a=(e=s.agent)==null?void 0:e.options)==null?void 0:a.provider_id)||""),onChange:c=>m(h=>({...h,agent:{...h.agent,options:{...h.agent.options||{},provider_id:c.target.value}}})),children:[t.jsx("option",{value:"",children:"No provider"}),l.map(c=>t.jsx("option",{value:c.id,children:c.name},c.id))]}),t.jsx(L,{label:"Model override",value:String(((i=(n=s.agent)==null?void 0:n.options)==null?void 0:i.model)||""),onChange:c=>m(h=>({...h,agent:{...h.agent,options:{...h.agent.options||{},model:c.target.value}}})),placeholder:"Use provider default model"})]}),t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("div",{children:[t.jsx("h3",{className:"text-sm font-semibold text-slate-950 dark:text-white",children:"Shared providers"}),t.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"Providers are shared and selected by projects."})]}),t.jsxs(T,{size:"sm",variant:"secondary",onClick:f,children:[t.jsx(Ce,{size:14})," Add provider"]})]}),l.length===0?t.jsx("div",{className:"rounded-xl border border-black/10 px-4 py-4 text-sm text-muted-foreground dark:border-white/[0.08]",children:"No shared providers configured."}):t.jsx("div",{className:"space-y-3",children:l.map(c=>{const h=o[c.id]||ye(c);return t.jsx("div",{className:"app-surface p-4",children:t.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:[t.jsxs(Z,{label:"Preset",value:Ns(h),onChange:u=>{u.target.value!==ee&&g(c.id,v=>Es(v,u.target.value))},children:[Fe.map(u=>t.jsx("option",{value:u.id,children:u.label},u.id)),t.jsx("option",{value:ee,children:"custom"})]}),t.jsx(L,{label:"Name",value:h.name||"",onChange:u=>g(c.id,v=>({...v,name:u.target.value}))}),t.jsx(L,{label:"API key",type:"password",value:h.api_key||"",onChange:u=>g(c.id,v=>({...v,api_key:u.target.value}))}),t.jsx(L,{label:"Base URL",value:h.base_url||"",onChange:u=>g(c.id,v=>({...v,base_url:u.target.value}))}),t.jsx(L,{label:"Default model",value:h.model||"",onChange:u=>g(c.id,v=>({...v,model:u.target.value}))}),t.jsxs("div",{className:"flex items-end gap-2",children:[t.jsxs(T,{variant:"secondary",size:"sm",onClick:()=>j(c.id),children:[t.jsx(we,{size:14})," Save"]}),t.jsxs(T,{variant:"danger",size:"sm",onClick:()=>b(c.id),children:[t.jsx(Te,{size:14})," Remove"]})]})]})},c.id)})})]})}function Os({project:s,updateProject:l,onOpenPlatformDialog:o}){return t.jsxs("section",{className:"space-y-3",children:[t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[t.jsxs("div",{children:[t.jsx("h3",{className:"text-sm font-semibold text-slate-950 dark:text-white",children:"Platforms"}),t.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"Configure each platform with its own required connection fields."})]}),t.jsxs(T,{size:"sm",variant:"secondary",onClick:()=>o(null),children:[t.jsx(Ce,{size:14})," Platform"]})]}),(s.platforms||[]).length===0?t.jsx(Oe,{message:"No platforms configured."}):t.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:(s.platforms||[]).map((m,g)=>t.jsxs("div",{className:"app-list-row flex items-center justify-between gap-3",children:[t.jsxs("div",{className:"min-w-0",children:[t.jsx("p",{className:"truncate text-sm font-medium text-slate-950 dark:text-white",children:m.type}),t.jsx("p",{className:"mt-1 truncate text-xs text-muted-foreground",children:Ss(m)})]}),t.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[t.jsx(T,{variant:"secondary",size:"sm",className:"app-icon-button",onClick:()=>o(g),"aria-label":`Configure ${m.type}`,children:t.jsx(Kt,{size:14})}),t.jsx(T,{variant:"danger",size:"sm",className:"app-icon-button",onClick:()=>l(f=>{const j=[...f.platforms||[]];return j.splice(g,1),{...f,platforms:j}}),children:t.jsx(Te,{size:14})})]})]},`${m.type}-${g}`))})]})}function zs({project:s,sandbox:l,profile:o,sandboxProvider:m,runtimeImage:g,updateSandbox:f,updateDeploymentProfile:j}){return t.jsxs("section",{className:"space-y-4",children:[t.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between",children:[t.jsxs("div",{children:[t.jsx("h3",{className:"text-sm font-semibold text-slate-950 dark:text-white",children:"云端模式"}),t.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"通过 OpenSandbox 为 Agent 运行启动独立容器。"})]}),t.jsx(Pe,{tone:l.enabled?"success":"neutral",children:l.enabled?"Enabled":"Local"})]}),t.jsxs("label",{className:"app-toolbar flex items-center gap-3 text-sm font-medium text-slate-950 dark:text-white",children:[t.jsx("input",{type:"checkbox",className:"h-4 w-4 rounded border-black/20 dark:border-white/20",checked:l.enabled,onChange:b=>f(e=>{var a;return{...e,enabled:b.target.checked,provider_id:e.provider_id||ze,runtime_image_id:e.runtime_image_id||De(((a=s==null?void 0:s.agent)==null?void 0:a.type)||"pi").id}})}),"启用云端模式(Sandbox)"]}),l.enabled?t.jsxs("div",{className:"space-y-4",children:[t.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[t.jsx(Z,{label:"Deployment",value:o.id,onChange:b=>j(b.target.value),children:cs.map(b=>t.jsx("option",{value:b.id,children:b.label},b.id))}),t.jsxs(Z,{label:"State scope",value:l.state_scope,onChange:b=>f(e=>({...e,state_scope:b.target.value})),children:[t.jsx("option",{value:"user",children:"User"}),t.jsx("option",{value:"project",children:"Project"}),t.jsx("option",{value:"thread",children:"Thread"}),t.jsx("option",{value:"run",children:"Run"})]}),t.jsx(L,{label:"CPU",value:l.cpu,onChange:b=>f(e=>({...e,cpu:b.target.value}))}),t.jsx(L,{label:"Memory",value:l.memory,onChange:b=>f(e=>({...e,memory:b.target.value}))}),t.jsx(L,{label:"Timeout seconds",type:"number",value:l.timeout_seconds,onChange:b=>f(e=>({...e,timeout_seconds:b.target.value}))}),t.jsxs(Z,{label:"Sandbox lifecycle",value:l.sandbox_lifecycle,onChange:b=>f(e=>({...e,sandbox_lifecycle:b.target.value})),children:[t.jsx("option",{value:"per_thread",children:"Keep warm per thread"}),t.jsx("option",{value:"per_run",children:"Close after each run"})]}),t.jsx(L,{label:"Idle seconds",type:"number",value:l.idle_seconds,onChange:b=>f(e=>({...e,idle_seconds:b.target.value}))}),t.jsx(L,{label:"Warm pool",type:"number",value:l.warm_pool_size,onChange:b=>f(e=>({...e,warm_pool_size:b.target.value}))})]}),t.jsxs("div",{className:"rounded-xl border border-black/10 px-4 py-3 text-sm text-muted-foreground dark:border-white/[0.08]",children:[t.jsx("div",{className:"font-medium text-slate-950 dark:text-white",children:"当前运行配置"}),t.jsxs("div",{className:"mt-2 grid grid-cols-1 gap-2 md:grid-cols-2",children:[t.jsxs("div",{children:["OpenSandbox: ",m.server_url||"not configured"]}),t.jsxs("div",{children:["Image: ",g.image]}),t.jsxs("div",{children:["ACP port: ",g.acp_port]}),t.jsxs("div",{children:["Sandbox workspace path: ",g.workspace_mount_path||o.workspaceMountPath]}),t.jsxs("div",{children:["State mount: ",g.state_mount_path||o.stateMountPath]}),t.jsxs("div",{children:["API key env: ",m.api_key_env||"OPEN_SANDBOX_API_KEY"]})]})]}),t.jsxs("details",{className:"rounded-xl border border-black/10 px-4 py-3 text-sm dark:border-white/[0.08]",children:[t.jsx("summary",{className:"cursor-pointer font-medium text-slate-950 dark:text-white",children:"Advanced"}),t.jsx("div",{className:"mt-3 text-muted-foreground",children:"Host workspace path 是 OpenSandbox 挂载源;Sandbox workspace path 是 Agent 容器内的工作目录。Core 只启动代理进程,不直接使用 host workspace path 作为代理工作目录。"})]})]}):t.jsx("div",{className:"rounded-xl border border-black/10 px-4 py-3 text-sm text-muted-foreground dark:border-white/[0.08]",children:"当前项目会继续使用本地 Agent runtime。"})]})}function Zs(){var He,Ye,Ve,We,Ke,Xe,qe,Je,Ze,et,tt,st;const[s,l]=Xt(),o=s.get("project")||"",[m,g]=S.useState(null),[f,j]=S.useState(null),[b,e]=S.useState([]),[a,n]=S.useState({}),[i,c]=S.useState(0),[h,u]=S.useState("basic"),[v,_]=S.useState(null),[p,P]=S.useState(null),[w,A]=S.useState(null),[$,W]=S.useState(!1),[C,Q]=S.useState(null),[ie,q]=S.useState(!1),[G,pe]=S.useState(!0),[le,V]=S.useState(""),[H,M]=S.useState(null),J=S.useRef(null),te=S.useRef(null),he=S.useRef(i),fe=S.useRef(""),se=S.useCallback(async(r="")=>{pe(!0);try{const[d,x]=await Promise.all([Jt(),Zt()]),k=U(d.config||{});if(k.projects=me(k).map(E=>ge(E)),g(k),j(U(k)),e(x.providers||[]),n(Object.fromEntries((x.providers||[]).map(E=>[E.id,ye(E)]))),r){const E=(k.projects||[]).findIndex(O=>O.name===r);c(E>=0?E:0)}}catch(d){M({tone:"error",message:d instanceof Error?d.message:String(d)})}finally{pe(!1)}},[]);S.useEffect(()=>{se(o)},[se]);const K=(m==null?void 0:m.projects)||[],y=K[i]||null,ce=ht((Ye=(He=y==null?void 0:y.agent)==null?void 0:He.options)==null?void 0:Ye.sandbox),Be=ct(String((m==null?void 0:m.deployment_profile)||"").trim()),Mt=((m==null?void 0:m.sandbox_providers)||[]).find(r=>r.id===ce.provider_id)||dt(Be.id),At=((m==null?void 0:m.sandbox_runtime_images)||[]).find(r=>r.id===ce.runtime_image_id)||De(((Ve=y==null?void 0:y.agent)==null?void 0:Ve.type)||"pi"),Ue=JSON.stringify(m||{})!==JSON.stringify(f||{});S.useEffect(()=>{J.current=m},[m]),S.useEffect(()=>{te.current=p},[p]),S.useEffect(()=>{he.current=i,fe.current=(y==null?void 0:y.name)||""},[i,y==null?void 0:y.name]),S.useEffect(()=>{if(!m||!o)return;const r=K.findIndex(d=>d.name===o);r>=0&&r!==i&&c(r)},[m,K,o,i]);const de=S.useCallback(r=>{g(d=>{if(!d)return d;const x=U(d),k=me(x),E=k[i];return E?(k[i]=ge(r(E)),x):d})},[i]),Rt=S.useCallback(r=>{de(d=>{var x;return{...d,agent:{...d.agent,options:{...d.agent.options||{},sandbox:Ms(r(ht((x=d.agent.options)==null?void 0:x.sandbox)))}}}})},[de]),It=S.useCallback(r=>{const d=ct(r);g(x=>{if(!x)return x;const k=U(x);k.deployment_profile=d.id;const E=dt(d.id),O=Array.isArray(k.sandbox_providers)?[...k.sandbox_providers]:[],B=O.findIndex(F=>F.id===E.id);return B>=0?O[B]={...O[B],server_url:E.server_url}:O.push(E),k.sandbox_providers=O,k})},[]),Lt=()=>{_(js(K))},Ot=S.useCallback((r,d)=>{n(x=>{const k=x[r];return k?{...x,[r]:d(k)}:x})},[]),zt=async()=>{try{const r=await ss({name:`provider-${b.length+1}`});e(d=>[...d,r].sort((x,k)=>x.name.localeCompare(k.name))),n(d=>({...d,[r.id]:ye(r)})),M({tone:"success",message:"Provider created."})}catch(r){M({tone:"error",message:r instanceof Error?r.message:String(r)})}},Dt=async r=>{const d=a[r];if(d)try{const x=await as(r,d);e(k=>k.map(E=>E.id===x.id?x:E).sort((E,O)=>E.name.localeCompare(O.name))),n(k=>({...k,[x.id]:ye(x)})),M({tone:"success",message:"Provider saved."})}catch(x){M({tone:"error",message:x instanceof Error?x.message:String(x)})}},Tt=async r=>{try{await ns(r),e(d=>d.filter(x=>x.id!==r)),n(d=>{const x={...d};return delete x[r],x}),M({tone:"success",message:"Provider removed."})}catch(d){M({tone:"error",message:d instanceof Error?d.message:String(d)})}},xe=r=>{_(d=>d&&{...d,...r})},Ft=()=>{if(!v)return;const r=v.name.trim(),d=v.agentType.trim(),x=v.workDir.trim(),k=v.model.trim();if(!r||!d||!x){M({tone:"warning",message:"Project name, agent type, and work directory are required."});return}if(K.some(B=>B.name===r)){M({tone:"warning",message:`Project "${r}" already exists.`});return}const E=ge({name:r,agent:{type:d,options:{model:k||Ae(d),work_dir:x},providers:[]},platforms:[],admin_from:"",disabled_commands:[]}),O=K.length;g(B=>{const F=U(B||{});return me(F).push(E),F}),c(O),l({project:r}),_(null),M(null)},Bt=r=>{g(d=>{if(!d)return d;const x=U(d),k=me(x);return k.splice(r,1),c(Math.max(0,Math.min(r,k.length-1))),x})},Ut=r=>{var x;if(A(null),Q(null),r===null){P({index:r,draft:Se()});return}const d=(x=y==null?void 0:y.platforms)==null?void 0:x[r];d&&P({index:r,draft:U(d)})},ae=r=>{P(d=>d&&{...d,draft:r(d.draft)})},$t=()=>{if(!p)return;const r=be(p.draft);de(d=>{const x=[...d.platforms||[]];return p.index===null?x.push(r):x[p.index]=r,{...d,platforms:x}}),P(null),A(null),Q(null)},$e=async()=>{if(!p||!m)return p==null?void 0:p.draft;const r=U(m),d=me(r),x=d[i];if(!x)return p.draft;const k=[...x.platforms||[]],E=be(p.draft);p.index===null?k.push(E):k[p.index]=E,d[i]=ge({...x,platforms:k});const O=await Ne(r),B=U(O.config||r);return j(B),g(U(B)),P(F=>F&&{index:F.index??k.length-1,draft:E}),E},Qt=async()=>{if(!(!(y!=null&&y.name)||!m)){W(!0);try{await $e();const r=await rs(y.name,re(p==null?void 0:p.draft));A({...r,status:"wait",createdAt:Date.now()}),M(null)}catch(r){M({tone:"error",message:r instanceof Error?r.message:String(r)})}finally{W(!1)}}},Gt=async()=>{if(!(!(y!=null&&y.name)||!m)){q(!0);try{await $e();const r=await os(y.name,re(p==null?void 0:p.draft));Q({...r,status:"wait",createdAt:Date.now()}),M(null)}catch(r){M({tone:"error",message:r instanceof Error?r.message:String(r)})}finally{q(!1)}}},Ht=async()=>{if(!(!(y!=null&&y.name)||!(w!=null&&w.ticket))){W(!0);try{const r=await is(y.name,w.ticket,re(p==null?void 0:p.draft));A(d=>d&&{...d,status:r.status}),r.status==="confirmed"&&M({tone:"success",message:"WeChat QR code confirmed."})}catch(r){M({tone:"error",message:r instanceof Error?r.message:String(r)})}finally{W(!1)}}},Qe=S.useCallback(async(r,d)=>{const x=await es(r,d);if(x.status!=="running"||x.connected!==!0)throw new Error(x.lastError||"Lark bot credentials were saved, but the gateway is not connected yet.");const k=await ts(r,d);if(!k.success)throw new Error(k.error||"Lark bot credentials were saved, but the connection test failed.")},[]),ke=S.useCallback(async r=>{var nt,rt,ot;const d=fe.current,x=re((nt=te.current)==null?void 0:nt.draft),k=J.current;if(!k)return;const E=U(k),O=me(E),B=he.current,F=O[B];if(!F)return;const R=[...F.platforms||[]],Y=te.current,X=(Y==null?void 0:Y.index)??R.findIndex(ne=>be(ne).type==="lark"&&re(ne)===x),ve=X>=0?R[X]:(Y==null?void 0:Y.draft)||Se("lark"),je=be({...ve,type:"lark",options:{...ve.options||{},instance_id:x,app_id:r.appId,app_secret:r.appSecret,verification_token:r.verificationToken||((rt=ve.options)==null?void 0:rt.verification_token)||"",encrypt_key:r.encryptKey||((ot=ve.options)==null?void 0:ot.encrypt_key)||"",card_actions:!0,subscribed_events:"im.message.receive_v1 card.action.trigger",subscribed_callbacks:"card.action.trigger"}});X>=0?R[X]=je:R.push(je),O[B]=ge({...F,platforms:R});const Vt=await Ne(E),at=U(Vt.config||E);j(at),g(U(at)),P(ne=>ne&&{...ne,index:ne.index??(X>=0?X:R.length-1),draft:je}),await Qe(d,x),M({tone:"success",message:"Lark bot bound, saved, and ready to send messages."}),await se(d)},[Qe,se]),Yt=async()=>{if(!(!(y!=null&&y.name)||!(C!=null&&C.ticket)||!m)){q(!0);try{const r=await lt(y.name,C.ticket,re(p==null?void 0:p.draft));Q(d=>{var x;return d&&{...d,status:r.status,botName:(x=r.credentials)==null?void 0:x.botName}}),r.status==="confirmed"&&r.credentials?await ke(r.credentials):r.status==="expired"&&M({tone:"warning",message:"Lark QR code expired. Generate a new QR code and scan again."})}catch(r){M({tone:"error",message:r instanceof Error?r.message:String(r)})}finally{q(!1)}}};S.useEffect(()=>{if(!(y!=null&&y.name)||!(C!=null&&C.ticket)||(p==null?void 0:p.draft.type)!=="lark"||C.status&&!["wait","signed"].includes(C.status))return;let r=!1,d;const k=(C.createdAt||Date.now())+Math.max(C.expiresIn||0,1)*1e3,E=Math.max(3,Math.min(Number(C.interval||5)||5,15))*1e3,O=F=>{d=window.setTimeout(()=>{B()},F)},B=async()=>{var F;if(!r){if(Date.now()>=k){Q(R=>(R==null?void 0:R.ticket)===C.ticket?{...R,status:"expired"}:R),M({tone:"warning",message:"Lark QR code expired. Generate a new QR code and scan again."});return}try{const R=await lt(y.name,C.ticket,re((F=te.current)==null?void 0:F.draft));if(r)return;if(Q(Y=>{var X;return(Y==null?void 0:Y.ticket)===C.ticket?{...Y,status:R.status,botName:(X=R.credentials)==null?void 0:X.botName}:Y}),R.status==="confirmed"&&R.credentials){await ke(R.credentials);return}if(R.status==="expired"){M({tone:"warning",message:"Lark QR code expired. Generate a new QR code and scan again."});return}O(E)}catch(R){if(r)return;M({tone:"error",message:R instanceof Error?R.message:String(R)})}}};return O(Math.min(2e3,E)),()=>{r=!0,d&&window.clearTimeout(d)}},[C==null?void 0:C.createdAt,C==null?void 0:C.expiresIn,C==null?void 0:C.interval,C==null?void 0:C.status,C==null?void 0:C.ticket,p==null?void 0:p.draft.type,ke,y==null?void 0:y.name]);const Ge=async()=>{if(m){V("config");try{const r=await Ne(m);j(U(r.config||m)),g(U(r.config||m)),M({tone:"success",message:"Project changes saved."}),await se()}catch(r){M({tone:"error",message:r instanceof Error?r.message:String(r)})}finally{V("")}}};return G&&!m?t.jsx("div",{className:"flex h-64 items-center justify-center text-sm text-slate-400 animate-pulse",children:"Loading workspace..."}):t.jsxs("div",{className:"space-y-6 animate-fade-in",children:[t.jsx(qt,{title:"工作区",description:"创建项目,配置 Agent、工作目录、Provider 和平台接入。"}),H?t.jsx("div",{role:"status",className:`rounded-xl border px-4 py-3 text-sm ${Ps(H.tone)}`,children:H.message}):null,Ue?t.jsxs("div",{className:"app-toolbar flex flex-col gap-3 border-amber-200 bg-amber-50 text-sm text-amber-700 dark:border-amber-400/20 dark:bg-amber-500/10 dark:text-amber-200 sm:flex-row sm:items-center sm:justify-between",children:[t.jsx("span",{children:"You have unsaved project changes."}),t.jsxs(T,{size:"sm",onClick:()=>void Ge(),loading:le==="config",children:[t.jsx(we,{size:14})," Save changes"]})]}):null,t.jsxs("div",{className:"grid min-w-0 grid-cols-1 gap-4 lg:grid-cols-[340px_minmax(0,1fr)]",children:[t.jsx(As,{projects:K,selectedIndex:i,onAddProject:Lt,onSelectProject:(r,d)=>{c(r),l(d.name?{project:d.name}:{})},onRemoveProject:r=>Bt(r)}),t.jsx(gt,{title:(y==null?void 0:y.name)||"Project details",description:y?t.jsxs("span",{className:"break-all",children:[((We=y.agent)==null?void 0:We.type)||"unknown"," · ",String(((Xe=(Ke=y.agent)==null?void 0:Ke.options)==null?void 0:Xe.work_dir)||"No work directory")]}):void 0,className:"app-panel",children:y?t.jsxs("div",{className:"space-y-6",children:[t.jsx(Rs,{project:y,sandbox:ce}),t.jsx("div",{className:"flex gap-2 overflow-x-auto border-b border-black/10 pb-4 [scrollbar-width:none] dark:border-white/[0.08] [&::-webkit-scrollbar]:hidden sm:flex-wrap",children:[["basic","基本信息"],["providers","Provider"],["platforms","平台接入"],["sandbox","云端模式"]].map(([r,d])=>t.jsx("button",{type:"button",onClick:()=>u(r),className:`app-segment ${h===r?"app-segment-active":"app-segment-idle"}`,children:d},r))}),h==="basic"?t.jsx(Is,{project:y,updateProject:de}):null,h==="providers"?t.jsx(Ls,{project:y,modelProviders:b,providerDrafts:a,updateProject:de,updateProviderDraft:Ot,onAddProvider:()=>void zt(),onSaveProvider:r=>void Dt(r),onDeleteProvider:r=>void Tt(r)}):null,h==="platforms"?t.jsx(Os,{project:y,updateProject:de,onOpenPlatformDialog:Ut}):null,h==="sandbox"?t.jsx(zs,{project:y,sandbox:ce,profile:Be,sandboxProvider:Mt,runtimeImage:At,updateSandbox:Rt,updateDeploymentProfile:It}):null,t.jsx("div",{className:"flex flex-wrap gap-2 border-t border-black/10 pt-5 dark:border-white/[0.08]",children:t.jsxs(T,{className:"w-full sm:w-auto",onClick:()=>void Ge(),loading:le==="config",disabled:!Ue&&le!=="config",children:[t.jsx(we,{size:14})," 保存更改"]})})]}):t.jsx(Oe,{message:"选择或新建项目后开始配置。"})})]}),t.jsx(it,{open:!!v,onClose:()=>_(null),title:"新建项目",children:v?t.jsxs("div",{className:"space-y-4",children:[t.jsx(L,{label:"Project name",value:v.name,onChange:r=>xe({name:r.target.value}),autoFocus:!0}),t.jsx(Z,{label:"Agent type",value:v.agentType,onChange:r=>{const d=r.target.value;xe({agentType:d})},children:Me.map(r=>t.jsx("option",{value:r,children:r},r))}),t.jsx(L,{label:"Host workspace path",value:v.workDir,onChange:r=>xe({workDir:r.target.value}),placeholder:"/Users/yinyin/code/my-project"}),t.jsx(L,{label:"Default model",value:v.model,onChange:r=>xe({model:r.target.value}),placeholder:Ae(v.agentType)||"Use agent default model"}),t.jsxs("div",{className:"flex flex-col-reverse gap-2 pt-2 sm:flex-row sm:justify-end",children:[t.jsx(T,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>_(null),children:"Cancel"}),t.jsxs(T,{className:"w-full sm:w-auto",onClick:Ft,children:[t.jsx(Ce,{size:14})," 新建项目"]})]})]}):null}),t.jsx(it,{open:!!p,onClose:()=>{P(null),A(null),Q(null)},title:(p==null?void 0:p.index)===null?"Add platform":"Configure platform",children:p?t.jsxs("div",{className:"space-y-4",children:[t.jsxs(Z,{label:"Platform",value:St(p.draft.type,[...Ee]),onChange:r=>{const d=r.target.value===ee?p.draft.type:r.target.value;ae(()=>Se(d)),A(null),Q(null)},children:[Ee.map(r=>t.jsx("option",{value:r,children:r},r)),ds.filter(r=>!Ee.includes(r)).map(r=>t.jsx("option",{value:r,children:r},r)),t.jsx("option",{value:ee,children:"custom"})]}),p.draft.type==="lark"?t.jsxs("div",{className:"grid grid-cols-1 gap-3",children:[C!=null&&C.qrCodeUrl?t.jsxs("div",{className:"flex flex-col items-center gap-3 rounded-lg border border-black/10 p-4 dark:border-white/[0.08]",children:[t.jsx("div",{className:"rounded-lg border border-black/10 bg-white p-3",children:t.jsx(Le,{value:C.qrCodeUrl,size:176,includeMargin:!0})}),t.jsx(Pe,{tone:C.status==="confirmed"?"success":C.status==="expired"?"danger":"warning",children:C.botName||C.status||"wait"})]}):null,t.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:flex-wrap",children:[t.jsxs(T,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>void Gt(),loading:ie,children:[t.jsx(mt,{size:14})," Generate QR"]}),t.jsx(T,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>void Yt(),loading:ie,disabled:!(C!=null&&C.ticket),children:"Check status"})]}),t.jsx(L,{label:"App ID",value:String(((qe=p.draft.options)==null?void 0:qe.app_id)||""),onChange:r=>ae(d=>({...d,options:{...d.options||{},app_id:r.target.value}})),placeholder:"cli_xxx"}),t.jsx(L,{label:"App Secret",type:"password",value:String(((Je=p.draft.options)==null?void 0:Je.app_secret)||""),onChange:r=>ae(d=>({...d,options:{...d.options||{},app_secret:r.target.value}}))}),t.jsx(L,{label:"Verification token",value:String(((Ze=p.draft.options)==null?void 0:Ze.verification_token)||""),onChange:r=>ae(d=>({...d,options:{...d.options||{},verification_token:r.target.value}}))}),t.jsx(L,{label:"Encrypt key",value:String(((et=p.draft.options)==null?void 0:et.encrypt_key)||""),onChange:r=>ae(d=>({...d,options:{...d.options||{},encrypt_key:r.target.value}}))}),t.jsxs("label",{className:"flex items-center gap-3 text-sm text-foreground",children:[t.jsx("input",{type:"checkbox",checked:((tt=p.draft.options)==null?void 0:tt.auto_approve)===!0,onChange:r=>ae(d=>({...d,options:{...d.options||{},auto_approve:r.target.checked}}))}),"Auto-approve Lark users"]}),t.jsxs("label",{className:"flex items-center gap-3 text-sm text-foreground",children:[t.jsx("input",{type:"checkbox",checked:((st=p.draft.options)==null?void 0:st.card_actions)===!0,onChange:r=>ae(d=>({...d,options:{...d.options||{},card_actions:r.target.checked}}))}),"Enable Lark card action buttons"]})]}):null,p.draft.type==="weixin"?t.jsxs("div",{className:"space-y-3",children:[t.jsx("div",{className:"rounded-lg border border-black/10 bg-black/[0.03] px-3 py-3 text-sm text-muted-foreground dark:border-white/[0.08] dark:bg-white/[0.04]",children:"WeChat does not need an App ID or secret. Save this platform, then generate a QR code and scan it to finish login."}),w!=null&&w.qrCodeUrl?t.jsxs("div",{className:"flex flex-col items-center gap-3 rounded-lg border border-black/10 p-4 dark:border-white/[0.08]",children:[t.jsx("div",{className:"rounded-lg border border-black/10 bg-white p-3",children:t.jsx(Le,{value:w.qrCodeUrl,size:176,includeMargin:!0})}),t.jsx(Pe,{tone:w.status==="confirmed"?"success":w.status==="expired"?"danger":"warning",children:w.status||"wait"})]}):null,t.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:flex-wrap",children:[t.jsxs(T,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>void Qt(),loading:$,children:[t.jsx(mt,{size:14})," Generate QR"]}),t.jsx(T,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>void Ht(),loading:$,disabled:!(w!=null&&w.ticket),children:"Check status"})]})]}):null,p.draft.type!=="lark"&&p.draft.type!=="weixin"?t.jsx("div",{className:"rounded-lg border border-black/10 bg-black/[0.03] px-3 py-3 text-sm text-muted-foreground dark:border-white/[0.08] dark:bg-white/[0.04]",children:"This platform has no daily UI fields yet. Existing advanced options are preserved in config."}):null,t.jsxs("div",{className:"flex flex-col-reverse gap-2 border-t border-black/10 pt-4 dark:border-white/[0.08] sm:flex-row sm:justify-end",children:[t.jsx(T,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>P(null),children:"Cancel"}),t.jsxs(T,{className:"w-full sm:w-auto",onClick:$t,children:[t.jsx(we,{size:14})," Apply"]})]})]}):null})]})}export{Zs as default};
@@ -1 +0,0 @@
1
- import{D as t}from"./index-CYaol0bB.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};