nextclaw 0.15.12 → 0.15.14

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 (28) hide show
  1. package/dist/cli/index.js +125 -152
  2. package/package.json +6 -6
  3. package/ui-dist/assets/{ChannelsList-ohaw9GpD.js → ChannelsList-Nu7Ig6_-.js} +1 -1
  4. package/ui-dist/assets/{ChatPage-BqFTFaut.js → ChatPage-CBCFSk4e.js} +24 -24
  5. package/ui-dist/assets/{DocBrowser-Cm8LqQ8S.js → DocBrowser-3CfKmJA6.js} +1 -1
  6. package/ui-dist/assets/{LogoBadge-GTNIKJO9.js → LogoBadge-DdthDJOp.js} +1 -1
  7. package/ui-dist/assets/{MarketplacePage-CfSXSQFi.js → MarketplacePage-inGGiv1T.js} +1 -1
  8. package/ui-dist/assets/{McpMarketplacePage-BRJudD8Z.js → McpMarketplacePage-Dg8GSZh6.js} +1 -1
  9. package/ui-dist/assets/{ModelConfig-B-P04UNK.js → ModelConfig-DyQ6cC92.js} +1 -1
  10. package/ui-dist/assets/{ProvidersList-D9IocmDB.js → ProvidersList-B2T8Lc_i.js} +1 -1
  11. package/ui-dist/assets/{RemoteAccessPage-58fYdCYK.js → RemoteAccessPage-C9LxgK-C.js} +1 -1
  12. package/ui-dist/assets/{RuntimeConfig-C5NlEc57.js → RuntimeConfig-Ey4VIqTW.js} +1 -1
  13. package/ui-dist/assets/{SearchConfig-Cw17ED0n.js → SearchConfig-R1BcCLWO.js} +1 -1
  14. package/ui-dist/assets/{SecretsConfig-DliEIjCS.js → SecretsConfig-D-jZMHeY.js} +2 -2
  15. package/ui-dist/assets/{SessionsConfig-BRqvuKqq.js → SessionsConfig-Cawoh4_2.js} +1 -1
  16. package/ui-dist/assets/{chat-message-C6dxqsRj.js → chat-message-BbuIK4dQ.js} +1 -1
  17. package/ui-dist/assets/index-BulnQWr6.js +8 -0
  18. package/ui-dist/assets/{label-B3FlNUAA.js → label-C7yzBvzK.js} +1 -1
  19. package/ui-dist/assets/{page-layout-HrT1hpq7.js → page-layout-DF0xpax2.js} +1 -1
  20. package/ui-dist/assets/{popover-BEo9XeN-.js → popover-DjaScZDJ.js} +1 -1
  21. package/ui-dist/assets/{security-config-BRE-9ipr.js → security-config-Bg2eriNx.js} +1 -1
  22. package/ui-dist/assets/{skeleton-BeC_fgbu.js → skeleton-DycBJAJF.js} +1 -1
  23. package/ui-dist/assets/{status-dot-D9tZgJWo.js → status-dot-B9opOZ22.js} +1 -1
  24. package/ui-dist/assets/{switch-Cq7y46-d.js → switch-l1P0ev4D.js} +1 -1
  25. package/ui-dist/assets/{tabs-custom-xrIDQNF2.js → tabs-custom-BG9y2JhC.js} +1 -1
  26. package/ui-dist/assets/{useConfirmDialog-DCZbJzHW.js → useConfirmDialog-DTducNfn.js} +1 -1
  27. package/ui-dist/index.html +1 -1
  28. package/ui-dist/assets/index-B3caHNCU.js +0 -8
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;
5763
+ }
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
+ };
5771
5772
  }
