@oxecli/oxe 1.0.55 → 1.0.57
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 +2 -2
- package/dist/ui.js +57 -56
- package/package.json +1 -1
package/dist/engine.js
CHANGED
|
@@ -43,7 +43,7 @@ export class InferenceEngine {
|
|
|
43
43
|
keyData;
|
|
44
44
|
client;
|
|
45
45
|
workActive = false;
|
|
46
|
-
workRows =
|
|
46
|
+
workRows = 0;
|
|
47
47
|
inQuery = false;
|
|
48
48
|
activeAbort = null;
|
|
49
49
|
interrupted = false;
|
|
@@ -403,7 +403,7 @@ export class InferenceEngine {
|
|
|
403
403
|
return [conversation, false];
|
|
404
404
|
const started = Date.now();
|
|
405
405
|
const comp = new Spinner();
|
|
406
|
-
comp.start(
|
|
406
|
+
comp.start(`Compacting conversation ${tickDuration(0)}`);
|
|
407
407
|
const compTimer = setInterval(() => {
|
|
408
408
|
comp.update(`Compacting conversation ${tickDuration((Date.now() - started) / 1000)}`);
|
|
409
409
|
}, 100);
|
package/dist/ui.js
CHANGED
|
@@ -334,11 +334,10 @@ export function aiMarkdown(text) {
|
|
|
334
334
|
return markdownToAnsi(text);
|
|
335
335
|
}
|
|
336
336
|
export function mutedMarkdown(text) {
|
|
337
|
-
|
|
337
|
+
return markdownToAnsi(text)
|
|
338
338
|
.split("\n")
|
|
339
339
|
.map((l) => `\x1b[2m${l}\x1b[0m`)
|
|
340
340
|
.join("\n");
|
|
341
|
-
return markdownToAnsi(dimmed);
|
|
342
341
|
}
|
|
343
342
|
// ---------------------------------------------------------------------------
|
|
344
343
|
// Panel Rendering
|
|
@@ -377,15 +376,8 @@ function panelString(content, title = "", subtitle = "", expand = true, borderSt
|
|
|
377
376
|
for (let i = 0; i < styledLines.length; i++) {
|
|
378
377
|
const line = styledLines[i];
|
|
379
378
|
const plain = plainLines[i] ?? "";
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
const truncated = line.slice(0, innerW);
|
|
383
|
-
out.push(`\x1b[${borderStyle}m│\x1b[0m ${truncated} \x1b[${borderStyle}m│\x1b[0m`);
|
|
384
|
-
}
|
|
385
|
-
else {
|
|
386
|
-
const pad = Math.max(innerW - plain.length, 0);
|
|
387
|
-
out.push(`\x1b[${borderStyle}m│\x1b[0m ${line}${" ".repeat(pad)} \x1b[${borderStyle}m│\x1b[0m`);
|
|
388
|
-
}
|
|
379
|
+
const pad = Math.max(innerW - plain.length, 0);
|
|
380
|
+
out.push(`\x1b[${borderStyle}m│\x1b[0m ${line}${" ".repeat(pad)} \x1b[${borderStyle}m│\x1b[0m`);
|
|
389
381
|
}
|
|
390
382
|
const bottom = `╰${embed(subtitle, "center")}╯`;
|
|
391
383
|
out.push(`\x1b[${borderStyle}m${bottom}\x1b[0m`);
|
|
@@ -830,60 +822,45 @@ export function renderBufferWithCursor(buffer, pasteSpans, prefix, label, cursor
|
|
|
830
822
|
const totalRows = body.length + 2;
|
|
831
823
|
return { frame, cursorRow, cursorCol, totalRows };
|
|
832
824
|
}
|
|
833
|
-
export function
|
|
825
|
+
export function isShiftEnterKey(str, key) {
|
|
834
826
|
if (!key)
|
|
835
827
|
return false;
|
|
836
828
|
const seq = key.sequence || str || "";
|
|
837
|
-
|
|
838
|
-
// Any modified Enter / Return / Linefeed / Ctrl+J
|
|
839
|
-
if (hasModifier &&
|
|
829
|
+
if (key.shift &&
|
|
840
830
|
(key.name === "return" ||
|
|
841
831
|
key.name === "enter" ||
|
|
842
832
|
key.name === "linefeed" ||
|
|
843
833
|
seq === "\r" ||
|
|
844
|
-
seq === "\n"
|
|
845
|
-
(key.ctrl && key.name === "j"))) {
|
|
834
|
+
seq === "\n")) {
|
|
846
835
|
return true;
|
|
847
836
|
}
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
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") {
|
|
837
|
+
if (seq === "\x1b[13;2u" ||
|
|
838
|
+
seq === "\x1b[13;2~" ||
|
|
839
|
+
seq === "\x1b[13;2_" ||
|
|
840
|
+
seq === "\x1b[27;2;13~" ||
|
|
841
|
+
seq === "\x1bOM") {
|
|
862
842
|
return true;
|
|
863
843
|
}
|
|
864
|
-
|
|
865
|
-
if (key.name === "f3" && key.shift)
|
|
844
|
+
if (!key.ctrl && (str === "\n" || seq === "\n" || key.name === "linefeed")) {
|
|
866
845
|
return true;
|
|
846
|
+
}
|
|
867
847
|
return false;
|
|
868
848
|
}
|
|
849
|
+
export const isNewlineKey = isShiftEnterKey;
|
|
869
850
|
export function isSubmitEnterKey(str, key) {
|
|
870
851
|
if (!key)
|
|
871
852
|
return false;
|
|
872
|
-
if (
|
|
853
|
+
if (isShiftEnterKey(str, key))
|
|
873
854
|
return false;
|
|
874
855
|
const seq = key.sequence || str || "";
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
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~")
|
|
856
|
+
if ((key.name === "return" ||
|
|
857
|
+
key.name === "enter" ||
|
|
858
|
+
seq === "\r" ||
|
|
859
|
+
seq === "\x1b[13u" ||
|
|
860
|
+
seq === "\x1b[13;1u") &&
|
|
861
|
+
!key.shift) {
|
|
886
862
|
return true;
|
|
863
|
+
}
|
|
887
864
|
return false;
|
|
888
865
|
}
|
|
889
866
|
export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
@@ -1017,6 +994,20 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1017
994
|
}
|
|
1018
995
|
cursor += text.length;
|
|
1019
996
|
};
|
|
997
|
+
// A paste span is treated as a single atomic "block" only when it collapses
|
|
998
|
+
// to a marker (large pastes). Small inline pastes behave like normal text.
|
|
999
|
+
const spanCollapsed = (span) => {
|
|
1000
|
+
return shouldCollapsePaste(buffer.slice(span[0], span[1]));
|
|
1001
|
+
};
|
|
1002
|
+
const deleteWholeSpan = (span) => {
|
|
1003
|
+
const [start, end] = span;
|
|
1004
|
+
buffer = buffer.slice(0, start) + buffer.slice(end);
|
|
1005
|
+
const delta = start - end;
|
|
1006
|
+
pasteSpans = pasteSpans
|
|
1007
|
+
.filter(([s, e]) => s !== start || e !== end)
|
|
1008
|
+
.map(([s, e]) => (s >= end ? [s + delta, e + delta] : [s, e]));
|
|
1009
|
+
cursor = start;
|
|
1010
|
+
};
|
|
1020
1011
|
const backspace = () => {
|
|
1021
1012
|
if (cursor <= 0)
|
|
1022
1013
|
return;
|
|
@@ -1025,14 +1016,8 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1025
1016
|
histIdx = hist.length;
|
|
1026
1017
|
}
|
|
1027
1018
|
const containing = pasteSpans.find(([s, e]) => s < cursor && cursor <= e);
|
|
1028
|
-
if (containing) {
|
|
1029
|
-
|
|
1030
|
-
buffer = buffer.slice(0, start) + buffer.slice(end);
|
|
1031
|
-
const delta = start - end;
|
|
1032
|
-
pasteSpans = pasteSpans
|
|
1033
|
-
.filter(([s, e]) => s !== start || e !== end)
|
|
1034
|
-
.map(([s, e]) => (s >= end ? [s + delta, e + delta] : [s, e]));
|
|
1035
|
-
cursor = start;
|
|
1019
|
+
if (containing && spanCollapsed(containing)) {
|
|
1020
|
+
deleteWholeSpan(containing);
|
|
1036
1021
|
return;
|
|
1037
1022
|
}
|
|
1038
1023
|
const before = Array.from(buffer.slice(0, cursor));
|
|
@@ -1064,7 +1049,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1064
1049
|
histIdx = hist.length;
|
|
1065
1050
|
}
|
|
1066
1051
|
const containing = pasteSpans.find(([s, e]) => s <= cursor && cursor < e);
|
|
1067
|
-
if (containing) {
|
|
1052
|
+
if (containing && spanCollapsed(containing)) {
|
|
1068
1053
|
const [start, end] = containing;
|
|
1069
1054
|
buffer = buffer.slice(0, start) + buffer.slice(end);
|
|
1070
1055
|
const delta = start - end;
|
|
@@ -1074,6 +1059,22 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1074
1059
|
return;
|
|
1075
1060
|
}
|
|
1076
1061
|
buffer = buffer.slice(0, cursor) + buffer.slice(cursor + 1);
|
|
1062
|
+
const deletedAt = cursor;
|
|
1063
|
+
const adjusted = [];
|
|
1064
|
+
for (const [s, e] of pasteSpans) {
|
|
1065
|
+
if (deletedAt >= s && deletedAt < e) {
|
|
1066
|
+
const ne = e - 1;
|
|
1067
|
+
if (s < ne)
|
|
1068
|
+
adjusted.push([s, ne]);
|
|
1069
|
+
}
|
|
1070
|
+
else if (deletedAt < s) {
|
|
1071
|
+
adjusted.push([s - 1, e - 1]);
|
|
1072
|
+
}
|
|
1073
|
+
else {
|
|
1074
|
+
adjusted.push([s, e]);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
pasteSpans = adjusted.filter(([s, e]) => s < e);
|
|
1077
1078
|
};
|
|
1078
1079
|
const deleteWordBefore = () => {
|
|
1079
1080
|
if (cursor <= 0)
|
|
@@ -1090,7 +1091,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1090
1091
|
if (cursor <= 0)
|
|
1091
1092
|
return;
|
|
1092
1093
|
for (const [s, e] of pasteSpans) {
|
|
1093
|
-
if (s < cursor && cursor <= e) {
|
|
1094
|
+
if (s < cursor && cursor <= e && spanCollapsed([s, e])) {
|
|
1094
1095
|
cursor = s;
|
|
1095
1096
|
return;
|
|
1096
1097
|
}
|
|
@@ -1101,7 +1102,7 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
1101
1102
|
if (cursor >= buffer.length)
|
|
1102
1103
|
return;
|
|
1103
1104
|
for (const [s, e] of pasteSpans) {
|
|
1104
|
-
if (s <= cursor && cursor < e) {
|
|
1105
|
+
if (s <= cursor && cursor < e && spanCollapsed([s, e])) {
|
|
1105
1106
|
cursor = e;
|
|
1106
1107
|
return;
|
|
1107
1108
|
}
|