@kafca/agentdock 0.1.50 → 0.1.52

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 (71) hide show
  1. package/README.md +5 -0
  2. package/dist/renderer/assets/{Badge-DphzI84h.js → Badge-H0XWc7vp.js} +1 -1
  3. package/dist/renderer/assets/{Chat-BkMHNdkV.js → Chat-bR-LSg9D.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-nmZelMA9.js → ChatMarkdown-ZnK1NWdh.js} +1 -1
  5. package/dist/renderer/assets/Config-DdhdELsW.js +21 -0
  6. package/dist/renderer/assets/{CronList-Ds9TTT0f.js → CronList-gyQuGhGg.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-DeWrprYz.js → Dashboard-DaLRkrf-.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-JnMCDgRB.js → EmptyState-Ci2bjyET.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-CQ3VlctJ.js → KnowledgeDetail-D5dqZC5f.js} +2 -2
  10. package/dist/renderer/assets/{KnowledgeHome-DsCVW1re.js → KnowledgeHome-DIhbMvM8.js} +2 -2
  11. package/dist/renderer/assets/{Logs-4ENSRVB4.js → Logs-DIF8ymaI.js} +1 -1
  12. package/dist/renderer/assets/{Modal-BIm0iRtp.js → Modal-O77lsvJu.js} +3 -3
  13. package/dist/renderer/assets/{MonitorList-CCj0KIGD.js → MonitorList-CJBrqytq.js} +1 -1
  14. package/dist/renderer/assets/{Page-uCVGTzRo.js → Page-CodHoUwH.js} +1 -1
  15. package/dist/renderer/assets/ProjectDetail-Bt4Dj60f.js +11 -0
  16. package/dist/renderer/assets/{ProjectList-DglTyk-r.js → ProjectList-CZTkHOyM.js} +1 -1
  17. package/dist/renderer/assets/{Select-wnvxGX9B.js → Select-DGCo_gYI.js} +1 -1
  18. package/dist/renderer/assets/{SessionChat-BvrFUqiK.js → SessionChat-CHm7HyvI.js} +1 -1
  19. package/dist/renderer/assets/{SessionList-DN0k8lCt.js → SessionList-Df2wQinW.js} +1 -1
  20. package/dist/renderer/assets/{ThreadChat-DqZwWTdK.js → ThreadChat-Iomr0Qx9.js} +1 -1
  21. package/dist/renderer/assets/{Workspace-VrjbrPbA.js → Workspace-r8lHxaBj.js} +2 -2
  22. package/dist/renderer/assets/{arrow-left-BflzNl62.js → arrow-left-r950YY17.js} +1 -1
  23. package/dist/renderer/assets/{book-open-D2ttV2IU.js → book-open-BslYrNTy.js} +1 -1
  24. package/dist/renderer/assets/{bot-cb9OifGp.js → bot-BVfQh_eb.js} +1 -1
  25. package/dist/renderer/assets/{check-B47n4xeR.js → check-BSAurnOI.js} +1 -1
  26. package/dist/renderer/assets/{chevron-down-CGsttXF_.js → chevron-down-B9G43XLT.js} +1 -1
  27. package/dist/renderer/assets/{circle-BnHI6FDe.js → circle-CBHOs0lN.js} +1 -1
  28. package/dist/renderer/assets/desktop-CXcNupTW.js +1 -0
  29. package/dist/renderer/assets/{funnel-DPnOoche.js → funnel-UDX21Ev4.js} +1 -1
  30. package/dist/renderer/assets/{heart-Bdhq7IqP.js → heart-CzmLZP5g.js} +1 -1
  31. package/dist/renderer/assets/{index-CrZRrTuv.js → index-C581X81v.js} +9 -9
  32. package/dist/renderer/assets/{index-BfJ1LHHo.js → index-DeTNhSbD.js} +2 -2
  33. package/dist/renderer/assets/{pencil-0zLgPSJa.js → pencil-BFLsShcu.js} +1 -1
  34. package/dist/renderer/assets/{play-fVd6Sq-t.js → play-YFpAnQ9r.js} +1 -1
  35. package/dist/renderer/assets/{plus-DmNVnnyt.js → plus-D8uIIQB9.js} +1 -1
  36. package/dist/renderer/assets/projects-D2hAJzY0.js +1 -0
  37. package/dist/renderer/assets/{save-CSIMXP6Z.js → save-Cgx9qe4w.js} +1 -1
  38. package/dist/renderer/assets/{search-Ddn9yqyb.js → search-CxscB_CP.js} +1 -1
  39. package/dist/renderer/assets/{server-BVPINrD2.js → server-KW8nGvbV.js} +1 -1
  40. package/dist/renderer/assets/{session-utils-BcyJwUyK.js → session-utils-oB-uPAPg.js} +1 -1
  41. package/dist/renderer/assets/{sessions-BtcQ4TyW.js → sessions-CefxFisH.js} +1 -1
  42. package/dist/renderer/assets/{shield-check-B2sF2E4F.js → shield-check-Bl-k8F5V.js} +1 -1
  43. package/dist/renderer/assets/{trash-2-BwMAwl5Q.js → trash-2-DvmnFiu7.js} +1 -1
  44. package/dist/renderer/assets/{user-BEZW7eDN.js → user-ZZO21GY4.js} +1 -1
  45. package/dist/renderer/assets/{wifi-off-C1uypxZf.js → wifi-off-1dHHA2Em.js} +1 -1
  46. package/dist/renderer/index.html +1 -1
  47. package/dist-electron/packages/core-sdk/src/index.js +6 -10
  48. package/dist-electron/services/local-ai-core/src/acp/store/local-core-acp-store.js +29 -0
  49. package/dist-electron/services/local-ai-core/src/acp/store/runtime-config-store.js +164 -0
  50. package/dist-electron/services/local-ai-core/src/acp/store/schema.js +8 -0
  51. package/dist-electron/services/local-ai-core/src/agents/shared/launch-utils.js +1 -2
  52. package/dist-electron/services/local-ai-core/src/cli/lac.js +2 -2
  53. package/dist-electron/services/local-ai-core/src/kernel/bootstrap.js +2 -2
  54. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +1 -1
  55. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +8 -7
  56. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +6 -9
  57. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +4 -8
  58. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +32 -35
  59. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +0 -89
  60. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +4 -7
  61. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +4 -4
  62. package/dist-electron/tests/electron/lac-cli.test.js +36 -0
  63. package/dist-electron/tests/electron/plugin-kernel.test.js +72 -34
  64. package/dist-electron/tests/electron/runtime-config-store.test.js +176 -0
  65. package/dist-electron/tests/electron/sandbox-config.test.js +5 -5
  66. package/dist-electron/tests/electron/workspace-task-store.test.js +5 -5
  67. package/package.json +1 -1
  68. package/dist/renderer/assets/Config-CY2peXi1.js +0 -21
  69. package/dist/renderer/assets/ProjectDetail-DJ0Z_Ixk.js +0 -11
  70. package/dist/renderer/assets/desktop-CRlWIOU3.js +0 -1
  71. package/dist/renderer/assets/projects-Cm9nXtkn.js +0 -1
