nextclaw 0.15.13 → 0.15.15

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 +128 -153
  2. package/package.json +12 -12
  3. package/ui-dist/assets/{ChannelsList-DzamwY1c.js → ChannelsList-Nu7Ig6_-.js} +1 -1
  4. package/ui-dist/assets/{ChatPage-CC7peq03.js → ChatPage-CBCFSk4e.js} +24 -24
  5. package/ui-dist/assets/{DocBrowser-P1tpZ6u-.js → DocBrowser-3CfKmJA6.js} +1 -1
  6. package/ui-dist/assets/{LogoBadge-CUkmmEqR.js → LogoBadge-DdthDJOp.js} +1 -1
  7. package/ui-dist/assets/{MarketplacePage-DSz0-TrP.js → MarketplacePage-inGGiv1T.js} +1 -1
  8. package/ui-dist/assets/{McpMarketplacePage-BMc8qnlG.js → McpMarketplacePage-Dg8GSZh6.js} +1 -1
  9. package/ui-dist/assets/{ModelConfig-0bTwTRDp.js → ModelConfig-DyQ6cC92.js} +1 -1
  10. package/ui-dist/assets/{ProvidersList-BkZ221Mc.js → ProvidersList-B2T8Lc_i.js} +1 -1
  11. package/ui-dist/assets/{RemoteAccessPage-Bgs6dt8q.js → RemoteAccessPage-C9LxgK-C.js} +1 -1
  12. package/ui-dist/assets/{RuntimeConfig-C8BLcW9z.js → RuntimeConfig-Ey4VIqTW.js} +1 -1
  13. package/ui-dist/assets/{SearchConfig-RLJwjg2O.js → SearchConfig-R1BcCLWO.js} +1 -1
  14. package/ui-dist/assets/{SecretsConfig-Dvp9EiSw.js → SecretsConfig-D-jZMHeY.js} +2 -2
  15. package/ui-dist/assets/{SessionsConfig-B6HcQDs_.js → SessionsConfig-Cawoh4_2.js} +1 -1
  16. package/ui-dist/assets/{chat-message-Dskmxe28.js → chat-message-BbuIK4dQ.js} +1 -1
  17. package/ui-dist/assets/{index-CgLYfF21.js → index-BulnQWr6.js} +2 -2
  18. package/ui-dist/assets/{label-OBmTFWFo.js → label-C7yzBvzK.js} +1 -1
  19. package/ui-dist/assets/{page-layout-RXrERDXi.js → page-layout-DF0xpax2.js} +1 -1
  20. package/ui-dist/assets/{popover-qKLbf6q8.js → popover-DjaScZDJ.js} +1 -1
  21. package/ui-dist/assets/{security-config-_N_JprU4.js → security-config-Bg2eriNx.js} +1 -1
  22. package/ui-dist/assets/{skeleton-CWOyxWj6.js → skeleton-DycBJAJF.js} +1 -1
  23. package/ui-dist/assets/{status-dot-B0cT0Xpo.js → status-dot-B9opOZ22.js} +1 -1
  24. package/ui-dist/assets/{switch-BNh78Agi.js → switch-l1P0ev4D.js} +1 -1
  25. package/ui-dist/assets/{tabs-custom-BeFo8B9X.js → tabs-custom-BG9y2JhC.js} +1 -1
  26. package/ui-dist/assets/{useConfirmDialog-DinMYrOA.js → useConfirmDialog-DTducNfn.js} +1 -1
  27. package/ui-dist/index.html +1 -1
package/dist/cli/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  loadConfig as loadConfig18,
11
11
  saveConfig as saveConfig11,
12
12
  getConfigPath as getConfigPath10,
13
- getDataDir as getDataDir10,
13
+ getDataDir as getDataDir11,
14
14
  getWorkspacePath as getWorkspacePath11,
15
15
  expandHome as expandHome2,
16
16
  MessageBus as MessageBus2,
@@ -28,7 +28,7 @@ import {
28
28
  setPluginRuntimeBridge as setPluginRuntimeBridge3
29
29
  } from "@nextclaw/openclaw-compat";
