@kafca/agentdock 0.1.51 → 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 (69) hide show
  1. package/README.md +4 -0
  2. package/dist/renderer/assets/{Badge-DpYXv6XT.js → Badge-H0XWc7vp.js} +1 -1
  3. package/dist/renderer/assets/{Chat-C_aNxLPf.js → Chat-bR-LSg9D.js} +1 -1
  4. package/dist/renderer/assets/{ChatMarkdown-DZgHg5zH.js → ChatMarkdown-ZnK1NWdh.js} +1 -1
  5. package/dist/renderer/assets/Config-DdhdELsW.js +21 -0
  6. package/dist/renderer/assets/{CronList-BuvMxOmF.js → CronList-gyQuGhGg.js} +1 -1
  7. package/dist/renderer/assets/{Dashboard-3nbUcH91.js → Dashboard-DaLRkrf-.js} +2 -2
  8. package/dist/renderer/assets/{EmptyState-LMG_D0FN.js → EmptyState-Ci2bjyET.js} +1 -1
  9. package/dist/renderer/assets/{KnowledgeDetail-DPuV1KoJ.js → KnowledgeDetail-D5dqZC5f.js} +2 -2
  10. package/dist/renderer/assets/{KnowledgeHome-VFIxwTp4.js → KnowledgeHome-DIhbMvM8.js} +2 -2
  11. package/dist/renderer/assets/{Logs-BymclbsW.js → Logs-DIF8ymaI.js} +1 -1
  12. package/dist/renderer/assets/{Modal-Dn_4NhR5.js → Modal-O77lsvJu.js} +3 -3
  13. package/dist/renderer/assets/{MonitorList-B1rSH7zN.js → MonitorList-CJBrqytq.js} +1 -1
  14. package/dist/renderer/assets/{Page-6cEj45pt.js → Page-CodHoUwH.js} +1 -1
  15. package/dist/renderer/assets/ProjectDetail-Bt4Dj60f.js +11 -0
  16. package/dist/renderer/assets/{ProjectList-CZbAGDMS.js → ProjectList-CZTkHOyM.js} +1 -1
  17. package/dist/renderer/assets/{Select-DE1pzt5p.js → Select-DGCo_gYI.js} +1 -1
  18. package/dist/renderer/assets/{SessionChat-DyBDEXW9.js → SessionChat-CHm7HyvI.js} +1 -1
  19. package/dist/renderer/assets/{SessionList-C8sTJnX6.js → SessionList-Df2wQinW.js} +1 -1
  20. package/dist/renderer/assets/{ThreadChat-CpAia9qR.js → ThreadChat-Iomr0Qx9.js} +1 -1
  21. package/dist/renderer/assets/{Workspace-CKpVbGne.js → Workspace-r8lHxaBj.js} +2 -2
  22. package/dist/renderer/assets/{arrow-left-455KUtQh.js → arrow-left-r950YY17.js} +1 -1
  23. package/dist/renderer/assets/{book-open-C_s_nHj6.js → book-open-BslYrNTy.js} +1 -1
  24. package/dist/renderer/assets/{bot-D0cidv6D.js → bot-BVfQh_eb.js} +1 -1
  25. package/dist/renderer/assets/{check-DS7qvqek.js → check-BSAurnOI.js} +1 -1
  26. package/dist/renderer/assets/{chevron-down-C43oRpZM.js → chevron-down-B9G43XLT.js} +1 -1
  27. package/dist/renderer/assets/{circle-aYyg1o0e.js → circle-CBHOs0lN.js} +1 -1
  28. package/dist/renderer/assets/desktop-CXcNupTW.js +1 -0
  29. package/dist/renderer/assets/{funnel-COrEnKiW.js → funnel-UDX21Ev4.js} +1 -1
  30. package/dist/renderer/assets/{heart-BO4CV3kx.js → heart-CzmLZP5g.js} +1 -1
  31. package/dist/renderer/assets/{index-C4ZGOKQv.js → index-C581X81v.js} +9 -9
  32. package/dist/renderer/assets/{index-CbvYBkud.js → index-DeTNhSbD.js} +2 -2
  33. package/dist/renderer/assets/{pencil-DR14wZjZ.js → pencil-BFLsShcu.js} +1 -1
  34. package/dist/renderer/assets/{play-CRTtErO_.js → play-YFpAnQ9r.js} +1 -1
  35. package/dist/renderer/assets/{plus-Bswb_LiK.js → plus-D8uIIQB9.js} +1 -1
  36. package/dist/renderer/assets/projects-D2hAJzY0.js +1 -0
  37. package/dist/renderer/assets/{save-CKgtUije.js → save-Cgx9qe4w.js} +1 -1
  38. package/dist/renderer/assets/{search-RCAjElg9.js → search-CxscB_CP.js} +1 -1
  39. package/dist/renderer/assets/{server-DlKngwyt.js → server-KW8nGvbV.js} +1 -1
  40. package/dist/renderer/assets/{session-utils-CZHYpZpR.js → session-utils-oB-uPAPg.js} +1 -1
  41. package/dist/renderer/assets/{sessions-ChGwwlqi.js → sessions-CefxFisH.js} +1 -1
  42. package/dist/renderer/assets/{shield-check-BRY90_8q.js → shield-check-Bl-k8F5V.js} +1 -1
  43. package/dist/renderer/assets/{trash-2-CwTS-NZu.js → trash-2-DvmnFiu7.js} +1 -1
  44. package/dist/renderer/assets/{user-mhOSrZ1d.js → user-ZZO21GY4.js} +1 -1
  45. package/dist/renderer/assets/{wifi-off-5-ojceU3.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/kernel/bootstrap.js +2 -2
  53. package/dist-electron/services/local-ai-core/src/router/workspace-route-config.js +1 -1
  54. package/dist-electron/services/local-ai-core/src/router/workspace-router.js +8 -7
  55. package/dist-electron/services/local-ai-core/src/runtime/external-service.js +6 -9
  56. package/dist-electron/services/local-ai-core/src/runtime/handlers/runtime-handler.js +4 -8
  57. package/dist-electron/services/local-ai-core/src/runtime/local-core-controller.js +32 -35
  58. package/dist-electron/services/local-ai-core/src/runtime/local-core-runtime-state.js +0 -89
  59. package/dist-electron/services/local-ai-core/src/runtime/server-routes.js +4 -7
  60. package/dist-electron/services/local-ai-core/src/sandbox/sandbox-config.js +4 -4
  61. package/dist-electron/tests/electron/plugin-kernel.test.js +72 -34
  62. package/dist-electron/tests/electron/runtime-config-store.test.js +176 -0
  63. package/dist-electron/tests/electron/sandbox-config.test.js +5 -5
  64. package/dist-electron/tests/electron/workspace-task-store.test.js +5 -5
  65. package/package.json +1 -1
  66. package/dist/renderer/assets/Config-DQAgYmCU.js +0 -21
  67. package/dist/renderer/assets/ProjectDetail-BcoxhPqE.js +0 -11
  68. package/dist/renderer/assets/desktop-CqHMtdOi.js +0 -1
  69. package/dist/renderer/assets/projects-BSilkED5.js +0 -1
@@ -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
  }
@@ -1,4 +1,37 @@
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
+ })();
2
35
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
37
  };
@@ -9,6 +42,7 @@ const node_events_1 = require("node:events");
9
42
  const node_fs_1 = require("node:fs");
10
43
  const node_os_1 = require("node:os");
11
44
  const node_path_1 = require("node:path");
45
+ const TOML = __importStar(require("@iarna/toml"));
12
46
  const bootstrap_js_1 = require("../../services/local-ai-core/src/kernel/bootstrap.js");
13
47
  const bootstrap_js_2 = require("../../services/local-ai-core/src/kernel/bootstrap.js");
14
48
  const capability_registry_js_1 = require("../../services/local-ai-core/src/kernel/capability-registry.js");
@@ -72,6 +106,9 @@ function withLogEnv(logDir, fn, options = {}) {
72
106
  function parseLogLine(line) {
73
107
  return JSON.parse(line);
74
108
  }
109
+ async function saveRawRuntimeConfig(runtime, raw) {
110
+ runtime.store.saveRuntimeConfig(TOML.parse(raw));
111
+ }
75
112
  function plugin(id, dependsOn = []) {
76
113
  return {
77
114
  manifest: {
@@ -315,15 +352,15 @@ async function invokeServer(server, method, url, inputBody) {
315
352
  userDataPath,
316
353
  enableKnowledge: false,
317
354
  });
318
- await runtime.state.saveRawConfigFile(`
355
+ await saveRawRuntimeConfig(runtime, `
319
356
  [[projects]]
320
357
  name = "codex-workspace"
321
358
 
322
359
  [projects.agent]
323
360
  type = "codex"
324
361
  `);
325
- const configState = await runtime.state.readConfigFile();
326
- const project = configState.parsed?.projects?.find((entry) => entry.name === 'codex-workspace');
362
+ const configState = runtime.store.readRuntimeConfig();
363
+ const project = configState.config?.projects?.find((entry) => entry.name === 'codex-workspace');
327
364
  const codexRuntime = runtime.agentRuntimes.find((entry) => entry.agentType === 'codex');
328
365
  const route = project ? codexRuntime?.createRoute(configState, project) : null;
329
366
  strict_1.default.equal(route?.agentType, 'codex');
@@ -352,7 +389,7 @@ type = "codex"
352
389
  userDataPath,
353
390
  enableKnowledge: false,
354
391
  });
355
- await runtime.state.saveRawConfigFile(`
392
+ await saveRawRuntimeConfig(runtime, `
356
393
  [[projects]]
357
394
  name = "agent-workspace"
358
395
 
@@ -378,15 +415,15 @@ type = "codex"
378
415
  userDataPath,
379
416
  enableKnowledge: false,
380
417
  });
381
- await runtime.state.saveRawConfigFile(`
418
+ await saveRawRuntimeConfig(runtime, `
382
419
  [[projects]]
383
420
  name = "hermes-workspace"
384
421
 
385
422
  [projects.agent]
386
423
  type = "hermes"
387
424
  `);
388
- const configState = await runtime.state.readConfigFile();
389
- const project = configState.parsed?.projects?.find((entry) => entry.name === 'hermes-workspace');
425
+ const configState = runtime.store.readRuntimeConfig();
426
+ const project = configState.config?.projects?.find((entry) => entry.name === 'hermes-workspace');
390
427
  const hermesRuntime = runtime.agentRuntimes.find((entry) => entry.agentType === 'hermes');
391
428
  const route = project ? hermesRuntime?.createRoute(configState, project) : null;
392
429
  strict_1.default.equal(route?.agentType, 'hermes');
@@ -416,7 +453,7 @@ type = "hermes"
416
453
  userDataPath,
417
454
  enableKnowledge: false,
418
455
  });
419
- await runtime.state.saveRawConfigFile(`
456
+ await saveRawRuntimeConfig(runtime, `
420
457
  [[projects]]
421
458
  name = "pi-workspace"
422
459
 
@@ -430,8 +467,8 @@ api_key = "test-openai-key"
430
467
  [projects.agent.options.env]
431
468
  OPENAI_API_KEY = "override-openai-key"
432
469
  `);
433
- const configState = await runtime.state.readConfigFile();
434
- const project = configState.parsed?.projects?.find((entry) => entry.name === 'pi-workspace');
470
+ const configState = runtime.store.readRuntimeConfig();
471
+ const project = configState.config?.projects?.find((entry) => entry.name === 'pi-workspace');
435
472
  const piRuntime = runtime.agentRuntimes.find((entry) => entry.agentType === 'pi');
436
473
  const route = project ? piRuntime?.createRoute(configState, project) : null;
437
474
  strict_1.default.equal(route?.agentType, 'pi');
@@ -468,7 +505,7 @@ OPENAI_API_KEY = "override-openai-key"
468
505
  userDataPath,
469
506
  enableKnowledge: false,
470
507
  });
471
- await runtime.state.saveRawConfigFile(`
508
+ await saveRawRuntimeConfig(runtime, `
472
509
  [[projects]]
473
510
  name = "deepseek-workspace"
474
511
 
@@ -481,8 +518,8 @@ api_key = "test-deepseek-key"
481
518
  base_url = "https://api.deepseek.com"
482
519
  model = "deepseek-v4-flash"
483
520
  `);
484
- const configState = await runtime.state.readConfigFile();
485
- const project = configState.parsed?.projects?.find((entry) => entry.name === 'deepseek-workspace');
521
+ const configState = runtime.store.readRuntimeConfig();
522
+ const project = configState.config?.projects?.find((entry) => entry.name === 'deepseek-workspace');
486
523
  const piRuntime = runtime.agentRuntimes.find((entry) => entry.agentType === 'pi');
487
524
  const route = project ? piRuntime?.createRoute(configState, project) : null;
488
525
  const piAgentDir = route?.config.env.PI_CODING_AGENT_DIR || '';
@@ -519,7 +556,7 @@ model = "deepseek-v4-flash"
519
556
  userDataPath,
520
557
  enableKnowledge: false,
521
558
  });
522
- await runtime.state.saveRawConfigFile(`
559
+ await saveRawRuntimeConfig(runtime, `
523
560
  [[projects]]
524
561
  name = "deepseek-model-name-workspace"
525
562
 
@@ -532,8 +569,8 @@ api_key = "test-deepseek-key"
532
569
  base_url = "https://api.deepseek.com"
533
570
  model = "deepseek-v4-flash"
534
571
  `);
535
- const configState = await runtime.state.readConfigFile();
536
- const project = configState.parsed?.projects?.find((entry) => entry.name === 'deepseek-model-name-workspace');
572
+ const configState = runtime.store.readRuntimeConfig();
573
+ const project = configState.config?.projects?.find((entry) => entry.name === 'deepseek-model-name-workspace');
537
574
  const piRuntime = runtime.agentRuntimes.find((entry) => entry.agentType === 'pi');
538
575
  const route = project ? piRuntime?.createRoute(configState, project) : null;
539
576
  const piAgentDir = route?.config.env.PI_CODING_AGENT_DIR || '';
@@ -584,7 +621,6 @@ model = "deepseek-v4-flash"
584
621
  const runtimeDir = (0, node_path_1.join)(userDataPath, 'runtime');
585
622
  (0, node_fs_1.mkdirSync)(runtimeDir, { recursive: true });
586
623
  (0, node_fs_1.writeFileSync)((0, node_path_1.join)(runtimeDir, 'local-core-settings.json'), JSON.stringify({
587
- configPath: (0, node_path_1.join)(runtimeDir, 'config.toml'),
588
624
  defaultProject: 'default',
589
625
  autoStartService: true,
590
626
  knowledge: {
@@ -644,6 +680,12 @@ model = "deepseek-v4-flash"
644
680
  let stopped = false;
645
681
  let channelRefreshes = 0;
646
682
  let weixinRefreshes = 0;
683
+ let runtimeConfig = {
684
+ storage: 'sqlite',
685
+ databasePath: '/tmp/local-core-controller-injected/runtime/local-core.db',
686
+ baseDir: '/tmp/local-core-controller-injected/runtime',
687
+ config: { projects: [] },
688
+ };
647
689
  const channelRuntime = {
648
690
  platform: 'test-channel',
649
691
  routeType: 'channel.test',
@@ -689,7 +731,6 @@ model = "deepseek-v4-flash"
689
731
  state: {
690
732
  getSettings: () => ({
691
733
  binaryPath: '',
692
- configPath: '',
693
734
  autoStartService: true,
694
735
  defaultProject: 'default',
695
736
  managementPort: 0,
@@ -708,20 +749,18 @@ model = "deepseek-v4-flash"
708
749
  }),
709
750
  getLogs: () => [],
710
751
  getLogEntries: () => [],
711
- readConfigFile: async () => ({
712
- path: '',
713
- exists: false,
714
- raw: '',
715
- parsed: null,
716
- }),
717
- saveStructuredConfigFile: async (config) => ({
718
- path: '',
719
- exists: true,
720
- raw: JSON.stringify(config),
721
- parsed: config,
722
- }),
723
752
  },
724
- store: {},
753
+ store: {
754
+ readRuntimeConfig: () => runtimeConfig,
755
+ saveRuntimeConfig: (config) => {
756
+ runtimeConfig = {
757
+ ...runtimeConfig,
758
+ config,
759
+ updatedAt: new Date().toISOString(),
760
+ };
761
+ return runtimeConfig;
762
+ },
763
+ },
725
764
  agentRuntimes: [],
726
765
  channelRuntimes: [channelRuntime, weixinChannelRuntime],
727
766
  channelRuntime,
@@ -750,7 +789,7 @@ model = "deepseek-v4-flash"
750
789
  strict_1.default.deepEqual(await controller.channelService.checkQrCodeStatus('test-channel', 'workspace-1', 'signed-ticket'), {
751
790
  status: 'signed',
752
791
  });
753
- await controller.saveStructuredConfigFile({ projects: [] });
792
+ await controller.saveRuntimeConfig({ projects: [] });
754
793
  strict_1.default.equal(channelRefreshes, 1);
755
794
  strict_1.default.equal(weixinRefreshes, 1);
756
795
  await controller.close();
@@ -1155,7 +1194,6 @@ model = "deepseek-v4-flash"
1155
1194
  const runtimeDir = (0, node_path_1.join)(userDataPath, 'runtime');
1156
1195
  (0, node_fs_1.mkdirSync)(runtimeDir, { recursive: true });
1157
1196
  (0, node_fs_1.writeFileSync)((0, node_path_1.join)(runtimeDir, 'local-core-settings.json'), JSON.stringify({
1158
- configPath: (0, node_path_1.join)(runtimeDir, 'config.toml'),
1159
1197
  defaultProject: 'default',
1160
1198
  autoStartService: true,
1161
1199
  knowledge: {
@@ -1173,7 +1211,7 @@ model = "deepseek-v4-flash"
1173
1211
  const runtime = (0, bootstrap_js_2.bootstrapLocalCoreRuntime)({
1174
1212
  userDataPath,
1175
1213
  });
1176
- await runtime.state.saveRawConfigFile(`
1214
+ await saveRawRuntimeConfig(runtime, `
1177
1215
  [[projects]]
1178
1216
  name = "claude-workspace"
1179
1217