nextclaw 0.13.9 → 0.13.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.
- package/dist/cli/index.js +178 -15
- package/package.json +5 -5
package/dist/cli/index.js
CHANGED
|
@@ -3001,6 +3001,73 @@ function readLoginPayload(raw) {
|
|
|
3001
3001
|
}
|
|
3002
3002
|
return { token, role };
|
|
3003
3003
|
}
|
|
3004
|
+
function persistPlatformToken(params) {
|
|
3005
|
+
params.nextclawProvider.apiBase = params.v1Base;
|
|
3006
|
+
params.nextclawProvider.apiKey = params.token;
|
|
3007
|
+
params.providers.nextclaw = params.nextclawProvider;
|
|
3008
|
+
saveConfig6(params.config, params.configPath);
|
|
3009
|
+
}
|
|
3010
|
+
function parseJsonText(raw) {
|
|
3011
|
+
try {
|
|
3012
|
+
return JSON.parse(raw);
|
|
3013
|
+
} catch {
|
|
3014
|
+
return null;
|
|
3015
|
+
}
|
|
3016
|
+
}
|
|
3017
|
+
function readPlatformErrorMessage(raw, fallbackStatus) {
|
|
3018
|
+
const parsed = parseJsonText(raw);
|
|
3019
|
+
return typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${fallbackStatus})`;
|
|
3020
|
+
}
|
|
3021
|
+
function readBrowserAuthStartPayload(raw) {
|
|
3022
|
+
const parsed = parseJsonText(raw);
|
|
3023
|
+
const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
|
|
3024
|
+
const sessionId = typeof data?.sessionId === "string" ? data.sessionId.trim() : "";
|
|
3025
|
+
const verificationUri = typeof data?.verificationUri === "string" ? data.verificationUri.trim() : "";
|
|
3026
|
+
const expiresAt = typeof data?.expiresAt === "string" ? data.expiresAt.trim() : "";
|
|
3027
|
+
const intervalMs = typeof data?.intervalMs === "number" && Number.isFinite(data.intervalMs) ? Math.max(1e3, Math.trunc(data.intervalMs)) : 1500;
|
|
3028
|
+
if (!sessionId || !verificationUri || !expiresAt) {
|
|
3029
|
+
throw new Error("Browser authorization session payload is incomplete.");
|
|
3030
|
+
}
|
|
3031
|
+
return {
|
|
3032
|
+
sessionId,
|
|
3033
|
+
verificationUri,
|
|
3034
|
+
expiresAt,
|
|
3035
|
+
intervalMs
|
|
3036
|
+
};
|
|
3037
|
+
}
|
|
3038
|
+
function readBrowserAuthPollPayload(raw) {
|
|
3039
|
+
const parsed = parseJsonText(raw);
|
|
3040
|
+
const data = typeof parsed === "object" && parsed && "data" in parsed ? parsed.data : null;
|
|
3041
|
+
const status = typeof data?.status === "string" ? data.status.trim() : "";
|
|
3042
|
+
if (status === "pending") {
|
|
3043
|
+
return {
|
|
3044
|
+
status,
|
|
3045
|
+
nextPollMs: typeof data?.nextPollMs === "number" && Number.isFinite(data.nextPollMs) ? Math.max(1e3, Math.trunc(data.nextPollMs)) : 1500
|
|
3046
|
+
};
|
|
3047
|
+
}
|
|
3048
|
+
if (status === "expired") {
|
|
3049
|
+
return {
|
|
3050
|
+
status,
|
|
3051
|
+
message: typeof data?.message === "string" && data.message.trim() ? data.message.trim() : "Authorization session expired."
|
|
3052
|
+
};
|
|
3053
|
+
}
|
|
3054
|
+
if (status !== "authorized") {
|
|
3055
|
+
throw new Error("Unexpected browser authorization status.");
|
|
3056
|
+
}
|
|
3057
|
+
const token = typeof data?.token === "string" ? data.token.trim() : "";
|
|
3058
|
+
const user = typeof data?.user === "object" && data.user ? data.user : null;
|
|
3059
|
+
const role = typeof user?.role === "string" ? user.role.trim() : "user";
|
|
3060
|
+
const email = typeof user?.email === "string" ? user.email.trim() : "";
|
|
3061
|
+
if (!token || !email) {
|
|
3062
|
+
throw new Error("Authorized browser login payload is incomplete.");
|
|
3063
|
+
}
|
|
3064
|
+
return {
|
|
3065
|
+
status,
|
|
3066
|
+
token,
|
|
3067
|
+
role,
|
|
3068
|
+
email
|
|
3069
|
+
};
|
|
3070
|
+
}
|
|
3004
3071
|
var PlatformAuthCommands = class {
|
|
3005
3072
|
async loginResult(opts = {}) {
|
|
3006
3073
|
const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
|
|
@@ -3015,20 +3082,17 @@ var PlatformAuthCommands = class {
|
|
|
3015
3082
|
});
|
|
3016
3083
|
const raw = await response.text();
|
|
3017
3084
|
if (!response.ok) {
|
|
3018
|
-
|
|
3019
|
-
try {
|
|
3020
|
-
parsed = JSON.parse(raw);
|
|
3021
|
-
} catch {
|
|
3022
|
-
parsed = null;
|
|
3023
|
-
}
|
|
3024
|
-
const maybeMessage = typeof parsed === "object" && parsed && "error" in parsed && typeof parsed.error?.message === "string" ? parsed.error.message : raw || `Request failed (${response.status})`;
|
|
3025
|
-
throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, maybeMessage));
|
|
3085
|
+
throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
3026
3086
|
}
|
|
3027
3087
|
const { token, role } = readLoginPayload(raw);
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3088
|
+
persistPlatformToken({
|
|
3089
|
+
configPath,
|
|
3090
|
+
config: config2,
|
|
3091
|
+
providers,
|
|
3092
|
+
nextclawProvider,
|
|
3093
|
+
v1Base,
|
|
3094
|
+
token
|
|
3095
|
+
});
|
|
3032
3096
|
return {
|
|
3033
3097
|
token,
|
|
3034
3098
|
role,
|
|
@@ -3037,6 +3101,73 @@ var PlatformAuthCommands = class {
|
|
|
3037
3101
|
v1Base
|
|
3038
3102
|
};
|
|
3039
3103
|
}
|
|
3104
|
+
async startBrowserAuth(opts = {}) {
|
|
3105
|
+
const { platformBase, v1Base, inputApiBase } = resolveProviderConfig(opts);
|
|
3106
|
+
const response = await fetch(`${platformBase}/platform/auth/browser/start`, {
|
|
3107
|
+
method: "POST",
|
|
3108
|
+
headers: {
|
|
3109
|
+
"Content-Type": "application/json"
|
|
3110
|
+
},
|
|
3111
|
+
body: JSON.stringify({})
|
|
3112
|
+
});
|
|
3113
|
+
const raw = await response.text();
|
|
3114
|
+
if (!response.ok) {
|
|
3115
|
+
throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
3116
|
+
}
|
|
3117
|
+
const result = readBrowserAuthStartPayload(raw);
|
|
3118
|
+
return {
|
|
3119
|
+
...result,
|
|
3120
|
+
platformBase,
|
|
3121
|
+
v1Base
|
|
3122
|
+
};
|
|
3123
|
+
}
|
|
3124
|
+
async pollBrowserAuth(params) {
|
|
3125
|
+
const { configPath, config: config2, providers, nextclawProvider, platformBase, v1Base, inputApiBase } = resolveProviderConfig({
|
|
3126
|
+
apiBase: params.apiBase
|
|
3127
|
+
});
|
|
3128
|
+
const response = await fetch(`${platformBase}/platform/auth/browser/poll`, {
|
|
3129
|
+
method: "POST",
|
|
3130
|
+
headers: {
|
|
3131
|
+
"Content-Type": "application/json"
|
|
3132
|
+
},
|
|
3133
|
+
body: JSON.stringify({
|
|
3134
|
+
sessionId: params.sessionId
|
|
3135
|
+
})
|
|
3136
|
+
});
|
|
3137
|
+
const raw = await response.text();
|
|
3138
|
+
if (!response.ok) {
|
|
3139
|
+
throw new Error(buildPlatformApiBaseErrorMessage(inputApiBase, readPlatformErrorMessage(raw, response.status)));
|
|
3140
|
+
}
|
|
3141
|
+
const result = readBrowserAuthPollPayload(raw);
|
|
3142
|
+
if (result.status === "pending") {
|
|
3143
|
+
return {
|
|
3144
|
+
status: "pending",
|
|
3145
|
+
nextPollMs: result.nextPollMs ?? 1500
|
|
3146
|
+
};
|
|
3147
|
+
}
|
|
3148
|
+
if (result.status === "expired") {
|
|
3149
|
+
return {
|
|
3150
|
+
status: "expired",
|
|
3151
|
+
message: result.message ?? "Authorization session expired."
|
|
3152
|
+
};
|
|
3153
|
+
}
|
|
3154
|
+
persistPlatformToken({
|
|
3155
|
+
configPath,
|
|
3156
|
+
config: config2,
|
|
3157
|
+
providers,
|
|
3158
|
+
nextclawProvider,
|
|
3159
|
+
v1Base,
|
|
3160
|
+
token: result.token ?? ""
|
|
3161
|
+
});
|
|
3162
|
+
return {
|
|
3163
|
+
status: "authorized",
|
|
3164
|
+
token: result.token ?? "",
|
|
3165
|
+
role: result.role ?? "user",
|
|
3166
|
+
email: result.email ?? "",
|
|
3167
|
+
platformBase,
|
|
3168
|
+
v1Base
|
|
3169
|
+
};
|
|
3170
|
+
}
|
|
3040
3171
|
async login(opts = {}) {
|
|
3041
3172
|
const result = await this.loginResult(opts);
|
|
3042
3173
|
console.log(`\u2713 Logged in to NextClaw platform (${result.platformBase})`);
|
|
@@ -3130,6 +3261,9 @@ function normalizeOptionalString3(value) {
|
|
|
3130
3261
|
const trimmed = value.trim();
|
|
3131
3262
|
return trimmed.length > 0 ? trimmed : void 0;
|
|
3132
3263
|
}
|
|
3264
|
+
function isPlatformSessionToken(value) {
|
|
3265
|
+
return typeof value === "string" && value.startsWith("nca.");
|
|
3266
|
+
}
|
|
3133
3267
|
function resolveConfiguredLocalOrigin(config2) {
|
|
3134
3268
|
const state = readServiceState();
|
|
3135
3269
|
if (state && isProcessRunning(state.pid) && Number.isFinite(state.uiPort)) {
|
|
@@ -3240,8 +3374,8 @@ var RemoteCommands = class {
|
|
|
3240
3374
|
},
|
|
3241
3375
|
{
|
|
3242
3376
|
name: "platform-token",
|
|
3243
|
-
ok:
|
|
3244
|
-
detail: token ? "token configured" : 'run "nextclaw login" first'
|
|
3377
|
+
ok: isPlatformSessionToken(token),
|
|
3378
|
+
detail: isPlatformSessionToken(token) ? "platform session token configured" : 'run remote browser login or "nextclaw login" first'
|
|
3245
3379
|
},
|
|
3246
3380
|
{
|
|
3247
3381
|
name: "platform-api-base",
|
|
@@ -6424,6 +6558,9 @@ function decodeJwtPayload(token) {
|
|
|
6424
6558
|
return null;
|
|
6425
6559
|
}
|
|
6426
6560
|
}
|
|
6561
|
+
function isPlatformSessionToken2(token) {
|
|
6562
|
+
return typeof token === "string" && token.startsWith("nca.");
|
|
6563
|
+
}
|
|
6427
6564
|
function toRemoteRuntimeView(runtime2) {
|
|
6428
6565
|
if (!runtime2) {
|
|
6429
6566
|
return null;
|
|
@@ -6480,6 +6617,32 @@ var RemoteAccessHost = class {
|
|
|
6480
6617
|
await this.deps.platformAuthCommands.loginResult(input);
|
|
6481
6618
|
return this.getStatus();
|
|
6482
6619
|
}
|
|
6620
|
+
async startBrowserAuth(input) {
|
|
6621
|
+
const result = await this.deps.platformAuthCommands.startBrowserAuth({
|
|
6622
|
+
apiBase: input.apiBase
|
|
6623
|
+
});
|
|
6624
|
+
return {
|
|
6625
|
+
sessionId: result.sessionId,
|
|
6626
|
+
verificationUri: result.verificationUri,
|
|
6627
|
+
expiresAt: result.expiresAt,
|
|
6628
|
+
intervalMs: result.intervalMs
|
|
6629
|
+
};
|
|
6630
|
+
}
|
|
6631
|
+
async pollBrowserAuth(input) {
|
|
6632
|
+
const config2 = loadConfig13(getConfigPath6());
|
|
6633
|
+
const result = await this.deps.platformAuthCommands.pollBrowserAuth({
|
|
6634
|
+
apiBase: normalizeOptionalString5(input.apiBase) ?? normalizeOptionalString5(config2.remote.platformApiBase) ?? normalizeOptionalString5(config2.providers.nextclaw?.apiBase) ?? void 0,
|
|
6635
|
+
sessionId: input.sessionId
|
|
6636
|
+
});
|
|
6637
|
+
if (result.status !== "authorized") {
|
|
6638
|
+
return result;
|
|
6639
|
+
}
|
|
6640
|
+
return {
|
|
6641
|
+
status: "authorized",
|
|
6642
|
+
email: result.email,
|
|
6643
|
+
role: result.role
|
|
6644
|
+
};
|
|
6645
|
+
}
|
|
6483
6646
|
logout() {
|
|
6484
6647
|
this.deps.platformAuthCommands.logout();
|
|
6485
6648
|
return this.getStatus();
|
|
@@ -6592,7 +6755,7 @@ var RemoteAccessHost = class {
|
|
|
6592
6755
|
};
|
|
6593
6756
|
}
|
|
6594
6757
|
readAccountView(params) {
|
|
6595
|
-
if (!params.token) {
|
|
6758
|
+
if (!isPlatformSessionToken2(params.token)) {
|
|
6596
6759
|
return {
|
|
6597
6760
|
loggedIn: false,
|
|
6598
6761
|
apiBase: params.apiBase,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nextclaw",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.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,15 +40,15 @@
|
|
|
40
40
|
"commander": "^12.1.0",
|
|
41
41
|
"yaml": "^2.8.1",
|
|
42
42
|
"@nextclaw/core": "0.9.5",
|
|
43
|
-
"@nextclaw/mcp": "0.1.
|
|
43
|
+
"@nextclaw/mcp": "0.1.10",
|
|
44
44
|
"@nextclaw/ncp": "0.3.1",
|
|
45
|
+
"@nextclaw/ncp-mcp": "0.1.10",
|
|
45
46
|
"@nextclaw/ncp-agent-runtime": "0.2.1",
|
|
46
|
-
"@nextclaw/ncp-mcp": "0.1.9",
|
|
47
47
|
"@nextclaw/ncp-toolkit": "0.4.1",
|
|
48
|
+
"@nextclaw/remote": "0.1.6",
|
|
48
49
|
"@nextclaw/runtime": "0.2.5",
|
|
49
|
-
"@nextclaw/server": "0.10.9",
|
|
50
50
|
"@nextclaw/openclaw-compat": "0.3.8",
|
|
51
|
-
"@nextclaw/
|
|
51
|
+
"@nextclaw/server": "0.10.10"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^20.17.6",
|