nextclaw 0.9.22 → 0.9.23
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.
- package/dist/cli/index.js +67 -3
- package/package.json +5 -5
package/dist/cli/index.js
CHANGED
|
@@ -235,7 +235,8 @@ async function installMarketplaceSkill(options) {
|
|
|
235
235
|
throw new Error(`Invalid marketplace file path: ${file.path}`);
|
|
236
236
|
}
|
|
237
237
|
mkdirSync2(dirname(targetPath), { recursive: true });
|
|
238
|
-
|
|
238
|
+
const bytes = await fetchMarketplaceSkillFileBlob(apiBase, slug, file);
|
|
239
|
+
writeFileSync2(targetPath, bytes);
|
|
239
240
|
}
|
|
240
241
|
if (!existsSync2(join(destinationDir, "SKILL.md"))) {
|
|
241
242
|
throw new Error(`Marketplace skill ${slug} does not include SKILL.md`);
|
|
@@ -362,7 +363,59 @@ async function fetchMarketplaceSkillFiles(apiBase, slug) {
|
|
|
362
363
|
const message = payload.error?.message || `marketplace skill file fetch failed: ${response.status}`;
|
|
363
364
|
throw new Error(message);
|
|
364
365
|
}
|
|
365
|
-
|
|
366
|
+
if (!isRecord(payload.data) || !Array.isArray(payload.data.files)) {
|
|
367
|
+
throw new Error("Invalid marketplace skill file manifest response");
|
|
368
|
+
}
|
|
369
|
+
const files = payload.data.files.map((entry, index) => {
|
|
370
|
+
if (!isRecord(entry) || typeof entry.path !== "string" || entry.path.trim().length === 0) {
|
|
371
|
+
throw new Error(`Invalid marketplace skill file manifest at index ${index}`);
|
|
372
|
+
}
|
|
373
|
+
const normalized = {
|
|
374
|
+
path: entry.path.trim()
|
|
375
|
+
};
|
|
376
|
+
if (typeof entry.downloadPath === "string" && entry.downloadPath.trim().length > 0) {
|
|
377
|
+
normalized.downloadPath = entry.downloadPath.trim();
|
|
378
|
+
}
|
|
379
|
+
return normalized;
|
|
380
|
+
});
|
|
381
|
+
return { files };
|
|
382
|
+
}
|
|
383
|
+
async function fetchMarketplaceSkillFileBlob(apiBase, slug, file) {
|
|
384
|
+
const downloadUrl = resolveSkillFileDownloadUrl(apiBase, slug, file);
|
|
385
|
+
const response = await fetch(downloadUrl, {
|
|
386
|
+
headers: {
|
|
387
|
+
Accept: "application/octet-stream"
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
if (!response.ok) {
|
|
391
|
+
const message = await tryReadMarketplaceError(response);
|
|
392
|
+
throw new Error(message || `marketplace skill file download failed: ${response.status}`);
|
|
393
|
+
}
|
|
394
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
395
|
+
return Buffer.from(arrayBuffer);
|
|
396
|
+
}
|
|
397
|
+
function resolveSkillFileDownloadUrl(apiBase, slug, file) {
|
|
398
|
+
const fallback = `${apiBase}/api/v1/skills/items/${encodeURIComponent(slug)}/files/blob?path=${encodeURIComponent(file.path)}`;
|
|
399
|
+
if (!file.downloadPath) {
|
|
400
|
+
return fallback;
|
|
401
|
+
}
|
|
402
|
+
if (file.downloadPath.startsWith("http://") || file.downloadPath.startsWith("https://")) {
|
|
403
|
+
return file.downloadPath;
|
|
404
|
+
}
|
|
405
|
+
const normalizedPath = file.downloadPath.startsWith("/") ? file.downloadPath : `/${file.downloadPath}`;
|
|
406
|
+
return `${apiBase}${normalizedPath}`;
|
|
407
|
+
}
|
|
408
|
+
async function tryReadMarketplaceError(response) {
|
|
409
|
+
const raw = await response.text();
|
|
410
|
+
if (!raw.trim()) {
|
|
411
|
+
return void 0;
|
|
412
|
+
}
|
|
413
|
+
try {
|
|
414
|
+
const payload = JSON.parse(raw);
|
|
415
|
+
return payload.error?.message;
|
|
416
|
+
} catch {
|
|
417
|
+
return void 0;
|
|
418
|
+
}
|
|
366
419
|
}
|
|
367
420
|
async function readMarketplaceEnvelope(response) {
|
|
368
421
|
const raw = await response.text();
|
|
@@ -3149,7 +3202,7 @@ var GatewayAgentRuntimePool = class {
|
|
|
3149
3202
|
await this.options.bus.publishOutbound({
|
|
3150
3203
|
channel: message.channel,
|
|
3151
3204
|
chatId: message.chatId,
|
|
3152
|
-
content: `Sorry, I encountered an error: ${
|
|
3205
|
+
content: `Sorry, I encountered an error: ${formatUserFacingError(error)}`,
|
|
3153
3206
|
media: [],
|
|
3154
3207
|
metadata: {}
|
|
3155
3208
|
});
|
|
@@ -3385,6 +3438,17 @@ function parseCommandOptionValue(type, rawValue) {
|
|
|
3385
3438
|
}
|
|
3386
3439
|
return value;
|
|
3387
3440
|
}
|
|
3441
|
+
function formatUserFacingError(error, maxChars = 320) {
|
|
3442
|
+
const raw = error instanceof Error ? error.message || error.name || "Unknown error" : String(error ?? "Unknown error");
|
|
3443
|
+
const normalized = raw.replace(/\s+/g, " ").trim();
|
|
3444
|
+
if (!normalized) {
|
|
3445
|
+
return "Unknown error";
|
|
3446
|
+
}
|
|
3447
|
+
if (normalized.length <= maxChars) {
|
|
3448
|
+
return normalized;
|
|
3449
|
+
}
|
|
3450
|
+
return `${normalized.slice(0, Math.max(0, maxChars - 3)).trimEnd()}...`;
|
|
3451
|
+
}
|
|
3388
3452
|
|
|
3389
3453
|
// src/cli/commands/ui-chat-run-coordinator.ts
|
|
3390
3454
|
import { existsSync as existsSync7, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "fs";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.23",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -38,10 +38,10 @@
|
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
|
-
"@nextclaw/core": "0.7.
|
|
42
|
-
"@nextclaw/runtime": "0.1.
|
|
43
|
-
"@nextclaw/
|
|
44
|
-
"@nextclaw/
|
|
41
|
+
"@nextclaw/core": "0.7.6",
|
|
42
|
+
"@nextclaw/runtime": "0.1.5",
|
|
43
|
+
"@nextclaw/openclaw-compat": "0.2.5",
|
|
44
|
+
"@nextclaw/server": "0.6.10"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/node": "^20.17.6",
|