@oxecli/oxe 1.0.53 → 1.0.55
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 +1 -1
- package/dist/engine.js +5 -6
- package/dist/ui.js +69 -54
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -373,7 +373,7 @@ export class CLI {
|
|
|
373
373
|
this.renderHeader(engine.modelName);
|
|
374
374
|
process.stdout.write("\n");
|
|
375
375
|
process.stdout.write(`\x1b[2mResumed:\x1b[0m \x1b[1m${truncateLabel(rec["label"])}\x1b[0m\n`);
|
|
376
|
-
process.stdout.write(`\x1b[2m(${this.inputItems.length} items · ${estimateTokens(this.inputItems).toLocaleString()} tokens
|
|
376
|
+
process.stdout.write(`\x1b[2m(${this.inputItems.length} items · ${estimateTokens(this.inputItems).toLocaleString()} tokens)\x1b[0m\n\n`);
|
|
377
377
|
renderPanel("Conversation history restored", "Restored");
|
|
378
378
|
process.stdout.write("\n");
|
|
379
379
|
if (this.story.length)
|
package/dist/engine.js
CHANGED
|
@@ -169,10 +169,10 @@ export class InferenceEngine {
|
|
|
169
169
|
let thinkingStart = null;
|
|
170
170
|
const workStatus = new Spinner();
|
|
171
171
|
const workingStarted = Date.now();
|
|
172
|
-
workStatus.start(`Working
|
|
172
|
+
workStatus.start(`Working ${tickDuration(0)}`);
|
|
173
173
|
const workTimer = setInterval(() => {
|
|
174
|
-
workStatus.update(`Working
|
|
175
|
-
},
|
|
174
|
+
workStatus.update(`Working ${tickDuration((Date.now() - workingStarted) / 1000)}`);
|
|
175
|
+
}, 100);
|
|
176
176
|
let workingReported = false;
|
|
177
177
|
let response = null;
|
|
178
178
|
let etype = null;
|
|
@@ -254,7 +254,7 @@ export class InferenceEngine {
|
|
|
254
254
|
if (thinkingStart === null) {
|
|
255
255
|
thinkingStart = Date.now();
|
|
256
256
|
status = new Spinner();
|
|
257
|
-
status.start(
|
|
257
|
+
status.start(`Thinking ${tickDuration(0)}`);
|
|
258
258
|
}
|
|
259
259
|
else {
|
|
260
260
|
status?.update(`Thinking ${tickDuration((Date.now() - thinkingStart) / 1000)}`);
|
|
@@ -406,7 +406,7 @@ export class InferenceEngine {
|
|
|
406
406
|
comp.start("Compacting conversation `0s`");
|
|
407
407
|
const compTimer = setInterval(() => {
|
|
408
408
|
comp.update(`Compacting conversation ${tickDuration((Date.now() - started) / 1000)}`);
|
|
409
|
-
},
|
|
409
|
+
}, 100);
|
|
410
410
|
let compacted;
|
|
411
411
|
try {
|
|
412
412
|
compacted = await this.compactHistory(conversation);
|
|
@@ -458,7 +458,6 @@ export class InferenceEngine {
|
|
|
458
458
|
if (stats["tokens"] > 0) {
|
|
459
459
|
parts.push(`Used \x1b[22;37m${stats["tokens"].toLocaleString()}\x1b[2m tokens`);
|
|
460
460
|
}
|
|
461
|
-
parts.push(`Effort: \x1b[1;36m${this.reasoningEffort}\x1b[0m\x1b[2m`);
|
|
462
461
|
return `\x1b[2m(${parts.join(" · ")})\x1b[0m`;
|
|
463
462
|
};
|
|
464
463
|
const summary = () => mutedMarkdown(footerText());
|
package/dist/ui.js
CHANGED
|
@@ -429,12 +429,13 @@ export function renderTableString(rows, opts = {}) {
|
|
|
429
429
|
// Durations & Text Formatting
|
|
430
430
|
// ---------------------------------------------------------------------------
|
|
431
431
|
export function formatDuration(seconds) {
|
|
432
|
-
const
|
|
433
|
-
if (
|
|
434
|
-
return `${
|
|
435
|
-
|
|
436
|
-
const
|
|
437
|
-
|
|
432
|
+
const s = Math.max(0, seconds);
|
|
433
|
+
if (s < 60) {
|
|
434
|
+
return `${s.toFixed(1)}s`;
|
|
435
|
+
}
|
|
436
|
+
const mins = Math.floor(s / 60);
|
|
437
|
+
const remSecs = (s % 60).toFixed(1);
|
|
438
|
+
return `${mins}m ${remSecs}s`;
|
|
438
439
|
}
|
|
439
440
|
export function tickDuration(seconds) {
|
|
440
441
|
return `\x1b[22;37m${formatDuration(seconds)}\x1b[2m`;
|
|
@@ -587,19 +588,19 @@ export function formatToolAction(name, argumentsJson, status = "ok") {
|
|
|
587
588
|
const start = args["start_line"];
|
|
588
589
|
const end = args["end_line"];
|
|
589
590
|
const span = start != null || end != null
|
|
590
|
-
? `
|
|
591
|
+
? ` lines ${start ?? 1}-${end ?? "end"}`
|
|
591
592
|
: "";
|
|
592
593
|
return phrase("Read", "Reading", "Failed to read", `${p}${span}`);
|
|
593
594
|
}
|
|
594
595
|
case "write_file":
|
|
595
|
-
return phrase("Wrote", "Writing", "Failed to write", `${p}
|
|
596
|
+
return phrase("Wrote", "Writing", "Failed to write", `${p} · ${String(args["content"] ?? "").length.toLocaleString()} chars`);
|
|
596
597
|
case "edit_file": {
|
|
597
|
-
const suffix = args["replace_all"] ? "
|
|
598
|
+
const suffix = args["replace_all"] ? " · replace all" : "";
|
|
598
599
|
return phrase("Edited", "Editing", "Failed to edit", `${p}${suffix}`);
|
|
599
600
|
}
|
|
600
601
|
case "bash": {
|
|
601
602
|
const cwd = args["cwd"];
|
|
602
|
-
const location = cwd ? `
|
|
603
|
+
const location = cwd ? ` in ${cwd}` : "";
|
|
603
604
|
const command = truncateEllipsis(String(args["command"] ?? ""), 400, "command");
|
|
604
605
|
if (status === "started")
|
|
605
606
|
return `Running command${location}: ${command}`;
|
|
@@ -829,6 +830,62 @@ export function renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor
|
|
|
829
830
|
const totalRows = body.length + 2;
|
|
830
831
|
return { frame, cursorRow, cursorCol, totalRows };
|
|
831
832
|
}
|
|
833
|
+
export function isNewlineKey(str, key) {
|
|
834
|
+
if (!key)
|
|
835
|
+
return false;
|
|
836
|
+
const seq = key.sequence || str || "";
|
|
837
|
+
const hasModifier = !!(key.shift || key.ctrl || key.meta);
|
|
838
|
+
// Any modified Enter / Return / Linefeed / Ctrl+J
|
|
839
|
+
if (hasModifier &&
|
|
840
|
+
(key.name === "return" ||
|
|
841
|
+
key.name === "enter" ||
|
|
842
|
+
key.name === "linefeed" ||
|
|
843
|
+
seq === "\r" ||
|
|
844
|
+
seq === "\n" ||
|
|
845
|
+
(key.ctrl && key.name === "j"))) {
|
|
846
|
+
return true;
|
|
847
|
+
}
|
|
848
|
+
// Kitty protocol: \x1b[13;<mod>u (mod 2=Shift, 3=Alt, 5=Ctrl, 6=Ctrl+Shift, etc.)
|
|
849
|
+
if (/^\x1b\[13;([2-9]|\d{2,})u$/.test(seq))
|
|
850
|
+
return true;
|
|
851
|
+
// Legacy kitty/xterm: \x1b[13;<mod>~
|
|
852
|
+
if (/^\x1b\[13;([2-9]|\d{2,})~$/.test(seq))
|
|
853
|
+
return true;
|
|
854
|
+
// Xterm modifyOtherKeys: \x1b[27;<mod>;13~
|
|
855
|
+
if (/^\x1b\[27;([2-9]|\d{2,});13~$/.test(seq))
|
|
856
|
+
return true;
|
|
857
|
+
// Alt+Enter / Esc+Enter
|
|
858
|
+
if (seq === "\x1b\r" ||
|
|
859
|
+
seq === "\x1b\n" ||
|
|
860
|
+
seq === "\x1b\x0d" ||
|
|
861
|
+
seq === "\x1b\x0a") {
|
|
862
|
+
return true;
|
|
863
|
+
}
|
|
864
|
+
// F3 Shift decode in legacy Node
|
|
865
|
+
if (key.name === "f3" && key.shift)
|
|
866
|
+
return true;
|
|
867
|
+
return false;
|
|
868
|
+
}
|
|
869
|
+
export function isSubmitEnterKey(str, key) {
|
|
870
|
+
if (!key)
|
|
871
|
+
return false;
|
|
872
|
+
if (isNewlineKey(str, key))
|
|
873
|
+
return false;
|
|
874
|
+
const seq = key.sequence || str || "";
|
|
875
|
+
const isPlainEnterName = (key.name === "return" || key.name === "enter") &&
|
|
876
|
+
!key.shift &&
|
|
877
|
+
!key.ctrl &&
|
|
878
|
+
!key.meta;
|
|
879
|
+
if (isPlainEnterName)
|
|
880
|
+
return true;
|
|
881
|
+
if (seq === "\r" && !key.ctrl && !key.shift && !key.meta)
|
|
882
|
+
return true;
|
|
883
|
+
if (seq === "\x1b[13u" || seq === "\x1b[13;1u")
|
|
884
|
+
return true;
|
|
885
|
+
if (seq === "\x1b[27;1;13~")
|
|
886
|
+
return true;
|
|
887
|
+
return false;
|
|
888
|
+
}
|
|
832
889
|
export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
833
890
|
return new Promise((resolve, reject) => {
|
|
834
891
|
const isTTY = process.stdin.isTTY;
|
|
@@ -1106,46 +1163,6 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1106
1163
|
}
|
|
1107
1164
|
}
|
|
1108
1165
|
};
|
|
1109
|
-
const isNewlineKey = (key) => {
|
|
1110
|
-
if (!key)
|
|
1111
|
-
return false;
|
|
1112
|
-
if (key.ctrl && key.name === "j")
|
|
1113
|
-
return true;
|
|
1114
|
-
if (key.name === "enter")
|
|
1115
|
-
return !!(key.shift || key.ctrl || key.meta);
|
|
1116
|
-
if (key.name === "return")
|
|
1117
|
-
return !!(key.shift || key.ctrl || key.meta);
|
|
1118
|
-
const seq = key.sequence || "";
|
|
1119
|
-
if (/^\x1b\[13;([2-9]|\d{2,})u$/.test(seq))
|
|
1120
|
-
return true;
|
|
1121
|
-
if (/^\x1b\[13;([2-9]|\d{2,})~$/.test(seq))
|
|
1122
|
-
return true;
|
|
1123
|
-
if (key.name === "f3" && key.shift)
|
|
1124
|
-
return true;
|
|
1125
|
-
return false;
|
|
1126
|
-
};
|
|
1127
|
-
const isModifiedEnterInput = (str, key) => {
|
|
1128
|
-
const value = str || "";
|
|
1129
|
-
const sequence = key?.sequence || "";
|
|
1130
|
-
if (value === "\n" || value === "\x0a")
|
|
1131
|
-
return true;
|
|
1132
|
-
if (key?.name === "linefeed" || (key?.ctrl && key?.name === "j"))
|
|
1133
|
-
return true;
|
|
1134
|
-
return (/^\x1b\[13;(?:[2-9]|\d{2,})(?:u|~)$/.test(value) ||
|
|
1135
|
-
/^\x1b\[13;(?:[2-9]|\d{2,})(?:u|~)$/.test(sequence));
|
|
1136
|
-
};
|
|
1137
|
-
const isSubmitEnterKey = (key) => {
|
|
1138
|
-
if (!key)
|
|
1139
|
-
return false;
|
|
1140
|
-
if ((key.name === "return" || key.name === "enter") &&
|
|
1141
|
-
!(key.shift || key.ctrl || key.meta)) {
|
|
1142
|
-
return true;
|
|
1143
|
-
}
|
|
1144
|
-
const seq = key.sequence || "";
|
|
1145
|
-
if (seq === "\x1b[13u" || /^\x1b\[13;1u$/.test(seq))
|
|
1146
|
-
return true;
|
|
1147
|
-
return false;
|
|
1148
|
-
};
|
|
1149
1166
|
const consumeBracketedPaste = (str, key) => {
|
|
1150
1167
|
const start = "\x1b[200~";
|
|
1151
1168
|
const end = "\x1b[201~";
|
|
@@ -1262,14 +1279,12 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1262
1279
|
repaint();
|
|
1263
1280
|
return;
|
|
1264
1281
|
}
|
|
1265
|
-
if (isNewlineKey(key) ||
|
|
1266
|
-
isModifiedEnterInput(str, key) ||
|
|
1267
|
-
(pasteBurst && isSubmitEnterKey(key))) {
|
|
1282
|
+
if (isNewlineKey(str, key) || (pasteBurst && isSubmitEnterKey(str, key))) {
|
|
1268
1283
|
insert("\n");
|
|
1269
1284
|
repaint();
|
|
1270
1285
|
return;
|
|
1271
1286
|
}
|
|
1272
|
-
if (isSubmitEnterKey(key)) {
|
|
1287
|
+
if (isSubmitEnterKey(str, key)) {
|
|
1273
1288
|
if (buffer.trim()) {
|
|
1274
1289
|
settle([buffer, pasteSpans], false);
|
|
1275
1290
|
}
|