@kafca/agentdock 0.1.19 → 0.1.21

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 (62) hide show
  1. package/README.md +7 -0
  2. package/dist/renderer/assets/{Badge-DcFVSGwl.js → Badge-BRmQIqbd.js} +1 -1
  3. package/dist/renderer/assets/{Chat-CTy10fKR.js → Chat-D94ODABB.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-C-ci0dQL.js → ChatMarkdown-DqW7OUvV.js} +1 -1
  5. package/dist/renderer/assets/{Config-Bl5vuqBS.js → Config-9lgzpTCp.js} +1 -1
  6. package/dist/renderer/assets/{CronList-BQOEXhHD.js → CronList-BYZ-x_bp.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-CauX4_SR.js → Dashboard-COISXbQy.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-DVYGGFl9.js → EmptyState-w5-I9zg7.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-BlV8Twrx.js → KnowledgeDetail-DVxwrTLw.js} +1 -1
  10. package/dist/renderer/assets/{KnowledgeHome-vd6AO-Fn.js → KnowledgeHome-BKkubcwi.js} +1 -1
  11. package/dist/renderer/assets/{Logs-BrtF26F7.js → Logs-D7HxZ8Nb.js} +1 -1
  12. package/dist/renderer/assets/{Modal-D6ucs8W2.js → Modal-Ceu_MP2e.js} +1 -1
  13. package/dist/renderer/assets/{Page-BdF9afpu.js → Page-CpSczAz8.js} +1 -1
  14. package/dist/renderer/assets/{ProjectDetail-RuoRHs1Q.js → ProjectDetail-FJ_bNXLF.js} +1 -1
  15. package/dist/renderer/assets/{ProjectList-r9MXhUu7.js → ProjectList-DZKL4K9C.js} +1 -1
  16. package/dist/renderer/assets/{Select-CEsAkZ5j.js → Select-BHQk6qCU.js} +1 -1
  17. package/dist/renderer/assets/{SessionChat-DwnZpTVu.js → SessionChat-DpgSXF3m.js} +1 -1
  18. package/dist/renderer/assets/{SessionList-C89Z6STB.js → SessionList-CU6drQ4N.js} +1 -1
  19. package/dist/renderer/assets/{ThreadChat-JB9GY3La.js → ThreadChat-D3s4GXGh.js} +1 -1
  20. package/dist/renderer/assets/Workspace-B7looTVo.js +14 -0
  21. package/dist/renderer/assets/{arrow-left-DuiS0IaQ.js → arrow-left-Dtal-eOi.js} +1 -1
  22. package/dist/renderer/assets/{book-open-B6l3y70b.js → book-open-q814R_Ov.js} +1 -1
  23. package/dist/renderer/assets/{check-CfewkzaJ.js → check-DjfCdLvw.js} +1 -1
  24. package/dist/renderer/assets/{circle-qzty4gzl.js → circle-vfhmyE8v.js} +1 -1
  25. package/dist/renderer/assets/{desktop-DTAjgvNs.js → desktop-BPIxWbkM.js} +1 -1
  26. package/dist/renderer/assets/desktop-DZHC4PDB.js +3 -0
  27. package/dist/renderer/assets/{funnel-CwjI0g4c.js → funnel-CUQibo1I.js} +1 -1
  28. package/dist/renderer/assets/{heart-CVHUi-lA.js → heart-DG9_b8P1.js} +1 -1
  29. package/dist/renderer/assets/{index-tQ6A4Zff.js → index-Bn8ane6_.js} +2 -2
  30. package/dist/renderer/assets/{index-BbDTSo1y.js → index-Ds0IN5rP.js} +1 -1
  31. package/dist/renderer/assets/{pencil-BvQPZxH6.js → pencil-Dij0LlRY.js} +1 -1
  32. package/dist/renderer/assets/{play-hJkkCcS6.js → play-CPFGjIyJ.js} +1 -1
  33. package/dist/renderer/assets/{plug-BGtbkjYJ.js → plug-DH3RKQyn.js} +1 -1
  34. package/dist/renderer/assets/{plus-DrYsrZyx.js → plus-afkK9_Y8.js} +1 -1
  35. package/dist/renderer/assets/projects-DTDS9SnT.js +1 -0
  36. package/dist/renderer/assets/{save-C8W3Wq2Z.js → save-B-cKgWcy.js} +1 -1
  37. package/dist/renderer/assets/{search-BuSByDes.js → search-DR6PeYkt.js} +1 -1
  38. package/dist/renderer/assets/{server-B9wEMLdo.js → server-BM6KOB5a.js} +1 -1
  39. package/dist/renderer/assets/{session-utils-K8E4S3Qx.js → session-utils-BDuThM0a.js} +1 -1
  40. package/dist/renderer/assets/{sessions-B-QTvESY.js → sessions-C1yKps4T.js} +1 -1
  41. package/dist/renderer/assets/{shield-check-C-oxstVp.js → shield-check-BFjMG-r2.js} +1 -1
  42. package/dist/renderer/assets/{trash-2-BQpE15-6.js → trash-2-CW1heMCf.js} +1 -1
  43. package/dist/renderer/assets/{user-CM4R9QVx.js → user-r_2sHG7m.js} +1 -1
  44. package/dist/renderer/assets/{wifi-off-CoaA7hVn.js → wifi-off-VMUokMpE.js} +1 -1
  45. package/dist/renderer/index.html +1 -1
  46. package/dist-electron/electron/agent-runtime-detector.test.js +11 -0
  47. package/dist-electron/electron/local-core-refactor.test.js +522 -0
  48. package/dist-electron/electron/plugin-kernel.test.js +77 -9
  49. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-backend.js +9 -9
  50. package/dist-electron/services/local-ai-core/src/acp/local-core-acp-content.js +60 -0
  51. package/dist-electron/services/local-ai-core/src/gateway/local-core-lark-gateway.js +337 -54
  52. package/dist-electron/services/local-ai-core/src/gateway/local-core-weixin-gateway.js +50 -2
  53. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +2 -1
  54. package/dist-electron/services/local-ai-core/src/plugins/builtin/agent-localcore-acp-plugin.js +9 -0
  55. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +19 -8
  56. package/dist-electron/services/local-ai-core/src/runtime/agent-runtime-detector.js +23 -12
  57. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +34 -0
  58. package/dist-electron/shared/desktop.js +4 -2
  59. package/package.json +2 -1
  60. package/dist/renderer/assets/Workspace-Cftl8zps.js +0 -14
  61. package/dist/renderer/assets/desktop-D4Z7M9RM.js +0 -3
  62. package/dist/renderer/assets/projects-DcNm9FDK.js +0 -1
@@ -585,7 +585,8 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
585
585
  return { paired: true, threadId };
586
586
  }
587
587
  this.options.store.updatePlatformThreadMessageId(input.workspaceId, input.chatId, input.platformUserId, input.contextToken || input.messageId, 'weixin');
588
- await router.sendThreadMessage(threadId, (0, desktop_js_1.wrapUserMessageWithSchedulerProtocol)(input.text));
588
+ const wrappedText = (0, desktop_js_1.wrapUserMessageWithSchedulerProtocol)(input.text);
589
+ await router.sendThreadMessage(threadId, this.createThreadMessageInput(wrappedText, input.contentParts));
589
590
  return { paired: true, threadId };
590
591
  }
591
592
  // ==================== Private: Bindings ====================
@@ -799,6 +800,7 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
799
800
  const msgId = msg.msg_id ?? String(Date.now());
800
801
  // Handle attachments
801
802
  let attachmentText = '';
803
+ const attachmentParts = [];
802
804
  if (mediaItems.length > 0) {
803
805
  const uploadsDir = node_path_1.default.join(binding.stateDir, 'weixin-uploads');
804
806
  for (const [idx, item] of mediaItems.entries()) {
@@ -807,6 +809,14 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
807
809
  if (att) {
808
810
  attachmentText += attachmentText ? '\n' : '';
809
811
  attachmentText += att.kind === 'image' ? `[Image: ${att.path}]` : `[File "${att.name}": ${att.path}]`;
812
+ if (att.kind === 'image' && att.data) {
813
+ attachmentParts.push({
814
+ type: 'image',
815
+ data: att.data,
816
+ mimeType: att.mimeType,
817
+ fileName: att.name,
818
+ });
819
+ }
810
820
  }
811
821
  }
812
822
  catch (dlErr) {
@@ -825,6 +835,10 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
825
835
  text: fullText,
826
836
  messageId: msgId,
827
837
  contextToken: msg.context_token,
838
+ contentParts: [
839
+ ...(text ? [{ type: 'text', text }] : []),
840
+ ...attachmentParts,
841
+ ],
828
842
  });
829
843
  }
830
844
  }
