nextclaw 0.13.0 → 0.13.2
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 +235 -140
- package/package.json +7 -7
package/dist/cli/index.js
CHANGED
|
@@ -6,9 +6,9 @@ import { APP_NAME as APP_NAME5, APP_TAGLINE } from "@nextclaw/core";
|
|
|
6
6
|
|
|
7
7
|
// src/cli/runtime.ts
|
|
8
8
|
import {
|
|
9
|
-
loadConfig as
|
|
10
|
-
saveConfig as
|
|
11
|
-
getConfigPath as
|
|
9
|
+
loadConfig as loadConfig13,
|
|
10
|
+
saveConfig as saveConfig9,
|
|
11
|
+
getConfigPath as getConfigPath6,
|
|
12
12
|
getDataDir as getDataDir9,
|
|
13
13
|
ConfigSchema as ConfigSchema2,
|
|
14
14
|
getWorkspacePath as getWorkspacePath10,
|
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
} from "@nextclaw/openclaw-compat";
|
|
29
29
|
import { existsSync as existsSync13, mkdirSync as mkdirSync8, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
|
|
30
30
|
import { join as join9, resolve as resolve12 } from "path";
|
|
31
|
-
import { createInterface as
|
|
31
|
+
import { createInterface as createInterface3 } from "readline";
|
|
32
32
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
33
33
|
import { spawn as spawn3 } from "child_process";
|
|
34
34
|
|
|
@@ -1440,27 +1440,7 @@ async function installPluginMutation(pathOrSpec, opts = {}) {
|
|
|
1440
1440
|
};
|
|
1441
1441
|
}
|
|
1442
1442
|
|
|
1443
|
-
// src/cli/commands/
|
|
1444
|
-
function loadPluginRegistry(config2, workspaceDir) {
|
|
1445
|
-
const workspaceExtensionsDir = process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR;
|
|
1446
|
-
const configWithDevPluginPaths = applyDevFirstPartyPluginLoadPaths(
|
|
1447
|
-
config2,
|
|
1448
|
-
workspaceExtensionsDir
|
|
1449
|
-
);
|
|
1450
|
-
const excludedRoots = resolveDevFirstPartyPluginInstallRoots(config2, workspaceExtensionsDir);
|
|
1451
|
-
return loadOpenClawPlugins({
|
|
1452
|
-
config: configWithDevPluginPaths,
|
|
1453
|
-
workspaceDir,
|
|
1454
|
-
excludeRoots: excludedRoots,
|
|
1455
|
-
...buildReservedPluginLoadOptions(),
|
|
1456
|
-
logger: {
|
|
1457
|
-
info: (message) => console.log(message),
|
|
1458
|
-
warn: (message) => console.warn(message),
|
|
1459
|
-
error: (message) => console.error(message),
|
|
1460
|
-
debug: (message) => console.debug(message)
|
|
1461
|
-
}
|
|
1462
|
-
});
|
|
1463
|
-
}
|
|
1443
|
+
// src/cli/commands/plugin-extension-registry.ts
|
|
1464
1444
|
function toExtensionRegistry(pluginRegistry) {
|
|
1465
1445
|
return {
|
|
1466
1446
|
tools: pluginRegistry.tools.map((tool) => ({
|
|
@@ -1497,6 +1477,28 @@ function toExtensionRegistry(pluginRegistry) {
|
|
|
1497
1477
|
}))
|
|
1498
1478
|
};
|
|
1499
1479
|
}
|
|
1480
|
+
|
|
1481
|
+
// src/cli/commands/plugins.ts
|
|
1482
|
+
function loadPluginRegistry(config2, workspaceDir) {
|
|
1483
|
+
const workspaceExtensionsDir = process.env.NEXTCLAW_DEV_FIRST_PARTY_PLUGIN_DIR;
|
|
1484
|
+
const configWithDevPluginPaths = applyDevFirstPartyPluginLoadPaths(
|
|
1485
|
+
config2,
|
|
1486
|
+
workspaceExtensionsDir
|
|
1487
|
+
);
|
|
1488
|
+
const excludedRoots = resolveDevFirstPartyPluginInstallRoots(config2, workspaceExtensionsDir);
|
|
1489
|
+
return loadOpenClawPlugins({
|
|
1490
|
+
config: configWithDevPluginPaths,
|
|
1491
|
+
workspaceDir,
|
|
1492
|
+
excludeRoots: excludedRoots,
|
|
1493
|
+
...buildReservedPluginLoadOptions(),
|
|
1494
|
+
logger: {
|
|
1495
|
+
info: (message) => console.log(message),
|
|
1496
|
+
warn: (message) => console.warn(message),
|
|
1497
|
+
error: (message) => console.error(message),
|
|
1498
|
+
debug: (message) => console.debug(message)
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
}
|
|
1500
1502
|
function logPluginDiagnostics(registry) {
|
|
1501
1503
|
for (const diag of registry.diagnostics) {
|
|
1502
1504
|
const prefix = diag.pluginId ? `${diag.pluginId}: ` : "";
|
|
@@ -2859,8 +2861,162 @@ var CronCommands = class {
|
|
|
2859
2861
|
}
|
|
2860
2862
|
};
|
|
2861
2863
|
|
|
2864
|
+
// src/cli/commands/platform-auth.ts
|
|
2865
|
+
import { getConfigPath as getConfigPath2, loadConfig as loadConfig7, saveConfig as saveConfig6 } from "@nextclaw/core";
|
|
2866
|
+
import { createInterface as createInterface2 } from "readline";
|
|
2867
|
+
|
|
2868
|
+
// src/cli/commands/platform-api-base.ts
|
|
2869
|
+
var DEFAULT_PLATFORM_API_BASE = "https://ai-gateway-api.nextclaw.io/v1";
|
|
2870
|
+
var INVALID_PLATFORM_HINT = `Use ${DEFAULT_PLATFORM_API_BASE} or the platform root URL without a trailing path.`;
|
|
2871
|
+
function trimTrailingSlash(value) {
|
|
2872
|
+
return value.replace(/\/+$/, "");
|
|
2873
|
+
}
|
|
2874
|
+
function normalizeExplicitApiBase(rawApiBase) {
|
|
2875
|
+
const trimmed = trimTrailingSlash(rawApiBase.trim());
|
|
2876
|
+
if (!trimmed) {
|
|
2877
|
+
return "";
|
|
2878
|
+
}
|
|
2879
|
+
return trimmed.replace(/\/v1?$/i, "");
|
|
2880
|
+
}
|
|
2881
|
+
function resolvePlatformApiBase(params) {
|
|
2882
|
+
const explicitApiBase = typeof params.explicitApiBase === "string" ? params.explicitApiBase.trim() : "";
|
|
2883
|
+
const configuredApiBase = typeof params.configuredApiBase === "string" ? params.configuredApiBase.trim() : "";
|
|
2884
|
+
const fallbackApiBase = params.fallbackApiBase ?? DEFAULT_PLATFORM_API_BASE;
|
|
2885
|
+
const inputApiBase = explicitApiBase || configuredApiBase || (params.requireConfigured ? "" : fallbackApiBase);
|
|
2886
|
+
if (!inputApiBase) {
|
|
2887
|
+
throw new Error("Platform API base is missing. Pass --api-base or run nextclaw login.");
|
|
2888
|
+
}
|
|
2889
|
+
const platformBase = normalizeExplicitApiBase(inputApiBase);
|
|
2890
|
+
if (!platformBase) {
|
|
2891
|
+
throw new Error(`Invalid --api-base "${inputApiBase}". ${INVALID_PLATFORM_HINT}`);
|
|
2892
|
+
}
|
|
2893
|
+
let parsedUrl;
|
|
2894
|
+
try {
|
|
2895
|
+
parsedUrl = new URL(platformBase);
|
|
2896
|
+
} catch {
|
|
2897
|
+
throw new Error(`Invalid --api-base "${inputApiBase}". ${INVALID_PLATFORM_HINT}`);
|
|
2898
|
+
}
|
|
2899
|
+
if (parsedUrl.pathname !== "" && parsedUrl.pathname !== "/") {
|
|
2900
|
+
throw new Error(`Invalid --api-base "${inputApiBase}". ${INVALID_PLATFORM_HINT}`);
|
|
2901
|
+
}
|
|
2902
|
+
const normalizedPlatformBase = trimTrailingSlash(parsedUrl.toString());
|
|
2903
|
+
return {
|
|
2904
|
+
platformBase: normalizedPlatformBase,
|
|
2905
|
+
v1Base: `${normalizedPlatformBase}/v1`,
|
|
2906
|
+
inputApiBase
|
|
2907
|
+
};
|
|
2908
|
+
}
|
|
2909
|
+
function buildPlatformApiBaseErrorMessage(inputApiBase, rawMessage) {
|
|
2910
|
+
if (rawMessage.includes("Remote session cookie missing") || rawMessage.includes("endpoint not found") || rawMessage.includes("NOT_FOUND")) {
|
|
2911
|
+
return `Invalid --api-base "${inputApiBase}". ${INVALID_PLATFORM_HINT}`;
|
|
2912
|
+
}
|
|
2913
|
+
return rawMessage;
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2916
|
+
// src/cli/commands/platform-auth.ts
|
|
2917
|
+
function resolveProviderConfig(opts) {
|
|
2918
|
+
const configPath = getConfigPath2();
|
|
2919
|
+
const config2 = loadConfig7(configPath);
|
|
2920
|
+
const providers = config2.providers;
|
|
2921
|
+
const nextclawProvider = providers.nextclaw ?? {
|
|
2922
|
+
displayName: "",
|
|
2923
|
+
apiKey: "",
|
|
2924
|
+
apiBase: null,
|
|
2925
|
+
extraHeaders: null,
|
|
2926
|
+
wireApi: "auto",
|
|
2927
|
+
models: []
|
|
2928
|
+
};
|
|
2929
|
+
const configuredApiBase = typeof nextclawProvider.apiBase === "string" && nextclawProvider.apiBase.trim().length > 0 ? nextclawProvider.apiBase.trim() : "https://ai-gateway-api.nextclaw.io/v1";
|
|
2930
|
+
const requestedApiBase = typeof opts.apiBase === "string" && opts.apiBase.trim().length > 0 ? opts.apiBase.trim() : configuredApiBase;
|
|
2931
|
+
const { platformBase, v1Base, inputApiBase } = resolvePlatformApiBase({
|
|
2932
|
+
explicitApiBase: requestedApiBase,
|
|
2933
|
+
fallbackApiBase: "https://ai-gateway-api.nextclaw.io/v1"
|
|
2934
|
+
});
|
|
2935
|
+
return {
|
|
2936
|
+
configPath,
|
|
2937
|
+
config: config2,
|
|
2938
|
+
providers,
|
|
2939
|
+
nextclawProvider,
|
|
2940
|
+
platformBase,
|
|
2941
|
+
v1Base,
|
|
2942
|
+
inputApiBase
|
|
2943
|
+
};
|
|
2944
|
+
}
|
|
2945
|
+
async function resolveCredentials(opts) {
|
|
2946
|
+
let email = typeof opts.email === "string" ? opts.email.trim() : "";
|
|
2947
|
+
let password = typeof opts.password === "string" ? opts.password : "";
|
|
2948
|
+
if (email && password) {
|
|
2949
|
+
return { email, password };
|
|
2950
|
+
}
|
|
2951
|
+
const rl = createInterface2({
|
|
2952
|
+
input: process.stdin,
|
|
2953
|
+
output: process.stdout
|
|
2954
|
+
});
|
|
2955
|
+
try {
|
|
2956
|
+
if (!email) {
|
|
2957
|
+
email = (await prompt(rl, "Email: ")).trim();
|
|
2958
|
+
}
|
|
2959
|
+
if (!password) {
|
|
2960
|
+
password = await prompt(rl, "Password: ");
|
|
2961
|
+
}
|
|
2962
|
+
} finally {
|
|
2963
|
+
rl.close();
|
|
2964
|
+
}
|
|
2965
|
+
if (!email || !password) {
|
|
2966
|
+
throw new Error("Email and password are required.");
|
|
2967
|
+
}
|
|
2968
|
+
return { email, password };
|
|
2969
|
+
}
|
|
2970
|
+
function readLoginPayload(raw) {
|
|
2971
|
+
let parsed = null;
|
|
2972
|
+
try {
|
|
2973
|
+
parsed = JSON.parse(raw);
|
|
2974
|
+
} catch {
|
|
2975
|
+
parsed = null;
|
|
2976
|
+
}
|
|
2977
|
+
const token = typeof parsed === "object" && parsed && "data" in parsed && typeof parsed.data?.token === "string" ? parsed.data.token : "";
|
|
2978
|
+
const role = typeof parsed === "object" && parsed && "data" in parsed && typeof parsed.data?.user?.role === "string" ? parsed.data.user.role : "user";
|
|
2979
|
+
if (!token) {
|
|
2980
|
+
throw new Error("Login succeeded but token is missing.");
|
|
2981
|
+
}
|
|
2982
|
+
return { token, role };
|
|
2983
|
+
}
|
|
2984
|
+
var PlatformAuthCommands = class {
|
|
2985
|
+
async login(opts = {}) {
|
|
2986
|
+
const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
|
|
2987
|
+
const { email, password } = await resolveCredentials(opts);
|
|
2988
|
+
const endpoint = opts.register ? `${platformBase}/platform/auth/register` : `${platformBase}/platform/auth/login`;
|
|
2989
|
+
const response = await fetch(endpoint, {
|
|
2990
|
+
method: "POST",
|
|
2991
|
+
headers: {
|
|
2992
|
+
"Content-Type": "application/json"
|
|
2993
|
+
},
|
|
2994
|
+
body: JSON.stringify({ email, password })
|
|
2995
|
+
});
|
|
2996
|
+
const raw = await response.text();
|
|
2997
|
+
if (!response.ok) {
|
|
2998
|
+
let parsed = null;
|
|
2999
|
+
try {
|
|
3000
|
+
parsed = JSON.parse(raw);
|
|
3001
|
+
} catch {
|
|
3002
|
+
parsed = null;
|
|
3003
|
+
}
|
|
3004
|
+
const maybeMessage = typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${response.status})`;
|
|
3005
|
+
throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, maybeMessage));
|
|
3006
|
+
}
|
|
3007
|
+
const { token, role } = readLoginPayload(raw);
|
|
3008
|
+
nextclawProvider.apiBase = v1Base;
|
|
3009
|
+
nextclawProvider.apiKey = token;
|
|
3010
|
+
providers.nextclaw = nextclawProvider;
|
|
3011
|
+
saveConfig6(config2, configPath);
|
|
3012
|
+
console.log(`\u2713 Logged in to NextClaw platform (${platformBase})`);
|
|
3013
|
+
console.log(`\u2713 Account: ${email} (${role})`);
|
|
3014
|
+
console.log(`\u2713 Token saved into providers.nextclaw.apiKey`);
|
|
3015
|
+
}
|
|
3016
|
+
};
|
|
3017
|
+
|
|
2862
3018
|
// src/cli/commands/remote.ts
|
|
2863
|
-
import { getConfigPath as
|
|
3019
|
+
import { getConfigPath as getConfigPath3, getDataDir as getDataDir4, loadConfig as loadConfig8 } from "@nextclaw/core";
|
|
2864
3020
|
import { ensureUiBridgeSecret } from "@nextclaw/server";
|
|
2865
3021
|
import { existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
|
|
2866
3022
|
import { dirname as dirname2, join as join4 } from "path";
|
|
@@ -2909,7 +3065,7 @@ var RemoteCommands = class {
|
|
|
2909
3065
|
return deviceInstallId;
|
|
2910
3066
|
}
|
|
2911
3067
|
resolvePlatformAccess(opts) {
|
|
2912
|
-
const config2 =
|
|
3068
|
+
const config2 = loadConfig8(getConfigPath3());
|
|
2913
3069
|
const providers = config2.providers;
|
|
2914
3070
|
const nextclawProvider = providers.nextclaw;
|
|
2915
3071
|
const token = typeof nextclawProvider?.apiKey === "string" ? nextclawProvider.apiKey.trim() : "";
|
|
@@ -2921,7 +3077,10 @@ var RemoteCommands = class {
|
|
|
2921
3077
|
if (!rawApiBase) {
|
|
2922
3078
|
throw new Error("Platform API base is missing. Pass --api-base or run nextclaw login.");
|
|
2923
3079
|
}
|
|
2924
|
-
const platformBase =
|
|
3080
|
+
const { platformBase } = resolvePlatformApiBase({
|
|
3081
|
+
explicitApiBase: rawApiBase,
|
|
3082
|
+
requireConfigured: true
|
|
3083
|
+
});
|
|
2925
3084
|
return { platformBase, token, config: config2 };
|
|
2926
3085
|
}
|
|
2927
3086
|
resolveLocalOrigin(config2, opts) {
|
|
@@ -3129,11 +3288,11 @@ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
|
|
|
3129
3288
|
import { resolve as resolve8 } from "path";
|
|
3130
3289
|
import {
|
|
3131
3290
|
APP_NAME,
|
|
3132
|
-
getConfigPath as
|
|
3291
|
+
getConfigPath as getConfigPath4,
|
|
3133
3292
|
getDataDir as getDataDir5,
|
|
3134
3293
|
getWorkspacePath as getWorkspacePath4,
|
|
3135
3294
|
hasSecretRef,
|
|
3136
|
-
loadConfig as
|
|
3295
|
+
loadConfig as loadConfig9
|
|
3137
3296
|
} from "@nextclaw/core";
|
|
3138
3297
|
import { listBuiltinProviders } from "@nextclaw/runtime";
|
|
3139
3298
|
var DiagnosticsCommands = class {
|
|
@@ -3294,8 +3453,8 @@ var DiagnosticsCommands = class {
|
|
|
3294
3453
|
process.exitCode = exitCode;
|
|
3295
3454
|
}
|
|
3296
3455
|
async collectRuntimeStatus(params) {
|
|
3297
|
-
const configPath =
|
|
3298
|
-
const config2 =
|
|
3456
|
+
const configPath = getConfigPath4();
|
|
3457
|
+
const config2 = loadConfig9();
|
|
3299
3458
|
const workspacePath = getWorkspacePath4(config2.agents.defaults.workspace);
|
|
3300
3459
|
const serviceStatePath = resolve8(getDataDir5(), "run", "service.json");
|
|
3301
3460
|
const fixActions = [];
|
|
@@ -3492,8 +3651,8 @@ import {
|
|
|
3492
3651
|
redactConfigObject
|
|
3493
3652
|
} from "@nextclaw/core";
|
|
3494
3653
|
var hashRaw = (raw) => createHash("sha256").update(raw).digest("hex");
|
|
3495
|
-
var readConfigSnapshot = (
|
|
3496
|
-
const path2 =
|
|
3654
|
+
var readConfigSnapshot = (getConfigPath7) => {
|
|
3655
|
+
const path2 = getConfigPath7();
|
|
3497
3656
|
let raw = "";
|
|
3498
3657
|
let parsed = {};
|
|
3499
3658
|
if (existsSync8(path2)) {
|
|
@@ -3954,7 +4113,7 @@ var MissingProvider = class extends LLMProvider {
|
|
|
3954
4113
|
};
|
|
3955
4114
|
|
|
3956
4115
|
// src/cli/commands/service-marketplace-installer.ts
|
|
3957
|
-
import { getWorkspacePath as getWorkspacePath5, loadConfig as
|
|
4116
|
+
import { getWorkspacePath as getWorkspacePath5, loadConfig as loadConfig11 } from "@nextclaw/core";
|
|
3958
4117
|
import { existsSync as existsSync9, rmSync as rmSync4 } from "fs";
|
|
3959
4118
|
import { join as join5 } from "path";
|
|
3960
4119
|
|
|
@@ -4004,7 +4163,7 @@ var buildMarketplaceSkillInstallArgs = (params) => {
|
|
|
4004
4163
|
};
|
|
4005
4164
|
|
|
4006
4165
|
// src/cli/commands/service-mcp-marketplace-ops.ts
|
|
4007
|
-
import { loadConfig as
|
|
4166
|
+
import { loadConfig as loadConfig10, saveConfig as saveConfig7 } from "@nextclaw/core";
|
|
4008
4167
|
import { McpDoctorFacade as McpDoctorFacade2, McpMutationService as McpMutationService2 } from "@nextclaw/mcp";
|
|
4009
4168
|
var ServiceMcpMarketplaceOps = class {
|
|
4010
4169
|
constructor(options) {
|
|
@@ -4072,13 +4231,13 @@ var ServiceMcpMarketplaceOps = class {
|
|
|
4072
4231
|
}
|
|
4073
4232
|
createMutationService() {
|
|
4074
4233
|
return new McpMutationService2({
|
|
4075
|
-
getConfig: () =>
|
|
4076
|
-
saveConfig: (config2) =>
|
|
4234
|
+
getConfig: () => loadConfig10(),
|
|
4235
|
+
saveConfig: (config2) => saveConfig7(config2)
|
|
4077
4236
|
});
|
|
4078
4237
|
}
|
|
4079
4238
|
createDoctorFacade() {
|
|
4080
4239
|
return new McpDoctorFacade2({
|
|
4081
|
-
getConfig: () =>
|
|
4240
|
+
getConfig: () => loadConfig10()
|
|
4082
4241
|
});
|
|
4083
4242
|
}
|
|
4084
4243
|
};
|
|
@@ -4119,7 +4278,7 @@ var ServiceMarketplaceInstaller = class {
|
|
|
4119
4278
|
if (params.kind && params.kind !== "marketplace") {
|
|
4120
4279
|
throw new Error(`Unsupported marketplace skill kind: ${params.kind}`);
|
|
4121
4280
|
}
|
|
4122
|
-
const workspace = getWorkspacePath5(
|
|
4281
|
+
const workspace = getWorkspacePath5(loadConfig11().agents.defaults.workspace);
|
|
4123
4282
|
const args = buildMarketplaceSkillInstallArgs({
|
|
4124
4283
|
slug: params.slug,
|
|
4125
4284
|
workspace,
|
|
@@ -4158,7 +4317,7 @@ var ServiceMarketplaceInstaller = class {
|
|
|
4158
4317
|
return { message: result.message };
|
|
4159
4318
|
}
|
|
4160
4319
|
async uninstallSkill(slug) {
|
|
4161
|
-
const workspace = getWorkspacePath5(
|
|
4320
|
+
const workspace = getWorkspacePath5(loadConfig11().agents.defaults.workspace);
|
|
4162
4321
|
const targetDir = join5(workspace, "skills", slug);
|
|
4163
4322
|
if (!existsSync9(targetDir)) {
|
|
4164
4323
|
throw new Error(`Skill not installed in workspace: ${slug}`);
|
|
@@ -6744,18 +6903,18 @@ var {
|
|
|
6744
6903
|
ChannelManager: ChannelManager2,
|
|
6745
6904
|
CronService: CronService2,
|
|
6746
6905
|
getApiBase,
|
|
6747
|
-
getConfigPath:
|
|
6906
|
+
getConfigPath: getConfigPath5,
|
|
6748
6907
|
getDataDir: getDataDir7,
|
|
6749
6908
|
getProvider,
|
|
6750
6909
|
getProviderName,
|
|
6751
6910
|
getWorkspacePath: getWorkspacePath9,
|
|
6752
6911
|
HeartbeatService,
|
|
6753
6912
|
LiteLLMProvider,
|
|
6754
|
-
loadConfig:
|
|
6913
|
+
loadConfig: loadConfig12,
|
|
6755
6914
|
MessageBus,
|
|
6756
6915
|
ProviderManager,
|
|
6757
6916
|
resolveConfigSecrets: resolveConfigSecrets2,
|
|
6758
|
-
saveConfig:
|
|
6917
|
+
saveConfig: saveConfig8,
|
|
6759
6918
|
SessionManager,
|
|
6760
6919
|
parseAgentScopedSessionKey: parseAgentScopedSessionKey3
|
|
6761
6920
|
} = NextclawCore;
|
|
@@ -6775,8 +6934,8 @@ var ServiceCommands = class {
|
|
|
6775
6934
|
async startGateway(options = {}) {
|
|
6776
6935
|
this.applyLiveConfigReload = null;
|
|
6777
6936
|
this.liveUiNcpAgent = null;
|
|
6778
|
-
const runtimeConfigPath =
|
|
6779
|
-
const config2 = resolveConfigSecrets2(
|
|
6937
|
+
const runtimeConfigPath = getConfigPath5();
|
|
6938
|
+
const config2 = resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath });
|
|
6780
6939
|
const workspace = getWorkspacePath9(config2.agents.defaults.workspace);
|
|
6781
6940
|
let pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
6782
6941
|
let extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
@@ -6821,7 +6980,7 @@ var ServiceCommands = class {
|
|
|
6821
6980
|
sessionManager,
|
|
6822
6981
|
providerManager,
|
|
6823
6982
|
makeProvider: (nextConfig) => this.makeProvider(nextConfig, { allowMissing: true }) ?? this.makeMissingProvider(nextConfig),
|
|
6824
|
-
loadConfig: () => resolveConfigSecrets2(
|
|
6983
|
+
loadConfig: () => resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath }),
|
|
6825
6984
|
getExtensionChannels: () => extensionRegistry.channels,
|
|
6826
6985
|
onRestartRequired: (paths) => {
|
|
6827
6986
|
void this.deps.requestRestart({
|
|
@@ -6832,14 +6991,14 @@ var ServiceCommands = class {
|
|
|
6832
6991
|
}
|
|
6833
6992
|
});
|
|
6834
6993
|
this.applyLiveConfigReload = async () => {
|
|
6835
|
-
await reloader.applyReloadPlan(resolveConfigSecrets2(
|
|
6994
|
+
await reloader.applyReloadPlan(resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath }));
|
|
6836
6995
|
};
|
|
6837
6996
|
const gatewayController = new GatewayControllerImpl({
|
|
6838
6997
|
reloader,
|
|
6839
6998
|
cron: cron2,
|
|
6840
6999
|
sessionManager,
|
|
6841
|
-
getConfigPath:
|
|
6842
|
-
saveConfig:
|
|
7000
|
+
getConfigPath: getConfigPath5,
|
|
7001
|
+
saveConfig: saveConfig8,
|
|
6843
7002
|
requestRestart: async (options2) => {
|
|
6844
7003
|
await this.deps.requestRestart({
|
|
6845
7004
|
reason: options2?.reason ?? "gateway tool restart",
|
|
@@ -6865,7 +7024,7 @@ var ServiceCommands = class {
|
|
|
6865
7024
|
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints({
|
|
6866
7025
|
registry: pluginRegistry,
|
|
6867
7026
|
channel,
|
|
6868
|
-
cfg: resolveConfigSecrets2(
|
|
7027
|
+
cfg: resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath }),
|
|
6869
7028
|
accountId
|
|
6870
7029
|
})
|
|
6871
7030
|
});
|
|
@@ -6898,14 +7057,14 @@ var ServiceCommands = class {
|
|
|
6898
7057
|
});
|
|
6899
7058
|
let pluginChannelBindings = getPluginChannelBindings3(pluginRegistry);
|
|
6900
7059
|
setPluginRuntimeBridge({
|
|
6901
|
-
loadConfig: () => toPluginConfigView(resolveConfigSecrets2(
|
|
7060
|
+
loadConfig: () => toPluginConfigView(resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath }), pluginChannelBindings),
|
|
6902
7061
|
writeConfigFile: async (nextConfigView) => {
|
|
6903
7062
|
if (!nextConfigView || typeof nextConfigView !== "object" || Array.isArray(nextConfigView)) {
|
|
6904
7063
|
throw new Error("plugin runtime writeConfigFile expects an object config");
|
|
6905
7064
|
}
|
|
6906
|
-
const current =
|
|
7065
|
+
const current = loadConfig12();
|
|
6907
7066
|
const next = mergePluginConfigView(current, nextConfigView, pluginChannelBindings);
|
|
6908
|
-
|
|
7067
|
+
saveConfig8(next);
|
|
6909
7068
|
},
|
|
6910
7069
|
dispatchReplyWithBufferedBlockDispatcher: async ({ ctx, dispatcherOptions }) => {
|
|
6911
7070
|
const bodyForAgent = typeof ctx.BodyForAgent === "string" ? ctx.BodyForAgent : "";
|
|
@@ -6979,12 +7138,12 @@ var ServiceCommands = class {
|
|
|
6979
7138
|
providerManager,
|
|
6980
7139
|
bus,
|
|
6981
7140
|
gatewayController,
|
|
6982
|
-
() => resolveConfigSecrets2(
|
|
7141
|
+
() => resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath }),
|
|
6983
7142
|
() => extensionRegistry,
|
|
6984
7143
|
({ channel, accountId }) => resolvePluginChannelMessageToolHints({
|
|
6985
7144
|
registry: pluginRegistry,
|
|
6986
7145
|
channel,
|
|
6987
|
-
cfg: resolveConfigSecrets2(
|
|
7146
|
+
cfg: resolveConfigSecrets2(loadConfig12(), { configPath: runtimeConfigPath }),
|
|
6988
7147
|
accountId
|
|
6989
7148
|
})
|
|
6990
7149
|
);
|
|
@@ -7021,7 +7180,7 @@ var ServiceCommands = class {
|
|
|
7021
7180
|
return trimmed || void 0;
|
|
7022
7181
|
}
|
|
7023
7182
|
watchConfigFile(reloader) {
|
|
7024
|
-
const configPath = resolve10(
|
|
7183
|
+
const configPath = resolve10(getConfigPath5());
|
|
7025
7184
|
const watcher = chokidar.watch(configPath, {
|
|
7026
7185
|
ignoreInitial: true,
|
|
7027
7186
|
awaitWriteFinish: { stabilityThreshold: 200, pollInterval: 50 }
|
|
@@ -7142,7 +7301,7 @@ var ServiceCommands = class {
|
|
|
7142
7301
|
});
|
|
7143
7302
|
}
|
|
7144
7303
|
async runForeground(options) {
|
|
7145
|
-
const config2 =
|
|
7304
|
+
const config2 = loadConfig12();
|
|
7146
7305
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
7147
7306
|
const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
|
|
7148
7307
|
if (options.open) {
|
|
@@ -7155,7 +7314,7 @@ var ServiceCommands = class {
|
|
|
7155
7314
|
});
|
|
7156
7315
|
}
|
|
7157
7316
|
async startService(options) {
|
|
7158
|
-
const config2 =
|
|
7317
|
+
const config2 = loadConfig12();
|
|
7159
7318
|
const uiConfig = resolveUiConfig(config2, options.uiOverrides);
|
|
7160
7319
|
const uiUrl = resolveUiApiBase(uiConfig.host, uiConfig.port);
|
|
7161
7320
|
const apiUrl = `${uiUrl}/api`;
|
|
@@ -7569,7 +7728,7 @@ var ServiceCommands = class {
|
|
|
7569
7728
|
return null;
|
|
7570
7729
|
}
|
|
7571
7730
|
console.error("Error: No API key configured.");
|
|
7572
|
-
console.error(`Set one in ${
|
|
7731
|
+
console.error(`Set one in ${getConfigPath5()} under providers section`);
|
|
7573
7732
|
process.exit(1);
|
|
7574
7733
|
}
|
|
7575
7734
|
return new LiteLLMProvider({
|
|
@@ -7696,7 +7855,7 @@ var ServiceCommands = class {
|
|
|
7696
7855
|
const uiServer = startUiServer({
|
|
7697
7856
|
host: uiConfig.host,
|
|
7698
7857
|
port: uiConfig.port,
|
|
7699
|
-
configPath:
|
|
7858
|
+
configPath: getConfigPath5(),
|
|
7700
7859
|
productVersion: getPackageVersion(),
|
|
7701
7860
|
staticDir: uiStaticDir ?? void 0,
|
|
7702
7861
|
cronService,
|
|
@@ -7784,7 +7943,7 @@ var ServiceCommands = class {
|
|
|
7784
7943
|
}
|
|
7785
7944
|
}
|
|
7786
7945
|
installBuiltinMarketplaceSkill(slug, force) {
|
|
7787
|
-
const workspace = getWorkspacePath9(
|
|
7946
|
+
const workspace = getWorkspacePath9(loadConfig12().agents.defaults.workspace);
|
|
7788
7947
|
const destination = join7(workspace, "skills", slug);
|
|
7789
7948
|
const destinationSkillFile = join7(destination, "SKILL.md");
|
|
7790
7949
|
if (existsSync11(destinationSkillFile) && !force) {
|
|
@@ -8063,6 +8222,7 @@ var CliRuntime = class {
|
|
|
8063
8222
|
pluginCommands;
|
|
8064
8223
|
channelCommands;
|
|
8065
8224
|
cronCommands;
|
|
8225
|
+
platformAuthCommands;
|
|
8066
8226
|
remoteCommands;
|
|
8067
8227
|
diagnosticsCommands;
|
|
8068
8228
|
constructor(options = {}) {
|
|
@@ -8085,6 +8245,7 @@ var CliRuntime = class {
|
|
|
8085
8245
|
requestRestart: (params) => this.requestRestart(params)
|
|
8086
8246
|
});
|
|
8087
8247
|
this.cronCommands = new CronCommands();
|
|
8248
|
+
this.platformAuthCommands = new PlatformAuthCommands();
|
|
8088
8249
|
this.remoteCommands = new RemoteCommands();
|
|
8089
8250
|
this.diagnosticsCommands = new DiagnosticsCommands({ logo: this.logo });
|
|
8090
8251
|
this.restartCoordinator = new RestartCoordinator({
|
|
@@ -8279,14 +8440,14 @@ var CliRuntime = class {
|
|
|
8279
8440
|
const source = options.source ?? "init";
|
|
8280
8441
|
const prefix = options.auto ? "Auto init" : "Init";
|
|
8281
8442
|
const force = Boolean(options.force);
|
|
8282
|
-
const configPath =
|
|
8443
|
+
const configPath = getConfigPath6();
|
|
8283
8444
|
let createdConfig = false;
|
|
8284
8445
|
if (!existsSync13(configPath)) {
|
|
8285
8446
|
const config3 = ConfigSchema2.parse({});
|
|
8286
|
-
|
|
8447
|
+
saveConfig9(config3);
|
|
8287
8448
|
createdConfig = true;
|
|
8288
8449
|
}
|
|
8289
|
-
const config2 =
|
|
8450
|
+
const config2 = loadConfig13();
|
|
8290
8451
|
const workspaceSetting = config2.agents.defaults.workspace;
|
|
8291
8452
|
const workspacePath = !workspaceSetting || workspaceSetting === DEFAULT_WORKSPACE_PATH ? join9(getDataDir9(), DEFAULT_WORKSPACE_DIR) : expandHome2(workspaceSetting);
|
|
8292
8453
|
const workspaceExisted = existsSync13(workspacePath);
|
|
@@ -8321,73 +8482,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8321
8482
|
}
|
|
8322
8483
|
async login(opts = {}) {
|
|
8323
8484
|
await this.init({ source: "login", auto: true });
|
|
8324
|
-
|
|
8325
|
-
const config2 = loadConfig12(configPath);
|
|
8326
|
-
const providers = config2.providers;
|
|
8327
|
-
const nextclawProvider = providers.nextclaw ?? {
|
|
8328
|
-
displayName: "",
|
|
8329
|
-
apiKey: "",
|
|
8330
|
-
apiBase: null,
|
|
8331
|
-
extraHeaders: null,
|
|
8332
|
-
wireApi: "auto",
|
|
8333
|
-
models: []
|
|
8334
|
-
};
|
|
8335
|
-
const configuredApiBase = typeof nextclawProvider.apiBase === "string" && nextclawProvider.apiBase.trim().length > 0 ? nextclawProvider.apiBase.trim() : "https://ai-gateway-api.nextclaw.io/v1";
|
|
8336
|
-
const requestedApiBase = typeof opts.apiBase === "string" && opts.apiBase.trim().length > 0 ? opts.apiBase.trim() : configuredApiBase;
|
|
8337
|
-
const platformBase = requestedApiBase.replace(/\/v1\/?$/i, "");
|
|
8338
|
-
const v1Base = `${platformBase}/v1`;
|
|
8339
|
-
let email = typeof opts.email === "string" ? opts.email.trim() : "";
|
|
8340
|
-
let password = typeof opts.password === "string" ? opts.password : "";
|
|
8341
|
-
if (!email || !password) {
|
|
8342
|
-
const rl = createInterface2({
|
|
8343
|
-
input: process.stdin,
|
|
8344
|
-
output: process.stdout
|
|
8345
|
-
});
|
|
8346
|
-
try {
|
|
8347
|
-
if (!email) {
|
|
8348
|
-
email = (await prompt(rl, "Email: ")).trim();
|
|
8349
|
-
}
|
|
8350
|
-
if (!password) {
|
|
8351
|
-
password = await prompt(rl, "Password: ");
|
|
8352
|
-
}
|
|
8353
|
-
} finally {
|
|
8354
|
-
rl.close();
|
|
8355
|
-
}
|
|
8356
|
-
}
|
|
8357
|
-
if (!email || !password) {
|
|
8358
|
-
throw new Error("Email and password are required.");
|
|
8359
|
-
}
|
|
8360
|
-
const endpoint = opts.register ? `${platformBase}/platform/auth/register` : `${platformBase}/platform/auth/login`;
|
|
8361
|
-
const response = await fetch(endpoint, {
|
|
8362
|
-
method: "POST",
|
|
8363
|
-
headers: {
|
|
8364
|
-
"Content-Type": "application/json"
|
|
8365
|
-
},
|
|
8366
|
-
body: JSON.stringify({ email, password })
|
|
8367
|
-
});
|
|
8368
|
-
const raw = await response.text();
|
|
8369
|
-
let parsed = null;
|
|
8370
|
-
try {
|
|
8371
|
-
parsed = JSON.parse(raw);
|
|
8372
|
-
} catch {
|
|
8373
|
-
parsed = null;
|
|
8374
|
-
}
|
|
8375
|
-
if (!response.ok) {
|
|
8376
|
-
const maybeMessage = typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${response.status})`;
|
|
8377
|
-
throw new Error(maybeMessage);
|
|
8378
|
-
}
|
|
8379
|
-
const token = typeof parsed === "object" && parsed && "data" in parsed && typeof parsed.data?.token === "string" ? parsed.data.token : "";
|
|
8380
|
-
const role = typeof parsed === "object" && parsed && "data" in parsed && typeof parsed.data?.user?.role === "string" ? parsed.data.user.role : "user";
|
|
8381
|
-
if (!token) {
|
|
8382
|
-
throw new Error("Login succeeded but token is missing.");
|
|
8383
|
-
}
|
|
8384
|
-
nextclawProvider.apiBase = v1Base;
|
|
8385
|
-
nextclawProvider.apiKey = token;
|
|
8386
|
-
providers.nextclaw = nextclawProvider;
|
|
8387
|
-
saveConfig8(config2, configPath);
|
|
8388
|
-
console.log(`\u2713 Logged in to NextClaw platform (${platformBase})`);
|
|
8389
|
-
console.log(`\u2713 Account: ${email} (${role})`);
|
|
8390
|
-
console.log(`\u2713 Token saved into providers.nextclaw.apiKey`);
|
|
8485
|
+
await this.platformAuthCommands.login(opts);
|
|
8391
8486
|
}
|
|
8392
8487
|
async remoteConnect(opts = {}) {
|
|
8393
8488
|
await this.remoteCommands.connect(opts);
|
|
@@ -8481,8 +8576,8 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8481
8576
|
await this.serviceCommands.stopService();
|
|
8482
8577
|
}
|
|
8483
8578
|
async agent(opts) {
|
|
8484
|
-
const configPath =
|
|
8485
|
-
const config2 = resolveConfigSecrets3(
|
|
8579
|
+
const configPath = getConfigPath6();
|
|
8580
|
+
const config2 = resolveConfigSecrets3(loadConfig13(), { configPath });
|
|
8486
8581
|
const workspace = getWorkspacePath10(config2.agents.defaults.workspace);
|
|
8487
8582
|
const pluginRegistry = loadPluginRegistry(config2, workspace);
|
|
8488
8583
|
const extensionRegistry = toExtensionRegistry(pluginRegistry);
|
|
@@ -8490,7 +8585,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8490
8585
|
const pluginChannelBindings = getPluginChannelBindings4(pluginRegistry);
|
|
8491
8586
|
setPluginRuntimeBridge2({
|
|
8492
8587
|
loadConfig: () => toPluginConfigView(
|
|
8493
|
-
resolveConfigSecrets3(
|
|
8588
|
+
resolveConfigSecrets3(loadConfig13(), { configPath }),
|
|
8494
8589
|
pluginChannelBindings
|
|
8495
8590
|
),
|
|
8496
8591
|
writeConfigFile: async (nextConfigView) => {
|
|
@@ -8499,13 +8594,13 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8499
8594
|
"plugin runtime writeConfigFile expects an object config"
|
|
8500
8595
|
);
|
|
8501
8596
|
}
|
|
8502
|
-
const current =
|
|
8597
|
+
const current = loadConfig13();
|
|
8503
8598
|
const next = mergePluginConfigView(
|
|
8504
8599
|
current,
|
|
8505
8600
|
nextConfigView,
|
|
8506
8601
|
pluginChannelBindings
|
|
8507
8602
|
);
|
|
8508
|
-
|
|
8603
|
+
saveConfig9(next);
|
|
8509
8604
|
}
|
|
8510
8605
|
});
|
|
8511
8606
|
try {
|
|
@@ -8531,7 +8626,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8531
8626
|
resolveMessageToolHints: ({ channel, accountId }) => resolvePluginChannelMessageToolHints2({
|
|
8532
8627
|
registry: pluginRegistry,
|
|
8533
8628
|
channel,
|
|
8534
|
-
cfg: resolveConfigSecrets3(
|
|
8629
|
+
cfg: resolveConfigSecrets3(loadConfig13(), { configPath }),
|
|
8535
8630
|
accountId
|
|
8536
8631
|
})
|
|
8537
8632
|
});
|
|
@@ -8554,7 +8649,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8554
8649
|
const historyDir = resolve12(historyFile, "..");
|
|
8555
8650
|
mkdirSync8(historyDir, { recursive: true });
|
|
8556
8651
|
const history = existsSync13(historyFile) ? readFileSync11(historyFile, "utf-8").split("\n").filter(Boolean) : [];
|
|
8557
|
-
const rl =
|
|
8652
|
+
const rl = createInterface3({
|
|
8558
8653
|
input: process.stdin,
|
|
8559
8654
|
output: process.stdout
|
|
8560
8655
|
});
|
|
@@ -8726,7 +8821,7 @@ ${this.logo} ${APP_NAME4} is ready! (${source})`);
|
|
|
8726
8821
|
await this.diagnosticsCommands.doctor(opts);
|
|
8727
8822
|
}
|
|
8728
8823
|
async skillsInstall(options) {
|
|
8729
|
-
const config2 =
|
|
8824
|
+
const config2 = loadConfig13();
|
|
8730
8825
|
const workdir = resolveSkillsInstallWorkdir({
|
|
8731
8826
|
explicitWorkdir: options.workdir,
|
|
8732
8827
|
configuredWorkspace: config2.agents.defaults.workspace
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.2",
|
|
4
4
|
"description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
"chokidar": "^3.6.0",
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
41
|
"yaml": "^2.8.1",
|
|
42
|
-
"@nextclaw/core": "0.9.
|
|
42
|
+
"@nextclaw/core": "0.9.3",
|
|
43
43
|
"@nextclaw/ncp": "0.3.1",
|
|
44
|
-
"@nextclaw/mcp": "0.1.
|
|
44
|
+
"@nextclaw/mcp": "0.1.2",
|
|
45
45
|
"@nextclaw/ncp-agent-runtime": "0.2.1",
|
|
46
|
-
"@nextclaw/
|
|
47
|
-
"@nextclaw/
|
|
48
|
-
"@nextclaw/ncp-mcp": "0.1.1",
|
|
46
|
+
"@nextclaw/ncp-mcp": "0.1.2",
|
|
47
|
+
"@nextclaw/runtime": "0.2.3",
|
|
49
48
|
"@nextclaw/ncp-toolkit": "0.4.1",
|
|
50
|
-
"@nextclaw/server": "0.10.
|
|
49
|
+
"@nextclaw/server": "0.10.2",
|
|
50
|
+
"@nextclaw/openclaw-compat": "0.3.6"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@types/node": "^20.17.6",
|