@oxecli/oxe 1.0.12 → 1.0.13
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/cli.js +7 -1
- package/dist/engine.js +1 -2
- package/dist/oxe.js +10 -0
- package/dist/ui.js +40 -15
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -46,7 +46,13 @@ export class CLI {
|
|
|
46
46
|
showHelp() {
|
|
47
47
|
process.stdout.write("\n");
|
|
48
48
|
for (const [cmd, desc] of COMMAND_HELP) {
|
|
49
|
-
|
|
49
|
+
// The whole command column is bold; any `<arg>` placeholder (e.g. <n>,
|
|
50
|
+
// <level>) is additionally cyan — matching the original's
|
|
51
|
+
// `[bold cyan]<n>[/bold cyan]`. Pad based on the plain text length so the
|
|
52
|
+
// ANSI codes don't skew the column alignment.
|
|
53
|
+
const styled = cmd.replace(/(<[^>]+>)/g, "\x1b[36m$1\x1b[0m");
|
|
54
|
+
const pad = Math.max(18 - cmd.length, 0);
|
|
55
|
+
process.stdout.write(`\x1b[1m${styled}${" ".repeat(pad)}\x1b[0m\x1b[2m${desc}\x1b[0m\n`);
|
|
50
56
|
}
|
|
51
57
|
process.stdout.write("\n");
|
|
52
58
|
}
|
package/dist/engine.js
CHANGED
|
@@ -2,7 +2,7 @@ import OpenAI from "openai";
|
|
|
2
2
|
import { max_output_tokens, max_empty_retries, max_agent_steps, max_context_tokens, context_overhead_margin, compact_keep_recent_turns, max_summary_source_chars, max_read_file_stored_chars, } from "./config.js";
|
|
3
3
|
import { SYSTEM_PROMPT } from "./system.js";
|
|
4
4
|
import { buildTools, truncateToolOutput, TOOL_IMPLEMENTATIONS } from "./tools.js";
|
|
5
|
-
import { mutedMarkdown, aiMarkdown, tickDuration, displayRows, safeCommitPoint, printAiChunk, formatToolAction, renderPanel, Spinner, hideCursor,
|
|
5
|
+
import { mutedMarkdown, aiMarkdown, tickDuration, displayRows, safeCommitPoint, printAiChunk, formatToolAction, renderPanel, Spinner, hideCursor, } from "./ui.js";
|
|
6
6
|
import { reportUsage } from "./api.js";
|
|
7
7
|
import { stripOrphanCalls, persistCompactionSummary, toolOutputFailed, } from "./sessions.js";
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
@@ -548,7 +548,6 @@ export class InferenceEngine {
|
|
|
548
548
|
}
|
|
549
549
|
finally {
|
|
550
550
|
this.inQuery = false;
|
|
551
|
-
showCursor();
|
|
552
551
|
if (stats["tokens"] > 0 && this.keyData) {
|
|
553
552
|
const userId = this.keyData["user_id"];
|
|
554
553
|
if (userId) {
|
package/dist/oxe.js
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { main } from "./cli.js";
|
|
2
2
|
export { main };
|
|
3
|
+
// The TUI keeps the terminal cursor hidden except inside a prompt field. Always
|
|
4
|
+
// restore it on exit so the shell isn't left with an invisible cursor.
|
|
5
|
+
process.on("exit", () => {
|
|
6
|
+
try {
|
|
7
|
+
process.stdout.write("\x1b[?25h");
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
/* ignore */
|
|
11
|
+
}
|
|
12
|
+
});
|
|
3
13
|
main().catch((err) => {
|
|
4
14
|
const msg = err?.message;
|
|
5
15
|
if (msg === "interrupt" || msg === "eof") {
|
package/dist/ui.js
CHANGED
|
@@ -588,6 +588,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
588
588
|
let done = false;
|
|
589
589
|
let lastCursorRow = 0;
|
|
590
590
|
let lastTotalRows = 0;
|
|
591
|
+
let prevFrameLines = null;
|
|
591
592
|
// Erase the prompt region: a leading blank line + the box. Cursor sits at
|
|
592
593
|
// lastCursorRow inside the box; move up to the box's top border, erase the
|
|
593
594
|
// box rows, then erase the leading blank line, leaving the cursor on that
|
|
@@ -609,7 +610,6 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
609
610
|
return;
|
|
610
611
|
done = true;
|
|
611
612
|
process.stdin.setRawMode(false);
|
|
612
|
-
showCursor();
|
|
613
613
|
clearBox();
|
|
614
614
|
process.stdin.removeListener("keypress", onKeypress);
|
|
615
615
|
process.stdin.pause();
|
|
@@ -620,9 +620,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
620
620
|
};
|
|
621
621
|
const repaint = (isFirst = false) => {
|
|
622
622
|
const { frame, cursorRow, cursorCol, totalRows } = renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor);
|
|
623
|
-
|
|
624
|
-
lastTotalRows = totalRows;
|
|
625
|
-
const frameLines = frame.split("\n");
|
|
623
|
+
const newLines = frame.split("\n");
|
|
626
624
|
if (isFirst) {
|
|
627
625
|
// The caller's content always ends with "\n", so the cursor sits at the
|
|
628
626
|
// start of a fresh (blank) line — that line is the leading blank
|
|
@@ -630,20 +628,47 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
630
628
|
// one line so the box starts below that blank; do NOT emit a second
|
|
631
629
|
// blank here (it caused a double gap above the box / on cancel).
|
|
632
630
|
process.stdout.write("\n");
|
|
631
|
+
for (let i = 0; i < newLines.length; i++) {
|
|
632
|
+
process.stdout.write(newLines[i]);
|
|
633
|
+
if (i < newLines.length - 1)
|
|
634
|
+
process.stdout.write("\n");
|
|
635
|
+
}
|
|
636
|
+
prevFrameLines = newLines;
|
|
637
|
+
lastCursorRow = cursorRow;
|
|
638
|
+
lastTotalRows = totalRows;
|
|
639
|
+
// Cursor sits on the bottom border line; move it up to the input row.
|
|
640
|
+
const up = totalRows - 1 - cursorRow;
|
|
641
|
+
process.stdout.write(`\x1b[${up}A\r\x1b[${cursorCol}C`);
|
|
642
|
+
return;
|
|
633
643
|
}
|
|
634
644
|
else {
|
|
635
|
-
// Cursor currently sits at
|
|
636
|
-
//
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
645
|
+
// Cursor currently sits at the previous input position (lastCursorRow
|
|
646
|
+
// inside the box). Move up to the top border, then rewrite ONLY the
|
|
647
|
+
// lines whose content actually changed, leaving the static borders
|
|
648
|
+
// untouched — this avoids the whole-box flicker on every keystroke.
|
|
649
|
+
process.stdout.write(`\x1b[${lastCursorRow}A\r`);
|
|
650
|
+
const oldLines = prevFrameLines ?? [];
|
|
651
|
+
const maxLen = Math.max(oldLines.length, newLines.length);
|
|
652
|
+
for (let i = 0; i < maxLen; i++) {
|
|
653
|
+
if (newLines[i] !== oldLines[i]) {
|
|
654
|
+
process.stdout.write("\r\x1b[K" + (newLines[i] ?? ""));
|
|
655
|
+
}
|
|
656
|
+
if (i < maxLen - 1)
|
|
657
|
+
process.stdout.write("\n");
|
|
658
|
+
}
|
|
659
|
+
// Cursor now sits at line (maxLen-1), column 0. Move it to the target
|
|
660
|
+
// input row (cursorRow), handling line-count changes in either direction.
|
|
661
|
+
const atLine = maxLen - 1;
|
|
662
|
+
if (atLine > cursorRow)
|
|
663
|
+
process.stdout.write(`\x1b[${atLine - cursorRow}A`);
|
|
664
|
+
else if (atLine < cursorRow)
|
|
665
|
+
process.stdout.write(`\x1b[${cursorRow - atLine}B`);
|
|
666
|
+
process.stdout.write(`\r\x1b[${cursorCol}C`);
|
|
667
|
+
prevFrameLines = newLines;
|
|
668
|
+
lastCursorRow = cursorRow;
|
|
669
|
+
lastTotalRows = totalRows;
|
|
670
|
+
return;
|
|
643
671
|
}
|
|
644
|
-
// Reposition the cursor inside the box.
|
|
645
|
-
const fromBottom = totalRows - 1 - cursorRow;
|
|
646
|
-
process.stdout.write(`\x1b[${fromBottom}A\r\x1b[${cursorCol}C`);
|
|
647
672
|
};
|
|
648
673
|
const insert = (text) => {
|
|
649
674
|
if (histIdx !== hist.length) {
|