@oxecli/oxe 1.0.110 → 1.0.112

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/engine.js CHANGED
@@ -585,12 +585,13 @@ export class InferenceEngine {
585
585
  for (const c of calls) {
586
586
  this.queryCalledTool = true;
587
587
  const started = toolCallLabel(c.name, c.arguments);
588
- // Print the tool label the instant the command starts, then show a
589
- // "╰─ Running..." dots line that swaps to the real result in place.
588
+ // Print the tool label the instant the tool starts, then show a
589
+ // "╰─ Working..." (file tools) or "╰─ Running..." (bash) dots line
590
+ // that streams while the tool runs and swaps to the real result.
590
591
  dockAppendContent(`${started}\n`);
591
592
  dockTransientStart("flush");
592
593
  const toolSpinner = new Spinner();
593
- toolSpinner.startDots("\x1b[90m╰─\x1b[0m Running");
594
+ toolSpinner.startDots(`\x1b[90m╰─\x1b[0m ${c.name === "bash" ? "Running" : "Working"}`);
594
595
  const rawResult = await this.runTool(c.name, c.arguments, this.activeAbort?.signal);
595
596
  // A tool call was made, which interrupts any current working phase,
596
597
  // so the next agent iteration may commit a fresh "Worked for …" block.
package/dist/tools.js CHANGED
@@ -31,6 +31,18 @@ function truncateDiffLine(line) {
31
31
  }
32
32
  return line;
33
33
  }
34
+ /**
35
+ * Truncate a styled line to at most `maxVisible` visible characters and, if
36
+ * truncation occurred, append a visible ellipsis "…". The diff viewer must
37
+ * NEVER wrap a line onto a new row (that breaks the +/- column alignment), so
38
+ * every row is hard-truncated here; the ellipsis makes the truncation obvious.
39
+ */
40
+ function truncateStyledEllipsis(text, maxVisible) {
41
+ if (plainLen(text) <= maxVisible)
42
+ return text;
43
+ const dot = maxVisible > 1 ? "…" : "";
44
+ return truncateStyled(text, Math.max(1, maxVisible - (dot ? 1 : 0))) + dot;
45
+ }
34
46
  /**
35
47
  * Recolor bracket syntax characters (`( ) [ ] { }`) inside an already-ANSI
36
48
  * rendered string to `fg`, restoring the row's white base after each bracket.
@@ -76,8 +88,9 @@ function displayDiff(pathName, oldContent, newContent) {
76
88
  // tool result text above it ("╰─ Wrote N chars").
77
89
  const ind = " ";
78
90
  if (oldContent.length + newContent.length > max_diff_source_chars) {
79
- pendingDiffOutput.push(`\x1b[90m${ind}${pathName}: ${oldContent.length.toLocaleString()} chars -> ${newContent.length.toLocaleString()} chars ` +
80
- `(diff hidden: exceeds ${max_diff_source_chars.toLocaleString()} char limit)\x1b[0m`);
91
+ const hiddenMsg = `${pathName}: ${oldContent.length.toLocaleString()} chars -> ${newContent.length.toLocaleString()} chars ` +
92
+ `(diff hidden: exceeds ${max_diff_source_chars.toLocaleString()} char limit)`;
93
+ pendingDiffOutput.push(`\x1b[90m${ind}${truncateStyledEllipsis(hiddenMsg, Math.max(terminalWidth() - 2, 1))}\x1b[0m`);
81
94
  return null;
82
95
  }
83
96
  const patch = structuredPatch(pathName, pathName, oldContent, newContent, "", "", { context: max_diff_context_lines });
@@ -164,7 +177,7 @@ function displayDiff(pathName, oldContent, newContent) {
164
177
  const gap = " ".repeat(numW);
165
178
  for (const v of visible) {
166
179
  if (v.kind === "~") {
167
- const body = truncateStyled(v.body, bodyMax);
180
+ const body = truncateStyledEllipsis(v.body, bodyMax);
168
181
  pendingDiffOutput.push(`\x1b[90m${ind}${gap} ${body}\x1b[0m`);
169
182
  continue;
170
183
  }
@@ -181,7 +194,7 @@ function displayDiff(pathName, oldContent, newContent) {
181
194
  // background + white base after each token reset so both hold across
182
195
  // the whole body.
183
196
  const raw = highlightCodeLine(v.body);
184
- const body = truncateStyled(raw.replace(/\x1b\[0m/g, `\x1b[0m${bg}\x1b[97m`), bodyMax);
197
+ const body = truncateStyledEllipsis(raw.replace(/\x1b\[0m/g, `\x1b[0m${bg}\x1b[97m`), bodyMax);
185
198
  // Deleted rows: recolor bracket syntax to the same red as the line
186
199
  // number (fg) so brackets match the row's deleted color. Added rows keep
187
200
  // their green highlighter as-is.
@@ -197,7 +210,7 @@ function displayDiff(pathName, oldContent, newContent) {
197
210
  // lines (only the number gutter stays dim). highlightCodeLine resets to
198
211
  // default after each token, so re-apply the base after every reset.
199
212
  const base = v.kind === "\\" ? "\x1b[90m" : "\x1b[97m";
200
- const body = truncateStyled(raw.replace(/\x1b\[0m/g, `\x1b[0m${base}`), bodyMax);
213
+ const body = truncateStyledEllipsis(raw.replace(/\x1b\[0m/g, `\x1b[0m${base}`), bodyMax);
201
214
  pendingDiffOutput.push(`\x1b[90m${ind}${numStr} \x1b[0m${base}${body}\x1b[0m`);
202
215
  }
203
216
  }
package/dist/ui.js CHANGED
@@ -173,6 +173,19 @@ export function truncateStyled(text, maxVisible) {
173
173
  }
174
174
  return out;
175
175
  }
176
+ /**
177
+ * Truncate styled text to at most `maxVisible` visible characters and, if
178
+ * truncated, append a visible ellipsis "…" so the cut is obvious. Used by the
179
+ * panel frame so long titles/subtitles shrink to the box instead of overflowing.
180
+ */
181
+ export function truncateStyledEllipsis(text, maxVisible) {
182
+ if (maxVisible <= 0)
183
+ return "";
184
+ if (plainLen(text) <= maxVisible)
185
+ return text;
186
+ const dot = maxVisible > 1 ? "…" : "";
187
+ return truncateStyled(text, Math.max(1, maxVisible - (dot ? 1 : 0))) + dot;
188
+ }
176
189
  /**
177
190
  * Wrap a styled (ANSI) string into lines of at most `width` visible characters,
178
191
  * wrapping whole words onto new lines and splitting any single word longer than
@@ -563,13 +576,17 @@ function panelString(content, title = "", subtitle = "", expand = true, borderSt
563
576
  const embed = (text, align) => {
564
577
  if (!text)
565
578
  return "─".repeat(Math.max(boxW - 2, 0));
566
- const inner = ` ${text} `;
579
+ // Truncate the title/subtitle so the frame always scales down to the box
580
+ // width (matching the prompt field): a long subtitle used to overflow the
581
+ // bottom border on narrow/scaled terminals. Ellipsis marks the cut.
582
+ const prefix = align === "left" ? "───" : "";
583
+ const avail = Math.max(boxW - 2 - plainLen(prefix), 0);
584
+ const inner = ` ${truncateStyledEllipsis(text, Math.max(avail - 2, 0))} `;
567
585
  if (align === "left") {
568
- const prefix = "───";
569
- const fill = Math.max(boxW - 2 - plainLen(prefix) - plainLen(inner), 0);
586
+ const fill = Math.max(avail - plainLen(inner), 0);
570
587
  return `${prefix}${inner}${"─".repeat(fill)}`;
571
588
  }
572
- const fill = Math.max(boxW - 2 - plainLen(inner), 0);
589
+ const fill = Math.max(avail - plainLen(inner), 0);
573
590
  const left = Math.floor(fill / 2);
574
591
  const right = fill - left;
575
592
  return `${"─".repeat(left)}${inner}${"─".repeat(right)}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxecli/oxe",
3
- "version": "1.0.110",
3
+ "version": "1.0.112",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },