omnius 1.0.103 → 1.0.104

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 CHANGED
@@ -21863,27 +21863,27 @@ function readInteger(buf, context2) {
21863
21863
  function readObjectIdentifier(buf, context2) {
21864
21864
  const count = readLength(buf, context2);
21865
21865
  const finalOffset = context2.offset + count;
21866
- const byte = buf[context2.offset];
21866
+ const byte2 = buf[context2.offset];
21867
21867
  context2.offset++;
21868
21868
  let val1 = 0;
21869
21869
  let val2 = 0;
21870
- if (byte < 40) {
21870
+ if (byte2 < 40) {
21871
21871
  val1 = 0;
21872
- val2 = byte;
21873
- } else if (byte < 80) {
21872
+ val2 = byte2;
21873
+ } else if (byte2 < 80) {
21874
21874
  val1 = 1;
21875
- val2 = byte - 40;
21875
+ val2 = byte2 - 40;
21876
21876
  } else {
21877
21877
  val1 = 2;
21878
- val2 = byte - 80;
21878
+ val2 = byte2 - 80;
21879
21879
  }
21880
21880
  let oid = `${val1}.${val2}`;
21881
21881
  let num = [];
21882
21882
  while (context2.offset < finalOffset) {
21883
- const byte2 = buf[context2.offset];
21883
+ const byte3 = buf[context2.offset];
21884
21884
  context2.offset++;
21885
- num.push(byte2 & 127);
21886
- if (byte2 < 128) {
21885
+ num.push(byte3 & 127);
21886
+ if (byte3 < 128) {
21887
21887
  num.reverse();
21888
21888
  let val = 0;
21889
21889
  for (let i2 = 0; i2 < num.length; i2++) {
@@ -28115,16 +28115,16 @@ function ipToString(ip) {
28115
28115
  }
28116
28116
  function simpleMaskLength(mask) {
28117
28117
  let ones = 0;
28118
- for (let [index, byte] of mask.entries()) {
28119
- if (byte === 255) {
28118
+ for (let [index, byte2] of mask.entries()) {
28119
+ if (byte2 === 255) {
28120
28120
  ones += 8;
28121
28121
  continue;
28122
28122
  }
28123
- while ((byte & 128) != 0) {
28123
+ while ((byte2 & 128) != 0) {
28124
28124
  ones++;
28125
- byte = byte << 1;
28125
+ byte2 = byte2 << 1;
28126
28126
  }
28127
- if ((byte & 128) != 0) {
28127
+ if ((byte2 & 128) != 0) {
28128
28128
  return -1;
28129
28129
  }
28130
28130
  for (let i2 = index + 1; i2 < mask.length; i2++) {
@@ -28138,8 +28138,8 @@ function simpleMaskLength(mask) {
28138
28138
  }
28139
28139
  function maskToHex(mask) {
28140
28140
  let hex = "0x";
28141
- for (const byte of mask) {
28142
- hex += (byte >> 4).toString(16) + (byte & 15).toString(16);
28141
+ for (const byte2 of mask) {
28142
+ hex += (byte2 >> 4).toString(16) + (byte2 & 15).toString(16);
28143
28143
  }
28144
28144
  return hex;
28145
28145
  }
@@ -30727,8 +30727,8 @@ var init_utils8 = __esm({
30727
30727
  ip4ToBytes = function(ip) {
30728
30728
  ip = ip.toString().trim();
30729
30729
  const bytes = new Uint8Array(4);
30730
- ip.split(/\./g).forEach((byte, index) => {
30731
- const value2 = parseInt(byte, 10);
30730
+ ip.split(/\./g).forEach((byte2, index) => {
30731
+ const value2 = parseInt(byte2, 10);
30732
30732
  if (isNaN(value2) || value2 < 0 || value2 > 255) {
30733
30733
  throw new InvalidMultiaddrError2("Invalid byte value in IP address");
30734
30734
  }
@@ -53788,11 +53788,11 @@ var require_build = __commonJS({
53788
53788
  let result = "";
53789
53789
  const len = buf.length;
53790
53790
  for (let i2 = 0; i2 < len; i2++) {
53791
- const byte = buf[i2];
53792
- if (byte < 16) {
53791
+ const byte2 = buf[i2];
53792
+ if (byte2 < 16) {
53793
53793
  result += "0";
53794
53794
  }
53795
- result += byte.toString(16);
53795
+ result += byte2.toString(16);
53796
53796
  }
53797
53797
  return result;
53798
53798
  }
@@ -55520,8 +55520,8 @@ ${values.join("\n")}` : `${blockName} :`;
55520
55520
  } else {
55521
55521
  const bits = [];
55522
55522
  const valueHex = this.valueBlock.valueHexView;
55523
- for (const byte of valueHex) {
55524
- bits.push(byte.toString(2).padStart(8, "0"));
55523
+ for (const byte2 of valueHex) {
55524
+ bits.push(byte2.toString(2).padStart(8, "0"));
55525
55525
  }
55526
55526
  const bitsStr = bits.join("");
55527
55527
  const name10 = this.constructor.NAME;
@@ -64507,12 +64507,12 @@ var require_Reflect = __commonJS({
64507
64507
  data[8] = data[8] & 191 | 128;
64508
64508
  var result = "";
64509
64509
  for (var offset = 0; offset < UUID_SIZE; ++offset) {
64510
- var byte = data[offset];
64510
+ var byte2 = data[offset];
64511
64511
  if (offset === 4 || offset === 6 || offset === 8)
64512
64512
  result += "-";
64513
- if (byte < 16)
64513
+ if (byte2 < 16)
64514
64514
  result += "0";
64515
- result += byte.toString(16).toLowerCase();
64515
+ result += byte2.toString(16).toLowerCase();
64516
64516
  }
64517
64517
  return result;
64518
64518
  }
@@ -66303,7 +66303,7 @@ var require_ip_converter = __commonJS({
66303
66303
  const half = uint8.length / 2;
66304
66304
  const addrBytes = uint8.slice(0, half);
66305
66305
  const maskBytes = uint8.slice(half);
66306
- const isAllZeros = uint8.every((byte) => byte === 0);
66306
+ const isAllZeros = uint8.every((byte2) => byte2 === 0);
66307
66307
  if (isAllZeros) {
66308
66308
  return uint8.length === 8 ? "0.0.0.0/0" : "::/0";
66309
66309
  }
@@ -119032,13 +119032,13 @@ var require_data_url = __commonJS({
119032
119032
  const bytes = encoder2.encode(input);
119033
119033
  return percentDecode(bytes);
119034
119034
  }
119035
- function isHexCharByte(byte) {
119036
- return byte >= 48 && byte <= 57 || byte >= 65 && byte <= 70 || byte >= 97 && byte <= 102;
119035
+ function isHexCharByte(byte2) {
119036
+ return byte2 >= 48 && byte2 <= 57 || byte2 >= 65 && byte2 <= 70 || byte2 >= 97 && byte2 <= 102;
119037
119037
  }
119038
- function hexByteToNumber(byte) {
119038
+ function hexByteToNumber(byte2) {
119039
119039
  return (
119040
119040
  // 0-9
119041
- byte >= 48 && byte <= 57 ? byte - 48 : (byte & 223) - 55
119041
+ byte2 >= 48 && byte2 <= 57 ? byte2 - 48 : (byte2 & 223) - 55
119042
119042
  );
119043
119043
  }
119044
119044
  function percentDecode(input) {
@@ -119047,10 +119047,10 @@ var require_data_url = __commonJS({
119047
119047
  let j = 0;
119048
119048
  let i2 = 0;
119049
119049
  while (i2 < length4) {
119050
- const byte = input[i2];
119051
- if (byte !== 37) {
119052
- output[j++] = byte;
119053
- } else if (byte === 37 && !(isHexCharByte(input[i2 + 1]) && isHexCharByte(input[i2 + 2]))) {
119050
+ const byte2 = input[i2];
119051
+ if (byte2 !== 37) {
119052
+ output[j++] = byte2;
119053
+ } else if (byte2 === 37 && !(isHexCharByte(input[i2 + 1]) && isHexCharByte(input[i2 + 2]))) {
119054
119054
  output[j++] = 37;
119055
119055
  } else {
119056
119056
  output[j++] = hexByteToNumber(input[i2 + 1]) << 4 | hexByteToNumber(input[i2 + 2]);
@@ -137344,8 +137344,8 @@ var require_util7 = __commonJS({
137344
137344
  return false;
137345
137345
  }
137346
137346
  for (let i2 = 0; i2 < value2.length; i2++) {
137347
- const byte = value2.charCodeAt(i2);
137348
- if (byte < 48 || byte > 57) {
137347
+ const byte2 = value2.charCodeAt(i2);
137348
+ if (byte2 < 48 || byte2 > 57) {
137349
137349
  return false;
137350
137350
  }
137351
137351
  }
@@ -211022,8 +211022,8 @@ var init_refresh = __esm({
211022
211022
  for (const { kadId } of this.routingTable.kb.toIterable()) {
211023
211023
  const distance = xor(this.routingTable.kb.localPeer.kadId, kadId);
211024
211024
  let leadingZeros = 0;
211025
- for (const byte of distance) {
211026
- if (byte === 0) {
211025
+ for (const byte2 of distance) {
211026
+ if (byte2 === 0) {
211027
211027
  leadingZeros++;
211028
211028
  } else {
211029
211029
  break;
@@ -232126,7 +232126,7 @@ function decodeCerthash(certhash2) {
232126
232126
  function ma2Fingerprint(ma) {
232127
232127
  const multihashDecoded = decodeCerthash(certhash(ma));
232128
232128
  const prefix = toSupportedHashFunction(multihashDecoded.code);
232129
- const fingerprint = multihashDecoded.digest.reduce((str, byte) => str + byte.toString(16).padStart(2, "0"), "");
232129
+ const fingerprint = multihashDecoded.digest.reduce((str, byte2) => str + byte2.toString(16).padStart(2, "0"), "");
232130
232130
  const sdp = fingerprint.match(/.{1,2}/g);
232131
232131
  if (sdp == null) {
232132
232132
  throw new InvalidFingerprintError(fingerprint, ma.toString());
@@ -236931,13 +236931,13 @@ var init_listener5 = __esm({
236931
236931
  await pEvent(socket, "readable");
236932
236932
  buffer2 = socket.read(1);
236933
236933
  }
236934
- const byte = buffer2[0];
236934
+ const byte2 = buffer2[0];
236935
236935
  let server2 = this.http;
236936
- if (byte < 32 || byte >= 127) {
236936
+ if (byte2 < 32 || byte2 >= 127) {
236937
236937
  server2 = this.https;
236938
236938
  }
236939
236939
  if (server2 == null) {
236940
- this.log.error("no appropriate listener configured for byte %d", byte);
236940
+ this.log.error("no appropriate listener configured for byte %d", byte2);
236941
236941
  socket.destroy();
236942
236942
  return;
236943
236943
  }
@@ -239340,15 +239340,15 @@ var require_sparse_array = __commonJS({
239340
239340
  if (bytePos >= this._bitArrays.length) {
239341
239341
  return -1;
239342
239342
  }
239343
- const byte = this._bitArrays[bytePos];
239343
+ const byte2 = this._bitArrays[bytePos];
239344
239344
  const bitPos = index - bytePos * BITS_PER_BYTE;
239345
- const exists2 = (byte & 1 << bitPos) > 0;
239345
+ const exists2 = (byte2 & 1 << bitPos) > 0;
239346
239346
  if (!exists2) {
239347
239347
  return -1;
239348
239348
  }
239349
239349
  const previousPopCount = this._bitArrays.slice(0, bytePos).reduce(popCountReduce, 0);
239350
239350
  const mask = ~(4294967295 << bitPos + 1);
239351
- const bytePopCount = popCount(byte & mask);
239351
+ const bytePopCount = popCount(byte2 & mask);
239352
239352
  const arrayPos = previousPopCount + bytePopCount - 1;
239353
239353
  return arrayPos;
239354
239354
  }
@@ -239440,8 +239440,8 @@ var require_sparse_array = __commonJS({
239440
239440
  return this._data.map(valueOnly);
239441
239441
  }
239442
239442
  };
239443
- function popCountReduce(count, byte) {
239444
- return count + popCount(byte);
239443
+ function popCountReduce(count, byte2) {
239444
+ return count + popCount(byte2);
239445
239445
  }
239446
239446
  function popCount(_v) {
239447
239447
  let v = _v;
@@ -239655,9 +239655,9 @@ var init_bucket2 = __esm({
239655
239655
  });
239656
239656
 
239657
239657
  // ../node_modules/hamt-sharding/dist/src/consumable-buffer.js
239658
- function byteBitsToInt(byte, start2, length4) {
239658
+ function byteBitsToInt(byte2, start2, length4) {
239659
239659
  const mask = maskFor(start2, length4);
239660
- return (byte & mask) >>> start2;
239660
+ return (byte2 & mask) >>> start2;
239661
239661
  }
239662
239662
  function maskFor(start2, length4) {
239663
239663
  return START_MASKS[start2] & STOP_MASKS[Math.min(length4 + start2 - 1, 7)];
@@ -239704,10 +239704,10 @@ var init_consumable_buffer = __esm({
239704
239704
  let pendingBits = bits;
239705
239705
  let result = 0;
239706
239706
  while (pendingBits > 0 && this._haveBits()) {
239707
- const byte = this._value[this._currentBytePos];
239707
+ const byte2 = this._value[this._currentBytePos];
239708
239708
  const availableBits = this._currentBitPos + 1;
239709
239709
  const taking = Math.min(availableBits, pendingBits);
239710
- const value2 = byteBitsToInt(byte, availableBits - taking, taking);
239710
+ const value2 = byteBitsToInt(byte2, availableBits - taking, taking);
239711
239711
  result = (result << taking) + value2;
239712
239712
  pendingBits -= taking;
239713
239713
  this._currentBitPos -= taking;
@@ -241535,9 +241535,9 @@ function wrapHash2(hashFn2) {
241535
241535
  }
241536
241536
  return hashing;
241537
241537
  }
241538
- function byteBitsToInt2(byte, start2, length4) {
241538
+ function byteBitsToInt2(byte2, start2, length4) {
241539
241539
  const mask = maskFor2(start2, length4);
241540
- return (byte & mask) >>> start2;
241540
+ return (byte2 & mask) >>> start2;
241541
241541
  }
241542
241542
  function maskFor2(start2, length4) {
241543
241543
  return START_MASKS2[start2] & STOP_MASKS2[Math.min(length4 + start2 - 1, 7)];
@@ -241645,10 +241645,10 @@ var init_consumable_hash2 = __esm({
241645
241645
  let pendingBits = bits;
241646
241646
  let result = 0;
241647
241647
  while (pendingBits > 0 && this._haveBits()) {
241648
- const byte = this._value[this._currentBytePos];
241648
+ const byte2 = this._value[this._currentBytePos];
241649
241649
  const availableBits = this._currentBitPos + 1;
241650
241650
  const taking = Math.min(availableBits, pendingBits);
241651
- const value2 = byteBitsToInt2(byte, availableBits - taking, taking);
241651
+ const value2 = byteBitsToInt2(byte2, availableBits - taking, taking);
241652
241652
  result = (result << taking) + value2;
241653
241653
  pendingBits -= taking;
241654
241654
  this._currentBitPos -= taking;
@@ -564075,7 +564075,8 @@ function renderImageAsciiPreview(title, imagePath, ascii2, renderer) {
564075
564075
  ${prefix}${c3.cyan(c3.bold(header.length > maxW ? header.slice(0, maxW - 3) + "..." : header))}
564076
564076
  `);
564077
564077
  for (const line of ascii2.split("\n")) {
564078
- process.stdout.write(`${prefix}${c3.dim(line)}
564078
+ const renderedLine = /\x1B\[[0-?]*[ -/]*[@-~]/.test(line) ? line : c3.dim(line);
564079
+ process.stdout.write(`${prefix}${renderedLine}
564079
564080
  `);
564080
564081
  }
564081
564082
  }
@@ -576297,8 +576298,8 @@ function stripAnsi3(s2) {
576297
576298
  return s2.replace(/\x1B\[[0-9;]*m/g, "");
576298
576299
  }
576299
576300
  function defaultRenderRow(item, focused, isActive) {
576300
- const marker = isActive ? selectColors.green("●") : focused ? selectColors.orange("●") : selectColors.dim("○");
576301
- const label = focused ? selectColors.orange(selectColors.bold(item.label)) : isActive ? selectColors.green(item.label) : item.label;
576301
+ const marker = isActive ? selectColors.green("●") : focused ? selectColors.blue("●") : selectColors.dim("○");
576302
+ const label = focused ? selectColors.blue(selectColors.bold(item.label)) : isActive ? selectColors.green(item.label) : item.label;
576302
576303
  const detail = item.detail ? ` ${selectColors.dim(item.detail)}` : "";
576303
576304
  return ` ${marker} ${label}${detail}`;
576304
576305
  }
@@ -576481,7 +576482,7 @@ function tuiSelect(opts) {
576481
576482
  const isActive = item.key === activeKey;
576482
576483
  if (deleteConfirmIdx === idx) {
576483
576484
  const yesLabel = deleteConfirmSel ? selectColors.bold(selectColors.green("[Yes]")) : selectColors.dim("[Yes]");
576484
- const noLabel = !deleteConfirmSel ? selectColors.bold(selectColors.orange("[No]")) : selectColors.dim("[No]");
576485
+ const noLabel = !deleteConfirmSel ? selectColors.bold(selectColors.blue("[No]")) : selectColors.dim("[No]");
576485
576486
  lines.push(` ${ansi3("31", "✕")} ${ansi3("31", stripAnsi3(item.label))} Delete? ${yesLabel} ${noLabel}`);
576486
576487
  } else if (filter2) {
576487
576488
  lines.push(matchRow(item, focused, isActive));
@@ -576921,7 +576922,7 @@ ${tuiBgSeq()}`);
576921
576922
  }
576922
576923
  });
576923
576924
  }
576924
- var isTTY3, selectColors;
576925
+ var isTTY3, MENU_ACTIVE_GREEN_256, selectColors;
576925
576926
  var init_tui_select = __esm({
576926
576927
  "packages/cli/src/tui/tui-select.ts"() {
576927
576928
  "use strict";
@@ -576929,9 +576930,10 @@ var init_tui_select = __esm({
576929
576930
  init_theme();
576930
576931
  init_layout2();
576931
576932
  isTTY3 = process.stdout.isTTY ?? false;
576933
+ MENU_ACTIVE_GREEN_256 = 154;
576932
576934
  selectColors = {
576933
- orange: (t2) => fg2563(208, t2),
576934
- green: (t2) => ansi3("32", t2),
576935
+ blue: (t2) => fg2563(39, t2),
576936
+ green: (t2) => fg2563(MENU_ACTIVE_GREEN_256, t2),
576935
576937
  dim: (t2) => fg2563(tuiTextDim(), t2),
576936
576938
  bold: (t2) => ansi3("1", t2),
576937
576939
  cyan: (t2) => ansi3("36", t2),
@@ -585130,7 +585132,7 @@ async function stepModelSelection(ep, rl, availableRows) {
585130
585132
  return false;
585131
585133
  },
585132
585134
  renderRow: (item, focused, _isActive) => {
585133
- const prefix = focused ? selectColors.orange("❯ ") : " ";
585135
+ const prefix = focused ? selectColors.blue("❯ ") : " ";
585134
585136
  if (item.key === "hdr") return selectColors.bold(item.label);
585135
585137
  return `${prefix}${item.label}`;
585136
585138
  }
@@ -585222,7 +585224,7 @@ async function stepEndpoints(config, ollamaUrl, rl, availableRows, repoRoot) {
585222
585224
  return false;
585223
585225
  },
585224
585226
  renderRow: (item, focused, _isActive) => {
585225
- const prefix = focused ? selectColors.orange("❯ ") : " ";
585227
+ const prefix = focused ? selectColors.blue("❯ ") : " ";
585226
585228
  if (item.key === "hdr") {
585227
585229
  return selectColors.bold(item.label);
585228
585230
  }
@@ -585685,7 +585687,7 @@ async function stepCohere(config, rl, availableRows) {
585685
585687
  return false;
585686
585688
  },
585687
585689
  renderRow: (item, focused, _isActive) => {
585688
- const prefix = focused ? selectColors.orange("❯ ") : " ";
585690
+ const prefix = focused ? selectColors.blue("❯ ") : " ";
585689
585691
  if (item.key === "hdr") return selectColors.bold(item.label);
585690
585692
  if (item.key.startsWith("desc")) return selectColors.dim(item.label);
585691
585693
  return `${prefix}${item.label}`;
@@ -585846,6 +585848,7 @@ var init_sponsor_wizard = __esm({
585846
585848
  // packages/cli/src/tui/image-ascii-preview.ts
585847
585849
  var image_ascii_preview_exports = {};
585848
585850
  __export(image_ascii_preview_exports, {
585851
+ IMAGE_ASCII_RENDER_OPTIONS: () => IMAGE_ASCII_RENDER_OPTIONS,
585849
585852
  buildImageAsciiPreview: () => buildImageAsciiPreview,
585850
585853
  defaultAsciiPreviewSize: () => defaultAsciiPreviewSize,
585851
585854
  extractSavedImagePath: () => extractSavedImagePath,
@@ -585919,9 +585922,101 @@ function readImageDimensions(imagePath) {
585919
585922
  }
585920
585923
  return null;
585921
585924
  }
585922
- function normalizeAscii(ascii2, width, height) {
585923
- const lines = ascii2.replace(ANSI_PATTERN, "").replace(/\r/g, "").split("\n").map((line) => line.replace(/\s+$/g, "")).filter((line, idx, all2) => line.length > 0 || idx > 0 && idx < all2.length - 1);
585924
- return lines.slice(0, height).map((line) => line.length > width ? line.slice(0, width) : line).join("\n").trimEnd();
585925
+ function stripAsciiAnsi(text) {
585926
+ return text.replace(ANSI_PATTERN, "");
585927
+ }
585928
+ function visibleWidth(text) {
585929
+ return stripAsciiAnsi(text).length;
585930
+ }
585931
+ function truncateVisible(text, width) {
585932
+ if (width <= 0) return "";
585933
+ let out = "";
585934
+ let visible = 0;
585935
+ let i2 = 0;
585936
+ let sawAnsi = false;
585937
+ while (i2 < text.length && visible < width) {
585938
+ ANSI_STICKY_PATTERN.lastIndex = i2;
585939
+ const ansi5 = ANSI_STICKY_PATTERN.exec(text);
585940
+ if (ansi5) {
585941
+ sawAnsi = true;
585942
+ out += ansi5[0];
585943
+ i2 = ANSI_STICKY_PATTERN.lastIndex;
585944
+ continue;
585945
+ }
585946
+ const codePoint = text.codePointAt(i2);
585947
+ if (codePoint == null) break;
585948
+ const ch = String.fromCodePoint(codePoint);
585949
+ out += ch;
585950
+ i2 += ch.length;
585951
+ visible++;
585952
+ }
585953
+ return sawAnsi ? `${out}\x1B[0m` : out;
585954
+ }
585955
+ function normalizeAscii(ascii2, width, height, options2 = {}) {
585956
+ const preserveAnsi = options2.preserveAnsi === true;
585957
+ const lines = ascii2.replace(/\r/g, "").split("\n").map((line) => preserveAnsi ? line : stripAsciiAnsi(line).replace(/\s+$/g, "")).filter((line, idx, all2) => stripAsciiAnsi(line).trim().length > 0 || idx > 0 && idx < all2.length - 1);
585958
+ const normalized = lines.slice(0, height).map((line) => visibleWidth(line) > width ? truncateVisible(line, width) : line);
585959
+ while (normalized.length > 0 && stripAsciiAnsi(normalized[normalized.length - 1] ?? "").trim().length === 0) {
585960
+ normalized.pop();
585961
+ }
585962
+ return normalized.join("\n");
585963
+ }
585964
+ function byte(value2, fallback) {
585965
+ const n2 = Number(value2);
585966
+ return Number.isFinite(n2) ? clamp5(n2, 0, 255) : fallback;
585967
+ }
585968
+ function luminance(r2, g, b) {
585969
+ return clamp5(Math.round(0.2126 * r2 + 0.7152 * g + 0.0722 * b), 0, 255);
585970
+ }
585971
+ function matrixPixel(cell) {
585972
+ if (cell && typeof cell === "object") {
585973
+ const pixel = cell;
585974
+ const valueFallback = byte(pixel.value, 0);
585975
+ const r2 = byte(pixel.r, valueFallback);
585976
+ const g = byte(pixel.g, valueFallback);
585977
+ const b = byte(pixel.b, valueFallback);
585978
+ const value2 = byte(pixel.value, luminance(r2, g, b));
585979
+ return { r: r2, g, b, value: value2 };
585980
+ }
585981
+ return { r: 0, g: 0, b: 0, value: 0 };
585982
+ }
585983
+ function stringifyImageAsciiMatrix(matrix) {
585984
+ const rows = Array.isArray(matrix) ? matrix : [];
585985
+ const displayLines = [];
585986
+ const plainLines = [];
585987
+ for (const rowUnknown of rows) {
585988
+ const row = Array.isArray(rowUnknown) ? rowUnknown : [];
585989
+ let displayLine = "";
585990
+ let plainLine = "";
585991
+ for (const cell of row) {
585992
+ const pixel = matrixPixel(cell);
585993
+ displayLine += `\x1B[38;2;${pixel.r};${pixel.g};${pixel.b}m${IMAGE_ASCII_BLOCK}\x1B[0m`;
585994
+ const idx = Math.round(pixel.value / 255 * (DEFAULT_PIXELS.length - 1));
585995
+ plainLine += DEFAULT_PIXELS[idx] ?? " ";
585996
+ }
585997
+ displayLines.push(displayLine);
585998
+ plainLines.push(plainLine.replace(/\s+$/g, ""));
585999
+ }
586000
+ return {
586001
+ ascii: displayLines.join("\n"),
586002
+ plainAscii: plainLines.join("\n")
586003
+ };
586004
+ }
586005
+ function normalizeImageToAsciiResult(converted, width, height) {
586006
+ let asciiSource = null;
586007
+ let plainSource = null;
586008
+ if (typeof converted === "string") {
586009
+ asciiSource = converted;
586010
+ } else if (converted && typeof converted === "object") {
586011
+ const result = converted;
586012
+ if (typeof result.ascii === "string") asciiSource = result.ascii;
586013
+ if (typeof result.plainAscii === "string") plainSource = result.plainAscii;
586014
+ }
586015
+ if (!asciiSource) return { ascii: null, error: "empty renderer output" };
586016
+ const ascii2 = normalizeAscii(asciiSource, width, height, { preserveAnsi: true });
586017
+ const plainAscii = normalizeAscii(plainSource ?? stripAsciiAnsi(asciiSource), width, height);
586018
+ if (!ascii2) return { ascii: null, error: "empty normalized renderer output" };
586019
+ return { ascii: ascii2, plainAscii: plainAscii || void 0 };
585925
586020
  }
585926
586021
  function previewFailure(message2, width) {
585927
586022
  const clean5 = message2.replace(/\s+/g, " ").trim();
@@ -585952,25 +586047,23 @@ async function convertWithImageToAscii(imagePath, width, height, timeoutMs) {
585952
586047
  imageToAscii(
585953
586048
  imagePath,
585954
586049
  {
585955
- colored: false,
586050
+ ...IMAGE_ASCII_RENDER_OPTIONS,
585956
586051
  size: { width, height },
585957
586052
  size_options: {
585958
586053
  preserve_aspect_ratio: false,
585959
586054
  fit_screen: false
585960
- }
586055
+ },
586056
+ stringify_fn: stringifyImageAsciiMatrix
585961
586057
  },
585962
586058
  (err, converted) => {
585963
586059
  if (settled) return;
585964
586060
  settled = true;
585965
586061
  clearTimeout(timer);
585966
- if (err || !converted) {
586062
+ if (err) {
585967
586063
  resolvePreview({ ascii: null, error: err?.message || "empty renderer output" });
585968
586064
  return;
585969
586065
  }
585970
- const normalized = normalizeAscii(converted, width, height);
585971
- resolvePreview(
585972
- normalized ? { ascii: normalized } : { ascii: null, error: "empty normalized renderer output" }
585973
- );
586066
+ resolvePreview(normalizeImageToAsciiResult(converted, width, height));
585974
586067
  }
585975
586068
  );
585976
586069
  } catch (err) {
@@ -586042,7 +586135,16 @@ async function buildImageAsciiPreview(inputPath, options2 = {}) {
586042
586135
  const timeoutMs = clamp5(options2.timeoutMs ?? 5e3, 500, 3e4);
586043
586136
  if (options2.preferPackage !== false) {
586044
586137
  const result = await convertWithImageToAscii(imagePath, width, height, timeoutMs);
586045
- if (result.ascii) return { path: imagePath, ascii: result.ascii, renderer: "image-to-ascii", width, height };
586138
+ if (result.ascii) {
586139
+ return {
586140
+ path: imagePath,
586141
+ ascii: result.ascii,
586142
+ plainAscii: result.plainAscii,
586143
+ renderer: "image-to-ascii",
586144
+ width,
586145
+ height
586146
+ };
586147
+ }
586046
586148
  return {
586047
586149
  path: imagePath,
586048
586150
  ascii: previewFailure(result.error || "renderer unavailable", width),
@@ -586052,12 +586154,13 @@ async function buildImageAsciiPreview(inputPath, options2 = {}) {
586052
586154
  };
586053
586155
  }
586054
586156
  const fallback = convertWithFfmpeg(imagePath, width, height, timeoutMs);
586055
- if (fallback) return { path: imagePath, ascii: fallback, renderer: "ffmpeg", width, height };
586157
+ if (fallback) return { path: imagePath, ascii: fallback, plainAscii: fallback, renderer: "ffmpeg", width, height };
586056
586158
  return null;
586057
586159
  }
586058
586160
  function formatImageAsciiContext(preview, label) {
586161
+ const ascii2 = preview.plainAscii ?? normalizeAscii(stripAsciiAnsi(preview.ascii), preview.width, preview.height);
586059
586162
  return `[ASCII preview of image: ${label}]
586060
- ${preview.ascii}`;
586163
+ ${ascii2}`;
586061
586164
  }
586062
586165
  function hasImageExtension(filePath) {
586063
586166
  const lower = filePath.toLowerCase();
@@ -586087,12 +586190,20 @@ function extractSavedImagePath(text, repoRoot) {
586087
586190
  }
586088
586191
  return null;
586089
586192
  }
586090
- var DEFAULT_PIXELS, ANSI_PATTERN, TERMINAL_CELL_ASPECT, IMAGE_PREVIEW_EXTENSIONS;
586193
+ var DEFAULT_PIXELS, IMAGE_ASCII_BLOCK, IMAGE_ASCII_RENDER_OPTIONS, ANSI_PATTERN, ANSI_STICKY_PATTERN, TERMINAL_CELL_ASPECT, IMAGE_PREVIEW_EXTENSIONS;
586091
586194
  var init_image_ascii_preview = __esm({
586092
586195
  "packages/cli/src/tui/image-ascii-preview.ts"() {
586093
586196
  "use strict";
586094
586197
  DEFAULT_PIXELS = " .,:;i1tfLCG08@";
586198
+ IMAGE_ASCII_BLOCK = "█";
586199
+ IMAGE_ASCII_RENDER_OPTIONS = Object.freeze({
586200
+ colored: true,
586201
+ pixels: IMAGE_ASCII_BLOCK.repeat(2),
586202
+ white_bg: true,
586203
+ px_background: Object.freeze({ r: 255, g: 255, b: 255 })
586204
+ });
586095
586205
  ANSI_PATTERN = /\x1B\[[0-?]*[ -/]*[@-~]/g;
586206
+ ANSI_STICKY_PATTERN = /\x1B\[[0-?]*[ -/]*[@-~]/y;
586096
586207
  TERMINAL_CELL_ASPECT = 0.52;
586097
586208
  IMAGE_PREVIEW_EXTENSIONS = /* @__PURE__ */ new Set([
586098
586209
  ".png",
@@ -596275,8 +596386,8 @@ async function showConfigEditor(ctx3) {
596275
596386
  if (item.kind === "header") {
596276
596387
  return ` ${item.label}`;
596277
596388
  }
596278
- const marker = focused ? selectColors.orange("●") : selectColors.dim("○");
596279
- const nameStr = focused ? selectColors.orange(selectColors.bold(item.label)) : item.label;
596389
+ const marker = focused ? selectColors.blue("●") : selectColors.dim("○");
596390
+ const nameStr = focused ? selectColors.blue(selectColors.bold(item.label)) : item.label;
596280
596391
  if (item.kind === "action") {
596281
596392
  return ` ${marker} ${nameStr} ${selectColors.dim(item.detail ?? "")}`;
596282
596393
  }
@@ -599891,7 +600002,7 @@ async function handleSponsoredEndpoint(ctx3, local) {
599891
600002
  availableRows: ctx3.availableContentRows?.(),
599892
600003
  renderRow: (item, focused, _isActive) => {
599893
600004
  if (item.key === "hdr") return selectColors.bold(item.label);
599894
- const prefix = focused ? selectColors.orange("❯ ") : " ";
600005
+ const prefix = focused ? selectColors.blue("❯ ") : " ";
599895
600006
  if (item.detail) {
599896
600007
  const detailLines = item.detail.split("\n");
599897
600008
  return `${prefix}${item.label}
@@ -601075,7 +601186,8 @@ async function handleUpdate(subcommand, ctx3) {
601075
601186
  buf += `\x1B[${boxTop + 2};${barCol}H\x1B[38;5;${accentColor}m${bar}\x1B[0m`;
601076
601187
  }
601077
601188
  const phaseText = _installPhase ? `${_installPhase}` : "";
601078
- const statusText = isDone ? `v${version4}` : statusLine || phaseText || `v${version4}`;
601189
+ const combinedStatus = phaseText && statusLine && !statusLine.startsWith(`${phaseText}:`) ? `${phaseText}: ${statusLine}` : statusLine || phaseText;
601190
+ const statusText = isDone ? `v${version4}` : combinedStatus || `v${version4}`;
601079
601191
  const statusTrunc = statusText.slice(0, innerW - 2);
601080
601192
  const sCol = centerCol - Math.floor(statusTrunc.length / 2);
601081
601193
  buf += `\x1B[${boxTop + 3};${sCol}H\x1B[38;5;${getDimColor()}m${statusTrunc}\x1B[0m`;
@@ -601134,7 +601246,7 @@ async function handleUpdate(subcommand, ctx3) {
601134
601246
  }
601135
601247
  };
601136
601248
  }
601137
- const { exec: exec5, execSync: es2 } = await import("node:child_process");
601249
+ const { exec: exec5, spawn: spawn32, execSync: es2 } = await import("node:child_process");
601138
601250
  const execA = (cmd, opts) => new Promise(
601139
601251
  (res, rej) => exec5(
601140
601252
  cmd,
@@ -601444,37 +601556,140 @@ async function handleUpdate(subcommand, ctx3) {
601444
601556
  const doOllama = menuResult.key === "full" && ollamaUpdate?.needsUpdate;
601445
601557
  const targetVersion = info?.latestVersion ?? currentVersion;
601446
601558
  const installOverlay = startInstallOverlay(targetVersion);
601559
+ const stripInstallAnsi = (value2) => value2.replace(/\x1B\][^\x07]*(?:\x07|\x1B\\)/g, "").replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, "").replace(/\r/g, "\n");
601560
+ const truncateInstallStatus = (value2, max = 88) => {
601561
+ const compact3 = value2.replace(/\s+/g, " ").trim();
601562
+ if (compact3.length <= max) return compact3;
601563
+ return compact3.slice(0, Math.max(1, max - 1)).trimEnd() + "…";
601564
+ };
601565
+ const summarizeInstallCommand = (cmd) => {
601566
+ const cleaned = cmd.replace(/^\s*sudo\s+/, "").replace(/\s+2>\/dev\/null/g, "").replace(/\s+\|\|\s+true\s*$/g, "").replace(/\s+/g, " ").trim();
601567
+ if (/^npm install -g omnius@/i.test(cleaned)) {
601568
+ const match = cleaned.match(/omnius@([^\s]+)/i);
601569
+ return `installing omnius@${match?.[1] ?? "latest"}`;
601570
+ }
601571
+ if (/^npm install\b/i.test(cleaned)) return "installing npm packages";
601572
+ if (/^npm update\b/i.test(cleaned)) return "updating npm packages";
601573
+ if (/^npm rebuild\b/i.test(cleaned)) return "rebuilding native modules";
601574
+ if (/pip"? install\b/i.test(cleaned)) return "upgrading Python packages";
601575
+ return truncateInstallStatus(cleaned, 64);
601576
+ };
601577
+ const summarizeInstallOutputLine = (line) => {
601578
+ const clean5 = truncateInstallStatus(stripInstallAnsi(line), 100);
601579
+ if (!clean5) return "";
601580
+ if (/^npm notice/i.test(clean5)) return "";
601581
+ if (/^\d+\s+packages?\s+are looking for funding/i.test(clean5)) return "";
601582
+ const deprecated = clean5.match(/^npm warn deprecated\s+(\S+)\s+(.+)/i);
601583
+ if (deprecated) {
601584
+ return truncateInstallStatus(`deprecated ${deprecated[1]}: ${deprecated[2]}`);
601585
+ }
601586
+ const warn = clean5.match(/^npm warn\s+(.+)/i);
601587
+ if (warn) return truncateInstallStatus(`warn: ${warn[1]}`);
601588
+ const fetch4 = clean5.match(/^npm http fetch\s+\S+\s+\d+\s+(.+?)\s+(\d+ms.*)?$/i);
601589
+ if (fetch4) return truncateInstallStatus(`fetching ${fetch4[1]}`);
601590
+ const run = clean5.match(/^npm info run\s+(\S+)\s+(\S+)\s+(.+)$/i);
601591
+ if (run) {
601592
+ const pkg = run[1];
601593
+ const script = run[2];
601594
+ const detail = run[3];
601595
+ if (/\{\s*code:\s*0/i.test(detail)) return `finished ${script}: ${pkg}`;
601596
+ return truncateInstallStatus(`running ${script}: ${pkg}`);
601597
+ }
601598
+ if (/node-gyp|prebuild-install|cmake|make\b|g\+\+|clang/i.test(clean5)) {
601599
+ return truncateInstallStatus(clean5);
601600
+ }
601601
+ if (/^(added|removed|changed|updated|up to date|audited)\b/i.test(clean5)) {
601602
+ return clean5;
601603
+ }
601604
+ if (/npm ERR!|error|failed/i.test(clean5)) return truncateInstallStatus(clean5);
601605
+ return clean5;
601606
+ };
601447
601607
  let installError = "";
601448
601608
  _installProgress = 0;
601449
601609
  _installTotal = 20;
601450
601610
  _installPhase = "Preparing...";
601451
- const runInstall2 = (cmd) => new Promise((resolve52) => {
601452
- const child = exec5(cmd, { timeout: 18e4 }, (err, _stdout, stderr) => {
601453
- if (err) installError = (stderr || err.message || "").trim();
601454
- resolve52(!err);
601611
+ const runInstall2 = (cmd, label = summarizeInstallCommand(cmd)) => new Promise((resolve52) => {
601612
+ const startedAt2 = Date.now();
601613
+ let lastOutputAt = startedAt2;
601614
+ let settled = false;
601615
+ const errorLines = [];
601616
+ const finish = (ok2, error) => {
601617
+ if (settled) return;
601618
+ settled = true;
601619
+ clearInterval(heartbeat);
601620
+ clearTimeout(timeout2);
601621
+ if (!ok2 && error) installError = error.trim();
601622
+ resolve52(ok2);
601623
+ };
601624
+ const noteLine = (line, isError2) => {
601625
+ const cleaned = stripInstallAnsi(line).trim();
601626
+ if (!cleaned) return;
601627
+ if (isError2) {
601628
+ errorLines.push(cleaned);
601629
+ if (errorLines.length > 12) errorLines.shift();
601630
+ }
601631
+ const status = summarizeInstallOutputLine(cleaned);
601632
+ if (!status) return;
601633
+ _installProgress++;
601634
+ lastOutputAt = Date.now();
601635
+ installOverlay.setStatus(status);
601636
+ };
601637
+ installOverlay.setStatus(`starting ${label}`);
601638
+ const heartbeat = setInterval(() => {
601639
+ if (settled) return;
601640
+ const elapsed = Math.max(1, Math.floor((Date.now() - startedAt2) / 1e3));
601641
+ if (Date.now() - lastOutputAt > 1500) {
601642
+ installOverlay.setStatus(`${label} · ${elapsed}s`);
601643
+ }
601644
+ }, 1e3);
601645
+ heartbeat.unref?.();
601646
+ const child = spawn32(cmd, {
601647
+ shell: true,
601648
+ stdio: ["ignore", "pipe", "pipe"],
601649
+ env: {
601650
+ ...process.env,
601651
+ FORCE_COLOR: "0",
601652
+ NO_COLOR: "1",
601653
+ npm_config_progress: "true",
601654
+ npm_config_loglevel: "notice"
601655
+ }
601455
601656
  });
601657
+ const timeout2 = setTimeout(() => {
601658
+ installError = `${label} timed out`;
601659
+ installOverlay.setStatus(`${label} timed out`);
601660
+ try {
601661
+ child.kill("SIGTERM");
601662
+ } catch {
601663
+ }
601664
+ setTimeout(() => {
601665
+ try {
601666
+ child.kill("SIGKILL");
601667
+ } catch {
601668
+ }
601669
+ }, 2500).unref?.();
601670
+ }, 18e4);
601671
+ timeout2.unref?.();
601456
601672
  child.stdout?.on("data", (chunk) => {
601457
601673
  const text = String(chunk);
601458
601674
  for (const line of text.split("\n")) {
601459
- const trimmed = line.trim();
601460
- if (trimmed) {
601461
- _installProgress++;
601462
- if (!trimmed.startsWith("npm") && trimmed.length < 50) {
601463
- installOverlay.setStatus(trimmed);
601464
- }
601465
- }
601675
+ noteLine(line, false);
601466
601676
  }
601467
601677
  });
601468
601678
  child.stderr?.on("data", (chunk) => {
601469
601679
  const text = String(chunk);
601470
601680
  for (const line of text.split("\n")) {
601471
- const trimmed = line.trim();
601472
- if (trimmed && !trimmed.includes("npm warn") && !trimmed.includes("npm notice")) {
601473
- _installProgress++;
601474
- installOverlay.setStatus(trimmed.slice(0, 40));
601475
- }
601681
+ noteLine(line, true);
601476
601682
  }
601477
601683
  });
601684
+ child.on("error", (err) => finish(false, err.message));
601685
+ child.on("close", (code8, signal) => {
601686
+ if (code8 === 0) {
601687
+ finish(true);
601688
+ return;
601689
+ }
601690
+ const errorText = errorLines.join("\n") || installError || `${label} exited with ${signal ? `signal ${signal}` : `code ${code8 ?? "unknown"}`}`;
601691
+ finish(false, errorText);
601692
+ });
601478
601693
  });
601479
601694
  if (needsSudo) {
601480
601695
  installOverlay.stop("Requesting permissions...");
@@ -601507,10 +601722,9 @@ async function handleUpdate(subcommand, ctx3) {
601507
601722
  installOverlay.setProgress(0, totalPhases || 1);
601508
601723
  if (doPackage && info) {
601509
601724
  installOverlay.setPhase("Package");
601510
- installOverlay.setStatus("Installing package...");
601511
601725
  const versionSpec = info.latestVersion ? `@${info.latestVersion}` : "@latest";
601512
601726
  const installCmd = `${sudoPrefix}npm install -g omnius${versionSpec} --prefer-online --cache-min=0`;
601513
- let installOk = await runInstall2(installCmd);
601727
+ let installOk = await runInstall2(installCmd, `installing omnius${versionSpec}`);
601514
601728
  if (!installOk && process.platform === "win32" && /EPERM|EACCES|access|denied|permission/i.test(installError)) {
601515
601729
  installOverlay.setStatus("Elevating permissions...");
601516
601730
  installError = "";
@@ -624452,6 +624666,7 @@ var init_mouse_filter = __esm({
624452
624666
  onPointer = null;
624453
624667
  onKeyboard = null;
624454
624668
  flushTimer = null;
624669
+ expectPrefixlessMouseUntil = 0;
624455
624670
  constructor(scrollHandler, activityHandler, pointerHandler, keyboardHandler) {
624456
624671
  super();
624457
624672
  this.onScroll = scrollHandler;
@@ -624467,32 +624682,26 @@ var init_mouse_filter = __esm({
624467
624682
  let output = "";
624468
624683
  let i2 = 0;
624469
624684
  while (i2 < this.buffer.length) {
624685
+ const remaining = this.buffer.slice(i2);
624686
+ const prefixlessMouse = this.matchPrefixlessSgrMouse(remaining);
624687
+ if (prefixlessMouse) {
624688
+ this.handleSgrMouse(prefixlessMouse);
624689
+ i2 += prefixlessMouse.raw.length;
624690
+ continue;
624691
+ }
624692
+ if (this.looksLikePartialPrefixlessSgrMouse(remaining)) {
624693
+ break;
624694
+ }
624470
624695
  if (this.buffer[i2] === "\x1B") {
624471
- const remaining = this.buffer.slice(i2);
624472
624696
  const mouseMatch = remaining.match(/^\x1B\[<(\d+);(\d+);(\d+)([Mm])/);
624473
624697
  if (mouseMatch) {
624474
- const btn = parseInt(mouseMatch[1]);
624475
- const col = parseInt(mouseMatch[2]);
624476
- const row = parseInt(mouseMatch[3]);
624477
- const suffix = mouseMatch[4];
624478
- if ((btn === 64 || btn === 96) && this.onScroll)
624479
- this.onScroll("up", 3, row);
624480
- else if ((btn === 65 || btn === 97) && this.onScroll)
624481
- this.onScroll("down", 3, row);
624482
- else if (this.onPointer) {
624483
- const hasShift = (btn & 4) !== 0 && btn < 32;
624484
- if (btn === 2) {
624485
- } else if (hasShift) {
624486
- process.stdout.write("\x1B[?1002l\x1B[?1006l");
624487
- } else if ((btn === 0 || btn === 1) && suffix === "M") {
624488
- this.onPointer("press", col, row);
624489
- } else if (btn >= 32 && btn <= 35 && suffix === "M") {
624490
- this.onPointer("drag", col, row);
624491
- } else if (suffix === "m") {
624492
- this.onPointer("release", col, row);
624493
- }
624494
- }
624495
- if (this.onActivity) this.onActivity();
624698
+ this.handleSgrMouse({
624699
+ raw: mouseMatch[0],
624700
+ btn: parseInt(mouseMatch[1]),
624701
+ col: parseInt(mouseMatch[2]),
624702
+ row: parseInt(mouseMatch[3]),
624703
+ suffix: mouseMatch[4]
624704
+ });
624496
624705
  i2 += mouseMatch[0].length;
624497
624706
  continue;
624498
624707
  }
@@ -624527,8 +624736,14 @@ var init_mouse_filter = __esm({
624527
624736
  this.flushTimer = setTimeout(() => {
624528
624737
  if (this.buffer.length > 0) {
624529
624738
  if (this.buffer.startsWith("\x1B[<") || this.buffer.startsWith("\x1B[M")) {
624739
+ this.expectPrefixlessMouseUntil = Date.now() + 1e3;
624740
+ this.buffer = "";
624741
+ } else if (this.buffer === "\x1B[") {
624742
+ this.expectPrefixlessMouseUntil = Date.now() + 1e3;
624743
+ this.buffer = "";
624744
+ } else if (this.looksLikePartialPrefixlessSgrMouse(this.buffer)) {
624530
624745
  this.buffer = "";
624531
- } else if (this.buffer === "\x1B" || this.buffer === "\x1B[") {
624746
+ } else if (this.buffer === "\x1B") {
624532
624747
  this.push(this.buffer);
624533
624748
  this.buffer = "";
624534
624749
  } else {
@@ -624546,11 +624761,68 @@ var init_mouse_filter = __esm({
624546
624761
  this.flushTimer = null;
624547
624762
  }
624548
624763
  if (this.buffer.length > 0) {
624764
+ if (this.buffer.startsWith("\x1B[<") || this.buffer.startsWith("\x1B[M") || this.buffer === "\x1B[" || this.looksLikePartialPrefixlessSgrMouse(this.buffer)) {
624765
+ this.buffer = "";
624766
+ callback();
624767
+ return;
624768
+ }
624549
624769
  this.push(this.buffer);
624550
624770
  this.buffer = "";
624551
624771
  }
624552
624772
  callback();
624553
624773
  }
624774
+ matchPrefixlessSgrMouse(input) {
624775
+ const match = input.match(/^(<)?(\d{1,3});(\d{1,5});(\d{1,5})([Mm])/);
624776
+ if (!match) return null;
624777
+ const hasMarker = Boolean(match[1]);
624778
+ const btn = parseInt(match[2], 10);
624779
+ const col = parseInt(match[3], 10);
624780
+ const row = parseInt(match[4], 10);
624781
+ const suffix = match[5];
624782
+ if (!Number.isFinite(btn) || !Number.isFinite(col) || !Number.isFinite(row))
624783
+ return null;
624784
+ if (col <= 0 || row <= 0) return null;
624785
+ if (!hasMarker && Date.now() > this.expectPrefixlessMouseUntil && !this.isKnownMouseButton(btn))
624786
+ return null;
624787
+ if (btn < 0 || btn > 255) return null;
624788
+ return { raw: match[0], btn, col, row, suffix };
624789
+ }
624790
+ looksLikePartialPrefixlessSgrMouse(input) {
624791
+ if (input.length < 2) return false;
624792
+ if (/^<\d{1,3};\d{0,5}(?:;\d{0,5})?$/.test(input)) return true;
624793
+ if (Date.now() <= this.expectPrefixlessMouseUntil && /^\d{1,3};\d{0,5}(?:;\d{0,5})?$/.test(input)) {
624794
+ return true;
624795
+ }
624796
+ return false;
624797
+ }
624798
+ isKnownMouseButton(btn) {
624799
+ if (btn >= 0 && btn <= 6) return true;
624800
+ if (btn >= 32 && btn <= 39) return true;
624801
+ if (btn >= 64 && btn <= 71) return true;
624802
+ if (btn >= 96 && btn <= 103) return true;
624803
+ return false;
624804
+ }
624805
+ handleSgrMouse(mouse) {
624806
+ const { btn, col, row, suffix } = mouse;
624807
+ if ((btn === 64 || btn === 96) && this.onScroll)
624808
+ this.onScroll("up", 3, row);
624809
+ else if ((btn === 65 || btn === 97) && this.onScroll)
624810
+ this.onScroll("down", 3, row);
624811
+ else if (this.onPointer) {
624812
+ const hasShift = (btn & 4) !== 0 && btn < 32;
624813
+ if (btn === 2) {
624814
+ } else if (hasShift) {
624815
+ process.stdout.write("\x1B[?1002l\x1B[?1006l");
624816
+ } else if ((btn === 0 || btn === 1) && suffix === "M") {
624817
+ this.onPointer("press", col, row);
624818
+ } else if (btn >= 32 && btn <= 35 && suffix === "M") {
624819
+ this.onPointer("drag", col, row);
624820
+ } else if (suffix === "m") {
624821
+ this.onPointer("release", col, row);
624822
+ }
624823
+ }
624824
+ if (this.onActivity) this.onActivity();
624825
+ }
624554
624826
  };
624555
624827
  }
624556
624828
  });
@@ -624582,6 +624854,7 @@ var init_direct_input = __esm({
624582
624854
  _buffer = "";
624583
624855
  // partial escape sequence buffer
624584
624856
  _flushTimer = null;
624857
+ _expectPrefixlessMouseUntil = 0;
624585
624858
  constructor(input, options2) {
624586
624859
  super();
624587
624860
  this._input = input;
@@ -624749,10 +625022,18 @@ var init_direct_input = __esm({
624749
625022
  _processBuffer() {
624750
625023
  let i2 = 0;
624751
625024
  while (i2 < this._buffer.length) {
625025
+ const remaining = this._buffer.slice(i2);
625026
+ const prefixlessMouse = this._matchPrefixlessSgrMouse(remaining);
625027
+ if (prefixlessMouse) {
625028
+ i2 += prefixlessMouse.length;
625029
+ continue;
625030
+ }
625031
+ if (this._looksLikePartialPrefixlessSgrMouse(remaining)) {
625032
+ break;
625033
+ }
624752
625034
  const ch = this._buffer[i2];
624753
625035
  const code8 = ch.charCodeAt(0);
624754
625036
  if (code8 === 27) {
624755
- const remaining = this._buffer.slice(i2);
624756
625037
  if (remaining.length >= 2 && remaining[1] === "[") {
624757
625038
  const mouseMatch = remaining.match(/^\x1B\[<(\d+);(\d+);(\d+)([Mm])/);
624758
625039
  if (mouseMatch) {
@@ -624770,6 +625051,7 @@ var init_direct_input = __esm({
624770
625051
  break;
624771
625052
  }
624772
625053
  if (remaining.startsWith("\x1B[<")) {
625054
+ this._expectPrefixlessMouseUntil = Date.now() + 1e3;
624773
625055
  let end = 3;
624774
625056
  while (end < remaining.length && remaining[end] !== "M" && remaining[end] !== "m") end++;
624775
625057
  if (end < remaining.length) end++;
@@ -624818,6 +625100,20 @@ var init_direct_input = __esm({
624818
625100
  this._flushTimer = setTimeout(() => {
624819
625101
  this._flushTimer = null;
624820
625102
  if (this._buffer.length > 0) {
625103
+ if (this._buffer.startsWith("\x1B[<") || this._buffer.startsWith("\x1B[M")) {
625104
+ this._expectPrefixlessMouseUntil = Date.now() + 1e3;
625105
+ this._buffer = "";
625106
+ return;
625107
+ }
625108
+ if (this._buffer === "\x1B[") {
625109
+ this._expectPrefixlessMouseUntil = Date.now() + 1e3;
625110
+ this._buffer = "";
625111
+ return;
625112
+ }
625113
+ if (this._looksLikePartialPrefixlessSgrMouse(this._buffer)) {
625114
+ this._buffer = "";
625115
+ return;
625116
+ }
624821
625117
  if (this._buffer === "\x1B") {
624822
625118
  this.emit("escape");
624823
625119
  }
@@ -624831,6 +625127,35 @@ var init_direct_input = __esm({
624831
625127
  }
624832
625128
  }
624833
625129
  }
625130
+ _matchPrefixlessSgrMouse(input) {
625131
+ const match = input.match(/^(<)?(\d{1,3});(\d{1,5});(\d{1,5})([Mm])/);
625132
+ if (!match) return null;
625133
+ const hasMarker = Boolean(match[1]);
625134
+ const btn = parseInt(match[2], 10);
625135
+ const col = parseInt(match[3], 10);
625136
+ const row = parseInt(match[4], 10);
625137
+ if (!Number.isFinite(btn) || !Number.isFinite(col) || !Number.isFinite(row))
625138
+ return null;
625139
+ if (btn < 0 || btn > 255 || col <= 0 || row <= 0) return null;
625140
+ if (!hasMarker && Date.now() > this._expectPrefixlessMouseUntil && !this._isKnownMouseButton(btn))
625141
+ return null;
625142
+ return { length: match[0].length };
625143
+ }
625144
+ _looksLikePartialPrefixlessSgrMouse(input) {
625145
+ if (input.length < 2) return false;
625146
+ if (/^<\d{1,3};\d{0,5}(?:;\d{0,5})?$/.test(input)) return true;
625147
+ if (Date.now() <= this._expectPrefixlessMouseUntil && /^\d{1,3};\d{0,5}(?:;\d{0,5})?$/.test(input)) {
625148
+ return true;
625149
+ }
625150
+ return false;
625151
+ }
625152
+ _isKnownMouseButton(btn) {
625153
+ if (btn >= 0 && btn <= 6) return true;
625154
+ if (btn >= 32 && btn <= 39) return true;
625155
+ if (btn >= 64 && btn <= 71) return true;
625156
+ if (btn >= 96 && btn <= 103) return true;
625157
+ return false;
625158
+ }
624834
625159
  _emitChangeIfNeeded(beforeLine, beforeCursor) {
624835
625160
  if (this.line === beforeLine && this.cursor === beforeCursor) return;
624836
625161
  this.emit("change", { line: this.line, cursor: this.cursor });
@@ -19,6 +19,33 @@ function clamp(value, min, max) {
19
19
  return Math.max(min, Math.min(max, n));
20
20
  }
21
21
 
22
+ function clampByte(value, fallback) {
23
+ var n = Number(value);
24
+ if (!Number.isFinite(n)) return fallback;
25
+ return clamp(n, 0, 255);
26
+ }
27
+
28
+ function normalizeRgb(value, fallback) {
29
+ if (!isObject(value)) return fallback || null;
30
+ return {
31
+ r: clampByte(value.r, fallback ? fallback.r : 0),
32
+ g: clampByte(value.g, fallback ? fallback.g : 0),
33
+ b: clampByte(value.b, fallback ? fallback.b : 0)
34
+ };
35
+ }
36
+
37
+ function rgbToFfmpegColor(rgb) {
38
+ if (!rgb) return "black";
39
+ function hex(value) {
40
+ return clampByte(value, 0).toString(16).padStart(2, "0");
41
+ }
42
+ return "0x" + hex(rgb.r) + hex(rgb.g) + hex(rgb.b);
43
+ }
44
+
45
+ function luminance(r, g, b) {
46
+ return clampByte(Math.round((0.2126 * r) + (0.7152 * g) + (0.0722 * b)), 0);
47
+ }
48
+
22
49
  function percentOrNumber(value, basis, fallback) {
23
50
  if (typeof value === "number" && Number.isFinite(value)) return value;
24
51
  if (typeof value === "string") {
@@ -53,9 +80,14 @@ function normalizeOptions(options) {
53
80
  if (Array.isArray(pixels)) pixels = pixels.join("");
54
81
  if (typeof pixels !== "string" || pixels.length < 2) pixels = DEFAULT_PIXELS;
55
82
  if (options.reverse === true) pixels = pixels.split("").reverse().join("");
83
+ var pxBackground = null;
84
+ if (options.white_bg === true) pxBackground = { r: 255, g: 255, b: 255 };
85
+ if (isObject(options.px_background)) pxBackground = normalizeRgb(options.px_background, pxBackground);
56
86
  return {
57
87
  pixels: pixels,
58
88
  colored: options.colored === true,
89
+ colorBackground: options.bg === true,
90
+ pxBackground: pxBackground,
59
91
  concat: options.concat !== false,
60
92
  stringify: options.stringify !== false,
61
93
  timeoutMs: clamp(options.timeoutMs || options.timeout || 5000, 500, 60000),
@@ -117,24 +149,38 @@ function sourceToFile(source, callback) {
117
149
  callback(null, source, false);
118
150
  }
119
151
 
120
- function buildFilter(width, height, preserveAspectRatio) {
152
+ function buildFilter(width, height, preserveAspectRatio, pxBackground) {
121
153
  if (preserveAspectRatio) {
154
+ var padColor = rgbToFfmpegColor(pxBackground);
122
155
  return [
123
156
  "scale=" + width + ":" + height + ":force_original_aspect_ratio=decrease",
124
- "pad=" + width + ":" + height + ":(ow-iw)/2:(oh-ih)/2:color=black",
125
- "format=gray"
157
+ "pad=" + width + ":" + height + ":(ow-iw)/2:(oh-ih)/2:color=" + padColor,
158
+ "format=rgba"
126
159
  ].join(",");
127
160
  }
128
- return "scale=" + width + ":" + height + ",format=gray";
161
+ return "scale=" + width + ":" + height + ",format=rgba";
129
162
  }
130
163
 
131
- function matrixFromRaw(raw, width, height) {
164
+ function matrixFromRaw(raw, width, height, pxBackground) {
132
165
  var matrix = [];
133
166
  for (var y = 0; y < height; y++) {
134
167
  var row = [];
135
168
  for (var x = 0; x < width; x++) {
136
- var value = raw[y * width + x] || 0;
137
- row.push({ r: value, g: value, b: value, a: 255, value: value });
169
+ var offset = ((y * width) + x) * 4;
170
+ var r = raw[offset] || 0;
171
+ var g = raw[offset + 1] || 0;
172
+ var b = raw[offset + 2] || 0;
173
+ var a = raw[offset + 3];
174
+ if (a == null) a = 255;
175
+ if (pxBackground && a < 255) {
176
+ var alpha = a / 255;
177
+ r = Math.round((r * alpha) + (pxBackground.r * (1 - alpha)));
178
+ g = Math.round((g * alpha) + (pxBackground.g * (1 - alpha)));
179
+ b = Math.round((b * alpha) + (pxBackground.b * (1 - alpha)));
180
+ a = 255;
181
+ }
182
+ var value = luminance(r, g, b);
183
+ row.push({ r: r, g: g, b: b, a: a, value: value });
138
184
  }
139
185
  matrix.push(row);
140
186
  }
@@ -148,11 +194,16 @@ function stringifyMatrix(matrix, options) {
148
194
  for (var y = 0; y < matrix.length; y++) {
149
195
  var line = "";
150
196
  for (var x = 0; x < matrix[y].length; x++) {
151
- var value = matrix[y][x].value || 0;
197
+ var pixel = matrix[y][x] || {};
198
+ var value = pixel.value || 0;
152
199
  var idx = Math.round((value / 255) * maxIdx);
153
200
  var ch = pixels[idx] || " ";
154
201
  if (options.colored) {
155
- line += "\x1b[38;2;" + value + ";" + value + ";" + value + "m" + ch + "\x1b[0m";
202
+ var r = pixel.r == null ? value : pixel.r;
203
+ var g = pixel.g == null ? value : pixel.g;
204
+ var b = pixel.b == null ? value : pixel.b;
205
+ var mode = options.colorBackground ? "48" : "38";
206
+ line += "\x1b[" + mode + ";2;" + r + ";" + g + ";" + b + "m" + ch + "\x1b[0m";
156
207
  } else {
157
208
  line += ch;
158
209
  }
@@ -172,19 +223,19 @@ function renderFile(filePath, options, callback) {
172
223
  "-i",
173
224
  filePath,
174
225
  "-vf",
175
- buildFilter(width, height, options.preserveAspectRatio),
226
+ buildFilter(width, height, options.preserveAspectRatio, options.pxBackground),
176
227
  "-frames:v",
177
228
  "1",
178
229
  "-f",
179
230
  "rawvideo",
180
231
  "-pix_fmt",
181
- "gray",
232
+ "rgba",
182
233
  "-"
183
234
  ];
184
235
 
185
236
  childProcess.execFile("ffmpeg", args, {
186
237
  encoding: "buffer",
187
- maxBuffer: width * height + 4096,
238
+ maxBuffer: (width * height * 4) + 4096,
188
239
  timeout: options.timeoutMs
189
240
  }, function (err, stdout, stderr) {
190
241
  if (err) {
@@ -192,11 +243,11 @@ function renderFile(filePath, options, callback) {
192
243
  callback(new Error("image-to-ascii failed via ffmpeg: " + detail));
193
244
  return;
194
245
  }
195
- if (!stdout || stdout.length < width * height) {
246
+ if (!stdout || stdout.length < width * height * 4) {
196
247
  callback(new Error("image-to-ascii decoded too few pixels for " + width + "x" + height));
197
248
  return;
198
249
  }
199
- var matrix = matrixFromRaw(stdout, width, height);
250
+ var matrix = matrixFromRaw(stdout, width, height, options.pxBackground);
200
251
  if (!options.stringify) {
201
252
  callback(null, matrix);
202
253
  return;
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.103",
3
+ "version": "1.0.104",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "omnius",
9
- "version": "1.0.103",
9
+ "version": "1.0.104",
10
10
  "bundleDependencies": [
11
11
  "image-to-ascii"
12
12
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnius",
3
- "version": "1.0.103",
3
+ "version": "1.0.104",
4
4
  "description": "AI coding agent powered by open-source models (Ollama/vLLM) — interactive TUI with agentic tool-calling loop",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,6 +19,33 @@ function clamp(value, min, max) {
19
19
  return Math.max(min, Math.min(max, n));
20
20
  }
21
21
 
22
+ function clampByte(value, fallback) {
23
+ var n = Number(value);
24
+ if (!Number.isFinite(n)) return fallback;
25
+ return clamp(n, 0, 255);
26
+ }
27
+
28
+ function normalizeRgb(value, fallback) {
29
+ if (!isObject(value)) return fallback || null;
30
+ return {
31
+ r: clampByte(value.r, fallback ? fallback.r : 0),
32
+ g: clampByte(value.g, fallback ? fallback.g : 0),
33
+ b: clampByte(value.b, fallback ? fallback.b : 0)
34
+ };
35
+ }
36
+
37
+ function rgbToFfmpegColor(rgb) {
38
+ if (!rgb) return "black";
39
+ function hex(value) {
40
+ return clampByte(value, 0).toString(16).padStart(2, "0");
41
+ }
42
+ return "0x" + hex(rgb.r) + hex(rgb.g) + hex(rgb.b);
43
+ }
44
+
45
+ function luminance(r, g, b) {
46
+ return clampByte(Math.round((0.2126 * r) + (0.7152 * g) + (0.0722 * b)), 0);
47
+ }
48
+
22
49
  function percentOrNumber(value, basis, fallback) {
23
50
  if (typeof value === "number" && Number.isFinite(value)) return value;
24
51
  if (typeof value === "string") {
@@ -53,9 +80,14 @@ function normalizeOptions(options) {
53
80
  if (Array.isArray(pixels)) pixels = pixels.join("");
54
81
  if (typeof pixels !== "string" || pixels.length < 2) pixels = DEFAULT_PIXELS;
55
82
  if (options.reverse === true) pixels = pixels.split("").reverse().join("");
83
+ var pxBackground = null;
84
+ if (options.white_bg === true) pxBackground = { r: 255, g: 255, b: 255 };
85
+ if (isObject(options.px_background)) pxBackground = normalizeRgb(options.px_background, pxBackground);
56
86
  return {
57
87
  pixels: pixels,
58
88
  colored: options.colored === true,
89
+ colorBackground: options.bg === true,
90
+ pxBackground: pxBackground,
59
91
  concat: options.concat !== false,
60
92
  stringify: options.stringify !== false,
61
93
  timeoutMs: clamp(options.timeoutMs || options.timeout || 5000, 500, 60000),
@@ -117,24 +149,38 @@ function sourceToFile(source, callback) {
117
149
  callback(null, source, false);
118
150
  }
119
151
 
120
- function buildFilter(width, height, preserveAspectRatio) {
152
+ function buildFilter(width, height, preserveAspectRatio, pxBackground) {
121
153
  if (preserveAspectRatio) {
154
+ var padColor = rgbToFfmpegColor(pxBackground);
122
155
  return [
123
156
  "scale=" + width + ":" + height + ":force_original_aspect_ratio=decrease",
124
- "pad=" + width + ":" + height + ":(ow-iw)/2:(oh-ih)/2:color=black",
125
- "format=gray"
157
+ "pad=" + width + ":" + height + ":(ow-iw)/2:(oh-ih)/2:color=" + padColor,
158
+ "format=rgba"
126
159
  ].join(",");
127
160
  }
128
- return "scale=" + width + ":" + height + ",format=gray";
161
+ return "scale=" + width + ":" + height + ",format=rgba";
129
162
  }
130
163
 
131
- function matrixFromRaw(raw, width, height) {
164
+ function matrixFromRaw(raw, width, height, pxBackground) {
132
165
  var matrix = [];
133
166
  for (var y = 0; y < height; y++) {
134
167
  var row = [];
135
168
  for (var x = 0; x < width; x++) {
136
- var value = raw[y * width + x] || 0;
137
- row.push({ r: value, g: value, b: value, a: 255, value: value });
169
+ var offset = ((y * width) + x) * 4;
170
+ var r = raw[offset] || 0;
171
+ var g = raw[offset + 1] || 0;
172
+ var b = raw[offset + 2] || 0;
173
+ var a = raw[offset + 3];
174
+ if (a == null) a = 255;
175
+ if (pxBackground && a < 255) {
176
+ var alpha = a / 255;
177
+ r = Math.round((r * alpha) + (pxBackground.r * (1 - alpha)));
178
+ g = Math.round((g * alpha) + (pxBackground.g * (1 - alpha)));
179
+ b = Math.round((b * alpha) + (pxBackground.b * (1 - alpha)));
180
+ a = 255;
181
+ }
182
+ var value = luminance(r, g, b);
183
+ row.push({ r: r, g: g, b: b, a: a, value: value });
138
184
  }
139
185
  matrix.push(row);
140
186
  }
@@ -148,11 +194,16 @@ function stringifyMatrix(matrix, options) {
148
194
  for (var y = 0; y < matrix.length; y++) {
149
195
  var line = "";
150
196
  for (var x = 0; x < matrix[y].length; x++) {
151
- var value = matrix[y][x].value || 0;
197
+ var pixel = matrix[y][x] || {};
198
+ var value = pixel.value || 0;
152
199
  var idx = Math.round((value / 255) * maxIdx);
153
200
  var ch = pixels[idx] || " ";
154
201
  if (options.colored) {
155
- line += "\x1b[38;2;" + value + ";" + value + ";" + value + "m" + ch + "\x1b[0m";
202
+ var r = pixel.r == null ? value : pixel.r;
203
+ var g = pixel.g == null ? value : pixel.g;
204
+ var b = pixel.b == null ? value : pixel.b;
205
+ var mode = options.colorBackground ? "48" : "38";
206
+ line += "\x1b[" + mode + ";2;" + r + ";" + g + ";" + b + "m" + ch + "\x1b[0m";
156
207
  } else {
157
208
  line += ch;
158
209
  }
@@ -172,19 +223,19 @@ function renderFile(filePath, options, callback) {
172
223
  "-i",
173
224
  filePath,
174
225
  "-vf",
175
- buildFilter(width, height, options.preserveAspectRatio),
226
+ buildFilter(width, height, options.preserveAspectRatio, options.pxBackground),
176
227
  "-frames:v",
177
228
  "1",
178
229
  "-f",
179
230
  "rawvideo",
180
231
  "-pix_fmt",
181
- "gray",
232
+ "rgba",
182
233
  "-"
183
234
  ];
184
235
 
185
236
  childProcess.execFile("ffmpeg", args, {
186
237
  encoding: "buffer",
187
- maxBuffer: width * height + 4096,
238
+ maxBuffer: (width * height * 4) + 4096,
188
239
  timeout: options.timeoutMs
189
240
  }, function (err, stdout, stderr) {
190
241
  if (err) {
@@ -192,11 +243,11 @@ function renderFile(filePath, options, callback) {
192
243
  callback(new Error("image-to-ascii failed via ffmpeg: " + detail));
193
244
  return;
194
245
  }
195
- if (!stdout || stdout.length < width * height) {
246
+ if (!stdout || stdout.length < width * height * 4) {
196
247
  callback(new Error("image-to-ascii decoded too few pixels for " + width + "x" + height));
197
248
  return;
198
249
  }
199
- var matrix = matrixFromRaw(stdout, width, height);
250
+ var matrix = matrixFromRaw(stdout, width, height, options.pxBackground);
200
251
  if (!options.stringify) {
201
252
  callback(null, matrix);
202
253
  return;