nolo-cli 0.33.0-alpha.21 → 0.33.0-alpha.22

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.
@@ -7,7 +7,7 @@ import {
7
7
  prependSubjectDialogMarker,
8
8
  resolveWorkflowReference,
9
9
  runAgentRunCommand
10
- } from "./chunk-46JSKTPF.js";
10
+ } from "./chunk-AEYCNMJI.js";
11
11
  import {
12
12
  parseAgentRunArgs
13
13
  } from "./chunk-ZHYK3N56.js";
@@ -318,10 +318,241 @@ function dimCliText(text, enabled = resolveCliColorEnabled()) {
318
318
  return styleCliText(text, "dim", enabled);
319
319
  }
320
320
 
321
+ // node_modules/strip-ansi/node_modules/ansi-regex/index.js
322
+ function ansiRegex({ onlyFirst = false } = {}) {
323
+ const ST = "(?:\\u0007|\\u001B\\u005C|\\u009C)";
324
+ const osc = `(?:\\u001B\\][^\\u0007\\u001B\\u009C]*${ST})`;
325
+ const csi = "[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]";
326
+ const pattern = `${osc}|${csi}`;
327
+ return new RegExp(pattern, onlyFirst ? void 0 : "g");
328
+ }
329
+
330
+ // node_modules/strip-ansi/index.js
331
+ var regex = ansiRegex();
332
+ function stripAnsi(string) {
333
+ if (typeof string !== "string") {
334
+ throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``);
335
+ }
336
+ if (!string.includes("\x1B") && !string.includes("\x9B")) {
337
+ return string;
338
+ }
339
+ return string.replace(regex, "");
340
+ }
341
+
342
+ // node_modules/get-east-asian-width/lookup-data.js
343
+ var ambiguousMinimalCodePoint = 161;
344
+ var ambiguousMaximumCodePoint = 1114109;
345
+ var ambiguousRanges = [161, 161, 164, 164, 167, 168, 170, 170, 173, 174, 176, 180, 182, 186, 188, 191, 198, 198, 208, 208, 215, 216, 222, 225, 230, 230, 232, 234, 236, 237, 240, 240, 242, 243, 247, 250, 252, 252, 254, 254, 257, 257, 273, 273, 275, 275, 283, 283, 294, 295, 299, 299, 305, 307, 312, 312, 319, 322, 324, 324, 328, 331, 333, 333, 338, 339, 358, 359, 363, 363, 462, 462, 464, 464, 466, 466, 468, 468, 470, 470, 472, 472, 474, 474, 476, 476, 593, 593, 609, 609, 708, 708, 711, 711, 713, 715, 717, 717, 720, 720, 728, 731, 733, 733, 735, 735, 768, 879, 913, 929, 931, 937, 945, 961, 963, 969, 1025, 1025, 1040, 1103, 1105, 1105, 8208, 8208, 8211, 8214, 8216, 8217, 8220, 8221, 8224, 8226, 8228, 8231, 8240, 8240, 8242, 8243, 8245, 8245, 8251, 8251, 8254, 8254, 8308, 8308, 8319, 8319, 8321, 8324, 8364, 8364, 8451, 8451, 8453, 8453, 8457, 8457, 8467, 8467, 8470, 8470, 8481, 8482, 8486, 8486, 8491, 8491, 8531, 8532, 8539, 8542, 8544, 8555, 8560, 8569, 8585, 8585, 8592, 8601, 8632, 8633, 8658, 8658, 8660, 8660, 8679, 8679, 8704, 8704, 8706, 8707, 8711, 8712, 8715, 8715, 8719, 8719, 8721, 8721, 8725, 8725, 8730, 8730, 8733, 8736, 8739, 8739, 8741, 8741, 8743, 8748, 8750, 8750, 8756, 8759, 8764, 8765, 8776, 8776, 8780, 8780, 8786, 8786, 8800, 8801, 8804, 8807, 8810, 8811, 8814, 8815, 8834, 8835, 8838, 8839, 8853, 8853, 8857, 8857, 8869, 8869, 8895, 8895, 8978, 8978, 9312, 9449, 9451, 9547, 9552, 9587, 9600, 9615, 9618, 9621, 9632, 9633, 9635, 9641, 9650, 9651, 9654, 9655, 9660, 9661, 9664, 9665, 9670, 9672, 9675, 9675, 9678, 9681, 9698, 9701, 9711, 9711, 9733, 9734, 9737, 9737, 9742, 9743, 9756, 9756, 9758, 9758, 9792, 9792, 9794, 9794, 9824, 9825, 9827, 9829, 9831, 9834, 9836, 9837, 9839, 9839, 9886, 9887, 9919, 9919, 9926, 9933, 9935, 9939, 9941, 9953, 9955, 9955, 9960, 9961, 9963, 9969, 9972, 9972, 9974, 9977, 9979, 9980, 9982, 9983, 10045, 10045, 10102, 10111, 11094, 11097, 12872, 12879, 57344, 63743, 65024, 65039, 65533, 65533, 127232, 127242, 127248, 127277, 127280, 127337, 127344, 127373, 127375, 127376, 127387, 127404, 917760, 917999, 983040, 1048573, 1048576, 1114109];
346
+ var fullwidthMinimalCodePoint = 12288;
347
+ var fullwidthMaximumCodePoint = 65510;
348
+ var fullwidthRanges = [12288, 12288, 65281, 65376, 65504, 65510];
349
+ var wideMinimalCodePoint = 4352;
350
+ var wideMaximumCodePoint = 262141;
351
+ var wideRanges = [4352, 4447, 8986, 8987, 9001, 9002, 9193, 9196, 9200, 9200, 9203, 9203, 9725, 9726, 9748, 9749, 9776, 9783, 9800, 9811, 9855, 9855, 9866, 9871, 9875, 9875, 9889, 9889, 9898, 9899, 9917, 9918, 9924, 9925, 9934, 9934, 9940, 9940, 9962, 9962, 9970, 9971, 9973, 9973, 9978, 9978, 9981, 9981, 9989, 9989, 9994, 9995, 10024, 10024, 10060, 10060, 10062, 10062, 10067, 10069, 10071, 10071, 10133, 10135, 10160, 10160, 10175, 10175, 11035, 11036, 11088, 11088, 11093, 11093, 11904, 11929, 11931, 12019, 12032, 12245, 12272, 12287, 12289, 12350, 12353, 12438, 12441, 12543, 12549, 12591, 12593, 12686, 12688, 12773, 12783, 12830, 12832, 12871, 12880, 42124, 42128, 42182, 43360, 43388, 44032, 55203, 63744, 64255, 65040, 65049, 65072, 65106, 65108, 65126, 65128, 65131, 94176, 94180, 94192, 94198, 94208, 101589, 101631, 101662, 101760, 101874, 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882, 110898, 110898, 110928, 110930, 110933, 110933, 110948, 110951, 110960, 111355, 119552, 119638, 119648, 119670, 126980, 126980, 127183, 127183, 127374, 127374, 127377, 127386, 127488, 127490, 127504, 127547, 127552, 127560, 127568, 127569, 127584, 127589, 127744, 127776, 127789, 127797, 127799, 127868, 127870, 127891, 127904, 127946, 127951, 127955, 127968, 127984, 127988, 127988, 127992, 128062, 128064, 128064, 128066, 128252, 128255, 128317, 128331, 128334, 128336, 128359, 128378, 128378, 128405, 128406, 128420, 128420, 128507, 128591, 128640, 128709, 128716, 128716, 128720, 128722, 128725, 128728, 128732, 128735, 128747, 128748, 128756, 128764, 128992, 129003, 129008, 129008, 129292, 129338, 129340, 129349, 129351, 129535, 129648, 129660, 129664, 129674, 129678, 129734, 129736, 129736, 129741, 129756, 129759, 129770, 129775, 129784, 131072, 196605, 196608, 262141];
352
+
353
+ // node_modules/get-east-asian-width/utilities.js
354
+ var isInRange = (ranges, codePoint) => {
355
+ let low = 0;
356
+ let high = Math.floor(ranges.length / 2) - 1;
357
+ while (low <= high) {
358
+ const mid = Math.floor((low + high) / 2);
359
+ const i = mid * 2;
360
+ if (codePoint < ranges[i]) {
361
+ high = mid - 1;
362
+ } else if (codePoint > ranges[i + 1]) {
363
+ low = mid + 1;
364
+ } else {
365
+ return true;
366
+ }
367
+ }
368
+ return false;
369
+ };
370
+
371
+ // node_modules/get-east-asian-width/lookup.js
372
+ var commonCjkCodePoint = 19968;
373
+ var [wideFastPathStart, wideFastPathEnd] = /* @__PURE__ */ findWideFastPathRange(wideRanges);
374
+ function findWideFastPathRange(ranges) {
375
+ let fastPathStart = ranges[0];
376
+ let fastPathEnd = ranges[1];
377
+ for (let index = 0; index < ranges.length; index += 2) {
378
+ const start = ranges[index];
379
+ const end = ranges[index + 1];
380
+ if (commonCjkCodePoint >= start && commonCjkCodePoint <= end) {
381
+ return [start, end];
382
+ }
383
+ if (end - start > fastPathEnd - fastPathStart) {
384
+ fastPathStart = start;
385
+ fastPathEnd = end;
386
+ }
387
+ }
388
+ return [fastPathStart, fastPathEnd];
389
+ }
390
+ var isAmbiguous = (codePoint) => {
391
+ if (codePoint < ambiguousMinimalCodePoint || codePoint > ambiguousMaximumCodePoint) {
392
+ return false;
393
+ }
394
+ return isInRange(ambiguousRanges, codePoint);
395
+ };
396
+ var isFullWidth = (codePoint) => {
397
+ if (codePoint < fullwidthMinimalCodePoint || codePoint > fullwidthMaximumCodePoint) {
398
+ return false;
399
+ }
400
+ return isInRange(fullwidthRanges, codePoint);
401
+ };
402
+ var isWide = (codePoint) => {
403
+ if (codePoint >= wideFastPathStart && codePoint <= wideFastPathEnd) {
404
+ return true;
405
+ }
406
+ if (codePoint < wideMinimalCodePoint || codePoint > wideMaximumCodePoint) {
407
+ return false;
408
+ }
409
+ return isInRange(wideRanges, codePoint);
410
+ };
411
+
412
+ // node_modules/get-east-asian-width/index.js
413
+ function validate(codePoint) {
414
+ if (!Number.isSafeInteger(codePoint)) {
415
+ throw new TypeError(`Expected a code point, got \`${typeof codePoint}\`.`);
416
+ }
417
+ }
418
+ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
419
+ validate(codePoint);
420
+ if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) {
421
+ return 2;
422
+ }
423
+ return 1;
424
+ }
425
+
426
+ // node_modules/string-width/index.js
427
+ var segmenter = new Intl.Segmenter();
428
+ var zeroWidthClusterRegex = new RegExp("^(?:\\p{Default_Ignorable_Code_Point}|\\p{Control}|\\p{Format}|\\p{Nonspacing_Mark}|\\p{Enclosing_Mark}|\\p{Surrogate})+$", "v");
429
+ var leadingNonPrintingRegex = new RegExp("^[\\p{Default_Ignorable_Code_Point}\\p{Control}\\p{Format}\\p{Nonspacing_Mark}\\p{Enclosing_Mark}\\p{Surrogate}]+", "v");
430
+ var spacingMarkRegex = new RegExp("\\p{Spacing_Mark}", "v");
431
+ var rgiEmojiRegex = new RegExp("^\\p{RGI_Emoji}$", "v");
432
+ var unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
433
+ var extendedPictographicRegex = new RegExp("\\p{Extended_Pictographic}", "gu");
434
+ function isDoubleWidthNonRgiEmojiSequence(segment) {
435
+ if (segment.length > 50) {
436
+ return false;
437
+ }
438
+ if (unqualifiedKeycapRegex.test(segment)) {
439
+ return true;
440
+ }
441
+ if (segment.includes("\u200D")) {
442
+ const pictographics = segment.match(extendedPictographicRegex);
443
+ return pictographics !== null && pictographics.length >= 2;
444
+ }
445
+ return false;
446
+ }
447
+ function baseVisible(segment) {
448
+ return segment.replace(leadingNonPrintingRegex, "");
449
+ }
450
+ function isZeroWidthCluster(segment) {
451
+ return zeroWidthClusterRegex.test(segment);
452
+ }
453
+ function isHangulLeadingJamo(codePoint) {
454
+ return codePoint >= 4352 && codePoint <= 4447 || codePoint >= 43360 && codePoint <= 43388;
455
+ }
456
+ function isHangulVowelJamo(codePoint) {
457
+ return codePoint >= 4448 && codePoint <= 4519 || codePoint >= 55216 && codePoint <= 55238;
458
+ }
459
+ function isHangulTrailingJamo(codePoint) {
460
+ return codePoint >= 4520 && codePoint <= 4607 || codePoint >= 55243 && codePoint <= 55291;
461
+ }
462
+ function isHangulJamo(codePoint) {
463
+ return isHangulLeadingJamo(codePoint) || isHangulVowelJamo(codePoint) || isHangulTrailingJamo(codePoint);
464
+ }
465
+ function hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {
466
+ const codePoints = [];
467
+ for (const character of visibleSegment) {
468
+ if (zeroWidthClusterRegex.test(character)) {
469
+ continue;
470
+ }
471
+ codePoints.push(character.codePointAt(0));
472
+ }
473
+ if (codePoints.length === 0) {
474
+ return void 0;
475
+ }
476
+ let width = 0;
477
+ for (let index = 0; index < codePoints.length; index++) {
478
+ const codePoint = codePoints[index];
479
+ if (!isHangulJamo(codePoint)) {
480
+ if (width === 0) {
481
+ return void 0;
482
+ }
483
+ for (let remaining = index; remaining < codePoints.length; remaining++) {
484
+ width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
485
+ }
486
+ return width;
487
+ }
488
+ if (isHangulLeadingJamo(codePoint) && isHangulVowelJamo(codePoints[index + 1])) {
489
+ width += 2;
490
+ index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
491
+ continue;
492
+ }
493
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
494
+ }
495
+ return width;
496
+ }
497
+ function trailingWidth(visibleSegment, eastAsianWidthOptions) {
498
+ let extra = 0;
499
+ let first = true;
500
+ for (const character of visibleSegment) {
501
+ if (first) {
502
+ first = false;
503
+ continue;
504
+ }
505
+ if (spacingMarkRegex.test(character) || character >= "\uFF00" && character <= "\uFFEF") {
506
+ extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
507
+ }
508
+ }
509
+ return extra;
510
+ }
511
+ function stringWidth(input, options = {}) {
512
+ if (typeof input !== "string" || input.length === 0) {
513
+ return 0;
514
+ }
515
+ const {
516
+ ambiguousIsNarrow = true,
517
+ countAnsiEscapeCodes = false
518
+ } = options;
519
+ let string = input;
520
+ if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("\x9B"))) {
521
+ string = stripAnsi(string);
522
+ }
523
+ if (string.length === 0) {
524
+ return 0;
525
+ }
526
+ if (/^[\u0020-\u007E]*$/.test(string)) {
527
+ return string.length;
528
+ }
529
+ let width = 0;
530
+ const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
531
+ for (const { segment } of segmenter.segment(string)) {
532
+ if (isZeroWidthCluster(segment)) {
533
+ continue;
534
+ }
535
+ if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
536
+ width += 2;
537
+ continue;
538
+ }
539
+ const visibleSegment = baseVisible(segment);
540
+ const hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);
541
+ if (hangulWidth !== void 0) {
542
+ width += hangulWidth;
543
+ continue;
544
+ }
545
+ const codePoint = visibleSegment.codePointAt(0);
546
+ width += eastAsianWidth(codePoint, eastAsianWidthOptions);
547
+ width += trailingWidth(visibleSegment, eastAsianWidthOptions);
548
+ }
549
+ return width;
550
+ }
551
+
321
552
  // packages/cli/tui/tuiAnsi.ts
