@oxecli/oxe 1.0.85 → 1.0.86
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 +23 -5
- package/dist/ui.js +19 -17
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
|
|
|
4
4
|
import { loadOrPrompt, default_reasoning_effort, max_action_chars, max_resume_history_items, runtimeOsSummary, max_context_tokens, context_overhead_margin, } from "./config.js";
|
|
5
5
|
import { InferenceEngine, estimateTokens } from "./engine.js";
|
|
6
6
|
import { saveSession, loadSession, listSessions, nextSessionId, conversationLabel, COMMAND_HELP, stripOrphanCalls, toolOutputFailed, } from "./sessions.js";
|
|
7
|
-
import { clearScreen, enableAnsi, askBottomPrompt, userDisplayText, aiMarkdown, mutedMarkdown, messageText, toolCallLabel, formatToolResult, truncateEllipsis, stripAnsi, renderPanel, renderTableString, enableRawStdin, disableRawStdin, waitRawKey, } from "./ui.js";
|
|
7
|
+
import { clearScreen, enableAnsi, askBottomPrompt, userDisplayText, aiMarkdown, mutedMarkdown, messageText, toolCallLabel, formatToolResult, truncateEllipsis, stripAnsi, plainLen, truncateStyled, terminalWidth, TOOL_RESULT_MAX_LINES, MAX_COMMAND_DISPLAY_CHARS, renderPanel, renderTableString, enableRawStdin, disableRawStdin, waitRawKey, } from "./ui.js";
|
|
8
8
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
9
|
const require = createRequire(import.meta.url);
|
|
10
10
|
const packageInfo = require("../package.json");
|
|
@@ -49,14 +49,32 @@ export class CLI {
|
|
|
49
49
|
const label = started && String(started).trim();
|
|
50
50
|
const body = String(text).trim();
|
|
51
51
|
if (label && /^[⎿╰]/.test(stripAnsi(body))) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
// The result body was formatted against the terminal width at tool time,
|
|
53
|
+
// but the window may be narrower on resume — re-truncate defensively so
|
|
54
|
+
// long persisted lines never run off the screen.
|
|
55
|
+
const lineMax = Math.max(terminalWidth() - 4, 20);
|
|
56
|
+
const allLines = body.split("\n");
|
|
57
|
+
const lines = allLines
|
|
58
|
+
.slice(0, TOOL_RESULT_MAX_LINES)
|
|
59
|
+
.map((ln) => plainLen(ln) > lineMax ? truncateStyled(ln, lineMax) + "…\x1b[0m" : ln);
|
|
60
|
+
if (allLines.length > TOOL_RESULT_MAX_LINES) {
|
|
61
|
+
lines.push("\x1b[90m…\x1b[0m");
|
|
62
|
+
}
|
|
63
|
+
const labelLine = plainLen(label) > lineMax ? truncateStyled(label, lineMax) + "…\x1b[0m" : label;
|
|
64
|
+
process.stdout.write(`${labelLine}\n${lines.join("\n")}\n`);
|
|
65
|
+
if (diff) {
|
|
66
|
+
const diffLines = diff.split("\n").map((ln) => plainLen(ln) > lineMax ? truncateStyled(ln, lineMax) + "…\x1b[0m" : ln);
|
|
67
|
+
process.stdout.write(diffLines.join("\n") + "\n\n");
|
|
68
|
+
}
|
|
55
69
|
return;
|
|
56
70
|
}
|
|
57
71
|
const icon = status === "failed" ? "\x1b[31m✗\x1b[0m" : "\x1b[32m✓\x1b[0m";
|
|
58
72
|
const style = status === "failed" ? "\x1b[31m" : "\x1b[32m";
|
|
59
|
-
|
|
73
|
+
const truncated = truncateEllipsis(body, Math.min(max_action_chars, MAX_COMMAND_DISPLAY_CHARS), "text");
|
|
74
|
+
// truncateEllipsis appends a "…(text truncated: N chars total)" suffix, so
|
|
75
|
+
// re-truncate to the current width to keep the legacy action on one row.
|
|
76
|
+
const displayMax = Math.max(terminalWidth() - 6, 20);
|
|
77
|
+
process.stdout.write(`${icon} ${style}${truncateStyled(truncated, displayMax)}\x1b[0m\n`);
|
|
60
78
|
}
|
|
61
79
|
printAssistantBlock(text) {
|
|
62
80
|
const rendered = aiMarkdown(text);
|
package/dist/ui.js
CHANGED
|
@@ -681,10 +681,13 @@ const TOOL_DISPLAY_NAMES = {
|
|
|
681
681
|
grep: "Grep",
|
|
682
682
|
load_skill: "Load",
|
|
683
683
|
};
|
|
684
|
-
const
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
684
|
+
export const TOOL_RESULT_MAX_LINES = 6;
|
|
685
|
+
/** Cap on the visible command/arg shown in a tool label, so the entry always
|
|
686
|
+
* fits on a single row regardless of terminal width. */
|
|
687
|
+
export const MAX_COMMAND_DISPLAY_CHARS = 100;
|
|
688
|
+
/** First line of a tool entry: `Bash(rm -f "…")` — cyan tool name, primary arg
|
|
689
|
+
* in parens. Newlines collapse to spaces and the arg is width-capped so the
|
|
690
|
+
* label never wraps past one row. */
|
|
688
691
|
export function toolCallLabel(name, argumentsJson) {
|
|
689
692
|
let args = {};
|
|
690
693
|
try {
|
|
@@ -713,11 +716,12 @@ export function toolCallLabel(name, argumentsJson) {
|
|
|
713
716
|
arg = String(args["skill_name"] ?? "");
|
|
714
717
|
break;
|
|
715
718
|
}
|
|
716
|
-
arg = arg.trim();
|
|
719
|
+
arg = arg.trim().replace(/\s*\r?\n\s*/g, " ");
|
|
717
720
|
if (!arg)
|
|
718
721
|
return `\x1b[1;36m${display}\x1b[0m`;
|
|
719
|
-
|
|
720
|
-
|
|
722
|
+
const cap = Math.max(Math.min(terminalWidth() - plainLen(display) - 4, MAX_COMMAND_DISPLAY_CHARS), 20);
|
|
723
|
+
if (plainLen(arg) > cap)
|
|
724
|
+
arg = truncateStyled(arg, cap) + "…";
|
|
721
725
|
return `\x1b[1;36m${display}\x1b[0m(${arg})`;
|
|
722
726
|
}
|
|
723
727
|
/**
|
|
@@ -737,17 +741,15 @@ export function formatToolResult(rawResult, failed) {
|
|
|
737
741
|
if (failed && (!clean || clean === "(no output)") && code) {
|
|
738
742
|
return `${corner}\x1b[31mexit code: ${code}\x1b[0m`;
|
|
739
743
|
}
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
const
|
|
745
|
-
|
|
744
|
+
// Truncate to the terminal width (rows OR per-line length, whichever trips
|
|
745
|
+
// first) so long tool output — e.g. Glob paths — never runs off the screen.
|
|
746
|
+
const termW = terminalWidth();
|
|
747
|
+
const lineMax = Math.max(termW - 4, 20);
|
|
748
|
+
const allLines = clean.split("\n");
|
|
749
|
+
const lines = allLines
|
|
746
750
|
.slice(0, TOOL_RESULT_MAX_LINES)
|
|
747
|
-
.map((ln) => ln.length >
|
|
748
|
-
|
|
749
|
-
: ln);
|
|
750
|
-
if (clipped || body.split("\n").length > TOOL_RESULT_MAX_LINES)
|
|
751
|
+
.map((ln) => (ln.length > lineMax ? ln.slice(0, lineMax) + "…" : ln));
|
|
752
|
+
if (allLines.length > TOOL_RESULT_MAX_LINES)
|
|
751
753
|
lines.push("…");
|
|
752
754
|
const styleOpen = failed ? "\x1b[31m" : "\x1b[90m";
|
|
753
755
|
const inner = lines
|