nexrall-code 0.5.24 → 0.5.28

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 +313 -33
  2. package/package.json +11 -10
package/dist/index.js CHANGED
@@ -12673,7 +12673,7 @@ Resolve the conflict (remove <<<<<<< / ======= / >>>>>>> markers and keep the in
12673
12673
  var _bgCounter = 0;
12674
12674
  function startBackgroundShell(command, displayCommand, workDir, note) {
12675
12675
  const id = `bg_${++_bgCounter}`;
12676
- const child = (0, child_process_1.spawn)(command, { shell: true, cwd: workDir ?? process.cwd(), env: process.env, detached: true });
12676
+ const child = (0, child_process_1.spawn)(command, { shell: true, cwd: workDir ?? process.cwd(), env: process.env, detached: true, stdio: ["ignore", "pipe", "pipe"] });
12677
12677
  const shell = {
12678
12678
  id,
12679
12679
  command: displayCommand,
@@ -12835,7 +12835,8 @@ ${r2.output}`;
12835
12835
  shell: true,
12836
12836
  cwd: workDir ?? process.cwd(),
12837
12837
  env: process.env,
12838
- detached: true
12838
+ detached: true,
12839
+ stdio: ["ignore", "pipe", "pipe"]
12839
12840
  });
12840
12841
  const killTree = (sig) => {
12841
12842
  try {
@@ -23209,22 +23210,6 @@ var icons = {
23209
23210
  thinking: "\u25C6",
23210
23211
  code: "{}"
23211
23212
  };
23212
- function banner() {
23213
- const version = "0.1.1";
23214
- console.log();
23215
- console.log(source_default.bold.blue(" \u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557"));
23216
- console.log(source_default.bold.blue(" \u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D"));
23217
- console.log(source_default.bold.blue(" \u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u255D "));
23218
- console.log(source_default.bold.blue(" \u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2588\u2588\u2557 "));
23219
- console.log(source_default.bold.blue(" \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u2588\u2588\u2557"));
23220
- console.log(source_default.bold.blue(" \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D"));
23221
- console.log();
23222
- console.log(
23223
- source_default.bold(" Nexrall Code") + source_default.dim(` v${version}`) + source_default.dim(" \xB7 ") + source_default.cyan("AI coding assistant")
23224
- );
23225
- console.log(source_default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
23226
- console.log();
23227
- }
23228
23213
  function visibleLen(s2) {
23229
23214
  return s2.replace(/\x1b\[[0-9;]*m/g, "").length;
23230
23215
  }
@@ -23468,6 +23453,77 @@ function formatUsage(outputTokens) {
23468
23453
  return source_default.dim(`\u2193 ${tok} tokens`);
23469
23454
  }
23470
23455
 
23456
+ // src/ui/paste.ts
23457
+ var PASTE_START = "\x1B[200~";
23458
+ var PASTE_END = "\x1B[201~";
23459
+ function enableBracketedPaste() {
23460
+ if (process.stdout.isTTY)
23461
+ process.stdout.write("\x1B[?2004h");
23462
+ }
23463
+ function disableBracketedPaste() {
23464
+ if (process.stdout.isTTY)
23465
+ process.stdout.write("\x1B[?2004l");
23466
+ }
23467
+ function installPasteHandling(rl, stdin) {
23468
+ const originalListeners = stdin.listeners("data");
23469
+ for (const l of originalListeners)
23470
+ stdin.removeListener("data", l);
23471
+ const forward = (buf) => {
23472
+ if (!buf.length)
23473
+ return;
23474
+ for (const l of originalListeners)
23475
+ l.call(stdin, buf);
23476
+ };
23477
+ let buffering = false;
23478
+ let buffer = "";
23479
+ const insertPastedText = (text) => {
23480
+ if (!text)
23481
+ return;
23482
+ const flattened = text.replace(/\r\n|\r|\n/g, " ");
23483
+ const anyRl = rl;
23484
+ if (typeof anyRl._insertString === "function") {
23485
+ anyRl._insertString(flattened);
23486
+ } else {
23487
+ rl.write(flattened);
23488
+ }
23489
+ };
23490
+ const onData = (chunk) => {
23491
+ let text = chunk.toString("utf-8");
23492
+ for (; ; ) {
23493
+ if (!buffering) {
23494
+ const startIdx = text.indexOf(PASTE_START);
23495
+ if (startIdx === -1) {
23496
+ forward(Buffer.from(text, "utf-8"));
23497
+ return;
23498
+ }
23499
+ const before = text.slice(0, startIdx);
23500
+ forward(Buffer.from(before, "utf-8"));
23501
+ text = text.slice(startIdx + PASTE_START.length);
23502
+ buffering = true;
23503
+ buffer = "";
23504
+ }
23505
+ const endIdx = text.indexOf(PASTE_END);
23506
+ if (endIdx === -1) {
23507
+ buffer += text;
23508
+ return;
23509
+ }
23510
+ buffer += text.slice(0, endIdx);
23511
+ insertPastedText(buffer);
23512
+ buffer = "";
23513
+ buffering = false;
23514
+ text = text.slice(endIdx + PASTE_END.length);
23515
+ if (!text)
23516
+ return;
23517
+ }
23518
+ };
23519
+ stdin.on("data", onData);
23520
+ return () => {
23521
+ stdin.removeListener("data", onData);
23522
+ for (const l of originalListeners)
23523
+ stdin.on("data", l);
23524
+ };
23525
+ }
23526
+
23471
23527
  // src/permissions/handler.ts
23472
23528
  var readline2 = __toESM(require("readline"));
23473
23529
  var fs2 = __toESM(require("fs"));
@@ -24022,6 +24078,9 @@ function setAutoApprove(category) {
24022
24078
  function isAutoApproved(category) {
24023
24079
  return autoApproved.has("all") || autoApproved.has(category);
24024
24080
  }
24081
+ function isYoloMode() {
24082
+ return autoApproved.has("all");
24083
+ }
24025
24084
  var _replInterface = null;
24026
24085
  function setReadlineInterface(rl) {
24027
24086
  _replInterface = rl;
@@ -24249,7 +24308,7 @@ async function requestPermission(req) {
24249
24308
  var fs3 = __toESM(require("fs"));
24250
24309
  var path = __toESM(require("path"));
24251
24310
  var os2 = __toESM(require("os"));
24252
- var SESSIONS_DIR = path.join(os2.homedir(), ".nexrall", "cli-sessions");
24311
+ var SESSIONS_DIR = process.env.NEXRALL_CLI_SESSIONS_DIR || path.join(os2.homedir(), ".nexrall", "cli-sessions");
24253
24312
  function ensureDir() {
24254
24313
  fs3.mkdirSync(SESSIONS_DIR, { recursive: true });
24255
24314
  }
@@ -24484,7 +24543,118 @@ async function updateCommand(opts) {
24484
24543
  console.log();
24485
24544
  }
24486
24545
 
24546
+ // src/ui/screen.ts
24547
+ function enableAltScreen() {
24548
+ if (process.stdout.isTTY)
24549
+ process.stdout.write("\x1B[?1049h");
24550
+ }
24551
+ function disableAltScreen() {
24552
+ if (process.stdout.isTTY)
24553
+ process.stdout.write("\x1B[?1049l");
24554
+ }
24555
+ var NEX_LOGO = [
24556
+ "\u2588\u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2557 \u2588\u2588\u2557",
24557
+ "\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D\u255A\u2588\u2588\u2557\u2588\u2588\u2554\u255D",
24558
+ "\u2588\u2588\u2554\u2588\u2588\u2557 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2557 \u255A\u2588\u2588\u2588\u2554\u255D ",
24559
+ "\u2588\u2588\u2551\u255A\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u255D \u2588\u2588\u2554\u2588\u2588\u2557 ",
24560
+ "\u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2554\u255D \u2588\u2588\u2557",
24561
+ "\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D"
24562
+ ];
24563
+ function center(s2, w) {
24564
+ const len = visibleLen(s2);
24565
+ if (len >= w)
24566
+ return s2;
24567
+ const left = Math.floor((w - len) / 2);
24568
+ return " ".repeat(left) + s2;
24569
+ }
24570
+ function renderBanner(info) {
24571
+ const LEFT_W = 38;
24572
+ const RIGHT_W = 44;
24573
+ const GAP = 2;
24574
+ const leftLines = [];
24575
+ leftLines.push(source_default.bold.hex("#d97757")(`Nexrall Code `) + source_default.dim(`v${info.version}`));
24576
+ leftLines.push("");
24577
+ leftLines.push(center(source_default.bold(`Welcome back ${info.userLabel}!`), LEFT_W));
24578
+ leftLines.push("");
24579
+ for (const l of NEX_LOGO)
24580
+ leftLines.push(center(source_default.hex("#d97757")(l), LEFT_W));
24581
+ leftLines.push("");
24582
+ leftLines.push(source_default.dim(info.modelLabel));
24583
+ leftLines.push(source_default.dim(info.workDir));
24584
+ if (info.nexrallMdLoaded)
24585
+ leftLines.push(source_default.dim("nexrall.md loaded"));
24586
+ const rightLines = [];
24587
+ rightLines.push(source_default.bold.yellow("Tips for getting started"));
24588
+ const tips = info.tips ?? [
24589
+ "Run /init to create a nexrall.md file with instructions for Nexrall Code.",
24590
+ "Use /help to see all slash commands."
24591
+ ];
24592
+ for (const t2 of tips)
24593
+ rightLines.push(...wrapText(t2, RIGHT_W));
24594
+ const whatsNew = info.whatsNew ?? [];
24595
+ if (whatsNew.length) {
24596
+ rightLines.push("");
24597
+ rightLines.push(source_default.bold.yellow("What's new"));
24598
+ for (const t2 of whatsNew)
24599
+ rightLines.push(...wrapText(t2, RIGHT_W));
24600
+ rightLines.push(source_default.dim.italic("/release-notes for more"));
24601
+ }
24602
+ const rowCount = Math.max(leftLines.length, rightLines.length);
24603
+ const border = source_default.hex("#d97757");
24604
+ const lines = [];
24605
+ lines.push(border("\u256D" + "\u2500".repeat(LEFT_W + GAP + RIGHT_W + 4) + "\u256E"));
24606
+ for (let i2 = 0; i2 < rowCount; i2++) {
24607
+ const l = padVis(leftLines[i2] ?? "", LEFT_W);
24608
+ const r2 = padVis(rightLines[i2] ?? "", RIGHT_W);
24609
+ lines.push(border("\u2502 ") + l + " ".repeat(GAP) + r2 + border(" \u2502"));
24610
+ }
24611
+ lines.push(border("\u2570" + "\u2500".repeat(LEFT_W + GAP + RIGHT_W + 4) + "\u256F"));
24612
+ return lines.join("\n");
24613
+ }
24614
+ function wrapText(text, width) {
24615
+ const words = text.split(" ");
24616
+ const out = [];
24617
+ let cur = "";
24618
+ for (const w of words) {
24619
+ const candidate = cur ? cur + " " + w : w;
24620
+ if (visibleLen(candidate) > width && cur) {
24621
+ out.push(cur);
24622
+ cur = w;
24623
+ } else {
24624
+ cur = candidate;
24625
+ }
24626
+ }
24627
+ if (cur)
24628
+ out.push(cur);
24629
+ return out;
24630
+ }
24631
+ var lastFooterText = "";
24632
+ function footerText(info) {
24633
+ const modeLabel = info.autoApprove ? "yolo mode on" : info.mode === "plan" ? "plan mode on" : info.mode === "edit" ? "edit mode on" : info.mode === "ask" ? "ask mode on" : "auto mode on";
24634
+ return `${modeLabel} \xB7 /help for shortcuts \xB7 /agents for agents`;
24635
+ }
24636
+ function drawStatusFooter(info) {
24637
+ if (!process.stdout.isTTY || !process.stdout.rows)
24638
+ return;
24639
+ const text = footerText(info);
24640
+ if (text === lastFooterText)
24641
+ return;
24642
+ lastFooterText = text;
24643
+ const row = process.stdout.rows;
24644
+ const out = `\x1B7\x1B[${row};1H\x1B[2K` + // clear the line
24645
+ source_default.dim(text) + "\x1B8";
24646
+ process.stdout.write(out);
24647
+ }
24648
+ function clearStatusFooter() {
24649
+ if (!process.stdout.isTTY || !process.stdout.rows)
24650
+ return;
24651
+ const row = process.stdout.rows;
24652
+ process.stdout.write(`\x1B7\x1B[${row};1H\x1B[2K\x1B8`);
24653
+ lastFooterText = "";
24654
+ }
24655
+
24487
24656
  // src/commands/chat.ts
24657
+ var CLI_VERSION = "0.5.28";
24488
24658
  var MODEL_LABELS = {
24489
24659
  turbo: "Nexrall Turbo",
24490
24660
  pro: "Nexrall Pro",
@@ -24517,6 +24687,14 @@ function printBalanceNotice(balance, zero) {
24517
24687
  console.log(" " + source_default.yellow(hyperlink("\u2192 Top up", BILLING_URL)) + source_default.dim(` (${BILLING_URL})`));
24518
24688
  console.log();
24519
24689
  }
24690
+ function currentUserLabel() {
24691
+ try {
24692
+ const u = os4.userInfo().username;
24693
+ return u ? u.charAt(0).toUpperCase() + u.slice(1) : "there";
24694
+ } catch {
24695
+ return "there";
24696
+ }
24697
+ }
24520
24698
  function collectEnv(workDir) {
24521
24699
  return {
24522
24700
  cwd: workDir,
@@ -24565,10 +24743,17 @@ var Spinner = class {
24565
24743
  interval = null;
24566
24744
  frames = ["\u25D0", "\u25D3", "\u25D1", "\u25D2"];
24567
24745
  i = 0;
24746
+ startedAt = 0;
24747
+ baseText = "";
24568
24748
  start(text) {
24569
24749
  this.stop();
24750
+ this.baseText = text;
24751
+ this.startedAt = Date.now();
24570
24752
  this.interval = setInterval(() => {
24571
- process.stdout.write(`\r${source_default.cyan(this.frames[this.i % this.frames.length])} ${source_default.dim(text)}`);
24753
+ const elapsedSec = Math.floor((Date.now() - this.startedAt) / 1e3);
24754
+ const timer = source_default.dim(` (${elapsedSec}s)`);
24755
+ const hint = elapsedSec >= 15 ? source_default.dim(" \xB7 still running, no output yet is normal for quiet commands") : "";
24756
+ process.stdout.write(`\r\x1B[K${source_default.cyan(this.frames[this.i % this.frames.length])} ${source_default.dim(this.baseText)}${timer}${hint}`);
24572
24757
  this.i++;
24573
24758
  }, 100);
24574
24759
  }
@@ -24889,6 +25074,7 @@ function printHelp() {
24889
25074
  ["/yolo", "Auto-approve all permissions"],
24890
25075
  ["/balance", "Show wallet balance"],
24891
25076
  ["/add <filepath>", "Add a file to conversation context"],
25077
+ ["/image <filepath> [caption]", "Attach an image or PDF (png/jpg/gif/webp/pdf, max 10MB) and send it to the model"],
24892
25078
  ["/skills", "List skills (.nexrall/skills/<name>/SKILL.md or .nexrall/commands/*.md) \u2014 the model can also auto-invoke these"],
24893
25079
  ["/plugins", "List installed plugins (.nexrall/plugins/)"],
24894
25080
  ["/mcp", "Show MCP server connection status"],
@@ -24921,25 +25107,34 @@ function printSessions() {
24921
25107
  }
24922
25108
  async function startChatSession(options) {
24923
25109
  const headless = options.outputFormat === "json" || options.outputFormat === "stream-json";
24924
- if (options.showBanner !== false && !headless)
24925
- banner();
24926
25110
  const { workDir } = options;
24927
25111
  let modelAlias = options.model;
24928
25112
  const env2 = collectEnv(workDir);
24929
25113
  const nexrallMd = readNexrallMd(workDir);
24930
- if (!headless) {
24931
- console.log(source_default.dim(" model ") + source_default.cyan(resolveModelLabel(modelAlias)));
24932
- console.log(source_default.dim(" workdir ") + source_default.white(workDir));
24933
- console.log(source_default.dim(" mode ") + source_default.cyan("auto") + source_default.dim(" \xB7 effort ") + source_default.cyan("medium"));
25114
+ const interactive = !headless && !options.prompt && !options.stdinText;
25115
+ if (interactive) {
25116
+ enableAltScreen();
25117
+ process.on("exit", () => {
25118
+ clearStatusFooter();
25119
+ disableAltScreen();
25120
+ });
25121
+ }
25122
+ if (options.showBanner !== false && !headless) {
24934
25123
  const branch = tryExec("git branch --show-current", workDir);
24935
25124
  const gitStatus = tryExec("git status --short", workDir);
25125
+ const changedLines = gitStatus ? gitStatus.split("\n").filter(Boolean).length : 0;
25126
+ const tips = ["Run /init to create a nexrall.md file with instructions for Nexrall Code."];
24936
25127
  if (branch) {
24937
- const changedLines = gitStatus ? gitStatus.split("\n").filter(Boolean).length : 0;
24938
- const changed = changedLines > 0 ? source_default.dim(" \xB7 ") + source_default.yellow(`${changedLines} changed`) : "";
24939
- console.log(source_default.dim(" branch ") + source_default.dim(branch) + changed);
24940
- }
24941
- if (nexrallMd)
24942
- console.log(source_default.dim(" nexrall.md loaded"));
25128
+ tips.push(`On branch ${branch}${changedLines > 0 ? ` (${changedLines} changed)` : ""}.`);
25129
+ }
25130
+ console.log(renderBanner({
25131
+ version: CLI_VERSION,
25132
+ userLabel: currentUserLabel(),
25133
+ modelLabel: resolveModelLabel(modelAlias),
25134
+ workDir,
25135
+ nexrallMdLoaded: !!nexrallMd,
25136
+ tips
25137
+ }));
24943
25138
  console.log();
24944
25139
  }
24945
25140
  let messages = [];
@@ -25103,6 +25298,16 @@ ${text}` : "");
25103
25298
  prompt: colors.primary.bold("> ")
25104
25299
  });
25105
25300
  setReadlineInterface(rl);
25301
+ enableBracketedPaste();
25302
+ process.on("exit", disableBracketedPaste);
25303
+ const uninstallPasteHandling = installPasteHandling(rl, process.stdin);
25304
+ const originalPrompt = rl.prompt.bind(rl);
25305
+ rl.prompt = (preserveCursor) => {
25306
+ if (interactive) {
25307
+ drawStatusFooter({ mode: agentMode, autoApprove: isYoloMode() });
25308
+ }
25309
+ return originalPrompt(preserveCursor);
25310
+ };
25106
25311
  rl.prompt();
25107
25312
  let inputBuffer = "";
25108
25313
  rl.on("line", async (rawLine) => {
@@ -25461,6 +25666,80 @@ ${content}
25461
25666
  rl.prompt();
25462
25667
  return;
25463
25668
  }
25669
+ case "/image": {
25670
+ if (agentRunning) {
25671
+ console.log(source_default.red(" Cannot attach while agent is running."));
25672
+ rl.prompt();
25673
+ return;
25674
+ }
25675
+ if (!arg) {
25676
+ console.log(source_default.red(" Usage: /image <filepath> [caption]"));
25677
+ rl.prompt();
25678
+ return;
25679
+ }
25680
+ const [rawPath, ...captionParts] = arg.split(/\s+/);
25681
+ const caption = captionParts.join(" ").trim();
25682
+ const filePath = path3.isAbsolute(rawPath) ? rawPath : path3.join(workDir, rawPath);
25683
+ const ext = path3.extname(filePath).toLowerCase();
25684
+ const IMAGE_MIME = {
25685
+ ".png": "image/png",
25686
+ ".jpg": "image/jpeg",
25687
+ ".jpeg": "image/jpeg",
25688
+ ".gif": "image/gif",
25689
+ ".webp": "image/webp"
25690
+ };
25691
+ const isPdf = ext === ".pdf";
25692
+ const mimeType = IMAGE_MIME[ext];
25693
+ if (!mimeType && !isPdf) {
25694
+ console.log(source_default.red(` Unsupported file type: ${ext || "(none)"}. Supported: png, jpg, jpeg, gif, webp, pdf.`));
25695
+ rl.prompt();
25696
+ return;
25697
+ }
25698
+ let buf;
25699
+ try {
25700
+ buf = fs5.readFileSync(filePath);
25701
+ } catch (err) {
25702
+ console.error(source_default.red(" Failed: ") + String(err.message));
25703
+ rl.prompt();
25704
+ return;
25705
+ }
25706
+ const MAX_BYTES = 10 * 1024 * 1024;
25707
+ if (buf.length > MAX_BYTES) {
25708
+ console.log(source_default.red(` File too large (${(buf.length / 1024 / 1024).toFixed(1)}MB) \u2014 max 10MB.`));
25709
+ rl.prompt();
25710
+ return;
25711
+ }
25712
+ const rel = path3.relative(workDir, filePath);
25713
+ const data = buf.toString("base64");
25714
+ const label = caption ? `[Attached: ${rel}]
25715
+ ${caption}` : `[Attached: ${rel}]`;
25716
+ const content = [{ type: "text", text: label }];
25717
+ content.push(
25718
+ isPdf ? { type: "document", source: { type: "base64", media_type: "application/pdf", data } } : { type: "image", source: { type: "base64", media_type: mimeType, data } }
25719
+ );
25720
+ console.log(source_default.dim(` Attached ${rel} (${(buf.length / 1024).toFixed(0)}KB) \u2014 sending\u2026`));
25721
+ checkpoints.beginTurn(`/image ${rel}${caption ? " " + caption : ""}`, messages.length);
25722
+ messages.push({ role: "user", content });
25723
+ rl.pause();
25724
+ abortSignal.aborted = false;
25725
+ agentRunning = true;
25726
+ try {
25727
+ const result = await runTurn(messages, modelAlias, workDir, abortSignal, env2, nexrallMd, agentMode, effortLevel, checkpoints, saveProgress);
25728
+ messages = result.messages;
25729
+ updateTitle();
25730
+ saveSession(sessionId, sessionTitle, workDir, messages);
25731
+ } catch (err) {
25732
+ messages = recoverTurn(err, messages);
25733
+ updateTitle();
25734
+ saveSession(sessionId, sessionTitle || "Untitled", workDir, messages);
25735
+ } finally {
25736
+ agentRunning = false;
25737
+ checkpoints.commitTurn();
25738
+ }
25739
+ rl.resume();
25740
+ rl.prompt();
25741
+ return;
25742
+ }
25464
25743
  case "/update": {
25465
25744
  rl.close();
25466
25745
  await updateCommand({ yes: false });
@@ -25584,6 +25863,7 @@ ${content}
25584
25863
  rl.prompt();
25585
25864
  });
25586
25865
  rl.on("close", () => {
25866
+ uninstallPasteHandling();
25587
25867
  updateTitle();
25588
25868
  if (messages.length)
25589
25869
  saveSession(sessionId, sessionTitle || "Untitled", workDir, messages);
@@ -25797,7 +26077,7 @@ function pluginListCommand() {
25797
26077
 
25798
26078
  // src/index.ts
25799
26079
  var program2 = new Command();
25800
- program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.24");
26080
+ program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.28");
25801
26081
  program2.command("auth").description("Login to your Nexrall account").action(authCommand);
25802
26082
  program2.command("logout").description("Log out of your Nexrall account").action(logoutCommand);
25803
26083
  program2.command("update").description("Update nex to the latest version").option("-c, --check", "Check for updates without installing").option("-y, --yes", "Skip confirmation prompt").action(async (opts) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nexrall-code",
3
- "version": "0.5.24",
3
+ "version": "0.5.28",
4
4
  "description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
5
5
  "keywords": [
6
6
  "ai",
@@ -30,14 +30,21 @@
30
30
  "engines": {
31
31
  "node": ">=18"
32
32
  },
33
+ "scripts": {
34
+ "build": "node build.js",
35
+ "dev": "tsx src/index.ts",
36
+ "start": "node dist/index.js",
37
+ "test": "tsc --noEmit && tsc --noEmit -p test/tsconfig.json && node --import tsx --test test/*.test.ts test/*.test.mts",
38
+ "release": "node build.js && node scripts/upload-release.js"
39
+ },
33
40
  "dependencies": {
41
+ "@nexrall/code-core": "workspace:*",
34
42
  "chalk": "^5.3.0",
35
43
  "commander": "^12.0.0",
36
44
  "diff": "^5.2.0",
37
45
  "ora": "^8.0.1",
38
46
  "prompts": "^2.4.2",
39
- "readline": "^1.3.0",
40
- "@nexrall/code-core": "1.4.19"
47
+ "readline": "^1.3.0"
41
48
  },
42
49
  "devDependencies": {
43
50
  "@aws-sdk/client-s3": "^3.600.0",
@@ -47,11 +54,5 @@
47
54
  "esbuild": "^0.20.0",
48
55
  "tsx": "^4.7.0",
49
56
  "typescript": "^6.0.3"
50
- },
51
- "scripts": {
52
- "build": "node build.js",
53
- "dev": "tsx src/index.ts",
54
- "start": "node dist/index.js",
55
- "release": "node build.js && node scripts/upload-release.js"
56
57
  }
57
- }
58
+ }