nexrall-code 0.5.38 → 0.5.40

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 +42 -95
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -53228,11 +53228,15 @@ function center(s2, w) {
53228
53228
  return " ".repeat(left) + s2;
53229
53229
  }
53230
53230
  function renderBanner(info) {
53231
- const LEFT_W = 38;
53232
- const RIGHT_W = 44;
53233
- const GAP = 2;
53231
+ const GAP = 4;
53232
+ const LOGO_W = Math.max(...NEX_LOGO.map(visibleLen));
53233
+ const headerText = `Nexrall Code v${info.version}`;
53234
+ const LEFT_W = Math.max(LOGO_W, visibleLen(headerText), visibleLen(info.modelLabel), visibleLen(info.workDir));
53235
+ const framing = 2 + GAP + 2;
53236
+ const termW = process.stdout.columns || 100;
53237
+ const RIGHT_W = Math.max(32, Math.min(46, termW - framing - LEFT_W));
53234
53238
  const leftLines = [];
53235
- leftLines.push(source_default.bold.hex("#3b82f6")(`Nexrall Code `) + source_default.dim(`v${info.version}`));
53239
+ leftLines.push(source_default.bold.hex("#3b82f6")("Nexrall Code ") + source_default.dim(`v${info.version}`));
53236
53240
  leftLines.push("");
53237
53241
  leftLines.push(center(source_default.bold(`Welcome back ${info.userLabel}!`), LEFT_W));
53238
53242
  leftLines.push("");
@@ -53261,14 +53265,15 @@ function renderBanner(info) {
53261
53265
  }
53262
53266
  const rowCount = Math.max(leftLines.length, rightLines.length);
53263
53267
  const border = source_default.hex("#3b82f6");
53268
+ const INNER_W = LEFT_W + GAP + RIGHT_W + 2;
53264
53269
  const lines = [];
53265
- lines.push(border("\u256D" + "\u2500".repeat(LEFT_W + GAP + RIGHT_W + 4) + "\u256E"));
53270
+ lines.push(border("\u256D" + "\u2500".repeat(INNER_W) + "\u256E"));
53266
53271
  for (let i2 = 0; i2 < rowCount; i2++) {
53267
53272
  const l = padVis(leftLines[i2] ?? "", LEFT_W);
53268
53273
  const r2 = padVis(rightLines[i2] ?? "", RIGHT_W);
53269
53274
  lines.push(border("\u2502 ") + l + " ".repeat(GAP) + r2 + border(" \u2502"));
53270
53275
  }
53271
- lines.push(border("\u2570" + "\u2500".repeat(LEFT_W + GAP + RIGHT_W + 4) + "\u256F"));
53276
+ lines.push(border("\u2570" + "\u2500".repeat(INNER_W) + "\u256F"));
53272
53277
  return lines.join("\n");
53273
53278
  }