@@ -991,7 +1005,41 @@ class LocalCoreWeixinGateway extends node_events_1.EventEmitter {
991
1005
  const filePath = node_path_1.default.join(uploadsDir, fileName);
992
1006
  node_fs_1.default.mkdirSync(uploadsDir, { recursive: true });
993
1007
  node_fs_1.default.writeFileSync(filePath, resultBuf);
994
- return { path: filePath, kind, name: declaredName };
1008
+ return {
1009
+ path: filePath,
1010
+ kind,
1011
+ name: declaredName,
1012
+ data: kind === 'image' ? resultBuf.toString('base64') : undefined,
1013
+ mimeType: kind === 'image' ? this.mimeTypeForImageExt(ext) : undefined,
1014
+ };
1015
+ }
1016
+ createWrappedContentParts(wrappedText, parts) {
1017
+ const nonTextParts = Array.isArray(parts)
1018
+ ? parts.filter((part) => part.type !== 'text')
1019
+ : [];
1020
+ return [
1021
+ { type: 'text', text: wrappedText },
1022
+ ...nonTextParts,
1023
+ ];
1024
+ }
1025
+ createThreadMessageInput(wrappedText, parts) {
1026
+ const hasNonTextPart = Array.isArray(parts) && parts.some((part) => part.type !== 'text');
1027
+ if (!hasNonTextPart) {
1028
+ return wrappedText;
1029
+ }
1030
+ return {
1031
+ displayText: wrappedText,
1032
+ contentParts: this.createWrappedContentParts(wrappedText, parts),
1033
+ };
1034
+ }
1035
+ mimeTypeForImageExt(ext) {
1036
+ if (ext === '.jpg')
1037
+ return 'image/jpeg';
1038
+ if (ext === '.png')
1039
+ return 'image/png';
1040
+ if (ext === '.gif')
1041
+ return 'image/gif';
1042
+ return 'application/octet-stream';
995
1043
  }
996
1044
  // ==================== Private: Turn State ====================
