nextclaw 0.13.17 → 0.13.20

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 (36) hide show
  1. package/dist/cli/index.js +331 -249
  2. package/package.json +9 -9
  3. package/ui-dist/assets/{ChannelsList-B5Ff_-Ul.js → ChannelsList-CIMYaIji.js} +1 -1
  4. package/ui-dist/assets/{ChatPage-DMwwbwgE.js → ChatPage-B5UpeEIp.js} +1 -1
  5. package/ui-dist/assets/{DocBrowser-D-do8agn.js → DocBrowser-BJ610SPa.js} +1 -1
  6. package/ui-dist/assets/{LogoBadge-B0QMblbJ.js → LogoBadge-BKq1GKWP.js} +1 -1
  7. package/ui-dist/assets/{MarketplacePage-tA3mJKUm.js → MarketplacePage-Bs3sLsgx.js} +1 -1
  8. package/ui-dist/assets/{McpMarketplacePage-CiMIBEK5.js → McpMarketplacePage-BWTguHCs.js} +1 -1
  9. package/ui-dist/assets/{ModelConfig-ByBWO9Az.js → ModelConfig-B-oTP-Bc.js} +1 -1
  10. package/ui-dist/assets/ProvidersList-r7bD0-R0.js +1 -0
  11. package/ui-dist/assets/RemoteAccessPage-D7On6waK.js +1 -0
  12. package/ui-dist/assets/{RuntimeConfig-lLsVDbII.js → RuntimeConfig-C11xVxH9.js} +1 -1
  13. package/ui-dist/assets/{SearchConfig-CWesIP06.js → SearchConfig-BVZdCxiM.js} +1 -1
  14. package/ui-dist/assets/{SecretsConfig-BGBAbTd4.js → SecretsConfig-DuEDdC3X.js} +1 -1
  15. package/ui-dist/assets/{SessionsConfig-2E9c7egF.js → SessionsConfig-Y-Blf_-K.js} +1 -1
  16. package/ui-dist/assets/{chat-message-BvBBmQgv.js → chat-message-B6VCCEXF.js} +1 -1
  17. package/ui-dist/assets/index-DfEAJJsA.css +1 -0
  18. package/ui-dist/assets/index-DvA7S11O.js +8 -0
  19. package/ui-dist/assets/{label-BeG9gzOw.js → label-DzwitL78.js} +1 -1
  20. package/ui-dist/assets/{page-layout-DvKrImNq.js → page-layout-DEq5N_8L.js} +1 -1
  21. package/ui-dist/assets/{popover-Cekr7SZs.js → popover-CY54V8F6.js} +1 -1
  22. package/ui-dist/assets/provider-models-BOeNnjk9.js +1 -0
  23. package/ui-dist/assets/{security-config-Lj50s5Xo.js → security-config-CgbYP57d.js} +1 -1
  24. package/ui-dist/assets/skeleton-zjQZMWu9.js +1 -0
  25. package/ui-dist/assets/{status-dot-KIalr-La.js → status-dot-CU_P0tvO.js} +1 -1
  26. package/ui-dist/assets/{switch-B6gxOJ4B.js → switch-PvjTvlcs.js} +1 -1
  27. package/ui-dist/assets/{tabs-custom-PUe25N6j.js → tabs-custom-Bke5J9ny.js} +1 -1
  28. package/ui-dist/assets/{useConfirmDialog-DLJEiZon.js → useConfirmDialog-8tzzp_oW.js} +1 -1
  29. package/ui-dist/assets/{vendor-BrKF_0FH.js → vendor-CmQZsDAE.js} +69 -74
  30. package/ui-dist/index.html +3 -3
  31. package/ui-dist/assets/ProvidersList-BQue1CzS.js +0 -1
  32. package/ui-dist/assets/RemoteAccessPage-Cf8lA4Pf.js +0 -1
  33. package/ui-dist/assets/index-C-eTzuYg.js +0 -8
  34. package/ui-dist/assets/index-ChJfCPnU.css +0 -1
  35. package/ui-dist/assets/provider-models-D3B_xWXx.js +0 -1
  36. package/ui-dist/assets/skeleton-CANT565a.js +0 -1
package/dist/cli/index.js CHANGED
@@ -7,9 +7,9 @@ import { registerRemoteCommands } from "@nextclaw/remote";
7
7
 
8
8
  // src/cli/runtime.ts
