nexrall-code 0.5.206 → 0.5.208
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/README.md +4 -2
- package/dist/index.js +1005 -630
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -10114,6 +10114,8 @@ var require_client = __commonJS({
|
|
|
10114
10114
|
exports.getUsageDaily = getUsageDaily;
|
|
10115
10115
|
exports.exchangeVscodeCode = exchangeVscodeCode;
|
|
10116
10116
|
exports.login = login2;
|
|
10117
|
+
exports.exchangeAuthCode = exchangeAuthCode2;
|
|
10118
|
+
exports.checkToken = checkToken2;
|
|
10117
10119
|
exports.getUserProfile = getUserProfile;
|
|
10118
10120
|
exports.clampScheduleMinutes = clampScheduleMinutes;
|
|
10119
10121
|
exports.listCloudSchedules = listCloudSchedules3;
|
|
@@ -10173,7 +10175,7 @@ var require_client = __commonJS({
|
|
|
10173
10175
|
function authHeaders() {
|
|
10174
10176
|
const token = (0, index_1.getToken)();
|
|
10175
10177
|
if (!token) {
|
|
10176
|
-
throw new Error("Not authenticated. Run `
|
|
10178
|
+
throw new Error("Not authenticated. Run `nex auth` first.");
|
|
10177
10179
|
}
|
|
10178
10180
|
const headers = {
|
|
10179
10181
|
"Content-Type": "application/json",
|
|
@@ -11159,6 +11161,42 @@ var require_client = __commonJS({
|
|
|
11159
11161
|
email: data.email ?? email
|
|
11160
11162
|
};
|
|
11161
11163
|
}
|
|
11164
|
+
async function exchangeAuthCode2(code) {
|
|
11165
|
+
const response = await (0, node_fetch_1.default)(`${exports.API_BASE}/api/auth/vscode-exchange`, {
|
|
11166
|
+
method: "POST",
|
|
11167
|
+
headers: { "Content-Type": "application/json", ...deviceHeader() },
|
|
11168
|
+
body: JSON.stringify({ code })
|
|
11169
|
+
});
|
|
11170
|
+
if (response.status === 401 || response.status === 400) {
|
|
11171
|
+
throw new Error("That sign-in code is invalid or has expired (codes last 5 minutes). Run `nex auth --browser` again.");
|
|
11172
|
+
}
|
|
11173
|
+
if (!response.ok) {
|
|
11174
|
+
const errText3 = await response.text().catch(() => "");
|
|
11175
|
+
throw new Error(`Sign-in failed (${response.status}): ${errText3}`);
|
|
11176
|
+
}
|
|
11177
|
+
const data = await response.json();
|
|
11178
|
+
if (!data.token)
|
|
11179
|
+
throw new Error("Sign-in response missing token");
|
|
11180
|
+
return {
|
|
11181
|
+
token: data.token,
|
|
11182
|
+
...data.refreshToken ? { refreshToken: data.refreshToken } : {},
|
|
11183
|
+
email: data.user?.email ?? ""
|
|
11184
|
+
};
|
|
11185
|
+
}
|
|
11186
|
+
async function checkToken2(token) {
|
|
11187
|
+
try {
|
|
11188
|
+
const response = await (0, node_fetch_1.default)(`${exports.API_BASE}/api/user/profile`, {
|
|
11189
|
+
method: "GET",
|
|
11190
|
+
headers: { Authorization: `Bearer ${token}`, ...deviceHeader() }
|
|
11191
|
+
});
|
|
11192
|
+
if (!response.ok)
|
|
11193
|
+
return { ok: false, status: response.status };
|
|
11194
|
+
const data = await response.json().catch(() => ({}));
|
|
11195
|
+
return { ok: true, status: response.status, ...data.email ? { email: data.email } : {} };
|
|
11196
|
+
} catch {
|
|
11197
|
+
return { ok: false, status: 0 };
|
|
11198
|
+
}
|
|
11199
|
+
}
|
|
11162
11200
|
async function getUserProfile() {
|
|
11163
11201
|
const fetchOnce = () => (0, node_fetch_1.default)(`${exports.API_BASE}/api/user/profile`, { method: "GET", headers: authHeaders() });
|
|
11164
11202
|
let response = await fetchOnce();
|
|
@@ -11393,6 +11431,102 @@ var require_client = __commonJS({
|
|
|
11393
11431
|
}
|
|
11394
11432
|
});
|
|
11395
11433
|
|
|
11434
|
+
// ../core/dist/util/proc.js
|
|
11435
|
+
var require_proc = __commonJS({
|
|
11436
|
+
"../core/dist/util/proc.js"(exports) {
|
|
11437
|
+
"use strict";
|
|
11438
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
11439
|
+
if (k2 === void 0)
|
|
11440
|
+
k2 = k;
|
|
11441
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k);
|
|
11442
|
+
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
11443
|
+
desc = { enumerable: true, get: function() {
|
|
11444
|
+
return m2[k];
|
|
11445
|
+
} };
|
|
11446
|
+
}
|
|
11447
|
+
Object.defineProperty(o, k2, desc);
|
|
11448
|
+
} : function(o, m2, k, k2) {
|
|
11449
|
+
if (k2 === void 0)
|
|
11450
|
+
k2 = k;
|
|
11451
|
+
o[k2] = m2[k];
|
|
11452
|
+
});
|
|
11453
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
11454
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11455
|
+
} : function(o, v) {
|
|
11456
|
+
o["default"] = v;
|
|
11457
|
+
});
|
|
11458
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
11459
|
+
var ownKeys = function(o) {
|
|
11460
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
11461
|
+
var ar = [];
|
|
11462
|
+
for (var k in o2)
|
|
11463
|
+
if (Object.prototype.hasOwnProperty.call(o2, k))
|
|
11464
|
+
ar[ar.length] = k;
|
|
11465
|
+
return ar;
|
|
11466
|
+
};
|
|
11467
|
+
return ownKeys(o);
|
|
11468
|
+
};
|
|
11469
|
+
return function(mod) {
|
|
11470
|
+
if (mod && mod.__esModule)
|
|
11471
|
+
return mod;
|
|
11472
|
+
var result = {};
|
|
11473
|
+
if (mod != null) {
|
|
11474
|
+
for (var k = ownKeys(mod), i2 = 0; i2 < k.length; i2++)
|
|
11475
|
+
if (k[i2] !== "default")
|
|
11476
|
+
__createBinding(result, mod, k[i2]);
|
|
11477
|
+
}
|
|
11478
|
+
__setModuleDefault(result, mod);
|
|
11479
|
+
return result;
|
|
11480
|
+
};
|
|
11481
|
+
}();
|
|
11482
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11483
|
+
exports.DETACH_GROUP = exports.IS_WINDOWS = exports.execFile = exports.execFileSync = exports.execSync = exports.spawnSync = exports.spawn = void 0;
|
|
11484
|
+
exports.killProcessTree = killProcessTree3;
|
|
11485
|
+
var cp = __importStar(__require("child_process"));
|
|
11486
|
+
var isOpts = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
11487
|
+
function hide(args, insertAt2) {
|
|
11488
|
+
const out = args.slice();
|
|
11489
|
+
for (let i2 = 1; i2 < out.length; i2++) {
|
|
11490
|
+
if (isOpts(out[i2])) {
|
|
11491
|
+
out[i2] = { windowsHide: true, ...out[i2] };
|
|
11492
|
+
return out;
|
|
11493
|
+
}
|
|
11494
|
+
}
|
|
11495
|
+
let at = insertAt2;
|
|
11496
|
+
if (Array.isArray(out[1]))
|
|
11497
|
+
at = Math.max(at, 2);
|
|
11498
|
+
out.splice(at, 0, { windowsHide: true });
|
|
11499
|
+
return out;
|
|
11500
|
+
}
|
|
11501
|
+
exports.spawn = (...a) => cp.spawn(...hide(a, 1));
|
|
11502
|
+
exports.spawnSync = (...a) => cp.spawnSync(...hide(a, 1));
|
|
11503
|
+
exports.execSync = (...a) => cp.execSync(...hide(a, 1));
|
|
11504
|
+
exports.execFileSync = (...a) => cp.execFileSync(...hide(a, 1));
|
|
11505
|
+
exports.execFile = (...a) => cp.execFile(...hide(a, 1));
|
|
11506
|
+
exports.IS_WINDOWS = process.platform === "win32";
|
|
11507
|
+
exports.DETACH_GROUP = !exports.IS_WINDOWS;
|
|
11508
|
+
function killProcessTree3(pid, sig = "SIGTERM") {
|
|
11509
|
+
if (!pid)
|
|
11510
|
+
return;
|
|
11511
|
+
if (exports.IS_WINDOWS) {
|
|
11512
|
+
try {
|
|
11513
|
+
cp.spawnSync("taskkill", ["/PID", String(pid), "/T", "/F"], { windowsHide: true, stdio: "ignore", timeout: 5e3 });
|
|
11514
|
+
} catch {
|
|
11515
|
+
}
|
|
11516
|
+
return;
|
|
11517
|
+
}
|
|
11518
|
+
try {
|
|
11519
|
+
process.kill(-pid, sig);
|
|
11520
|
+
} catch {
|
|
11521
|
+
try {
|
|
11522
|
+
process.kill(pid, sig);
|
|
11523
|
+
} catch {
|
|
11524
|
+
}
|
|
11525
|
+
}
|
|
11526
|
+
}
|
|
11527
|
+
}
|
|
11528
|
+
});
|
|
11529
|
+
|
|
11396
11530
|
// ../core/dist/tools/sandbox.js
|
|
11397
11531
|
var require_sandbox = __commonJS({
|
|
11398
11532
|
"../core/dist/tools/sandbox.js"(exports) {
|
|
@@ -11444,7 +11578,7 @@ var require_sandbox = __commonJS({
|
|
|
11444
11578
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11445
11579
|
exports.parseSandboxConfig = parseSandboxConfig;
|
|
11446
11580
|
exports.wrapCommandForSandbox = wrapCommandForSandbox;
|
|
11447
|
-
var
|
|
11581
|
+
var proc_1 = require_proc();
|
|
11448
11582
|
var os25 = __importStar(__require("os"));
|
|
11449
11583
|
function parseSandboxConfig(raw) {
|
|
11450
11584
|
if (raw === void 0 || raw === null || raw === false || raw === "off")
|
|
@@ -11467,7 +11601,7 @@ var require_sandbox = __commonJS({
|
|
|
11467
11601
|
var _bwrapAvailable = false;
|
|
11468
11602
|
function commandExists3(cmd) {
|
|
11469
11603
|
try {
|
|
11470
|
-
(0,
|
|
11604
|
+
(0, proc_1.execSync)(process.platform === "win32" ? `where ${cmd}` : `command -v ${cmd}`, { stdio: "ignore" });
|
|
11471
11605
|
return true;
|
|
11472
11606
|
} catch {
|
|
11473
11607
|
return false;
|
|
@@ -15869,7 +16003,7 @@ var require_loader = __commonJS({
|
|
|
15869
16003
|
var fs33 = __importStar(__require("fs"));
|
|
15870
16004
|
var path36 = __importStar(__require("path"));
|
|
15871
16005
|
var os25 = __importStar(__require("os"));
|
|
15872
|
-
var
|
|
16006
|
+
var proc_1 = require_proc();
|
|
15873
16007
|
var index_1 = require_plugins();
|
|
15874
16008
|
var frontmatter_1 = require_frontmatter();
|
|
15875
16009
|
var agentTypes_1 = require_agentTypes();
|
|
@@ -15958,7 +16092,7 @@ var require_loader = __commonJS({
|
|
|
15958
16092
|
let out = body;
|
|
15959
16093
|
out = out.replace(/!`([^`]+)`/g, (_m, c) => {
|
|
15960
16094
|
try {
|
|
15961
|
-
const stdout = (0,
|
|
16095
|
+
const stdout = (0, proc_1.execSync)(c, {
|
|
15962
16096
|
cwd: workDir,
|
|
15963
16097
|
encoding: "utf-8",
|
|
15964
16098
|
timeout: 15e3,
|
|
@@ -16063,7 +16197,7 @@ var require_skills = __commonJS({
|
|
|
16063
16197
|
var fs33 = __importStar(__require("fs"));
|
|
16064
16198
|
var path36 = __importStar(__require("path"));
|
|
16065
16199
|
var os25 = __importStar(__require("os"));
|
|
16066
|
-
var
|
|
16200
|
+
var proc_1 = require_proc();
|
|
16067
16201
|
var index_1 = require_plugins();
|
|
16068
16202
|
var resolve_1 = require_resolve();
|
|
16069
16203
|
var loader_1 = require_loader();
|
|
@@ -16447,7 +16581,7 @@ var require_skills = __commonJS({
|
|
|
16447
16581
|
verdict = true;
|
|
16448
16582
|
} else {
|
|
16449
16583
|
try {
|
|
16450
|
-
const r2 = (0,
|
|
16584
|
+
const r2 = (0, proc_1.spawnSync)("git", ["-C", workDir, "check-ignore", "-q", "--", dir], {
|
|
16451
16585
|
stdio: "ignore",
|
|
16452
16586
|
timeout: 3e3
|
|
16453
16587
|
});
|
|
@@ -18583,7 +18717,7 @@ var require_executor = __commonJS({
|
|
|
18583
18717
|
var https3 = __importStar(__require("https"));
|
|
18584
18718
|
var http4 = __importStar(__require("http"));
|
|
18585
18719
|
var dns = __importStar(__require("dns"));
|
|
18586
|
-
var
|
|
18720
|
+
var proc_1 = require_proc();
|
|
18587
18721
|
var sandbox_1 = require_sandbox();
|
|
18588
18722
|
var auth_1 = require_auth();
|
|
18589
18723
|
var client_1 = require_client();
|
|
@@ -19105,11 +19239,11 @@ Resolve the conflict (remove <<<<<<< / ======= / >>>>>>> markers and keep the in
|
|
|
19105
19239
|
}
|
|
19106
19240
|
function startBackgroundShell(command, displayCommand, workDir, note) {
|
|
19107
19241
|
const id = `bg_${++_bgCounter}`;
|
|
19108
|
-
const child = (0,
|
|
19242
|
+
const child = (0, proc_1.spawn)(command, {
|
|
19109
19243
|
shell: true,
|
|
19110
19244
|
cwd: workDir ?? process.cwd(),
|
|
19111
19245
|
env: bashSpawnEnv(workDir),
|
|
19112
|
-
detached:
|
|
19246
|
+
detached: proc_1.DETACH_GROUP,
|
|
19113
19247
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19114
19248
|
});
|
|
19115
19249
|
const shell = {
|
|
@@ -19224,14 +19358,10 @@ ${fresh || "(no new output)"}${trunc}` };
|
|
|
19224
19358
|
if (shell.status === "running") {
|
|
19225
19359
|
shell.status = "killed";
|
|
19226
19360
|
const killTree = (sig) => {
|
|
19361
|
+
(0, proc_1.killProcessTree)(shell.child.pid, sig);
|
|
19227
19362
|
try {
|
|
19228
|
-
|
|
19229
|
-
process.kill(-shell.child.pid, sig);
|
|
19363
|
+
shell.child.kill(sig);
|
|
19230
19364
|
} catch {
|
|
19231
|
-
try {
|
|
19232
|
-
shell.child.kill(sig);
|
|
19233
|
-
} catch {
|
|
19234
|
-
}
|
|
19235
19365
|
}
|
|
19236
19366
|
};
|
|
19237
19367
|
killTree("SIGTERM");
|
|
@@ -19273,22 +19403,18 @@ ${fresh || "(no new output)"}${trunc}` };
|
|
|
19273
19403
|
${r2.output}`;
|
|
19274
19404
|
return r2;
|
|
19275
19405
|
};
|
|
19276
|
-
const child = (0,
|
|
19406
|
+
const child = (0, proc_1.spawn)(effectiveCommand, {
|
|
19277
19407
|
shell: true,
|
|
19278
19408
|
cwd: workDir ?? process.cwd(),
|
|
19279
19409
|
env: bashSpawnEnv(workDir),
|
|
19280
|
-
detached:
|
|
19410
|
+
detached: proc_1.DETACH_GROUP,
|
|
19281
19411
|
stdio: ["ignore", "pipe", "pipe"]
|
|
19282
19412
|
});
|
|
19283
19413
|
const killTree = (sig) => {
|
|
19414
|
+
(0, proc_1.killProcessTree)(child.pid, sig);
|
|
19284
19415
|
try {
|
|
19285
|
-
|
|
19286
|
-
process.kill(-child.pid, sig);
|
|
19416
|
+
child.kill(sig);
|
|
19287
19417
|
} catch {
|
|
19288
|
-
try {
|
|
19289
|
-
child.kill(sig);
|
|
19290
|
-
} catch {
|
|
19291
|
-
}
|
|
19292
19418
|
}
|
|
19293
19419
|
};
|
|
19294
19420
|
const HEAD_CHARS = Math.floor(MAX_OUTPUT_CHARS * 0.25);
|
|
@@ -19473,7 +19599,7 @@ ${(0, safeSlice_1.sliceSafeStart)(output, output.length - tailLen)}`;
|
|
|
19473
19599
|
let settled = false;
|
|
19474
19600
|
let child;
|
|
19475
19601
|
try {
|
|
19476
|
-
child = (0,
|
|
19602
|
+
child = (0, proc_1.spawn)(cmd, args, { cwd: opts.cwd, stdio: ["ignore", "pipe", "pipe"] });
|
|
19477
19603
|
} catch (e2) {
|
|
19478
19604
|
resolve19({ stdout: "", stderr: "", status: null, signal: null, error: e2 });
|
|
19479
19605
|
return;
|
|
@@ -19610,7 +19736,7 @@ ${(0, safeSlice_1.sliceSafeStart)(output, output.length - tailLen)}`;
|
|
|
19610
19736
|
for (const bin of ripgrepCandidates()) {
|
|
19611
19737
|
if (path36.isAbsolute(bin) && !fs33.existsSync(bin))
|
|
19612
19738
|
continue;
|
|
19613
|
-
const probe = (0,
|
|
19739
|
+
const probe = (0, proc_1.spawnSync)(bin, ["--version"], { encoding: "utf-8", timeout: 3e3 });
|
|
19614
19740
|
if (probe.status === 0) {
|
|
19615
19741
|
_rgBin = bin;
|
|
19616
19742
|
_rgAvailable = true;
|
|
@@ -20994,7 +21120,7 @@ ${lines.join("\n")}`;
|
|
|
20994
21120
|
return { error: "Missing required parameter: path" };
|
|
20995
21121
|
const token = (0, auth_1.getToken)();
|
|
20996
21122
|
if (!token)
|
|
20997
|
-
return { error: "Not authenticated. Run `
|
|
21123
|
+
return { error: "Not authenticated. Run `nex auth` first." };
|
|
20998
21124
|
let imageUrl;
|
|
20999
21125
|
let cost;
|
|
21000
21126
|
let balance;
|
|
@@ -21048,7 +21174,7 @@ ${lines.join("\n")}`;
|
|
|
21048
21174
|
return { error: "Missing required parameter: query" };
|
|
21049
21175
|
const token = (0, auth_1.getToken)();
|
|
21050
21176
|
if (!token)
|
|
21051
|
-
return { error: "Not authenticated. Run `
|
|
21177
|
+
return { error: "Not authenticated. Run `nex auth` first." };
|
|
21052
21178
|
let photos;
|
|
21053
21179
|
try {
|
|
21054
21180
|
const u = new URL(`${client_2.API_BASE}/api/code/assets/stock`);
|
|
@@ -21105,7 +21231,7 @@ ${lines.join("\n")}` };
|
|
|
21105
21231
|
return { error: "Missing required parameter: query" };
|
|
21106
21232
|
const token = (0, auth_1.getToken)();
|
|
21107
21233
|
if (!token)
|
|
21108
|
-
return { error: "Not authenticated. Run `
|
|
21234
|
+
return { error: "Not authenticated. Run `nex auth` first." };
|
|
21109
21235
|
try {
|
|
21110
21236
|
const r2 = await _httpsPost(`${client_2.API_BASE}/api/code/tools/web_search`, JSON.stringify({ query, ...(0, client_1.billingOverrideFields)() }), { "Content-Type": "application/json", Authorization: `Bearer ${token}` }, 3e4, abortSignal);
|
|
21111
21237
|
let json = {};
|
|
@@ -22643,7 +22769,7 @@ var require_worktree = __commonJS({
|
|
|
22643
22769
|
exports.findWorktreeByName = findWorktreeByName2;
|
|
22644
22770
|
var fs33 = __importStar(__require("fs"));
|
|
22645
22771
|
var path36 = __importStar(__require("path"));
|
|
22646
|
-
var
|
|
22772
|
+
var proc_1 = require_proc();
|
|
22647
22773
|
var crypto6 = __importStar(__require("crypto"));
|
|
22648
22774
|
var rules_1 = require_rules();
|
|
22649
22775
|
function prRefFromUrl(spec) {
|
|
@@ -22669,7 +22795,7 @@ var require_worktree = __commonJS({
|
|
|
22669
22795
|
}
|
|
22670
22796
|
function resolveFreshStartPoint(gitRoot) {
|
|
22671
22797
|
const run = (args) => {
|
|
22672
|
-
const r2 = (0,
|
|
22798
|
+
const r2 = (0, proc_1.spawnSync)("git", args, { cwd: gitRoot, encoding: "utf-8", timeout: 1e4 });
|
|
22673
22799
|
return { status: r2.status, stdout: r2.stdout };
|
|
22674
22800
|
};
|
|
22675
22801
|
const head = run(["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"]);
|
|
@@ -22698,7 +22824,7 @@ var require_worktree = __commonJS({
|
|
|
22698
22824
|
]);
|
|
22699
22825
|
function isGitRepo2(dir) {
|
|
22700
22826
|
try {
|
|
22701
|
-
const r2 = (0,
|
|
22827
|
+
const r2 = (0, proc_1.spawnSync)("git", ["rev-parse", "--show-toplevel"], {
|
|
22702
22828
|
cwd: dir,
|
|
22703
22829
|
encoding: "utf-8",
|
|
22704
22830
|
timeout: 5e3
|
|
@@ -22739,7 +22865,7 @@ var require_worktree = __commonJS({
|
|
|
22739
22865
|
if (!cmd)
|
|
22740
22866
|
return { ran: false, ok: false };
|
|
22741
22867
|
try {
|
|
22742
|
-
const r2 = (0,
|
|
22868
|
+
const r2 = (0, proc_1.spawnSync)(cmd, {
|
|
22743
22869
|
shell: true,
|
|
22744
22870
|
cwd: workDir,
|
|
22745
22871
|
timeout: 6e4,
|
|
@@ -22806,7 +22932,7 @@ var require_worktree = __commonJS({
|
|
|
22806
22932
|
let startPoint;
|
|
22807
22933
|
let baseLabel;
|
|
22808
22934
|
if (prRef) {
|
|
22809
|
-
const fetched = (0,
|
|
22935
|
+
const fetched = (0, proc_1.spawnSync)("git", ["fetch", "--no-tags", "origin", prRef.refspec], {
|
|
22810
22936
|
cwd: git.root,
|
|
22811
22937
|
encoding: "utf-8",
|
|
22812
22938
|
timeout: 12e4
|
|
@@ -22817,7 +22943,7 @@ var require_worktree = __commonJS({
|
|
|
22817
22943
|
error: `Could not fetch ${prRef.label} (${prRef.refspec}): ${(fetched.stderr ?? fetched.stdout ?? "").trim() || "unknown error"}`
|
|
22818
22944
|
};
|
|
22819
22945
|
}
|
|
22820
|
-
const head = (0,
|
|
22946
|
+
const head = (0, proc_1.spawnSync)("git", ["rev-parse", "FETCH_HEAD"], { cwd: git.root, encoding: "utf-8", timeout: 1e4 });
|
|
22821
22947
|
const sha = head.status === 0 ? (head.stdout ?? "").trim() : "";
|
|
22822
22948
|
if (!/^[0-9a-f]{40}$/i.test(sha)) {
|
|
22823
22949
|
return { ok: false, error: `Fetched ${prRef.label} but could not resolve its commit.` };
|
|
@@ -22834,7 +22960,7 @@ var require_worktree = __commonJS({
|
|
|
22834
22960
|
baseLabel = startPoint;
|
|
22835
22961
|
}
|
|
22836
22962
|
const args = ["worktree", "add", "-b", branch, worktreePath, ...startPoint ? [startPoint] : []];
|
|
22837
|
-
const r2 = (0,
|
|
22963
|
+
const r2 = (0, proc_1.spawnSync)("git", args, {
|
|
22838
22964
|
cwd: git.root,
|
|
22839
22965
|
encoding: "utf-8",
|
|
22840
22966
|
timeout: 3e4
|
|
@@ -22865,7 +22991,7 @@ var require_worktree = __commonJS({
|
|
|
22865
22991
|
function worktreeHasWork2(state) {
|
|
22866
22992
|
if (state.backend === "git") {
|
|
22867
22993
|
try {
|
|
22868
|
-
const status = (0,
|
|
22994
|
+
const status = (0, proc_1.spawnSync)("git", ["status", "--porcelain"], {
|
|
22869
22995
|
cwd: state.worktreePath,
|
|
22870
22996
|
encoding: "utf-8",
|
|
22871
22997
|
timeout: 1e4
|
|
@@ -22873,7 +22999,7 @@ var require_worktree = __commonJS({
|
|
|
22873
22999
|
const meaningfulLines = (status.stdout ?? "").split("\n").filter((line) => line.trim().length > 0 && !line.includes(METADATA_FILENAME));
|
|
22874
23000
|
if (meaningfulLines.length > 0)
|
|
22875
23001
|
return true;
|
|
22876
|
-
const unpushed = (0,
|
|
23002
|
+
const unpushed = (0, proc_1.spawnSync)("git", ["log", "@{u}..HEAD", "--oneline"], {
|
|
22877
23003
|
cwd: state.worktreePath,
|
|
22878
23004
|
encoding: "utf-8",
|
|
22879
23005
|
timeout: 1e4
|
|
@@ -22911,7 +23037,7 @@ var require_worktree = __commonJS({
|
|
|
22911
23037
|
fs33.unlinkSync(metadataPath(state.worktreePath));
|
|
22912
23038
|
} catch {
|
|
22913
23039
|
}
|
|
22914
|
-
const r2 = (0,
|
|
23040
|
+
const r2 = (0, proc_1.spawnSync)("git", ["worktree", "remove", state.worktreePath, ...opts.force ? ["--force"] : []], {
|
|
22915
23041
|
cwd: state.mainCheckout,
|
|
22916
23042
|
encoding: "utf-8",
|
|
22917
23043
|
timeout: 3e4
|
|
@@ -22923,7 +23049,7 @@ var require_worktree = __commonJS({
|
|
|
22923
23049
|
};
|
|
22924
23050
|
}
|
|
22925
23051
|
if (state.branch) {
|
|
22926
|
-
(0,
|
|
23052
|
+
(0, proc_1.spawnSync)("git", ["branch", "-D", state.branch], { cwd: state.mainCheckout, encoding: "utf-8", timeout: 1e4 });
|
|
22927
23053
|
}
|
|
22928
23054
|
return { ok: true };
|
|
22929
23055
|
}
|
|
@@ -23685,7 +23811,7 @@ var require_hooks = __commonJS({
|
|
|
23685
23811
|
var data_1 = require_data();
|
|
23686
23812
|
var fs33 = __importStar(__require("fs"));
|
|
23687
23813
|
var path36 = __importStar(__require("path"));
|
|
23688
|
-
var
|
|
23814
|
+
var proc_1 = require_proc();
|
|
23689
23815
|
function withAgentHooks(base, agent) {
|
|
23690
23816
|
if (!agent)
|
|
23691
23817
|
return base;
|
|
@@ -24019,7 +24145,7 @@ ${d.text}
|
|
|
24019
24145
|
};
|
|
24020
24146
|
let child;
|
|
24021
24147
|
try {
|
|
24022
|
-
child = (0,
|
|
24148
|
+
child = (0, proc_1.spawn)(command, {
|
|
24023
24149
|
shell: true,
|
|
24024
24150
|
cwd: opts.cwd,
|
|
24025
24151
|
env: opts.env ?? process.env,
|
|
@@ -28722,6 +28848,50 @@ ${s2.prompt}`;
|
|
|
28722
28848
|
var require_client2 = __commonJS({
|
|
28723
28849
|
"../core/dist/mcp/client.js"(exports) {
|
|
28724
28850
|
"use strict";
|
|
28851
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m2, k, k2) {
|
|
28852
|
+
if (k2 === void 0)
|
|
28853
|
+
k2 = k;
|
|
28854
|
+
var desc = Object.getOwnPropertyDescriptor(m2, k);
|
|
28855
|
+
if (!desc || ("get" in desc ? !m2.__esModule : desc.writable || desc.configurable)) {
|
|
28856
|
+
desc = { enumerable: true, get: function() {
|
|
28857
|
+
return m2[k];
|
|
28858
|
+
} };
|
|
28859
|
+
}
|
|
28860
|
+
Object.defineProperty(o, k2, desc);
|
|
28861
|
+
} : function(o, m2, k, k2) {
|
|
28862
|
+
if (k2 === void 0)
|
|
28863
|
+
k2 = k;
|
|
28864
|
+
o[k2] = m2[k];
|
|
28865
|
+
});
|
|
28866
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
28867
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28868
|
+
} : function(o, v) {
|
|
28869
|
+
o["default"] = v;
|
|
28870
|
+
});
|
|
28871
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
28872
|
+
var ownKeys = function(o) {
|
|
28873
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
28874
|
+
var ar = [];
|
|
28875
|
+
for (var k in o2)
|
|
28876
|
+
if (Object.prototype.hasOwnProperty.call(o2, k))
|
|
28877
|
+
ar[ar.length] = k;
|
|
28878
|
+
return ar;
|
|
28879
|
+
};
|
|
28880
|
+
return ownKeys(o);
|
|
28881
|
+
};
|
|
28882
|
+
return function(mod) {
|
|
28883
|
+
if (mod && mod.__esModule)
|
|
28884
|
+
return mod;
|
|
28885
|
+
var result = {};
|
|
28886
|
+
if (mod != null) {
|
|
28887
|
+
for (var k = ownKeys(mod), i2 = 0; i2 < k.length; i2++)
|
|
28888
|
+
if (k[i2] !== "default")
|
|
28889
|
+
__createBinding(result, mod, k[i2]);
|
|
28890
|
+
}
|
|
28891
|
+
__setModuleDefault(result, mod);
|
|
28892
|
+
return result;
|
|
28893
|
+
};
|
|
28894
|
+
}();
|
|
28725
28895
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28726
28896
|
exports.McpClient = exports.MCP_PROTOCOL_VERSION = exports.MCP_PROTOCOL_VERSIONS = exports.MCP_ELICITATION_CAPABILITY = exports.MAX_RESULT_SIZE_CHARS = void 0;
|
|
28727
28897
|
exports.toolResultSizeCap = toolResultSizeCap;
|
|
@@ -28730,7 +28900,8 @@ var require_client2 = __commonJS({
|
|
|
28730
28900
|
exports.elicitationCapability = elicitationCapability;
|
|
28731
28901
|
exports.normalizeElicitationRequest = normalizeElicitationRequest;
|
|
28732
28902
|
exports.serverRequestReply = serverRequestReply;
|
|
28733
|
-
var
|
|
28903
|
+
var path36 = __importStar(__require("path"));
|
|
28904
|
+
var proc_1 = require_proc();
|
|
28734
28905
|
exports.MAX_RESULT_SIZE_CHARS = 5e5;
|
|
28735
28906
|
function toolResultSizeCap(tool) {
|
|
28736
28907
|
const raw = (tool._meta ?? {})["anthropic/maxResultSizeChars"];
|
|
@@ -28843,10 +29014,11 @@ var require_client2 = __commonJS({
|
|
|
28843
29014
|
if (!this.config.command)
|
|
28844
29015
|
throw new Error(`MCP server "${this.name}" has no command (stdio transport requires one).`);
|
|
28845
29016
|
const env3 = { ...process.env, ...this.config.env ?? {} };
|
|
28846
|
-
|
|
29017
|
+
const needsShell = process.platform === "win32" && /^(npx|npm|pnpm|yarn|bunx)(\.cmd)?$/i.test(path36.basename(this.config.command));
|
|
29018
|
+
this._proc = (0, proc_1.spawn)(this.config.command, this.config.args ?? [], {
|
|
28847
29019
|
env: env3,
|
|
28848
29020
|
stdio: ["pipe", "pipe", "pipe"],
|
|
28849
|
-
shell:
|
|
29021
|
+
shell: needsShell
|
|
28850
29022
|
});
|
|
28851
29023
|
this._proc.stdout.on("data", (chunk) => {
|
|
28852
29024
|
this._buf += chunk.toString("utf-8");
|
|
@@ -30522,7 +30694,7 @@ var require_manager2 = __commonJS({
|
|
|
30522
30694
|
var os25 = __importStar(__require("os"));
|
|
30523
30695
|
var path36 = __importStar(__require("path"));
|
|
30524
30696
|
var crypto6 = __importStar(__require("crypto"));
|
|
30525
|
-
var
|
|
30697
|
+
var proc_1 = require_proc();
|
|
30526
30698
|
var MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024;
|
|
30527
30699
|
var MAX_PERSISTED_TURNS = 50;
|
|
30528
30700
|
var MUTATING_TOOLS = /* @__PURE__ */ new Set([
|
|
@@ -30663,7 +30835,7 @@ var require_manager2 = __commonJS({
|
|
|
30663
30835
|
}
|
|
30664
30836
|
tryGitStashCreate() {
|
|
30665
30837
|
try {
|
|
30666
|
-
const r2 = (0,
|
|
30838
|
+
const r2 = (0, proc_1.spawnSync)("git", ["stash", "create", "nexrall-checkpoint"], {
|
|
30667
30839
|
cwd: this.workDir,
|
|
30668
30840
|
encoding: "utf-8",
|
|
30669
30841
|
timeout: 1e4
|
|
@@ -31524,7 +31696,7 @@ var require_installer = __commonJS({
|
|
|
31524
31696
|
var fs33 = __importStar(__require("fs"));
|
|
31525
31697
|
var path36 = __importStar(__require("path"));
|
|
31526
31698
|
var os25 = __importStar(__require("os"));
|
|
31527
|
-
var
|
|
31699
|
+
var proc_1 = require_proc();
|
|
31528
31700
|
var client_1 = require_client();
|
|
31529
31701
|
var index_1 = require_plugins();
|
|
31530
31702
|
var data_1 = require_data();
|
|
@@ -31882,7 +32054,7 @@ var require_installer = __commonJS({
|
|
|
31882
32054
|
}
|
|
31883
32055
|
function extractTarball(tarFile, destDir) {
|
|
31884
32056
|
fs33.mkdirSync(destDir, { recursive: true });
|
|
31885
|
-
(0,
|
|
32057
|
+
(0, proc_1.execFileSync)("tar", ["-xzf", tarFile, "-C", destDir], { stdio: "pipe" });
|
|
31886
32058
|
const entries = fs33.readdirSync(destDir).filter((e2) => {
|
|
31887
32059
|
try {
|
|
31888
32060
|
return fs33.statSync(path36.join(destDir, e2)).isDirectory();
|
|
@@ -32939,7 +33111,7 @@ var require_monitor = __commonJS({
|
|
|
32939
33111
|
exports.stopMonitor = stopMonitor;
|
|
32940
33112
|
exports.stopAllMonitors = stopAllMonitors;
|
|
32941
33113
|
exports.executeMonitorTool = executeMonitorTool2;
|
|
32942
|
-
var
|
|
33114
|
+
var proc_1 = require_proc();
|
|
32943
33115
|
exports.MONITOR_TOOL_NAME = "monitor";
|
|
32944
33116
|
exports.DEFAULT_TIMEOUT_MS = 5 * 6e4;
|
|
32945
33117
|
exports.MAX_TIMEOUT_MS = 30 * 6e4;
|
|
@@ -32967,10 +33139,8 @@ var require_monitor = __commonJS({
|
|
|
32967
33139
|
}
|
|
32968
33140
|
function killTree(m2) {
|
|
32969
33141
|
try {
|
|
32970
|
-
|
|
32971
|
-
|
|
32972
|
-
else
|
|
32973
|
-
m2.child.kill("SIGTERM");
|
|
33142
|
+
(0, proc_1.killProcessTree)(m2.child.pid, "SIGTERM");
|
|
33143
|
+
m2.child.kill("SIGTERM");
|
|
32974
33144
|
} catch {
|
|
32975
33145
|
}
|
|
32976
33146
|
if (m2.killTimer)
|
|
@@ -32978,8 +33148,7 @@ var require_monitor = __commonJS({
|
|
|
32978
33148
|
m2.killTimer = setTimeout(() => {
|
|
32979
33149
|
m2.killTimer = null;
|
|
32980
33150
|
try {
|
|
32981
|
-
|
|
32982
|
-
process.kill(-m2.child.pid, "SIGKILL");
|
|
33151
|
+
(0, proc_1.killProcessTree)(m2.child.pid, "SIGKILL");
|
|
32983
33152
|
} catch {
|
|
32984
33153
|
}
|
|
32985
33154
|
}, m2.timing.killGraceMs);
|
|
@@ -33100,7 +33269,7 @@ var require_monitor = __commonJS({
|
|
|
33100
33269
|
const now = opts.now ?? Date.now;
|
|
33101
33270
|
const id = `mon${++_seq}`;
|
|
33102
33271
|
const label = opts.label && String(opts.label).trim().slice(0, 60) || command.slice(0, 60);
|
|
33103
|
-
const spawnFn = opts.spawnFn ??
|
|
33272
|
+
const spawnFn = opts.spawnFn ?? proc_1.spawn;
|
|
33104
33273
|
let child;
|
|
33105
33274
|
try {
|
|
33106
33275
|
child = spawnFn(command, {
|
|
@@ -33110,7 +33279,7 @@ var require_monitor = __commonJS({
|
|
|
33110
33279
|
// Own process group so the deadline kill reaches `sh -c "tail -f | grep"`
|
|
33111
33280
|
// trees; stdin closed so a watcher that reads blocks on nothing and gets
|
|
33112
33281
|
// EOF instead of hanging the watch until its deadline.
|
|
33113
|
-
detached:
|
|
33282
|
+
detached: proc_1.DETACH_GROUP,
|
|
33114
33283
|
stdio: ["ignore", "pipe", "pipe"]
|
|
33115
33284
|
});
|
|
33116
33285
|
} catch (e2) {
|
|
@@ -33206,8 +33375,7 @@ var require_monitor = __commonJS({
|
|
|
33206
33375
|
if (silent) {
|
|
33207
33376
|
const m2 = _monitors.get(id);
|
|
33208
33377
|
try {
|
|
33209
|
-
|
|
33210
|
-
process.kill(-m2.child.pid, "SIGKILL");
|
|
33378
|
+
(0, proc_1.killProcessTree)(m2.child.pid, "SIGKILL");
|
|
33211
33379
|
} catch {
|
|
33212
33380
|
}
|
|
33213
33381
|
finalize(m2);
|
|
@@ -33964,12 +34132,12 @@ var require_collect = __commonJS({
|
|
|
33964
34132
|
exports.gitDiffRaw = gitDiffRaw2;
|
|
33965
34133
|
exports.collectChangedFiles = collectChangedFiles2;
|
|
33966
34134
|
exports.gitBranch = gitBranch2;
|
|
33967
|
-
var
|
|
34135
|
+
var proc_1 = require_proc();
|
|
33968
34136
|
var fs33 = __importStar(__require("fs"));
|
|
33969
34137
|
var path36 = __importStar(__require("path"));
|
|
33970
34138
|
var diffView_1 = require_diffView();
|
|
33971
34139
|
function gitDiffRaw2(cwd2) {
|
|
33972
|
-
const run = (args) => (0,
|
|
34140
|
+
const run = (args) => (0, proc_1.execFileSync)("git", args, {
|
|
33973
34141
|
cwd: cwd2,
|
|
33974
34142
|
encoding: "utf8",
|
|
33975
34143
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -47693,7 +47861,7 @@ var require_mergeAssistant = __commonJS({
|
|
|
47693
47861
|
exports.parseMergeTree = parseMergeTree2;
|
|
47694
47862
|
exports.checkBranchMerges = checkBranchMerges2;
|
|
47695
47863
|
exports.formatMergePanel = formatMergePanel2;
|
|
47696
|
-
var
|
|
47864
|
+
var proc_1 = require_proc();
|
|
47697
47865
|
var globalSearch_1 = require_globalSearch();
|
|
47698
47866
|
var collect_1 = require_collect();
|
|
47699
47867
|
exports.MAX_NODE_FILES = 40;
|
|
@@ -47709,7 +47877,7 @@ var require_mergeAssistant = __commonJS({
|
|
|
47709
47877
|
}
|
|
47710
47878
|
var gitRunnerForMerge2 = (cwd2, args) => {
|
|
47711
47879
|
try {
|
|
47712
|
-
const stdout = (0,
|
|
47880
|
+
const stdout = (0, proc_1.execFileSync)("git", args, {
|
|
47713
47881
|
cwd: cwd2,
|
|
47714
47882
|
encoding: "utf-8",
|
|
47715
47883
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -78310,7 +78478,7 @@ import * as fs32 from "fs";
|
|
|
78310
78478
|
import { createRequire as createRequire2 } from "module";
|
|
78311
78479
|
|
|
78312
78480
|
// src/commands/auth.ts
|
|
78313
|
-
var
|
|
78481
|
+
var import_code_core2 = __toESM(require_dist2(), 1);
|
|
78314
78482
|
import * as readline from "readline";
|
|
78315
78483
|
|
|
78316
78484
|
// ../../node_modules/.pnpm/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
|
|
@@ -79626,7 +79794,452 @@ function formatUsage(outputTokens) {
|
|
|
79626
79794
|
return paint.dim(`\u2193 ${tok} tokens`);
|
|
79627
79795
|
}
|
|
79628
79796
|
|
|
79797
|
+
// src/mcp/oauth.ts
|
|
79798
|
+
var import_proc = __toESM(require_proc(), 1);
|
|
79799
|
+
var import_code_core = __toESM(require_dist2(), 1);
|
|
79800
|
+
import * as fs2 from "fs";
|
|
79801
|
+
import * as os2 from "os";
|
|
79802
|
+
import * as path from "path";
|
|
79803
|
+
import * as http3 from "http";
|
|
79804
|
+
import * as crypto from "crypto";
|
|
79805
|
+
var CALLBACK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
79806
|
+
function tokensFile(env3 = process.env) {
|
|
79807
|
+
return env3.NEXRALL_MCP_AUTH_FILE || path.join(os2.homedir(), ".nexrall", "mcp-auth.json");
|
|
79808
|
+
}
|
|
79809
|
+
function readStore(file) {
|
|
79810
|
+
try {
|
|
79811
|
+
const parsed = JSON.parse(fs2.readFileSync(file, "utf-8"));
|
|
79812
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
79813
|
+
return {};
|
|
79814
|
+
const out = {};
|
|
79815
|
+
for (const [k, v] of Object.entries(parsed)) {
|
|
79816
|
+
const b = v;
|
|
79817
|
+
if (b && typeof b.access_token === "string" && typeof b.token_endpoint === "string")
|
|
79818
|
+
out[k] = b;
|
|
79819
|
+
}
|
|
79820
|
+
return out;
|
|
79821
|
+
} catch {
|
|
79822
|
+
return {};
|
|
79823
|
+
}
|
|
79824
|
+
}
|
|
79825
|
+
function writeStore(file, store) {
|
|
79826
|
+
fs2.mkdirSync(path.dirname(file), { recursive: true });
|
|
79827
|
+
fs2.writeFileSync(file, JSON.stringify(store, null, 2), { mode: 384 });
|
|
79828
|
+
try {
|
|
79829
|
+
fs2.chmodSync(file, 384);
|
|
79830
|
+
} catch {
|
|
79831
|
+
}
|
|
79832
|
+
}
|
|
79833
|
+
function loadToken(server, file = tokensFile()) {
|
|
79834
|
+
return readStore(file)[server] ?? null;
|
|
79835
|
+
}
|
|
79836
|
+
function saveToken(server, bundle, file = tokensFile()) {
|
|
79837
|
+
const store = readStore(file);
|
|
79838
|
+
store[server] = bundle;
|
|
79839
|
+
writeStore(file, store);
|
|
79840
|
+
}
|
|
79841
|
+
function clearToken(server, file = tokensFile()) {
|
|
79842
|
+
const store = readStore(file);
|
|
79843
|
+
if (!(server in store))
|
|
79844
|
+
return false;
|
|
79845
|
+
delete store[server];
|
|
79846
|
+
writeStore(file, store);
|
|
79847
|
+
return true;
|
|
79848
|
+
}
|
|
79849
|
+
function defaultFetch() {
|
|
79850
|
+
const f3 = globalThis.fetch;
|
|
79851
|
+
if (typeof f3 !== "function")
|
|
79852
|
+
throw new Error("global fetch unavailable \u2014 Node 18+ is required for MCP OAuth");
|
|
79853
|
+
return f3;
|
|
79854
|
+
}
|
|
79855
|
+
async function getValidAccessToken(server, opts = {}) {
|
|
79856
|
+
const file = opts.file ?? tokensFile();
|
|
79857
|
+
const bundle = loadToken(server, file);
|
|
79858
|
+
if (!bundle)
|
|
79859
|
+
return null;
|
|
79860
|
+
const fresh = !bundle.expires_at || bundle.expires_at - Date.now() > 6e4;
|
|
79861
|
+
if (fresh || !bundle.refresh_token)
|
|
79862
|
+
return bundle.access_token;
|
|
79863
|
+
try {
|
|
79864
|
+
const refreshed = await refreshAccessToken(bundle, opts.fetchImpl ?? defaultFetch());
|
|
79865
|
+
saveToken(server, refreshed, file);
|
|
79866
|
+
return refreshed.access_token;
|
|
79867
|
+
} catch {
|
|
79868
|
+
return bundle.access_token;
|
|
79869
|
+
}
|
|
79870
|
+
}
|
|
79871
|
+
function parseResourceMetadataUrl(wwwAuthenticate) {
|
|
79872
|
+
const m2 = /resource_metadata\s*=\s*"([^"]+)"/i.exec(wwwAuthenticate || "");
|
|
79873
|
+
return m2 ? m2[1] : null;
|
|
79874
|
+
}
|
|
79875
|
+
function protectedResourceCandidates(serverUrl) {
|
|
79876
|
+
const u = new URL(serverUrl);
|
|
79877
|
+
const base = u.origin;
|
|
79878
|
+
const p = u.pathname.replace(/\/$/, "");
|
|
79879
|
+
return [
|
|
79880
|
+
...p ? [`${base}/.well-known/oauth-protected-resource${p}`] : [],
|
|
79881
|
+
`${base}/.well-known/oauth-protected-resource`
|
|
79882
|
+
];
|
|
79883
|
+
}
|
|
79884
|
+
function authServerCandidates(authServer) {
|
|
79885
|
+
const u = new URL(authServer);
|
|
79886
|
+
const base = u.origin;
|
|
79887
|
+
const p = u.pathname.replace(/\/$/, "");
|
|
79888
|
+
const root = authServer.replace(/\/$/, "");
|
|
79889
|
+
return [
|
|
79890
|
+
`${base}/.well-known/oauth-authorization-server${p}`,
|
|
79891
|
+
`${base}/.well-known/openid-configuration${p}`,
|
|
79892
|
+
`${root}/.well-known/oauth-authorization-server`,
|
|
79893
|
+
`${root}/.well-known/openid-configuration`
|
|
79894
|
+
];
|
|
79895
|
+
}
|
|
79896
|
+
function buildAuthorizeUrl(meta, p) {
|
|
79897
|
+
const url = new URL(meta.authorization_endpoint);
|
|
79898
|
+
url.searchParams.set("response_type", "code");
|
|
79899
|
+
url.searchParams.set("client_id", p.clientId);
|
|
79900
|
+
url.searchParams.set("redirect_uri", p.redirectUri);
|
|
79901
|
+
url.searchParams.set("state", p.state);
|
|
79902
|
+
url.searchParams.set("code_challenge", p.codeChallenge);
|
|
79903
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
79904
|
+
url.searchParams.set("resource", meta.resource);
|
|
79905
|
+
if (meta.scope)
|
|
79906
|
+
url.searchParams.set("scope", meta.scope);
|
|
79907
|
+
return url.toString();
|
|
79908
|
+
}
|
|
79909
|
+
function toBundle(data, p) {
|
|
79910
|
+
const accessToken = data.access_token;
|
|
79911
|
+
if (!accessToken)
|
|
79912
|
+
throw new Error("Token response had no access_token");
|
|
79913
|
+
const expiresIn = typeof data.expires_in === "number" ? data.expires_in : void 0;
|
|
79914
|
+
return {
|
|
79915
|
+
access_token: accessToken,
|
|
79916
|
+
refresh_token: data.refresh_token ?? p.prevRefresh,
|
|
79917
|
+
expires_at: expiresIn ? Date.now() + expiresIn * 1e3 : void 0,
|
|
79918
|
+
token_endpoint: p.tokenEndpoint,
|
|
79919
|
+
client_id: p.clientId,
|
|
79920
|
+
client_secret: p.clientSecret,
|
|
79921
|
+
resource: p.resource,
|
|
79922
|
+
scope: data.scope ?? p.scope
|
|
79923
|
+
};
|
|
79924
|
+
}
|
|
79925
|
+
async function fetchJsonSafe(f3, url) {
|
|
79926
|
+
try {
|
|
79927
|
+
const resp = await f3(url, { headers: { Accept: "application/json" } });
|
|
79928
|
+
if (!resp.ok)
|
|
79929
|
+
return null;
|
|
79930
|
+
return await resp.json();
|
|
79931
|
+
} catch {
|
|
79932
|
+
return null;
|
|
79933
|
+
}
|
|
79934
|
+
}
|
|
79935
|
+
async function discover(serverUrl, wwwAuthenticate, f3 = defaultFetch()) {
|
|
79936
|
+
const origin = new URL(serverUrl).origin;
|
|
79937
|
+
let authServer = null;
|
|
79938
|
+
let resource = serverUrl;
|
|
79939
|
+
let scope;
|
|
79940
|
+
const prmCandidates = [parseResourceMetadataUrl(wwwAuthenticate), ...protectedResourceCandidates(serverUrl)].filter(
|
|
79941
|
+
(u) => Boolean(u)
|
|
79942
|
+
);
|
|
79943
|
+
let prm = null;
|
|
79944
|
+
for (const url of new Set(prmCandidates)) {
|
|
79945
|
+
prm = await fetchJsonSafe(f3, url);
|
|
79946
|
+
if (prm)
|
|
79947
|
+
break;
|
|
79948
|
+
}
|
|
79949
|
+
if (prm) {
|
|
79950
|
+
const servers = prm.authorization_servers;
|
|
79951
|
+
if (Array.isArray(servers) && servers.length)
|
|
79952
|
+
authServer = servers[0];
|
|
79953
|
+
if (typeof prm.resource === "string")
|
|
79954
|
+
resource = prm.resource;
|
|
79955
|
+
const scopes = prm.scopes_supported;
|
|
79956
|
+
if (Array.isArray(scopes) && scopes.length)
|
|
79957
|
+
scope = scopes.join(" ");
|
|
79958
|
+
}
|
|
79959
|
+
if (!authServer)
|
|
79960
|
+
authServer = origin;
|
|
79961
|
+
let asm = null;
|
|
79962
|
+
for (const url of authServerCandidates(authServer)) {
|
|
79963
|
+
asm = await fetchJsonSafe(f3, url);
|
|
79964
|
+
if (asm && asm.authorization_endpoint && asm.token_endpoint)
|
|
79965
|
+
break;
|
|
79966
|
+
asm = null;
|
|
79967
|
+
}
|
|
79968
|
+
if (!asm)
|
|
79969
|
+
throw new Error(`No OAuth metadata found for authorization server ${authServer}`);
|
|
79970
|
+
return {
|
|
79971
|
+
authorization_endpoint: asm.authorization_endpoint,
|
|
79972
|
+
token_endpoint: asm.token_endpoint,
|
|
79973
|
+
registration_endpoint: asm.registration_endpoint,
|
|
79974
|
+
resource,
|
|
79975
|
+
scope
|
|
79976
|
+
};
|
|
79977
|
+
}
|
|
79978
|
+
async function registerClient(meta, redirectUri, f3) {
|
|
79979
|
+
if (!meta.registration_endpoint) {
|
|
79980
|
+
throw new Error(
|
|
79981
|
+
'Authorization server does not support dynamic client registration; a client_id must be configured manually \u2014 create an OAuth client for this server, then re-run `nex mcp login <server> --client-id <id> [--client-secret <secret>]` (or set "clientId" / "clientSecret" in its mcp.json entry).'
|
|
79982
|
+
);
|
|
79983
|
+
}
|
|
79984
|
+
const resp = await f3(meta.registration_endpoint, {
|
|
79985
|
+
method: "POST",
|
|
79986
|
+
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
79987
|
+
body: JSON.stringify({
|
|
79988
|
+
client_name: "Nexrall Code CLI",
|
|
79989
|
+
redirect_uris: [redirectUri],
|
|
79990
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
79991
|
+
response_types: ["code"],
|
|
79992
|
+
token_endpoint_auth_method: "none",
|
|
79993
|
+
scope: meta.scope
|
|
79994
|
+
})
|
|
79995
|
+
});
|
|
79996
|
+
if (!resp.ok)
|
|
79997
|
+
throw new Error(`Client registration failed (HTTP ${resp.status})`);
|
|
79998
|
+
const data = await resp.json();
|
|
79999
|
+
if (!data.client_id)
|
|
80000
|
+
throw new Error("Client registration returned no client_id");
|
|
80001
|
+
return data.client_id;
|
|
80002
|
+
}
|
|
80003
|
+
async function postToken(tokenEndpoint, body, f3) {
|
|
80004
|
+
const resp = await f3(tokenEndpoint, {
|
|
80005
|
+
method: "POST",
|
|
80006
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
80007
|
+
body: body.toString()
|
|
80008
|
+
});
|
|
80009
|
+
if (!resp.ok) {
|
|
80010
|
+
const txt = await resp.text().catch(() => "");
|
|
80011
|
+
throw new Error(`Token endpoint error (HTTP ${resp.status})${txt ? `: ${txt.slice(0, 200)}` : ""}`);
|
|
80012
|
+
}
|
|
80013
|
+
return await resp.json();
|
|
80014
|
+
}
|
|
80015
|
+
async function exchangeCode(meta, clientId, clientSecret, code, verifier, redirectUri, f3) {
|
|
80016
|
+
const body = new URLSearchParams({
|
|
80017
|
+
grant_type: "authorization_code",
|
|
80018
|
+
code,
|
|
80019
|
+
redirect_uri: redirectUri,
|
|
80020
|
+
client_id: clientId,
|
|
80021
|
+
code_verifier: verifier,
|
|
80022
|
+
resource: meta.resource
|
|
80023
|
+
});
|
|
80024
|
+
if (clientSecret)
|
|
80025
|
+
body.set("client_secret", clientSecret);
|
|
80026
|
+
const data = await postToken(meta.token_endpoint, body, f3);
|
|
80027
|
+
return toBundle(data, {
|
|
80028
|
+
tokenEndpoint: meta.token_endpoint,
|
|
80029
|
+
clientId,
|
|
80030
|
+
clientSecret,
|
|
80031
|
+
resource: meta.resource,
|
|
80032
|
+
scope: meta.scope
|
|
80033
|
+
});
|
|
80034
|
+
}
|
|
80035
|
+
async function refreshAccessToken(bundle, f3) {
|
|
80036
|
+
const body = new URLSearchParams({
|
|
80037
|
+
grant_type: "refresh_token",
|
|
80038
|
+
refresh_token: bundle.refresh_token,
|
|
80039
|
+
client_id: bundle.client_id,
|
|
80040
|
+
resource: bundle.resource
|
|
80041
|
+
});
|
|
80042
|
+
if (bundle.client_secret)
|
|
80043
|
+
body.set("client_secret", bundle.client_secret);
|
|
80044
|
+
const data = await postToken(bundle.token_endpoint, body, f3);
|
|
80045
|
+
return toBundle(data, {
|
|
80046
|
+
tokenEndpoint: bundle.token_endpoint,
|
|
80047
|
+
clientId: bundle.client_id,
|
|
80048
|
+
clientSecret: bundle.client_secret,
|
|
80049
|
+
resource: bundle.resource,
|
|
80050
|
+
scope: bundle.scope,
|
|
80051
|
+
prevRefresh: bundle.refresh_token
|
|
80052
|
+
});
|
|
80053
|
+
}
|
|
80054
|
+
function startLoopback() {
|
|
80055
|
+
return new Promise((resolve19, reject) => {
|
|
80056
|
+
let resolveCode;
|
|
80057
|
+
let rejectCode;
|
|
80058
|
+
const codePromise = new Promise((res, rej) => {
|
|
80059
|
+
resolveCode = res;
|
|
80060
|
+
rejectCode = rej;
|
|
80061
|
+
});
|
|
80062
|
+
codePromise.catch(() => void 0);
|
|
80063
|
+
const server = http3.createServer((req, res) => {
|
|
80064
|
+
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
80065
|
+
if (url.pathname !== "/callback") {
|
|
80066
|
+
res.writeHead(404);
|
|
80067
|
+
res.end();
|
|
80068
|
+
return;
|
|
80069
|
+
}
|
|
80070
|
+
const code = url.searchParams.get("code");
|
|
80071
|
+
const state = url.searchParams.get("state");
|
|
80072
|
+
const error = url.searchParams.get("error");
|
|
80073
|
+
res.writeHead(200, { "Content-Type": "text/html", Connection: "close" });
|
|
80074
|
+
res.end(
|
|
80075
|
+
`<!doctype html><html><body style="font-family:system-ui;text-align:center;padding:40px"><h2>${error || !code ? "Authentication failed" : "Authentication complete"}</h2><p>You can close this tab and return to the terminal.</p></body></html>`
|
|
80076
|
+
);
|
|
80077
|
+
if (error) {
|
|
80078
|
+
rejectCode(new Error(`Authorization denied: ${error}`));
|
|
80079
|
+
return;
|
|
80080
|
+
}
|
|
80081
|
+
if (!code) {
|
|
80082
|
+
rejectCode(new Error("No authorization code in redirect"));
|
|
80083
|
+
return;
|
|
80084
|
+
}
|
|
80085
|
+
resolveCode({ code, state });
|
|
80086
|
+
});
|
|
80087
|
+
server.on("error", reject);
|
|
80088
|
+
server.listen(0, "127.0.0.1", () => {
|
|
80089
|
+
const port = server.address().port;
|
|
80090
|
+
resolve19({
|
|
80091
|
+
port,
|
|
80092
|
+
waitForCode(expectedState) {
|
|
80093
|
+
const timeout = setTimeout(
|
|
80094
|
+
() => rejectCode(new Error("Timed out waiting for authorization")),
|
|
80095
|
+
CALLBACK_TIMEOUT_MS
|
|
80096
|
+
);
|
|
80097
|
+
return codePromise.then(
|
|
80098
|
+
({ code, state }) => {
|
|
80099
|
+
clearTimeout(timeout);
|
|
80100
|
+
if (state !== expectedState)
|
|
80101
|
+
throw new Error("OAuth state mismatch \u2014 possible CSRF, aborting");
|
|
80102
|
+
return code;
|
|
80103
|
+
},
|
|
80104
|
+
// A denial must clear the timer too: otherwise `nex mcp login` reports the
|
|
80105
|
+
// failure but the process sits on a 5-minute keep-alive before exiting.
|
|
80106
|
+
(err) => {
|
|
80107
|
+
clearTimeout(timeout);
|
|
80108
|
+
throw err;
|
|
80109
|
+
}
|
|
80110
|
+
);
|
|
80111
|
+
},
|
|
80112
|
+
close() {
|
|
80113
|
+
try {
|
|
80114
|
+
server.closeAllConnections?.();
|
|
80115
|
+
} catch {
|
|
80116
|
+
}
|
|
80117
|
+
try {
|
|
80118
|
+
server.close();
|
|
80119
|
+
} catch {
|
|
80120
|
+
}
|
|
80121
|
+
}
|
|
80122
|
+
});
|
|
80123
|
+
});
|
|
80124
|
+
});
|
|
80125
|
+
}
|
|
80126
|
+
function b64url(buf) {
|
|
80127
|
+
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
80128
|
+
}
|
|
80129
|
+
function openInBrowser(url) {
|
|
80130
|
+
const win = process.platform === "win32";
|
|
80131
|
+
const cmd = process.platform === "darwin" ? "open" : win ? "rundll32" : "xdg-open";
|
|
80132
|
+
const args = win ? ["url.dll,FileProtocolHandler", url] : [url];
|
|
80133
|
+
try {
|
|
80134
|
+
const child = (0, import_proc.spawn)(cmd, args, { stdio: "ignore", detached: !win });
|
|
80135
|
+
child.on("error", () => void 0);
|
|
80136
|
+
child.unref();
|
|
80137
|
+
} catch {
|
|
80138
|
+
}
|
|
80139
|
+
}
|
|
80140
|
+
async function probeAuthChallenge(serverUrl, f3 = defaultFetch()) {
|
|
80141
|
+
const steps = [
|
|
80142
|
+
{
|
|
80143
|
+
method: "initialize",
|
|
80144
|
+
params: {
|
|
80145
|
+
protocolVersion: import_code_core.MCP_PROTOCOL_VERSION,
|
|
80146
|
+
capabilities: {},
|
|
80147
|
+
clientInfo: { name: "nexrall-code", version: "1.0" }
|
|
80148
|
+
}
|
|
80149
|
+
},
|
|
80150
|
+
{ method: "tools/list", params: {} }
|
|
80151
|
+
];
|
|
80152
|
+
for (const { method, params } of steps) {
|
|
80153
|
+
try {
|
|
80154
|
+
const resp = await f3(serverUrl, {
|
|
80155
|
+
method: "POST",
|
|
80156
|
+
headers: { "Content-Type": "application/json", Accept: "application/json, text/event-stream" },
|
|
80157
|
+
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
|
|
80158
|
+
});
|
|
80159
|
+
const challenge = resp.headers?.get("www-authenticate") ?? "";
|
|
80160
|
+
if (challenge)
|
|
80161
|
+
return challenge;
|
|
80162
|
+
} catch {
|
|
80163
|
+
return "";
|
|
80164
|
+
}
|
|
80165
|
+
}
|
|
80166
|
+
return "";
|
|
80167
|
+
}
|
|
80168
|
+
async function authorizeServer(o) {
|
|
80169
|
+
const f3 = o.fetchImpl ?? defaultFetch();
|
|
80170
|
+
const challenge = o.wwwAuthenticate ?? await probeAuthChallenge(o.serverUrl, f3);
|
|
80171
|
+
const meta = await discover(o.serverUrl, challenge, f3);
|
|
80172
|
+
const scope = [meta.scope, (0, import_code_core.parseOAuthChallenge)(challenge).scope, o.extraScope].map((s2) => s2?.trim()).filter((s2) => Boolean(s2)).join(" ").split(/\s+/).filter((s2, i2, a) => Boolean(s2) && a.indexOf(s2) === i2).join(" ");
|
|
80173
|
+
meta.scope = scope || void 0;
|
|
80174
|
+
const loopback = await startLoopback();
|
|
80175
|
+
const redirectUri = `http://127.0.0.1:${loopback.port}/callback`;
|
|
80176
|
+
try {
|
|
80177
|
+
const creds = o.credentials ?? {};
|
|
80178
|
+
let clientId;
|
|
80179
|
+
if (creds.clientId) {
|
|
80180
|
+
clientId = creds.clientId;
|
|
80181
|
+
o.onStep?.("Using the OAuth client configured for this server\u2026");
|
|
80182
|
+
} else {
|
|
80183
|
+
o.onStep?.(`Registering with ${new URL(meta.token_endpoint).origin}\u2026`);
|
|
80184
|
+
clientId = await registerClient(meta, redirectUri, f3);
|
|
80185
|
+
}
|
|
80186
|
+
const verifier = b64url(crypto.randomBytes(32));
|
|
80187
|
+
const challengeB64 = b64url(crypto.createHash("sha256").update(verifier).digest());
|
|
80188
|
+
const state = b64url(crypto.randomBytes(16));
|
|
80189
|
+
const authUrl = buildAuthorizeUrl(meta, { clientId, redirectUri, codeChallenge: challengeB64, state });
|
|
80190
|
+
o.onStep?.("Opening your browser to authorize\u2026");
|
|
80191
|
+
await o.openUrl(authUrl);
|
|
80192
|
+
const code = await loopback.waitForCode(state);
|
|
80193
|
+
const bundle = await exchangeCode(meta, clientId, creds.clientSecret, code, verifier, redirectUri, f3);
|
|
80194
|
+
saveToken(o.server, bundle, o.file ?? tokensFile());
|
|
80195
|
+
} finally {
|
|
80196
|
+
loopback.close();
|
|
80197
|
+
}
|
|
80198
|
+
}
|
|
80199
|
+
var isRemote = (cfg) => cfg.type === "http" || cfg.type === "sse" || !cfg.command && !!cfg.url;
|
|
80200
|
+
async function injectMcpTokens(config, opts = {}) {
|
|
80201
|
+
const file = opts.file ?? tokensFile();
|
|
80202
|
+
const injected = [];
|
|
80203
|
+
for (const [name, cfg] of Object.entries(config.mcpServers ?? {})) {
|
|
80204
|
+
if (!isRemote(cfg))
|
|
80205
|
+
continue;
|
|
80206
|
+
const hasAuth = cfg.headers && Object.keys(cfg.headers).some((h2) => h2.toLowerCase() === "authorization");
|
|
80207
|
+
if (hasAuth)
|
|
80208
|
+
continue;
|
|
80209
|
+
let token;
|
|
80210
|
+
try {
|
|
80211
|
+
token = await getValidAccessToken(name, { file, fetchImpl: opts.fetchImpl });
|
|
80212
|
+
} catch {
|
|
80213
|
+
token = null;
|
|
80214
|
+
}
|
|
80215
|
+
if (!token)
|
|
80216
|
+
continue;
|
|
80217
|
+
cfg.headers = { ...cfg.headers ?? {}, Authorization: `Bearer ${token}` };
|
|
80218
|
+
injected.push(name);
|
|
80219
|
+
}
|
|
80220
|
+
return injected;
|
|
80221
|
+
}
|
|
80222
|
+
|
|
79629
80223
|
// src/commands/auth.ts
|
|
80224
|
+
var AUTH_APP_URL = "https://app.nexrall.com";
|
|
80225
|
+
function browserAuthUrl() {
|
|
80226
|
+
return `${AUTH_APP_URL}/auth/vscode?cli=1`;
|
|
80227
|
+
}
|
|
80228
|
+
function normalizeAuthCode(raw) {
|
|
80229
|
+
const cleaned = raw.trim().replace(/^[`'"“”‘’]+|[`'"“”‘’]+$/g, "").trim();
|
|
80230
|
+
const fromUrl = /[?&]code=([^&\s]+)/.exec(cleaned);
|
|
80231
|
+
return fromUrl ? decodeURIComponent(fromUrl[1]) : cleaned.replace(/\s+/g, "");
|
|
80232
|
+
}
|
|
80233
|
+
function parseAuthMethod(input) {
|
|
80234
|
+
const v = input.trim().toLowerCase();
|
|
80235
|
+
if (v === "" || v === "1" || v === "b" || v === "browser")
|
|
80236
|
+
return "browser";
|
|
80237
|
+
if (v === "2" || v === "p" || v === "e" || v === "email" || v === "password")
|
|
80238
|
+
return "password";
|
|
80239
|
+
if (v === "3" || v === "t" || v === "token")
|
|
80240
|
+
return "token";
|
|
80241
|
+
return null;
|
|
80242
|
+
}
|
|
79630
80243
|
function prompt(question, hidden = false) {
|
|
79631
80244
|
return new Promise((resolve19) => {
|
|
79632
80245
|
const rl = readline.createInterface({
|
|
@@ -79653,13 +80266,14 @@ function prompt(question, hidden = false) {
|
|
|
79653
80266
|
process.exit(0);
|
|
79654
80267
|
}
|
|
79655
80268
|
resolve19(value);
|
|
79656
|
-
|
|
79657
|
-
|
|
80269
|
+
return;
|
|
80270
|
+
}
|
|
80271
|
+
if (char === "\x7F" || char === "\b") {
|
|
80272
|
+
if (value.length > 0)
|
|
79658
80273
|
value = value.slice(0, -1);
|
|
79659
|
-
|
|
79660
|
-
} else {
|
|
79661
|
-
value += char;
|
|
80274
|
+
return;
|
|
79662
80275
|
}
|
|
80276
|
+
value += char;
|
|
79663
80277
|
};
|
|
79664
80278
|
stdin.on("data", onData);
|
|
79665
80279
|
} else {
|
|
@@ -79670,12 +80284,12 @@ function prompt(question, hidden = false) {
|
|
|
79670
80284
|
}
|
|
79671
80285
|
});
|
|
79672
80286
|
}
|
|
79673
|
-
async function authCommand() {
|
|
80287
|
+
async function authCommand(opts = {}) {
|
|
79674
80288
|
console.log();
|
|
79675
80289
|
console.log(paint.boldBlue(" Nexrall Code \u2014 Login"));
|
|
79676
80290
|
console.log(paint.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
79677
80291
|
console.log();
|
|
79678
|
-
if ((0,
|
|
80292
|
+
if ((0, import_code_core2.isAuthenticated)() && !opts.token && !opts.code) {
|
|
79679
80293
|
const overwrite = await prompt(paint.yellow(" Already logged in. Login again? ") + paint.dim("[y/n] > "));
|
|
79680
80294
|
if (overwrite !== "y" && overwrite !== "yes") {
|
|
79681
80295
|
console.log(paint.dim(" Cancelled."));
|
|
@@ -79683,21 +80297,90 @@ async function authCommand() {
|
|
|
79683
80297
|
}
|
|
79684
80298
|
console.log();
|
|
79685
80299
|
}
|
|
80300
|
+
if (opts.token)
|
|
80301
|
+
return loginWithToken(opts.token);
|
|
80302
|
+
if (opts.browser || opts.code)
|
|
80303
|
+
return loginWithBrowser(opts.code);
|
|
80304
|
+
if (opts.password)
|
|
80305
|
+
return loginWithPassword();
|
|
80306
|
+
if (!process.stdin.isTTY)
|
|
80307
|
+
return loginWithPassword();
|
|
80308
|
+
const method = await chooseMethod();
|
|
80309
|
+
if (method === null) {
|
|
80310
|
+
console.log(paint.dim(" Cancelled."));
|
|
80311
|
+
return;
|
|
80312
|
+
}
|
|
80313
|
+
if (method === "browser")
|
|
80314
|
+
return loginWithBrowser();
|
|
80315
|
+
if (method === "token")
|
|
80316
|
+
return loginWithTokenPrompt();
|
|
80317
|
+
return loginWithPassword();
|
|
80318
|
+
}
|
|
80319
|
+
async function chooseMethod() {
|
|
80320
|
+
console.log(" How do you want to sign in?");
|
|
80321
|
+
console.log();
|
|
80322
|
+
console.log(
|
|
80323
|
+
` ${paint.bold("1.")} Browser ${paint.dim("Google, Apple, SSO or email + password \u2014 recommended")}`
|
|
80324
|
+
);
|
|
80325
|
+
console.log(` ${paint.bold("2.")} Email + password ${paint.dim("typed here in the terminal")}`);
|
|
80326
|
+
console.log(` ${paint.bold("3.")} Token ${paint.dim("CI / headless \u2014 paste a token")}`);
|
|
80327
|
+
console.log();
|
|
80328
|
+
for (; ; ) {
|
|
80329
|
+
const answer = await prompt(paint.bold(" Choose ") + paint.dim("[1] > "));
|
|
80330
|
+
const method = parseAuthMethod(answer);
|
|
80331
|
+
if (method)
|
|
80332
|
+
return method;
|
|
80333
|
+
console.log(paint.yellow(" Pick 1, 2 or 3."));
|
|
80334
|
+
}
|
|
80335
|
+
}
|
|
80336
|
+
async function loginWithBrowser(codeArg) {
|
|
80337
|
+
let code = codeArg ? normalizeAuthCode(codeArg) : "";
|
|
80338
|
+
if (!code) {
|
|
80339
|
+
const url = browserAuthUrl();
|
|
80340
|
+
openInBrowser(url);
|
|
80341
|
+
console.log(paint.dim(" Opened: ") + paint.cyan(url));
|
|
80342
|
+
console.log();
|
|
80343
|
+
console.log(" Sign in there \u2014 Google, Apple, SSO or your password all work.");
|
|
80344
|
+
console.log(paint.dim(" Copy the code the page shows, then paste it here."));
|
|
80345
|
+
console.log();
|
|
80346
|
+
code = normalizeAuthCode(await prompt(paint.bold(" Code ") + paint.dim("> ")));
|
|
80347
|
+
}
|
|
80348
|
+
if (!code) {
|
|
80349
|
+
console.log(paint.red(" \u2717 No code entered."));
|
|
80350
|
+
console.log();
|
|
80351
|
+
process.exitCode = 1;
|
|
80352
|
+
return;
|
|
80353
|
+
}
|
|
80354
|
+
console.log();
|
|
80355
|
+
const spinner = startSpinner("Signing in\u2026");
|
|
80356
|
+
try {
|
|
80357
|
+
const authConfig = await (0, import_code_core2.exchangeAuthCode)(code);
|
|
80358
|
+
(0, import_code_core2.saveAuth)(authConfig);
|
|
80359
|
+
stopSpinner(spinner);
|
|
80360
|
+
console.log(paint.green(" \u2713 Logged in as ") + paint.bold(authConfig.email || "your account"));
|
|
80361
|
+
await showBalance();
|
|
80362
|
+
console.log();
|
|
80363
|
+
console.log(paint.dim(" Run ") + paint.bold("nex") + paint.dim(" to start coding."));
|
|
80364
|
+
console.log();
|
|
80365
|
+
} catch (err) {
|
|
80366
|
+
stopSpinner(spinner);
|
|
80367
|
+
console.log();
|
|
80368
|
+
console.log(paint.red(" \u2717 Login failed: ") + String(err.message));
|
|
80369
|
+
console.log();
|
|
80370
|
+
process.exitCode = 1;
|
|
80371
|
+
}
|
|
80372
|
+
}
|
|
80373
|
+
async function loginWithPassword() {
|
|
79686
80374
|
const email = await prompt(paint.bold(" Email ") + paint.dim("> "));
|
|
79687
80375
|
const password = await prompt(paint.bold(" Password ") + paint.dim("> "), true);
|
|
79688
80376
|
console.log();
|
|
79689
80377
|
const spinner = startSpinner("Logging in\u2026");
|
|
79690
80378
|
try {
|
|
79691
|
-
const authConfig = await (0,
|
|
79692
|
-
(0,
|
|
80379
|
+
const authConfig = await (0, import_code_core2.login)(email, password);
|
|
80380
|
+
(0, import_code_core2.saveAuth)(authConfig);
|
|
79693
80381
|
stopSpinner(spinner);
|
|
79694
80382
|
console.log(paint.green(" \u2713 Logged in as ") + paint.bold(authConfig.email ?? email));
|
|
79695
|
-
|
|
79696
|
-
try {
|
|
79697
|
-
const balance = await (0, import_code_core.getBalance)();
|
|
79698
|
-
console.log(paint.dim(" Wallet balance: ") + paint.cyan(`$${balance.toFixed(4)}`));
|
|
79699
|
-
} catch {
|
|
79700
|
-
}
|
|
80383
|
+
await showBalance();
|
|
79701
80384
|
console.log();
|
|
79702
80385
|
console.log(paint.dim(" Run ") + paint.bold("nex") + paint.dim(" to start coding."));
|
|
79703
80386
|
console.log();
|
|
@@ -79706,12 +80389,71 @@ async function authCommand() {
|
|
|
79706
80389
|
console.log();
|
|
79707
80390
|
console.log(paint.red(" \u2717 Login failed: ") + String(err.message));
|
|
79708
80391
|
console.log();
|
|
79709
|
-
process.
|
|
80392
|
+
process.exitCode = 1;
|
|
80393
|
+
}
|
|
80394
|
+
}
|
|
80395
|
+
async function loginWithTokenPrompt() {
|
|
80396
|
+
console.log(paint.dim(" Paste a token from the Nexrall dashboard."));
|
|
80397
|
+
const token = await prompt(paint.bold(" Token ") + paint.dim("> "), true);
|
|
80398
|
+
if (!token) {
|
|
80399
|
+
console.log(paint.red(" \u2717 No token entered."));
|
|
80400
|
+
console.log();
|
|
80401
|
+
process.exitCode = 1;
|
|
80402
|
+
return;
|
|
80403
|
+
}
|
|
80404
|
+
await loginWithToken(token);
|
|
80405
|
+
}
|
|
80406
|
+
async function loginWithToken(rawToken) {
|
|
80407
|
+
const token = rawToken.trim();
|
|
80408
|
+
if (!token) {
|
|
80409
|
+
console.log(paint.red(" \u2717 Empty token."));
|
|
80410
|
+
console.log();
|
|
80411
|
+
process.exitCode = 1;
|
|
80412
|
+
return;
|
|
80413
|
+
}
|
|
80414
|
+
console.log();
|
|
80415
|
+
const spinner = startSpinner("Checking the token\u2026");
|
|
80416
|
+
const check2 = await (0, import_code_core2.checkToken)(token);
|
|
80417
|
+
if (!check2.ok && check2.status !== 0) {
|
|
80418
|
+
stopSpinner(spinner);
|
|
80419
|
+
console.log();
|
|
80420
|
+
console.log(paint.red(` \u2717 The API refused this token (HTTP ${check2.status}).`) + paint.dim(" Nothing was saved."));
|
|
80421
|
+
console.log();
|
|
80422
|
+
process.exitCode = 1;
|
|
80423
|
+
return;
|
|
80424
|
+
}
|
|
80425
|
+
(0, import_code_core2.saveAuth)({ token, ...check2.email ? { email: check2.email } : {} });
|
|
80426
|
+
stopSpinner(spinner);
|
|
80427
|
+
console.log(paint.green(" \u2713 Token saved") + (check2.email ? paint.dim(` for ${check2.email}`) : ""));
|
|
80428
|
+
if (check2.status === 0) {
|
|
80429
|
+
console.log(paint.yellow(" Could not reach the API to verify it \u2014 check the token once you are online."));
|
|
80430
|
+
}
|
|
80431
|
+
warnIfEnvTokenWins();
|
|
80432
|
+
await showBalance();
|
|
80433
|
+
console.log();
|
|
80434
|
+
}
|
|
80435
|
+
function warnIfEnvTokenWins() {
|
|
80436
|
+
const envToken = process.env.NEXRALL_TOKEN?.trim();
|
|
80437
|
+
if (!envToken)
|
|
80438
|
+
return;
|
|
80439
|
+
console.log(
|
|
80440
|
+
paint.yellow(" NEXRALL_TOKEN is set in this shell and takes precedence over the saved login.") + paint.dim(" Unset it to use what you just saved.")
|
|
80441
|
+
);
|
|
80442
|
+
}
|
|
80443
|
+
async function showBalance() {
|
|
80444
|
+
try {
|
|
80445
|
+
const balance = await (0, import_code_core2.getBalance)();
|
|
80446
|
+
console.log(paint.dim(" Wallet balance: ") + paint.cyan(`$${balance.toFixed(4)}`));
|
|
80447
|
+
} catch {
|
|
79710
80448
|
}
|
|
79711
80449
|
}
|
|
80450
|
+
async function signOut() {
|
|
80451
|
+
await (0, import_code_core2.revokeRefreshToken)();
|
|
80452
|
+
(0, import_code_core2.clearAuth)();
|
|
80453
|
+
}
|
|
79712
80454
|
async function logoutCommand() {
|
|
79713
80455
|
console.log();
|
|
79714
|
-
if (!(0,
|
|
80456
|
+
if (!(0, import_code_core2.isAuthenticated)()) {
|
|
79715
80457
|
console.log(paint.dim(" Not logged in."));
|
|
79716
80458
|
console.log();
|
|
79717
80459
|
return;
|
|
@@ -79722,9 +80464,13 @@ async function logoutCommand() {
|
|
|
79722
80464
|
console.log();
|
|
79723
80465
|
return;
|
|
79724
80466
|
}
|
|
79725
|
-
await (
|
|
79726
|
-
(0, import_code_core.clearAuth)();
|
|
80467
|
+
await signOut();
|
|
79727
80468
|
console.log(paint.green(" \u2713 Logged out."));
|
|
80469
|
+
if (process.env.NEXRALL_TOKEN?.trim()) {
|
|
80470
|
+
console.log(
|
|
80471
|
+
paint.yellow(" NEXRALL_TOKEN is still set in this shell") + paint.dim(" \u2014 unset it, or the CLI stays signed in with that token.")
|
|
80472
|
+
);
|
|
80473
|
+
}
|
|
79728
80474
|
console.log();
|
|
79729
80475
|
}
|
|
79730
80476
|
function startSpinner(text) {
|
|
@@ -79743,12 +80489,12 @@ function stopSpinner(handle2) {
|
|
|
79743
80489
|
}
|
|
79744
80490
|
|
|
79745
80491
|
// src/commands/billing.ts
|
|
79746
|
-
var
|
|
80492
|
+
var import_code_core3 = __toESM(require_dist2(), 1);
|
|
79747
80493
|
function money(usd) {
|
|
79748
80494
|
return "$" + usd.toFixed(2);
|
|
79749
80495
|
}
|
|
79750
80496
|
async function requireAuth() {
|
|
79751
|
-
if ((0,
|
|
80497
|
+
if ((0, import_code_core3.isAuthenticated)())
|
|
79752
80498
|
return true;
|
|
79753
80499
|
console.log(paint.red("Not logged in. Run `nex auth` first."));
|
|
79754
80500
|
return false;
|
|
@@ -79758,7 +80504,7 @@ async function billingStatusCommand() {
|
|
|
79758
80504
|
return;
|
|
79759
80505
|
let orgs;
|
|
79760
80506
|
try {
|
|
79761
|
-
orgs = await (0,
|
|
80507
|
+
orgs = await (0, import_code_core3.getOrgs)();
|
|
79762
80508
|
} catch {
|
|
79763
80509
|
console.log(paint.yellow("Could not read your billing target (offline, or a server without team support)."));
|
|
79764
80510
|
return;
|
|
@@ -79790,7 +80536,7 @@ async function billingStatusCommand() {
|
|
|
79790
80536
|
console.log("");
|
|
79791
80537
|
console.log(paint.gray("Change it with `nex billing use <id>` or `nex billing use personal`."));
|
|
79792
80538
|
}
|
|
79793
|
-
const override = (0,
|
|
80539
|
+
const override = (0, import_code_core3.billingOverrideFields)();
|
|
79794
80540
|
if ("teamId" in override) {
|
|
79795
80541
|
console.log("");
|
|
79796
80542
|
console.log(
|
|
@@ -79818,7 +80564,7 @@ async function billingUseCommand(target) {
|
|
|
79818
80564
|
}
|
|
79819
80565
|
async function applyTarget(teamId, label) {
|
|
79820
80566
|
try {
|
|
79821
|
-
await (0,
|
|
80567
|
+
await (0, import_code_core3.setBillingTarget)(teamId);
|
|
79822
80568
|
} catch (e2) {
|
|
79823
80569
|
console.log(paint.red(e2.message));
|
|
79824
80570
|
process.exitCode = 1;
|
|
@@ -79832,14 +80578,14 @@ async function applyTarget(teamId, label) {
|
|
|
79832
80578
|
|
|
79833
80579
|
// src/commands/schedule.ts
|
|
79834
80580
|
var import_prompts = __toESM(require_prompts3(), 1);
|
|
79835
|
-
var
|
|
80581
|
+
var import_code_core5 = __toESM(require_dist2(), 1);
|
|
79836
80582
|
|
|
79837
80583
|
// src/ui/scheduleLines.ts
|
|
79838
|
-
var
|
|
80584
|
+
var import_code_core4 = __toESM(require_dist2(), 1);
|
|
79839
80585
|
|
|
79840
80586
|
// src/commands/schedule.ts
|
|
79841
80587
|
async function requireAuth2() {
|
|
79842
|
-
if ((0,
|
|
80588
|
+
if ((0, import_code_core5.isAuthenticated)())
|
|
79843
80589
|
return true;
|
|
79844
80590
|
console.log(paint.red("Not logged in. Run `nex auth` first."));
|
|
79845
80591
|
process.exitCode = 1;
|
|
@@ -79860,7 +80606,7 @@ async function scheduleListCommand(opts = {}) {
|
|
|
79860
80606
|
return;
|
|
79861
80607
|
let list;
|
|
79862
80608
|
try {
|
|
79863
|
-
list = await (0,
|
|
80609
|
+
list = await (0, import_code_core5.listCloudSchedules)();
|
|
79864
80610
|
} catch (e2) {
|
|
79865
80611
|
fail(errText(e2));
|
|
79866
80612
|
return;
|
|
@@ -79869,7 +80615,7 @@ async function scheduleListCommand(opts = {}) {
|
|
|
79869
80615
|
console.log(JSON.stringify(list, null, 2));
|
|
79870
80616
|
return;
|
|
79871
80617
|
}
|
|
79872
|
-
for (const line of (0,
|
|
80618
|
+
for (const line of (0, import_code_core4.scheduleListLines)(list, { cols: cols() }))
|
|
79873
80619
|
console.log(line);
|
|
79874
80620
|
if (list.length) {
|
|
79875
80621
|
console.log(paint.dim(`
|
|
@@ -79889,7 +80635,7 @@ async function scheduleAddCommand(taskParts, opts) {
|
|
|
79889
80635
|
fail("Missing --every. Usage: nex schedule add --every 1d <task> (e.g. --every 2h)");
|
|
79890
80636
|
return;
|
|
79891
80637
|
}
|
|
79892
|
-
const every = (0,
|
|
80638
|
+
const every = (0, import_code_core4.parseScheduleEvery)(everyRaw);
|
|
79893
80639
|
if ("error" in every) {
|
|
79894
80640
|
fail(every.error);
|
|
79895
80641
|
return;
|
|
@@ -79897,7 +80643,7 @@ async function scheduleAddCommand(taskParts, opts) {
|
|
|
79897
80643
|
const domains = (opts.domains ?? "").split(",").map((d) => d.trim()).filter(Boolean);
|
|
79898
80644
|
let s2;
|
|
79899
80645
|
try {
|
|
79900
|
-
s2 = await (0,
|
|
80646
|
+
s2 = await (0, import_code_core5.createCloudSchedule)({
|
|
79901
80647
|
task,
|
|
79902
80648
|
intervalMinutes: every.minutes,
|
|
79903
80649
|
startUrl: opts.startUrl,
|
|
@@ -79909,12 +80655,12 @@ async function scheduleAddCommand(taskParts, opts) {
|
|
|
79909
80655
|
return;
|
|
79910
80656
|
}
|
|
79911
80657
|
console.log(
|
|
79912
|
-
`\u2714 Scheduled ${paint.bold(`#${s2.id}`)} \u2014 every ${(0,
|
|
80658
|
+
`\u2714 Scheduled ${paint.bold(`#${s2.id}`)} \u2014 every ${(0, import_code_core4.formatEvery)(s2.intervalMinutes)}${s2.enabled ? "" : paint.yellow(" (paused)")}`
|
|
79913
80659
|
);
|
|
79914
80660
|
console.log(` ${s2.task}`);
|
|
79915
80661
|
if (s2.nextRunAt) {
|
|
79916
80662
|
console.log(
|
|
79917
|
-
paint.dim(` Next run ${(0,
|
|
80663
|
+
paint.dim(` Next run ${(0, import_code_core4.fmtScheduleWhen)(s2.nextRunAt)} \u2014 on Nexrall's servers; your laptop can be closed.`)
|
|
79918
80664
|
);
|
|
79919
80665
|
}
|
|
79920
80666
|
console.log(paint.dim(` History: nex schedule runs ${s2.id} \xB7 Pause: nex schedule pause ${s2.id}`));
|
|
@@ -79927,8 +80673,8 @@ async function scheduleSetEnabled(id, enabled) {
|
|
|
79927
80673
|
return;
|
|
79928
80674
|
}
|
|
79929
80675
|
try {
|
|
79930
|
-
const s2 = await (0,
|
|
79931
|
-
const next = s2.nextRunAt ? paint.dim(` \u2014 next run ${(0,
|
|
80676
|
+
const s2 = await (0, import_code_core5.updateCloudSchedule)(id, { enabled });
|
|
80677
|
+
const next = s2.nextRunAt ? paint.dim(` \u2014 next run ${(0, import_code_core4.fmtScheduleWhen)(s2.nextRunAt)}`) : "";
|
|
79932
80678
|
console.log(`\u2714 Schedule #${s2.id} is now ${s2.enabled ? "on" : "paused"}${next}`);
|
|
79933
80679
|
} catch (e2) {
|
|
79934
80680
|
fail(errText(e2));
|
|
@@ -79949,7 +80695,7 @@ async function scheduleRunCommand(id) {
|
|
|
79949
80695
|
return;
|
|
79950
80696
|
}
|
|
79951
80697
|
try {
|
|
79952
|
-
const s2 = await (0,
|
|
80698
|
+
const s2 = await (0, import_code_core5.runCloudScheduleNow)(clean);
|
|
79953
80699
|
console.log(`\u2714 Schedule #${s2.id} armed \u2014 the cloud runner picks it up within ~60s.`);
|
|
79954
80700
|
console.log(paint.dim(` Result: nex schedule runs ${s2.id}`));
|
|
79955
80701
|
} catch (e2) {
|
|
@@ -79983,7 +80729,7 @@ async function scheduleRemoveCommand(id, opts = {}) {
|
|
|
79983
80729
|
}
|
|
79984
80730
|
}
|
|
79985
80731
|
try {
|
|
79986
|
-
await (0,
|
|
80732
|
+
await (0, import_code_core5.deleteCloudSchedule)(clean);
|
|
79987
80733
|
console.log(`\u2714 Removed schedule #${clean}`);
|
|
79988
80734
|
} catch (e2) {
|
|
79989
80735
|
fail(errText(e2));
|
|
@@ -79999,7 +80745,7 @@ async function scheduleRunsCommand(id, opts = {}) {
|
|
|
79999
80745
|
}
|
|
80000
80746
|
let runs2;
|
|
80001
80747
|
try {
|
|
80002
|
-
runs2 = await (0,
|
|
80748
|
+
runs2 = await (0, import_code_core5.getCloudScheduleRuns)(clean);
|
|
80003
80749
|
} catch (e2) {
|
|
80004
80750
|
fail(errText(e2));
|
|
80005
80751
|
return;
|
|
@@ -80008,7 +80754,7 @@ async function scheduleRunsCommand(id, opts = {}) {
|
|
|
80008
80754
|
console.log(JSON.stringify(runs2, null, 2));
|
|
80009
80755
|
return;
|
|
80010
80756
|
}
|
|
80011
|
-
for (const line of (0,
|
|
80757
|
+
for (const line of (0, import_code_core4.scheduleRunsLines)(runs2, { cols: cols() }))
|
|
80012
80758
|
console.log(line);
|
|
80013
80759
|
if (runs2.length) {
|
|
80014
80760
|
console.log(
|
|
@@ -80021,10 +80767,10 @@ async function scheduleRunsCommand(id, opts = {}) {
|
|
|
80021
80767
|
}
|
|
80022
80768
|
|
|
80023
80769
|
// src/commands/cloud.ts
|
|
80024
|
-
var
|
|
80025
|
-
|
|
80770
|
+
var import_proc2 = __toESM(require_proc(), 1);
|
|
80771
|
+
var import_code_core6 = __toESM(require_dist2(), 1);
|
|
80026
80772
|
async function requireAuth3() {
|
|
80027
|
-
if ((0,
|
|
80773
|
+
if ((0, import_code_core6.isAuthenticated)())
|
|
80028
80774
|
return true;
|
|
80029
80775
|
console.log(paint.red("Not logged in. Run `nex auth` first."));
|
|
80030
80776
|
process.exitCode = 1;
|
|
@@ -80058,10 +80804,11 @@ var writeRaw = (s2) => {
|
|
|
80058
80804
|
process.stdout.write(s2);
|
|
80059
80805
|
};
|
|
80060
80806
|
function openUrl(url) {
|
|
80061
|
-
const
|
|
80062
|
-
const
|
|
80807
|
+
const win = process.platform === "win32";
|
|
80808
|
+
const cmd = process.platform === "darwin" ? "open" : win ? "rundll32" : "xdg-open";
|
|
80809
|
+
const args = win ? ["url.dll,FileProtocolHandler", url] : [url];
|
|
80063
80810
|
try {
|
|
80064
|
-
const child = spawn(cmd, args, { stdio: "ignore", detached:
|
|
80811
|
+
const child = (0, import_proc2.spawn)(cmd, args, { stdio: "ignore", detached: !win });
|
|
80065
80812
|
child.on("error", () => {
|
|
80066
80813
|
});
|
|
80067
80814
|
child.unref();
|
|
@@ -80093,7 +80840,7 @@ async function cloudRunCommand(taskParts, opts) {
|
|
|
80093
80840
|
}
|
|
80094
80841
|
let created;
|
|
80095
80842
|
try {
|
|
80096
|
-
created = await (0,
|
|
80843
|
+
created = await (0, import_code_core6.createCloudSession)({ repo: opts.repo, task, baseBranch: opts.base, pat: pat || void 0 });
|
|
80097
80844
|
} catch (e2) {
|
|
80098
80845
|
return fail2(errText2(e2));
|
|
80099
80846
|
}
|
|
@@ -80112,7 +80859,7 @@ async function cloudListCommand(opts = {}) {
|
|
|
80112
80859
|
return;
|
|
80113
80860
|
let list;
|
|
80114
80861
|
try {
|
|
80115
|
-
list = await (0,
|
|
80862
|
+
list = await (0, import_code_core6.listCloudSessions)();
|
|
80116
80863
|
} catch (e2) {
|
|
80117
80864
|
return fail2(errText2(e2));
|
|
80118
80865
|
}
|
|
@@ -80120,7 +80867,7 @@ async function cloudListCommand(opts = {}) {
|
|
|
80120
80867
|
console.log(JSON.stringify({ sessions: list }, null, 2));
|
|
80121
80868
|
return;
|
|
80122
80869
|
}
|
|
80123
|
-
for (const line of (0,
|
|
80870
|
+
for (const line of (0, import_code_core6.cloudListLines)(list, { cols: cols2() }))
|
|
80124
80871
|
console.log(` ${line}`);
|
|
80125
80872
|
}
|
|
80126
80873
|
async function cloudLogsCommand(id, opts) {
|
|
@@ -80133,7 +80880,7 @@ async function cloudLogsCommand(id, opts) {
|
|
|
80133
80880
|
if (!opts.follow) {
|
|
80134
80881
|
let r2;
|
|
80135
80882
|
try {
|
|
80136
|
-
r2 = await (0,
|
|
80883
|
+
r2 = await (0, import_code_core6.getCloudSessionLogs)(id, tail ?? 300);
|
|
80137
80884
|
} catch (e2) {
|
|
80138
80885
|
return fail2(errText2(e2));
|
|
80139
80886
|
}
|
|
@@ -80159,7 +80906,7 @@ async function cloudLogsCommand(id, opts) {
|
|
|
80159
80906
|
for (; ; ) {
|
|
80160
80907
|
let r2;
|
|
80161
80908
|
try {
|
|
80162
|
-
r2 = await (0,
|
|
80909
|
+
r2 = await (0, import_code_core6.getCloudSessionLogs)(id, tail ?? 1e3);
|
|
80163
80910
|
consecutiveErrors = 0;
|
|
80164
80911
|
} catch (e2) {
|
|
80165
80912
|
const msg = errText2(e2);
|
|
@@ -80208,7 +80955,7 @@ async function cloudStopCommand(id) {
|
|
|
80208
80955
|
return;
|
|
80209
80956
|
let s2;
|
|
80210
80957
|
try {
|
|
80211
|
-
s2 = await (0,
|
|
80958
|
+
s2 = await (0, import_code_core6.stopCloudSession)(id);
|
|
80212
80959
|
} catch (e2) {
|
|
80213
80960
|
return fail2(errText2(e2));
|
|
80214
80961
|
}
|
|
@@ -80223,7 +80970,7 @@ async function cloudWatchCommand(id, opts = {}) {
|
|
|
80223
80970
|
return;
|
|
80224
80971
|
let s2;
|
|
80225
80972
|
try {
|
|
80226
|
-
s2 = await (0,
|
|
80973
|
+
s2 = await (0, import_code_core6.getCloudSession)(id);
|
|
80227
80974
|
} catch (e2) {
|
|
80228
80975
|
return fail2(errText2(e2));
|
|
80229
80976
|
}
|
|
@@ -80393,11 +81140,11 @@ async function channelPushCommand(textParts, opts, deps = {}) {
|
|
|
80393
81140
|
}
|
|
80394
81141
|
|
|
80395
81142
|
// src/commands/usageCmd.ts
|
|
80396
|
-
import
|
|
80397
|
-
import
|
|
81143
|
+
import fs3 from "node:fs";
|
|
81144
|
+
import path2 from "node:path";
|
|
80398
81145
|
|
|
80399
81146
|
// src/sessionEvents.ts
|
|
80400
|
-
var
|
|
81147
|
+
var import_code_core7 = __toESM(require_dist2(), 1);
|
|
80401
81148
|
|
|
80402
81149
|
// src/usageExport.ts
|
|
80403
81150
|
var DURATION_RE = /^(\d+)([mhdw])$/;
|
|
@@ -80694,7 +81441,7 @@ var USAGE_FORMATS = ["json", "jsonl", "csv"];
|
|
|
80694
81441
|
function logFileIds(dir) {
|
|
80695
81442
|
let names;
|
|
80696
81443
|
try {
|
|
80697
|
-
names =
|
|
81444
|
+
names = fs3.readdirSync(dir);
|
|
80698
81445
|
} catch {
|
|
80699
81446
|
return [];
|
|
80700
81447
|
}
|
|
@@ -80704,7 +81451,7 @@ function readRows(file) {
|
|
|
80704
81451
|
const rows = [];
|
|
80705
81452
|
let text;
|
|
80706
81453
|
try {
|
|
80707
|
-
text =
|
|
81454
|
+
text = fs3.readFileSync(file, "utf8");
|
|
80708
81455
|
} catch {
|
|
80709
81456
|
return rows;
|
|
80710
81457
|
}
|
|
@@ -80752,13 +81499,13 @@ function usageExportCommand(opts, deps = {}) {
|
|
|
80752
81499
|
}
|
|
80753
81500
|
limit = n;
|
|
80754
81501
|
}
|
|
80755
|
-
const dir = deps.eventsDirPath ?? (0,
|
|
81502
|
+
const dir = deps.eventsDirPath ?? (0, import_code_core7.eventsDir)(deps.env ?? process.env);
|
|
80756
81503
|
const ids = logFileIds(dir);
|
|
80757
81504
|
const acc = createAccumulator({ since, until });
|
|
80758
81505
|
acc.filesTotal = ids.length;
|
|
80759
81506
|
let candidates = ids;
|
|
80760
81507
|
if (opts.session) {
|
|
80761
|
-
const wanted = (0,
|
|
81508
|
+
const wanted = (0, import_code_core7.safeId)(opts.session);
|
|
80762
81509
|
if (!candidates.includes(wanted)) {
|
|
80763
81510
|
stderr(paint.red(`Session not found: ${opts.session}`));
|
|
80764
81511
|
stderr(paint.dim(` Logs live in ${dir} (one .jsonl per session).`));
|
|
@@ -80769,7 +81516,7 @@ function usageExportCommand(opts, deps = {}) {
|
|
|
80769
81516
|
if (since !== void 0) {
|
|
80770
81517
|
candidates = candidates.filter((id) => {
|
|
80771
81518
|
try {
|
|
80772
|
-
return
|
|
81519
|
+
return fs3.statSync(path2.join(dir, `${id}.jsonl`)).mtimeMs >= since;
|
|
80773
81520
|
} catch {
|
|
80774
81521
|
return false;
|
|
80775
81522
|
}
|
|
@@ -80777,7 +81524,7 @@ function usageExportCommand(opts, deps = {}) {
|
|
|
80777
81524
|
}
|
|
80778
81525
|
const byNewest = candidates.map((id) => {
|
|
80779
81526
|
try {
|
|
80780
|
-
return { id, mtime:
|
|
81527
|
+
return { id, mtime: fs3.statSync(path2.join(dir, `${id}.jsonl`)).mtimeMs };
|
|
80781
81528
|
} catch {
|
|
80782
81529
|
return { id, mtime: 0 };
|
|
80783
81530
|
}
|
|
@@ -80786,7 +81533,7 @@ function usageExportCommand(opts, deps = {}) {
|
|
|
80786
81533
|
acc.truncated = taken.length < byNewest.length;
|
|
80787
81534
|
for (const { id } of taken) {
|
|
80788
81535
|
acc.filesRead += 1;
|
|
80789
|
-
addSessionFile(acc, id, readRows(
|
|
81536
|
+
addSessionFile(acc, id, readRows(path2.join(dir, `${id}.jsonl`)));
|
|
80790
81537
|
}
|
|
80791
81538
|
const report = finalizeUsage(acc, now);
|
|
80792
81539
|
let content;
|
|
@@ -80798,7 +81545,7 @@ function usageExportCommand(opts, deps = {}) {
|
|
|
80798
81545
|
content = formatUsageJson(report);
|
|
80799
81546
|
if (opts.out) {
|
|
80800
81547
|
try {
|
|
80801
|
-
|
|
81548
|
+
fs3.writeFileSync(opts.out, content);
|
|
80802
81549
|
} catch (e2) {
|
|
80803
81550
|
stderr(paint.red(`Could not write ${opts.out}: ${e2.message}`));
|
|
80804
81551
|
return USAGE_EXIT.FAIL;
|
|
@@ -80832,7 +81579,7 @@ import * as path27 from "path";
|
|
|
80832
81579
|
import * as fs26 from "fs";
|
|
80833
81580
|
|
|
80834
81581
|
// src/ui/diffView.ts
|
|
80835
|
-
var
|
|
81582
|
+
var import_code_core8 = __toESM(require_dist2(), 1);
|
|
80836
81583
|
function paintLine(l) {
|
|
80837
81584
|
switch (l.kind) {
|
|
80838
81585
|
case "file":
|
|
@@ -80853,431 +81600,7 @@ function paintLine(l) {
|
|
|
80853
81600
|
}
|
|
80854
81601
|
|
|
80855
81602
|
// src/ui/reviewQueue.ts
|
|
80856
|
-
var import_code_core8 = __toESM(require_dist2(), 1);
|
|
80857
|
-
|
|
80858
|
-
// src/mcp/oauth.ts
|
|
80859
81603
|
var import_code_core9 = __toESM(require_dist2(), 1);
|
|
80860
|
-
import * as fs3 from "fs";
|
|
80861
|
-
import * as os2 from "os";
|
|
80862
|
-
import * as path2 from "path";
|
|
80863
|
-
import * as http3 from "http";
|
|
80864
|
-
import * as crypto from "crypto";
|
|
80865
|
-
import { spawn as spawn2 } from "child_process";
|
|
80866
|
-
var CALLBACK_TIMEOUT_MS = 5 * 60 * 1e3;
|
|
80867
|
-
function tokensFile(env3 = process.env) {
|
|
80868
|
-
return env3.NEXRALL_MCP_AUTH_FILE || path2.join(os2.homedir(), ".nexrall", "mcp-auth.json");
|
|
80869
|
-
}
|
|
80870
|
-
function readStore(file) {
|
|
80871
|
-
try {
|
|
80872
|
-
const parsed = JSON.parse(fs3.readFileSync(file, "utf-8"));
|
|
80873
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
80874
|
-
return {};
|
|
80875
|
-
const out = {};
|
|
80876
|
-
for (const [k, v] of Object.entries(parsed)) {
|
|
80877
|
-
const b = v;
|
|
80878
|
-
if (b && typeof b.access_token === "string" && typeof b.token_endpoint === "string")
|
|
80879
|
-
out[k] = b;
|
|
80880
|
-
}
|
|
80881
|
-
return out;
|
|
80882
|
-
} catch {
|
|
80883
|
-
return {};
|
|
80884
|
-
}
|
|
80885
|
-
}
|
|
80886
|
-
function writeStore(file, store) {
|
|
80887
|
-
fs3.mkdirSync(path2.dirname(file), { recursive: true });
|
|
80888
|
-
fs3.writeFileSync(file, JSON.stringify(store, null, 2), { mode: 384 });
|
|
80889
|
-
try {
|
|
80890
|
-
fs3.chmodSync(file, 384);
|
|
80891
|
-
} catch {
|
|
80892
|
-
}
|
|
80893
|
-
}
|
|
80894
|
-
function loadToken(server, file = tokensFile()) {
|
|
80895
|
-
return readStore(file)[server] ?? null;
|
|
80896
|
-
}
|
|
80897
|
-
function saveToken(server, bundle, file = tokensFile()) {
|
|
80898
|
-
const store = readStore(file);
|
|
80899
|
-
store[server] = bundle;
|
|
80900
|
-
writeStore(file, store);
|
|
80901
|
-
}
|
|
80902
|
-
function clearToken(server, file = tokensFile()) {
|
|
80903
|
-
const store = readStore(file);
|
|
80904
|
-
if (!(server in store))
|
|
80905
|
-
return false;
|
|
80906
|
-
delete store[server];
|
|
80907
|
-
writeStore(file, store);
|
|
80908
|
-
return true;
|
|
80909
|
-
}
|
|
80910
|
-
function defaultFetch() {
|
|
80911
|
-
const f3 = globalThis.fetch;
|
|
80912
|
-
if (typeof f3 !== "function")
|
|
80913
|
-
throw new Error("global fetch unavailable \u2014 Node 18+ is required for MCP OAuth");
|
|
80914
|
-
return f3;
|
|
80915
|
-
}
|
|
80916
|
-
async function getValidAccessToken(server, opts = {}) {
|
|
80917
|
-
const file = opts.file ?? tokensFile();
|
|
80918
|
-
const bundle = loadToken(server, file);
|
|
80919
|
-
if (!bundle)
|
|
80920
|
-
return null;
|
|
80921
|
-
const fresh = !bundle.expires_at || bundle.expires_at - Date.now() > 6e4;
|
|
80922
|
-
if (fresh || !bundle.refresh_token)
|
|
80923
|
-
return bundle.access_token;
|
|
80924
|
-
try {
|
|
80925
|
-
const refreshed = await refreshAccessToken(bundle, opts.fetchImpl ?? defaultFetch());
|
|
80926
|
-
saveToken(server, refreshed, file);
|
|
80927
|
-
return refreshed.access_token;
|
|
80928
|
-
} catch {
|
|
80929
|
-
return bundle.access_token;
|
|
80930
|
-
}
|
|
80931
|
-
}
|
|
80932
|
-
function parseResourceMetadataUrl(wwwAuthenticate) {
|
|
80933
|
-
const m2 = /resource_metadata\s*=\s*"([^"]+)"/i.exec(wwwAuthenticate || "");
|
|
80934
|
-
return m2 ? m2[1] : null;
|
|
80935
|
-
}
|
|
80936
|
-
function protectedResourceCandidates(serverUrl) {
|
|
80937
|
-
const u = new URL(serverUrl);
|
|
80938
|
-
const base = u.origin;
|
|
80939
|
-
const p = u.pathname.replace(/\/$/, "");
|
|
80940
|
-
return [
|
|
80941
|
-
...p ? [`${base}/.well-known/oauth-protected-resource${p}`] : [],
|
|
80942
|
-
`${base}/.well-known/oauth-protected-resource`
|
|
80943
|
-
];
|
|
80944
|
-
}
|
|
80945
|
-
function authServerCandidates(authServer) {
|
|
80946
|
-
const u = new URL(authServer);
|
|
80947
|
-
const base = u.origin;
|
|
80948
|
-
const p = u.pathname.replace(/\/$/, "");
|
|
80949
|
-
const root = authServer.replace(/\/$/, "");
|
|
80950
|
-
return [
|
|
80951
|
-
`${base}/.well-known/oauth-authorization-server${p}`,
|
|
80952
|
-
`${base}/.well-known/openid-configuration${p}`,
|
|
80953
|
-
`${root}/.well-known/oauth-authorization-server`,
|
|
80954
|
-
`${root}/.well-known/openid-configuration`
|
|
80955
|
-
];
|
|
80956
|
-
}
|
|
80957
|
-
function buildAuthorizeUrl(meta, p) {
|
|
80958
|
-
const url = new URL(meta.authorization_endpoint);
|
|
80959
|
-
url.searchParams.set("response_type", "code");
|
|
80960
|
-
url.searchParams.set("client_id", p.clientId);
|
|
80961
|
-
url.searchParams.set("redirect_uri", p.redirectUri);
|
|
80962
|
-
url.searchParams.set("state", p.state);
|
|
80963
|
-
url.searchParams.set("code_challenge", p.codeChallenge);
|
|
80964
|
-
url.searchParams.set("code_challenge_method", "S256");
|
|
80965
|
-
url.searchParams.set("resource", meta.resource);
|
|
80966
|
-
if (meta.scope)
|
|
80967
|
-
url.searchParams.set("scope", meta.scope);
|
|
80968
|
-
return url.toString();
|
|
80969
|
-
}
|
|
80970
|
-
function toBundle(data, p) {
|
|
80971
|
-
const accessToken = data.access_token;
|
|
80972
|
-
if (!accessToken)
|
|
80973
|
-
throw new Error("Token response had no access_token");
|
|
80974
|
-
const expiresIn = typeof data.expires_in === "number" ? data.expires_in : void 0;
|
|
80975
|
-
return {
|
|
80976
|
-
access_token: accessToken,
|
|
80977
|
-
refresh_token: data.refresh_token ?? p.prevRefresh,
|
|
80978
|
-
expires_at: expiresIn ? Date.now() + expiresIn * 1e3 : void 0,
|
|
80979
|
-
token_endpoint: p.tokenEndpoint,
|
|
80980
|
-
client_id: p.clientId,
|
|
80981
|
-
client_secret: p.clientSecret,
|
|
80982
|
-
resource: p.resource,
|
|
80983
|
-
scope: data.scope ?? p.scope
|
|
80984
|
-
};
|
|
80985
|
-
}
|
|
80986
|
-
async function fetchJsonSafe(f3, url) {
|
|
80987
|
-
try {
|
|
80988
|
-
const resp = await f3(url, { headers: { Accept: "application/json" } });
|
|
80989
|
-
if (!resp.ok)
|
|
80990
|
-
return null;
|
|
80991
|
-
return await resp.json();
|
|
80992
|
-
} catch {
|
|
80993
|
-
return null;
|
|
80994
|
-
}
|
|
80995
|
-
}
|
|
80996
|
-
async function discover(serverUrl, wwwAuthenticate, f3 = defaultFetch()) {
|
|
80997
|
-
const origin = new URL(serverUrl).origin;
|
|
80998
|
-
let authServer = null;
|
|
80999
|
-
let resource = serverUrl;
|
|
81000
|
-
let scope;
|
|
81001
|
-
const prmCandidates = [parseResourceMetadataUrl(wwwAuthenticate), ...protectedResourceCandidates(serverUrl)].filter(
|
|
81002
|
-
(u) => Boolean(u)
|
|
81003
|
-
);
|
|
81004
|
-
let prm = null;
|
|
81005
|
-
for (const url of new Set(prmCandidates)) {
|
|
81006
|
-
prm = await fetchJsonSafe(f3, url);
|
|
81007
|
-
if (prm)
|
|
81008
|
-
break;
|
|
81009
|
-
}
|
|
81010
|
-
if (prm) {
|
|
81011
|
-
const servers = prm.authorization_servers;
|
|
81012
|
-
if (Array.isArray(servers) && servers.length)
|
|
81013
|
-
authServer = servers[0];
|
|
81014
|
-
if (typeof prm.resource === "string")
|
|
81015
|
-
resource = prm.resource;
|
|
81016
|
-
const scopes = prm.scopes_supported;
|
|
81017
|
-
if (Array.isArray(scopes) && scopes.length)
|
|
81018
|
-
scope = scopes.join(" ");
|
|
81019
|
-
}
|
|
81020
|
-
if (!authServer)
|
|
81021
|
-
authServer = origin;
|
|
81022
|
-
let asm = null;
|
|
81023
|
-
for (const url of authServerCandidates(authServer)) {
|
|
81024
|
-
asm = await fetchJsonSafe(f3, url);
|
|
81025
|
-
if (asm && asm.authorization_endpoint && asm.token_endpoint)
|
|
81026
|
-
break;
|
|
81027
|
-
asm = null;
|
|
81028
|
-
}
|
|
81029
|
-
if (!asm)
|
|
81030
|
-
throw new Error(`No OAuth metadata found for authorization server ${authServer}`);
|
|
81031
|
-
return {
|
|
81032
|
-
authorization_endpoint: asm.authorization_endpoint,
|
|
81033
|
-
token_endpoint: asm.token_endpoint,
|
|
81034
|
-
registration_endpoint: asm.registration_endpoint,
|
|
81035
|
-
resource,
|
|
81036
|
-
scope
|
|
81037
|
-
};
|
|
81038
|
-
}
|
|
81039
|
-
async function registerClient(meta, redirectUri, f3) {
|
|
81040
|
-
if (!meta.registration_endpoint) {
|
|
81041
|
-
throw new Error(
|
|
81042
|
-
'Authorization server does not support dynamic client registration; a client_id must be configured manually \u2014 create an OAuth client for this server, then re-run `nex mcp login <server> --client-id <id> [--client-secret <secret>]` (or set "clientId" / "clientSecret" in its mcp.json entry).'
|
|
81043
|
-
);
|
|
81044
|
-
}
|
|
81045
|
-
const resp = await f3(meta.registration_endpoint, {
|
|
81046
|
-
method: "POST",
|
|
81047
|
-
headers: { "Content-Type": "application/json", Accept: "application/json" },
|
|
81048
|
-
body: JSON.stringify({
|
|
81049
|
-
client_name: "Nexrall Code CLI",
|
|
81050
|
-
redirect_uris: [redirectUri],
|
|
81051
|
-
grant_types: ["authorization_code", "refresh_token"],
|
|
81052
|
-
response_types: ["code"],
|
|
81053
|
-
token_endpoint_auth_method: "none",
|
|
81054
|
-
scope: meta.scope
|
|
81055
|
-
})
|
|
81056
|
-
});
|
|
81057
|
-
if (!resp.ok)
|
|
81058
|
-
throw new Error(`Client registration failed (HTTP ${resp.status})`);
|
|
81059
|
-
const data = await resp.json();
|
|
81060
|
-
if (!data.client_id)
|
|
81061
|
-
throw new Error("Client registration returned no client_id");
|
|
81062
|
-
return data.client_id;
|
|
81063
|
-
}
|
|
81064
|
-
async function postToken(tokenEndpoint, body, f3) {
|
|
81065
|
-
const resp = await f3(tokenEndpoint, {
|
|
81066
|
-
method: "POST",
|
|
81067
|
-
headers: { "Content-Type": "application/x-www-form-urlencoded", Accept: "application/json" },
|
|
81068
|
-
body: body.toString()
|
|
81069
|
-
});
|
|
81070
|
-
if (!resp.ok) {
|
|
81071
|
-
const txt = await resp.text().catch(() => "");
|
|
81072
|
-
throw new Error(`Token endpoint error (HTTP ${resp.status})${txt ? `: ${txt.slice(0, 200)}` : ""}`);
|
|
81073
|
-
}
|
|
81074
|
-
return await resp.json();
|
|
81075
|
-
}
|
|
81076
|
-
async function exchangeCode(meta, clientId, clientSecret, code, verifier, redirectUri, f3) {
|
|
81077
|
-
const body = new URLSearchParams({
|
|
81078
|
-
grant_type: "authorization_code",
|
|
81079
|
-
code,
|
|
81080
|
-
redirect_uri: redirectUri,
|
|
81081
|
-
client_id: clientId,
|
|
81082
|
-
code_verifier: verifier,
|
|
81083
|
-
resource: meta.resource
|
|
81084
|
-
});
|
|
81085
|
-
if (clientSecret)
|
|
81086
|
-
body.set("client_secret", clientSecret);
|
|
81087
|
-
const data = await postToken(meta.token_endpoint, body, f3);
|
|
81088
|
-
return toBundle(data, {
|
|
81089
|
-
tokenEndpoint: meta.token_endpoint,
|
|
81090
|
-
clientId,
|
|
81091
|
-
clientSecret,
|
|
81092
|
-
resource: meta.resource,
|
|
81093
|
-
scope: meta.scope
|
|
81094
|
-
});
|
|
81095
|
-
}
|
|
81096
|
-
async function refreshAccessToken(bundle, f3) {
|
|
81097
|
-
const body = new URLSearchParams({
|
|
81098
|
-
grant_type: "refresh_token",
|
|
81099
|
-
refresh_token: bundle.refresh_token,
|
|
81100
|
-
client_id: bundle.client_id,
|
|
81101
|
-
resource: bundle.resource
|
|
81102
|
-
});
|
|
81103
|
-
if (bundle.client_secret)
|
|
81104
|
-
body.set("client_secret", bundle.client_secret);
|
|
81105
|
-
const data = await postToken(bundle.token_endpoint, body, f3);
|
|
81106
|
-
return toBundle(data, {
|
|
81107
|
-
tokenEndpoint: bundle.token_endpoint,
|
|
81108
|
-
clientId: bundle.client_id,
|
|
81109
|
-
clientSecret: bundle.client_secret,
|
|
81110
|
-
resource: bundle.resource,
|
|
81111
|
-
scope: bundle.scope,
|
|
81112
|
-
prevRefresh: bundle.refresh_token
|
|
81113
|
-
});
|
|
81114
|
-
}
|
|
81115
|
-
function startLoopback() {
|
|
81116
|
-
return new Promise((resolve19, reject) => {
|
|
81117
|
-
let resolveCode;
|
|
81118
|
-
let rejectCode;
|
|
81119
|
-
const codePromise = new Promise((res, rej) => {
|
|
81120
|
-
resolveCode = res;
|
|
81121
|
-
rejectCode = rej;
|
|
81122
|
-
});
|
|
81123
|
-
codePromise.catch(() => void 0);
|
|
81124
|
-
const server = http3.createServer((req, res) => {
|
|
81125
|
-
const url = new URL(req.url ?? "/", "http://127.0.0.1");
|
|
81126
|
-
if (url.pathname !== "/callback") {
|
|
81127
|
-
res.writeHead(404);
|
|
81128
|
-
res.end();
|
|
81129
|
-
return;
|
|
81130
|
-
}
|
|
81131
|
-
const code = url.searchParams.get("code");
|
|
81132
|
-
const state = url.searchParams.get("state");
|
|
81133
|
-
const error = url.searchParams.get("error");
|
|
81134
|
-
res.writeHead(200, { "Content-Type": "text/html", Connection: "close" });
|
|
81135
|
-
res.end(
|
|
81136
|
-
`<!doctype html><html><body style="font-family:system-ui;text-align:center;padding:40px"><h2>${error || !code ? "Authentication failed" : "Authentication complete"}</h2><p>You can close this tab and return to the terminal.</p></body></html>`
|
|
81137
|
-
);
|
|
81138
|
-
if (error) {
|
|
81139
|
-
rejectCode(new Error(`Authorization denied: ${error}`));
|
|
81140
|
-
return;
|
|
81141
|
-
}
|
|
81142
|
-
if (!code) {
|
|
81143
|
-
rejectCode(new Error("No authorization code in redirect"));
|
|
81144
|
-
return;
|
|
81145
|
-
}
|
|
81146
|
-
resolveCode({ code, state });
|
|
81147
|
-
});
|
|
81148
|
-
server.on("error", reject);
|
|
81149
|
-
server.listen(0, "127.0.0.1", () => {
|
|
81150
|
-
const port = server.address().port;
|
|
81151
|
-
resolve19({
|
|
81152
|
-
port,
|
|
81153
|
-
waitForCode(expectedState) {
|
|
81154
|
-
const timeout = setTimeout(
|
|
81155
|
-
() => rejectCode(new Error("Timed out waiting for authorization")),
|
|
81156
|
-
CALLBACK_TIMEOUT_MS
|
|
81157
|
-
);
|
|
81158
|
-
return codePromise.then(
|
|
81159
|
-
({ code, state }) => {
|
|
81160
|
-
clearTimeout(timeout);
|
|
81161
|
-
if (state !== expectedState)
|
|
81162
|
-
throw new Error("OAuth state mismatch \u2014 possible CSRF, aborting");
|
|
81163
|
-
return code;
|
|
81164
|
-
},
|
|
81165
|
-
// A denial must clear the timer too: otherwise `nex mcp login` reports the
|
|
81166
|
-
// failure but the process sits on a 5-minute keep-alive before exiting.
|
|
81167
|
-
(err) => {
|
|
81168
|
-
clearTimeout(timeout);
|
|
81169
|
-
throw err;
|
|
81170
|
-
}
|
|
81171
|
-
);
|
|
81172
|
-
},
|
|
81173
|
-
close() {
|
|
81174
|
-
try {
|
|
81175
|
-
server.closeAllConnections?.();
|
|
81176
|
-
} catch {
|
|
81177
|
-
}
|
|
81178
|
-
try {
|
|
81179
|
-
server.close();
|
|
81180
|
-
} catch {
|
|
81181
|
-
}
|
|
81182
|
-
}
|
|
81183
|
-
});
|
|
81184
|
-
});
|
|
81185
|
-
});
|
|
81186
|
-
}
|
|
81187
|
-
function b64url(buf) {
|
|
81188
|
-
return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
81189
|
-
}
|
|
81190
|
-
function openInBrowser(url) {
|
|
81191
|
-
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
81192
|
-
try {
|
|
81193
|
-
const child = spawn2(cmd, [url], { stdio: "ignore", detached: true, shell: process.platform === "win32" });
|
|
81194
|
-
child.on("error", () => void 0);
|
|
81195
|
-
child.unref();
|
|
81196
|
-
} catch {
|
|
81197
|
-
}
|
|
81198
|
-
}
|
|
81199
|
-
async function probeAuthChallenge(serverUrl, f3 = defaultFetch()) {
|
|
81200
|
-
const steps = [
|
|
81201
|
-
{
|
|
81202
|
-
method: "initialize",
|
|
81203
|
-
params: {
|
|
81204
|
-
protocolVersion: import_code_core9.MCP_PROTOCOL_VERSION,
|
|
81205
|
-
capabilities: {},
|
|
81206
|
-
clientInfo: { name: "nexrall-code", version: "1.0" }
|
|
81207
|
-
}
|
|
81208
|
-
},
|
|
81209
|
-
{ method: "tools/list", params: {} }
|
|
81210
|
-
];
|
|
81211
|
-
for (const { method, params } of steps) {
|
|
81212
|
-
try {
|
|
81213
|
-
const resp = await f3(serverUrl, {
|
|
81214
|
-
method: "POST",
|
|
81215
|
-
headers: { "Content-Type": "application/json", Accept: "application/json, text/event-stream" },
|
|
81216
|
-
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
|
|
81217
|
-
});
|
|
81218
|
-
const challenge = resp.headers?.get("www-authenticate") ?? "";
|
|
81219
|
-
if (challenge)
|
|
81220
|
-
return challenge;
|
|
81221
|
-
} catch {
|
|
81222
|
-
return "";
|
|
81223
|
-
}
|
|
81224
|
-
}
|
|
81225
|
-
return "";
|
|
81226
|
-
}
|
|
81227
|
-
async function authorizeServer(o) {
|
|
81228
|
-
const f3 = o.fetchImpl ?? defaultFetch();
|
|
81229
|
-
const challenge = o.wwwAuthenticate ?? await probeAuthChallenge(o.serverUrl, f3);
|
|
81230
|
-
const meta = await discover(o.serverUrl, challenge, f3);
|
|
81231
|
-
const scope = [meta.scope, (0, import_code_core9.parseOAuthChallenge)(challenge).scope, o.extraScope].map((s2) => s2?.trim()).filter((s2) => Boolean(s2)).join(" ").split(/\s+/).filter((s2, i2, a) => Boolean(s2) && a.indexOf(s2) === i2).join(" ");
|
|
81232
|
-
meta.scope = scope || void 0;
|
|
81233
|
-
const loopback = await startLoopback();
|
|
81234
|
-
const redirectUri = `http://127.0.0.1:${loopback.port}/callback`;
|
|
81235
|
-
try {
|
|
81236
|
-
const creds = o.credentials ?? {};
|
|
81237
|
-
let clientId;
|
|
81238
|
-
if (creds.clientId) {
|
|
81239
|
-
clientId = creds.clientId;
|
|
81240
|
-
o.onStep?.("Using the OAuth client configured for this server\u2026");
|
|
81241
|
-
} else {
|
|
81242
|
-
o.onStep?.(`Registering with ${new URL(meta.token_endpoint).origin}\u2026`);
|
|
81243
|
-
clientId = await registerClient(meta, redirectUri, f3);
|
|
81244
|
-
}
|
|
81245
|
-
const verifier = b64url(crypto.randomBytes(32));
|
|
81246
|
-
const challengeB64 = b64url(crypto.createHash("sha256").update(verifier).digest());
|
|
81247
|
-
const state = b64url(crypto.randomBytes(16));
|
|
81248
|
-
const authUrl = buildAuthorizeUrl(meta, { clientId, redirectUri, codeChallenge: challengeB64, state });
|
|
81249
|
-
o.onStep?.("Opening your browser to authorize\u2026");
|
|
81250
|
-
await o.openUrl(authUrl);
|
|
81251
|
-
const code = await loopback.waitForCode(state);
|
|
81252
|
-
const bundle = await exchangeCode(meta, clientId, creds.clientSecret, code, verifier, redirectUri, f3);
|
|
81253
|
-
saveToken(o.server, bundle, o.file ?? tokensFile());
|
|
81254
|
-
} finally {
|
|
81255
|
-
loopback.close();
|
|
81256
|
-
}
|
|
81257
|
-
}
|
|
81258
|
-
var isRemote = (cfg) => cfg.type === "http" || cfg.type === "sse" || !cfg.command && !!cfg.url;
|
|
81259
|
-
async function injectMcpTokens(config, opts = {}) {
|
|
81260
|
-
const file = opts.file ?? tokensFile();
|
|
81261
|
-
const injected = [];
|
|
81262
|
-
for (const [name, cfg] of Object.entries(config.mcpServers ?? {})) {
|
|
81263
|
-
if (!isRemote(cfg))
|
|
81264
|
-
continue;
|
|
81265
|
-
const hasAuth = cfg.headers && Object.keys(cfg.headers).some((h2) => h2.toLowerCase() === "authorization");
|
|
81266
|
-
if (hasAuth)
|
|
81267
|
-
continue;
|
|
81268
|
-
let token;
|
|
81269
|
-
try {
|
|
81270
|
-
token = await getValidAccessToken(name, { file, fetchImpl: opts.fetchImpl });
|
|
81271
|
-
} catch {
|
|
81272
|
-
token = null;
|
|
81273
|
-
}
|
|
81274
|
-
if (!token)
|
|
81275
|
-
continue;
|
|
81276
|
-
cfg.headers = { ...cfg.headers ?? {}, Authorization: `Bearer ${token}` };
|
|
81277
|
-
injected.push(name);
|
|
81278
|
-
}
|
|
81279
|
-
return injected;
|
|
81280
|
-
}
|
|
81281
81604
|
|
|
81282
81605
|
// src/commands/mcpCmd.ts
|
|
81283
81606
|
var import_code_core10 = __toESM(require_dist2(), 1);
|
|
@@ -82344,7 +82667,7 @@ function classify(err, opts) {
|
|
|
82344
82667
|
return {
|
|
82345
82668
|
kind: "auth",
|
|
82346
82669
|
title: "Not signed in",
|
|
82347
|
-
hints: ["Run `
|
|
82670
|
+
hints: ["Run `nex auth` to sign in again", "Your session keeps its place: /resume picks it back up"]
|
|
82348
82671
|
};
|
|
82349
82672
|
}
|
|
82350
82673
|
if (status === 429 || RATE_RE.test(msg)) {
|
|
@@ -82463,15 +82786,15 @@ async function executeMcpResourceTool(name, input, mgr) {
|
|
|
82463
82786
|
}
|
|
82464
82787
|
|
|
82465
82788
|
// src/ui/clipboardImage.ts
|
|
82789
|
+
var import_proc3 = __toESM(require_proc(), 1);
|
|
82466
82790
|
import * as fs6 from "fs";
|
|
82467
82791
|
import * as os3 from "os";
|
|
82468
82792
|
import * as path5 from "path";
|
|
82469
|
-
import { spawnSync } from "child_process";
|
|
82470
82793
|
var MAX_PASTE_BYTES = 10 * 1024 * 1024;
|
|
82471
82794
|
var PNG_MAGIC = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
|
82472
82795
|
var realRunner = (cmd, args) => {
|
|
82473
82796
|
try {
|
|
82474
|
-
return spawnSync(cmd, args, { stdio: "ignore", timeout: 8e3 }).status === 0;
|
|
82797
|
+
return (0, import_proc3.spawnSync)(cmd, args, { stdio: "ignore", timeout: 8e3 }).status === 0;
|
|
82475
82798
|
} catch {
|
|
82476
82799
|
return false;
|
|
82477
82800
|
}
|
|
@@ -83009,7 +83332,7 @@ function capEffortForScale(levels, effort, cap) {
|
|
|
83009
83332
|
var import_code_core26 = __toESM(require_dist2(), 1);
|
|
83010
83333
|
|
|
83011
83334
|
// src/ui/statusLine.ts
|
|
83012
|
-
|
|
83335
|
+
var import_proc4 = __toESM(require_proc(), 1);
|
|
83013
83336
|
var STATUSLINE_TIMEOUT_MS = 2e3;
|
|
83014
83337
|
var MIN_INTERVAL_MS2 = 1500;
|
|
83015
83338
|
var MAX_OUTPUT_BYTES = 4096;
|
|
@@ -83056,7 +83379,7 @@ var shellRunner = (command, stdin, cwd2, timeoutMs) => new Promise((resolve19) =
|
|
|
83056
83379
|
};
|
|
83057
83380
|
let child;
|
|
83058
83381
|
try {
|
|
83059
|
-
child =
|
|
83382
|
+
child = (0, import_proc4.spawn)(command, { shell: true, cwd: cwd2, stdio: ["pipe", "pipe", "ignore"], env: process.env });
|
|
83060
83383
|
} catch {
|
|
83061
83384
|
resolve19(null);
|
|
83062
83385
|
return;
|
|
@@ -84838,12 +85161,12 @@ function formatDeployTargets(targets, cols3) {
|
|
|
84838
85161
|
}
|
|
84839
85162
|
|
|
84840
85163
|
// src/commands/chat.ts
|
|
85164
|
+
var import_proc12 = __toESM(require_proc(), 1);
|
|
84841
85165
|
var import_code_core66 = __toESM(require_dist2(), 1);
|
|
84842
85166
|
import * as os17 from "os";
|
|
84843
85167
|
import * as crypto4 from "crypto";
|
|
84844
85168
|
import { createRequire } from "module";
|
|
84845
85169
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
84846
|
-
import { execFile as execFile2, execFileSync as execFileSync6 } from "child_process";
|
|
84847
85170
|
|
|
84848
85171
|
// src/permissions/handler.ts
|
|
84849
85172
|
import * as readline2 from "readline";
|
|
@@ -87118,17 +87441,17 @@ function debugLog(event, fields) {
|
|
|
87118
87441
|
}
|
|
87119
87442
|
|
|
87120
87443
|
// src/commands/doctor.ts
|
|
87444
|
+
var import_proc6 = __toESM(require_proc(), 1);
|
|
87121
87445
|
var import_code_core46 = __toESM(require_dist2(), 1);
|
|
87122
87446
|
import fs11 from "fs";
|
|
87123
87447
|
import os6 from "os";
|
|
87124
87448
|
import path13 from "path";
|
|
87125
|
-
import { spawnSync as spawnSync3, execFileSync as execFileSync2 } from "child_process";
|
|
87126
87449
|
|
|
87127
87450
|
// src/commands/sessionTools.ts
|
|
87451
|
+
var import_proc5 = __toESM(require_proc(), 1);
|
|
87128
87452
|
var import_code_core42 = __toESM(require_dist2(), 1);
|
|
87129
87453
|
var import_code_core43 = __toESM(require_dist2(), 1);
|
|
87130
87454
|
var import_code_core44 = __toESM(require_dist2(), 1);
|
|
87131
|
-
import { spawnSync as spawnSync2, execFileSync } from "child_process";
|
|
87132
87455
|
var UsageTotals = class {
|
|
87133
87456
|
input = 0;
|
|
87134
87457
|
output = 0;
|
|
@@ -87221,7 +87544,7 @@ function copyToClipboard(text, platform3 = process.platform) {
|
|
|
87221
87544
|
];
|
|
87222
87545
|
for (const [cmd, args] of candidates) {
|
|
87223
87546
|
try {
|
|
87224
|
-
const r2 =
|
|
87547
|
+
const r2 = (0, import_proc5.spawnSync)(cmd, args, { input: text, stdio: ["pipe", "ignore", "ignore"], timeout: 5e3 });
|
|
87225
87548
|
if (!r2.error && r2.status === 0)
|
|
87226
87549
|
return cmd;
|
|
87227
87550
|
} catch {
|
|
@@ -87233,7 +87556,7 @@ function osc52(text) {
|
|
|
87233
87556
|
return `\x1B]52;c;${Buffer.from(text, "utf8").toString("base64")}\x07`;
|
|
87234
87557
|
}
|
|
87235
87558
|
function gitChanges(cwd2) {
|
|
87236
|
-
const run = (args) => execFileSync("git", args, { cwd: cwd2, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 1e4 }).trimEnd();
|
|
87559
|
+
const run = (args) => (0, import_proc5.execFileSync)("git", args, { cwd: cwd2, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"], timeout: 1e4 }).trimEnd();
|
|
87237
87560
|
try {
|
|
87238
87561
|
run(["rev-parse", "--is-inside-work-tree"]);
|
|
87239
87562
|
return { status: run(["status", "--short"]), stat: run(["diff", "--stat", "HEAD"]) };
|
|
@@ -87714,7 +88037,7 @@ function doctorExitCode(checks) {
|
|
|
87714
88037
|
return checks.some((c) => c.status === "fail") ? 1 : 0;
|
|
87715
88038
|
}
|
|
87716
88039
|
function commandExists(cmd, platform3 = process.platform) {
|
|
87717
|
-
const r2 =
|
|
88040
|
+
const r2 = (0, import_proc6.spawnSync)(platform3 === "win32" ? "where" : "which", [cmd], { stdio: "ignore", timeout: 5e3 });
|
|
87718
88041
|
return !r2.error && r2.status === 0;
|
|
87719
88042
|
}
|
|
87720
88043
|
function ripgrepInstallHint(platform3) {
|
|
@@ -87765,7 +88088,7 @@ function realProbes(c) {
|
|
|
87765
88088
|
resolveRipgrep: () => (0, import_code_core46.resolveRipgrepBinary)(),
|
|
87766
88089
|
gitInfo: () => {
|
|
87767
88090
|
try {
|
|
87768
|
-
|
|
88091
|
+
(0, import_proc6.execFileSync)("git", ["rev-parse", "--is-inside-work-tree"], { cwd: c.workDir, stdio: "ignore", timeout: 5e3 });
|
|
87769
88092
|
return { inRepo: true, branch: (0, import_code_core43.gitBranch)(c.workDir) ?? void 0 };
|
|
87770
88093
|
} catch {
|
|
87771
88094
|
return { inRepo: false };
|
|
@@ -87847,7 +88170,7 @@ function knownSessionIds() {
|
|
|
87847
88170
|
}
|
|
87848
88171
|
};
|
|
87849
88172
|
add(SESSIONS_DIR, ".json");
|
|
87850
|
-
add((0,
|
|
88173
|
+
add((0, import_code_core7.eventsDir)(), ".jsonl");
|
|
87851
88174
|
return [...ids];
|
|
87852
88175
|
}
|
|
87853
88176
|
function findSessionsByLink(link2) {
|
|
@@ -87920,7 +88243,7 @@ function deleteSession(id) {
|
|
|
87920
88243
|
return false;
|
|
87921
88244
|
}
|
|
87922
88245
|
try {
|
|
87923
|
-
fs12.unlinkSync((0,
|
|
88246
|
+
fs12.unlinkSync((0, import_code_core7.eventsPath)(r2.id));
|
|
87924
88247
|
} catch {
|
|
87925
88248
|
}
|
|
87926
88249
|
return true;
|
|
@@ -87954,7 +88277,7 @@ function exportSession(id, events) {
|
|
|
87954
88277
|
version: 1,
|
|
87955
88278
|
exportedAt: Date.now(),
|
|
87956
88279
|
session,
|
|
87957
|
-
events: events ?? (0,
|
|
88280
|
+
events: events ?? (0, import_code_core7.readEvents)(r2.id)
|
|
87958
88281
|
};
|
|
87959
88282
|
return JSON.stringify(bundle, null, 2);
|
|
87960
88283
|
}
|
|
@@ -87996,7 +88319,7 @@ function importSession(bundle) {
|
|
|
87996
88319
|
renamed = true;
|
|
87997
88320
|
}
|
|
87998
88321
|
saveSession(id, title, bundle.session.workDir || process.cwd(), bundle.session.messages);
|
|
87999
|
-
(0,
|
|
88322
|
+
(0, import_code_core7.writeEvents)(id, bundle.events);
|
|
88000
88323
|
return { id, messages: bundle.session.messages.length, renamed };
|
|
88001
88324
|
}
|
|
88002
88325
|
|
|
@@ -88232,7 +88555,7 @@ async function enableAppleTerminalOptionAsMeta(deps) {
|
|
|
88232
88555
|
}
|
|
88233
88556
|
|
|
88234
88557
|
// src/commands/update.ts
|
|
88235
|
-
|
|
88558
|
+
var import_proc7 = __toESM(require_proc(), 1);
|
|
88236
88559
|
import * as fs13 from "fs";
|
|
88237
88560
|
import * as https2 from "https";
|
|
88238
88561
|
import * as path16 from "path";
|
|
@@ -88285,7 +88608,7 @@ function installArgs(version) {
|
|
|
88285
88608
|
}
|
|
88286
88609
|
function installedGlobalVersion() {
|
|
88287
88610
|
try {
|
|
88288
|
-
const root =
|
|
88611
|
+
const root = (0, import_proc7.execFileSync)("npm", ["root", "-g"], { encoding: "utf-8" }).trim();
|
|
88289
88612
|
return JSON.parse(fs13.readFileSync(path16.join(root, "nexrall-code", "package.json"), "utf-8")).version ?? null;
|
|
88290
88613
|
} catch {
|
|
88291
88614
|
return null;
|
|
@@ -88293,7 +88616,7 @@ function installedGlobalVersion() {
|
|
|
88293
88616
|
}
|
|
88294
88617
|
function npmInstallGlobal(version) {
|
|
88295
88618
|
return new Promise((resolve19) => {
|
|
88296
|
-
const child =
|
|
88619
|
+
const child = (0, import_proc7.spawn)("npm", installArgs(version), { stdio: "pipe" });
|
|
88297
88620
|
let stderr = "";
|
|
88298
88621
|
child.stderr?.on("data", (c) => {
|
|
88299
88622
|
stderr += c.toString();
|
|
@@ -88302,7 +88625,7 @@ function npmInstallGlobal(version) {
|
|
|
88302
88625
|
if (code === 0)
|
|
88303
88626
|
return resolve19({ ok: true, usedSudo: false });
|
|
88304
88627
|
if (/EACCES|permission denied/i.test(stderr)) {
|
|
88305
|
-
const sudo =
|
|
88628
|
+
const sudo = (0, import_proc7.spawn)("sudo", ["npm", ...installArgs(version)], { stdio: "inherit" });
|
|
88306
88629
|
sudo.on("close", (sudoCode) => resolve19({ ok: sudoCode === 0, usedSudo: true }));
|
|
88307
88630
|
} else {
|
|
88308
88631
|
console.error(paint.dim(stderr.trim()));
|
|
@@ -98194,6 +98517,11 @@ var BUILTIN_SLASH_COMMANDS = [
|
|
|
98194
98517
|
kind: "builtin"
|
|
98195
98518
|
},
|
|
98196
98519
|
{ name: "cost", description: "Where the tokens and money went (per model, per agent, per turn)", kind: "builtin" },
|
|
98520
|
+
{
|
|
98521
|
+
name: "logout",
|
|
98522
|
+
description: "Sign out on this machine (revokes the saved refresh token)",
|
|
98523
|
+
kind: "builtin"
|
|
98524
|
+
},
|
|
98197
98525
|
{
|
|
98198
98526
|
name: "stats",
|
|
98199
98527
|
description: "Usage across sessions: activity by day, tokens and models (local event logs)",
|
|
@@ -99340,9 +99668,9 @@ function decidePick(item, tab2) {
|
|
|
99340
99668
|
}
|
|
99341
99669
|
|
|
99342
99670
|
// src/commands/bangShell.ts
|
|
99671
|
+
var import_proc8 = __toESM(require_proc(), 1);
|
|
99343
99672
|
var import_code_core50 = __toESM(require_dist2(), 1);
|
|
99344
99673
|
var import_code_core51 = __toESM(require_dist2(), 1);
|
|
99345
|
-
import { spawn as spawn5 } from "child_process";
|
|
99346
99674
|
function parseBang(line) {
|
|
99347
99675
|
const t2 = line.trim();
|
|
99348
99676
|
if (!t2.startsWith("!"))
|
|
@@ -99365,18 +99693,14 @@ function runBang(cmd, opts) {
|
|
|
99365
99693
|
let aborted = false;
|
|
99366
99694
|
let settled = false;
|
|
99367
99695
|
let detached = false;
|
|
99368
|
-
const
|
|
99369
|
-
|
|
99370
|
-
env: opts.env ?? process.env,
|
|
99371
|
-
stdio: ["ignore", "pipe", "pipe"],
|
|
99372
|
-
detached: process.platform !== "win32"
|
|
99373
|
-
});
|
|
99696
|
+
const common = { cwd: opts.cwd, env: opts.env ?? process.env, stdio: ["ignore", "pipe", "pipe"] };
|
|
99697
|
+
const child = import_proc8.IS_WINDOWS ? (0, import_proc8.spawn)(cmd, { ...common, shell: true }) : (0, import_proc8.spawn)("bash", ["-c", cmd], { ...common, detached: true });
|
|
99374
99698
|
const kill = () => {
|
|
99375
99699
|
try {
|
|
99376
99700
|
if (child.pid && process.platform !== "win32")
|
|
99377
99701
|
process.kill(-child.pid, "SIGTERM");
|
|
99378
99702
|
else
|
|
99379
|
-
child.
|
|
99703
|
+
(0, import_proc8.killProcessTree)(child.pid);
|
|
99380
99704
|
} catch {
|
|
99381
99705
|
}
|
|
99382
99706
|
setTimeout(() => {
|
|
@@ -99537,16 +99861,16 @@ function searchMeta(scope, origin) {
|
|
|
99537
99861
|
var SEARCH_HINT = " type to search \xB7 Ctrl+R older \xB7 Ctrl+S all/this project \xB7 Enter/Tab use it \xB7 Esc cancel";
|
|
99538
99862
|
|
|
99539
99863
|
// src/ui/externalEditor.ts
|
|
99864
|
+
var import_proc9 = __toESM(require_proc(), 1);
|
|
99540
99865
|
import * as fs20 from "fs";
|
|
99541
99866
|
import * as os13 from "os";
|
|
99542
99867
|
import * as path20 from "path";
|
|
99543
|
-
import { spawnSync as spawnSync4 } from "child_process";
|
|
99544
99868
|
function resolveEditor(env3) {
|
|
99545
99869
|
const pick = (v) => v && v.trim() ? v.trim() : null;
|
|
99546
99870
|
return pick(env3.VISUAL) ?? pick(env3.EDITOR) ?? "vi";
|
|
99547
99871
|
}
|
|
99548
99872
|
function defaultRun(editor, file) {
|
|
99549
|
-
const r2 =
|
|
99873
|
+
const r2 = process.platform === "win32" ? (0, import_proc9.spawnSync)(`${editor} "${file}"`, { stdio: "inherit", shell: true }) : (0, import_proc9.spawnSync)("sh", ["-c", `${editor} "$1"`, "sh", file], { stdio: "inherit" });
|
|
99550
99874
|
return { status: r2.status, error: r2.error };
|
|
99551
99875
|
}
|
|
99552
99876
|
function editInEditor(text, opts = {}) {
|
|
@@ -99579,7 +99903,7 @@ function editInEditor(text, opts = {}) {
|
|
|
99579
99903
|
}
|
|
99580
99904
|
|
|
99581
99905
|
// src/ui/openInEditor.ts
|
|
99582
|
-
|
|
99906
|
+
var import_proc10 = __toESM(require_proc(), 1);
|
|
99583
99907
|
import * as fs21 from "node:fs";
|
|
99584
99908
|
import * as os14 from "node:os";
|
|
99585
99909
|
import * as path21 from "node:path";
|
|
@@ -99799,7 +100123,7 @@ function launchEditor(spec, target, opts = {}) {
|
|
|
99799
100123
|
const needsShell = /\s/.test(spec.command);
|
|
99800
100124
|
const argv = () => needsShell ? ["sh", ["-c", `${spec.command} "$@"`, "sh", ...args]] : [spec.command, args];
|
|
99801
100125
|
if (spec.kind === "gui") {
|
|
99802
|
-
const runSpawn = opts.spawnImpl ??
|
|
100126
|
+
const runSpawn = opts.spawnImpl ?? import_proc10.spawn;
|
|
99803
100127
|
try {
|
|
99804
100128
|
const child = runSpawn(...argv(), { detached: true, stdio: "ignore" });
|
|
99805
100129
|
child.on("error", (e2) => opts.onAsyncError?.(`could not start ${spec.command}: ${e2.message}`));
|
|
@@ -99809,7 +100133,7 @@ function launchEditor(spec, target, opts = {}) {
|
|
|
99809
100133
|
return { ok: false, reason: `could not start ${spec.command}: ${e2.message}` };
|
|
99810
100134
|
}
|
|
99811
100135
|
}
|
|
99812
|
-
const r2 = (opts.spawnSyncImpl ??
|
|
100136
|
+
const r2 = (opts.spawnSyncImpl ?? import_proc10.spawnSync)(...argv(), { stdio: "inherit" });
|
|
99813
100137
|
if (r2.error)
|
|
99814
100138
|
return { ok: false, reason: `could not start ${spec.command}: ${r2.error.message}` };
|
|
99815
100139
|
if (typeof r2.status === "number" && r2.status !== 0)
|
|
@@ -99826,9 +100150,9 @@ function describeOpen(spec, target, cwd2) {
|
|
|
99826
100150
|
}
|
|
99827
100151
|
|
|
99828
100152
|
// src/ui/fileMention.ts
|
|
100153
|
+
var import_proc11 = __toESM(require_proc(), 1);
|
|
99829
100154
|
import * as fs22 from "fs";
|
|
99830
100155
|
import * as path22 from "path";
|
|
99831
|
-
import { execFile, execFileSync as execFileSync5 } from "child_process";
|
|
99832
100156
|
|
|
99833
100157
|
// src/ui/contextFiles.ts
|
|
99834
100158
|
var import_code_core52 = __toESM(require_dist2(), 1);
|
|
@@ -99873,7 +100197,7 @@ function listProjectFiles(cwd2) {
|
|
|
99873
100197
|
function listProjectFilesFrom(cwd2) {
|
|
99874
100198
|
let files = null;
|
|
99875
100199
|
try {
|
|
99876
|
-
const out =
|
|
100200
|
+
const out = (0, import_proc11.execFileSync)("git", ["-C", cwd2, "ls-files", "-co", "--exclude-standard", "-z"], {
|
|
99877
100201
|
encoding: "utf-8",
|
|
99878
100202
|
maxBuffer: 64 * 1024 * 1024,
|
|
99879
100203
|
stdio: ["ignore", "pipe", "ignore"],
|
|
@@ -100009,7 +100333,7 @@ function primeMentionIndex(cwd2) {
|
|
|
100009
100333
|
building.cancelled = true;
|
|
100010
100334
|
const job = { cwd: cwd2, cancelled: false };
|
|
100011
100335
|
building = job;
|
|
100012
|
-
execFile(
|
|
100336
|
+
(0, import_proc11.execFile)(
|
|
100013
100337
|
"git",
|
|
100014
100338
|
["-C", cwd2, "ls-files", "-co", "--exclude-standard", "-z"],
|
|
100015
100339
|
{
|
|
@@ -103752,7 +104076,7 @@ function scanRecentSkillEvents(dir, maxFiles = DOCTOR_SESSION_WINDOW) {
|
|
|
103752
104076
|
const out = [];
|
|
103753
104077
|
for (const { full } of withTime.slice(0, maxFiles)) {
|
|
103754
104078
|
try {
|
|
103755
|
-
out.push((0,
|
|
104079
|
+
out.push((0, import_code_core7.readEvents)("", { file: full }));
|
|
103756
104080
|
} catch {
|
|
103757
104081
|
}
|
|
103758
104082
|
}
|
|
@@ -104364,7 +104688,7 @@ function agentFooterBadge() {
|
|
|
104364
104688
|
}
|
|
104365
104689
|
var runGitForMerge = (cwd2, args) => {
|
|
104366
104690
|
try {
|
|
104367
|
-
const stdout =
|
|
104691
|
+
const stdout = (0, import_proc12.execFileSync)("git", args, {
|
|
104368
104692
|
cwd: cwd2,
|
|
104369
104693
|
encoding: "utf-8",
|
|
104370
104694
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -104621,7 +104945,7 @@ function resolveModelLabel(alias) {
|
|
|
104621
104945
|
async function tryExecAsync(file, args, cwd2) {
|
|
104622
104946
|
return new Promise((resolve19) => {
|
|
104623
104947
|
try {
|
|
104624
|
-
|
|
104948
|
+
(0, import_proc12.execFile)(file, args, { cwd: cwd2, encoding: "utf-8" }, (err, stdout) => {
|
|
104625
104949
|
resolve19(err ? void 0 : String(stdout).trim() || void 0);
|
|
104626
104950
|
});
|
|
104627
104951
|
} catch {
|
|
@@ -105300,7 +105624,7 @@ function emitEvent(type, data = {}) {
|
|
|
105300
105624
|
}
|
|
105301
105625
|
function startSessionLog(id, resumed, extra = {}) {
|
|
105302
105626
|
const previous = liveSessionId;
|
|
105303
|
-
sessionLog = (0,
|
|
105627
|
+
sessionLog = (0, import_code_core7.eventsEnabled)() ? new import_code_core7.EventLog(id) : null;
|
|
105304
105628
|
liveSessionId = id;
|
|
105305
105629
|
if (previous && previous !== id)
|
|
105306
105630
|
(0, import_code_core22.rebindSessionShare)(id);
|
|
@@ -105645,7 +105969,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrall
|
|
|
105645
105969
|
emitEvent("tool.started", {
|
|
105646
105970
|
name,
|
|
105647
105971
|
sub: !!isSubTask,
|
|
105648
|
-
target: name === "use_skill" && typeof input.name === "string" ? input.name : (0,
|
|
105972
|
+
target: name === "use_skill" && typeof input.name === "string" ? input.name : (0, import_code_core7.toolTarget)(name, input)
|
|
105649
105973
|
});
|
|
105650
105974
|
if (!isSubTask)
|
|
105651
105975
|
sessionToolCalls++;
|
|
@@ -105698,7 +106022,7 @@ async function runTurn(messages, modelAlias, workDir, abortSignal, env3, nexrall
|
|
|
105698
106022
|
const changed = noteToolResult(turnStats, tracked?.name ?? name, tracked?.input, cmdOk);
|
|
105699
106023
|
for (const t2 of changed)
|
|
105700
106024
|
failureLedger.noteEdit(t2);
|
|
105701
|
-
for (const t2 of changed.slice(0,
|
|
106025
|
+
for (const t2 of changed.slice(0, import_code_core7.MAX_FILE_EVENTS))
|
|
105702
106026
|
emitEvent("file.changed", { path: t2 });
|
|
105703
106027
|
}
|
|
105704
106028
|
if (!isSubTask && tracked?.command)
|
|
@@ -106040,7 +106364,7 @@ async function runTurnHeadless(messages, modelAlias, workDir, _abortSignal, env3
|
|
|
106040
106364
|
onToolUse: (name, input, isSubTask, meta) => {
|
|
106041
106365
|
debugLog("tool_use", { tool: name, sub: !!isSubTask });
|
|
106042
106366
|
emit({ type: "tool_use", tool: name, input, ...toolIds(isSubTask, meta) });
|
|
106043
|
-
verbose(`[verbose] -> ${name}${isSubTask ? " (sub-agent)" : ""} ${(0,
|
|
106367
|
+
verbose(`[verbose] -> ${name}${isSubTask ? " (sub-agent)" : ""} ${(0, import_code_core7.toolTarget)(name, input)}`);
|
|
106044
106368
|
},
|
|
106045
106369
|
// Live bash progress for scripted/CI consumers — lets a wrapper tail a
|
|
106046
106370
|
// long-running build/test command instead of blocking silently until
|
|
@@ -106320,6 +106644,7 @@ function printHelp() {
|
|
|
106320
106644
|
["/yolo", "Auto-approve all permissions"],
|
|
106321
106645
|
["/balance", "Show what is paying (personal wallet or team) and what is left"],
|
|
106322
106646
|
["/team [use <id|personal>]", "List your teams, or switch what usage is billed to"],
|
|
106647
|
+
["/logout", "Sign out on this machine (revokes the saved refresh token)"],
|
|
106323
106648
|
["/cost [--all]", "Cost and tokens: per model, per sub-agent, per turn (/balance shows the wallet)"],
|
|
106324
106649
|
["/stats", "Usage across sessions: activity by day, tokens and models (local event logs)"],
|
|
106325
106650
|
[
|
|
@@ -107036,7 +107361,7 @@ Resume it with: nex --worktree ${worktreeState.name}
|
|
|
107036
107361
|
console.log(paint.green(` Resumed session: ${paint.bold(stored.title.slice(0, 60))}`));
|
|
107037
107362
|
console.log(paint.dim(` ${messages.length} messages restored`));
|
|
107038
107363
|
if (autoRecap) {
|
|
107039
|
-
const recap = (0, import_code_core33.buildRecap)((0,
|
|
107364
|
+
const recap = (0, import_code_core33.buildRecap)((0, import_code_core7.readEvents)(stored.id, { last: import_code_core33.RECAP_EVENT_WINDOW }), { now: Date.now() });
|
|
107040
107365
|
if (recap)
|
|
107041
107366
|
console.log(paint.dim(` Recap: ${recap}`));
|
|
107042
107367
|
}
|
|
@@ -108876,6 +109201,26 @@ ${dirList}`;
|
|
|
108876
109201
|
rl.prompt();
|
|
108877
109202
|
return;
|
|
108878
109203
|
}
|
|
109204
|
+
case "/logout": {
|
|
109205
|
+
const answer = await new Promise(
|
|
109206
|
+
(resolve19) => rl.question(paint.yellow(" Sign out on this machine? ") + paint.dim("[y/n] "), (a) => resolve19(a.trim()))
|
|
109207
|
+
);
|
|
109208
|
+
if (answer !== "y" && answer !== "yes") {
|
|
109209
|
+
console.log(paint.dim(" Cancelled."));
|
|
109210
|
+
rl.prompt();
|
|
109211
|
+
return;
|
|
109212
|
+
}
|
|
109213
|
+
await signOut();
|
|
109214
|
+
console.log(paint.green(" \u2713 Logged out."));
|
|
109215
|
+
if (process.env.NEXRALL_TOKEN?.trim()) {
|
|
109216
|
+
console.log(
|
|
109217
|
+
paint.yellow(" NEXRALL_TOKEN is still set in this shell") + paint.dim(" \u2014 unset it, or the CLI stays signed in with that token.")
|
|
109218
|
+
);
|
|
109219
|
+
}
|
|
109220
|
+
console.log(paint.dim(" Run `nex auth` (in any terminal) to sign in again; this session picks it up."));
|
|
109221
|
+
rl.prompt();
|
|
109222
|
+
return;
|
|
109223
|
+
}
|
|
108879
109224
|
case "/cost": {
|
|
108880
109225
|
const parsed = parseCostArgs(arg);
|
|
108881
109226
|
if ("error" in parsed) {
|
|
@@ -108938,14 +109283,14 @@ ${dirList}`;
|
|
|
108938
109283
|
return;
|
|
108939
109284
|
}
|
|
108940
109285
|
case "/recap": {
|
|
108941
|
-
if (!(0,
|
|
109286
|
+
if (!(0, import_code_core7.eventsEnabled)()) {
|
|
108942
109287
|
console.log(
|
|
108943
109288
|
paint.dim(" Events are off for this run (NEXRALL_EVENTS=off), so there is nothing to read back.")
|
|
108944
109289
|
);
|
|
108945
109290
|
rl.prompt();
|
|
108946
109291
|
return;
|
|
108947
109292
|
}
|
|
108948
|
-
const recap = (0, import_code_core33.buildRecap)((0,
|
|
109293
|
+
const recap = (0, import_code_core33.buildRecap)((0, import_code_core7.readEvents)(sessionId, { last: import_code_core33.RECAP_EVENT_WINDOW }), { now: Date.now() });
|
|
108949
109294
|
console.log();
|
|
108950
109295
|
if (recap)
|
|
108951
109296
|
console.log(` ${paint.bold("Recap: ")}${recap}`);
|
|
@@ -109509,11 +109854,11 @@ ${dirList}`;
|
|
|
109509
109854
|
return;
|
|
109510
109855
|
}
|
|
109511
109856
|
if (!(0, import_code_core64.getToken)()) {
|
|
109512
|
-
console.log(paint.yellow(" Sign in first (`nex
|
|
109857
|
+
console.log(paint.yellow(" Sign in first (`nex auth`) \u2014 watching uses your Nexrall account."));
|
|
109513
109858
|
rl.prompt();
|
|
109514
109859
|
return;
|
|
109515
109860
|
}
|
|
109516
|
-
if (!(0,
|
|
109861
|
+
if (!(0, import_code_core7.eventsEnabled)()) {
|
|
109517
109862
|
console.log(
|
|
109518
109863
|
paint.yellow(" Sharing follows the event stream, and this run has it off (NEXRALL_EVENTS=off).")
|
|
109519
109864
|
);
|
|
@@ -109617,7 +109962,7 @@ ${dirList}`;
|
|
|
109617
109962
|
}
|
|
109618
109963
|
if (!(0, import_code_core64.getToken)()) {
|
|
109619
109964
|
console.log(
|
|
109620
|
-
paint.yellow(" Sign in first (`nex
|
|
109965
|
+
paint.yellow(" Sign in first (`nex auth`) \u2014 pushes find this session through your account.")
|
|
109621
109966
|
);
|
|
109622
109967
|
rl.prompt();
|
|
109623
109968
|
return;
|
|
@@ -109688,7 +110033,7 @@ ${dirList}`;
|
|
|
109688
110033
|
}
|
|
109689
110034
|
case "/schedule":
|
|
109690
110035
|
case "/routines": {
|
|
109691
|
-
const action = (0,
|
|
110036
|
+
const action = (0, import_code_core4.parseScheduleChatArg)(arg);
|
|
109692
110037
|
if (action.kind === "error") {
|
|
109693
110038
|
console.log(paint.yellow(" " + action.message));
|
|
109694
110039
|
rl.prompt();
|
|
@@ -109699,7 +110044,7 @@ ${dirList}`;
|
|
|
109699
110044
|
const panelCols = Math.max(60, (process.stdout.columns || 100) - 2);
|
|
109700
110045
|
if (action.kind === "list") {
|
|
109701
110046
|
const list = await (0, import_code_core63.listCloudSchedules)();
|
|
109702
|
-
for (const l of (0,
|
|
110047
|
+
for (const l of (0, import_code_core4.scheduleListLines)(list, { cols: panelCols }))
|
|
109703
110048
|
console.log(" " + l);
|
|
109704
110049
|
if (list.length)
|
|
109705
110050
|
console.log(
|
|
@@ -109709,7 +110054,7 @@ ${dirList}`;
|
|
|
109709
110054
|
const s2 = await (0, import_code_core63.createCloudSchedule)({ task: action.task, intervalMinutes: action.intervalMinutes });
|
|
109710
110055
|
console.log(
|
|
109711
110056
|
paint.green(
|
|
109712
|
-
` \u2713 Scheduled #${s2.id} \u2014 every ${(0,
|
|
110057
|
+
` \u2713 Scheduled #${s2.id} \u2014 every ${(0, import_code_core4.formatEvery)(s2.intervalMinutes)}${s2.nextRunAt ? `, next run ${(0, import_code_core4.fmtScheduleWhen)(s2.nextRunAt)}` : ""}.`
|
|
109713
110058
|
)
|
|
109714
110059
|
);
|
|
109715
110060
|
console.log(
|
|
@@ -109727,7 +110072,7 @@ ${dirList}`;
|
|
|
109727
110072
|
console.log(paint.dim(` Removed schedule #${action.id} \u2014 no further runs fire.`));
|
|
109728
110073
|
} else {
|
|
109729
110074
|
const runs2 = await (0, import_code_core63.getCloudScheduleRuns)(action.id);
|
|
109730
|
-
for (const l of (0,
|
|
110075
|
+
for (const l of (0, import_code_core4.scheduleRunsLines)(runs2, { cols: panelCols }))
|
|
109731
110076
|
console.log(" " + l);
|
|
109732
110077
|
}
|
|
109733
110078
|
} catch (err) {
|
|
@@ -109945,7 +110290,7 @@ ${dirList}`;
|
|
|
109945
110290
|
};
|
|
109946
110291
|
const want = arg.trim();
|
|
109947
110292
|
if (want) {
|
|
109948
|
-
const hit = (0,
|
|
110293
|
+
const hit = (0, import_code_core8.findFiles)(files, want);
|
|
109949
110294
|
if (!hit.length)
|
|
109950
110295
|
console.log(paint.dim(` No changed file matches "${want}". (/diff lists them all)`));
|
|
109951
110296
|
else if (hit.length > 1) {
|
|
@@ -109954,14 +110299,14 @@ ${dirList}`;
|
|
|
109954
110299
|
console.log(" " + f3.path);
|
|
109955
110300
|
} else {
|
|
109956
110301
|
verification.noteDiffReviewed();
|
|
109957
|
-
out((0,
|
|
110302
|
+
out((0, import_code_core8.capLines)((0, import_code_core8.renderFile)(hit[0], { foldHunks: false })));
|
|
109958
110303
|
}
|
|
109959
110304
|
} else {
|
|
109960
110305
|
console.log(paint.bold(" Uncommitted changes"));
|
|
109961
|
-
out((0,
|
|
110306
|
+
out((0, import_code_core8.summaryLines)(files));
|
|
109962
110307
|
console.log();
|
|
109963
110308
|
verification.noteDiffReviewed();
|
|
109964
|
-
out((0,
|
|
110309
|
+
out((0, import_code_core8.renderAll)(files));
|
|
109965
110310
|
}
|
|
109966
110311
|
rl.prompt();
|
|
109967
110312
|
return;
|
|
@@ -109982,7 +110327,7 @@ ${dirList}`;
|
|
|
109982
110327
|
const emit = (line) => console.log(truncateCells(line, cols3));
|
|
109983
110328
|
const want = arg.replace(/(^|\s)--all(?=\s|$)/, " ").trim();
|
|
109984
110329
|
if (want) {
|
|
109985
|
-
const hit = (0,
|
|
110330
|
+
const hit = (0, import_code_core8.findFiles)(files, want);
|
|
109986
110331
|
if (!hit.length)
|
|
109987
110332
|
emit(paint.dim(` No changed file matches "${want}". (/review lists them all)`));
|
|
109988
110333
|
else if (hit.length > 1) {
|
|
@@ -109990,14 +110335,14 @@ ${dirList}`;
|
|
|
109990
110335
|
for (const f3 of hit.slice(0, 10))
|
|
109991
110336
|
emit(" " + f3.path);
|
|
109992
110337
|
} else {
|
|
109993
|
-
const ctx = { tests: files.filter((x2) => (0,
|
|
109994
|
-
for (const line of (0,
|
|
110338
|
+
const ctx = { tests: files.filter((x2) => (0, import_code_core9.isTestPath)(x2.path)) };
|
|
110339
|
+
for (const line of (0, import_code_core9.formatReviewDetail)((0, import_code_core9.classifyFile)(hit[0], ctx), cols3))
|
|
109995
110340
|
emit(" " + line);
|
|
109996
110341
|
}
|
|
109997
110342
|
} else {
|
|
109998
110343
|
const all = /(^|\s)--all(\s|$)/.test(arg);
|
|
109999
|
-
const q = (0,
|
|
110000
|
-
for (const line of (0,
|
|
110344
|
+
const q = (0, import_code_core9.buildReviewQueue)(files, all ? Number.POSITIVE_INFINITY : import_code_core9.DEFAULT_PER_GROUP);
|
|
110345
|
+
for (const line of (0, import_code_core9.formatReviewQueue)(q, cols3))
|
|
110001
110346
|
emit(" " + line);
|
|
110002
110347
|
emit(paint.dim(" /review <file> for one entry's reasons \xB7 /diff for the change itself"));
|
|
110003
110348
|
}
|
|
@@ -110643,7 +110988,7 @@ ${text}
|
|
|
110643
110988
|
const res = await enableAppleTerminalOptionAsMeta({
|
|
110644
110989
|
run: async (cmd2, args) => {
|
|
110645
110990
|
try {
|
|
110646
|
-
const stdout =
|
|
110991
|
+
const stdout = (0, import_proc12.execFileSync)(cmd2, args, { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] });
|
|
110647
110992
|
return { code: 0, stdout };
|
|
110648
110993
|
} catch (err) {
|
|
110649
110994
|
const e2 = err;
|
|
@@ -110774,7 +111119,7 @@ ${text}
|
|
|
110774
111119
|
}
|
|
110775
111120
|
case "/skill-doctor": {
|
|
110776
111121
|
const loadedSkills = (0, import_code_core66.loadSkills)(workDir);
|
|
110777
|
-
const usage2 = collectSkillUsage(scanRecentSkillEvents((0,
|
|
111122
|
+
const usage2 = collectSkillUsage(scanRecentSkillEvents((0, import_code_core7.eventsDir)()));
|
|
110778
111123
|
for (const l of buildSkillDoctorReport(loadedSkills, usage2).lines)
|
|
110779
111124
|
console.log(l);
|
|
110780
111125
|
rl.prompt();
|
|
@@ -112212,11 +112557,11 @@ function pluginSourceRemoveCommand(name, opts) {
|
|
|
112212
112557
|
}
|
|
112213
112558
|
|
|
112214
112559
|
// src/commands/pluginEvalCmd.ts
|
|
112560
|
+
var import_proc13 = __toESM(require_proc(), 1);
|
|
112215
112561
|
var import_code_core71 = __toESM(require_dist2(), 1);
|
|
112216
112562
|
import * as fs27 from "fs";
|
|
112217
112563
|
import * as os18 from "os";
|
|
112218
112564
|
import * as path28 from "path";
|
|
112219
|
-
import { spawn as spawn7 } from "node:child_process";
|
|
112220
112565
|
function pluginEvalInitCommand(dir) {
|
|
112221
112566
|
const target = path28.resolve(dir ?? process.cwd());
|
|
112222
112567
|
const displayPath = (p) => {
|
|
@@ -112328,7 +112673,7 @@ function walkFiles(root) {
|
|
|
112328
112673
|
}
|
|
112329
112674
|
function runChild(args, cwd2, env3, timeoutMs) {
|
|
112330
112675
|
return new Promise((resolve19) => {
|
|
112331
|
-
const child =
|
|
112676
|
+
const child = (0, import_proc13.spawn)(process.execPath, args, {
|
|
112332
112677
|
cwd: cwd2,
|
|
112333
112678
|
env: env3,
|
|
112334
112679
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -112682,7 +113027,7 @@ function planProjectPurge(targetDir, env3 = process.env) {
|
|
|
112682
113027
|
}
|
|
112683
113028
|
}
|
|
112684
113029
|
for (const id of sessionIds) {
|
|
112685
|
-
const p = (0,
|
|
113030
|
+
const p = (0, import_code_core7.eventsPath)(id, env3);
|
|
112686
113031
|
if (fs28.existsSync(p))
|
|
112687
113032
|
items.push({ kind: "events", path: p, dir: false });
|
|
112688
113033
|
}
|
|
@@ -112836,11 +113181,11 @@ async function projectPurgeCommand(dir, opts = {}) {
|
|
|
112836
113181
|
}
|
|
112837
113182
|
|
|
112838
113183
|
// src/commands/sessionPlugins.ts
|
|
113184
|
+
var import_proc14 = __toESM(require_proc(), 1);
|
|
112839
113185
|
var import_code_core73 = __toESM(require_dist2(), 1);
|
|
112840
113186
|
import * as fs29 from "node:fs";
|
|
112841
113187
|
import * as os20 from "node:os";
|
|
112842
113188
|
import * as path30 from "node:path";
|
|
112843
|
-
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
112844
113189
|
var MAX_ARCHIVE_BYTES = 50 * 1024 * 1024;
|
|
112845
113190
|
function mkTemp(label) {
|
|
112846
113191
|
return fs29.mkdtempSync(path30.join(os20.tmpdir(), `nex-${label}-`));
|
|
@@ -112862,7 +113207,14 @@ function descendIntoWrapper(root) {
|
|
|
112862
113207
|
return root;
|
|
112863
113208
|
}
|
|
112864
113209
|
function extractZip(archive, dest) {
|
|
112865
|
-
|
|
113210
|
+
if (process.platform === "win32") {
|
|
113211
|
+
const t2 = (0, import_proc14.spawnSync)("tar", ["-xf", archive, "-C", dest], { encoding: "utf-8", timeout: 6e4 });
|
|
113212
|
+
if (t2.status !== 0) {
|
|
113213
|
+
return { ok: false, error: `tar failed: ${(t2.stderr ?? "").trim() || (t2.error?.message ?? "unknown error")}` };
|
|
113214
|
+
}
|
|
113215
|
+
return { ok: true };
|
|
113216
|
+
}
|
|
113217
|
+
const r2 = (0, import_proc14.spawnSync)("unzip", ["-o", "-q", archive, "-d", dest], { encoding: "utf-8", timeout: 6e4 });
|
|
112866
113218
|
if (r2.error && r2.error.code === "ENOENT") {
|
|
112867
113219
|
return { ok: false, error: "The `unzip` command was not found \u2014 install it, or use a .tar.gz archive." };
|
|
112868
113220
|
}
|
|
@@ -112872,7 +113224,7 @@ function extractZip(archive, dest) {
|
|
|
112872
113224
|
return { ok: true };
|
|
112873
113225
|
}
|
|
112874
113226
|
function extractTarGz(archive, dest) {
|
|
112875
|
-
const r2 =
|
|
113227
|
+
const r2 = (0, import_proc14.spawnSync)("tar", ["-xzf", archive, "-C", dest], { encoding: "utf-8", timeout: 6e4 });
|
|
112876
113228
|
if (r2.status !== 0) {
|
|
112877
113229
|
return { ok: false, error: `tar failed: ${(r2.stderr ?? "").trim() || (r2.error?.message ?? "unknown error")}` };
|
|
112878
113230
|
}
|
|
@@ -113239,11 +113591,11 @@ async function autoModeResetCommand(opts) {
|
|
|
113239
113591
|
var import_code_core79 = __toESM(require_dist2(), 1);
|
|
113240
113592
|
|
|
113241
113593
|
// src/commands/bgJobs.ts
|
|
113594
|
+
var import_proc15 = __toESM(require_proc(), 1);
|
|
113242
113595
|
import * as fs31 from "node:fs";
|
|
113243
113596
|
import * as os22 from "node:os";
|
|
113244
113597
|
import * as path32 from "node:path";
|
|
113245
113598
|
import * as crypto5 from "node:crypto";
|
|
113246
|
-
import { spawn as spawn8 } from "node:child_process";
|
|
113247
113599
|
function bgDir(env3 = process.env) {
|
|
113248
113600
|
return env3.NEXRALL_CLI_BG_DIR || path32.join(os22.homedir(), ".nexrall", "cli-bg");
|
|
113249
113601
|
}
|
|
@@ -113306,9 +113658,11 @@ function startJob(o) {
|
|
|
113306
113658
|
const codeFile = path32.join(dir, `${id}.code`);
|
|
113307
113659
|
const fd = fs31.openSync(log, "a");
|
|
113308
113660
|
const command = o.shell !== void 0 ? ["/bin/sh", "-c", o.shell] : [o.execPath ?? process.execPath, o.script ?? "", ...o.args ?? []];
|
|
113309
|
-
const
|
|
113661
|
+
const [wrapBin, wrapArgs] = wrapperArgv(codeFile, command, o.shell, process.execPath);
|
|
113662
|
+
const child = (0, import_proc15.spawn)(wrapBin, wrapArgs, {
|
|
113310
113663
|
cwd: o.cwd,
|
|
113311
|
-
detached:
|
|
113664
|
+
detached: !import_proc15.IS_WINDOWS,
|
|
113665
|
+
// detached on Windows = DETACHED_PROCESS: ignores windowsHide, pops a console
|
|
113312
113666
|
stdio: ["ignore", fd, fd],
|
|
113313
113667
|
env: { ...process.env, NEXRALL_BG_JOB: id }
|
|
113314
113668
|
});
|
|
@@ -113368,6 +113722,23 @@ function respawnJob(job, opts) {
|
|
|
113368
113722
|
});
|
|
113369
113723
|
return { ok: true, job: meta };
|
|
113370
113724
|
}
|
|
113725
|
+
var WIN_WRAPPER = [
|
|
113726
|
+
"const {spawn}=require('child_process'),fs=require('fs');",
|
|
113727
|
+
"const [codeFile,mode,...rest]=process.argv.slice(1);",
|
|
113728
|
+
"const o={stdio:'inherit',windowsHide:true};",
|
|
113729
|
+
"const c=mode==='shell'?spawn(rest[0],{...o,shell:true}):spawn(rest[0],rest.slice(1),o);",
|
|
113730
|
+
"c.on('error',()=>{fs.writeFileSync(codeFile,'127\\n');process.exit(127)});",
|
|
113731
|
+
"c.on('exit',(code)=>{fs.writeFileSync(codeFile,String(code??1)+'\\n');process.exit(code??1)});"
|
|
113732
|
+
].join("");
|
|
113733
|
+
function wrapperArgv(codeFile, command, shell, nodePath) {
|
|
113734
|
+
if (import_proc15.IS_WINDOWS) {
|
|
113735
|
+
return [
|
|
113736
|
+
nodePath,
|
|
113737
|
+
["-e", WIN_WRAPPER, codeFile, shell !== void 0 ? "shell" : "argv", ...shell !== void 0 ? [shell] : command]
|
|
113738
|
+
];
|
|
113739
|
+
}
|
|
113740
|
+
return ["/bin/sh", ["-c", '"$@"; echo $? > "$0"', codeFile, ...command]];
|
|
113741
|
+
}
|
|
113371
113742
|
function killJob(job, dir = bgDir()) {
|
|
113372
113743
|
if (job.state !== "running")
|
|
113373
113744
|
return false;
|
|
@@ -113375,6 +113746,10 @@ function killJob(job, dir = bgDir()) {
|
|
|
113375
113746
|
fs31.writeFileSync(path32.join(dir, `${job.id}.killed`), "");
|
|
113376
113747
|
} catch {
|
|
113377
113748
|
}
|
|
113749
|
+
if (import_proc15.IS_WINDOWS) {
|
|
113750
|
+
(0, import_proc15.killProcessTree)(job.pid);
|
|
113751
|
+
return true;
|
|
113752
|
+
}
|
|
113378
113753
|
try {
|
|
113379
113754
|
process.kill(-job.pid, "SIGTERM");
|
|
113380
113755
|
return true;
|
|
@@ -113936,7 +114311,7 @@ var NEX_VERSION = require3("../package.json").version;
|
|
|
113936
114311
|
installEpipeGuard();
|
|
113937
114312
|
var program2 = new Command();
|
|
113938
114313
|
program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version(NEX_VERSION).enablePositionalOptions();
|
|
113939
|
-
var auth = program2.command("auth").description("
|
|
114314
|
+
var auth = program2.command("auth").alias("login").description("Log in (browser, email + password, or a token)").option("--browser", "Sign in through the browser \u2014 works for Google, Apple and SSO accounts").option("--code <code>", "Finish a browser sign-in with a code you already copied (no browser is opened)").option("--token <token>", "Save a token directly (CI/headless). Prefer NEXRALL_TOKEN where you can").option("--password", "Ask for email and password in this terminal (skips the method menu)").action(authCommand);
|
|
113940
114315
|
auth.command("status").description("Show whether you are logged in (exit 0 = yes, 1 = no). --json for scripts; the token is never printed").option("--json", "Machine-readable output").action((opts) => {
|
|
113941
114316
|
const r2 = authStatusReport((0, import_code_core79.loadAuth)(), process.env);
|
|
113942
114317
|
if (opts.json)
|
|
@@ -114394,7 +114769,7 @@ program2.command("sessions").description("List, export, import, or delete saved
|
|
|
114394
114769
|
process.exitCode = 1;
|
|
114395
114770
|
return;
|
|
114396
114771
|
}
|
|
114397
|
-
const events = (0,
|
|
114772
|
+
const events = (0, import_code_core7.readEvents)(hit.id, { last: Number.isFinite(want) && want > 0 ? want : 20 });
|
|
114398
114773
|
if (!events.length) {
|
|
114399
114774
|
console.log(
|
|
114400
114775
|
paint.dim(` No events recorded for ${hit.id.slice(0, 8)} (NEXRALL_EVENTS=off disables the stream).`)
|
|
@@ -114409,9 +114784,9 @@ program2.command("sessions").description("List, export, import, or delete saved
|
|
|
114409
114784
|
console.log();
|
|
114410
114785
|
console.log(paint.bold(` Events for ${hit.id.slice(0, 8)} `) + paint.dim(`(last ${events.length})`));
|
|
114411
114786
|
for (const ev of events)
|
|
114412
|
-
console.log(" " + paint.dim((0,
|
|
114787
|
+
console.log(" " + paint.dim((0, import_code_core7.summarizeEvent)(ev)));
|
|
114413
114788
|
console.log(paint.dim(`
|
|
114414
|
-
Raw JSONL: ${(0,
|
|
114789
|
+
Raw JSONL: ${(0, import_code_core7.eventsPath)(hit.id)}`));
|
|
114415
114790
|
console.log();
|
|
114416
114791
|
return;
|
|
114417
114792
|
}
|