997
1045
  createTurnState(sessionKey) {
@@ -35,7 +35,7 @@ function bootstrapLocalCoreKernel(options) {
35
35
  const lifecycle = new lifecycle_manager_js_1.LocalCoreLifecycleManager(plugins, context);
36
36
  const diagnostics = new diagnostics_js_1.LocalCoreDiagnostics(plugins, lifecycle);
37
37
  const builtIns = [
38
- ...['codex', 'cursor', 'gemini', 'qoder', 'iflow'].map((agentType) => (0, agent_localcore_acp_plugin_js_1.createBuiltinStaticAgentCapabilityPlugin)(agentType)),
38
+ ...['cursor', 'gemini', 'qoder', 'iflow'].map((agentType) => (0, agent_localcore_acp_plugin_js_1.createBuiltinStaticAgentCapabilityPlugin)(agentType)),
39
39
  (0, agent_localcore_acp_plugin_js_1.createBuiltinLocalCoreAcpAgentPlugin)(),
40
40
  (0, scheduler_cron_plugin_js_1.createBuiltinCronSchedulerPlugin)(),
41
41
  ];
@@ -164,6 +164,7 @@ function bootstrapLocalCoreRuntime(options) {
164
164
  const agentPlugins = [
165
165
  localCoreAgentPlugin,
166
166
  (0, agent_localcore_acp_plugin_js_1.createBuiltinOpencodeAgentPlugin)(),
167
+ (0, agent_localcore_acp_plugin_js_1.createBuiltinCodexAgentPlugin)(),
167
168
  (0, agent_localcore_acp_plugin_js_1.createBuiltinClaudeCodeAgentPlugin)(),
168
169
  ];
169
170
  let workspaceRouter;
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBuiltinLocalCoreAcpAgentPlugin = createBuiltinLocalCoreAcpAgentPlugin;
4
4
  exports.createBuiltinOpencodeAgentPlugin = createBuiltinOpencodeAgentPlugin;
5
+ exports.createBuiltinCodexAgentPlugin = createBuiltinCodexAgentPlugin;
5
6
  exports.createBuiltinClaudeCodeAgentPlugin = createBuiltinClaudeCodeAgentPlugin;
6
7
  exports.createBuiltinStaticAgentCapabilityPlugin = createBuiltinStaticAgentCapabilityPlugin;
7
8
  const desktop_js_1 = require("../../../../../shared/desktop.js");
@@ -85,6 +86,14 @@ function createBuiltinOpencodeAgentPlugin() {
85
86
  displayName: 'OpenCode',
86
87
  });
87
88
  }
89
+ function createBuiltinCodexAgentPlugin() {
90
+ return createBuiltinAgentPlugin({
91
+ pluginId: 'builtin.agent-codex',
92
+ agentType: 'codex',
93
+ match: (normalizedAgentType) => normalizedAgentType === 'codex',
94
+ displayName: 'Codex',
95
+ });
96
+ }
88
97
  function createBuiltinClaudeCodeAgentPlugin() {
89
98
  return createBuiltinAgentPlugin({
90
99
  pluginId: 'builtin.agent-claudecode',
@@ -150,22 +150,28 @@ function shouldUseOpenAiCompatibleProvider(providerId) {
150
150
  ]);
151
151
  return !builtInNonCompatibleProviders.has(providerId);
152
152
  }
153
- function resolveBundledClaudeCodeCommand() {
153
+ function resolveBundledAcpCommand(packageName, binName) {
154
154
  const require = (0, node_module_1.createRequire)(__filename);
155
- const packageJsonPath = require.resolve(`${desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE}/package.json`);
155
+ const packageJsonPath = require.resolve(`${packageName}/package.json`);
156
156
  const packageJson = require(packageJsonPath);
157
157
  const binField = packageJson.bin;
158
158
  const relativeBinPath = typeof binField === 'string'
159
159
  ? binField
160
- : binField?.['claude-agent-acp'];
160
+ : binField?.[binName];
161
161
  if (!relativeBinPath) {
162
- throw new Error(`Bundled package "${desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE}" does not declare the claude-agent-acp bin.`);
162
+ throw new Error(`Bundled package "${packageName}" does not declare the ${binName} bin.`);
163
163
  }
164
164
  return {
165
165
  command: process.execPath,
166
166
  args: [(0, node_path_1.resolve)((0, node_path_1.dirname)(packageJsonPath), relativeBinPath)],
167
167
  };
168
168
  }
169
+ function resolveBundledCodexCommand() {
170
+ return resolveBundledAcpCommand(desktop_js_1.DESKTOP_CODEX_ACP_PACKAGE, 'codex-acp');
171
+ }
172
+ function resolveBundledClaudeCodeCommand() {
173
+ return resolveBundledAcpCommand(desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE, 'claude-agent-acp');
174
+ }
169
175
  function toLocalCoreProjectConfig(configState, project) {
170
176
  const rawWorkDir = String(project.agent?.options?.work_dir || '.').trim() || '.';
171
177
  const configDir = (0, node_path_1.dirname)(configState.path);
@@ -198,21 +204,26 @@ function toLocalCoreProjectConfig(configState, project) {
198
204
  ANTHROPIC_MODEL: model,
199
205
  }
200
206
  : {};
207
+ const bundledCodex = agentType === 'codex'
208
+ ? resolveBundledCodexCommand()
209
+ : null;
201
210
  const bundledClaudeCode = agentType === 'claudecode'
202
211
  ? resolveBundledClaudeCodeCommand()
203
212
  : null;
204
213
  const inferredCommand = agentType === 'opencode'
205
214
  ? 'opencode'
206
- : bundledClaudeCode?.command || '';
215
+ : bundledCodex?.command || bundledClaudeCode?.command || '';
207
216
  const command = String(project.agent?.options?.command || inferredCommand).trim();
208
217
  if (!command) {
209
218
  throw new Error(`Workspace "${project.name}" requires [projects.agent.options].command for Local AI Core ACP execution.`);
210
219
  }
211
220
  const defaultArgs = agentType === 'opencode'
212
221
  ? ['acp']
213
- : agentType === 'claudecode'
214
- ? [...(bundledClaudeCode?.args || [])]
215
- : [];
222
+ : agentType === 'codex'
223
+ ? [...(bundledCodex?.args || [])]
224
+ : agentType === 'claudecode'
225
+ ? [...(bundledClaudeCode?.args || [])]
226
+ : [];
216
227
  return {
217
228
  workspaceId: project.name,
218
229
  agentType,
@@ -18,7 +18,7 @@ const DISPLAY_NAMES = {
18
18
  };
19
19
  const COMMAND_CANDIDATES = {
20
20
  opencode: ['opencode'],
21
- codex: ['codex'],
21
+ codex: ['codex-acp', 'codex'],
22
22
  claudecode: ['claude-agent-acp'],
23
23
  cursor: ['cursor-agent', 'cursor'],
24
24
  gemini: ['gemini'],
@@ -61,8 +61,14 @@ function detectInstalledAgentRuntimes(options = {}) {
61
61
  ? installedRuntime(agentType, resolved, 'config', detectedAt, env, versionTimeoutMs)
62
62
  : missingRuntime(agentType, detectedAt, `Configured command not found: ${configured}`);
63
63
  }
64
- if (agentType === 'claudecode') {
65
- const bundled = resolveBundledClaudeAgentAcp(options.requireFrom);
64
+ if (agentType === 'codex' || agentType === 'claudecode') {
65
+ const bundled = agentType === 'codex'
66
+ ? resolveBundledAcpPackage(options.requireFrom, desktop_js_1.DESKTOP_CODEX_ACP_PACKAGE, ['bin/codex-acp.js'])
67
+ : resolveBundledAcpPackage(options.requireFrom, desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE, [
68
+ 'dist/cli.js',
69
+ 'bin/claude-agent-acp.js',
70
+ 'cli.js',
71
+ ]);
66
72
  if (bundled) {
67
73
  return installedRuntime(agentType, bundled, 'bundled', detectedAt, env, versionTimeoutMs);
68
74
  }
@@ -215,18 +221,23 @@ function parseVersionOutput(output) {
215
221
  const match = text.match(/\d+(?:\.\d+)+(?:[-+._a-zA-Z0-9]*)?/);
216
222
  return match?.[0] || text || undefined;
217
223
  }
218
- function resolveBundledClaudeAgentAcp(requireFrom) {
224
+ function resolveBundledAcpPackage(requireFrom, packageName, candidates) {
219
225
  try {
220
226
  const require = (0, node_module_1.createRequire)(requireFrom || (0, node_path_1.join)(process.cwd(), 'package.json'));
221
- const packageJsonPath = require.resolve(`${desktop_js_1.DESKTOP_CLAUDECODE_ACP_PACKAGE}/package.json`);
227
+ const packageJsonPath = require.resolve(`${packageName}/package.json`);
222
228
  const packageDir = (0, node_path_1.dirname)(packageJsonPath);
223
- for (const candidate of [
224
- (0, node_path_1.join)(packageDir, 'dist', 'cli.js'),
225
- (0, node_path_1.join)(packageDir, 'bin', 'claude-agent-acp.js'),
226
- (0, node_path_1.join)(packageDir, 'cli.js'),
227
- ]) {
228
- if ((0, node_fs_1.existsSync)(candidate)) {
229
- return candidate;
229
+ const packageJson = require(packageJsonPath);
230
+ const binField = packageJson.bin;
231
+ if (typeof binField === 'string') {
232
+ candidates = [binField, ...candidates];
233
+ }
234
+ else if (binField && typeof binField === 'object') {
235
+ candidates = [...Object.values(binField), ...candidates];
236
+ }
237
+ for (const candidate of candidates) {
238
+ const candidatePath = (0, node_path_1.join)(packageDir, candidate);
239
+ if ((0, node_fs_1.existsSync)(candidatePath)) {
240
+ return candidatePath;
230
241
  }
231
242
  }
232
243
  return packageJsonPath;
@@ -17,6 +17,8 @@ class LocalCoreController extends node_events_1.EventEmitter {
17
17
  runtime;
18
18
  runtimeDetection;
19
19
  busUnsubscribers = [];
20
+ pendingLogs = [];
21
+ handlingLog = false;
20
22
  constructor(userDataPath, runtime) {
21
23
  super();
22
24
  this.userDataPath = userDataPath;
@@ -38,6 +40,7 @@ class LocalCoreController extends node_events_1.EventEmitter {
38
40
  log: (message) => this.handleLog(message),
39
41
  emit: (event) => this.handleRuntimeDetectionEvent(event),
40
42
  });
43
+ this.flushPendingLogs();
41
44
  this.busUnsubscribers.push(this.kernel.context.bus.on('platform.bridge.updated', (event) => {
42
45
  this.emit('bridge', event);
43
46
  }), this.kernel.context.bus.on('scheduler.job.updated', (job) => {
@@ -382,8 +385,39 @@ class LocalCoreController extends node_events_1.EventEmitter {
382
385
  this.emit('runtime', await this.getRuntimeStatus());
383
386
  }
384
387
  handleLog(message) {
388
+ if (this.handlingLog) {
389
+ return;
390
+ }
391
+ const state = this.state;
392
+ if (!state) {
393
+ this.pendingLogs.push(message);
394
+ this.emit('logs', message);
395
+ return;
396
+ }
397
+ this.handlingLog = true;
398
+ try {
399
+ state.pushLog?.(message);
400
+ }
401
+ finally {
402
+ this.handlingLog = false;
403
+ }
385
404
  this.emit('logs', message);
386
405
  }
406
+ flushPendingLogs() {
407
+ if (this.pendingLogs.length === 0) {
408
+ return;
409
+ }
410
+ const logs = this.pendingLogs.splice(0);
411
+ this.handlingLog = true;
412
+ try {
413
+ for (const message of logs) {
414
+ this.state.pushLog?.(message);
415
+ }
416
+ }
417
+ finally {
418
+ this.handlingLog = false;
419
+ }
420
+ }
387
421
  resolveChannelRuntime(platform) {
388
422
  if (platform === this.channelRuntime.platform) {
389
423
  return this.channelRuntime;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SCHEDULER_PROTOCOL_INSTRUCTION = exports.LOCALCORE_ACP_AGENT_TYPE = exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = exports.DESKTOP_PROVIDER_THINKING_OPTIONS = exports.DESKTOP_PROVIDER_PRESET_OPTIONS = exports.DESKTOP_PLATFORM_TYPE_OPTIONS = exports.DESKTOP_AGENT_TYPE_OPTIONS = exports.DESKTOP_LARK_SDK_PACKAGE = exports.DESKTOP_CLAUDECODE_ACP_PACKAGE = exports.DEFAULT_DESKTOP_CLAUDECODE_MODEL = exports.DEFAULT_DESKTOP_OPENCODE_MODEL = exports.DEFAULT_DESKTOP_AGENT_TYPE = void 0;
3
+ exports.SCHEDULER_PROTOCOL_INSTRUCTION = exports.LOCALCORE_ACP_AGENT_TYPE = exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = exports.DESKTOP_PROVIDER_THINKING_OPTIONS = exports.DESKTOP_PROVIDER_PRESET_OPTIONS = exports.DESKTOP_PLATFORM_TYPE_OPTIONS = exports.DESKTOP_AGENT_TYPE_OPTIONS = exports.DESKTOP_LARK_SDK_PACKAGE = exports.DESKTOP_CLAUDECODE_ACP_PACKAGE = exports.DESKTOP_CODEX_ACP_PACKAGE = exports.DEFAULT_DESKTOP_CLAUDECODE_MODEL = exports.DEFAULT_DESKTOP_OPENCODE_MODEL = exports.DEFAULT_DESKTOP_AGENT_TYPE = void 0;
4
4
  exports.deriveDesktopRuntimePhase = deriveDesktopRuntimePhase;
5
5
  exports.deriveDesktopRuntimeRoles = deriveDesktopRuntimeRoles;
6
6
  exports.normalizeDesktopPlatformType = normalizeDesktopPlatformType;
@@ -15,6 +15,7 @@ exports.isAcpAgentType = isAcpAgentType;
15
15
  exports.DEFAULT_DESKTOP_AGENT_TYPE = 'opencode';
16
16
  exports.DEFAULT_DESKTOP_OPENCODE_MODEL = 'opencode/minimax-m2.5-free';
17
17
  exports.DEFAULT_DESKTOP_CLAUDECODE_MODEL = '';
18
+ exports.DESKTOP_CODEX_ACP_PACKAGE = '@zed-industries/codex-acp';
18
19
  exports.DESKTOP_CLAUDECODE_ACP_PACKAGE = '@agentclientprotocol/claude-agent-acp';
19
20
  exports.DESKTOP_LARK_SDK_PACKAGE = '@larksuiteoapi/node-sdk';
20
21
  exports.DESKTOP_AGENT_TYPE_OPTIONS = [
@@ -52,7 +53,7 @@ exports.DESKTOP_PROVIDER_PRESET_OPTIONS = [
52
53
  'ollama',
53
54
  ];
54
55
  exports.DESKTOP_PROVIDER_THINKING_OPTIONS = ['', 'enabled', 'disabled'];
55
- exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = ['opencode', 'claudecode', 'acp', 'localcore-acp'];
56
+ exports.DESKTOP_INTERACTIVE_PERMISSION_AGENT_TYPES = ['opencode', 'codex', 'claudecode', 'acp', 'localcore-acp'];
56
57
  exports.LOCALCORE_ACP_AGENT_TYPE = 'localcore-acp';
57
58
  exports.SCHEDULER_PROTOCOL_INSTRUCTION = [
58
59
  '[Scheduler Tools]',
@@ -190,6 +191,7 @@ function isAcpAgentType(agentType) {
190
191
  const normalized = String(agentType || '').trim().toLowerCase();
191
192
  return normalized === 'acp'
192
193
  || normalized === 'opencode'
194
+ || normalized === 'codex'
193
195
  || normalized === 'claudecode'
194
196
  || normalized === exports.LOCALCORE_ACP_AGENT_TYPE;
195
197
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kafca/agentdock",
3
- "version": "0.1.19",
3
+ "version": "0.1.21",
4
4
  "type": "module",
5
5
  "main": "dist-electron/electron/main.js",
6
6
  "bin": {
@@ -49,6 +49,7 @@
49
49
  "@radix-ui/react-select": "^2.2.6",
50
50
  "@radix-ui/react-slot": "^1.2.4",
51
51
  "@tailwindcss/typography": "^0.5.19",
52
+ "@zed-industries/codex-acp": "^0.12.0",
52
53
  "clsx": "^2.1.1",
53
54
  "highlight.js": "^11.11.1",
54
55
  "i18next": "^25.1.2",
@@ -1,14 +0,0 @@
1
- import{c as tt,x as S,t as rt,r as A,j as a,B as I,I as T,S as st}from"./index-tQ6A4Zff.js";import{M as De}from"./Modal-D6ucs8W2.js";import{S as ae}from"./Select-CEsAkZ5j.js";import{E as he}from"./EmptyState-DVYGGFl9.js";import{P as nt,S as Oe,a as at}from"./Page-BdF9afpu.js";import{c as ot,d as Te,e as it,f as lt}from"./desktop-DTAjgvNs.js";import{D as me,c as Qe,g as fe,d as ct,e as dt}from"./desktop-D4Z7M9RM.js";import{T as ge}from"./trash-2-BQpE15-6.js";import{P as ee}from"./plus-DrYsrZyx.js";import{S as ze}from"./save-C8W3Wq2Z.js";import"./index-BbDTSo1y.js";import"./check-CfewkzaJ.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 ut=[["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"}]],ht=tt("qr-code",ut);var mt=Object.defineProperty,ie=Object.getOwnPropertySymbols,$e=Object.prototype.hasOwnProperty,He=Object.prototype.propertyIsEnumerable,Le=(c,d,o)=>d in c?mt(c,d,{enumerable:!0,configurable:!0,writable:!0,value:o}):c[d]=o,xe=(c,d)=>{for(var o in d||(d={}))$e.call(d,o)&&Le(c,o,d[o]);if(ie)for(var o of ie(d))He.call(d,o)&&Le(c,o,d[o]);return c},ve=(c,d)=>{var o={};for(var h in c)$e.call(c,h)&&d.indexOf(h)<0&&(o[h]=c[h]);if(c!=null&&ie)for(var h of ie(c))d.indexOf(h)<0&&He.call(c,h)&&(o[h]=c[h]);return o};/**
7
- * @license QR Code generator library (TypeScript)
8
- * Copyright (c) Project Nayuki.
9
- * SPDX-License-Identifier: MIT
10
- */var W;(c=>{const d=class C{constructor(e,r,t,n){if(this.version=e,this.errorCorrectionLevel=r,this.modules=[],this.isFunction=[],e<C.MIN_VERSION||e>C.MAX_VERSION)throw new RangeError("Version value out of range");if(n<-1||n>7)throw new RangeError("Mask value out of range");this.size=e*4+17;let l=[];for(let m=0;m<this.size;m++)l.push(!1);for(let m=0;m<this.size;m++)this.modules.push(l.slice()),this.isFunction.push(l.slice());this.drawFunctionPatterns();const u=this.addEccAndInterleave(t);if(this.drawCodewords(u),n==-1){let m=1e9;for(let g=0;g<8;g++){this.applyMask(g),this.drawFormatBits(g);const p=this.getPenaltyScore();p<m&&(n=g,m=p),this.applyMask(g)}}x(0<=n&&n<=7),this.mask=n,this.applyMask(n),this.drawFormatBits(n),this.isFunction=[]}static encodeText(e,r){const t=c.QrSegment.makeSegments(e);return C.encodeSegments(t,r)}static encodeBinary(e,r){const t=c.QrSegment.makeBytes(e);return C.encodeSegments([t],r)}static encodeSegments(e,r,t=1,n=40,l=-1,u=!0){if(!(C.MIN_VERSION<=t&&t<=n&&n<=C.MAX_VERSION)||l<-1||l>7)throw new RangeError("Invalid value");let m,g;for(m=t;;m++){const w=C.getNumDataCodewords(m,r)*8,N=M.getTotalBits(e,m);if(N<=w){g=N;break}if(m>=n)throw new RangeError("Data too long")}for(const w of[C.Ecc.MEDIUM,C.Ecc.QUARTILE,C.Ecc.HIGH])u&&g<=C.getNumDataCodewords(m,w)*8&&(r=w);let p=[];for(const w of e){o(w.mode.modeBits,4,p),o(w.numChars,w.mode.numCharCountBits(m),p);for(const N of w.getData())p.push(N)}x(p.length==g);const R=C.getNumDataCodewords(m,r)*8;x(p.length<=R),o(0,Math.min(4,R-p.length),p),o(0,(8-p.length%8)%8,p),x(p.length%8==0);for(let w=236;p.length<R;w^=253)o(w,8,p);let k=[];for(;k.length*8<p.length;)k.push(0);return p.forEach((w,N)=>k[N>>>3]|=w<<7-(N&7)),new C(m,r,k,l)}getModule(e,r){return 0<=e&&e<this.size&&0<=r&&r<this.size&&this.modules[r][e]}getModules(){return this.modules}drawFunctionPatterns(){for(let t=0;t<this.size;t++)this.setFunctionModule(6,t,t%2==0),this.setFunctionModule(t,6,t%2==0);this.drawFinderPattern(3,3),this.drawFinderPattern(this.size-4,3),this.drawFinderPattern(3,this.size-4);const e=this.getAlignmentPatternPositions(),r=e.length;for(let t=0;t<r;t++)for(let n=0;n<r;n++)t==0&&n==0||t==0&&n==r-1||t==r-1&&n==0||this.drawAlignmentPattern(e[t],e[n]);this.drawFormatBits(0),this.drawVersion()}drawFormatBits(e){const r=this.errorCorrectionLevel.formatBits<<3|e;let t=r;for(let l=0;l<10;l++)t=t<<1^(t>>>9)*1335;const n=(r<<10|t)^21522;x(n>>>15==0);for(let l=0;l<=5;l++)this.setFunctionModule(8,l,h(n,l));this.setFunctionModule(8,7,h(n,6)),this.setFunctionModule(8,8,h(n,7)),this.setFunctionModule(7,8,h(n,8));for(let l=9;l<15;l++)this.setFunctionModule(14-l,8,h(n,l));for(let l=0;l<8;l++)this.setFunctionModule(this.size-1-l,8,h(n,l));for(let l=8;l<15;l++)this.setFunctionModule(8,this.size-15+l,h(n,l));this.setFunctionModule(8,this.size-8,!0)}drawVersion(){if(this.version<7)return;let e=this.version;for(let t=0;t<12;t++)e=e<<1^(e>>>11)*7973;const r=this.version<<12|e;x(r>>>18==0);for(let t=0;t<18;t++){const n=h(r,t),l=this.size-11+t%3,u=Math.floor(t/3);this.setFunctionModule(l,u,n),this.setFunctionModule(u,l,n)}}drawFinderPattern(e,r){for(let t=-4;t<=4;t++)for(let n=-4;n<=4;n++){const l=Math.max(Math.abs(n),Math.abs(t)),u=e+n,m=r+t;0<=u&&u<this.size&&0<=m&&m<this.size&&this.setFunctionModule(u,m,l!=2&&l!=4)}}drawAlignmentPattern(e,r){for(let t=-2;t<=2;t++)for(let n=-2;n<=2;n++)this.setFunctionModule(e+n,r+t,Math.max(Math.abs(n),Math.abs(t))!=1)}setFunctionModule(e,r,t){this.modules[r][e]=t,this.isFunction[r][e]=!0}addEccAndInterleave(e){const r=this.version,t=this.errorCorrectionLevel;if(e.length!=C.getNumDataCodewords(r,t))throw new RangeError("Invalid argument");const n=C.NUM_ERROR_CORRECTION_BLOCKS[t.ordinal][r],l=C.ECC_CODEWORDS_PER_BLOCK[t.ordinal][r],u=Math.floor(C.getNumRawDataModules(r)/8),m=n-u%n,g=Math.floor(u/n);let p=[];const R=C.reedSolomonComputeDivisor(l);for(let w=0,N=0;w<n;w++){let _=e.slice(N,N+g-l+(w<m?0:1));N+=_.length;const $=C.reedSolomonComputeRemainder(_,R);w<m&&_.push(0),p.push(_.concat($))}let k=[];for(let w=0;w<p[0].length;w++)p.forEach((N,_)=>{(w!=g-l||_>=m)&&k.push(N[w])});return x(k.length==u),k}drawCodewords(e){if(e.length!=Math.floor(C.getNumRawDataModules(this.version)/8))throw new RangeError("Invalid argument");let r=0;for(let t=this.size-1;t>=1;t-=2){t==6&&(t=5);for(let n=0;n<this.size;n++)for(let l=0;l<2;l++){const u=t-l,g=(t+1&2)==0?this.size-1-n:n;!this.isFunction[g][u]&&r<e.length*8&&(this.modules[g][u]=h(e[r>>>3],7-(r&7)),r++)}}x(r==e.length*8)}applyMask(e){if(e<0||e>7)throw new RangeError("Mask value out of range");for(let r=0;r<this.size;r++)for(let t=0;t<this.size;t++){let n;switch(e){case 0:n=(t+r)%2==0;break;case 1:n=r%2==0;break;case 2:n=t%3==0;break;case 3:n=(t+r)%3==0;break;case 4:n=(Math.floor(t/3)+Math.floor(r/2))%2==0;break;case 5:n=t*r%2+t*r%3==0;break;case 6:n=(t*r%2+t*r%3)%2==0;break;case 7:n=((t+r)%2+t*r%3)%2==0;break;default:throw new Error("Unreachable")}!this.isFunction[r][t]&&n&&(this.modules[r][t]=!this.modules[r][t])}}getPenaltyScore(){let e=0;for(let l=0;l<this.size;l++){let u=!1,m=0,g=[0,0,0,0,0,0,0];for(let p=0;p<this.size;p++)this.modules[l][p]==u?(m++,m==5?e+=C.PENALTY_N1:m>5&&e++):(this.finderPenaltyAddHistory(m,g),u||(e+=this.finderPenaltyCountPatterns(g)*C.PENALTY_N3),u=this.modules[l][p],m=1);e+=this.finderPenaltyTerminateAndCount(u,m,g)*C.PENALTY_N3}for(let l=0;l<this.size;l++){let u=!1,m=0,g=[0,0,0,0,0,0,0];for(let p=0;p<this.size;p++)this.modules[p][l]==u?(m++,m==5?e+=C.PENALTY_N1:m>5&&e++):(this.finderPenaltyAddHistory(m,g),u||(e+=this.finderPenaltyCountPatterns(g)*C.PENALTY_N3),u=this.modules[p][l],m=1);e+=this.finderPenaltyTerminateAndCount(u,m,g)*C.PENALTY_N3}for(let l=0;l<this.size-1;l++)for(let u=0;u<this.size-1;u++){const m=this.modules[l][u];m==this.modules[l][u+1]&&m==this.modules[l+1][u]&&m==this.modules[l+1][u+1]&&(e+=C.PENALTY_N2)}let r=0;for(const l of this.modules)r=l.reduce((u,m)=>u+(m?1:0),r);const t=this.size*this.size,n=Math.ceil(Math.abs(r*20-t*10)/t)-1;return x(0<=n&&n<=9),e+=n*C.PENALTY_N4,x(0<=e&&e<=2568888),e}getAlignmentPatternPositions(){if(this.version==1)return[];{const e=Math.floor(this.version/7)+2,r=this.version==32?26:Math.ceil((this.version*4+4)/(e*2-2))*2;let t=[6];for(let n=this.size-7;t.length<e;n-=r)t.splice(1,0,n);return t}}static getNumRawDataModules(e){if(e<C.MIN_VERSION||e>C.MAX_VERSION)throw new RangeError("Version number out of range");let r=(16*e+128)*e+64;if(e>=2){const t=Math.floor(e/7)+2;r-=(25*t-10)*t-55,e>=7&&(r-=36)}return x(208<=r&&r<=29648),r}static getNumDataCodewords(e,r){return Math.floor(C.getNumRawDataModules(e)/8)-C.ECC_CODEWORDS_PER_BLOCK[r.ordinal][e]*C.NUM_ERROR_CORRECTION_BLOCKS[r.ordinal][e]}static reedSolomonComputeDivisor(e){if(e<1||e>255)throw new RangeError("Degree out of range");let r=[];for(let n=0;n<e-1;n++)r.push(0);r.push(1);let t=1;for(let n=0;n<e;n++){for(let l=0;l<r.length;l++)r[l]=C.reedSolomonMultiply(r[l],t),l+1<r.length&&(r[l]^=r[l+1]);t=C.reedSolomonMultiply(t,2)}return r}static reedSolomonComputeRemainder(e,r){let t=r.map(n=>0);for(const n of e){const l=n^t.shift();t.push(0),r.forEach((u,m)=>t[m]^=C.reedSolomonMultiply(u,l))}return t}static reedSolomonMultiply(e,r){if(e>>>8||r>>>8)throw new RangeError("Byte out of range");let t=0;for(let n=7;n>=0;n--)t=t<<1^(t>>>7)*285,t^=(r>>>n&1)*e;return x(t>>>8==0),t}finderPenaltyCountPatterns(e){const r=e[1];x(r<=this.size*3);const t=r>0&&e[2]==r&&e[3]==r*3&&e[4]==r&&e[5]==r;return(t&&e[0]>=r*4&&e[6]>=r?1:0)+(t&&e[6]>=r*4&&e[0]>=r?1:0)}finderPenaltyTerminateAndCount(e,r,t){return e&&(this.finderPenaltyAddHistory(r,t),r=0),r+=this.size,this.finderPenaltyAddHistory(r,t),this.finderPenaltyCountPatterns(t)}finderPenaltyAddHistory(e,r){r[0]==0&&(e+=this.size),r.pop(),r.unshift(e)}};d.MIN_VERSION=1,d.MAX_VERSION=40,d.PENALTY_N1=3,d.PENALTY_N2=3,d.PENALTY_N3=40,d.PENALTY_N4=10,d.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]],d.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]],c.QrCode=d;function o(E,e,r){if(e<0||e>31||E>>>e)throw new RangeError("Value out of range");for(let t=e-1;t>=0;t--)r.push(E>>>t&1)}function h(E,e){return(E>>>e&1)!=0}function x(E){if(!E)throw new Error("Assertion error")}const v=class P{constructor(e,r,t){if(this.mode=e,this.numChars=r,this.bitData=t,r<0)throw new RangeError("Invalid argument");this.bitData=t.slice()}static makeBytes(e){let r=[];for(const t of e)o(t,8,r);return new P(P.Mode.BYTE,e.length,r)}static makeNumeric(e){if(!P.isNumeric(e))throw new RangeError("String contains non-numeric characters");let r=[];for(let t=0;t<e.length;){const n=Math.min(e.length-t,3);o(parseInt(e.substring(t,t+n),10),n*3+1,r),t+=n}return new P(P.Mode.NUMERIC,e.length,r)}static makeAlphanumeric(e){if(!P.isAlphanumeric(e))throw new RangeError("String contains unencodable characters in alphanumeric mode");let r=[],t;for(t=0;t+2<=e.length;t+=2){let n=P.ALPHANUMERIC_CHARSET.indexOf(e.charAt(t))*45;n+=P.ALPHANUMERIC_CHARSET.indexOf(e.charAt(t+1)),o(n,11,r)}return t<e.length&&o(P.ALPHANUMERIC_CHARSET.indexOf(e.charAt(t)),6,r),new P(P.Mode.ALPHANUMERIC,e.length,r)}static makeSegments(e){return e==""?[]:P.isNumeric(e)?[P.makeNumeric(e)]:P.isAlphanumeric(e)?[P.makeAlphanumeric(e)]:[P.makeBytes(P.toUtf8ByteArray(e))]}static makeEci(e){let r=[];if(e<0)throw new RangeError("ECI assignment value out of range");if(e<128)o(e,8,r);else if(e<16384)o(2,2,r),o(e,14,r);else if(e<1e6)o(6,3,r),o(e,21,r);else throw new RangeError("ECI assignment value out of range");return new P(P.Mode.ECI,0,r)}static isNumeric(e){return P.NUMERIC_REGEX.test(e)}static isAlphanumeric(e){return P.ALPHANUMERIC_REGEX.test(e)}getData(){return this.bitData.slice()}static getTotalBits(e,r){let t=0;for(const n of e){const l=n.mode.numCharCountBits(r);if(n.numChars>=1<<l)return 1/0;t+=4+l+n.bitData.length}return t}static toUtf8ByteArray(e){e=encodeURI(e);let r=[];for(let t=0;t<e.length;t++)e.charAt(t)!="%"?r.push(e.charCodeAt(t)):(r.push(parseInt(e.substring(t+1,t+3),16)),t+=2);return r}};v.NUMERIC_REGEX=/^[0-9]*$/,v.ALPHANUMERIC_REGEX=/^[A-Z0-9 $%*+.\/:-]*$/,v.ALPHANUMERIC_CHARSET="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:";let M=v;c.QrSegment=v})(W||(W={}));(c=>{(d=>{const o=class{constructor(x,v){this.ordinal=x,this.formatBits=v}};o.LOW=new o(0,1),o.MEDIUM=new o(1,0),o.QUARTILE=new o(2,3),o.HIGH=new o(3,2),d.Ecc=o})(c.QrCode||(c.QrCode={}))})(W||(W={}));(c=>{(d=>{const o=class{constructor(x,v){this.modeBits=x,this.numBitsCharCount=v}numCharCountBits(x){return this.numBitsCharCount[Math.floor((x+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]),d.Mode=o})(c.QrSegment||(c.QrSegment={}))})(W||(W={}));var K=W;/**
11
- * @license qrcode.react
12
- * Copyright (c) Paul O'Shannessy
13
- * SPDX-License-Identifier: ISC
14
- */var ft={L:K.QrCode.Ecc.LOW,M:K.QrCode.Ecc.MEDIUM,Q:K.QrCode.Ecc.QUARTILE,H:K.QrCode.Ecc.HIGH},Ye=128,Ge="L",We="#FFFFFF",Ve="#000000",Ke=!1,Xe=1,gt=4,pt=0,xt=.1;function qe(c,d=0){const o=[];return c.forEach(function(h,x){let v=null;h.forEach(function(M,E){if(!M&&v!==null){o.push(`M${v+d} ${x+d}h${E-v}v1H${v+d}z`),v=null;return}if(E===h.length-1){if(!M)return;v===null?o.push(`M${E+d},${x+d} h1v1H${E+d}z`):o.push(`M${v+d},${x+d} h${E+1-v}v1H${v+d}z`);return}M&&v===null&&(v=E)})}),o.join("")}function Je(c,d){return c.slice().map((o,h)=>h<d.y||h>=d.y+d.h?o:o.map((x,v)=>v<d.x||v>=d.x+d.w?x:!1))}function vt(c,d,o,h){if(h==null)return null;const x=c.length+o*2,v=Math.floor(d*xt),M=x/d,E=(h.width||v)*M,e=(h.height||v)*M,r=h.x==null?c.length/2-E/2:h.x*M,t=h.y==null?c.length/2-e/2:h.y*M,n=h.opacity==null?1:h.opacity;let l=null;if(h.excavate){let m=Math.floor(r),g=Math.floor(t),p=Math.ceil(E+r-m),R=Math.ceil(e+t-g);l={x:m,y:g,w:p,h:R}}const u=h.crossOrigin;return{x:r,y:t,h:e,w:E,excavation:l,opacity:n,crossOrigin:u}}function bt(c,d){return d!=null?Math.max(Math.floor(d),0):c?gt:pt}function Ze({value:c,level:d,minVersion:o,includeMargin:h,marginSize:x,imageSettings:v,size:M,boostLevel:E}){let e=S.useMemo(()=>{const m=(Array.isArray(c)?c:[c]).reduce((g,p)=>(g.push(...K.QrSegment.makeSegments(p)),g),[]);return K.QrCode.encodeSegments(m,ft[d],o,void 0,void 0,E)},[c,d,o,E]);const{cells:r,margin:t,numCells:n,calculatedImageSettings:l}=S.useMemo(()=>{let u=e.getModules();const m=bt(h,x),g=u.length+m*2,p=vt(u,M,m,v);return{cells:u,margin:m,numCells:g,calculatedImageSettings:p}},[e,M,v,h,x]);return{qrcode:e,margin:t,cells:r,numCells:n,calculatedImageSettings:l}}var wt=(function(){try{new Path2D().addPath(new Path2D)}catch{return!1}return!0})(),yt=S.forwardRef(function(d,o){const h=d,{value:x,size:v=Ye,level:M=Ge,bgColor:E=We,fgColor:e=Ve,includeMargin:r=Ke,minVersion:t=Xe,boostLevel:n,marginSize:l,imageSettings:u}=h,g=ve(h,["value","size","level","bgColor","fgColor","includeMargin","minVersion","boostLevel","marginSize","imageSettings"]),{style:p}=g,R=ve(g,["style"]),k=u==null?void 0:u.src,w=S.useRef(null),N=S.useRef(null),_=S.useCallback(z=>{w.current=z,typeof o=="function"?o(z):o&&(o.current=z)},[o]),[$,V]=S.useState(!1),{margin:j,cells:H,numCells:L,calculatedImageSettings:y}=Ze({value:x,level:M,minVersion:t,boostLevel:n,includeMargin:r,marginSize:l,imageSettings:u,size:v});S.useEffect(()=>{if(w.current!=null){const z=w.current,F=z.getContext("2d");if(!F)return;let Y=H;const G=N.current,se=y!=null&&G!==null&&G.complete&&G.naturalHeight!==0&&G.naturalWidth!==0;se&&y.excavation!=null&&(Y=Je(H,y.excavation));const X=window.devicePixelRatio||1;z.height=z.width=v*X;const U=v/L*X;F.scale(U,U),F.fillStyle=E,F.fillRect(0,0,L,L),F.fillStyle=e,wt?F.fill(new Path2D(qe(Y,j))):H.forEach(function(le,ce){le.forEach(function(de,ue){de&&F.fillRect(ue+j,ce+j,1,1)})}),y&&(F.globalAlpha=y.opacity),se&&F.drawImage(G,y.x+j,y.y+j,y.w,y.h)}}),S.useEffect(()=>{V(!1)},[k]);const re=xe({height:v,width:v},p);let D=null;return k!=null&&(D=S.createElement("img",{src:k,key:k,style:{display:"none"},onLoad:()=>{V(!0)},ref:N,crossOrigin:y==null?void 0:y.crossOrigin})),S.createElement(S.Fragment,null,S.createElement("canvas",xe({style:re,height:v,width:v,ref:_,role:"img"},R)),D)});yt.displayName="QRCodeCanvas";var et=S.forwardRef(function(d,o){const h=d,{value:x,size:v=Ye,level:M=Ge,bgColor:E=We,fgColor:e=Ve,includeMargin:r=Ke,minVersion:t=Xe,boostLevel:n,title:l,marginSize:u,imageSettings:m}=h,g=ve(h,["value","size","level","bgColor","fgColor","includeMargin","minVersion","boostLevel","title","marginSize","imageSettings"]),{margin:p,cells:R,numCells:k,calculatedImageSettings:w}=Ze({value:x,level:M,minVersion:t,boostLevel:n,includeMargin:r,marginSize:u,imageSettings:m,size:v});let N=R,_=null;m!=null&&w!=null&&(w.excavation!=null&&(N=Je(R,w.excavation)),_=S.createElement("image",{href:m.src,height:w.h,width:w.w,x:w.x+p,y:w.y+p,preserveAspectRatio:"none",opacity:w.opacity,crossOrigin:w.crossOrigin}));const $=qe(N,p);return S.createElement("svg",xe({height:v,width:v,viewBox:`0 0 ${k} ${k}`,ref:o,role:"img"},g),!!l&&S.createElement("title",null,l),S.createElement("path",{fill:E,d:`M0,0 h${k}v${k}H0z`,shapeRendering:"crispEdges"}),S.createElement("path",{fill:e,d:$,shapeRendering:"crispEdges"}),_)});et.displayName="QRCodeSVG";const Q="__custom__",pe=["weixin","lark"],be=[{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:"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"}];function B(c){return JSON.parse(JSON.stringify(c))}function te(c){return Array.isArray(c.projects)||(c.projects=[]),c.projects}function Ct(c){const d=new Set(c.map(h=>h.name).filter(Boolean));let o=c.length+1;for(;d.has(`project-${o}`);)o+=1;return{name:`project-${o}`,agentType:dt,workDir:"",model:""}}function oe(c){var d,o,h,x,v;return{...c,agent:{...c.agent,options:{...((d=c.agent)==null?void 0:d.options)||{},model:Qe((o=c.agent)==null?void 0:o.type,String(((x=(h=c.agent)==null?void 0:h.options)==null?void 0:x.model)||""))},providers:((v=c.agent)==null?void 0:v.providers)||[]},platforms:c.platforms||[]}}function Fe(c,d){return d.includes(c)?c:Q}function Et(c){var d;return((d=be.find(o=>c.name===o.name||o.base_url&&c.base_url===o.base_url||o.model&&c.model===o.model&&c.name===o.name))==null?void 0:d.id)||Q}function kt(c,d){const o=be.find(h=>h.id===d);return o?{...c,name:o.name,base_url:o.base_url,model:o.model}:c}function Be(c="weixin"){return{type:c,options:{}}}function Ue(c){const d=c.type==="feishu"?"lark":c.type,o=c.options&&typeof c.options=="object"?{...c.options}:{};return d==="weixin"?{type:d,options:{...o}}:d==="lark"?{type:d,options:{...o,app_id:String(o.app_id||"").trim(),app_secret:String(o.app_secret||"").trim()}}:{type:d,options:o}}function Nt(c){var d;if(c.type==="weixin")return"WeChat QR login";if(c.type==="lark"){const o=String(((d=c.options)==null?void 0:d.app_id)||"").trim();return o?`App ID ${o}`:"App ID and secret required"}return"Custom platform"}function Pt(c){var h,x;const d=String(((x=(h=c.agent)==null?void 0:h.options)==null?void 0:x.work_dir)||"").trim();return d?d.replace(/\/+$/,"").split("/").filter(Boolean).pop()||d:"No work directory"}function Mt(c){return c==="success"?"border-primary/20 bg-primary/10 text-primary dark:border-primary/25 dark:bg-primary/10 dark:text-blue-200":c==="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 Qt(){var we,ye,Ce,Ee,ke,Ne,Pe,Me,Se,je,Ae,Re,Ie,_e;const[c,d]=rt(),o=c.get("project")||"",[h,x]=A.useState(null),[v,M]=A.useState(null),[E,e]=A.useState(0),[r,t]=A.useState("basic"),[n,l]=A.useState(null),[u,m]=A.useState(null),[g,p]=A.useState(null),[R,k]=A.useState(!1),[w,N]=A.useState(!0),[_,$]=A.useState(""),[V,j]=A.useState(null),H=A.useCallback(async(s="")=>{N(!0);try{const i=await ot(),f=B(i.parsed||{});if(f.projects=te(f).map(b=>oe(b)),x(f),M(B(f)),s){const b=(f.projects||[]).findIndex(O=>O.name===s);e(b>=0?b:0)}}catch(i){j({tone:"error",message:i instanceof Error?i.message:String(i)})}finally{N(!1)}},[]);A.useEffect(()=>{H(o)},[H]);const L=(h==null?void 0:h.projects)||[],y=L[E]||null,re=JSON.stringify(h||{})!==JSON.stringify(v||{});A.useEffect(()=>{if(!h||!o)return;const s=L.findIndex(i=>i.name===o);s>=0&&s!==E&&e(s)},[h,L,o,E]);const D=A.useCallback(s=>{x(i=>{if(!i)return i;const f=B(i),b=te(f),O=b[E];return O?(b[E]=oe(s(O)),f):i})},[E]),z=A.useCallback((s,i)=>{D(f=>{const b=[...f.agent.providers||[]],O=b[s];return O?(b[s]=i(O),{...f,agent:{...f.agent,providers:b}}):f})},[D]),F=()=>{l(Ct(L))},Y=s=>{l(i=>i&&{...i,...s})},G=()=>{if(!n)return;const s=n.name.trim(),i=n.agentType.trim(),f=n.workDir.trim(),b=n.model.trim();if(!s||!i||!f){j({tone:"warning",message:"Project name, agent type, and work directory are required."});return}if(L.some(J=>J.name===s)){j({tone:"warning",message:`Project "${s}" already exists.`});return}const O=oe({name:s,agent:{type:i,options:{model:b||fe(i),work_dir:f},providers:[]},platforms:[],admin_from:"",disabled_commands:[]}),q=L.length;x(J=>{const Z=B(J||{});return te(Z).push(O),Z}),e(q),d({project:s}),l(null),j(null)},se=s=>{x(i=>{if(!i)return i;const f=B(i),b=te(f);return b.splice(s,1),e(Math.max(0,Math.min(s,b.length-1))),f})},X=s=>{var f;if(p(null),s===null){m({index:s,draft:Be()});return}const i=(f=y==null?void 0:y.platforms)==null?void 0:f[s];i&&m({index:s,draft:B(i)})},U=s=>{m(i=>i&&{...i,draft:s(i.draft)})},le=()=>{if(!u)return;const s=Ue(u.draft);D(i=>{const f=[...i.platforms||[]];return u.index===null?f.push(s):f[u.index]=s,{...i,platforms:f}}),m(null),p(null)},ce=async()=>{if(!(!(y!=null&&y.name)||!h)){k(!0);try{if(u){const i=B(h),f=te(i),b=f[E];if(b){const O=[...b.platforms||[]],q=Ue(u.draft);u.index===null?O.push(q):O[u.index]=q,f[E]=oe({...b,platforms:O});const J=await Te(i),Z=B(J.parsed||i);M(Z),x(B(Z)),m(ne=>ne&&{index:ne.index??O.length-1,draft:q})}}const s=await it(y.name);p({...s,status:"wait"}),j(null)}catch(s){j({tone:"error",message:s instanceof Error?s.message:String(s)})}finally{k(!1)}}},de=async()=>{if(!(!(y!=null&&y.name)||!(g!=null&&g.ticket))){k(!0);try{const s=await lt(y.name,g.ticket);p(i=>i&&{...i,status:s.status}),s.status==="confirmed"&&j({tone:"success",message:"WeChat QR code confirmed."})}catch(s){j({tone:"error",message:s instanceof Error?s.message:String(s)})}finally{k(!1)}}},ue=async()=>{if(h){$("config");try{const s=await Te(h);M(B(s.parsed||h)),x(B(s.parsed||h)),j({tone:"success",message:"Project changes saved."}),await H()}catch(s){j({tone:"error",message:s instanceof Error?s.message:String(s)})}finally{$("")}}};return w&&!h?a.jsx("div",{className:"flex h-64 items-center justify-center text-sm text-slate-400 animate-pulse",children:"Loading workspace..."}):a.jsxs("div",{className:"space-y-6 animate-fade-in",children:[a.jsx(nt,{title:"工作区",description:"创建项目,配置 Agent、工作目录、Provider 和平台接入。"}),V?a.jsx("div",{role:"status",className:`rounded-xl border px-4 py-3 text-sm ${Mt(V.tone)}`,children:V.message}):null,re?a.jsx("div",{className:"rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-700 dark:border-amber-400/20 dark:bg-amber-500/10 dark:text-amber-200",children:"You have unsaved project changes."}):null,a.jsxs("div",{className:"grid min-w-0 grid-cols-1 gap-4 lg:grid-cols-[340px_minmax(0,1fr)]",children:[a.jsx(Oe,{title:"项目",actions:a.jsxs(I,{size:"sm",onClick:F,children:[a.jsx(ee,{size:14})," 新建项目"]}),className:"lg:self-start",children:L.length===0?a.jsx(he,{message:"还没有项目。"}):a.jsx("div",{className:"space-y-2",children:L.map((s,i)=>{var f,b;return a.jsxs("div",{className:`flex items-center justify-between gap-2 rounded-xl border px-3 py-2 transition-colors ${i===E?"border-accent/30 bg-accent/10":"border-black/10 hover:bg-black/[0.04] dark:border-white/[0.08] dark:hover:bg-white/[0.06]"}`,children:[a.jsxs("button",{type:"button",onClick:()=>{e(i),d(s.name?{project:s.name}:{})},className:"min-w-0 flex-1 text-left",children:[a.jsx("p",{className:"truncate text-sm font-medium text-slate-950 dark:text-white",children:s.name||`Project ${i+1}`}),a.jsxs("p",{className:"mt-0.5 truncate text-xs text-muted-foreground",children:[((f=s.agent)==null?void 0:f.type)||"unknown"," · ",Pt(s)," · ",((b=s.platforms)==null?void 0:b.length)||0," platforms"]})]}),a.jsx(I,{variant:"ghost",size:"sm",onClick:()=>se(i),"aria-label":`Remove ${s.name}`,children:a.jsx(ge,{size:14})})]},`${s.name}-${i}`)})})}),a.jsx(Oe,{title:(y==null?void 0:y.name)||"Project details",description:y?a.jsxs("span",{className:"break-all",children:[((we=y.agent)==null?void 0:we.type)||"unknown"," · ",String(((Ce=(ye=y.agent)==null?void 0:ye.options)==null?void 0:Ce.work_dir)||"No work directory")]}):void 0,children:y?a.jsxs("div",{className:"space-y-6",children:[a.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","平台接入"]].map(([s,i])=>a.jsx("button",{type:"button",onClick:()=>t(s),className:`shrink-0 rounded-lg px-3 py-1.5 text-sm font-medium transition-colors ${r===s?"bg-accent text-white":"bg-black/[0.04] text-muted-foreground hover:bg-black/[0.07] hover:text-foreground dark:bg-white/[0.05] dark:hover:bg-white/[0.08]"}`,children:i},s))}),r==="basic"?a.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-2",children:[a.jsx(T,{label:"Project name",value:y.name,onChange:s=>D(i=>({...i,name:s.target.value}))}),a.jsxs(ae,{label:"Agent type",value:Fe(((Ee=y.agent)==null?void 0:Ee.type)||"",me),onChange:s=>D(i=>{var b;const f=s.target.value===Q?i.agent.type:s.target.value;return{...i,agent:{...i.agent,type:f,options:{...i.agent.options||{},model:Qe(f,String(((b=i.agent.options)==null?void 0:b.model)||""))}}}}),children:[me.map(s=>a.jsx("option",{value:s,children:s},s)),a.jsx("option",{value:Q,children:"custom"})]}),a.jsx(T,{label:"Work directory",value:String(((Ne=(ke=y.agent)==null?void 0:ke.options)==null?void 0:Ne.work_dir)||""),onChange:s=>D(i=>({...i,agent:{...i.agent,options:{...i.agent.options||{},work_dir:s.target.value}}}))}),a.jsx(T,{label:"Default model",value:String(((Me=(Pe=y.agent)==null?void 0:Pe.options)==null?void 0:Me.model)||""),onChange:s=>D(i=>({...i,agent:{...i.agent,options:{...i.agent.options||{},model:s.target.value}}})),placeholder:fe((Se=y.agent)==null?void 0:Se.type)||"Use agent default model"})]}):null,r==="providers"?a.jsxs("section",{className:"space-y-3",children:[a.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-sm font-semibold text-slate-950 dark:text-white",children:"Providers"}),a.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"Basic endpoint and default model only."})]}),a.jsxs(I,{size:"sm",variant:"secondary",onClick:()=>D(s=>({...s,agent:{...s.agent,providers:[...s.agent.providers||[],{name:`provider-${(s.agent.providers||[]).length+1}`}]}})),children:[a.jsx(ee,{size:14})," Provider"]})]}),(y.agent.providers||[]).length===0?a.jsxs("div",{className:"flex flex-col gap-3 rounded-xl border border-black/10 px-4 py-4 dark:border-white/[0.08] sm:flex-row sm:items-center sm:justify-between",children:[a.jsx("p",{className:"text-sm text-muted-foreground",children:"No providers configured."}),a.jsxs(I,{size:"sm",variant:"secondary",onClick:()=>D(s=>({...s,agent:{...s.agent,providers:[...s.agent.providers||[],{name:`provider-${(s.agent.providers||[]).length+1}`}]}})),children:[a.jsx(ee,{size:14})," Add provider"]})]}):a.jsx("div",{className:"space-y-3",children:(y.agent.providers||[]).map((s,i)=>a.jsx("div",{className:"rounded-xl border border-black/10 p-4 dark:border-white/[0.08]",children:a.jsxs("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:[a.jsxs(ae,{label:"Preset",value:Et(s),onChange:f=>{f.target.value!==Q&&z(i,b=>kt(b,f.target.value))},children:[be.map(f=>a.jsx("option",{value:f.id,children:f.label},f.id)),a.jsx("option",{value:Q,children:"custom"})]}),a.jsx(T,{label:"Name",value:s.name||"",onChange:f=>z(i,b=>({...b,name:f.target.value}))}),a.jsx(T,{label:"API key",type:"password",value:s.api_key||"",onChange:f=>z(i,b=>({...b,api_key:f.target.value}))}),a.jsx(T,{label:"Base URL",value:s.base_url||"",onChange:f=>z(i,b=>({...b,base_url:f.target.value}))}),a.jsx(T,{label:"Default model",value:s.model||"",onChange:f=>z(i,b=>({...b,model:f.target.value}))}),a.jsx("div",{className:"flex items-end",children:a.jsxs(I,{variant:"danger",size:"sm",onClick:()=>D(f=>{const b=[...f.agent.providers||[]];return b.splice(i,1),{...f,agent:{...f.agent,providers:b}}}),children:[a.jsx(ge,{size:14})," Remove"]})})]})},`${s.name}-${i}`))})]}):null,r==="platforms"?a.jsxs("section",{className:"space-y-3",children:[a.jsxs("div",{className:"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",children:[a.jsxs("div",{children:[a.jsx("h3",{className:"text-sm font-semibold text-slate-950 dark:text-white",children:"Platforms"}),a.jsx("p",{className:"mt-1 text-sm text-muted-foreground",children:"Configure each platform with its own required connection fields."})]}),a.jsxs(I,{size:"sm",variant:"secondary",onClick:()=>X(null),children:[a.jsx(ee,{size:14})," Platform"]})]}),(y.platforms||[]).length===0?a.jsx(he,{message:"No platforms configured."}):a.jsx("div",{className:"grid grid-cols-1 gap-3 md:grid-cols-2",children:(y.platforms||[]).map((s,i)=>a.jsxs("div",{className:"flex items-center justify-between gap-3 rounded-xl border border-black/10 p-3 dark:border-white/[0.08]",children:[a.jsxs("div",{className:"min-w-0",children:[a.jsx("p",{className:"truncate text-sm font-medium text-slate-950 dark:text-white",children:s.type}),a.jsx("p",{className:"mt-1 truncate text-xs text-muted-foreground",children:Nt(s)})]}),a.jsxs("div",{className:"flex shrink-0 items-center gap-2",children:[a.jsx(I,{variant:"secondary",size:"sm",onClick:()=>X(i),"aria-label":`Configure ${s.type}`,children:a.jsx(st,{size:14})}),a.jsx(I,{variant:"danger",size:"sm",onClick:()=>D(f=>{const b=[...f.platforms||[]];return b.splice(i,1),{...f,platforms:b}}),children:a.jsx(ge,{size:14})})]})]},`${s.type}-${i}`))})]}):null,a.jsx("div",{className:"flex flex-wrap gap-2 border-t border-black/10 pt-5 dark:border-white/[0.08]",children:a.jsxs(I,{className:"w-full sm:w-auto",onClick:()=>void ue(),loading:_==="config",disabled:!re&&_!=="config",children:[a.jsx(ze,{size:14})," 保存更改"]})})]}):a.jsx(he,{message:"选择或新建项目后开始配置。"})})]}),a.jsx(De,{open:!!n,onClose:()=>l(null),title:"新建项目",children:n?a.jsxs("div",{className:"space-y-4",children:[a.jsx(T,{label:"Project name",value:n.name,onChange:s=>Y({name:s.target.value}),autoFocus:!0}),a.jsx(ae,{label:"Agent type",value:n.agentType,onChange:s=>{const i=s.target.value;Y({agentType:i})},children:me.map(s=>a.jsx("option",{value:s,children:s},s))}),a.jsx(T,{label:"Work directory",value:n.workDir,onChange:s=>Y({workDir:s.target.value}),placeholder:"/Users/yinyin/code/my-project"}),a.jsx(T,{label:"Default model",value:n.model,onChange:s=>Y({model:s.target.value}),placeholder:fe(n.agentType)||"Use agent default model"}),a.jsxs("div",{className:"flex flex-col-reverse gap-2 pt-2 sm:flex-row sm:justify-end",children:[a.jsx(I,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>l(null),children:"Cancel"}),a.jsxs(I,{className:"w-full sm:w-auto",onClick:G,children:[a.jsx(ee,{size:14})," 新建项目"]})]})]}):null}),a.jsx(De,{open:!!u,onClose:()=>{m(null),p(null)},title:(u==null?void 0:u.index)===null?"Add platform":"Configure platform",children:u?a.jsxs("div",{className:"space-y-4",children:[a.jsxs(ae,{label:"Platform",value:Fe(u.draft.type,[...pe]),onChange:s=>{const i=s.target.value===Q?u.draft.type:s.target.value;U(()=>Be(i)),p(null)},children:[pe.map(s=>a.jsx("option",{value:s,children:s},s)),ct.filter(s=>!pe.includes(s)).map(s=>a.jsx("option",{value:s,children:s},s)),a.jsx("option",{value:Q,children:"custom"})]}),u.draft.type==="lark"?a.jsxs("div",{className:"grid grid-cols-1 gap-3",children:[a.jsx(T,{label:"App ID",value:String(((je=u.draft.options)==null?void 0:je.app_id)||""),onChange:s=>U(i=>({...i,options:{...i.options||{},app_id:s.target.value}})),placeholder:"cli_xxx"}),a.jsx(T,{label:"App Secret",type:"password",value:String(((Ae=u.draft.options)==null?void 0:Ae.app_secret)||""),onChange:s=>U(i=>({...i,options:{...i.options||{},app_secret:s.target.value}}))}),a.jsx(T,{label:"Verification token",value:String(((Re=u.draft.options)==null?void 0:Re.verification_token)||""),onChange:s=>U(i=>({...i,options:{...i.options||{},verification_token:s.target.value}}))}),a.jsx(T,{label:"Encrypt key",value:String(((Ie=u.draft.options)==null?void 0:Ie.encrypt_key)||""),onChange:s=>U(i=>({...i,options:{...i.options||{},encrypt_key:s.target.value}}))}),a.jsxs("label",{className:"flex items-center gap-3 text-sm text-foreground",children:[a.jsx("input",{type:"checkbox",checked:((_e=u.draft.options)==null?void 0:_e.auto_approve)===!0,onChange:s=>U(i=>({...i,options:{...i.options||{},auto_approve:s.target.checked}}))}),"Auto-approve Lark users"]})]}):null,u.draft.type==="weixin"?a.jsxs("div",{className:"space-y-3",children:[a.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."}),g!=null&&g.qrCodeUrl?a.jsxs("div",{className:"flex flex-col items-center gap-3 rounded-lg border border-black/10 p-4 dark:border-white/[0.08]",children:[a.jsx("div",{className:"rounded-lg border border-black/10 bg-white p-3",children:a.jsx(et,{value:g.qrCodeUrl,size:176,includeMargin:!0})}),a.jsx(at,{tone:g.status==="confirmed"?"success":g.status==="expired"?"danger":"warning",children:g.status||"wait"})]}):null,a.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:flex-wrap",children:[a.jsxs(I,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>void ce(),loading:R,children:[a.jsx(ht,{size:14})," Generate QR"]}),a.jsx(I,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>void de(),loading:R,disabled:!(g!=null&&g.ticket),children:"Check status"})]})]}):null,u.draft.type!=="lark"&&u.draft.type!=="weixin"?a.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,a.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:[a.jsx(I,{className:"w-full sm:w-auto",variant:"secondary",onClick:()=>m(null),children:"Cancel"}),a.jsxs(I,{className:"w-full sm:w-auto",onClick:le,children:[a.jsx(ze,{size:14})," Apply"]})]})]}):null})]})}export{Qt as default};
@@ -1,3 +0,0 @@
1
- const u="opencode",s="opencode/minimax-m2.5-free";const h=["opencode","codex","claudecode","cursor","gemini","qoder","iflow","localcore-acp"],_=["telegram","feishu","lark","discord","slack","dingtalk","wecom","weixin","qq","qqbot","line"],l=["opencode","claudecode","acp","localcore-acp"],c="localcore-acp",d=["[Scheduler Tools]","If the user asks to create, view, edit, delete, or manually run a scheduled task for this conversation, use the Bash tool to run the local scheduler CLI.","Use these commands:",'lac scheduler add --cron "<5-field cron>" --message "<exact message to send>" --desc "<short label>" [--execution-mode same-thread|side-thread]',"lac scheduler list","lac scheduler list --thread","lac scheduler info <job-id>",'lac scheduler edit <job-id> [--cron "<5-field cron>"] [--message "<exact message>"] [--desc "<short label>"] [--enabled true|false] [--execution-mode same-thread|side-thread]',"lac scheduler del <job-id>","lac scheduler run <job-id>","Environment variables LOCAL_AI_WORKSPACE_ID, LOCAL_AI_THREAD_ID, LOCAL_AI_PLATFORM, LOCAL_AI_CHAT_ID, and LOCAL_AI_PLATFORM_USER_ID are already set when available.","Prefer relying on those variables instead of inventing your own route or creating session-only cron jobs.","By default, `lac scheduler list` shows all scheduled tasks in the current workspace. Use `lac scheduler list --thread` to show only the current conversation thread.","Use `--execution-mode same-thread` to reuse the current thread, or `--execution-mode side-thread` to run in a dedicated scheduled thread.","Only use the scheduler CLI when the user explicitly asks for scheduled automation.","[/Scheduler Tools]"].join(`
2
- `),i={allow:"allow",deny:"deny","allow all":"allow all",allowall:"allow all","perm:allow":"allow","perm:deny":"deny","perm:allow_all":"allow all"};function E(e,t=[]){return[d,...t.flatMap(o=>o?["",o]:[]),"","[User Message]",e,"[/User Message]"].join(`
3
- `)}function m(e){switch(String(e||"").trim().toLowerCase()){case"opencode":return s;case"claudecode":return"";default:return""}}function O(e,t){const o=String(e||"").trim().toLowerCase(),r=String(t||"").trim();return o?o==="opencode"?r||s:o==="claudecode"&&r.startsWith("opencode/")?"":r:r}function n(e){return e&&i[String(e).trim().toLowerCase()]||null}function f(e){return!!n(e==null?void 0:e.data)}function T(e){if(!e||typeof e!="object")return null;const t=e,o=typeof t.text=="string"?t.text:typeof t.Text=="string"?t.Text:"",r=typeof t.data=="string"?t.data:typeof t.Data=="string"?t.Data:"";if(!o||!r)return null;const a=n(r);return a?{text:a,data:a}:{text:o,data:r}}function A(e){return e?l.includes(String(e).trim().toLowerCase()):!1}function D(e){const t=String(e||"").trim().toLowerCase();return t==="acp"||t==="opencode"||t==="claudecode"||t===c}export{h as D,n as a,D as b,O as c,_ as d,u as e,m as g,f as i,T as n,A as s,E as w};
@@ -1 +0,0 @@
1
- import{y as t}from"./index-tQ6A4Zff.js";const e=()=>t.get("/projects"),r=o=>t.get(`/projects/${o}`);export{r as g,e as l};