@nextclaw/server 0.12.3 → 0.12.4
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/index.js +61 -44
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -2,9 +2,9 @@ import { Hono } from "hono";
|
|
|
2
2
|
import { compress } from "hono/compress";
|
|
3
3
|
import { serve } from "@hono/node-server";
|
|
4
4
|
import { WebSocket, WebSocketServer } from "ws";
|
|
5
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
|
+
import fs, { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { readFile, readdir, realpath, stat } from "node:fs/promises";
|
|
7
|
-
import { dirname, isAbsolute, join, parse, resolve } from "node:path";
|
|
7
|
+
import path, { dirname, isAbsolute, join, parse, resolve } from "node:path";
|
|
8
8
|
import * as NextclawCore from "@nextclaw/core";
|
|
9
9
|
import { ConfigSchema, DEFAULT_WORKSPACE_PATH, LiteLLMProvider, SessionManager, buildConfigSchema, createAgentProfile, expandHome, findEffectiveAgentProfile, getDataDir, getPackageVersion, getProviderName, getWorkspacePathFromConfig, hasSecretRef, isSensitiveConfigPath, loadConfig, normalizeThinkingLevels, parseThinkingLevel, probeFeishu, readAgentAvatarContent, removeAgentProfile, resolveEffectiveAgentProfiles, saveConfig, updateAgentProfile } from "@nextclaw/core";
|
|
10
10
|
import { createHash, randomBytes, randomUUID, scryptSync, timingSafeEqual } from "node:crypto";
|
|
@@ -1077,6 +1077,7 @@ const PREFERRED_PROVIDER_ORDER_INDEX = new Map([
|
|
|
1077
1077
|
"deepseek",
|
|
1078
1078
|
"minimax",
|
|
1079
1079
|
"moonshot",
|
|
1080
|
+
"kimi-coding",
|
|
1080
1081
|
"zhipu"
|
|
1081
1082
|
].map((name, index) => [name, index]));
|
|
1082
1083
|
const BUILTIN_PROVIDERS = listServerBuiltinProviders();
|
|
@@ -3491,6 +3492,21 @@ var McpMarketplaceController = class {
|
|
|
3491
3492
|
};
|
|
3492
3493
|
//#endregion
|
|
3493
3494
|
//#region src/ui/ui-routes/marketplace/spec.ts
|
|
3495
|
+
function readPluginPackageNameFromSource(source) {
|
|
3496
|
+
const trimmed = source?.trim();
|
|
3497
|
+
if (!trimmed) return;
|
|
3498
|
+
let cursor = path.dirname(path.resolve(trimmed));
|
|
3499
|
+
for (let index = 0; index < 8; index += 1) {
|
|
3500
|
+
try {
|
|
3501
|
+
const manifestPath = path.join(cursor, "package.json");
|
|
3502
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
3503
|
+
if (typeof manifest.name === "string" && manifest.name.trim().length > 0) return manifest.name.trim();
|
|
3504
|
+
} catch {}
|
|
3505
|
+
const parent = path.dirname(cursor);
|
|
3506
|
+
if (parent === cursor) break;
|
|
3507
|
+
cursor = parent;
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3494
3510
|
function normalizePluginNpmSpec(rawSpec) {
|
|
3495
3511
|
const spec = rawSpec.trim();
|
|
3496
3512
|
if (!spec.startsWith("@")) return spec;
|
|
@@ -3512,6 +3528,12 @@ function resolvePluginCanonicalSpec(params) {
|
|
|
3512
3528
|
}
|
|
3513
3529
|
return params.pluginId;
|
|
3514
3530
|
}
|
|
3531
|
+
function resolveDiscoveredPluginCanonicalSpec(params) {
|
|
3532
|
+
return resolvePluginCanonicalSpec({
|
|
3533
|
+
pluginId: params.pluginId,
|
|
3534
|
+
installSpec: params.installSpec ?? readPluginPackageNameFromSource(params.source)
|
|
3535
|
+
});
|
|
3536
|
+
}
|
|
3515
3537
|
function readPluginRuntimeStatusPriority(status) {
|
|
3516
3538
|
if (status === "loaded") return 400;
|
|
3517
3539
|
if (status === "disabled") return 300;
|
|
@@ -3606,36 +3628,32 @@ function buildDiscoveredPluginMap(params) {
|
|
|
3606
3628
|
}
|
|
3607
3629
|
return discoveredById;
|
|
3608
3630
|
}
|
|
3609
|
-
function
|
|
3610
|
-
|
|
3631
|
+
function collectDiscoveredPluginRecords(params) {
|
|
3632
|
+
return Array.from(params.discoveredById.values()).map((plugin) => {
|
|
3611
3633
|
const installRecord = params.pluginRecordsMap[plugin.id];
|
|
3612
3634
|
const entry = params.pluginEntries[plugin.id];
|
|
3613
|
-
|
|
3614
|
-
pluginId: plugin.id,
|
|
3615
|
-
installSpec: installRecord?.spec
|
|
3616
|
-
});
|
|
3617
|
-
const enabled = entry?.enabled === false ? false : plugin.enabled;
|
|
3618
|
-
const runtimeStatus = entry?.enabled === false ? "disabled" : plugin.status;
|
|
3619
|
-
params.pluginRecords.push({
|
|
3635
|
+
return {
|
|
3620
3636
|
type: "plugin",
|
|
3621
3637
|
id: plugin.id,
|
|
3622
|
-
spec:
|
|
3638
|
+
spec: resolveDiscoveredPluginCanonicalSpec({
|
|
3639
|
+
pluginId: plugin.id,
|
|
3640
|
+
installSpec: installRecord?.spec,
|
|
3641
|
+
source: plugin.source
|
|
3642
|
+
}),
|
|
3623
3643
|
label: plugin.name && plugin.name.trim().length > 0 ? plugin.name : plugin.id,
|
|
3624
3644
|
source: plugin.source,
|
|
3625
3645
|
installedAt: installRecord?.installedAt,
|
|
3626
|
-
enabled,
|
|
3627
|
-
runtimeStatus,
|
|
3646
|
+
enabled: entry?.enabled === false ? false : plugin.enabled,
|
|
3647
|
+
runtimeStatus: entry?.enabled === false ? "disabled" : plugin.status,
|
|
3628
3648
|
origin: plugin.origin,
|
|
3629
3649
|
installPath: installRecord?.installPath
|
|
3630
|
-
}
|
|
3631
|
-
|
|
3632
|
-
}
|
|
3650
|
+
};
|
|
3651
|
+
});
|
|
3633
3652
|
}
|
|
3634
|
-
function
|
|
3635
|
-
|
|
3636
|
-
if (params.seenPluginIds.has(pluginId)) continue;
|
|
3653
|
+
function collectInstalledOnlyPluginRecords(params) {
|
|
3654
|
+
return Object.entries(params.pluginRecordsMap).filter(([pluginId]) => !params.seenPluginIds.has(pluginId)).map(([pluginId, installRecord]) => {
|
|
3637
3655
|
const entry = params.pluginEntries[pluginId];
|
|
3638
|
-
|
|
3656
|
+
return {
|
|
3639
3657
|
type: "plugin",
|
|
3640
3658
|
id: pluginId,
|
|
3641
3659
|
spec: resolvePluginCanonicalSpec({
|
|
@@ -3648,14 +3666,12 @@ function appendInstalledOnlyPluginRecords(params) {
|
|
|
3648
3666
|
enabled: entry?.enabled !== false,
|
|
3649
3667
|
runtimeStatus: entry?.enabled === false ? "disabled" : "unresolved",
|
|
3650
3668
|
installPath: installRecord.installPath
|
|
3651
|
-
}
|
|
3652
|
-
|
|
3653
|
-
}
|
|
3669
|
+
};
|
|
3670
|
+
});
|
|
3654
3671
|
}
|
|
3655
|
-
function
|
|
3656
|
-
|
|
3657
|
-
|
|
3658
|
-
params.pluginRecords.push({
|
|
3672
|
+
function collectConfigOnlyPluginRecords(params) {
|
|
3673
|
+
return Object.entries(params.pluginEntries).filter(([pluginId]) => !params.seenPluginIds.has(pluginId)).map(([pluginId, entry]) => {
|
|
3674
|
+
return {
|
|
3659
3675
|
type: "plugin",
|
|
3660
3676
|
id: pluginId,
|
|
3661
3677
|
spec: resolvePluginCanonicalSpec({ pluginId }),
|
|
@@ -3663,9 +3679,8 @@ function appendConfigOnlyPluginRecords(params) {
|
|
|
3663
3679
|
source: "config",
|
|
3664
3680
|
enabled: entry?.enabled !== false,
|
|
3665
3681
|
runtimeStatus: entry?.enabled === false ? "disabled" : "unresolved"
|
|
3666
|
-
}
|
|
3667
|
-
|
|
3668
|
-
}
|
|
3682
|
+
};
|
|
3683
|
+
});
|
|
3669
3684
|
}
|
|
3670
3685
|
function findPluginIdByExactId(pluginRecords, lowerTargetId) {
|
|
3671
3686
|
for (const record of pluginRecords) {
|
|
@@ -3681,12 +3696,13 @@ function findPluginIdByNormalizedSpec(pluginRecords, normalizedSpec) {
|
|
|
3681
3696
|
if (normalizePluginNpmSpec(record.spec).toLowerCase() === normalizedSpec) return recordId;
|
|
3682
3697
|
}
|
|
3683
3698
|
}
|
|
3699
|
+
function collectDefinedRecordIds(records) {
|
|
3700
|
+
return new Set(records.map((record) => readNonEmptyString(record.id)).filter((recordId) => Boolean(recordId)));
|
|
3701
|
+
}
|
|
3684
3702
|
function collectInstalledPluginRecords(options) {
|
|
3685
3703
|
const config = loadConfigOrDefault(options.configPath);
|
|
3686
3704
|
const pluginRecordsMap = config.plugins.installs ?? {};
|
|
3687
3705
|
const pluginEntries = config.plugins.entries ?? {};
|
|
3688
|
-
const pluginRecords = [];
|
|
3689
|
-
const seenPluginIds = /* @__PURE__ */ new Set();
|
|
3690
3706
|
const installedPluginIds = new Set(Object.keys(pluginRecordsMap));
|
|
3691
3707
|
let discoveredPlugins = [];
|
|
3692
3708
|
try {
|
|
@@ -3697,28 +3713,29 @@ function collectInstalledPluginRecords(options) {
|
|
|
3697
3713
|
} catch {
|
|
3698
3714
|
discoveredPlugins = [];
|
|
3699
3715
|
}
|
|
3700
|
-
|
|
3716
|
+
const discoveredRecords = collectDiscoveredPluginRecords({
|
|
3701
3717
|
discoveredById: buildDiscoveredPluginMap({
|
|
3702
3718
|
discoveredPlugins,
|
|
3703
3719
|
installedPluginIds
|
|
3704
3720
|
}),
|
|
3705
3721
|
pluginRecordsMap,
|
|
3706
|
-
pluginEntries
|
|
3707
|
-
pluginRecords,
|
|
3708
|
-
seenPluginIds
|
|
3722
|
+
pluginEntries
|
|
3709
3723
|
});
|
|
3710
|
-
|
|
3724
|
+
const seenDiscoveredPluginIds = collectDefinedRecordIds(discoveredRecords);
|
|
3725
|
+
const installedOnlyRecords = collectInstalledOnlyPluginRecords({
|
|
3711
3726
|
pluginRecordsMap,
|
|
3712
3727
|
pluginEntries,
|
|
3713
|
-
|
|
3714
|
-
seenPluginIds
|
|
3728
|
+
seenPluginIds: seenDiscoveredPluginIds
|
|
3715
3729
|
});
|
|
3716
|
-
|
|
3730
|
+
const configOnlyRecords = collectConfigOnlyPluginRecords({
|
|
3717
3731
|
pluginEntries,
|
|
3718
|
-
|
|
3719
|
-
seenPluginIds
|
|
3732
|
+
seenPluginIds: new Set([...seenDiscoveredPluginIds, ...collectDefinedRecordIds(installedOnlyRecords)])
|
|
3720
3733
|
});
|
|
3721
|
-
const dedupedPluginRecords = dedupeInstalledPluginRecordsByCanonicalSpec(
|
|
3734
|
+
const dedupedPluginRecords = dedupeInstalledPluginRecordsByCanonicalSpec([
|
|
3735
|
+
...discoveredRecords,
|
|
3736
|
+
...installedOnlyRecords,
|
|
3737
|
+
...configOnlyRecords
|
|
3738
|
+
]);
|
|
3722
3739
|
dedupedPluginRecords.sort((left, right) => {
|
|
3723
3740
|
return left.spec.localeCompare(right.spec);
|
|
3724
3741
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nextclaw/server",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Nextclaw UI/API server.",
|
|
6
6
|
"type": "module",
|
|
@@ -18,12 +18,12 @@
|
|
|
18
18
|
"@hono/node-server": "^1.13.3",
|
|
19
19
|
"hono": "^4.6.2",
|
|
20
20
|
"ws": "^8.18.0",
|
|
21
|
-
"@nextclaw/core": "0.12.
|
|
22
|
-
"@nextclaw/mcp": "0.1.
|
|
23
|
-
"@nextclaw/ncp-http-agent-server": "0.3.12",
|
|
24
|
-
"@nextclaw/openclaw-compat": "1.0.3",
|
|
21
|
+
"@nextclaw/core": "0.12.4",
|
|
22
|
+
"@nextclaw/mcp": "0.1.69",
|
|
25
23
|
"@nextclaw/ncp": "0.5.0",
|
|
26
|
-
"@nextclaw/
|
|
24
|
+
"@nextclaw/ncp-http-agent-server": "0.3.12",
|
|
25
|
+
"@nextclaw/openclaw-compat": "1.0.4",
|
|
26
|
+
"@nextclaw/runtime": "0.2.36"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^20.17.6",
|