@oxecli/oxe 1.0.78 → 1.0.79
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 +7 -5
- package/dist/tools.js +9 -4
- package/dist/ui.js +16 -10
- package/package.json +1 -1
package/dist/engine.js
CHANGED
|
@@ -577,8 +577,11 @@ export class InferenceEngine {
|
|
|
577
577
|
for (const c of calls) {
|
|
578
578
|
this.workActive = false;
|
|
579
579
|
const started = toolCallLabel(c.name, c.arguments);
|
|
580
|
+
// Print the tool label the instant the command starts, then show a
|
|
581
|
+
// "⎿ Working..." dots line that swaps to the real result in place.
|
|
582
|
+
process.stdout.write(`${started}\n`);
|
|
580
583
|
const toolSpinner = new Spinner();
|
|
581
|
-
toolSpinner.startDots("
|
|
584
|
+
toolSpinner.startDots("\x1b[90m⎿\x1b[0m Working");
|
|
582
585
|
const rawResult = await this.runTool(c.name, c.arguments);
|
|
583
586
|
if (this.interrupted) {
|
|
584
587
|
toolSpinner.stop();
|
|
@@ -592,10 +595,9 @@ export class InferenceEngine {
|
|
|
592
595
|
text: action,
|
|
593
596
|
status: failed ? "failed" : "ok",
|
|
594
597
|
});
|
|
595
|
-
//
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
process.stdout.write(`${action}\n\n`);
|
|
598
|
+
// Swap the "⎿ Working..." line for the real result, then a blank line.
|
|
599
|
+
toolSpinner.replaceWith(action);
|
|
600
|
+
process.stdout.write(`\n`);
|
|
599
601
|
// Any diff the tool produced is flushed only now, after the spinner
|
|
600
602
|
// has stopped, so the box renders cleanly below the action line.
|
|
601
603
|
flushPendingDiffOutput();
|
package/dist/tools.js
CHANGED
|
@@ -133,11 +133,16 @@ function displayDiff(pathName, oldContent, newContent) {
|
|
|
133
133
|
const num = v.kind === "+" ? v.newNum : v.oldNum;
|
|
134
134
|
const numStr = num ? String(num).padStart(numW, " ") : gap;
|
|
135
135
|
if (v.kind === "+" || v.kind === "-") {
|
|
136
|
-
const
|
|
137
|
-
const
|
|
138
|
-
const
|
|
136
|
+
const isAdd = v.kind === "+";
|
|
137
|
+
const bg = isAdd ? "\x1b[48;2;2;40;0m" : "\x1b[48;2;61;1;0m";
|
|
138
|
+
const fg = isAdd ? "\x1b[38;2;80;200;80m" : "\x1b[38;2;220;90;90m";
|
|
139
|
+
const sign = isAdd ? "+" : "-";
|
|
140
|
+
// Changed content renders normal white with syntax highlighting;
|
|
141
|
+
// re-apply the white base after each token reset.
|
|
142
|
+
const raw = highlightCodeLine(v.body);
|
|
143
|
+
const body = truncateStyled(raw.replace(/\x1b\[0m/g, "\x1b[0m\x1b[97m"), bodyMax);
|
|
139
144
|
const fill = Math.max(0, termW - numW - 4 - plainLen(body));
|
|
140
|
-
pendingDiffOutput.push(`${bg}
|
|
145
|
+
pendingDiffOutput.push(`${bg}${fg}${numStr} ${sign} \x1b[0m\x1b[97m${body}${" ".repeat(fill)}\x1b[0m`);
|
|
141
146
|
}
|
|
142
147
|
else {
|
|
143
148
|
const raw = v.kind === "\\" ? v.body : highlightCodeLine(v.body);
|
package/dist/ui.js
CHANGED
|
@@ -550,9 +550,10 @@ export class Spinner {
|
|
|
550
550
|
}, 80);
|
|
551
551
|
this.draw();
|
|
552
552
|
}
|
|
553
|
-
/** Dots-mode label: renders `
|
|
554
|
-
* Each tick rewrites ONLY the dots cells
|
|
555
|
-
* the line never flickers. Swap in the
|
|
553
|
+
/** Dots-mode label: renders `text` (ANSI pre-colored by the caller) + a
|
|
554
|
+
* fixed 3-cell animated dots field. Each tick rewrites ONLY the dots cells
|
|
555
|
+
* via a cursor jump, so the rest of the line never flickers. Swap in the
|
|
556
|
+
* final label with replaceWith(). */
|
|
556
557
|
startDots(text) {
|
|
557
558
|
if (!this.enabled)
|
|
558
559
|
return;
|
|
@@ -562,7 +563,7 @@ export class Spinner {
|
|
|
562
563
|
this.dotsFrame = 0;
|
|
563
564
|
this.rows = 1;
|
|
564
565
|
this.lastRendered = "";
|
|
565
|
-
this.lastLen = text
|
|
566
|
+
this.lastLen = plainLen(text) + 3;
|
|
566
567
|
this.writeDots(true);
|
|
567
568
|
this.timer = setInterval(() => {
|
|
568
569
|
this.dotsFrame = (this.dotsFrame + 1) % DOT_FRAMES.length;
|
|
@@ -570,18 +571,18 @@ export class Spinner {
|
|
|
570
571
|
}, 300);
|
|
571
572
|
}
|
|
572
573
|
writeDots(initial) {
|
|
573
|
-
const label = `\x1b[1;36m${this.dotsText}\x1b[0m`;
|
|
574
574
|
const dots = `\x1b[1;36m${DOT_FRAMES[this.dotsFrame]}\x1b[0m`;
|
|
575
575
|
if (initial) {
|
|
576
|
-
process.stdout.write("\r" +
|
|
576
|
+
process.stdout.write("\r" + this.dotsText + dots + "\r");
|
|
577
577
|
}
|
|
578
578
|
else {
|
|
579
579
|
// Jump to the dots column (1-based) and rewrite only the 3-cell field.
|
|
580
|
-
process.stdout.write(`\x1b[${this.dotsText
|
|
580
|
+
process.stdout.write(`\x1b[${plainLen(this.dotsText) + 1}G` + dots + "\r");
|
|
581
581
|
}
|
|
582
582
|
}
|
|
583
583
|
/** Overwrite the dots line in place with `text` and advance to the next
|
|
584
|
-
* line, without erasing (so there is no flash).
|
|
584
|
+
* line, without erasing (so there is no flash). Multi-line text replaces
|
|
585
|
+
* the first line in place and prints the remaining lines below it. */
|
|
585
586
|
replaceWith(text) {
|
|
586
587
|
if (this.timer) {
|
|
587
588
|
clearInterval(this.timer);
|
|
@@ -591,9 +592,14 @@ export class Spinner {
|
|
|
591
592
|
process.stdout.write(`${text}\n`);
|
|
592
593
|
return;
|
|
593
594
|
}
|
|
594
|
-
const
|
|
595
|
+
const parts = text.split("\n");
|
|
596
|
+
const first = parts[0];
|
|
597
|
+
const rest = parts.slice(1);
|
|
598
|
+
const plain = stripAnsi(first);
|
|
595
599
|
const pad = Math.max(0, this.lastLen - plain.length);
|
|
596
|
-
process.stdout.write("\r" +
|
|
600
|
+
process.stdout.write("\r" + first + " ".repeat(pad) + "\r\n");
|
|
601
|
+
if (rest.length)
|
|
602
|
+
process.stdout.write(rest.join("\n") + "\n");
|
|
597
603
|
this.rows = 0;
|
|
598
604
|
this.lastLen = plain.length;
|
|
599
605
|
}
|