9
9
  import {
10
- loadConfig as loadConfig15,
11
- saveConfig as saveConfig10,
12
- getConfigPath as getConfigPath8,
10
+ loadConfig as loadConfig17,
11
+ saveConfig as saveConfig11,
12
+ getConfigPath as getConfigPath9,
13
13
  getDataDir as getDataDir9,
14
14
  ConfigSchema as ConfigSchema2,
15
15
  getWorkspacePath as getWorkspacePath10,
@@ -17,7 +17,7 @@ import {
17
17
  MessageBus as MessageBus2,
18
18
  AgentLoop,
19
19
  ProviderManager as ProviderManager2,
20
- resolveConfigSecrets as resolveConfigSecrets3,
20
+ resolveConfigSecrets as resolveConfigSecrets4,
21
21
  APP_NAME as APP_NAME5,
22
22
  DEFAULT_WORKSPACE_DIR,
23
23
  DEFAULT_WORKSPACE_PATH
@@ -26,7 +26,7 @@ import { RemoteRuntimeActions } from "@nextclaw/remote";
26
26
  import {
27
27
  getPluginChannelBindings as getPluginChannelBindings4,
28
28
  resolvePluginChannelMessageToolHints as resolvePluginChannelMessageToolHints2,
29
- setPluginRuntimeBridge as setPluginRuntimeBridge2
29
+ setPluginRuntimeBridge as setPluginRuntimeBridge3
30
30
  } from "@nextclaw/openclaw-compat";
31
31
  import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
32
32
  import { join as join8, resolve as resolve12 } from "path";
@@ -3183,6 +3183,7 @@ import {
3183
3183
  buildConfiguredRemoteState,
3184
3184
  resolveRemoteStatusSnapshot
3185
3185
  } from "@nextclaw/remote";
3186
+ var currentProcessRemoteRuntimeState = null;
3186
3187
  function hasRunningNextclawManagedService() {
3187
3188
  const state = readServiceState();
3188
3189
  return Boolean(state && isProcessRunning(state.pid));
@@ -3218,6 +3219,11 @@ function createNextclawRemoteConnector(params = {}) {
3218
3219
  function createNextclawRemoteStatusStore(mode) {
3219
3220
  return new RemoteStatusStore(mode, {
3220
3221
  writeRemoteState: (next) => {
3222
+ currentProcessRemoteRuntimeState = next;
3223
+ const serviceState = readServiceState();
3224
+ if (!serviceState || serviceState.pid !== process.pid) {
3225
+ return;
3226
+ }
3221
3227
  updateServiceState((state) => ({
3222
3228
  ...state,
3223
3229
  remote: next
@@ -3229,7 +3235,7 @@ function buildNextclawConfiguredRemoteState(config2) {
3229
3235
  return buildConfiguredRemoteState(config2);
3230
3236
  }
3231
3237
  function readCurrentNextclawRemoteRuntimeState() {
3232
- return readServiceState()?.remote ?? null;
3238
+ return currentProcessRemoteRuntimeState ?? readServiceState()?.remote ?? null;
3233
3239
  }
3234
3240
  function resolveNextclawRemoteStatusSnapshot(config2) {
3235
3241
  return resolveRemoteStatusSnapshot({
@@ -3272,6 +3278,9 @@ async function probeLocalUi(localOrigin) {
3272
3278
  }
3273
3279
  }
3274
3280
  var RemoteCommands = class {
3281
+ constructor(deps = {}) {
3282
+ this.deps = deps;
3283
+ }
3275
3284
  updateConfig(params = {}) {
3276
3285
  const config2 = loadConfig9(getConfigPath4());
3277
3286
  const nextEnabled = typeof params.enabled === "boolean" ? params.enabled : config2.remote.enabled;
@@ -3312,10 +3321,11 @@ var RemoteCommands = class {
3312
3321
  getStatusView() {
3313
3322
  const config2 = loadConfig9(getConfigPath4());
3314
3323
  const snapshot = resolveNextclawRemoteStatusSnapshot(config2);
3324
+ const resolvedLocalOrigin = snapshot.runtime?.localOrigin ?? this.deps.currentLocalOrigin ?? resolveConfiguredLocalOrigin(config2);
3315
3325
  return {
3316
3326
  configuredEnabled: snapshot.configuredEnabled,
3317
3327
  runtime: snapshot.runtime,
3318
- localOrigin: resolveConfiguredLocalOrigin(config2),
3328
+ localOrigin: resolvedLocalOrigin,
3319
3329
  deviceName: snapshot.runtime?.deviceName ?? normalizeOptionalString3(config2.remote.deviceName) ?? hostname(),
3320
3330
  platformBase: snapshot.runtime?.platformBase ?? normalizeOptionalString3(config2.remote.platformApiBase) ?? normalizeOptionalString3(config2.providers.nextclaw?.apiBase) ?? null
3321
3331
  };
@@ -3347,7 +3357,7 @@ var RemoteCommands = class {
3347
3357
  async getDoctorView() {
3348
3358
  const config2 = loadConfig9(getConfigPath4());
3349
3359
  const snapshot = resolveNextclawRemoteStatusSnapshot(config2);
3350
- const localOrigin = resolveConfiguredLocalOrigin(config2);
3360
+ const localOrigin = snapshot.runtime?.localOrigin ?? this.deps.currentLocalOrigin ?? resolveConfiguredLocalOrigin(config2);
3351
3361
  const localUi = await probeLocalUi(localOrigin);
3352
3362
  const token = normalizeOptionalString3(config2.providers.nextclaw?.apiKey);
3353
3363
  const platformApiBase = normalizeOptionalString3(config2.remote.platformApiBase) ?? normalizeOptionalString3(config2.providers.nextclaw?.apiBase);
@@ -3699,6 +3709,9 @@ var DiagnosticsCommands = class {
3699
3709
  if (!provider) {
3700
3710
  return { name: spec.displayName ?? spec.name, configured: false, detail: "missing config" };
3701
3711
  }
3712
+ if (provider.enabled === false) {
3713
+ return { name: spec.displayName ?? spec.name, configured: false, detail: "disabled" };
3714
+ }
3702
3715
  if (spec.isLocal) {
3703
3716
  return {
3704
3717
  name: spec.displayName ?? spec.name,
@@ -3786,7 +3799,7 @@ import * as NextclawCore from "@nextclaw/core";
3786
3799
  import {
3787
3800
  getPluginChannelBindings as getPluginChannelBindings3,
3788
3801
  resolvePluginChannelMessageToolHints,
3789
- setPluginRuntimeBridge,
3802
+ setPluginRuntimeBridge as setPluginRuntimeBridge2,
3790
3803
  startPluginChannelGateways as startPluginChannelGateways2,
3791
3804
  stopPluginChannelGateways as stopPluginChannelGateways2
3792
3805
  } from "@nextclaw/openclaw-compat";
@@ -3809,8 +3822,8 @@ import {
3809
3822
  redactConfigObject
3810
3823
  } from "@nextclaw/core";
3811
3824
  var hashRaw = (raw) => createHash("sha256").update(raw).digest("hex");
3812
- var readConfigSnapshot = (getConfigPath9) => {
3813
- const path2 = getConfigPath9();
3825
+ var readConfigSnapshot = (getConfigPath10) => {
3826
+ const path2 = getConfigPath10();
3814
3827
  let raw = "";
3815
3828
  let parsed = {};
3816
3829
  if (existsSync7(path2)) {
@@ -4504,6 +4517,74 @@ var ServiceMarketplaceInstaller = class {
4504
4517
  }
4505
4518
  };
4506
4519
 
4520
+ // src/cli/commands/service-plugin-runtime-bridge.ts
4521
+ import { loadConfig as loadConfig13, resolveConfigSecrets as resolveConfigSecrets2, saveConfig as saveConfig9 } from "@nextclaw/core";
4522
+ import { setPluginRuntimeBridge } from "@nextclaw/openclaw-compat";
4523
+ function installPluginRuntimeBridge(params) {
4524
+ const { runtimePool, runtimeConfigPath, pluginChannelBindings } = params;
4525
+ setPluginRuntimeBridge({
4526
+ loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig13(), { configPath: runtimeConfigPath }), pluginChannelBindings),
4527
+ writeConfigFile: async (nextConfigView) => {
4528
+ if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
4529
+ throw new Error("plugin runtime writeConfigFile expects an object config");
4530
+ }
4531
+ const current = loadConfig13();
4532
+ const next = mergePluginConfigView(current, nextConfigView, pluginChannelBindings);
4533
+ saveConfig9(next);
4534
+ },
4535
+ dispatchReplyWithBufferedBlockDispatcher: async ({ ctx, dispatcherOptions }) => {
4536
+ const request = resolvePluginRuntimeRequest(ctx);
4537
+ if (!request) {
4538
+ return;
4539
+ }
4540
+ try {
4541
+ const response = await runtimePool.processDirect(request);
4542
+ const replyText = typeof response === "string" ? response : String(response ?? "");
4543
+ if (replyText.trim()) {
4544
+ await dispatcherOptions.deliver({ text: replyText }, { kind: "final" });
4545
+ }
4546
+ } catch (error) {
4547
+ dispatcherOptions.onError?.(error);
4548
+ throw error;
4549
+ }
4550
+ }
4551
+ });
4552
+ }
4553
+ function resolvePluginRuntimeRequest(ctx) {
4554
+ const bodyForAgent = typeof ctx.BodyForAgent === "string" ? ctx.BodyForAgent : "";
4555
+ const body = typeof ctx.Body === "string" ? ctx.Body : "";
4556
+ const content = (bodyForAgent || body).trim();
4557
+ if (!content) {
4558
+ return null;
4559
+ }
4560
+ const sessionKey = typeof ctx.SessionKey === "string" && ctx.SessionKey.trim().length > 0 ? ctx.SessionKey : void 0;
4561
+ const channel = typeof ctx.OriginatingChannel === "string" && ctx.OriginatingChannel.trim().length > 0 ? ctx.OriginatingChannel : "cli";
4562
+ const chatId = typeof ctx.OriginatingTo === "string" && ctx.OriginatingTo.trim().length > 0 ? ctx.OriginatingTo : typeof ctx.SenderId === "string" && ctx.SenderId.trim().length > 0 ? ctx.SenderId : "direct";
4563
+ const agentId = typeof ctx.AgentId === "string" ? ctx.AgentId : void 0;
4564
+ const modelOverride = resolveModelOverride(ctx);
4565
+ const accountId = typeof ctx.AccountId === "string" && ctx.AccountId.trim().length > 0 ? ctx.AccountId : void 0;
4566
+ return {
4567
+ content,
4568
+ sessionKey,
4569
+ channel,
4570
+ chatId,
4571
+ agentId,
4572
+ metadata: {
4573
+ ...accountId ? { account_id: accountId } : {},
4574
+ ...modelOverride ? { model: modelOverride } : {}
4575
+ }
4576
+ };
4577
+ }
4578
+ function resolveModelOverride(ctx) {
4579
+ if (typeof ctx.Model === "string" && ctx.Model.trim().length > 0) {
4580
+ return ctx.Model.trim();
4581
+ }
4582
+ if (typeof ctx.AgentModel === "string" && ctx.AgentModel.trim().length > 0) {
4583
+ return ctx.AgentModel.trim();
4584
+ }
4585
+ return void 0;
4586
+ }
4587
+
4507
4588
  // src/cli/commands/service-plugin-reload.ts
4508
4589
  import { getWorkspacePath as getWorkspacePath6 } from "@nextclaw/core";
4509
4590
  import {
@@ -6469,11 +6550,12 @@ async function createUiNcpAgent(params) {
6469
6550
  // src/cli/commands/service-remote-runtime.ts
6470
6551
  import { RemoteServiceModule } from "@nextclaw/remote";
6471
6552
  function createManagedRemoteModule(params) {
6472
- if (!params.config.ui.enabled) {
6553
+ if (!params.uiEnabled) {
6473
6554
  return null;
6474
6555
  }
6475
6556
  return new RemoteServiceModule({
6476
- config: params.config,
6557
+ loadConfig: params.loadConfig,
6558
+ uiEnabled: params.uiEnabled,
6477
6559
  localOrigin: params.localOrigin,
6478
6560
  statusStore: createNextclawRemoteStatusStore("service"),
6479
6561
  createConnector: (logger) => createNextclawRemoteConnector({ logger }),
@@ -6484,6 +6566,13 @@ function createManagedRemoteModule(params) {
6484
6566
  }
6485
6567
  });
6486
6568
  }
6569
+ function createManagedRemoteModuleForUi(params) {
6570
+ return createManagedRemoteModule({
6571
+ loadConfig: params.loadConfig,
6572
+ uiEnabled: params.uiConfig.enabled,
6573
+ localOrigin: resolveUiApiBase(params.uiConfig.host, params.uiConfig.port)
6574
+ });
6575
+ }
6487
6576
  function writeInitialManagedServiceState(params) {
6488
6577
  writeServiceState({
6489
6578
  pid: params.snapshot.pid,
@@ -6520,9 +6609,169 @@ function writeReadyManagedServiceState(params) {
6520
6609
  }
6521
6610
 
6522
6611
  // src/cli/commands/remote-access-host.ts
6523
- import { getConfigPath as getConfigPath6, loadConfig as loadConfig13 } from "@nextclaw/core";
6612
+ import { getConfigPath as getConfigPath7, loadConfig as loadConfig15 } from "@nextclaw/core";
6613
+
6614
+ // src/cli/commands/remote-access-service-control.ts
6615
+ import { getConfigPath as getConfigPath6, loadConfig as loadConfig14 } from "@nextclaw/core";
6524
6616
  import { spawn as spawn2 } from "child_process";
6525
6617
  var FORCED_PUBLIC_UI_HOST = "0.0.0.0";
6618
+ function resolveRemoteServiceView(currentUi) {
6619
+ if (currentUi) {
6620
+ return {
6621
+ running: true,
6622
+ currentProcess: true,
6623
+ pid: process.pid,
6624
+ uiUrl: resolveUiApiBase(currentUi.host, currentUi.port),
6625
+ uiPort: currentUi.port
6626
+ };
6627
+ }
6628
+ const serviceState = readServiceState();
6629
+ const serviceRunning = Boolean(serviceState && isProcessRunning(serviceState.pid));
6630
+ return {
6631
+ running: serviceRunning,
6632
+ currentProcess: Boolean(serviceRunning && serviceState?.pid === process.pid),
6633
+ ...serviceState?.pid ? { pid: serviceState.pid } : {},
6634
+ ...serviceState?.uiUrl ? { uiUrl: serviceState.uiUrl } : {},
6635
+ ...typeof serviceState?.uiPort === "number" ? { uiPort: serviceState.uiPort } : {}
6636
+ };
6637
+ }
6638
+ async function controlRemoteService(action, deps) {
6639
+ if (deps.remoteRuntimeController) {
6640
+ return controlCurrentProcessRuntime(action, deps.remoteRuntimeController);
6641
+ }
6642
+ return controlManagedService(action, deps);
6643
+ }
6644
+ async function controlCurrentProcessRuntime(action, controller) {
6645
+ if (action === "start") {
6646
+ await controller.start();
6647
+ return { accepted: true, action, message: "Remote runtime started." };
6648
+ }
6649
+ if (action === "stop") {
6650
+ await controller.stop();
6651
+ return { accepted: true, action, message: "Remote runtime stopped." };
6652
+ }
6653
+ await controller.restart();
6654
+ return { accepted: true, action, message: "Remote runtime restarted." };
6655
+ }
6656
+ async function controlManagedService(action, deps) {
6657
+ const state = readServiceState();
6658
+ const running = Boolean(state && isProcessRunning(state.pid));
6659
+ const currentProcess = Boolean(running && state?.pid === process.pid);
6660
+ const uiOverrides = resolveManagedUiOverrides();
6661
+ if (action === "start") {
6662
+ if (running) {
6663
+ return {
6664
+ accepted: true,
6665
+ action,
6666
+ message: currentProcess ? "Managed service is already running for this UI." : "Managed service is already running."
6667
+ };
6668
+ }
6669
+ await deps.serviceCommands.startService({ uiOverrides, open: false });
6670
+ return { accepted: true, action, message: "Managed service started." };
6671
+ }
6672
+ if (!running) {
6673
+ if (action === "restart") {
6674
+ await deps.serviceCommands.startService({ uiOverrides, open: false });
6675
+ return {
6676
+ accepted: true,
6677
+ action,
6678
+ message: "Managed service was not running and has been started."
6679
+ };
6680
+ }
6681
+ return { accepted: true, action, message: "No managed service is currently running." };
6682
+ }
6683
+ if (currentProcess) {
6684
+ if (action === "restart") {
6685
+ await deps.requestManagedServiceRestart({ uiPort: uiOverrides.port ?? 18791 });
6686
+ } else {
6687
+ scheduleManagedSelfStop();
6688
+ }
6689
+ return {
6690
+ accepted: true,
6691
+ action,
6692
+ message: action === "restart" ? "Restart scheduled. This page may disconnect for a few seconds." : "Stop scheduled. This page will disconnect shortly."
6693
+ };
6694
+ }
6695
+ if (action === "stop") {
6696
+ await deps.serviceCommands.stopService();
6697
+ return { accepted: true, action, message: "Managed service stopped." };
6698
+ }
6699
+ await deps.serviceCommands.stopService();
6700
+ await deps.serviceCommands.startService({ uiOverrides, open: false });
6701
+ return { accepted: true, action, message: "Managed service restarted." };
6702
+ }
6703
+ function resolveManagedUiOverrides() {
6704
+ const config2 = loadConfig14(getConfigPath6());
6705
+ const resolved = resolveUiConfig(config2, {
6706
+ enabled: true,
6707
+ host: FORCED_PUBLIC_UI_HOST,
6708
+ open: false
6709
+ });
6710
+ return {
6711
+ enabled: true,
6712
+ host: FORCED_PUBLIC_UI_HOST,
6713
+ open: false,
6714
+ port: resolved.port
6715
+ };
6716
+ }
6717
+ function scheduleManagedSelfStop() {
6718
+ launchManagedSelfControl();
6719
+ }
6720
+ function launchManagedSelfControl(params = {}) {
6721
+ const script = [
6722
+ 'const { spawn } = require("node:child_process");',
6723
+ 'const { rmSync } = require("node:fs");',
6724
+ `const parentPid = ${process.pid};`,
6725
+ `const serviceStatePath = ${JSON.stringify(resolveServiceStatePath())};`,
6726
+ `const command = ${JSON.stringify(params.command ?? null)};`,
6727
+ `const args = ${JSON.stringify(params.args ?? [])};`,
6728
+ `const cwd = ${JSON.stringify(process.cwd())};`,
6729
+ "const env = process.env;",
6730
+ "function isRunning(pid) {",
6731
+ " try {",
6732
+ " process.kill(pid, 0);",
6733
+ " return true;",
6734
+ " } catch {",
6735
+ " return false;",
6736
+ " }",
6737
+ "}",
6738
+ "setTimeout(() => {",
6739
+ " try {",
6740
+ " process.kill(parentPid, 'SIGTERM');",
6741
+ " } catch {}",
6742
+ "}, 150);",
6743
+ "const startedAt = Date.now();",
6744
+ "const maxWaitMs = 30000;",
6745
+ "const timer = setInterval(() => {",
6746
+ " if (isRunning(parentPid)) {",
6747
+ " if (Date.now() - startedAt > maxWaitMs) {",
6748
+ " try {",
6749
+ " process.kill(parentPid, 'SIGKILL');",
6750
+ " } catch {}",
6751
+ " }",
6752
+ " return;",
6753
+ " }",
6754
+ " clearInterval(timer);",
6755
+ " try {",
6756
+ " rmSync(serviceStatePath, { force: true });",
6757
+ " } catch {}",
6758
+ " if (command) {",
6759
+ " const child = spawn(command, args, { detached: true, stdio: 'ignore', cwd, env });",
6760
+ " child.unref();",
6761
+ " }",
6762
+ " process.exit(0);",
6763
+ "}, 250);"
6764
+ ].join("");
6765
+ const helper = spawn2(process.execPath, ["-e", script], {
6766
+ detached: true,
6767
+ stdio: "ignore",
6768
+ env: process.env,
6769
+ cwd: process.cwd()
6770
+ });
6771
+ helper.unref();
6772
+ }
6773
+
6774
+ // src/cli/commands/remote-access-host.ts
6526
6775
  function normalizeOptionalString5(value) {
6527
6776
  if (typeof value !== "string") {
6528
6777
  return null;
@@ -6568,22 +6817,13 @@ var RemoteAccessHost = class {
6568
6817
  this.deps = deps;
6569
6818
  }
6570
6819
  getStatus() {
6571
- const config2 = loadConfig13(getConfigPath6());
6820
+ const config2 = loadConfig15(getConfigPath7());
6572
6821
  const status = this.deps.remoteCommands.getStatusView();
6573
- const serviceState = readServiceState();
6574
- const serviceRunning = Boolean(serviceState && isProcessRunning(serviceState.pid));
6575
6822
  const account = this.readAccountView({
6576
6823
  token: normalizeOptionalString5(config2.providers.nextclaw?.apiKey),
6577
6824
  apiBase: normalizeOptionalString5(config2.providers.nextclaw?.apiBase),
6578
6825
  platformBase: status.platformBase
6579
6826
  });
6580
- const service = {
6581
- running: serviceRunning,
6582
- currentProcess: Boolean(serviceRunning && serviceState?.pid === process.pid),
6583
- ...serviceState?.pid ? { pid: serviceState.pid } : {},
6584
- ...serviceState?.uiUrl ? { uiUrl: serviceState.uiUrl } : {},
6585
- ...typeof serviceState?.uiPort === "number" ? { uiPort: serviceState.uiPort } : {}
6586
- };
6587
6827
  return {
6588
6828
  account,
6589
6829
  settings: {
@@ -6591,7 +6831,7 @@ var RemoteAccessHost = class {
6591
6831
  deviceName: config2.remote.deviceName,
6592
6832
  platformApiBase: config2.remote.platformApiBase
6593
6833
  },
6594
- service,
6834
+ service: resolveRemoteServiceView(this.deps.currentUi),
6595
6835
  localOrigin: status.localOrigin,
6596
6836
  configuredEnabled: status.configuredEnabled,
6597
6837
  platformBase: status.platformBase,
@@ -6614,7 +6854,7 @@ var RemoteAccessHost = class {
6614
6854
  };
6615
6855
  }
6616
6856
  async pollBrowserAuth(input) {
6617
- const config2 = loadConfig13(getConfigPath6());
6857
+ const config2 = loadConfig15(getConfigPath7());
6618
6858
  const result = await this.deps.platformAuthCommands.pollBrowserAuth({
6619
6859
  apiBase: normalizeOptionalString5(input.apiBase) ?? normalizeOptionalString5(config2.remote.platformApiBase) ?? normalizeOptionalString5(config2.providers.nextclaw?.apiBase) ?? void 0,
6620
6860
  sessionId: input.sessionId
@@ -6652,92 +6892,7 @@ var RemoteAccessHost = class {
6652
6892
  };
6653
6893
  }
6654
6894
  async controlService(action) {
6655
- const state = readServiceState();
6656
- const running = Boolean(state && isProcessRunning(state.pid));
6657
- const currentProcess = Boolean(running && state?.pid === process.pid);
6658
- const uiOverrides = this.resolveManagedUiOverrides();
6659
- if (action === "start") {
6660
- if (running) {
6661
- return {
6662
- accepted: true,
6663
- action,
6664
- message: currentProcess ? "Managed service is already running for this UI." : "Managed service is already running."
6665
- };
6666
- }
6667
- await this.deps.serviceCommands.startService({
6668
- uiOverrides,
6669
- open: false
6670
- });
6671
- return {
6672
- accepted: true,
6673
- action,
6674
- message: "Managed service started."
6675
- };
6676
- }
6677
- if (!running) {
6678
- if (action === "restart") {
6679
- await this.deps.serviceCommands.startService({
6680
- uiOverrides,
6681
- open: false
6682
- });
6683
- return {
6684
- accepted: true,
6685
- action,
6686
- message: "Managed service was not running and has been started."
6687
- };
6688
- }
6689
- return {
6690
- accepted: true,
6691
- action,
6692
- message: "No managed service is currently running."
6693
- };
6694
- }
6695
- if (currentProcess) {
6696
- if (action === "restart") {
6697
- await this.deps.requestManagedServiceRestart({
6698
- uiPort: uiOverrides.port ?? 18791
6699
- });
6700
- } else {
6701
- this.scheduleSelfStop();
6702
- }
6703
- return {
6704
- accepted: true,
6705
- action,
6706
- message: action === "restart" ? "Restart scheduled. This page may disconnect for a few seconds." : "Stop scheduled. This page will disconnect shortly."
6707
- };
6708
- }
6709
- if (action === "stop") {
6710
- await this.deps.serviceCommands.stopService();
6711
- return {
6712
- accepted: true,
6713
- action,
6714
- message: "Managed service stopped."
6715
- };
6716
- }
6717
- await this.deps.serviceCommands.stopService();
6718
- await this.deps.serviceCommands.startService({
6719
- uiOverrides,
6720
- open: false
6721
- });
6722
- return {
6723
- accepted: true,
6724
- action,
6725
- message: "Managed service restarted."
6726
- };
6727
- }
6728
- resolveManagedUiOverrides() {
6729
- const config2 = loadConfig13(getConfigPath6());
6730
- const resolved = resolveUiConfig(config2, {
6731
- enabled: true,
6732
- host: FORCED_PUBLIC_UI_HOST,
6733
- open: false
6734
- });
6735
- return {
6736
- enabled: true,
6737
- host: FORCED_PUBLIC_UI_HOST,
6738
- open: false,
6739
- port: resolved.port
6740
- };
6895
+ return controlRemoteService(action, this.deps);
6741
6896
  }
6742
6897
  readAccountView(params) {
6743
6898
  if (!isPlatformSessionToken2(params.token)) {
@@ -6758,62 +6913,6 @@ var RemoteAccessHost = class {
6758
6913
  platformBase: params.platformBase
6759
6914
  };
6760
6915
  }
6761
- scheduleSelfStop() {
6762
- this.launchManagedSelfControl();
6763
- }
6764
- launchManagedSelfControl(params = {}) {
6765
- const script = [
6766
- 'const { spawn } = require("node:child_process");',
6767
- 'const { rmSync } = require("node:fs");',
6768
- `const parentPid = ${process.pid};`,
6769
- `const serviceStatePath = ${JSON.stringify(resolveServiceStatePath())};`,
6770
- `const command = ${JSON.stringify(params.command ?? null)};`,
6771
- `const args = ${JSON.stringify(params.args ?? [])};`,
6772
- `const cwd = ${JSON.stringify(process.cwd())};`,
6773
- "const env = process.env;",
6774
- "function isRunning(pid) {",
6775
- " try {",
6776
- " process.kill(pid, 0);",
6777
- " return true;",
6778
- " } catch {",
6779
- " return false;",
6780
- " }",
6781
- "}",
6782
- "setTimeout(() => {",
6783
- " try {",
6784
- " process.kill(parentPid, 'SIGTERM');",
6785
- " } catch {}",
6786
- "}, 150);",
6787
- "const startedAt = Date.now();",
6788
- "const maxWaitMs = 30000;",
6789
- "const timer = setInterval(() => {",
6790
- " if (isRunning(parentPid)) {",
6791
- " if (Date.now() - startedAt > maxWaitMs) {",
6792
- " try {",
6793
- " process.kill(parentPid, 'SIGKILL');",
6794
- " } catch {}",
6795
- " }",
6796
- " return;",
6797
- " }",
6798
- " clearInterval(timer);",
6799
- " try {",
6800
- " rmSync(serviceStatePath, { force: true });",
6801
- " } catch {}",
6802
- " if (command) {",
6803
- " const child = spawn(command, args, { detached: true, stdio: 'ignore', cwd, env });",
6804
- " child.unref();",
6805
- " }",
6806
- " process.exit(0);",
6807
- "}, 250);"
6808
- ].join("");
6809
- const helper = spawn2(process.execPath, ["-e", script], {
6810
- detached: true,
6811
- stdio: "ignore",
6812
- env: process.env,
6813
- cwd: process.cwd()
6814
- });
6815
- helper.unref();
6816
- }
6817
6916
  };
6818
6917
 
6819
6918
  // src/cli/commands/service-remote-access.ts
@@ -6830,11 +6929,24 @@ function requestManagedServiceRestart(requestRestart, options = {}) {
6830
6929
  });
6831
6930
  }
6832
6931
  function createRemoteAccessHost(params) {
6932
+ const currentLocalOrigin = `http://127.0.0.1:${params.uiConfig.port}`;
6833
6933
  return new RemoteAccessHost({
6834
6934
  serviceCommands: params.serviceCommands,
6835
6935
  requestManagedServiceRestart: (options) => requestManagedServiceRestart(params.requestRestart, options),
6836
- remoteCommands: new RemoteCommands(),
6837
- platformAuthCommands: new PlatformAuthCommands()
6936
+ remoteCommands: new RemoteCommands({ currentLocalOrigin }),
6937
+ platformAuthCommands: new PlatformAuthCommands(),
6938
+ currentUi: params.uiConfig,
6939
+ remoteRuntimeController: params.remoteModule ? {
6940
+ start: async () => {
6941
+ params.remoteModule?.start();
6942
+ },
6943
+ stop: async () => {
6944
+ await params.remoteModule?.stop();
6945
+ },
6946
+ restart: async () => {
6947
+ await params.remoteModule?.restart();
6948
+ }
6949
+ } : null
6838
6950
  });
6839
6951
  }
6840
6952
 
@@ -7462,18 +7574,18 @@ var {
7462
7574
  ChannelManager: ChannelManager2,
7463
7575
  CronService: CronService2,
7464
7576
  getApiBase,
7465
- getConfigPath: getConfigPath7,
7577
+ getConfigPath: getConfigPath8,
7466
7578
  getDataDir: getDataDir7,
7467
7579
  getProvider,
7468
7580
  getProviderName,
7469
7581
  getWorkspacePath: getWorkspacePath9,
7470
7582
  HeartbeatService,
7471
7583
  LiteLLMProvider,
7472
- loadConfig: loadConfig14,
7584
+ loadConfig: loadConfig16,
7473
7585
  MessageBus,
7474
7586
  ProviderManager,
7475
- resolveConfigSecrets: resolveConfigSecrets2,
7476
- saveConfig: saveConfig9,
7587
+ resolveConfigSecrets: resolveConfigSecrets3,
7588
+ saveConfig: saveConfig10,
7477
7589
  SessionManager,
7478
7590
  parseAgentScopedSessionKey: parseAgentScopedSessionKey3
7479
7591
  } = NextclawCore;
@@ -7493,8 +7605,8 @@ var ServiceCommands = class {
7493
7605
  async startGateway(options = {}) {
7494
7606
  this.applyLiveConfigReload = null;
7495
7607
  this.liveUiNcpAgent = null;
7496
- const runtimeConfigPath = getConfigPath7();
7497
- const config2 = resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath });
7608
+ const runtimeConfigPath = getConfigPath8();
7609
+ const config2 = resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath });
7498
7610
  const workspace = getWorkspacePath9(config2.agents.defaults.workspace);
7499
7611
  let pluginRegistry = loadPluginRegistry(config2, workspace);
7500
7612
  let extensionRegistry = toExtensionRegistry(pluginRegistry);
@@ -7511,7 +7623,10 @@ var ServiceCommands = class {
7511
7623
  const cron2 = new CronService2(cronStorePath);
7512
7624
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7513
7625
  const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
7514
- const localOrigin = resolveUiApiBase(uiConfig.host, uiConfig.port);
7626
+ const remoteModule = createManagedRemoteModuleForUi({
7627
+ loadConfig: () => resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7628
+ uiConfig
7629
+ });
7515
7630
  if (!provider) {
7516
7631
  console.warn("Warning: No API key configured. The gateway is running, but agent replies are disabled until provider config is set.");
7517
7632
  }
@@ -7523,7 +7638,7 @@ var ServiceCommands = class {
7523
7638
  sessionManager,
7524
7639
  providerManager,
7525
7640
  makeProvider: (nextConfig) => this.makeProvider(nextConfig, { allowMissing: true }) ?? this.makeMissingProvider(nextConfig),
7526
- loadConfig: () => resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7641
+ loadConfig: () => resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7527
7642
  getExtensionChannels: () => extensionRegistry.channels,
7528
7643
  onRestartRequired: (paths) => {
7529
7644
  void this.deps.requestRestart({
@@ -7534,14 +7649,14 @@ var ServiceCommands = class {
7534
7649
  }
7535
7650
  });
7536
7651
  this.applyLiveConfigReload = async () => {
7537
- await reloader.applyReloadPlan(resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }));
7652
+ await reloader.applyReloadPlan(resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }));
7538
7653
  };
7539
7654
  const gatewayController = new GatewayControllerImpl({
7540
7655
  reloader,
7541
7656
  cron: cron2,
7542
7657
  sessionManager,
7543
- getConfigPath: getConfigPath7,
7544
- saveConfig: saveConfig9,
7658
+ getConfigPath: getConfigPath8,
7659
+ saveConfig: saveConfig10,
7545
7660
  requestRestart: async (options2) => {
7546
7661
  await this.deps.requestRestart({
7547
7662
  reason: options2?.reason ?? "gateway tool restart",
@@ -7567,7 +7682,7 @@ var ServiceCommands = class {
7567
7682
  resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
7568
7683
  registry: pluginRegistry,
7569
7684
  channel,
7570
- cfg: resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7685
+ cfg: resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7571
7686
  accountId
7572
7687
  })
7573
7688
  });
@@ -7599,48 +7714,10 @@ var ServiceCommands = class {
7599
7714
  await this.liveUiNcpAgent?.applyMcpConfig?.(nextConfig);
7600
7715
  });
7601
7716
  let pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
7602
- setPluginRuntimeBridge({
7603
- loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }), pluginChannelBindings),
7604
- writeConfigFile: async (nextConfigView) => {
7605
- if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
7606
- throw new Error("plugin runtime writeConfigFile expects an object config");
7607
- }
7608
- const current = loadConfig14();
7609
- const next = mergePluginConfigView(current, nextConfigView, pluginChannelBindings);
7610
- saveConfig9(next);
7611
- },
7612
- dispatchReplyWithBufferedBlockDispatcher: async ({ ctx, dispatcherOptions }) => {
7613
- const bodyForAgent = typeof ctx.BodyForAgent === "string" ? ctx.BodyForAgent : "";
7614
- const body = typeof ctx.Body === "string" ? ctx.Body : "";
7615
- const content = (bodyForAgent || body).trim();
7616
- if (!content) {
7617
- return;
7618
- }
7619
- const sessionKey = typeof ctx.SessionKey === "string" && ctx.SessionKey.trim().length > 0 ? ctx.SessionKey : void 0;
7620
- const channel = typeof ctx.OriginatingChannel === "string" && ctx.OriginatingChannel.trim().length > 0 ? ctx.OriginatingChannel : "cli";
7621
- const chatId = typeof ctx.OriginatingTo === "string" && ctx.OriginatingTo.trim().length > 0 ? ctx.OriginatingTo : typeof ctx.SenderId === "string" && ctx.SenderId.trim().length > 0 ? ctx.SenderId : "direct";
7622
- const modelOverride = typeof ctx.Model === "string" && ctx.Model?.trim().length ? ctx.Model.trim() : typeof ctx.AgentModel === "string" && ctx.AgentModel?.trim().length ? ctx.AgentModel.trim() : void 0;
7623
- try {
7624
- const response = await runtimePool.processDirect({
7625
- content,
7626
- sessionKey,
7627
- channel,
7628
- chatId,
7629
- agentId: typeof ctx.AgentId === "string" ? ctx.AgentId : void 0,
7630
- metadata: {
7631
- ...typeof ctx.AccountId === "string" && ctx.AccountId.trim().length > 0 ? { account_id: ctx.AccountId } : {},
7632
- ...modelOverride ? { model: modelOverride } : {}
7633
- }
7634
- });
7635
- const replyText = typeof response === "string" ? response : String(response ?? "");
7636
- if (replyText.trim()) {
7637
- await dispatcherOptions.deliver({ text: replyText }, { kind: "final" });
7638
- }
7639
- } catch (error) {
7640
- dispatcherOptions.onError?.(error);
7641
- throw error;
7642
- }
7643
- }
7717
+ installPluginRuntimeBridge({
7718
+ runtimePool,
7719
+ runtimeConfigPath,
7720
+ pluginChannelBindings
7644
7721
  });
7645
7722
  cron2.onJob = async (job) => {
7646
7723
  const response = await runtimePool.processDirect({
@@ -7681,16 +7758,16 @@ var ServiceCommands = class {
7681
7758
  providerManager,
7682
7759
  bus,
7683
7760
  gatewayController,
7684
- () => resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7761
+ () => resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7685
7762
  () => extensionRegistry,
7686
7763
  ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
7687
7764
  registry: pluginRegistry,
7688
7765
  channel,
7689
- cfg: resolveConfigSecrets2(loadConfig14(), { configPath: runtimeConfigPath }),
7766
+ cfg: resolveConfigSecrets3(loadConfig16(), { configPath: runtimeConfigPath }),
7690
7767
  accountId
7691
- })
7768
+ }),
7769
+ remoteModule
7692
7770
  );
7693
- const remoteModule = createManagedRemoteModule({ config: config2, localOrigin });
7694
7771
  await startGatewaySupportServices({
7695
7772
  cronJobs: cron2.status().jobs,
7696
7773
  remoteModule,
@@ -7713,7 +7790,7 @@ var ServiceCommands = class {
7713
7790
  this.liveUiNcpAgent = null;
7714
7791
  await remoteModule?.stop();
7715
7792
  await stopPluginChannelGateways2(pluginGatewayHandles);
7716
- setPluginRuntimeBridge(null);
7793
+ setPluginRuntimeBridge2(null);
7717
7794
  }
7718
7795
  }
7719
7796
  normalizeOptionalString(value) {
@@ -7724,7 +7801,7 @@ var ServiceCommands = class {
7724
7801
  return trimmed || void 0;
7725
7802
  }
7726
7803
  watchConfigFile(reloader) {
7727
- const configPath = resolve10(getConfigPath7());
7804
+ const configPath = resolve10(getConfigPath8());
7728
7805
  const watcher = chokidar.watch(configPath, {
7729
7806
  ignoreInitial: true,
7730
7807
  awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
@@ -7845,7 +7922,7 @@ var ServiceCommands = class {
7845
7922
  });
7846
7923
  }
7847
7924
  async runForeground(options) {
7848
- const config2 = loadConfig14();
7925
+ const config2 = loadConfig16();
7849
7926
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7850
7927
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
7851
7928
  if (options.open) {
@@ -7858,7 +7935,7 @@ var ServiceCommands = class {
7858
7935
  });
7859
7936
  }
7860
7937
  async startService(options) {
7861
- const config2 = loadConfig14();
7938
+ const config2 = loadConfig16();
7862
7939
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
7863
7940
  const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
7864
7941
  const apiUrl = `${uiUrl}/api`;
@@ -8266,7 +8343,7 @@ var ServiceCommands = class {
8266
8343
  return null;
8267
8344
  }
8268
8345
  console.error("Error: No API key configured.");
8269
- console.error(`Set one in ${getConfigPath7()} under providers section`);
8346
+ console.error(`Set one in ${getConfigPath8()} under providers section`);
8270
8347
  process.exit(1);
8271
8348
  }
8272
8349
  return new LiteLLMProvider({
@@ -8306,7 +8383,7 @@ var ServiceCommands = class {
8306
8383
  console.log(` - Check status: ${APP_NAME3} status`);
8307
8384
  console.log(` - If you need to stop the service, run: ${APP_NAME3} stop`);
8308
8385
  }
8309
- async startUiIfEnabled(uiConfig, uiStaticDir, cronService, runtimePool, sessionManager, providerManager, bus, gatewayController, getConfig, getExtensionRegistry, resolveMessageToolHints) {
8386
+ async startUiIfEnabled(uiConfig, uiStaticDir, cronService, runtimePool, sessionManager, providerManager, bus, gatewayController, getConfig, getExtensionRegistry, resolveMessageToolHints, remoteModule) {
8310
8387
  if (!uiConfig.enabled) {
8311
8388
  return;
8312
8389
  }
@@ -8387,11 +8464,16 @@ var ServiceCommands = class {
8387
8464
  runCliSubcommand: (args) => this.runCliSubcommand(args),
8388
8465
  installBuiltinSkill: (slug, force) => this.installBuiltinMarketplaceSkill(slug, force)
8389
8466
  }).createInstaller();
8390
- const remoteAccess = createRemoteAccessHost({ serviceCommands: this, requestRestart: this.deps.requestRestart });
8467
+ const remoteAccess = createRemoteAccessHost({
8468
+ serviceCommands: this,
8469
+ requestRestart: this.deps.requestRestart,
8470
+ uiConfig,
8471
+ remoteModule
8472
+ });
8391
8473
  const uiServer = startUiServer({
8392
8474
  host: uiConfig.host,
8393
8475
  port: uiConfig.port,
8394
- configPath: getConfigPath7(),
8476
+ configPath: getConfigPath8(),
8395
8477
  productVersion: getPackageVersion(),
8396
8478
  staticDir: uiStaticDir ?? void 0,
8397
8479
  cronService,
@@ -8480,7 +8562,7 @@ var ServiceCommands = class {
8480
8562
  }
8481
8563
  }
8482
8564
  installBuiltinMarketplaceSkill(slug, force) {
8483
- const workspace = getWorkspacePath9(loadConfig14().agents.defaults.workspace);
8565
+ const workspace = getWorkspacePath9(loadConfig16().agents.defaults.workspace);
8484
8566
  const destination = join6(workspace, "skills", slug);
8485
8567
  const destinationSkillFile = join6(destination, "SKILL.md");
8486
8568
  if (existsSync10(destinationSkillFile) && !force) {
@@ -8985,14 +9067,14 @@ var CliRuntime = class {
8985
9067
  const source = options.source ?? "init";
8986
9068
  const prefix = options.auto ? "Auto init" : "Init";
8987
9069
  const force = Boolean(options.force);
8988
- const configPath = getConfigPath8();
9070
+ const configPath = getConfigPath9();
8989
9071
  let createdConfig = false;
8990
9072
  if (!existsSync12(configPath)) {
8991
9073
  const config3 = ConfigSchema2.parse({});
8992
- saveConfig10(config3);
9074
+ saveConfig11(config3);
8993
9075
  createdConfig = true;
8994
9076
  }
8995
- const config2 = loadConfig15();
9077
+ const config2 = loadConfig17();
8996
9078
  const workspaceSetting = config2.agents.defaults.workspace;
8997
9079
  const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
8998
9080
  const workspaceExisted = existsSync12(workspacePath);
@@ -9118,16 +9200,16 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9118
9200
  await this.serviceCommands.stopService();
9119
9201
  }
9120
9202
  async agent(opts) {
9121
- const configPath = getConfigPath8();
9122
- const config2 = resolveConfigSecrets3(loadConfig15(), { configPath });
9203
+ const configPath = getConfigPath9();
9204
+ const config2 = resolveConfigSecrets4(loadConfig17(), { configPath });
9123
9205
  const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
9124
9206
  const pluginRegistry = loadPluginRegistry(config2, workspace);
9125
9207
  const extensionRegistry = toExtensionRegistry(pluginRegistry);
9126
9208
  logPluginDiagnostics(pluginRegistry);
9127
9209
  const pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
9128
- setPluginRuntimeBridge2({
9210
+ setPluginRuntimeBridge3({
9129
9211
  loadConfig: () => toPluginConfigView(
9130
- resolveConfigSecrets3(loadConfig15(), { configPath }),
9212
+ resolveConfigSecrets4(loadConfig17(), { configPath }),
9131
9213
  pluginChannelBindings
9132
9214
  ),
9133
9215
  writeConfigFile: async (nextConfigView) => {
@@ -9136,13 +9218,13 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9136
9218
  "plugin runtime writeConfigFile expects an object config"
9137
9219
  );
9138
9220
  }
9139
- const current = loadConfig15();
9221
+ const current = loadConfig17();
9140
9222
  const next = mergePluginConfigView(
9141
9223
  current,
9142
9224
  nextConfigView,
9143
9225
  pluginChannelBindings
9144
9226
  );
9145
- saveConfig10(next);
9227
+ saveConfig11(next);
9146
9228
  }
9147
9229
  });
9148
9230
  try {
@@ -9168,7 +9250,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9168
9250
  resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
9169
9251
  registry: pluginRegistry,
9170
9252
  channel,
9171
- cfg: resolveConfigSecrets3(loadConfig15(), { configPath }),
9253
+ cfg: resolveConfigSecrets4(loadConfig17(), { configPath }),
9172
9254
  accountId
9173
9255
  })
9174
9256
  });
@@ -9222,7 +9304,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9222
9304
  printAgentResponse(response);
9223
9305
  }
9224
9306
  } finally {
9225
- setPluginRuntimeBridge2(null);
9307
+ setPluginRuntimeBridge3(null);
9226
9308
  }
9227
9309
  }
9228
9310
  async update(opts) {
@@ -9363,7 +9445,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9363
9445
  await this.diagnosticsCommands.doctor(opts);
9364
9446
  }
9365
9447
  async skillsInstall(options) {
9366
- const config2 = loadConfig15();
9448
+ const config2 = loadConfig17();
9367
9449
  const workdir = resolveSkillsInstallWorkdir({
9368
9450
  explicitWorkdir: options.workdir,
9369
9451
  configuredWorkspace: config2.agents.defaults.workspace