nextclaw 0.17.8 → 0.17.10

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 (2) hide show
  1. package/dist/cli/index.js +124 -81
  2. package/package.json +11 -11
package/dist/cli/index.js CHANGED
@@ -19,7 +19,7 @@ import { request } from "node:http";
19
19
  import { request as request$1 } from "node:https";
20
20
  import { setImmediate as setImmediate$1, setTimeout as setTimeout$1 } from "node:timers/promises";
21
21
  import chokidar from "chokidar";
22
- import { DefaultNcpAgentRuntime, LocalAssetStore, buildAssetContentPath, buildNcpUserContent } from "@nextclaw/ncp-agent-runtime";
22
+ import { DefaultNcpAgentRuntime, LocalAssetStore, buildAssetContentPath, buildNcpUserContent, buildOpenAiFunctionTool } from "@nextclaw/ncp-agent-runtime";
23
23
  import { McpNcpToolRegistryAdapter } from "@nextclaw/ncp-mcp";
24
24
  import { NCP_INTERNAL_VISIBILITY_METADATA_KEY, NcpEventType, readAssistantReasoningNormalizationMode, readAssistantReasoningNormalizationModeFromMetadata, sanitizeAssistantReplyTags, writeAssistantReasoningNormalizationModeToMetadata } from "@nextclaw/ncp";
25
25
  import { DefaultNcpAgentBackend, createAgentClientFromServer } from "@nextclaw/ncp-toolkit";
@@ -6204,6 +6204,41 @@ function decodeMarketplaceFileContent(path, contentBase64) {
6204
6204
  return Buffer.from(normalized, "base64");
6205
6205
  }
6206
6206
  //#endregion
6207
+ //#region src/cli/update/self-update-report.utils.ts
6208
+ function reportSelfUpdateResult(params) {
6209
+ const { appName, currentVersion, result, readInstalledVersion } = params;
6210
+ const printSteps = () => {
6211
+ for (const step of result.steps) {
6212
+ console.log(`- ${step.cmd} ${step.args.join(" ")} (code ${step.code ?? "?"})`);
6213
+ if (step.stderr) console.log(` stderr: ${step.stderr}`);
6214
+ if (step.stdout) console.log(` stdout: ${step.stdout}`);
6215
+ }
6216
+ };
6217
+ if (!result.ok) {
6218
+ console.error(`Update failed: ${result.error ?? "unknown error"}`);
6219
+ if (result.steps.length > 0) printSteps();
6220
+ return {
6221
+ ok: false,
6222
+ shouldSuggestRestart: false
6223
+ };
6224
+ }
6225
+ if (result.strategy === "noop") {
6226
+ console.log(`✓ ${appName} is already up to date (${result.latestVersion ?? currentVersion})`);
6227
+ return {
6228
+ ok: true,
6229
+ shouldSuggestRestart: false
6230
+ };
6231
+ }
6232
+ const versionAfter = result.latestVersion ?? readInstalledVersion();
6233
+ console.log(`✓ Update complete (${result.strategy})`);
6234
+ if (versionAfter === currentVersion) console.log(`Version unchanged: ${currentVersion}`);
6235
+ else console.log(`Version updated: ${currentVersion} -> ${versionAfter}`);
6236
+ return {
6237
+ ok: true,
6238
+ shouldSuggestRestart: true
6239
+ };
6240
+ }
6241
+ //#endregion
6207
6242
  //#region src/cli/update/runner.ts
6208
6243
  const DEFAULT_TIMEOUT_MS = 20 * 6e4;
