nexrall-code 0.5.159 → 0.5.160

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.
Files changed (2) hide show
  1. package/dist/index.js +75 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -172524,6 +172524,8 @@ function jobState(dir, m2) {
172524
172524
  if (Number.isFinite(n))
172525
172525
  return { state: n === 0 ? "done" : "failed", exitCode: n };
172526
172526
  }
172527
+ if (fs25.existsSync(path25.join(dir, `${m2.id}.killed`)))
172528
+ return { state: alive(m2.pid) ? "running" : "killed" };
172527
172529
  return { state: alive(m2.pid) ? "running" : "lost" };
172528
172530
  }
172529
172531
  function listJobs(dir = bgDir()) {
@@ -172574,9 +172576,13 @@ function startJob(o) {
172574
172576
  fs25.writeFileSync(path25.join(dir, `${id}.json`), JSON.stringify(meta));
172575
172577
  return meta;
172576
172578
  }
172577
- function killJob(job) {
172579
+ function killJob(job, dir = bgDir()) {
172578
172580
  if (job.state !== "running")
172579
172581
  return false;
172582
+ try {
172583
+ fs25.writeFileSync(path25.join(dir, `${job.id}.killed`), "");
172584
+ } catch {
172585
+ }
172580
172586
  try {
172581
172587
  process.kill(-job.pid, "SIGTERM");
172582
172588
  return true;
@@ -172601,9 +172607,67 @@ function formatJobs(jobs) {
172601
172607
  return `${j.id} ${st.padEnd(11)} ${ago(j.startedAt).padStart(4)} ago ${j.prompt.replace(/\s+/g, " ").slice(0, 60)}`;
172602
172608
  }).join("\n");
172603
172609
  }
172604
- async function followLog(job, follow, write = (s2) => process.stdout.write(s2), dir = bgDir()) {
172610
+ function renderJobLine(line) {
172611
+ const t2 = line.trim();
172612
+ if (!t2)
172613
+ return "";
172614
+ let o;
172615
+ try {
172616
+ o = JSON.parse(t2);
172617
+ } catch {
172618
+ return line + "\n";
172619
+ }
172620
+ switch (o.type) {
172621
+ case "start":
172622
+ return `\u2500\u2500 started (${o.model ?? "model"})
172623
+ `;
172624
+ case "text":
172625
+ return o.text ?? "";
172626
+ case "tool_use": {
172627
+ const inp = o.input && typeof o.input === "object" ? Object.values(o.input).find((v) => typeof v === "string") : void 0;
172628
+ return `
172629
+ \u25B8 ${o.tool}${inp ? " " + inp.replace(/\s+/g, " ").slice(0, 80) : ""}
172630
+ `;
172631
+ }
172632
+ case "tool_result":
172633
+ return o.ok === false ? ` \u2717 ${o.tool}: ${o.error ?? "failed"}
172634
+ ` : ` \u2713 ${o.tool}
172635
+ `;
172636
+ case "permission_denied":
172637
+ return ` \u2717 denied: ${o.tool ?? ""} ${o.reason ?? ""}
172638
+ `;
172639
+ case "error":
172640
+ return `
172641
+ \u2717 error: ${o.error ?? ""}
172642
+ `;
172643
+ case "budget_exceeded":
172644
+ return "\n\u2717 budget exceeded\n";
172645
+ case "result":
172646
+ return `
172647
+ \u2500\u2500 done
172648
+ `;
172649
+ default:
172650
+ return "";
172651
+ }
172652
+ }
172653
+ async function followLog(job, follow, write = (s2) => process.stdout.write(s2), dir = bgDir(), pretty = false) {
172605
172654
  const log = path25.join(dir, `${job.id}.log`);
172606
172655
  let pos = 0;
172656
+ let carry = "";
172657
+ const emit = (chunk) => {
172658
+ if (!pretty) {
172659
+ write(chunk);
172660
+ return;
172661
+ }
172662
+ carry += chunk;
172663
+ const lines = carry.split("\n");
172664
+ carry = lines.pop() ?? "";
172665
+ for (const l2 of lines) {
172666
+ const r2 = renderJobLine(l2);
172667
+ if (r2)
172668
+ write(r2);
172669
+ }
172670
+ };
172607
172671
  const drain = () => {
172608
172672
  let size = 0;
172609
172673
  try {
@@ -172617,7 +172681,7 @@ async function followLog(job, follow, write = (s2) => process.stdout.write(s2),
172617
172681
  try {
172618
172682
  const buf = Buffer.alloc(size - pos);
172619
172683
  fs25.readSync(fd, buf, 0, buf.length, pos);
172620
- write(buf.toString("utf8"));
172684
+ emit(buf.toString("utf8"));
172621
172685
  pos = size;
172622
172686
  } finally {
172623
172687
  fs25.closeSync(fd);
@@ -172631,7 +172695,12 @@ async function followLog(job, follow, write = (s2) => process.stdout.write(s2),
172631
172695
  drain();
172632
172696
  if (st.state !== "running") {
172633
172697
  drain();
172634
- return st.exitCode ?? (st.state === "lost" ? 1 : 0);
172698
+ if (carry) {
172699
+ const r2 = pretty ? renderJobLine(carry) : carry;
172700
+ if (r2)
172701
+ write(r2);
172702
+ }
172703
+ return st.exitCode ?? (st.state === "done" ? 0 : 1);
172635
172704
  }
172636
172705
  await new Promise((r2) => setTimeout(r2, 300));
172637
172706
  }
@@ -172883,13 +172952,13 @@ program2.command("logs <id>").description("Print a background job's output").opt
172883
172952
  }
172884
172953
  process.exit(await followLog(r2.job, !!opts.follow));
172885
172954
  });
172886
- program2.command("attach <id>").description("Follow a background job live (Ctrl+C detaches; the job keeps running)").action(async (id) => {
172955
+ 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
172956
  const r2 = resolveJob(id);
172888
172957
  if (!r2.ok) {
172889
172958
  console.error(r2.error);
172890
172959
  process.exit(1);
172891
172960
  }
172892
- process.exit(await followLog(r2.job, true));
172961
+ process.exit(await followLog(r2.job, true, void 0, void 0, true));
172893
172962
  });
172894
172963
  program2.command("kill <id>").description("Stop a background job").action((id) => {
172895
172964
  const r2 = resolveJob(id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexrall-code",
3
- "version": "0.5.159",
3
+ "version": "0.5.160",
4
4
  "description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
5
5
  "keywords": [
6
6
  "ai",