@@ -107,8 +107,8 @@ class ExternalService {
107
107
  async ensureWorkspaceConfig(project, model) {
108
108
  const current = await this.readAndMigrateConfigFile();
109
109
  const config = {
110
- ...(current.parsed || {}),
111
- projects: Array.isArray(current.parsed?.projects) ? [...current.parsed.projects] : [],
110
+ ...(current.config || {}),
111
+ projects: Array.isArray(current.config?.projects) ? [...current.config.projects] : [],
112
112
  };
113
113
  const existingIndex = config.projects.findIndex((item) => item?.name === project.workspaceId);
114
114
  const existing = existingIndex >= 0 ? config.projects[existingIndex] : undefined;
@@ -146,7 +146,7 @@ class ExternalService {
146
146
  else {
147
147
  config.projects.push(nextProject);
148
148
  }
149
- await this.deps.saveStructuredConfig(config);
149
+ await this.deps.saveRuntimeConfig(config);
150
150
  }
151
151
  async ensureThread(project, input) {
152
152
  const externalThreadId = normalizeExternalId(input.external_thread_id || `thread-${(0, node_crypto_1.randomUUID)()}`, 'external_thread_id');
@@ -175,15 +175,12 @@ class ExternalService {
175
175
  });
176
176
  }
177
177
  async readAndMigrateConfigFile() {
178
- const current = await this.deps.readConfigState();
179
- if (!current.parsed) {
180
- return current;
181
- }
182
- const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(current.parsed, this.store);
178
+ const current = await this.deps.readRuntimeConfig();
179
+ const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(current.config, this.store);
183
180
  if (!migrated.changed) {
184
181
  return current;
185
182
  }
186
- const saved = await this.deps.saveStructuredConfig(migrated.config);
183
+ const saved = await this.deps.saveRuntimeConfig(migrated.config);
187
184
  return {
188
185
  ...saved,
189
186
  warnings: [
@@ -38,16 +38,12 @@ function registerRuntimeHandlers(map, controller, errorReporter, attachSseClient
38
38
  map.set('diagnostics.errors', async (_route, _req, res) => {
39
39
  (0, server_helpers_js_1.json)(res, 200, { errors: await errorReporter.list() });
40
40
  });
41
- map.set('runtime.config.read', async (_route, _req, res) => {
42
- (0, server_helpers_js_1.json)(res, 200, await controller.readConfigFile());
41
+ map.set('runtime.runtime-config.read', async (_route, _req, res) => {
42
+ (0, server_helpers_js_1.json)(res, 200, await controller.readRuntimeConfig());
43
43
  });
44
- map.set('runtime.config.save-raw', async (_route, req, res) => {
44
+ map.set('runtime.runtime-config.save', async (_route, req, res) => {
45
45
  const body = await (0, server_helpers_js_1.readJsonBody)(req);
46
- (0, server_helpers_js_1.json)(res, 200, await controller.saveRawConfigFile(String(body.raw || '')));
47
- });
48
- map.set('runtime.config.save-structured', async (_route, req, res) => {
49
- const body = await (0, server_helpers_js_1.readJsonBody)(req);
50
- (0, server_helpers_js_1.json)(res, 200, await controller.saveStructuredConfigFile((body.config || {})));
46
+ (0, server_helpers_js_1.json)(res, 200, await controller.saveRuntimeConfig((body.config || {})));
51
47
  });
52
48
  map.set('runtime.settings.save', async (_route, req, res) => {
53
49
  const body = await (0, server_helpers_js_1.readJsonBody)(req);
@@ -44,8 +44,8 @@ class LocalCoreController extends node_events_1.EventEmitter {
44
44
  const channelRuntimes = new Map(runtimeChannels.filter(Boolean).map((ch) => [ch.platform, ch]));
45
45
  this.channelService = new channel_service_js_1.ChannelService(channelRuntimes);
46
46
  this.externalService = new external_service_js_1.ExternalService(this.store, this.workspaceRouter, {
47
- readConfigState: () => this.readConfigFile(),
48
- saveStructuredConfig: (config) => this.saveStructuredConfigFile(config),
47
+ readRuntimeConfig: () => this.readRuntimeConfig(),
48
+ saveRuntimeConfig: (config) => this.saveRuntimeConfig(config),
49
49
  }, userDataPath);
50
50
  this.scheduledJobs = this.runtime.scheduledJobs;
51
51
  this.automationMonitors = this.runtime.automationMonitors || {
@@ -60,7 +60,7 @@ class LocalCoreController extends node_events_1.EventEmitter {
60
60
  this.errorReporter = new local_core_errors_js_1.LocalCoreErrorReporter((message) => this.handleLog(message));
61
61
  this.runtimeDetection = new runtime_detection_service_js_1.RuntimeDetectionService({
62
62
  userDataPath,
63
- readConfig: async () => (await this.readConfigFile()).parsed,
63
+ readConfig: async () => (await this.readRuntimeConfig()).config,
64
64
  log: (message) => this.handleLog(message),
65
65
  emit: (event) => this.handleRuntimeDetectionEvent(event),
66
66
  });
@@ -105,10 +105,10 @@ class LocalCoreController extends node_events_1.EventEmitter {
105
105
  status: 'running',
106
106
  startedAt: new Date().toISOString(),
107
107
  };
108
- const configFile = await this.readConfigFile();
108
+ const runtimeConfig = await this.readRuntimeConfig();
109
109
  const settings = this.state.getSettings();
110
- const workspaceIds = Array.isArray(configFile.parsed?.projects)
111
- ? configFile.parsed.projects
110
+ const workspaceIds = Array.isArray(runtimeConfig.config?.projects)
111
+ ? runtimeConfig.config.projects
112
112
  .map((project) => String(project?.name || '').trim())
113
113
  .filter(Boolean)
114
114
  : [];
@@ -125,7 +125,7 @@ class LocalCoreController extends node_events_1.EventEmitter {
125
125
  ...settings,
126
126
  defaultProject,
127
127
  },
128
- configFile,
128
+ runtimeConfig,
129
129
  logs: this.getLogs(200),
130
130
  pluginDiagnostics: await this.getPluginDiagnostics(),
131
131
  };
@@ -147,21 +147,21 @@ class LocalCoreController extends node_events_1.EventEmitter {
147
147
  getLogEntries(level = 'sys', limit = 200) {
148
148
  return this.state.getLogEntries(level, limit);
149
149
  }
150
- async readConfigFile() {
151
- return this.readAndMigrateConfigFile();
150
+ async readRuntimeConfig() {
151
+ return this.readAndMigrateRuntimeConfig();
152
152
  }
153
- async saveRawConfigFile(raw) {
154
- const next = await this.state.saveRawConfigFile(raw);
155
- await this.channelService.refreshBindings();
156
- await this.emitRuntime();
157
- return next;
158
- }
159
- async saveStructuredConfigFile(config) {
153
+ async saveRuntimeConfig(config) {
160
154
  const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(config, this.store);
161
- const next = await this.state.saveStructuredConfigFile(migrated.config);
155
+ const next = this.store.saveRuntimeConfig(migrated.config);
162
156
  await this.channelService.refreshBindings();
163
157
  await this.emitRuntime();
164
- return next;
158
+ return {
159
+ ...next,
160
+ warnings: [
161
+ ...(next.warnings || []),
162
+ ...migrated.warnings,
163
+ ],
164
+ };
165
165
  }
166
166
  async saveSettings(input) {
167
167
  const settings = await this.state.saveSettings(input);
@@ -174,7 +174,7 @@ class LocalCoreController extends node_events_1.EventEmitter {
174
174
  }
175
175
  async runDiagnosticsDoctor() {
176
176
  const checkedAt = new Date().toISOString();
177
- const configFile = await this.readConfigFile();
177
+ const runtimeConfig = await this.readRuntimeConfig();
178
178
  const runtimeChecks = await this.runtimeDetection.refresh().catch((error) => {
179
179
  const errorInfo = (0, local_core_errors_js_1.toLocalCoreErrorInfo)(error, 'internal_error');
180
180
  return [{
@@ -195,19 +195,19 @@ class LocalCoreController extends node_events_1.EventEmitter {
195
195
  });
196
196
  const channelStatuses = await this.channelService.listStatuses().catch(() => []);
197
197
  const checks = [
198
- configFile.error
198
+ runtimeConfig.error
199
199
  ? {
200
200
  id: 'config',
201
- label: 'Configuration',
201
+ label: 'Runtime Configuration',
202
202
  status: 'fail',
203
- summary: configFile.error,
204
- errorInfo: new local_core_errors_js_1.LocalCoreError('config_invalid', configFile.error).info,
203
+ summary: runtimeConfig.error,
204
+ errorInfo: new local_core_errors_js_1.LocalCoreError('config_invalid', runtimeConfig.error).info,
205
205
  }
206
206
  : {
207
207
  id: 'config',
208
- label: 'Configuration',
209
- status: configFile.exists ? 'pass' : 'warn',
210
- summary: configFile.exists ? 'Configuration file is readable.' : 'Configuration file has not been created yet.',
208
+ label: 'Runtime Configuration',
209
+ status: 'pass',
210
+ summary: `Runtime configuration is stored in SQLite at ${runtimeConfig.databasePath}.`,
211
211
  },
212
212
  {
213
213
  id: 'runtime-detection',
@@ -237,8 +237,8 @@ class LocalCoreController extends node_events_1.EventEmitter {
237
237
  return { status, checkedAt, checks };
238
238
  }
239
239
  async runDeploymentDiagnostics() {
240
- const configFile = await this.readConfigFile();
241
- return (0, deployment_diagnostics_js_1.runDeploymentDiagnostics)({ config: configFile.parsed });
240
+ const runtimeConfig = await this.readRuntimeConfig();
241
+ return (0, deployment_diagnostics_js_1.runDeploymentDiagnostics)({ config: runtimeConfig.config });
242
242
  }
243
243
  emitBridge(event) {
244
244
  this.emit('bridge', event);
@@ -283,16 +283,13 @@ class LocalCoreController extends node_events_1.EventEmitter {
283
283
  this.handlingLog = false;
284
284
  }
285
285
  }
286
- async readAndMigrateConfigFile() {
287
- const current = await this.state.readConfigFile();
288
- if (!current.parsed) {
289
- return current;
290
- }
291
- const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(current.parsed, this.store);
286
+ async readAndMigrateRuntimeConfig() {
287
+ const current = this.store.readRuntimeConfig();
288
+ const migrated = (0, provider_config_migration_js_1.migrateLegacyProjectProvidersToStore)(current.config, this.store);
292
289
  if (!migrated.changed) {
293
290
  return current;
294
291
  }
295
- const saved = await this.state.saveStructuredConfigFile(migrated.config);
292
+ const saved = this.store.saveRuntimeConfig(migrated.config);
296
293
  return {
297
294
  ...saved,
298
295
  warnings: [
@@ -1,47 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
2
  Object.defineProperty(exports, "__esModule", { value: true });
36
3
  exports.createLocalCoreRuntimeState = createLocalCoreRuntimeState;
37
4
  const node_fs_1 = require("node:fs");
38
5
  const node_path_1 = require("node:path");
39
- const TOML = __importStar(require("@iarna/toml"));
40
6
  const rotating_logger_js_1 = require("../kernel/rotating-logger.js");
41
- const config_migration_js_1 = require("./config-migration.js");
42
- const DEFAULT_CONFIG = `# Managed by Local AI Core
43
- # Add [[projects]] entries from the workspace page before starting a conversation.
44
- `;
45
7
  class FileBackedLocalCoreRuntimeState {
46
8
  userDataPath;
47
9
  onLog;
@@ -62,7 +24,6 @@ class FileBackedLocalCoreRuntimeState {
62
24
  (0, node_fs_1.mkdirSync)(this.runtimeDir, { recursive: true });
63
25
  this.cliBinDir = this.ensureCliWrapper();
64
26
  this.settings = this.loadSettings();
65
- this.ensureConfigFile();
66
27
  }
67
28
  getSettings() {
68
29
  return this.settings;
@@ -72,7 +33,6 @@ class FileBackedLocalCoreRuntimeState {
72
33
  ...this.settings,
73
34
  ...(input.defaultProject !== undefined ? { defaultProject: input.defaultProject } : {}),
74
35
  ...(typeof input.autoStartService === 'boolean' ? { autoStartService: input.autoStartService } : {}),
75
- ...(input.configPath ? { configPath: input.configPath } : {}),
76
36
  plugins: input.plugins
77
37
  ? Object.fromEntries(Object.entries({
78
38
  ...this.settings.plugins,
@@ -133,47 +93,8 @@ class FileBackedLocalCoreRuntimeState {
133
93
  this.logs.splice(0, this.logs.length - 400);
134
94
  }
135
95
  }
136
- async readConfigFile() {
137
- const path = this.settings.configPath;
138
- if (!(0, node_fs_1.existsSync)(path)) {
139
- return { path, exists: false, raw: '', parsed: null };
140
- }
141
- const raw = (0, node_fs_1.readFileSync)(path, 'utf8');
142
- try {
143
- const parsed = TOML.parse(raw);
144
- const migrated = (0, config_migration_js_1.migrateDesktopConnectConfig)(parsed);
145
- return {
146
- path,
147
- exists: true,
148
- raw,
149
- parsed: migrated.config,
150
- warnings: migrated.warnings.length > 0 ? migrated.warnings : undefined,
151
- };
152
- }
153
- catch (error) {
154
- return {
155
- path,
156
- exists: true,
157
- raw,
158
- parsed: null,
159
- error: error instanceof Error ? error.message : String(error),
160
- };
161
- }
162
- }
163
- async saveRawConfigFile(raw) {
164
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.settings.configPath), { recursive: true });
165
- (0, node_fs_1.writeFileSync)(this.settings.configPath, raw, 'utf8');
166
- return this.readConfigFile();
167
- }
168
- async saveStructuredConfigFile(config) {
169
- const migrated = (0, config_migration_js_1.migrateDesktopConnectConfig)(config);
170
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.settings.configPath), { recursive: true });
171
- (0, node_fs_1.writeFileSync)(this.settings.configPath, TOML.stringify(migrated.config), 'utf8');
172
- return this.readConfigFile();
173
- }
174
96
  loadSettings() {
175
97
  const defaults = {
176
- configPath: (0, node_path_1.join)(this.runtimeDir, 'config.toml'),
177
98
  defaultProject: '',
178
99
  autoStartService: true,
179
100
  plugins: {},
@@ -188,7 +109,6 @@ class FileBackedLocalCoreRuntimeState {
188
109
  if (!(0, node_fs_1.existsSync)(this.settingsPath)) {
189
110
  return {
190
111
  binaryPath: '',
191
- configPath: defaults.configPath,
192
112
  autoStartService: defaults.autoStartService,
193
113
  defaultProject: defaults.defaultProject,
194
114
  managementPort: 0,
@@ -203,7 +123,6 @@ class FileBackedLocalCoreRuntimeState {
203
123
  const raw = JSON.parse((0, node_fs_1.readFileSync)(this.settingsPath, 'utf8'));
204
124
  return {
205
125
  binaryPath: '',
206
- configPath: String(raw.configPath || defaults.configPath),
207
126
  autoStartService: typeof raw.autoStartService === 'boolean' ? raw.autoStartService : defaults.autoStartService,
208
127
  defaultProject: String(raw.defaultProject || defaults.defaultProject),
209
128
  managementPort: 0,
@@ -220,7 +139,6 @@ class FileBackedLocalCoreRuntimeState {
220
139
  }
221
140
  persistSettings() {
222
141
  const payload = {
223
- configPath: this.settings.configPath,
224
142
  defaultProject: this.settings.defaultProject,
225
143
  autoStartService: this.settings.autoStartService,
226
144
  plugins: this.settings.plugins,
@@ -229,13 +147,6 @@ class FileBackedLocalCoreRuntimeState {
229
147
  (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.settingsPath), { recursive: true });
230
148
  (0, node_fs_1.writeFileSync)(this.settingsPath, `${JSON.stringify(payload, null, 2)}\n`, 'utf8');
231
149
  }
232
- ensureConfigFile() {
233
- if ((0, node_fs_1.existsSync)(this.settings.configPath)) {
234
- return;
235
- }
236
- (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(this.settings.configPath), { recursive: true });
237
- (0, node_fs_1.writeFileSync)(this.settings.configPath, DEFAULT_CONFIG, 'utf8');
238
- }
239
150
  ensureCliWrapper() {
240
151
  const binDir = (0, node_path_1.join)(this.runtimeDir, 'bin');
241
152
  (0, node_fs_1.mkdirSync)(binDir, { recursive: true });
@@ -29,14 +29,11 @@ function parseLocalAiCoreRoute(method, path) {
29
29
  if (normalizedMethod === 'GET' && relativePath === '/runtime/agent-runtimes') {
30
30
  return { name: 'runtime.agent-runtimes' };
31
31
  }
32
- if (normalizedMethod === 'GET' && relativePath === '/runtime/config') {
33
- return { name: 'runtime.config.read' };
32
+ if (normalizedMethod === 'GET' && (relativePath === '/runtime/runtime-config' || relativePath === '/runtime/config')) {
33
+ return { name: 'runtime.runtime-config.read' };
34
34
  }
35
- if (normalizedMethod === 'POST' && relativePath === '/runtime/config/raw') {
36
- return { name: 'runtime.config.save-raw' };
37
- }
38
- if (normalizedMethod === 'POST' && relativePath === '/runtime/config/structured') {
39
- return { name: 'runtime.config.save-structured' };
35
+ if (normalizedMethod === 'POST' && relativePath === '/runtime/runtime-config') {
36
+ return { name: 'runtime.runtime-config.save' };
40
37
  }
41
38
  if (normalizedMethod === 'POST' && relativePath === '/runtime/settings') {
42
39
  return { name: 'runtime.settings.save' };
@@ -41,10 +41,10 @@ function normalizeSandboxLaunchConfig(input) {
41
41
  if (!raw?.enabled) {
42
42
  return undefined;
43
43
  }
44
- const configDir = (0, node_path_1.dirname)(input.configState.path);
45
- const userDataRoot = (0, node_path_1.dirname)(configDir);
44
+ const configDir = input.configState.baseDir;
45
+ const userDataRoot = (0, node_path_1.resolve)(configDir, '..');
46
46
  const agentType = input.launchConfig.agentType || String(input.project.agent?.type || '').trim().toLowerCase() || 'agent';
47
- const desktopConfig = input.configState.parsed || {};
47
+ const desktopConfig = input.configState.config || {};
48
48
  const deploymentProfileId = String(raw.deployment_profile || desktopConfig.deployment_profile || process.env.AGENTDOCK_DEPLOYMENT_PROFILE || '').trim();
49
49
  const profile = (0, index_js_1.getDesktopDeploymentProfile)(deploymentProfileId);
50
50
  const sandboxProvider = resolveSandboxProvider(desktopConfig.sandbox_providers, raw, profile.id);
@@ -269,5 +269,5 @@ function sanitizePathSegment(value, fallback) {
269
269
  .replace(/^-+|-+$/g, '') || fallback;
270
270
  }
271
271
  function resolveHostPathFromConfigDir(configState, rawPath) {
272
- return (0, node_path_1.isAbsolute)(rawPath) ? rawPath : (0, node_path_1.resolve)((0, node_path_1.dirname)(configState.path), rawPath);
272
+ return (0, node_path_1.isAbsolute)(rawPath) ? rawPath : (0, node_path_1.resolve)(configState.baseDir, rawPath);
273
273
  }
@@ -566,6 +566,42 @@ function withFetchMock(mock) {
566
566
  restore();
567
567
  }
568
568
  });
569
+ (0, node_test_1.default)('lac scheduler edit with only --cron does not clear message or description', async () => {
570
+ let capturedBody = null;
571
+ const { restore } = withFetchMock(async (_input, init) => {
572
+ if (init?.body)
573
+ capturedBody = init.body;
574
+ return new Response(JSON.stringify({
575
+ ok: true,
576
+ data: {
577
+ id: 'job:826aff79-570b-4308-822e-18318e2c96ba',
578
+ workspaceId: '知识库',
579
+ platform: 'lark',
580
+ route: { type: 'channel.chat', channelId: 'chat-1', participantId: 'user-1', threadId: 'thread-1' },
581
+ executionMode: 'same-thread',
582
+ triggerType: 'cron',
583
+ cronExpr: '0 2 * * *',
584
+ promptTemplate: 'preserved message',
585
+ description: 'preserved desc',
586
+ enabled: true,
587
+ concurrencyPolicy: 'skip_if_running',
588
+ createdAt: '2026-04-22T06:00:00.000Z',
589
+ updatedAt: '2026-04-22T07:00:00.000Z',
590
+ },
591
+ }), { headers: { 'content-type': 'application/json' } });
592
+ });
593
+ try {
594
+ const { io, read } = createIo();
595
+ const exitCode = await (0, lac_js_1.runCli)(['scheduler', 'edit', '826aff79', '--cron', '0 2 * * *'], { LOCAL_AI_CORE_BASE: 'http://127.0.0.1:9831/api/local/v1' }, io);
596
+ strict_1.default.equal(exitCode, 0);
597
+ (0, strict_1.default)(capturedBody);
598
+ strict_1.default.deepEqual(JSON.parse(capturedBody), { cronExpr: '0 2 * * *' });
599
+ strict_1.default.match(read().stdout, /Updated scheduler job 826aff79/);
600
+ }
601
+ finally {
602
+ restore();
603
+ }
604
+ });
569
605
  (0, node_test_1.default)('lac scheduler del deletes a short job id', async () => {
570
606
  const { restore } = withFetchMock(async () => {
571
607
  return new Response(JSON.stringify({ ok: true, data: { deleted: true } }), { headers: { 'content-type': 'application/json' } });