6209
6244
  function runSelfUpdate(options = {}) {
@@ -6211,6 +6246,7 @@ function runSelfUpdate(options = {}) {
6211
6246
  const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
6212
6247
  const updateCommand = options.updateCommand ?? process.env.NEXTCLAW_UPDATE_COMMAND?.trim();
6213
6248
  const packageName = options.packageName ?? "nextclaw";
6249
+ const currentVersion = options.currentVersion?.trim() || null;
6214
6250
  const resolveShellCommand = (command) => {
6215
6251
  if (process.platform === "win32") return {
6216
6252
  cmd: process.env.ComSpec || "cmd.exe",
@@ -6234,19 +6270,33 @@ function runSelfUpdate(options = {}) {
6234
6270
  timeout: timeoutMs,
6235
6271
  stdio: "pipe"
6236
6272
  });
6273
+ const stdout = (result.stdout ?? "").toString().slice(0, 4e3);
6274
+ const stderr = (result.stderr ?? "").toString().slice(0, 4e3);
6237
6275
  steps.push({
6238
6276
  cmd,
6239
6277
  args,
6240
6278
  cwd,
6241
6279
  code: result.status,
6242
- stdout: (result.stdout ?? "").toString().slice(0, 4e3),
6243
- stderr: (result.stderr ?? "").toString().slice(0, 4e3)
6280
+ stdout,
6281
+ stderr
6244
6282
  });
6245
6283
  return {
6246
6284
  ok: result.status === 0,
6247
- code: result.status
6285
+ code: result.status,
6286
+ stdout,
6287
+ stderr
6248
6288
  };
6249
6289
  };
6290
+ const parseLatestVersion = (raw) => {
6291
+ const trimmed = raw.trim();
6292
+ if (!trimmed) return null;
6293
+ try {
6294
+ const parsed = JSON.parse(trimmed);
6295
+ return typeof parsed === "string" && parsed.trim() ? parsed.trim() : null;
6296
+ } catch {
6297
+ return trimmed;
6298
+ }
6299
+ };
6250
6300
  if (updateCommand) {
6251
6301
  const cwd = options.cwd ? resolve(options.cwd) : process.cwd();
6252
6302
  const shellCommand = resolveShellCommand(updateCommand);
@@ -6264,19 +6314,35 @@ function runSelfUpdate(options = {}) {
6264
6314
  }
6265
6315
  const npmExecutable = findExecutableOnPath("npm");
6266
6316
  if (npmExecutable) {
6317
+ const cwd = options.cwd ? resolve(options.cwd) : process.cwd();
6318
+ const latestVersionStep = runStep(npmExecutable, [
6319
+ "view",
6320
+ packageName,
6321
+ "version",
6322
+ "--json"
6323
+ ], cwd);
6324
+ const latestVersion = latestVersionStep.ok ? parseLatestVersion(latestVersionStep.stdout) : null;
6325
+ if (latestVersion && currentVersion && latestVersion === currentVersion) return {
6326
+ ok: true,
6327
+ strategy: "noop",
6328
+ latestVersion,
6329
+ steps
6330
+ };
6267
6331
  if (!runStep(npmExecutable, [
6268
6332
  "i",
6269
6333
  "-g",
6270
6334
  packageName
6271
- ], process.cwd()).ok) return {
6335
+ ], cwd).ok) return {
6272
6336
  ok: false,
6273
6337
  error: `npm install -g ${packageName} failed`,
6274
6338
  strategy: "npm",
6339
+ latestVersion: latestVersion ?? void 0,
6275
6340
  steps
6276
6341
  };
6277
6342
  return {
6278
6343
  ok: true,
6279
6344
  strategy: "npm",
6345
+ latestVersion: latestVersion ?? void 0,
6280
6346
  steps
6281
6347
  };
6282
6348
  }
@@ -10343,48 +10409,39 @@ var AssetPutTool = class {
10343
10409
  description = "Put a normal file path or base64 bytes into the managed asset store.";
10344
10410
  parameters = {
10345
10411
  type: "object",
10346
- oneOf: [{
10347
- type: "object",
10348
- properties: {
10349
- path: {
10350
- type: "string",
10351
- description: "Existing local file path to put into the asset store."
10352
- },
10353
- fileName: {
10354
- type: "string",
10355
- description: "Optional asset file name override."
10356
- },
10357
- mimeType: {
10358
- type: "string",
10359
- description: "Optional mime type override."
10360
- }
10412
+ properties: {
10413
+ path: {
10414
+ type: "string",
10415
+ description: "Existing local file path to put into the asset store."
10361
10416
  },
10362
- required: ["path"],
10363
- additionalProperties: false
10364
- }, {
10365
- type: "object",
10366
- properties: {
10367
- bytesBase64: {
10368
- type: "string",
10369
- description: "Base64 file bytes. Use together with fileName when no source path exists."
10370
- },
10371
- fileName: {
10372
- type: "string",
10373
- description: "Asset file name. Required when using bytesBase64."
10374
- },
10375
- mimeType: {
10376
- type: "string",
10377
- description: "Optional mime type override."
10378
- }
10417
+ bytesBase64: {
10418
+ type: "string",
10419
+ description: "Base64 file bytes. Use together with fileName when no source path exists."
10379
10420
  },
10380
- required: ["bytesBase64", "fileName"],
10381
- additionalProperties: false
10382
- }]
10421
+ fileName: {
10422
+ type: "string",
10423
+ description: "Optional asset file name override. Required when using bytesBase64."
10424
+ },
10425
+ mimeType: {
10426
+ type: "string",
10427
+ description: "Optional mime type override."
10428
+ }
10429
+ },
10430
+ additionalProperties: false
10383
10431
  };
10384
10432
  constructor(assetStore, contentBasePath) {
10385
10433
  this.assetStore = assetStore;
10386
10434
  this.contentBasePath = contentBasePath;
10387
10435
  }
10436
+ validateArgs = (args) => {
10437
+ const path = readOptionalString$5(args.path);
10438
+ const bytesBase64 = readOptionalString$5(args.bytesBase64);
10439
+ const fileName = readOptionalString$5(args.fileName);
10440
+ if (path && bytesBase64) return ["Provide either path, or bytesBase64 + fileName, not both."];
10441
+ if (path) return [];
10442
+ if (bytesBase64) return fileName ? [] : ["fileName is required when using bytesBase64."];
10443
+ return ["Provide either path, or bytesBase64 + fileName."];
10444
+ };
10388
10445
  execute = async (args) => {
10389
10446
  const path = readOptionalString$5(args?.path);
10390
10447
  const fileName = readOptionalString$5(args?.fileName);
@@ -10475,11 +10532,12 @@ var AssetStatTool = class {
10475
10532
  };
10476
10533
  };
10477
10534
  function createAssetTools(params) {
10535
+ const { assetStore } = params;
10478
10536
  const contentBasePath = params.contentBasePath ?? "/api/ncp/assets/content";
10479
10537
  return [
10480
- new AssetPutTool(params.assetStore, contentBasePath),
10481
- new AssetExportTool(params.assetStore),
10482
- new AssetStatTool(params.assetStore, contentBasePath)
10538
+ new AssetPutTool(assetStore, contentBasePath),
10539
+ new AssetExportTool(assetStore),
10540
+ new AssetStatTool(assetStore, contentBasePath)
10483
10541
  ];
10484
10542
  }
10485
10543
  //#endregion
@@ -11181,19 +11239,20 @@ function readRequestedAgentId(metadata) {
11181
11239
  return normalizeString(metadata.agent_id)?.toLowerCase() ?? normalizeString(metadata.agentId)?.toLowerCase() ?? null;
11182
11240
  }
11183
11241
  function resolveAgentProfile(params) {
11184
- const defaultAgentId = resolveDefaultAgentProfileId(params.config);
11185
- const candidateAgentId = normalizeString(params.storedAgentId)?.toLowerCase() ?? readRequestedAgentId(params.requestMetadata) ?? defaultAgentId;
11186
- const profile = findEffectiveAgentProfile(params.config, candidateAgentId) ?? findEffectiveAgentProfile(params.config, defaultAgentId);
11242
+ const { config, requestMetadata, storedAgentId } = params;
11243
+ const { agents: { defaults }, search: searchConfig, tools: { restrictToWorkspace, exec: { timeout: execTimeoutSeconds } } } = config;
11244
+ const defaultAgentId = resolveDefaultAgentProfileId(config);
11245
+ const profile = findEffectiveAgentProfile(config, normalizeString(storedAgentId)?.toLowerCase() ?? readRequestedAgentId(requestMetadata) ?? defaultAgentId) ?? findEffectiveAgentProfile(config, defaultAgentId);
11187
11246
  if (!profile) throw new Error(`default agent profile not found: ${defaultAgentId}`);
11188
11247
  return {
11189
11248
  agentId: profile.id,
11190
- workspace: getWorkspacePath(profile.workspace ?? params.config.agents.defaults.workspace),
11191
- model: profile.model ?? params.config.agents.defaults.model,
11192
- maxIterations: profile.maxToolIterations ?? params.config.agents.defaults.maxToolIterations,
11193
- contextTokens: profile.contextTokens ?? params.config.agents.defaults.contextTokens,
11194
- restrictToWorkspace: params.config.tools.restrictToWorkspace,
11195
- searchConfig: params.config.search,
11196
- execTimeoutSeconds: params.config.tools.exec.timeout
11249
+ workspace: getWorkspacePath(profile.workspace ?? defaults.workspace),
11250
+ model: profile.model ?? defaults.model,
11251
+ maxIterations: profile.maxToolIterations ?? defaults.maxToolIterations,
11252
+ contextTokens: profile.contextTokens ?? defaults.contextTokens,
11253
+ restrictToWorkspace,
11254
+ searchConfig,
11255
+ execTimeoutSeconds
11197
11256
  };
11198
11257
  }
11199
11258
  function shouldAppendTimeHint(content) {
@@ -11241,14 +11300,7 @@ function filterTools(toolDefinitions, requestedToolNames) {
11241
11300
  return filtered.length > 0 ? filtered : void 0;
11242
11301
  }
11243
11302
  function buildRequestedOpenAiTools(toolDefinitions, requestedToolNames) {
11244
- return filterTools(toolDefinitions.map((tool) => ({
11245
- type: "function",
11246
- function: {
11247
- name: tool.name,
11248
- description: tool.description,
11249
- parameters: tool.parameters
11250
- }
11251
- })), requestedToolNames);
11303
+ return filterTools(toolDefinitions.map(buildOpenAiFunctionTool), requestedToolNames);
11252
11304
  }
11253
11305
  var NextclawNcpContextBuilder = class {
11254
11306
  inputBudgetPruner = new InputBudgetPruner();
@@ -15842,28 +15894,19 @@ var CliRuntime = class {
15842
15894
  }
15843
15895
  const versionBefore = getPackageVersion$1();
15844
15896
  console.log(`Current version: ${versionBefore}`);
15845
- const result = runSelfUpdate({
15846
- timeoutMs,
15847
- cwd: process.cwd()
15897
+ const report = reportSelfUpdateResult({
15898
+ appName: APP_NAME,
15899
+ currentVersion: versionBefore,
15900
+ result: runSelfUpdate({
15901
+ timeoutMs,
15902
+ cwd: process.cwd(),
15903
+ currentVersion: versionBefore
15904
+ }),
15905
+ readInstalledVersion: getPackageVersion$1
15848
15906
  });
15849
- const printSteps = () => {
15850
- for (const step of result.steps) {
15851
- console.log(`- ${step.cmd} ${step.args.join(" ")} (code ${step.code ?? "?"})`);
15852
- if (step.stderr) console.log(` stderr: ${step.stderr}`);
15853
- if (step.stdout) console.log(` stdout: ${step.stdout}`);
15854
- }
15855
- };
15856
- if (!result.ok) {
15857
- console.error(`Update failed: ${result.error ?? "unknown error"}`);
15858
- if (result.steps.length > 0) printSteps();
15859
- process.exit(1);
15860
- }
15861
- const versionAfter = getPackageVersion$1();
15862
- console.log(`✓ Update complete (${result.strategy})`);
15863
- if (versionAfter === versionBefore) console.log(`Version unchanged: ${versionBefore}`);
15864
- else console.log(`Version updated: ${versionBefore} -> ${versionAfter}`);
15907
+ if (!report.ok) process.exit(1);
15865
15908
  const state = managedServiceStateStore.read();
15866
- if (state && isProcessRunning(state.pid)) console.log(`Tip: restart ${APP_NAME} to apply the update.`);
15909
+ if (report.shouldSuggestRestart && state && isProcessRunning(state.pid)) console.log(`Tip: restart ${APP_NAME} to apply the update.`);
15867
15910
  };
15868
15911
  agentsList = (opts = {}) => {
15869
15912
  this.agentCommands.agentsList(opts);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.17.8",
3
+ "version": "0.17.10",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -40,16 +40,16 @@
40
40
  "chokidar": "^3.6.0",
41
41
  "commander": "^12.1.0",
42
42
  "yaml": "^2.8.1",
43
- "@nextclaw/ncp-mcp": "0.1.71",
43
+ "@nextclaw/core": "0.12.5",
44
+ "@nextclaw/ncp-agent-runtime": "0.3.10",
44
45
  "@nextclaw/ncp": "0.5.0",
45
- "@nextclaw/ncp-toolkit": "0.5.4",
46
- "@nextclaw/openclaw-compat": "1.0.4",
47
- "@nextclaw/ncp-agent-runtime": "0.3.9",
48
- "@nextclaw/remote": "0.1.81",
49
- "@nextclaw/server": "0.12.4",
50
- "@nextclaw/mcp": "0.1.69",
51
- "@nextclaw/core": "0.12.4",
52
- "@nextclaw/runtime": "0.2.36"
46
+ "@nextclaw/openclaw-compat": "1.0.5",
47
+ "@nextclaw/mcp": "0.1.70",
48
+ "@nextclaw/ncp-toolkit": "0.5.5",
49
+ "@nextclaw/ncp-mcp": "0.1.72",
50
+ "@nextclaw/server": "0.12.5",
51
+ "@nextclaw/remote": "0.1.82",
52
+ "@nextclaw/runtime": "0.2.37"
53
53
  },
54
54
  "devDependencies": {
55
55
  "@types/node": "^20.17.6",
@@ -57,7 +57,7 @@
57
57
  "tsx": "^4.19.2",
58
58
  "typescript": "^5.6.3",
59
59
  "vitest": "^4.1.2",
60
- "@nextclaw/ui": "0.12.6"
60
+ "@nextclaw/ui": "0.12.7"
61
61
  },
62
62
  "scripts": {
63
63
  "dev": "tsx watch --tsconfig tsconfig.json src/cli/index.ts",