322
553
  var ANSI_ESCAPE_REGEX = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]/g;
323
554
  var OSC_HYPERLINK_REGEX = /\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)\x1b\]8;;(?:\x07|\x1b\\)|\x1b\]8;;[^\x07\x1b]*(?:\x07|\x1b\\)/g;
324
- function stripAnsi(text) {
555
+ function stripAnsi2(text) {
325
556
  return text.replace(OSC_HYPERLINK_REGEX, "").replace(ANSI_ESCAPE_REGEX, "");
326
557
  }
327
558
  var SGR_SEQUENCE_REGEX = /^\x1b\[[0-9;]*m/;
@@ -384,32 +615,19 @@ function applyTerminalOutputToText(existing, chunk) {
384
615
  return text;
385
616
  }
386
617
  function displayWidth(str) {
387
- let width = 0;
388
- for (const char of str) {
389
- const code = char.codePointAt(0) ?? 0;
390
- if (code < 32 || code === 127) continue;
391
- if (code >= 768 && code <= 879 || code >= 6832 && code <= 6911 || code >= 7616 && code <= 7679 || code >= 8203 && code <= 8207 || code >= 8234 && code <= 8238 || code >= 8288 && code <= 8303 || code >= 8400 && code <= 8447 || code >= 65024 && code <= 65039 || code >= 65056 && code <= 65071 || code >= 917760 && code <= 917999) {
392
- continue;
393
- }
394
- if (code >= 4352 && code <= 4447 || // 0x2768-0x2775 (ornamental brackets, incl. the ❯ prompt at U+276F)
395
- // render narrow in terminals; counting them wide drifts the cursor.
396
- code >= 9728 && code <= 10175 && !(code >= 10088 && code <= 10101) || // 0x2B00-0x2BFF (Misc Symbols and Arrows, incl. ⬢ U+2B22 used as the
397
- // status-line agent icon) render double-wide in common monospace fonts;
398
- // counting ⬢ as width 1 drifts the whole status line right of the icon.
399
- code >= 11008 && code <= 11263 || code >= 11904 && code <= 12350 || code >= 12352 && code <= 13247 || code >= 13312 && code <= 19903 || code >= 19968 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65072 && code <= 65135 || code >= 65281 && code <= 65376 || code >= 65504 && code <= 65510 || code >= 127744 && code <= 129791 || code >= 131072 && code <= 196605 || code >= 196608 && code <= 262141 || // East Asian Ambiguous CJK quotation marks (U+201C/D “ ”, U+2018/9 ‘ ’).
400
- // In CJK locale + CJK fonts these render double-wide like 全角 punctuation;
401
- // in English fonts they stay width 1. Follow the active locale so Chinese
402
- // replies align correctly without breaking English terminal output.
403
- getCliLocale() === "zh" && (code === 8220 || code === 8221 || code === 8216 || code === 8217)) {
404
- width += 2;
405
- } else {
406
- width += 1;
407
- }
618
+ const plain = stripAnsi2(str);
619
+ let width = stringWidth(plain);
620
+ for (const { segment } of graphemeSegmenter.segment(plain)) {
621
+ if (stringWidth(segment) !== 1) continue;
622
+ const code = segment.codePointAt(0) ?? 0;
623
+ const forceWideSymbol = code >= 9728 && code <= 10175 && !(code >= 10088 && code <= 10101) || code >= 11008 && code <= 11263 || code >= 127744 && code <= 129791;
624
+ const cjkQuote = getCliLocale() === "zh" && (code === 8220 || code === 8221 || code === 8216 || code === 8217);
625
+ if (forceWideSymbol || cjkQuote) width += 1;
408
626
  }
409
627
  return width;
410
628
  }
411
629
  function visibleWidth(str) {
412
- return displayWidth(stripAnsi(str));
630
+ return displayWidth(stripAnsi2(str));
413
631
  }
414
632
  function truncateAnsi(text, maxWidth) {
415
633
  if (maxWidth <= 0) return "";
@@ -685,9 +903,11 @@ function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSou
685
903
  }
686
904
  }
687
905
  start = segmentEnd;
906
+ let softWrapJoiner = "";
688
907
  while (start < tokens.length) {
689
908
  const token = tokens[start];
690
909
  if (token.kind === "char" && token.value === " " && token.charIndex >= prefixCharCount) {
910
+ softWrapJoiner += token.value;
691
911
  const mappedOffset = sourceMapping && sourceMapping[plainCharIndex] !== void 0 ? sourceMapping[plainCharIndex] + 1 : plainCharIndex + 1;
692
912
  segSourceEnd = lineSourceStart + mappedOffset;
693
913
  plainCharIndex += token.value.length;
@@ -704,7 +924,9 @@ function wrapTranscriptLineWithLayout(line, columns, hangingIndent = "", lineSou
704
924
  sourceStart: segSourceStart,
705
925
  sourceEnd: segSourceEnd,
706
926
  prefixWidth: currentPrefixWidth,
707
- sourceMapping: rowMapping.length > 0 ? rowMapping : void 0
927
+ sourceMapping: rowMapping.length > 0 ? rowMapping : void 0,
928
+ softWrapped: start < tokens.length,
929
+ softWrapJoiner
708
930
  });
709
931
  }
710
932
  return rows.length > 0 ? rows : [
@@ -720,7 +942,7 @@ function wrapTranscriptLine(line, columns, hangingIndent = "") {
720
942
  return wrapTranscriptLineWithLayout(line, columns, hangingIndent).map((r) => r.rendered);
721
943
  }
722
944
  function buildWindowTitle(title) {
723
- const plain = stripAnsi(title).replace(/[\x00-\x1f\x7f]+/g, " ");
945
+ const plain = stripAnsi2(title).replace(/[\x00-\x1f\x7f]+/g, " ");
724
946
  let truncated = "";
725
947
  let width = 0;
726
948
  const maxCols = 80;
@@ -5511,7 +5733,7 @@ export {
5511
5733
  resolveCliColorEnabled,
5512
5734
  dimCliText,
5513
5735
  ANSI_ESCAPE_REGEX,
5514
- stripAnsi,
5736
+ stripAnsi2 as stripAnsi,
5515
5737
  applyTerminalOutputToText,
5516
5738
  displayWidth,
5517
5739
  visibleWidth,
package/index.js CHANGED
@@ -126,7 +126,7 @@ function createDaemonShortcutCommand(path, description, command2) {
126
126
  // packages/cli/agentInternalCommandEntries.ts
127
127
  function getAgentInternalCommandEntries() {
128
128
  const createAgentRunCommand = (path, description) => createContextCommand(path, description, async (args2, ctx) => {
129
- const { runAgentRunCommand } = await import("./agentRunCommand-OJX27NII.js");
129
+ const { runAgentRunCommand } = await import("./agentRunCommand-LEBZ6PNB.js");
130
130
  return runAgentRunCommand(args2, {
131
131
  env: ctx.env,
132
132
  scriptDir: ctx.scriptDir,
@@ -796,7 +796,7 @@ async function runScript(script, forwardedArgs, env) {
796
796
  return proc.exited;
797
797
  }
798
798
  async function launchTuiWorkspace(args2) {
799
- const { startTuiWorkspace } = await import("./readlineWorkspace-J2ARMEUC.js");
799
+ const { startTuiWorkspace } = await import("./readlineWorkspace-R6QZRAIA.js");
800
800
  const { createTuiSummaryLlmCaller } = await import("./tuiSummaryLlmCaller-WUVAOIYU.js");
801
801
  return startTuiWorkspace({
802
802
  ...args2,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nolo-cli",
3
- "version": "0.33.0-alpha.21",
3
+ "version": "0.33.0-alpha.22",
4
4
  "type": "module",
5
5
  "description": "Agent-first terminal workspace for Nolo",
6
6
  "bin": {
@@ -73,7 +73,7 @@ import {
73
73
  wrapTextToLines,
74
74
  wrapTranscriptLine,
75
75
  wrapTranscriptLineWithLayout
76
- } from "./chunk-46JSKTPF.js";
76
+ } from "./chunk-AEYCNMJI.js";
77
77
  import "./chunk-ZHYK3N56.js";
78
78
  import {
79
79
  getReadableCliDb
@@ -1767,22 +1767,15 @@ function areSelectionPointsEqual(a, b) {
1767
1767
  if (a === null || b === null) return false;
1768
1768
  return a.globalRow === b.globalRow && a.col === b.col;
1769
1769
  }
1770
- function highlightLineByColumns(line, selStartCol, selEndCol) {
1771
- if (selStartCol >= selEndCol) return line;
1770
+ function highlightLineByColumns(line, selStartCol, selEndCol, prefixWidth = 0) {
1772
1771
  const tokens = tokenizeAnsiLine(line);
1773
- if (tokens.length === 0) return line;
1774
- let lastNonSpaceCol = 0;
1775
- let colScan = 0;
1776
- for (const tok of tokens) {
1777
- if (tok.kind === "char") {
1778
- if (tok.value.trim().length > 0) {
1779
- lastNonSpaceCol = colScan + tok.width;
1780
- }
1781
- colScan += tok.width;
1782
- }
1783
- }
1784
- const effectiveEndCol = Math.min(selEndCol, lastNonSpaceCol);
1785
- if (selStartCol >= effectiveEndCol) return line;
1772
+ const range = resolveSelectableColumnRange(
1773
+ tokens,
1774
+ selStartCol,
1775
+ selEndCol,
1776
+ prefixWidth
1777
+ );
1778
+ if (!range) return line;
1786
1779
  let out = "";
1787
1780
  let currentCol = 0;
1788
1781
  let isHighlightActive = false;
@@ -1802,7 +1795,7 @@ function highlightLineByColumns(line, selStartCol, selEndCol) {
1802
1795
  }
1803
1796
  const charStartCol = currentCol;
1804
1797
  const charEndCol = currentCol + token.width;
1805
- const isSelected = charStartCol >= selStartCol && charStartCol < effectiveEndCol;
1798
+ const isSelected = charStartCol >= range.start && charStartCol < range.end;
1806
1799
  if (isSelected && !isHighlightActive) {
1807
1800
  out += "\x1B[7m";
1808
1801
  isHighlightActive = true;
@@ -1818,56 +1811,71 @@ function highlightLineByColumns(line, selStartCol, selEndCol) {
1818
1811
  }
1819
1812
  return out;
1820
1813
  }
1814
+ function resolveSelectableColumnRange(tokens, requestedStart, requestedEnd, prefixWidth) {
1815
+ if (requestedStart >= requestedEnd) return null;
1816
+ let col = 0;
1817
+ let lastNonSpaceCol = 0;
1818
+ for (const token of tokens) {
1819
+ if (token.kind !== "char") continue;
1820
+ if (token.value.trim().length > 0) {
1821
+ lastNonSpaceCol = col + token.width;
1822
+ }
1823
+ col += token.width;
1824
+ }
1825
+ const start = Math.max(prefixWidth, requestedStart);
1826
+ const end = Math.min(requestedEnd, lastNonSpaceCol);
1827
+ if (start >= end) return null;
1828
+ let snappedStart = null;
1829
+ let snappedEnd = null;
1830
+ col = 0;
1831
+ for (const token of tokens) {
1832
+ if (token.kind !== "char") continue;
1833
+ const tokenStart = col;
1834
+ const tokenEnd = col + token.width;
1835
+ if (tokenEnd > start && tokenStart < end) {
1836
+ snappedStart ??= tokenStart;
1837
+ snappedEnd = tokenEnd;
1838
+ }
1839
+ col = tokenEnd;
1840
+ }
1841
+ return snappedStart === null || snappedEnd === null ? null : { start: snappedStart, end: snappedEnd };
1842
+ }
1821
1843
  function hitTestHistory(history, screenRow, screenCol, _contentWidth, scrollTop) {
1822
1844
  const globalRow = Math.max(0, scrollTop + screenRow);
1823
1845
  const col = Math.max(0, screenCol);
1824
1846
  return { globalRow, col };
1825
1847
  }
1826
- function extractTextSliceByColumns(plain, startCol, endCol) {
1827
- let text = plain;
1828
- let textStartCol = 0;
1829
- if (text.startsWith("\u25C8 ")) {
1830
- text = text.slice(2);
1831
- textStartCol = 2;
1832
- } else if (text.startsWith("\u2503 ")) {
1833
- text = text.slice(3);
1834
- textStartCol = 3;
1835
- } else if (text.startsWith("\u203A ")) {
1836
- text = text.slice(2);
1837
- textStartCol = 2;
1838
- }
1839
- const effectiveStart = Math.max(0, startCol - textStartCol);
1840
- const effectiveEnd = Math.max(0, endCol - textStartCol);
1841
- if (effectiveStart >= effectiveEnd) return "";
1842
- let out = "";
1848
+ function extractTextSliceByColumns(line, startCol, endCol, prefixWidth = 0) {
1849
+ const tokens = tokenizeAnsiLine(line);
1850
+ const range = resolveSelectableColumnRange(
1851
+ tokens,
1852
+ startCol,
1853
+ endCol,
1854
+ prefixWidth
1855
+ );
1856
+ if (!range) return "";
1843
1857
  let col = 0;
1844
- for (const char of text) {
1845
- const w = displayWidth(char);
1846
- if (col + w > effectiveStart && col < effectiveEnd) {
1847
- out += char;
1858
+ let text = "";
1859
+ for (const token of tokens) {
1860
+ if (token.kind !== "char") continue;
1861
+ if (col >= range.start && col < range.end) {
1862
+ text += token.value;
1848
1863
  }
1849
- col += w;
1864
+ col += token.width;
1850
1865
  }
1851
- return out;
1866
+ return text;
1852
1867
  }
1853
- function extractSelectedText(history, anchor, head, contentWidth = 80) {
1868
+ function extractSelectedText(history, anchor, head, contentWidth) {
1854
1869
  if (!anchor || !head) return "";
1855
1870
  const cmp = compareSelectionPoints(anchor, head);
1856
1871
  if (cmp === 0) return "";
1857
1872
  const start = cmp < 0 ? anchor : head;
1858
1873
  const end = cmp < 0 ? head : anchor;
1859
- const lines = buildHistoryLines(history, contentWidth);
1860
- const selectedLines = [];
1874
+ const rows = buildHistoryLayoutRows(history, contentWidth);
1875
+ const pieces = [];
1861
1876
  for (let r = start.globalRow; r <= end.globalRow; r++) {
1862
- const rawLine = lines[r];
1863
- if (rawLine === void 0) continue;
1864
- const plain = stripAnsi(rawLine);
1865
- if (plain.trim().length === 0) {
1866
- if (selectedLines.length > 0 && selectedLines[selectedLines.length - 1] !== "") {
1867
- selectedLines.push("");
1868
- }
1869
- continue;
1870
- }
1877
+ const row = rows[r];
1878
+ if (!row) continue;
1871
1879
  let lineStartCol = 0;
1872
1880
  let lineEndCol = Infinity;
1873
1881
  if (r === start.globalRow) {
@@ -1876,14 +1884,21 @@ function extractSelectedText(history, anchor, head, contentWidth = 80) {
1876
1884
  if (r === end.globalRow) {
1877
1885
  lineEndCol = end.col;
1878
1886
  }
1879
- const extracted = extractTextSliceByColumns(plain, lineStartCol, lineEndCol);
1880
- if (extracted.length > 0) {
1881
- selectedLines.push(extracted);
1887
+ pieces.push(
1888
+ extractTextSliceByColumns(
1889
+ row.rendered,
1890
+ lineStartCol,
1891
+ lineEndCol,
1892
+ row.prefixWidth
1893
+ )
1894
+ );
1895
+ if (r < end.globalRow) {
1896
+ pieces.push(row.softWrapped ? row.softWrapJoiner ?? "" : "\n");
1882
1897
  }
1883
1898
  }
1884
- return selectedLines.join("\n");
1899
+ return pieces.join("");
1885
1900
  }
1886
- function applySelectionOverlay(visibleLines, _history, _contentWidth, scrollTop, selection) {
1901
+ function applySelectionOverlay(visibleLines, history, contentWidth, scrollTop, selection) {
1887
1902
  if (!selection.anchor || !selection.head) {
1888
1903
  return visibleLines;
1889
1904
  }
@@ -1891,6 +1906,7 @@ function applySelectionOverlay(visibleLines, _history, _contentWidth, scrollTop,
1891
1906
  if (cmp === 0) return visibleLines;
1892
1907
  const start = cmp < 0 ? selection.anchor : selection.head;
1893
1908
  const end = cmp < 0 ? selection.head : selection.anchor;
1909
+ const layoutRows = buildHistoryLayoutRows(history, contentWidth);
1894
1910
  const result = [...visibleLines];
1895
1911
  for (let screenRow = 0; screenRow < visibleLines.length; screenRow++) {
1896
1912
  const globalRow = scrollTop + screenRow;
@@ -1899,6 +1915,7 @@ function applySelectionOverlay(visibleLines, _history, _contentWidth, scrollTop,
1899
1915
  }
1900
1916
  const currentLine = result[screenRow] ?? "";
1901
1917
  if (currentLine.length === 0) continue;
1918
+ const layoutRow = layoutRows[globalRow];
1902
1919
  let selStartCol = 0;
1903
1920
  let selEndCol = Infinity;
1904
1921
  if (globalRow === start.globalRow) {
@@ -1910,7 +1927,8 @@ function applySelectionOverlay(visibleLines, _history, _contentWidth, scrollTop,
1910
1927
  result[screenRow] = highlightLineByColumns(
1911
1928
  currentLine,
1912
1929
  selStartCol,
1913
- selEndCol
1930
+ selEndCol,
1931
+ layoutRow?.prefixWidth ?? 0
1914
1932
  );
1915
1933
  }
1916
1934
  return result;
@@ -2031,7 +2049,9 @@ function layoutTurnRows(role, content, contentWidth, colorEnabled, command) {
2031
2049
  sourceStart: r.sourceStart,
2032
2050
  sourceEnd: r.sourceEnd,
2033
2051
  prefixWidth: r.prefixWidth,
2034
- sourceMapping: r.sourceMapping
2052
+ sourceMapping: r.sourceMapping,
2053
+ softWrapped: r.softWrapped,
2054
+ softWrapJoiner: r.softWrapJoiner
2035
2055
  });
2036
2056
  }
2037
2057
  lineSourceStart += line.length + 1;
@@ -2059,7 +2079,9 @@ function layoutTurnRows(role, content, contentWidth, colorEnabled, command) {
2059
2079
  sourceStart: 0,
2060
2080
  sourceEnd: 0,
2061
2081
  prefixWidth: 2,
2062
- sourceMapping: void 0
2082
+ sourceMapping: void 0,
2083
+ softWrapped: r.softWrapped,
2084
+ softWrapJoiner: r.softWrapJoiner
2063
2085
  });
2064
2086
  }
2065
2087
  }
@@ -2329,35 +2351,39 @@ function buildCopyViewLines(history) {
2329
2351
  }
2330
2352
  return lines;
2331
2353
  }
2332
- function buildHistoryLines(history, contentWidth) {
2354
+ function buildHistoryLayoutRows(history, contentWidth) {
2333
2355
  const colorEnabled = resolveCliColorEnabled();
2334
2356
  const density = getActiveDensity();
2335
2357
  const surface = colorEnabled ? userSurfaceBackgroundSequence() : "";
2336
- const wrapped = [];
2358
+ const rows = [];
2359
+ const separatorRow = () => ({
2360
+ rendered: "",
2361
+ sourceStart: 0,
2362
+ sourceEnd: 0,
2363
+ prefixWidth: 0
2364
+ });
2337
2365
  for (let i = 0; i < history.turns.length; i++) {
2338
2366
  const turn = history.turns[i];
2339
2367
  if (density === "spacious" && (i > 0 || turn.role === "user")) {
2340
- wrapped.push("");
2368
+ rows.push(separatorRow());
2341
2369
  }
2342
- const layoutRows = getTurnLayoutRows(turn, contentWidth, colorEnabled, density, surface);
2343
- wrapped.push(...layoutRows.map((r) => r.rendered));
2370
+ rows.push(...getTurnLayoutRows(turn, contentWidth, colorEnabled, density, surface));
2344
2371
  }
2345
2372
  if (history.currentRole !== null && history.currentContent) {
2346
2373
  const i = history.turns.length;
2347
2374
  if (density === "spacious" && (i > 0 || history.currentRole === "user")) {
2348
- wrapped.push("");
2375
+ rows.push(separatorRow());
2349
2376
  }
2350
- const streamingLines = getStreamingTurnLines(
2351
- history.currentRole,
2352
- history.currentContent,
2353
- contentWidth,
2354
- colorEnabled,
2355
- density,
2356
- surface
2377
+ rows.push(
2378
+ ...layoutTurnRows(
2379
+ history.currentRole,
2380
+ history.currentContent,
2381
+ contentWidth,
2382
+ colorEnabled
2383
+ )
2357
2384
  );
2358
- wrapped.push(...streamingLines);
2359
2385
  }
2360
- return wrapped;
2386
+ return rows;
2361
2387
  }
2362
2388
  var renderCacheMissCount = 0;
2363
2389
  function renderHistory(output, history, inputLines, selection) {
@@ -6392,6 +6418,10 @@ async function startTuiWorkspace(options) {
6392
6418
  const output = options.output ?? defaultOutput;
6393
6419
  const fetchImpl = options.fetchImpl ?? fetch;
6394
6420
  const spawnRunner = options.spawnRunner ?? spawnProcess;
6421
+ const writeClipboard = options.clipboardWriter ?? (async (text) => {
6422
+ const { default: clipboard } = await import("./clipboardy-MMBYVRLF.js");
6423
+ await clipboard.write(text);
6424
+ });
6395
6425
  const selfUpdater = options.selfUpdater ?? ((target) => runSelfUpdate({ output: target }));
6396
6426
  if (output.isTTY) {
6397
6427
  enterAltScreen(output);
@@ -7128,8 +7158,7 @@ async function startTuiWorkspace(options) {
7128
7158
  emitCommandOutput(t("copyNothing"));
7129
7159
  } else {
7130
7160
  try {
7131
- const { default: clipboard } = await import("./clipboardy-MMBYVRLF.js");
7132
- await clipboard.write(text);
7161
+ await writeClipboard(text);
7133
7162
  emitCommandOutput(t("copiedLastReply"));
7134
7163
  } catch (error) {
7135
7164
  const message = toErrorMessage(error);
@@ -7642,10 +7671,14 @@ ${merged}` : merged;
7642
7671
  const textToCopy = extractSelectedText(
7643
7672
  history,
7644
7673
  selectionState.anchor,
7645
- selectionState.head
7674
+ selectionState.head,
7675
+ contentWidth
7646
7676
  );
7647
7677
  if (textToCopy.length > 0) {
7648
- import("./clipboardy-MMBYVRLF.js").then(({ default: clipboard }) => clipboard.write(textToCopy)).catch(() => {
7678
+ writeClipboard(textToCopy).catch((error) => {
7679
+ emitCommandOutput(
7680
+ `[nolo] ${t("copyFailed")}: ${toErrorMessage(error)}`
7681
+ );
7649
7682
  });
7650
7683
  }
7651
7684
  selectionState.dragging = false;