30
30
  import { existsSync as existsSync14, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
31
- import { join as join8, resolve as resolve13 } from "path";
31
+ import { join as join9, resolve as resolve13 } from "path";
32
32
  import { createInterface as createInterface3 } from "readline";
33
33
  import { fileURLToPath as fileURLToPath5 } from "url";
34
34
  import { spawn as spawn4 } from "child_process";
@@ -3956,7 +3956,7 @@ import {
3956
3956
  } from "@nextclaw/openclaw-compat";
3957
3957
  import { startUiServer } from "@nextclaw/server";
3958
3958
  import { appendFileSync, closeSync as closeSync2, cpSync as cpSync2, existsSync as existsSync12, mkdirSync as mkdirSync6, openSync as openSync2 } from "fs";
3959
- import { dirname as dirname3, join as join6, resolve as resolve11 } from "path";
3959
+ import { dirname as dirname3, join as join7, resolve as resolve11 } from "path";
3960
3960
  import { spawn as spawn3 } from "child_process";
3961
3961
  import { request as httpRequest } from "http";
3962
3962
  import { request as httpsRequest } from "https";
@@ -5568,10 +5568,11 @@ var resolveCliSubcommandEntry = (params) => {
5568
5568
 
5569
5569
  // src/cli/commands/ncp/create-ui-ncp-agent.ts
5570
5570
  import {
5571
- DisposableStore
5571
+ DisposableStore,
5572
+ getDataDir as getDataDir6
5572
5573
  } from "@nextclaw/core";
5573
5574
  import { McpRegistryService as McpRegistryService2, McpServerLifecycleManager } from "@nextclaw/mcp";
5574
- import { DefaultNcpAgentRuntime } from "@nextclaw/ncp-agent-runtime";
5575
+ import { DefaultNcpAgentRuntime, LocalAttachmentStore } from "@nextclaw/ncp-agent-runtime";
5575
5576
  import { McpNcpToolRegistryAdapter } from "@nextclaw/ncp-mcp";
5576
5577
  import {
5577
5578
  readAssistantReasoningNormalizationMode,
@@ -5594,6 +5595,7 @@ import {
5594
5595
  } from "@nextclaw/core";
5595
5596
 
5596
5597
  // src/cli/commands/ncp/nextclaw-ncp-message-bridge.ts
5598
+ import { buildNcpUserContent } from "@nextclaw/ncp-agent-runtime";
5597
5599
  import {
5598
5600
  sanitizeAssistantReplyTags
5599
5601
  } from "@nextclaw/ncp";
@@ -5704,128 +5706,80 @@ function extractTextFromNcpMessage(message) {
5704
5706
  function isTextLikePart(part) {
5705
5707
  return part.type === "text" || part.type === "rich-text";
5706
5708
  }
5707
- function guessImageMime(pathOrUrl) {
5708
- if (!pathOrUrl) {
5709
- return null;
5709
+ function buildLegacyUserContent(parts, options = {}) {
5710
+ const content = buildNcpUserContent(parts, {
5711
+ attachmentStore: options.attachmentStore,
5712
+ maxTextBytes: options.attachmentTextMaxBytes
5713
+ });
5714
+ if (content === "") {
5715
+ return serializeLegacyContent(parts);
5710
5716
  }
5711
- const normalized = pathOrUrl.trim().toLowerCase();
5712
- if (normalized.endsWith(".png")) return "image/png";
5713
- if (normalized.endsWith(".jpg") || normalized.endsWith(".jpeg")) return "image/jpeg";
5714
- if (normalized.endsWith(".gif")) return "image/gif";
5715
- if (normalized.endsWith(".webp")) return "image/webp";
5716
- if (normalized.endsWith(".bmp")) return "image/bmp";
5717
- if (normalized.endsWith(".tif") || normalized.endsWith(".tiff")) return "image/tiff";
5718
- return null;
5717
+ return content;
5719
5718
  }
5720
- function isRenderableImageFilePart(part) {
5721
- if (part.type !== "file") {
5722
- return false;
5723
- }
5724
- const mimeType = normalizeString(part.mimeType);
5725
- if (mimeType?.startsWith("image/")) {
5726
- return true;
5719
+ function buildLegacyAssistantMessages(message, timestamp) {
5720
+ const textContent = extractTextFromNcpMessage(message);
5721
+ const reasoningContent = message.parts.filter((part) => part.type === "reasoning").map((part) => part.text).join("");
5722
+ const toolInvocations = message.parts.filter(
5723
+ (part) => part.type === "tool-invocation"
5724
+ );
5725
+ const assistantMessage = {
5726
+ role: "assistant",
5727
+ content: textContent,
5728
+ timestamp,
5729
+ ncp_message_id: message.id,
5730
+ ncp_parts: structuredClone(message.parts)
5731
+ };
5732
+ if (typeof message.metadata?.reply_to === "string" && message.metadata.reply_to.trim().length > 0) {
5733
+ assistantMessage.reply_to = message.metadata.reply_to.trim();
5727
5734
  }
5728
- return Boolean(guessImageMime(normalizeString(part.url) ?? normalizeString(part.name)));
5729
- }
5730
- function resolveImageUrl(part) {
5731
- const url = normalizeString(part.url);
5732
- if (url) {
5733
- return url;
5735
+ if (reasoningContent.length > 0) {
5736
+ assistantMessage.reasoning_content = reasoningContent;
5734
5737
  }
5735
- const mimeType = normalizeString(part.mimeType);
5736
- const contentBase64 = normalizeString(part.contentBase64);
5737
- if (!mimeType || !contentBase64) {
5738
- return null;
5738
+ if (toolInvocations.length > 0) {
5739
+ assistantMessage.tool_calls = toolInvocations.map((toolInvocation, index) => ({
5740
+ id: toolInvocation.toolCallId ?? `${message.id}:tool:${index}`,
5741
+ type: "function",
5742
+ function: {
5743
+ name: toolInvocation.toolName,
5744
+ arguments: serializeToolArgs(toolInvocation.args)
5745
+ }
5746
+ }));
5739
5747
  }
5740
- return `data:${mimeType};base64,${contentBase64}`;
5741
- }
5742
- function buildLegacyUserContent(parts) {
5743
- const blocks = [];
5744
- for (const part of parts) {
5745
- if (isTextLikePart(part) && part.text.length > 0) {
5746
- blocks.push({ type: "text", text: part.text });
5747
- continue;
5748
- }
5749
- if (!isRenderableImageFilePart(part)) {
5750
- continue;
5751
- }
5752
- const imageUrl = resolveImageUrl(part);
5753
- if (!imageUrl) {
5748
+ const messages = [assistantMessage];
5749
+ for (const toolInvocation of toolInvocations) {
5750
+ if (toolInvocation.state !== "result") {
5754
5751
  continue;
5755
5752
  }
5756
- blocks.push({
5757
- type: "image_url",
5758
- image_url: {
5759
- url: imageUrl
5760
- }
5753
+ messages.push({
5754
+ role: "tool",
5755
+ name: toolInvocation.toolName,
5756
+ tool_call_id: toolInvocation.toolCallId,
5757
+ content: typeof toolInvocation.result === "string" ? toolInvocation.result : JSON.stringify(toolInvocation.result ?? null),
5758
+ timestamp,
5759
+ ncp_message_id: message.id
5761
5760
  });
5762
5761
  }
5763
- if (blocks.length === 0) {
5764
- return serializeLegacyContent(parts);
5765
- }
5766
- const textOnly = blocks.every((part) => part.type === "text");
5767
- if (textOnly) {
5768
- return blocks.map((part) => String(part.text ?? "")).join("");
5769
- }
5770
- return blocks;
5762
+ return messages;
5771
5763
  }
5772
- function toLegacyMessages(messages) {
5764
+ function buildLegacyNonAssistantMessage(message, timestamp, options) {
5765
+ return {
5766
+ role: message.role,
5767
+ content: buildLegacyUserContent(message.parts, options),
5768
+ timestamp,
5769
+ ncp_message_id: message.id,
5770
+ ncp_parts: structuredClone(message.parts)
5771
+ };
5772
+ }
5773
+ function toLegacyMessages(messages, options = {}) {
5773
5774
  const legacyMessages = [];
5774
5775
  for (const rawMessage of messages) {
5775
5776
  const message = rawMessage.role === "assistant" ? sanitizeAssistantReplyTags(rawMessage) : rawMessage;
5776
5777
  const timestamp = ensureIsoTimestamp(message.timestamp, (/* @__PURE__ */ new Date()).toISOString());
5777
5778
  if (message.role === "assistant") {
5778
- const textContent = extractTextFromNcpMessage(message);
5779
- const reasoningContent = message.parts.filter((part) => part.type === "reasoning").map((part) => part.text).join("");
5780
- const toolInvocations = message.parts.filter(
5781
- (part) => part.type === "tool-invocation"
5782
- );
5783
- const assistantMessage = {
5784
- role: "assistant",
5785
- content: textContent,
5786
- timestamp,
5787
- ncp_message_id: message.id,
5788
- ncp_parts: structuredClone(message.parts)
5789
- };
5790
- if (typeof message.metadata?.reply_to === "string" && message.metadata.reply_to.trim().length > 0) {
5791
- assistantMessage.reply_to = message.metadata.reply_to.trim();
5792
- }
5793
- if (reasoningContent.length > 0) {
5794
- assistantMessage.reasoning_content = reasoningContent;
5795
- }
5796
- if (toolInvocations.length > 0) {
5797
- assistantMessage.tool_calls = toolInvocations.map((toolInvocation, index) => ({
5798
- id: toolInvocation.toolCallId ?? `${message.id}:tool:${index}`,
5799
- type: "function",
5800
- function: {
5801
- name: toolInvocation.toolName,
5802
- arguments: serializeToolArgs(toolInvocation.args)
5803
- }
5804
- }));
5805
- }
5806
- legacyMessages.push(assistantMessage);
5807
- for (const toolInvocation of toolInvocations) {
5808
- if (toolInvocation.state !== "result") {
5809
- continue;
5810
- }
5811
- legacyMessages.push({
5812
- role: "tool",
5813
- name: toolInvocation.toolName,
5814
- tool_call_id: toolInvocation.toolCallId,
5815
- content: typeof toolInvocation.result === "string" ? toolInvocation.result : JSON.stringify(toolInvocation.result ?? null),
5816
- timestamp,
5817
- ncp_message_id: message.id
5818
- });
5819
- }
5779
+ legacyMessages.push(...buildLegacyAssistantMessages(message, timestamp));
5820
5780
  continue;
5821
5781
  }
5822
- legacyMessages.push({
5823
- role: message.role,
5824
- content: buildLegacyUserContent(message.parts),
5825
- timestamp,
5826
- ncp_message_id: message.id,
5827
- ncp_parts: structuredClone(message.parts)
5828
- });
5782
+ legacyMessages.push(buildLegacyNonAssistantMessage(message, timestamp, options));
5829
5783
  }
5830
5784
  return legacyMessages;
5831
5785
  }
@@ -5991,7 +5945,10 @@ function buildCurrentTurnState(params) {
5991
5945
  originalText
5992
5946
  });
5993
5947
  return {
5994
- currentUserContent: buildLegacyUserContent(currentParts),
5948
+ currentUserContent: buildLegacyUserContent(currentParts, {
5949
+ attachmentStore: params.attachmentStore,
5950
+ attachmentTextMaxBytes: params.attachmentTextMaxBytes
5951
+ }),
5995
5952
  effectiveModel: params.currentModel
5996
5953
  };
5997
5954
  }
@@ -6392,7 +6349,9 @@ var NextclawNcpContextBuilder = class {
6392
6349
  formatPrompt: ({ text, timestamp }) => appendTimeHintForPrompt(
6393
6350
  prependRequestedSkills(text, requestedSkillNames),
6394
6351
  timestamp
6395
- )
6352
+ ),
6353
+ attachmentStore: this.options.attachmentStore,
6354
+ attachmentTextMaxBytes: this.options.attachmentTextMaxBytes
6396
6355
  });
6397
6356
  effectiveModel = currentTurn.effectiveModel;
6398
6357
  const runtimeThinking = resolveThinkingLevel({
@@ -6428,7 +6387,10 @@ var NextclawNcpContextBuilder = class {
6428
6387
  const contextBuilder = new ContextBuilder(profile.workspace, config2.agents.context);
6429
6388
  const sessionMessages = _options?.sessionMessages ?? [];
6430
6389
  const messages = contextBuilder.buildMessages({
6431
- history: toLegacyMessages([...sessionMessages]),
6390
+ history: toLegacyMessages([...sessionMessages], {
6391
+ attachmentStore: this.options.attachmentStore,
6392
+ attachmentTextMaxBytes: this.options.attachmentTextMaxBytes
6393
+ }),
6432
6394
  currentMessage: "",
6433
6395
  attachments: [],
6434
6396
  channel,
@@ -6966,6 +6928,7 @@ var UiNcpRuntimeRegistry = class {
6966
6928
  };
6967
6929
 
6968
6930
  // src/cli/commands/ncp/create-ui-ncp-agent.ts
6931
+ import { join as join5 } from "path";
6969
6932
  var CODEX_RUNTIME_KIND = "codex";
6970
6933
  var CODEX_DIRECT_RUNTIME_BACKEND = "codex-sdk";
6971
6934
  function isRecord5(value) {
@@ -7037,7 +7000,7 @@ async function createMcpRuntimeSupport(getConfig) {
7037
7000
  }
7038
7001
  };
7039
7002
  }
7040
- function createNativeRuntimeFactory(params, mcpToolRegistryAdapter) {
7003
+ function createNativeRuntimeFactory(params, mcpToolRegistryAdapter, attachmentStore) {
7041
7004
  return ({
7042
7005
  stateManager,
7043
7006
  sessionMetadata,
@@ -7072,7 +7035,8 @@ function createNativeRuntimeFactory(params, mcpToolRegistryAdapter) {
7072
7035
  sessionManager: params.sessionManager,
7073
7036
  toolRegistry,
7074
7037
  getConfig: params.getConfig,
7075
- resolveMessageToolHints: params.resolveMessageToolHints
7038
+ resolveMessageToolHints: params.resolveMessageToolHints,
7039
+ attachmentStore
7076
7040
  }),
7077
7041
  llmApi: new ProviderManagerNcpLLMApi(params.providerManager),
7078
7042
  toolRegistry,
@@ -7142,6 +7106,11 @@ function createUiNcpAgentHandle(params) {
7142
7106
  params.refreshPluginRuntimeRegistrations();
7143
7107
  return params.runtimeRegistry.listSessionTypes(describeParams);
7144
7108
  },
7109
+ attachmentApi: {
7110
+ saveAttachment: (input) => params.attachmentStore.saveAttachment(input),
7111
+ statAttachment: (uri) => params.attachmentStore.statAttachment(uri),
7112
+ resolveContentPath: (uri) => params.attachmentStore.resolveContentPath(uri)
7113
+ },
7145
7114
  applyExtensionRegistry: params.applyExtensionRegistry,
7146
7115
  applyMcpConfig: params.applyMcpConfig
7147
7116
  };
@@ -7150,7 +7119,10 @@ async function createUiNcpAgent(params) {
7150
7119
  const sessionStore = new NextclawAgentSessionStore(params.sessionManager);
7151
7120
  const runtimeRegistry = new UiNcpRuntimeRegistry();
7152
7121
  const { toolRegistryAdapter, applyMcpConfig } = await createMcpRuntimeSupport(params.getConfig);
7153
- const createNativeRuntime = createNativeRuntimeFactory(params, toolRegistryAdapter);
7122
+ const attachmentStore = new LocalAttachmentStore({
7123
+ rootDir: join5(getDataDir6(), "attachments")
7124
+ });
7125
+ const createNativeRuntime = createNativeRuntimeFactory(params, toolRegistryAdapter, attachmentStore);
7154
7126
  runtimeRegistry.register({
7155
7127
  kind: "native",
7156
7128
  label: "Native",
@@ -7177,7 +7149,8 @@ async function createUiNcpAgent(params) {
7177
7149
  runtimeRegistry,
7178
7150
  refreshPluginRuntimeRegistrations: pluginRuntimeRegistrationController.refreshPluginRuntimeRegistrations,
7179
7151
  applyExtensionRegistry: pluginRuntimeRegistrationController.applyExtensionRegistry,
7180
- applyMcpConfig
7152
+ applyMcpConfig,
7153
+ attachmentStore
7181
7154
  });
7182
7155
  }
7183
7156
 
@@ -7194,9 +7167,9 @@ import {
7194
7167
  writeFileSync as writeFileSync4
7195
7168
  } from "fs";
7196
7169
  import { dirname as dirname2, resolve as resolve10 } from "path";
7197
- import { getDataDir as getDataDir6 } from "@nextclaw/core";
7170
+ import { getDataDir as getDataDir7 } from "@nextclaw/core";
7198
7171
  function resolveRemoteOwnershipLockPath() {
7199
- return resolve10(getDataDir6(), "run", "remote-owner.lock.json");
7172
+ return resolve10(getDataDir7(), "run", "remote-owner.lock.json");
7200
7173
  }
7201
7174
  function readRemoteOwnershipRecord(lockPath) {
7202
7175
  try {
@@ -7341,10 +7314,11 @@ function createManagedRemoteModule(params) {
7341
7314
  });
7342
7315
  }
7343
7316
  function createManagedRemoteModuleForUi(params) {
7317
+ const explicitLocalOrigin = params.localOriginOverride?.trim() ?? process.env.NEXTCLAW_REMOTE_LOCAL_ORIGIN?.trim();
7344
7318
  return createManagedRemoteModule({
7345
7319
  loadConfig: params.loadConfig,
7346
7320
  uiEnabled: params.uiConfig.enabled,
7347
- localOrigin: resolveUiApiBase(params.uiConfig.host, params.uiConfig.port)
7321
+ localOrigin: explicitLocalOrigin && explicitLocalOrigin.length > 0 ? explicitLocalOrigin.replace(/\/+$/, "") : resolveUiApiBase(params.uiConfig.host, params.uiConfig.port)
7348
7322
  });
7349
7323
  }
7350
7324
  function writeInitialManagedServiceState(params) {
@@ -7712,13 +7686,13 @@ function createRemoteAccessHost(params) {
7712
7686
 
7713
7687
  // src/cli/commands/ui-chat-run-coordinator.ts
7714
7688
  import { existsSync as existsSync11, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync9, writeFileSync as writeFileSync5 } from "fs";
7715
- import { join as join5 } from "path";
7689
+ import { join as join6 } from "path";
7716
7690
  import {
7717
- getDataDir as getDataDir7,
7691
+ getDataDir as getDataDir8,
7718
7692
  parseAgentScopedSessionKey as parseAgentScopedSessionKey3,
7719
7693
  safeFilename
7720
7694
  } from "@nextclaw/core";
7721
- var RUNS_DIR = join5(getDataDir7(), "runs");
7695
+ var RUNS_DIR = join6(getDataDir8(), "runs");
7722
7696
  var NON_TERMINAL_STATES = /* @__PURE__ */ new Set(["queued", "running"]);
7723
7697
  var DEFAULT_SESSION_TYPE = "native";
7724
7698
  var SESSION_TYPE_METADATA_KEY = "session_type";
@@ -8244,7 +8218,7 @@ var UiChatRunCoordinator = class {
8244
8218
  };
8245
8219
  }
8246
8220
  getRunPath(runId) {
8247
- return join5(RUNS_DIR, `${safeFilename(runId)}.json`);
8221
+ return join6(RUNS_DIR, `${safeFilename(runId)}.json`);
8248
8222
  }
8249
8223
  persistRun(run) {
8250
8224
  const persisted = {
@@ -8273,7 +8247,7 @@ var UiChatRunCoordinator = class {
8273
8247
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
8274
8248
  continue;
8275
8249
  }
8276
- const path2 = join5(RUNS_DIR, entry.name);
8250
+ const path2 = join6(RUNS_DIR, entry.name);
8277
8251
  try {
8278
8252
  const parsed = JSON.parse(readFileSync9(path2, "utf-8"));
8279
8253
  const runId = readOptionalString2(parsed.runId);
@@ -8335,7 +8309,7 @@ var {
8335
8309
  CronService: CronService2,
8336
8310
  getApiBase,
8337
8311
  getConfigPath: getConfigPath9,
8338
- getDataDir: getDataDir8,
8312
+ getDataDir: getDataDir9,
8339
8313
  getProvider,
8340
8314
  getProviderName,
8341
8315
  getWorkspacePath: getWorkspacePath10,
@@ -8380,7 +8354,7 @@ var ServiceCommands = class {
8380
8354
  });
8381
8355
  const sessionManager = new SessionManager(workspace);
8382
8356
  let pluginGatewayHandles = [];
8383
- const cronStorePath = join6(getDataDir8(), "cron", "jobs.json");
8357
+ const cronStorePath = join7(getDataDir9(), "cron", "jobs.json");
8384
8358
  const cron2 = new CronService2(cronStorePath);
8385
8359
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
8386
8360
  const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
@@ -9184,6 +9158,7 @@ var ServiceCommands = class {
9184
9158
  configPath: getConfigPath9(),
9185
9159
  productVersion: getPackageVersion(),
9186
9160
  staticDir: uiStaticDir ?? void 0,
9161
+ applyLiveConfigReload: this.applyLiveConfigReload ?? void 0,
9187
9162
  cronService,
9188
9163
  marketplace: {
9189
9164
  apiBaseUrl: process.env.NEXTCLAW_MARKETPLACE_API_BASE,
@@ -9208,8 +9183,8 @@ var ServiceCommands = class {
9208
9183
  }
9209
9184
  installBuiltinMarketplaceSkill(slug, force) {
9210
9185
  const workspace = getWorkspacePath10(loadConfig17().agents.defaults.workspace);
9211
- const destination = join6(workspace, "skills", slug);
9212
- const destinationSkillFile = join6(destination, "SKILL.md");
9186
+ const destination = join7(workspace, "skills", slug);
9187
+ const destinationSkillFile = join7(destination, "SKILL.md");
9213
9188
  if (existsSync12(destinationSkillFile) && !force) {
9214
9189
  return {
9215
9190
  message: `${slug} is already installed`
@@ -9225,7 +9200,7 @@ var ServiceCommands = class {
9225
9200
  }
9226
9201
  return null;
9227
9202
  }
9228
- mkdirSync6(join6(workspace, "skills"), { recursive: true });
9203
+ mkdirSync6(join7(workspace, "skills"), { recursive: true });
9229
9204
  cpSync2(dirname3(builtin.path), destination, { recursive: true, force: true });
9230
9205
  return {
9231
9206
  message: `Installed skill: ${slug}`
@@ -9287,9 +9262,9 @@ ${stderr}`.trim();
9287
9262
  // src/cli/workspace.ts
9288
9263
  import { cpSync as cpSync3, existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync10, readdirSync as readdirSync3, rmSync as rmSync6, writeFileSync as writeFileSync6 } from "fs";
9289
9264
  import { createRequire as createRequire2 } from "module";
9290
- import { dirname as dirname4, join as join7, resolve as resolve12 } from "path";
9265
+ import { dirname as dirname4, join as join8, resolve as resolve12 } from "path";
9291
9266
  import { fileURLToPath as fileURLToPath4 } from "url";
9292
- import { APP_NAME as APP_NAME4, getDataDir as getDataDir9 } from "@nextclaw/core";
9267
+ import { APP_NAME as APP_NAME4, getDataDir as getDataDir10 } from "@nextclaw/core";
9293
9268
  import { spawnSync as spawnSync3 } from "child_process";
9294
9269
  var WorkspaceManager = class {
9295
9270
  constructor(logo) {
@@ -9317,11 +9292,11 @@ var WorkspaceManager = class {
9317
9292
  { source: "memory/MEMORY.md", target: "memory/MEMORY.md" }
9318
9293
  ];
9319
9294
  for (const entry of templateFiles) {
9320
- const filePath = join7(workspace, entry.target);
9295
+ const filePath = join8(workspace, entry.target);
9321
9296
  if (!force && existsSync13(filePath)) {
9322
9297
  continue;
9323
9298
  }
9324
- const templatePath = join7(templateDir, entry.source);
9299
+ const templatePath = join8(templateDir, entry.source);
9325
9300
  if (!existsSync13(templatePath)) {
9326
9301
  console.warn(`Warning: Template file missing: ${templatePath}`);
9327
9302
  continue;
@@ -9332,15 +9307,15 @@ var WorkspaceManager = class {
9332
9307
  writeFileSync6(filePath, content);
9333
9308
  created.push(entry.target);
9334
9309
  }
9335
- const memoryDir = join7(workspace, "memory");
9310
+ const memoryDir = join8(workspace, "memory");
9336
9311
  if (!existsSync13(memoryDir)) {
9337
9312
  mkdirSync7(memoryDir, { recursive: true });
9338
- created.push(join7("memory", ""));
9313
+ created.push(join8("memory", ""));
9339
9314
  }
9340
- const skillsDir = join7(workspace, "skills");
9315
+ const skillsDir = join8(workspace, "skills");
9341
9316
  if (!existsSync13(skillsDir)) {
9342
9317
  mkdirSync7(skillsDir, { recursive: true });
9343
- created.push(join7("skills", ""));
9318
+ created.push(join8("skills", ""));
9344
9319
  }
9345
9320
  const seeded = this.seedBuiltinSkills(skillsDir, { force });
9346
9321
  if (seeded > 0) {
@@ -9359,11 +9334,11 @@ var WorkspaceManager = class {
9359
9334
  if (!entry.isDirectory()) {
9360
9335
  continue;
9361
9336
  }
9362
- const src = join7(sourceDir, entry.name);
9363
- if (!existsSync13(join7(src, "SKILL.md"))) {
9337
+ const src = join8(sourceDir, entry.name);
9338
+ if (!existsSync13(join8(src, "SKILL.md"))) {
9364
9339
  continue;
9365
9340
  }
9366
- const dest = join7(targetDir, entry.name);
9341
+ const dest = join8(targetDir, entry.name);
9367
9342
  if (!force && existsSync13(dest)) {
9368
9343
  continue;
9369
9344
  }
@@ -9382,11 +9357,11 @@ var WorkspaceManager = class {
9382
9357
  const require3 = createRequire2(import.meta.url);
9383
9358
  const entry = require3.resolve("@nextclaw/core");
9384
9359
  const pkgRoot = resolve12(dirname4(entry), "..");
9385
- const distSkills = join7(pkgRoot, "dist", "skills");
9360
+ const distSkills = join8(pkgRoot, "dist", "skills");
9386
9361
  if (existsSync13(distSkills)) {
9387
9362
  return distSkills;
9388
9363
  }
9389
- const srcSkills = join7(pkgRoot, "src", "agent", "skills");
9364
+ const srcSkills = join8(pkgRoot, "src", "agent", "skills");
9390
9365
  if (existsSync13(srcSkills)) {
9391
9366
  return srcSkills;
9392
9367
  }
@@ -9402,7 +9377,7 @@ var WorkspaceManager = class {
9402
9377
  }
9403
9378
  const cliDir = resolve12(fileURLToPath4(new URL(".", import.meta.url)));
9404
9379
  const pkgRoot = resolve12(cliDir, "..", "..");
9405
- const candidates = [join7(pkgRoot, "templates")];
9380
+ const candidates = [join8(pkgRoot, "templates")];
9406
9381
  for (const candidate of candidates) {
9407
9382
  if (existsSync13(candidate)) {
9408
9383
  return candidate;
@@ -9411,8 +9386,8 @@ var WorkspaceManager = class {
9411
9386
  return null;
9412
9387
  }
9413
9388
  getBridgeDir() {
9414
- const userBridge = join7(getDataDir9(), "bridge");
9415
- if (existsSync13(join7(userBridge, "dist", "index.js"))) {
9389
+ const userBridge = join8(getDataDir10(), "bridge");
9390
+ if (existsSync13(join8(userBridge, "dist", "index.js"))) {
9416
9391
  return userBridge;
9417
9392
  }
9418
9393
  if (!which("npm")) {
@@ -9421,12 +9396,12 @@ var WorkspaceManager = class {
9421
9396
  }
9422
9397
  const cliDir = resolve12(fileURLToPath4(new URL(".", import.meta.url)));
9423
9398
  const pkgRoot = resolve12(cliDir, "..", "..");
9424
- const pkgBridge = join7(pkgRoot, "bridge");
9425
- const srcBridge = join7(pkgRoot, "..", "..", "bridge");
9399
+ const pkgBridge = join8(pkgRoot, "bridge");
9400
+ const srcBridge = join8(pkgRoot, "..", "..", "bridge");
9426
9401
  let source = null;
9427
- if (existsSync13(join7(pkgBridge, "package.json"))) {
9402
+ if (existsSync13(join8(pkgBridge, "package.json"))) {
9428
9403
  source = pkgBridge;
9429
- } else if (existsSync13(join7(srcBridge, "package.json"))) {
9404
+ } else if (existsSync13(join8(srcBridge, "package.json"))) {
9430
9405
  source = srcBridge;
9431
9406
  }
9432
9407
  if (!source) {
@@ -9584,7 +9559,7 @@ var CliRuntime = class {
9584
9559
  const delayMs = typeof params.delayMs === "number" && Number.isFinite(params.delayMs) ? Math.max(0, Math.floor(params.delayMs)) : 100;
9585
9560
  const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath5(new URL("./index.js", import.meta.url));
9586
9561
  const startArgs = [cliPath, "start", "--ui-port", String(uiPort)];
9587
- const serviceStatePath = resolve13(getDataDir10(), "run", "service.json");
9562
+ const serviceStatePath = resolve13(getDataDir11(), "run", "service.json");
9588
9563
  const helperScript = [
9589
9564
  'const { spawnSync } = require("node:child_process");',
9590
9565
  'const { readFileSync } = require("node:fs");',
@@ -9716,7 +9691,7 @@ var CliRuntime = class {
9716
9691
  const createdConfig = initializeConfigIfMissing(configPath);
9717
9692
  const config2 = loadConfig18();
9718
9693
  const workspaceSetting = config2.agents.defaults.workspace;
9719
- const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir10(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9694
+ const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join9(getDataDir11(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9720
9695
  const workspaceExisted = existsSync14(workspacePath);
9721
9696
  mkdirSync8(workspacePath, { recursive: true });
9722
9697
  const templateResult = this.workspaceManager.createWorkspaceTemplates(
@@ -9909,7 +9884,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9909
9884
  `${this.logo} Interactive mode (type exit or Ctrl+C to quit)
9910
9885
  `
9911
9886
  );
9912
- const historyFile = join8(getDataDir10(), "history", "cli_history");
9887
+ const historyFile = join9(getDataDir11(), "history", "cli_history");
9913
9888
  const historyDir = resolve13(historyFile, "..");
9914
9889
  mkdirSync8(historyDir, { recursive: true });
9915
9890
  const history = existsSync14(historyFile) ? readFileSync11(historyFile, "utf-8").split("\n").filter(Boolean) : [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.15.13",
3
+ "version": "0.15.15",
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.1",
43
- "@nextclaw/mcp": "0.1.50",
44
- "@nextclaw/ncp-agent-runtime": "0.2.3",
45
- "@nextclaw/ncp": "0.3.2",
46
- "@nextclaw/ncp-mcp": "0.1.49",
47
- "@nextclaw/ncp-toolkit": "0.4.2",
48
- "@nextclaw/remote": "0.1.49",
49
- "@nextclaw/runtime": "0.2.15",
50
- "@nextclaw/server": "0.10.55",
51
- "@nextclaw/openclaw-compat": "0.3.31"
42
+ "@nextclaw/core": "0.11.2",
43
+ "@nextclaw/mcp": "0.1.51",
44
+ "@nextclaw/ncp": "0.3.3",
45
+ "@nextclaw/ncp-agent-runtime": "0.2.4",
46
+ "@nextclaw/ncp-mcp": "0.1.50",
47
+ "@nextclaw/ncp-toolkit": "0.4.3",
48
+ "@nextclaw/remote": "0.1.51",
49
+ "@nextclaw/runtime": "0.2.16",
50
+ "@nextclaw/server": "0.10.57",
51
+ "@nextclaw/openclaw-compat": "0.3.33"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^20.17.6",
@@ -57,7 +57,7 @@
57
57
  "tsx": "^4.19.2",
58
58
  "typescript": "^5.6.3",
59
59
  "vitest": "^2.1.2",
60
- "@nextclaw/ui": "0.10.4"
60
+ "@nextclaw/ui": "0.10.5"
61
61
  },
62
62
  "scripts": {
63
63
  "dev": "tsx watch --tsconfig tsconfig.json src/cli/index.ts",