5772
- function toLegacyMessages(messages) {
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 {
@@ -7712,13 +7685,13 @@ function createRemoteAccessHost(params) {
7712
7685
 
7713
7686
  // src/cli/commands/ui-chat-run-coordinator.ts
7714
7687
  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";
7688
+ import { join as join6 } from "path";
7716
7689
  import {
7717
- getDataDir as getDataDir7,
7690
+ getDataDir as getDataDir8,
7718
7691
  parseAgentScopedSessionKey as parseAgentScopedSessionKey3,
7719
7692
  safeFilename
7720
7693
  } from "@nextclaw/core";
7721
- var RUNS_DIR = join5(getDataDir7(), "runs");
7694
+ var RUNS_DIR = join6(getDataDir8(), "runs");
7722
7695
  var NON_TERMINAL_STATES = /* @__PURE__ */ new Set(["queued", "running"]);
7723
7696
  var DEFAULT_SESSION_TYPE = "native";
7724
7697
  var SESSION_TYPE_METADATA_KEY = "session_type";
@@ -8244,7 +8217,7 @@ var UiChatRunCoordinator = class {
8244
8217
  };
8245
8218
  }
8246
8219
  getRunPath(runId) {
8247
- return join5(RUNS_DIR, `${safeFilename(runId)}.json`);
8220
+ return join6(RUNS_DIR, `${safeFilename(runId)}.json`);
8248
8221
  }
8249
8222
  persistRun(run) {
8250
8223
  const persisted = {
@@ -8273,7 +8246,7 @@ var UiChatRunCoordinator = class {
8273
8246
  if (!entry.isFile() || !entry.name.endsWith(".json")) {
8274
8247
  continue;
8275
8248
  }
8276
- const path2 = join5(RUNS_DIR, entry.name);
8249
+ const path2 = join6(RUNS_DIR, entry.name);
8277
8250
  try {
8278
8251
  const parsed = JSON.parse(readFileSync9(path2, "utf-8"));
8279
8252
  const runId = readOptionalString2(parsed.runId);
@@ -8335,7 +8308,7 @@ var {
8335
8308
  CronService: CronService2,
8336
8309
  getApiBase,
8337
8310
  getConfigPath: getConfigPath9,
8338
- getDataDir: getDataDir8,
8311
+ getDataDir: getDataDir9,
8339
8312
  getProvider,
8340
8313
  getProviderName,
8341
8314
  getWorkspacePath: getWorkspacePath10,
@@ -8380,7 +8353,7 @@ var ServiceCommands = class {
8380
8353
  });
8381
8354
  const sessionManager = new SessionManager(workspace);
8382
8355
  let pluginGatewayHandles = [];
8383
- const cronStorePath = join6(getDataDir8(), "cron", "jobs.json");
8356
+ const cronStorePath = join7(getDataDir9(), "cron", "jobs.json");
8384
8357
  const cron2 = new CronService2(cronStorePath);
8385
8358
  const uiConfig = resolveUiConfig(config2, options.uiOverrides);
8386
8359
  const uiStaticDir = options.uiStaticDir === void 0 ? resolveUiStaticDir() : options.uiStaticDir;
@@ -9208,8 +9181,8 @@ var ServiceCommands = class {
9208
9181
  }
9209
9182
  installBuiltinMarketplaceSkill(slug, force) {
9210
9183
  const workspace = getWorkspacePath10(loadConfig17().agents.defaults.workspace);
9211
- const destination = join6(workspace, "skills", slug);
9212
- const destinationSkillFile = join6(destination, "SKILL.md");
9184
+ const destination = join7(workspace, "skills", slug);
9185
+ const destinationSkillFile = join7(destination, "SKILL.md");
9213
9186
  if (existsSync12(destinationSkillFile) && !force) {
9214
9187
  return {
9215
9188
  message: `${slug} is already installed`
@@ -9225,7 +9198,7 @@ var ServiceCommands = class {
9225
9198
  }
9226
9199
  return null;
9227
9200
  }
9228
- mkdirSync6(join6(workspace, "skills"), { recursive: true });
9201
+ mkdirSync6(join7(workspace, "skills"), { recursive: true });
9229
9202
  cpSync2(dirname3(builtin.path), destination, { recursive: true, force: true });
9230
9203
  return {
9231
9204
  message: `Installed skill: ${slug}`
@@ -9287,9 +9260,9 @@ ${stderr}`.trim();
9287
9260
  // src/cli/workspace.ts
9288
9261
  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
9262
  import { createRequire as createRequire2 } from "module";
9290
- import { dirname as dirname4, join as join7, resolve as resolve12 } from "path";
9263
+ import { dirname as dirname4, join as join8, resolve as resolve12 } from "path";
9291
9264
  import { fileURLToPath as fileURLToPath4 } from "url";
9292
- import { APP_NAME as APP_NAME4, getDataDir as getDataDir9 } from "@nextclaw/core";
9265
+ import { APP_NAME as APP_NAME4, getDataDir as getDataDir10 } from "@nextclaw/core";
9293
9266
  import { spawnSync as spawnSync3 } from "child_process";
9294
9267
  var WorkspaceManager = class {
9295
9268
  constructor(logo) {
@@ -9317,11 +9290,11 @@ var WorkspaceManager = class {
9317
9290
  { source: "memory/MEMORY.md", target: "memory/MEMORY.md" }
9318
9291
  ];
9319
9292
  for (const entry of templateFiles) {
9320
- const filePath = join7(workspace, entry.target);
9293
+ const filePath = join8(workspace, entry.target);
9321
9294
  if (!force && existsSync13(filePath)) {
9322
9295
  continue;
9323
9296
  }
9324
- const templatePath = join7(templateDir, entry.source);
9297
+ const templatePath = join8(templateDir, entry.source);
9325
9298
  if (!existsSync13(templatePath)) {
9326
9299
  console.warn(`Warning: Template file missing: ${templatePath}`);
9327
9300
  continue;
@@ -9332,15 +9305,15 @@ var WorkspaceManager = class {
9332
9305
  writeFileSync6(filePath, content);
9333
9306
  created.push(entry.target);
9334
9307
  }
9335
- const memoryDir = join7(workspace, "memory");
9308
+ const memoryDir = join8(workspace, "memory");
9336
9309
  if (!existsSync13(memoryDir)) {
9337
9310
  mkdirSync7(memoryDir, { recursive: true });
9338
- created.push(join7("memory", ""));
9311
+ created.push(join8("memory", ""));
9339
9312
  }
9340
- const skillsDir = join7(workspace, "skills");
9313
+ const skillsDir = join8(workspace, "skills");
9341
9314
  if (!existsSync13(skillsDir)) {
9342
9315
  mkdirSync7(skillsDir, { recursive: true });
9343
- created.push(join7("skills", ""));
9316
+ created.push(join8("skills", ""));
9344
9317
  }
9345
9318
  const seeded = this.seedBuiltinSkills(skillsDir, { force });
9346
9319
  if (seeded > 0) {
@@ -9359,11 +9332,11 @@ var WorkspaceManager = class {
9359
9332
  if (!entry.isDirectory()) {
9360
9333
  continue;
9361
9334
  }
9362
- const src = join7(sourceDir, entry.name);
9363
- if (!existsSync13(join7(src, "SKILL.md"))) {
9335
+ const src = join8(sourceDir, entry.name);
9336
+ if (!existsSync13(join8(src, "SKILL.md"))) {
9364
9337
  continue;
9365
9338
  }
9366
- const dest = join7(targetDir, entry.name);
9339
+ const dest = join8(targetDir, entry.name);
9367
9340
  if (!force && existsSync13(dest)) {
9368
9341
  continue;
9369
9342
  }
@@ -9382,11 +9355,11 @@ var WorkspaceManager = class {
9382
9355
  const require3 = createRequire2(import.meta.url);
9383
9356
  const entry = require3.resolve("@nextclaw/core");
9384
9357
  const pkgRoot = resolve12(dirname4(entry), "..");
9385
- const distSkills = join7(pkgRoot, "dist", "skills");
9358
+ const distSkills = join8(pkgRoot, "dist", "skills");
9386
9359
  if (existsSync13(distSkills)) {
9387
9360
  return distSkills;
9388
9361
  }
9389
- const srcSkills = join7(pkgRoot, "src", "agent", "skills");
9362
+ const srcSkills = join8(pkgRoot, "src", "agent", "skills");
9390
9363
  if (existsSync13(srcSkills)) {
9391
9364
  return srcSkills;
9392
9365
  }
@@ -9402,7 +9375,7 @@ var WorkspaceManager = class {
9402
9375
  }
9403
9376
  const cliDir = resolve12(fileURLToPath4(new URL(".", import.meta.url)));
9404
9377
  const pkgRoot = resolve12(cliDir, "..", "..");
9405
- const candidates = [join7(pkgRoot, "templates")];
9378
+ const candidates = [join8(pkgRoot, "templates")];
9406
9379
  for (const candidate of candidates) {
9407
9380
  if (existsSync13(candidate)) {
9408
9381
  return candidate;
@@ -9411,8 +9384,8 @@ var WorkspaceManager = class {
9411
9384
  return null;
9412
9385
  }
9413
9386
  getBridgeDir() {
9414
- const userBridge = join7(getDataDir9(), "bridge");
9415
- if (existsSync13(join7(userBridge, "dist", "index.js"))) {
9387
+ const userBridge = join8(getDataDir10(), "bridge");
9388
+ if (existsSync13(join8(userBridge, "dist", "index.js"))) {
9416
9389
  return userBridge;
9417
9390
  }
9418
9391
  if (!which("npm")) {
@@ -9421,12 +9394,12 @@ var WorkspaceManager = class {
9421
9394
  }
9422
9395
  const cliDir = resolve12(fileURLToPath4(new URL(".", import.meta.url)));
9423
9396
  const pkgRoot = resolve12(cliDir, "..", "..");
9424
- const pkgBridge = join7(pkgRoot, "bridge");
9425
- const srcBridge = join7(pkgRoot, "..", "..", "bridge");
9397
+ const pkgBridge = join8(pkgRoot, "bridge");
9398
+ const srcBridge = join8(pkgRoot, "..", "..", "bridge");
9426
9399
  let source = null;
9427
- if (existsSync13(join7(pkgBridge, "package.json"))) {
9400
+ if (existsSync13(join8(pkgBridge, "package.json"))) {
9428
9401
  source = pkgBridge;
9429
- } else if (existsSync13(join7(srcBridge, "package.json"))) {
9402
+ } else if (existsSync13(join8(srcBridge, "package.json"))) {
9430
9403
  source = srcBridge;
9431
9404
  }
9432
9405
  if (!source) {
@@ -9584,7 +9557,7 @@ var CliRuntime = class {
9584
9557
  const delayMs = typeof params.delayMs === "number" && Number.isFinite(params.delayMs) ? Math.max(0, Math.floor(params.delayMs)) : 100;
9585
9558
  const cliPath = process.env.NEXTCLAW_SELF_RELAUNCH_CLI?.trim() || fileURLToPath5(new URL("./index.js", import.meta.url));
9586
9559
  const startArgs = [cliPath, "start", "--ui-port", String(uiPort)];
9587
- const serviceStatePath = resolve13(getDataDir10(), "run", "service.json");
9560
+ const serviceStatePath = resolve13(getDataDir11(), "run", "service.json");
9588
9561
  const helperScript = [
9589
9562
  'const { spawnSync } = require("node:child_process");',
9590
9563
  'const { readFileSync } = require("node:fs");',
@@ -9716,7 +9689,7 @@ var CliRuntime = class {
9716
9689
  const createdConfig = initializeConfigIfMissing(configPath);
9717
9690
  const config2 = loadConfig18();
9718
9691
  const workspaceSetting = config2.agents.defaults.workspace;
9719
- const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join8(getDataDir10(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9692
+ const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join9(getDataDir11(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
9720
9693
  const workspaceExisted = existsSync14(workspacePath);
9721
9694
  mkdirSync8(workspacePath, { recursive: true });
9722
9695
  const templateResult = this.workspaceManager.createWorkspaceTemplates(
@@ -9909,7 +9882,7 @@ ${this.logo} ${APP_NAME5} is ready! (${source})`);
9909
9882
  `${this.logo} Interactive mode (type exit or Ctrl+C to quit)
9910
9883
  `
9911
9884
  );
9912
- const historyFile = join8(getDataDir10(), "history", "cli_history");
9885
+ const historyFile = join9(getDataDir11(), "history", "cli_history");
9913
9886
  const historyDir = resolve13(historyFile, "..");
9914
9887
  mkdirSync8(historyDir, { recursive: true });
9915
9888
  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.12",
3
+ "version": "0.15.14",
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
42
  "@nextclaw/mcp": "0.1.50",
44
- "@nextclaw/ncp": "0.3.2",
45
43
  "@nextclaw/ncp-agent-runtime": "0.2.3",
44
+ "@nextclaw/core": "0.11.1",
46
45
  "@nextclaw/ncp-mcp": "0.1.49",
46
+ "@nextclaw/ncp": "0.3.2",
47
47
  "@nextclaw/ncp-toolkit": "0.4.2",
48
- "@nextclaw/remote": "0.1.48",
49
48
  "@nextclaw/runtime": "0.2.15",
50
- "@nextclaw/server": "0.10.54",
51
- "@nextclaw/openclaw-compat": "0.3.30"
49
+ "@nextclaw/remote": "0.1.50",
50
+ "@nextclaw/server": "0.10.56",
51
+ "@nextclaw/openclaw-compat": "0.3.32"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^20.17.6",