53274
53279
  function wrapText(text, width) {
@@ -62092,74 +62097,31 @@ var import_react32 = __toESM(require_react(), 1);
62092
62097
  // ../../node_modules/.pnpm/ink@7.1.1_@types+react@19.2.18_react@19.2.8/node_modules/ink/build/hooks/use-box-metrics.js
62093
62098
  var import_react33 = __toESM(require_react(), 1);
62094
62099
 
62095
- // src/ui/imeBuffer.ts
62096
- function isImeLikeInput(input) {
62097
- if (!input)
62098
- return false;
62099
- if (input.length === 1 && input.charCodeAt(0) < 128)
62100
- return false;
62101
- if (Buffer.byteLength(input, "utf8") > input.length)
62102
- return true;
62103
- if (/[\u0300-\u036F]/.test(input))
62104
- return true;
62105
- return false;
62106
- }
62107
- var ImeCompositionBuffer = class {
62108
- buf = "";
62109
- timer = null;
62110
- timeoutMs;
62111
- onFlush;
62112
- constructor(options) {
62113
- this.timeoutMs = options.timeoutMs ?? 50;
62114
- this.onFlush = options.onFlush;
62115
- }
62116
- /** Buffer a chunk of IME-like input, (re)starting the auto-flush timer. */
62117
- add(chunk) {
62118
- this.buf += chunk;
62119
- this.restartTimer();
62120
- }
62121
- /** Remove the last character from the buffer (used for IME backspace). */
62122
- backspace() {
62123
- if (!this.buf)
62124
- return false;
62125
- this.buf = this.buf.slice(0, -1);
62126
- this.restartTimer();
62127
- return true;
62128
- }
62129
- hasContent() {
62130
- return this.buf.length > 0;
62131
- }
62132
- /** Flush immediately (used when an unambiguous non-IME key arrives). */
62133
- flush() {
62134
- this.clearTimer();
62135
- if (!this.buf)
62136
- return;
62137
- const text = this.buf;
62138
- this.buf = "";
62139
- this.onFlush(text);
62140
- }
62141
- /** Cancel the timer without flushing (used on unmount). */
62142
- destroy() {
62143
- this.clearTimer();
62144
- this.buf = "";
62145
- }
62146
- restartTimer() {
62147
- this.clearTimer();
62148
- this.timer = setTimeout(() => this.flush(), this.timeoutMs);
62149
- }
62150
- clearTimer() {
62151
- if (this.timer !== null) {
62152
- clearTimeout(this.timer);
62153
- this.timer = null;
62154
- }
62155
- }
62156
- };
62157
-
62158
62100
  // src/ui/inkTerminal.tsx
62159
62101
  function footerText(info) {
62160
62102
  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";
62161
62103
  return `${modeLabel} \xB7 /help for shortcuts \xB7 /agents for agents`;
62162
62104
  }
62105
+ var IntlWithSegmenter = Intl;
62106
+ var graphemeSegmenter = typeof IntlWithSegmenter.Segmenter === "function" ? new IntlWithSegmenter.Segmenter(void 0, { granularity: "grapheme" }) : null;
62107
+ function dropLastGrapheme(text) {
62108
+ if (!text)
62109
+ return "";
62110
+ if (graphemeSegmenter) {
62111
+ let lastStart = 0;
62112
+ for (const { index } of graphemeSegmenter.segment(text))
62113
+ lastStart = index;
62114
+ return text.slice(0, lastStart);
62115
+ }
62116
+ let end = text.length - 1;
62117
+ while (end > 0 && /[\u0300-\u036F\u1AB0-\u1AFF\u20D0-\u20F0]/.test(text[end]))
62118
+ end--;
62119
+ const prev = text.charCodeAt(end - 1);
62120
+ const curr = text.charCodeAt(end);
62121
+ if (end > 0 && prev >= 55296 && prev <= 56319 && curr >= 56320 && curr <= 57343)
62122
+ end--;
62123
+ return text.slice(0, end);
62124
+ }
62163
62125
  var handle = null;
62164
62126
  var inkInstance = null;
62165
62127
  var idCounter = 0;
@@ -62168,9 +62130,15 @@ var App2 = ({ onReady }) => {
62168
62130
  const [items, setItems] = (0, import_react34.useState)([]);
62169
62131
  const [footer, setFooterState] = (0, import_react34.useState)({ mode: "auto", autoApprove: false });
62170
62132
  const [inputEnabled, setInputEnabledState] = (0, import_react34.useState)(true);
62171
- const [line, setLine] = (0, import_react34.useState)("");
62133
+ const [line, setLineState] = (0, import_react34.useState)("");
62172
62134
  const [prompt2, setPrompt] = (0, import_react34.useState)(DEFAULT_PROMPT);
62173
62135
  const { exit } = use_app_default();
62136
+ const lineRef = (0, import_react34.useRef)("");
62137
+ const setLine = (0, import_react34.useCallback)((next) => {
62138
+ const value = typeof next === "function" ? next(lineRef.current) : next;
62139
+ lineRef.current = value;
62140
+ setLineState(value);
62141
+ }, []);
62174
62142
  const askResolverRef = (0, import_react34.useRef)(null);
62175
62143
  const onLineRef = (0, import_react34.useRef)(null);
62176
62144
  const [live, setLiveState] = (0, import_react34.useState)("");
@@ -62193,16 +62161,6 @@ var App2 = ({ onReady }) => {
62193
62161
  const onLine = (0, import_react34.useCallback)((cb) => {
62194
62162
  onLineRef.current = cb;
62195
62163
  }, []);
62196
- const imeBufferRef = (0, import_react34.useRef)(null);
62197
- if (imeBufferRef.current === null) {
62198
- imeBufferRef.current = new ImeCompositionBuffer({
62199
- onFlush: (text) => setLine((s2) => s2 + text)
62200
- });
62201
- }
62202
- import_react34.default.useEffect(() => {
62203
- const buf = imeBufferRef.current;
62204
- return () => buf?.destroy();
62205
- }, []);
62206
62164
  use_input_default((char, key) => {
62207
62165
  if (!inputEnabled)
62208
62166
  return;
@@ -62211,15 +62169,10 @@ var App2 = ({ onReady }) => {
62211
62169
  return;
62212
62170
  }
62213
62171
  if (key.backspace || key.delete) {
62214
- if (imeBufferRef.current?.hasContent()) {
62215
- imeBufferRef.current.backspace();
62216
- return;
62217
- }
62218
- setLine((s2) => s2.slice(0, -1));
62172
+ setLine((s2) => dropLastGrapheme(s2));
62219
62173
  return;
62220
62174
  }
62221
62175
  if (key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.tab) {
62222
- imeBufferRef.current?.flush();
62223
62176
  return;
62224
62177
  }
62225
62178
  const newlineIdx = char.search(/[\r\n]/);
@@ -62227,8 +62180,7 @@ var App2 = ({ onReady }) => {
62227
62180
  if (hasNewline) {
62228
62181
  const before = newlineIdx === -1 ? char : char.slice(0, newlineIdx);
62229
62182
  const after = newlineIdx === -1 ? "" : char.slice(newlineIdx + 1).replace(/^[\r\n]/, "");
62230
- imeBufferRef.current?.flush();
62231
- const submitted = line + before;
62183
+ const submitted = lineRef.current + before;
62232
62184
  setLine(after);
62233
62185
  print(prompt2 + submitted);
62234
62186
  const askResolve = askResolverRef.current;
@@ -62240,11 +62192,6 @@ var App2 = ({ onReady }) => {
62240
62192
  }
62241
62193
  return;
62242
62194
  }
62243
- if (isImeLikeInput(char)) {
62244
- imeBufferRef.current?.add(char);
62245
- return;
62246
- }
62247
- imeBufferRef.current?.flush();
62248
62195
  setLine((s2) => s2 + char);
62249
62196
  });
62250
62197
  import_react34.default.useEffect(() => {
@@ -62320,7 +62267,7 @@ var InkReadlineAdapter = class extends EventEmitter3 {
62320
62267
  };
62321
62268
 
62322
62269
  // src/commands/chat.ts
62323
- var CLI_VERSION = "0.5.38";
62270
+ var CLI_VERSION = "0.5.40";
62324
62271
  var MODEL_LABELS = {
62325
62272
  turbo: "Nexrall Turbo",
62326
62273
  pro: "Nexrall Pro",
@@ -63726,7 +63673,7 @@ function pluginListCommand() {
63726
63673
 
63727
63674
  // src/index.ts
63728
63675
  var program2 = new Command();
63729
- program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.38");
63676
+ program2.name("nex").description("Nexrall Code \u2014 AI coding assistant (powered by Nexrall)").version("0.5.40");
63730
63677
  program2.command("auth").description("Login to your Nexrall account").action(authCommand);
63731
63678
  program2.command("logout").description("Log out of your Nexrall account").action(logoutCommand);
63732
63679
  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.38",
3
+ "version": "0.5.40",
4
4
  "description": "Nexrall Code — AI coding assistant for your terminal (headless agent for scripts, CI and automation)",
5
5
  "keywords": [
6
6
  "ai",