nexrall-code 0.5.159 → 0.5.161
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +108 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -10369,9 +10369,18 @@ var require_client = __commonJS({
|
|
|
10369
10369
|
const haveCompleteMessage = () => completedMessage !== null;
|
|
10370
10370
|
const partialInputs = {};
|
|
10371
10371
|
let heartbeatWatchdog;
|
|
10372
|
+
let onControllerAbort;
|
|
10372
10373
|
try {
|
|
10373
10374
|
await new Promise((resolve11, reject) => {
|
|
10374
10375
|
const stream = response.body;
|
|
10376
|
+
onControllerAbort = () => {
|
|
10377
|
+
stream.destroy?.();
|
|
10378
|
+
resolve11();
|
|
10379
|
+
};
|
|
10380
|
+
if (controller.signal.aborted)
|
|
10381
|
+
onControllerAbort();
|
|
10382
|
+
else
|
|
10383
|
+
controller.signal.addEventListener("abort", onControllerAbort, { once: true });
|
|
10375
10384
|
const HEARTBEAT_TIMEOUT_MS = 9e4;
|
|
10376
10385
|
const FIRST_EVENT_TIMEOUT_MS = Number(process.env.NEXRALL_FIRST_EVENT_TIMEOUT_MS) || 3e5;
|
|
10377
10386
|
const PROGRESS_TIMEOUT_MS = Number(process.env.NEXRALL_PROGRESS_TIMEOUT_MS) || 15e4;
|
|
@@ -10646,6 +10655,8 @@ var require_client = __commonJS({
|
|
|
10646
10655
|
} finally {
|
|
10647
10656
|
if (heartbeatWatchdog !== void 0)
|
|
10648
10657
|
clearInterval(heartbeatWatchdog);
|
|
10658
|
+
if (onControllerAbort)
|
|
10659
|
+
controller.signal.removeEventListener("abort", onControllerAbort);
|
|
10649
10660
|
}
|
|
10650
10661
|
if (completedMessage) {
|
|
10651
10662
|
return completedMessage;
|
|
@@ -172524,6 +172535,8 @@ function jobState(dir, m2) {
|
|
|
172524
172535
|
if (Number.isFinite(n))
|
|
172525
172536
|
return { state: n === 0 ? "done" : "failed", exitCode: n };
|
|
172526
172537
|
}
|
|
172538
|
+
if (fs25.existsSync(path25.join(dir, `${m2.id}.killed`)))
|
|
172539
|
+
return { state: alive(m2.pid) ? "running" : "killed" };
|
|
172527
172540
|
return { state: alive(m2.pid) ? "running" : "lost" };
|
|
172528
172541
|
}
|
|
172529
172542
|
function listJobs(dir = bgDir()) {
|
|
@@ -172574,9 +172587,13 @@ function startJob(o) {
|
|
|
172574
172587
|
fs25.writeFileSync(path25.join(dir, `${id}.json`), JSON.stringify(meta));
|
|
172575
172588
|
return meta;
|
|
172576
172589
|
}
|
|
172577
|
-
function killJob(job) {
|
|
172590
|
+
function killJob(job, dir = bgDir()) {
|
|
172578
172591
|
if (job.state !== "running")
|
|
172579
172592
|
return false;
|
|
172593
|
+
try {
|
|
172594
|
+
fs25.writeFileSync(path25.join(dir, `${job.id}.killed`), "");
|
|
172595
|
+
} catch {
|
|
172596
|
+
}
|
|
172580
172597
|
try {
|
|
172581
172598
|
process.kill(-job.pid, "SIGTERM");
|
|
172582
172599
|
return true;
|
|
@@ -172601,9 +172618,67 @@ function formatJobs(jobs) {
|
|
|
172601
172618
|
return `${j.id} ${st.padEnd(11)} ${ago(j.startedAt).padStart(4)} ago ${j.prompt.replace(/\s+/g, " ").slice(0, 60)}`;
|
|
172602
172619
|
}).join("\n");
|
|
172603
172620
|
}
|
|
172604
|
-
|
|
172621
|
+
function renderJobLine(line) {
|
|
172622
|
+
const t2 = line.trim();
|
|
172623
|
+
if (!t2)
|
|
172624
|
+
return "";
|
|
172625
|
+
let o;
|
|
172626
|
+
try {
|
|
172627
|
+
o = JSON.parse(t2);
|
|
172628
|
+
} catch {
|
|
172629
|
+
return line + "\n";
|
|
172630
|
+
}
|
|
172631
|
+
switch (o.type) {
|
|
172632
|
+
case "start":
|
|
172633
|
+
return `\u2500\u2500 started (${o.model ?? "model"})
|
|
172634
|
+
`;
|
|
172635
|
+
case "text":
|
|
172636
|
+
return o.text ?? "";
|
|
172637
|
+
case "tool_use": {
|
|
172638
|
+
const inp = o.input && typeof o.input === "object" ? Object.values(o.input).find((v) => typeof v === "string") : void 0;
|
|
172639
|
+
return `
|
|
172640
|
+
\u25B8 ${o.tool}${inp ? " " + inp.replace(/\s+/g, " ").slice(0, 80) : ""}
|
|
172641
|
+
`;
|
|
172642
|
+
}
|
|
172643
|
+
case "tool_result":
|
|
172644
|
+
return o.ok === false ? ` \u2717 ${o.tool}: ${o.error ?? "failed"}
|
|
172645
|
+
` : ` \u2713 ${o.tool}
|
|
172646
|
+
`;
|
|
172647
|
+
case "permission_denied":
|
|
172648
|
+
return ` \u2717 denied: ${o.tool ?? ""} ${o.reason ?? ""}
|
|
172649
|
+
`;
|
|
172650
|
+
case "error":
|
|
172651
|
+
return `
|
|
172652
|
+
\u2717 error: ${o.error ?? ""}
|
|
172653
|
+
`;
|
|
172654
|
+
case "budget_exceeded":
|
|
172655
|
+
return "\n\u2717 budget exceeded\n";
|
|
172656
|
+
case "result":
|
|
172657
|
+
return `
|
|
172658
|
+
\u2500\u2500 done
|
|
172659
|
+
`;
|
|
172660
|
+
default:
|
|
172661
|
+
return "";
|
|
172662
|
+
}
|
|
172663
|
+
}
|
|
172664
|
+
async function followLog(job, follow, write = (s2) => process.stdout.write(s2), dir = bgDir(), pretty = false) {
|
|
172605
172665
|
const log = path25.join(dir, `${job.id}.log`);
|
|
172606
172666
|
let pos = 0;
|
|
172667
|
+
let carry = "";
|
|
172668
|
+
const emit = (chunk) => {
|
|
172669
|
+
if (!pretty) {
|
|
172670
|
+
write(chunk);
|
|
172671
|
+
return;
|
|
172672
|
+
}
|
|
172673
|
+
carry += chunk;
|
|
172674
|
+
const lines = carry.split("\n");
|
|
172675
|
+
carry = lines.pop() ?? "";
|
|
172676
|
+
for (const l2 of lines) {
|
|
172677
|
+
const r2 = renderJobLine(l2);
|
|
172678
|
+
if (r2)
|
|
172679
|
+
write(r2);
|
|
172680
|
+
}
|
|
172681
|
+
};
|
|
172607
172682
|
const drain = () => {
|
|
172608
172683
|
let size = 0;
|
|
172609
172684
|
try {
|
|
@@ -172617,7 +172692,7 @@ async function followLog(job, follow, write = (s2) => process.stdout.write(s2),
|
|
|
172617
172692
|
try {
|
|
172618
172693
|
const buf = Buffer.alloc(size - pos);
|
|
172619
172694
|
fs25.readSync(fd, buf, 0, buf.length, pos);
|
|
172620
|
-
|
|
172695
|
+
emit(buf.toString("utf8"));
|
|
172621
172696
|
pos = size;
|
|
172622
172697
|
} finally {
|
|
172623
172698
|
fs25.closeSync(fd);
|
|
@@ -172631,7 +172706,12 @@ async function followLog(job, follow, write = (s2) => process.stdout.write(s2),
|
|
|
172631
172706
|
drain();
|
|
172632
172707
|
if (st.state !== "running") {
|
|
172633
172708
|
drain();
|
|
172634
|
-
|
|
172709
|
+
if (carry) {
|
|
172710
|
+
const r2 = pretty ? renderJobLine(carry) : carry;
|
|
172711
|
+
if (r2)
|
|
172712
|
+
write(r2);
|
|
172713
|
+
}
|
|
172714
|
+
return st.exitCode ?? (st.state === "done" ? 0 : 1);
|
|
172635
172715
|
}
|
|
172636
172716
|
await new Promise((r2) => setTimeout(r2, 300));
|
|
172637
172717
|
}
|
|
@@ -172883,13 +172963,13 @@ program2.command("logs <id>").description("Print a background job's output").opt
|
|
|
172883
172963
|
}
|
|
172884
172964
|
process.exit(await followLog(r2.job, !!opts.follow));
|
|
172885
172965
|
});
|
|
172886
|
-
program2.command("attach <id>").description("
|
|
172966
|
+
program2.command("attach <id>").description("Watch a background job live, readable (tool calls, text, result). Ctrl+C detaches; the job keeps running").action(async (id) => {
|
|
172887
172967
|
const r2 = resolveJob(id);
|
|
172888
172968
|
if (!r2.ok) {
|
|
172889
172969
|
console.error(r2.error);
|
|
172890
172970
|
process.exit(1);
|
|
172891
172971
|
}
|
|
172892
|
-
process.exit(await followLog(r2.job, true));
|
|
172972
|
+
process.exit(await followLog(r2.job, true, void 0, void 0, true));
|
|
172893
172973
|
});
|
|
172894
172974
|
program2.command("kill <id>").description("Stop a background job").action((id) => {
|
|
172895
172975
|
const r2 = resolveJob(id);
|
|
@@ -173100,24 +173180,6 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173100
173180
|
console.error("--strict-mcp-config needs --mcp-config.");
|
|
173101
173181
|
process.exit(1);
|
|
173102
173182
|
}
|
|
173103
|
-
if (options.bg) {
|
|
173104
|
-
if (!promptParts.length) {
|
|
173105
|
-
console.error('--bg needs a prompt: nex --bg "your task"');
|
|
173106
|
-
process.exit(1);
|
|
173107
|
-
}
|
|
173108
|
-
if (process.env.NEXRALL_BG_JOB) {
|
|
173109
|
-
console.error("--bg cannot be nested inside a background job.");
|
|
173110
|
-
process.exit(1);
|
|
173111
|
-
}
|
|
173112
|
-
const args = stripBgFlag(process.argv.slice(2));
|
|
173113
|
-
if (!options.outputFormat)
|
|
173114
|
-
args.push("--output-format", "stream-json");
|
|
173115
|
-
const job = startJob({ script: process.argv[1], args, cwd: process.cwd(), prompt: promptParts.join(" ") });
|
|
173116
|
-
console.log(`Started background job ${job.id}`);
|
|
173117
|
-
console.log(` nex logs ${job.id} -f follow its output`);
|
|
173118
|
-
console.log(` nex jobs list jobs \xB7 nex kill ${job.id} stop it`);
|
|
173119
|
-
process.exit(0);
|
|
173120
|
-
}
|
|
173121
173183
|
const addDirs = parseAddDirs(options.addDir, process.cwd());
|
|
173122
173184
|
if (!addDirs.ok) {
|
|
173123
173185
|
console.error(addDirs.error);
|
|
@@ -173142,6 +173204,28 @@ program2.option("-p, --pro", "Use Claude Opus 5.5 (most capable)").option("-t, -
|
|
|
173142
173204
|
console.error(`Invalid --input-format "${options.inputFormat}". Use: text | stream-json`);
|
|
173143
173205
|
process.exit(1);
|
|
173144
173206
|
}
|
|
173207
|
+
if (options.bg) {
|
|
173208
|
+
if (!promptParts.length) {
|
|
173209
|
+
console.error('--bg needs a prompt: nex --bg "your task"');
|
|
173210
|
+
process.exit(1);
|
|
173211
|
+
}
|
|
173212
|
+
if (inFmt === "stream-json") {
|
|
173213
|
+
console.error("--bg cannot read stream-json from stdin (a background job has no stdin). Pass the prompt as an argument.");
|
|
173214
|
+
process.exit(1);
|
|
173215
|
+
}
|
|
173216
|
+
if (process.env.NEXRALL_BG_JOB) {
|
|
173217
|
+
console.error("--bg cannot be nested inside a background job.");
|
|
173218
|
+
process.exit(1);
|
|
173219
|
+
}
|
|
173220
|
+
const args = stripBgFlag(process.argv.slice(2));
|
|
173221
|
+
if (!options.outputFormat)
|
|
173222
|
+
args.push("--output-format", "stream-json");
|
|
173223
|
+
const job = startJob({ script: process.argv[1], args, cwd: process.cwd(), prompt: promptParts.join(" ") });
|
|
173224
|
+
console.log(`Started background job ${job.id}`);
|
|
173225
|
+
console.log(` nex logs ${job.id} -f follow its output`);
|
|
173226
|
+
console.log(` nex jobs list jobs \xB7 nex kill ${job.id} stop it`);
|
|
173227
|
+
process.exit(0);
|
|
173228
|
+
}
|
|
173145
173229
|
const resume = options.resume === true ? "last" : typeof options.resume === "string" ? options.resume : void 0;
|
|
173146
173230
|
const worktree = options.worktree === true ? true : typeof options.worktree === "string" ? options.worktree : void 0;
|
|
173147
173231
|
let stdinText;
|