nextclaw 0.15.7 → 0.15.8

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 (27) hide show
  1. package/dist/cli/index.js +121 -89
  2. package/package.json +9 -9
  3. package/ui-dist/assets/{ChannelsList-DJ7ab8I2.js → ChannelsList-crliTYFY.js} +1 -1
  4. package/ui-dist/assets/{ChatPage-BLPRATYE.js → ChatPage-D62rq89Z.js} +1 -1
  5. package/ui-dist/assets/{DocBrowser-CjN_yaEf.js → DocBrowser-jL7EPfFz.js} +1 -1
  6. package/ui-dist/assets/{LogoBadge-CkZsATHX.js → LogoBadge-zJtu1O-N.js} +1 -1
  7. package/ui-dist/assets/{MarketplacePage-BFhohJco.js → MarketplacePage-CoD2WPY8.js} +1 -1
  8. package/ui-dist/assets/{McpMarketplacePage-c8vjHO0A.js → McpMarketplacePage-CVipuaD2.js} +1 -1
  9. package/ui-dist/assets/{ModelConfig-CSGq2NC4.js → ModelConfig-BRVQsNen.js} +1 -1
  10. package/ui-dist/assets/{ProvidersList-DmBQ8OF-.js → ProvidersList-pk-T1nyn.js} +1 -1
  11. package/ui-dist/assets/{RemoteAccessPage-NVr19yJR.js → RemoteAccessPage-BHgBQkju.js} +1 -1
  12. package/ui-dist/assets/{RuntimeConfig-CGETL6Yu.js → RuntimeConfig-DuMTIFc2.js} +1 -1
  13. package/ui-dist/assets/{SearchConfig-DE3LnLxY.js → SearchConfig-B6tNa347.js} +1 -1
  14. package/ui-dist/assets/{SecretsConfig-D2FPk5Yu.js → SecretsConfig-D2PAIXVI.js} +1 -1
  15. package/ui-dist/assets/{SessionsConfig-C_9hUwA8.js → SessionsConfig-BuNjB4P2.js} +1 -1
  16. package/ui-dist/assets/{chat-message-QHCI1bOU.js → chat-message-DO23l97K.js} +1 -1
  17. package/ui-dist/assets/{index-BLzicsBO.js → index-B7YuQ6xv.js} +6 -6
  18. package/ui-dist/assets/{label-X47yzn0H.js → label-CPzVnKyC.js} +1 -1
  19. package/ui-dist/assets/{page-layout-x7tLtJ9c.js → page-layout-B0fknS7V.js} +1 -1
  20. package/ui-dist/assets/{popover-DACrbH7x.js → popover-eFo7VWsC.js} +1 -1
  21. package/ui-dist/assets/{security-config-DxjEyIcP.js → security-config-BDzgMici.js} +1 -1
  22. package/ui-dist/assets/{skeleton-CXzreG6F.js → skeleton-nZ5c17f2.js} +1 -1
  23. package/ui-dist/assets/{status-dot-C1NZWCI_.js → status-dot-BSMwUSEM.js} +1 -1
  24. package/ui-dist/assets/{switch-DOrbztKw.js → switch-D94UWMj6.js} +1 -1
  25. package/ui-dist/assets/{tabs-custom-Cd0VgGG5.js → tabs-custom-DZO89c8f.js} +1 -1
  26. package/ui-dist/assets/{useConfirmDialog-KRJdAz3v.js → useConfirmDialog-BkD25Y5k.js} +1 -1
  27. package/ui-dist/index.html +1 -1
package/dist/cli/index.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  saveConfig as saveConfig11,
12
12
  getConfigPath as getConfigPath10,
13
13
  getDataDir as getDataDir10,
14
- getWorkspacePath as getWorkspacePath10,
14
+ getWorkspacePath as getWorkspacePath11,
15
15
  expandHome as expandHome2,
16
16
  MessageBus as MessageBus2,
17
17
  AgentLoop,
@@ -23,7 +23,7 @@ import {
23
23
  } from "@nextclaw/core";
24
24
  import { RemoteRuntimeActions } from "@nextclaw/remote";
25
25
  import {
26
- getPluginChannelBindings as getPluginChannelBindings4,
26
+ getPluginChannelBindings as getPluginChannelBindings5,
27
27
  resolvePluginChannelMessageToolHints as resolvePluginChannelMessageToolHints2,
28
28
  setPluginRuntimeBridge as setPluginRuntimeBridge3
29
29
  } from "@nextclaw/openclaw-compat";
@@ -1807,7 +1807,8 @@ var PluginCommands = class {
1807
1807
  };
1808
1808
 
1809
1809
  // src/cli/commands/config.ts
1810
- import { buildReloadPlan, diffConfigPaths, loadConfig as loadConfig4, saveConfig as saveConfig2 } from "@nextclaw/core";
1810
+ import { buildReloadPlan, diffConfigPaths, getWorkspacePath as getWorkspacePath3, loadConfig as loadConfig4, saveConfig as saveConfig2 } from "@nextclaw/core";
1811
+ import { getPluginChannelBindings } from "@nextclaw/openclaw-compat";
1811
1812
 
1812
1813
  // src/cli/config-path.ts
1813
1814
  function isIndexSegment(raw) {
@@ -1996,13 +1997,18 @@ function unsetAtConfigPath(root, pathSegments) {
1996
1997
  return true;
1997
1998
  }
1998
1999
 
2000
+ // src/cli/commands/channel-config-view.ts
2001
+ import { toPluginConfigView as toPluginConfigView2 } from "@nextclaw/openclaw-compat";
2002
+ function resolveChannelConfigView(config2, bindings) {
2003
+ return toPluginConfigView2(config2, bindings);
2004
+ }
2005
+
1999
2006
  // src/cli/commands/config.ts
2000
2007
  var ConfigCommands = class {
2001
2008
  constructor(deps) {
2002
2009
  this.deps = deps;
2003
2010
  }
2004
2011
  configGet(pathExpr, opts = {}) {
2005
- const config2 = loadConfig4();
2006
2012
  let parsedPath;
2007
2013
  try {
2008
2014
  parsedPath = parseRequiredConfigPath(pathExpr);
@@ -2011,7 +2017,9 @@ var ConfigCommands = class {
2011
2017
  process.exit(1);
2012
2018
  return;
2013
2019
  }
2014
- const result = getAtConfigPath(config2, parsedPath);
2020
+ const config2 = loadConfig4();
2021
+ const resolvedConfig = this.resolveReadConfigView(config2, parsedPath);
2022
+ const result = getAtConfigPath(resolvedConfig, parsedPath);
2015
2023
  if (!result.found) {
2016
2024
  console.error(`Config path not found: ${pathExpr}`);
2017
2025
  process.exit(1);
@@ -2045,14 +2053,16 @@ var ConfigCommands = class {
2045
2053
  return;
2046
2054
  }
2047
2055
  const prevConfig = loadConfig4();
2048
- const nextConfig = structuredClone(prevConfig);
2056
+ const projectedContext = this.resolveProjectedChannelContext(prevConfig, parsedPath);
2057
+ const nextConfigTarget = projectedContext ? structuredClone(projectedContext.view) : structuredClone(prevConfig);
2049
2058
  try {
2050
- setAtConfigPath(nextConfig, parsedPath, parsedValue);
2059
+ setAtConfigPath(nextConfigTarget, parsedPath, parsedValue);
2051
2060
  } catch (error) {
2052
2061
  console.error(String(error));
2053
2062
  process.exit(1);
2054
2063
  return;
2055
2064
  }
2065
+ const nextConfig = projectedContext ? mergePluginConfigView(prevConfig, nextConfigTarget, projectedContext.bindings) : nextConfigTarget;
2056
2066
  saveConfig2(nextConfig);
2057
2067
  await this.requestRestartForConfigDiff({
2058
2068
  prevConfig,
@@ -2071,13 +2081,15 @@ var ConfigCommands = class {
2071
2081
  return;
2072
2082
  }
2073
2083
  const prevConfig = loadConfig4();
2074
- const nextConfig = structuredClone(prevConfig);
2075
- const removed = unsetAtConfigPath(nextConfig, parsedPath);
2084
+ const projectedContext = this.resolveProjectedChannelContext(prevConfig, parsedPath);
2085
+ const nextConfigTarget = projectedContext ? structuredClone(projectedContext.view) : structuredClone(prevConfig);
2086
+ const removed = unsetAtConfigPath(nextConfigTarget, parsedPath);
2076
2087
  if (!removed) {
2077
2088
  console.error(`Config path not found: ${pathExpr}`);
2078
2089
  process.exit(1);
2079
2090
  return;
2080
2091
  }
2092
+ const nextConfig = projectedContext ? mergePluginConfigView(prevConfig, nextConfigTarget, projectedContext.bindings) : nextConfigTarget;
2081
2093
  saveConfig2(nextConfig);
2082
2094
  await this.requestRestartForConfigDiff({
2083
2095
  prevConfig,
@@ -2086,6 +2098,34 @@ var ConfigCommands = class {
2086
2098
  manualMessage: `Removed ${pathExpr}. Restart the gateway to apply.`
2087
2099
  });
2088
2100
  }
2101
+ resolveReadConfigView(config2, parsedPath) {
2102
+ if (parsedPath[0] !== "channels") {
2103
+ return config2;
2104
+ }
2105
+ const { bindings } = this.loadPluginChannelBindings(config2);
2106
+ return resolveChannelConfigView(config2, bindings);
2107
+ }
2108
+ resolveProjectedChannelContext(config2, parsedPath) {
2109
+ if (parsedPath[0] !== "channels" || parsedPath.length < 2) {
2110
+ return null;
2111
+ }
2112
+ const channelId = parsedPath[1];
2113
+ const { bindings } = this.loadPluginChannelBindings(config2);
2114
+ if (!bindings.some((binding) => binding.channelId === channelId)) {
2115
+ return null;
2116
+ }
2117
+ return {
2118
+ bindings,
2119
+ view: resolveChannelConfigView(config2, bindings)
2120
+ };
2121
+ }
2122
+ loadPluginChannelBindings(config2) {
2123
+ const workspaceDir = getWorkspacePath3(config2.agents.defaults.workspace);
2124
+ const pluginRegistry = loadPluginRegistry(config2, workspaceDir);
2125
+ return {
2126
+ bindings: getPluginChannelBindings(pluginRegistry)
2127
+ };
2128
+ }
2089
2129
  async requestRestartForConfigDiff(params) {
2090
2130
  const changedPaths = diffConfigPaths(params.prevConfig, params.nextConfig);
2091
2131
  if (!changedPaths.length) {
@@ -2656,9 +2696,9 @@ var SecretsCommands = class {
2656
2696
 
2657
2697
  // src/cli/commands/channels.ts
2658
2698
  import { spawnSync as spawnSync2 } from "child_process";
2659
- import { getWorkspacePath as getWorkspacePath3, loadConfig as loadConfig7, saveConfig as saveConfig5 } from "@nextclaw/core";
2699
+ import { getWorkspacePath as getWorkspacePath4, loadConfig as loadConfig7, saveConfig as saveConfig5 } from "@nextclaw/core";
2660
2700
  import { BUILTIN_CHANNEL_PLUGIN_IDS, builtinProviderIds as builtinProviderIds2 } from "@nextclaw/runtime";
2661
- import { buildPluginStatusReport as buildPluginStatusReport3, enablePluginInConfig as enablePluginInConfig2, getPluginChannelBindings } from "@nextclaw/openclaw-compat";
2701
+ import { buildPluginStatusReport as buildPluginStatusReport3, enablePluginInConfig as enablePluginInConfig2, getPluginChannelBindings as getPluginChannelBindings2 } from "@nextclaw/openclaw-compat";
2662
2702
  var CHANNEL_LABELS = {
2663
2703
  telegram: "Telegram",
2664
2704
  whatsapp: "WhatsApp",
@@ -2678,14 +2718,16 @@ var ChannelCommands = class {
2678
2718
  }
2679
2719
  channelsStatus() {
2680
2720
  const config2 = loadConfig7();
2721
+ const workspaceDir = getWorkspacePath4(config2.agents.defaults.workspace);
2722
+ const pluginRegistry = loadPluginRegistry(config2, workspaceDir);
2723
+ const channelConfig = resolveChannelConfigView(config2, getPluginChannelBindings2(pluginRegistry));
2681
2724
  console.log("Channel Status");
2682
- const channelConfig = config2.channels;
2725
+ const channels2 = channelConfig.channels;
2683
2726
  for (const channelId of BUILTIN_CHANNEL_PLUGIN_IDS) {
2684
2727
  const label = CHANNEL_LABELS[channelId] ?? channelId;
2685
- const enabled = channelConfig[channelId]?.enabled === true;
2728
+ const enabled = channels2[channelId]?.enabled === true;
2686
2729
  console.log(`${label}: ${enabled ? "\u2713" : "\u2717"}`);
2687
2730
  }
2688
- const workspaceDir = getWorkspacePath3(config2.agents.defaults.workspace);
2689
2731
  const report = buildPluginStatusReport3({
2690
2732
  config: config2,
2691
2733
  workspaceDir,
@@ -2696,8 +2738,8 @@ var ChannelCommands = class {
2696
2738
  if (pluginChannels.length > 0) {
2697
2739
  console.log("Plugin Channels:");
2698
2740
  for (const plugin of pluginChannels) {
2699
- const channels2 = plugin.channelIds.join(", ");
2700
- console.log(`- ${channels2} (plugin: ${plugin.id})`);
2741
+ const channels3 = plugin.channelIds.join(", ");
2742
+ console.log(`- ${channels3} (plugin: ${plugin.id})`);
2701
2743
  }
2702
2744
  }
2703
2745
  }
@@ -2708,19 +2750,19 @@ var ChannelCommands = class {
2708
2750
  return;
2709
2751
  }
2710
2752
  const config2 = loadConfig7();
2711
- const binding = this.resolvePluginChannelBinding(config2, channelId);
2712
- if (!binding) {
2753
+ const channelContext = this.resolvePluginChannelContext(config2, channelId);
2754
+ if (!channelContext) {
2713
2755
  console.error(`No plugin channel found for: ${channelId}`);
2714
2756
  process.exit(1);
2715
2757
  }
2716
- const result = await this.loginPluginChannel(config2, binding, opts);
2758
+ const result = await this.loginPluginChannel(config2, channelContext, opts);
2717
2759
  if (!result) {
2718
2760
  return;
2719
2761
  }
2720
- saveConfig5(this.buildNextConfigAfterChannelLogin(config2, binding, result));
2721
- this.printPluginChannelLoginResult(binding, result);
2762
+ saveConfig5(this.buildNextConfigAfterChannelLogin(config2, channelContext.binding, result));
2763
+ this.printPluginChannelLoginResult(channelContext.binding, result);
2722
2764
  await this.deps.requestRestart({
2723
- reason: `channel login via plugin: ${binding.pluginId}`,
2765
+ reason: `channel login via plugin: ${channelContext.binding.pluginId}`,
2724
2766
  manualMessage: "Restart the gateway to apply changes."
2725
2767
  });
2726
2768
  }
@@ -2733,13 +2775,18 @@ var ChannelCommands = class {
2733
2775
  console.error(`Bridge failed: ${result.status ?? 1}`);
2734
2776
  }
2735
2777
  }
2736
- resolvePluginChannelBinding(config2, channelId) {
2737
- const workspaceDir = getWorkspacePath3(config2.agents.defaults.workspace);
2778
+ resolvePluginChannelContext(config2, channelId) {
2779
+ const workspaceDir = getWorkspacePath4(config2.agents.defaults.workspace);
2738
2780
  const pluginRegistry = loadPluginRegistry(config2, workspaceDir);
2739
- const bindings = getPluginChannelBindings(pluginRegistry);
2740
- return bindings.find((entry) => entry.channelId === channelId || entry.pluginId === channelId);
2781
+ const bindings = getPluginChannelBindings2(pluginRegistry);
2782
+ const binding = bindings.find((entry) => entry.channelId === channelId || entry.pluginId === channelId);
2783
+ if (!binding) {
2784
+ return null;
2785
+ }
2786
+ return { binding, bindings };
2741
2787
  }
2742
- async loginPluginChannel(config2, binding, opts) {
2788
+ async loginPluginChannel(config2, channelContext, opts) {
2789
+ const { binding, bindings } = channelContext;
2743
2790
  const login = binding.channel.auth?.login;
2744
2791
  if (!login) {
2745
2792
  if (binding.channelId === "whatsapp") {
@@ -2749,11 +2796,12 @@ var ChannelCommands = class {
2749
2796
  console.error(`Channel "${binding.channelId}" does not support login.`);
2750
2797
  process.exit(1);
2751
2798
  }
2799
+ const configView = resolveChannelConfigView(config2, bindings);
2752
2800
  const result = await login({
2753
- cfg: config2,
2801
+ cfg: configView,
2754
2802
  pluginId: binding.pluginId,
2755
2803
  channelId: binding.channelId,
2756
- pluginConfig: this.clonePluginConfig(config2.plugins.entries?.[binding.pluginId]?.config),
2804
+ pluginConfig: this.clonePluginConfig(configView.channels?.[binding.channelId]),
2757
2805
  accountId: opts.account?.trim() || null,
2758
2806
  baseUrl: opts.url?.trim() || opts.httpUrl?.trim() || null,
2759
2807
  verbose: Boolean(opts.verbose)
@@ -2779,22 +2827,14 @@ var ChannelCommands = class {
2779
2827
  }
2780
2828
  }
2781
2829
  buildNextConfigAfterChannelLogin(config2, binding, result) {
2782
- return enablePluginInConfig2(
2783
- {
2784
- ...config2,
2785
- plugins: {
2786
- ...config2.plugins,
2787
- entries: {
2788
- ...config2.plugins.entries ?? {},
2789
- [binding.pluginId]: {
2790
- ...config2.plugins.entries?.[binding.pluginId] ?? {},
2791
- config: result.pluginConfig
2792
- }
2793
- }
2794
- }
2795
- },
2796
- binding.pluginId
2797
- );
2830
+ const nextConfig = {
2831
+ ...config2,
2832
+ channels: {
2833
+ ...config2.channels,
2834
+ [binding.channelId]: result.pluginConfig
2835
+ }
2836
+ };
2837
+ return enablePluginInConfig2(nextConfig, binding.pluginId);
2798
2838
  }
2799
2839
  printPluginChannelLoginResult(binding, result) {
2800
2840
  console.log(`Logged into channel "${binding.channelId}" via plugin "${binding.pluginId}".`);
@@ -2812,9 +2852,9 @@ var ChannelCommands = class {
2812
2852
  process.exit(1);
2813
2853
  }
2814
2854
  const config2 = loadConfig7();
2815
- const workspaceDir = getWorkspacePath3(config2.agents.defaults.workspace);
2855
+ const workspaceDir = getWorkspacePath4(config2.agents.defaults.workspace);
2816
2856
  const pluginRegistry = loadPluginRegistry(config2, workspaceDir);
2817
- const bindings = getPluginChannelBindings(pluginRegistry);
2857
+ const bindings = getPluginChannelBindings2(pluginRegistry);
2818
2858
  const binding = bindings.find((entry) => entry.channelId === channelId || entry.pluginId === channelId);
2819
2859
  if (!binding) {
2820
2860
  console.error(`No plugin channel found for: ${channelId}`);
@@ -3525,7 +3565,7 @@ import {
3525
3565
  APP_NAME as APP_NAME2,
3526
3566
  getConfigPath as getConfigPath6,
3527
3567
  getDataDir as getDataDir5,
3528
- getWorkspacePath as getWorkspacePath4,
3568
+ getWorkspacePath as getWorkspacePath5,
3529
3569
  hasSecretRef,
3530
3570
  loadConfig as loadConfig11
3531
3571
  } from "@nextclaw/core";
@@ -3714,7 +3754,7 @@ var DiagnosticsCommands = class {
3714
3754
  async collectRuntimeStatus(params) {
3715
3755
  const configPath = getConfigPath6();
3716
3756
  const config2 = loadConfig11();
3717
- const workspacePath = getWorkspacePath4(config2.agents.defaults.workspace);
3757
+ const workspacePath = getWorkspacePath5(config2.agents.defaults.workspace);
3718
3758
  const serviceStatePath = resolve8(getDataDir5(), "run", "service.json");
3719
3759
  const fixActions = [];
3720
3760
  let serviceState = readServiceState();
@@ -3907,7 +3947,7 @@ var DiagnosticsCommands = class {
3907
3947
  // src/cli/commands/service.ts
3908
3948
  import * as NextclawCore from "@nextclaw/core";
3909
3949
  import {
3910
- getPluginChannelBindings as getPluginChannelBindings3,
3950
+ getPluginChannelBindings as getPluginChannelBindings4,
3911
3951
  getPluginUiMetadataFromRegistry,
3912
3952
  resolvePluginChannelMessageToolHints,
3913
3953
  setPluginRuntimeBridge as setPluginRuntimeBridge2,
@@ -4325,8 +4365,9 @@ var ConfigReloader = class {
4325
4365
  }
4326
4366
  this.reloadTask = (async () => {
4327
4367
  await this.channels.stopAll();
4368
+ const channelConfig = this.options.resolveChannelConfig?.(nextConfig) ?? nextConfig;
4328
4369
  this.channels = new ChannelManager(
4329
- nextConfig,
4370
+ channelConfig,
4330
4371
  this.options.bus,
4331
4372
  this.options.sessionManager,
4332
4373
  this.options.getExtensionChannels?.() ?? []
@@ -4395,7 +4436,7 @@ var MissingProvider = class extends LLMProvider {
4395
4436
  };
4396
4437
 
4397
4438
  // src/cli/commands/service-marketplace-installer.ts
4398
- import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig13 } from "@nextclaw/core";
4439
+ import { getWorkspacePath as getWorkspacePath6, loadConfig as loadConfig13 } from "@nextclaw/core";
4399
4440
  import { existsSync as existsSync9, rmSync as rmSync4 } from "fs";
4400
4441
  import { join as join4 } from "path";
4401
4442
 
@@ -4560,7 +4601,7 @@ var ServiceMarketplaceInstaller = class {
4560
4601
  if (params.kind && params.kind !== "marketplace") {
4561
4602
  throw new Error(`Unsupported marketplace skill kind: ${params.kind}`);
4562
4603
  }
4563
- const workspace = getWorkspacePath5(loadConfig13().agents.defaults.workspace);
4604
+ const workspace = getWorkspacePath6(loadConfig13().agents.defaults.workspace);
4564
4605
  const args = buildMarketplaceSkillInstallArgs({
4565
4606
  slug: params.slug,
4566
4607
  workspace,
@@ -4599,7 +4640,7 @@ var ServiceMarketplaceInstaller = class {
4599
4640
  return { message: result.message };
4600
4641
  }
4601
4642
  async uninstallSkill(slug) {
4602
- const workspace = getWorkspacePath5(loadConfig13().agents.defaults.workspace);
4643
+ const workspace = getWorkspacePath6(loadConfig13().agents.defaults.workspace);
4603
4644
  const targetDir = join4(workspace, "skills", slug);
4604
4645
  if (!existsSync9(targetDir)) {
4605
4646
  throw new Error(`Skill not installed in workspace: ${slug}`);
@@ -4887,9 +4928,9 @@ function resolveUiSessionTypeLabel(sessionType) {
4887
4928
  }
4888
4929
 
4889
4930
  // src/cli/commands/service-plugin-reload.ts
4890
- import { getWorkspacePath as getWorkspacePath6 } from "@nextclaw/core";
4931
+ import { getWorkspacePath as getWorkspacePath7 } from "@nextclaw/core";
4891
4932
  import {
4892
- getPluginChannelBindings as getPluginChannelBindings2,
4933
+ getPluginChannelBindings as getPluginChannelBindings3,
4893
4934
  startPluginChannelGateways,
4894
4935
  stopPluginChannelGateways
4895
4936
  } from "@nextclaw/openclaw-compat";
@@ -4953,10 +4994,10 @@ function shouldRestartChannelsForPluginReload(params) {
4953
4994
 
4954
4995
  // src/cli/commands/service-plugin-reload.ts
4955
4996
  async function reloadServicePlugins(params) {
4956
- const nextWorkspace = getWorkspacePath6(params.nextConfig.agents.defaults.workspace);
4997
+ const nextWorkspace = getWorkspacePath7(params.nextConfig.agents.defaults.workspace);
4957
4998
  const nextPluginRegistry = loadPluginRegistry(params.nextConfig, nextWorkspace);
4958
4999
  const nextExtensionRegistry = toExtensionRegistry(nextPluginRegistry);
4959
- const nextPluginChannelBindings = getPluginChannelBindings2(nextPluginRegistry);
5000
+ const nextPluginChannelBindings = getPluginChannelBindings3(nextPluginRegistry);
4960
5001
  const shouldRestartChannels = shouldRestartChannelsForPluginReload({
4961
5002
  changedPaths: params.changedPaths,
4962
5003
  currentPluginChannelBindings: params.pluginChannelBindings,
@@ -5021,7 +5062,7 @@ import {
5021
5062
  createAssistantStreamDeltaControlMessage,
5022
5063
  createAssistantStreamResetControlMessage,
5023
5064
  AgentRouteResolver,
5024
- getWorkspacePath as getWorkspacePath7,
5065
+ getWorkspacePath as getWorkspacePath8,
5025
5066
  parseAgentScopedSessionKey as parseAgentScopedSessionKey2
5026
5067
  } from "@nextclaw/core";
5027
5068
  function normalizeAgentId(value) {
@@ -5066,7 +5107,7 @@ function resolveAgentProfiles(config2) {
5066
5107
  }
5067
5108
  return Array.from(unique.values()).map((entry) => ({
5068
5109
  id: entry.id,
5069
- workspace: getWorkspacePath7(entry.workspace ?? defaults.workspace),
5110
+ workspace: getWorkspacePath8(entry.workspace ?? defaults.workspace),
5070
5111
  model: entry.model ?? defaults.model,
5071
5112
  engine: normalizeEngineKind(entry.engine ?? defaults.engine),
5072
5113
  engineConfig: entry.engineConfig ?? toRecord(defaults.engineConfig),
@@ -5334,7 +5375,7 @@ var GatewayAgentRuntimePool = class {
5334
5375
  const normalizedAgentId = normalizeAgentId(agentId);
5335
5376
  return this.resolvedProfiles.find((profile) => profile.id === normalizedAgentId) ?? this.resolvedProfiles.find((profile) => profile.id === this.defaultAgentId) ?? this.resolvedProfiles[0] ?? {
5336
5377
  id: this.defaultAgentId,
5337
- workspace: getWorkspacePath7(this.options.config.agents.defaults.workspace),
5378
+ workspace: getWorkspacePath8(this.options.config.agents.defaults.workspace),
5338
5379
  model: this.options.config.agents.defaults.model,
5339
5380
  maxIterations: this.options.config.agents.defaults.maxToolIterations,
5340
5381
  contextTokens: this.options.config.agents.defaults.contextTokens,
@@ -5546,7 +5587,7 @@ import {
5546
5587
  buildToolCatalogEntries,
5547
5588
  ContextBuilder,
5548
5589
  InputBudgetPruner,
5549
- getWorkspacePath as getWorkspacePath8,
5590
+ getWorkspacePath as getWorkspacePath9,
5550
5591
  parseThinkingLevel as parseThinkingLevel2,
5551
5592
  resolveThinkingLevel
5552
5593
  } from "@nextclaw/core";
@@ -6251,7 +6292,7 @@ function resolvePrimaryAgentProfile(config2) {
6251
6292
  const profile = config2.agents.list.find((entry) => entry.id.trim() === configuredDefaultAgentId);
6252
6293
  return {
6253
6294
  agentId: configuredDefaultAgentId,
6254
- workspace: getWorkspacePath8(profile?.workspace ?? config2.agents.defaults.workspace),
6295
+ workspace: getWorkspacePath9(profile?.workspace ?? config2.agents.defaults.workspace),
6255
6296
  model: profile?.model ?? config2.agents.defaults.model,
6256
6297
  maxIterations: profile?.maxToolIterations ?? config2.agents.defaults.maxToolIterations,
6257
6298
  contextTokens: profile?.contextTokens ?? config2.agents.defaults.contextTokens,
@@ -6972,27 +7013,17 @@ async function createMcpRuntimeSupport(getConfig) {
6972
7013
  getConfig: () => currentMcpConfig,
6973
7014
  lifecycleManager: mcpLifecycleManager
6974
7015
  });
6975
- let currentWarmPromise = Promise.resolve();
6976
- const startBackgroundWarm = () => {
6977
- currentWarmPromise = mcpRegistryService.prewarmEnabledServers().then((mcpPrewarmResults) => {
6978
- for (const result of mcpPrewarmResults) {
6979
- if (!result.ok) {
6980
- console.warn(`[mcp] Failed to warm ${result.name}: ${result.error}`);
6981
- }
6982
- }
6983
- }).catch((error) => {
6984
- const message = error instanceof Error ? error.message : String(error);
6985
- console.warn(`[mcp] Failed to prewarm enabled MCP servers: ${message}`);
6986
- });
6987
- return currentWarmPromise;
6988
- };
6989
- void startBackgroundWarm();
7016
+ const mcpPrewarmResults = await mcpRegistryService.prewarmEnabledServers();
7017
+ for (const result of mcpPrewarmResults) {
7018
+ if (!result.ok) {
7019
+ console.warn(`[mcp] Failed to warm ${result.name}: ${result.error}`);
7020
+ }
7021
+ }
6990
7022
  return {
6991
7023
  toolRegistryAdapter: new McpNcpToolRegistryAdapter(mcpRegistryService),
6992
7024
  applyMcpConfig: async (config2) => {
6993
7025
  const previousConfig = currentMcpConfig;
6994
7026
  currentMcpConfig = config2;
6995
- await currentWarmPromise.catch(() => void 0);
6996
7027
  const reconcileResult = await mcpRegistryService.reconcileConfig({
6997
7028
  prevConfig: previousConfig,
6998
7029
  nextConfig: config2
@@ -8306,7 +8337,7 @@ var {
8306
8337
  getDataDir: getDataDir8,
8307
8338
  getProvider,
8308
8339
  getProviderName,
8309
- getWorkspacePath: getWorkspacePath9,
8340
+ getWorkspacePath: getWorkspacePath10,
8310
8341
  HeartbeatService,
8311
8342
  LiteLLMProvider,
8312
8343
  loadConfig: loadConfig17,
@@ -8335,8 +8366,9 @@ var ServiceCommands = class {
8335
8366
  this.liveUiNcpAgent = null;
8336
8367
  const runtimeConfigPath = getConfigPath9();
8337
8368
  const config2 = resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath });
8338
- const workspace = getWorkspacePath9(config2.agents.defaults.workspace);
8369
+ const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
8339
8370
  let pluginRegistry = loadPluginRegistry(config2, workspace);
8371
+ let pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
8340
8372
  let extensionRegistry = toExtensionRegistry(pluginRegistry);
8341
8373
  logPluginDiagnostics(pluginRegistry);
8342
8374
  const bus = new MessageBus();
@@ -8358,7 +8390,7 @@ var ServiceCommands = class {
8358
8390
  if (!provider) {
8359
8391
  console.warn("Warning: No API key configured. The gateway is running, but agent replies are disabled until provider config is set.");
8360
8392
  }
8361
- const channels2 = new ChannelManager2(config2, bus, sessionManager, extensionRegistry.channels);
8393
+ const channels2 = new ChannelManager2(resolveChannelConfigView(config2, pluginChannelBindings), bus, sessionManager, extensionRegistry.channels);
8362
8394
  const reloader = new ConfigReloader({
8363
8395
  initialConfig: config2,
8364
8396
  channels: channels2,
@@ -8367,6 +8399,7 @@ var ServiceCommands = class {
8367
8399
  providerManager,
8368
8400
  makeProvider: (nextConfig) => this.makeProvider(nextConfig, { allowMissing: true }) ?? this.makeMissingProvider(nextConfig),
8369
8401
  loadConfig: () => resolveConfigSecrets3(loadConfig17(), { configPath: runtimeConfigPath }),
8402
+ resolveChannelConfig: (nextConfig) => resolveChannelConfigView(nextConfig, pluginChannelBindings),
8370
8403
  getExtensionChannels: () => extensionRegistry.channels,
8371
8404
  onRestartRequired: (paths) => {
8372
8405
  void this.deps.requestRestart({
@@ -8441,7 +8474,6 @@ var ServiceCommands = class {
8441
8474
  reloader.setReloadMcp(async ({ config: nextConfig }) => {
8442
8475
  await this.liveUiNcpAgent?.applyMcpConfig?.(nextConfig);
8443
8476
  });
8444
- let pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
8445
8477
  installPluginRuntimeBridge({
8446
8478
  runtimePool,
8447
8479
  runtimeConfigPath,
@@ -9096,7 +9128,7 @@ var ServiceCommands = class {
9096
9128
  console.log(` - Check status: ${APP_NAME3} status`);
9097
9129
  console.log(` - If you need to stop the service, run: ${APP_NAME3} stop`);
9098
9130
  }
9099
- async startUiIfEnabled(uiConfig, uiStaticDir, cronService, runtimePool, sessionManager, providerManager, bus, gatewayController, getConfig, getExtensionRegistry, resolveMessageToolHints, getPluginChannelBindings5, getPluginUiMetadata, remoteModule) {
9131
+ async startUiIfEnabled(uiConfig, uiStaticDir, cronService, runtimePool, sessionManager, providerManager, bus, gatewayController, getConfig, getExtensionRegistry, resolveMessageToolHints, getPluginChannelBindings6, getPluginUiMetadata, remoteModule) {
9100
9132
  if (!uiConfig.enabled) {
9101
9133
  return;
9102
9134
  }
@@ -9157,7 +9189,7 @@ var ServiceCommands = class {
9157
9189
  installer: marketplaceInstaller
9158
9190
  },
9159
9191
  remoteAccess,
9160
- getPluginChannelBindings: getPluginChannelBindings5,
9192
+ getPluginChannelBindings: getPluginChannelBindings6,
9161
9193
  getPluginUiMetadata,
9162
9194
  ncpAgent,
9163
9195
  chatRuntime: createServiceUiChatRuntime({ runtimePool, runCoordinator })
@@ -9174,7 +9206,7 @@ var ServiceCommands = class {
9174
9206
  }
9175
9207
  }
9176
9208
  installBuiltinMarketplaceSkill(slug, force) {
9177
- const workspace = getWorkspacePath9(loadConfig17().agents.defaults.workspace);
9209
+ const workspace = getWorkspacePath10(loadConfig17().agents.defaults.workspace);
9178
9210
  const destination = join6(workspace, "skills", slug);
9179
9211
  const destinationSkillFile = join6(destination, "SKILL.md");
9180
9212
  if (existsSync12(destinationSkillFile) && !force) {
@@ -9438,7 +9470,7 @@ function resolveSkillsInstallWorkdir(params) {
9438
9470
  if (params.explicitWorkdir) {
9439
9471
  return expandHome2(params.explicitWorkdir);
9440
9472
  }
9441
- return getWorkspacePath10(params.configuredWorkspace);
9473
+ return getWorkspacePath11(params.configuredWorkspace);
9442
9474
  }
9443
9475
  var CliRuntime = class {
9444
9476
  logo;
@@ -9809,11 +9841,11 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9809
9841
  async agent(opts) {
9810
9842
  const configPath = getConfigPath10();
9811
9843
  const config2 = resolveConfigSecrets4(loadConfig18(), { configPath });
9812
- const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
9844
+ const workspace = getWorkspacePath11(config2.agents.defaults.workspace);
9813
9845
  const pluginRegistry = loadPluginRegistry(config2, workspace);
9814
9846
  const extensionRegistry = toExtensionRegistry(pluginRegistry);
9815
9847
  logPluginDiagnostics(pluginRegistry);
9816
- const pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
9848
+ const pluginChannelBindings = getPluginChannelBindings5(pluginRegistry);
9817
9849
  setPluginRuntimeBridge3({
9818
9850
  loadConfig: () => toPluginConfigView(
9819
9851
  resolveConfigSecrets4(loadConfig18(), { configPath }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.15.7",
3
+ "version": "0.15.8",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -39,16 +39,16 @@
39
39
  "chokidar": "^3.6.0",
40
40
  "commander": "^12.1.0",
41
41
  "yaml": "^2.8.1",
42
- "@nextclaw/core": "0.11.0",
42
+ "@nextclaw/core": "0.11.1",
43
+ "@nextclaw/mcp": "0.1.46",
43
44
  "@nextclaw/ncp": "0.3.2",
44
- "@nextclaw/ncp-mcp": "0.1.44",
45
- "@nextclaw/mcp": "0.1.45",
45
+ "@nextclaw/ncp-agent-runtime": "0.2.3",
46
+ "@nextclaw/ncp-mcp": "0.1.45",
46
47
  "@nextclaw/ncp-toolkit": "0.4.2",
47
- "@nextclaw/remote": "0.1.43",
48
- "@nextclaw/runtime": "0.2.14",
49
- "@nextclaw/server": "0.10.49",
50
- "@nextclaw/openclaw-compat": "0.3.26",
51
- "@nextclaw/ncp-agent-runtime": "0.2.3"
48
+ "@nextclaw/remote": "0.1.44",
49
+ "@nextclaw/runtime": "0.2.15",
50
+ "@nextclaw/server": "0.10.50",
51
+ "@nextclaw/openclaw-compat": "0.3.27"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^20.17.6",