@oxecli/oxe 1.0.17 → 1.0.19
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 +8 -6
- package/dist/ui.js +29 -2
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -59,7 +59,9 @@ export class CLI {
|
|
|
59
59
|
titleAlign: "left",
|
|
60
60
|
colGap: 2,
|
|
61
61
|
});
|
|
62
|
-
|
|
62
|
+
// Write the panel starting on a fresh line. No extra leading/trailing blank
|
|
63
|
+
// here — askBottomPrompt's own leading newline supplies the single gap.
|
|
64
|
+
process.stdout.write(panel + "\n");
|
|
63
65
|
if (process.stdin.isTTY) {
|
|
64
66
|
// Wait for a close key, then erase the panel (mirrors Python's Live).
|
|
65
67
|
enableRawStdin();
|
|
@@ -72,10 +74,12 @@ export class CLI {
|
|
|
72
74
|
finally {
|
|
73
75
|
disableRawStdin();
|
|
74
76
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
// Cursor sits one line below the panel; move up to its top border and
|
|
78
|
+
// clear downward so the whole panel disappears and the cursor lands back
|
|
79
|
+
// on the fresh line before the prompt.
|
|
80
|
+
const n = panel.split("\n").length;
|
|
81
|
+
process.stdout.write(`\x1b[${n}A\r\x1b[J`);
|
|
77
82
|
}
|
|
78
|
-
process.stdout.write("\n");
|
|
79
83
|
}
|
|
80
84
|
async awaitRawCloseKey() {
|
|
81
85
|
const k = await waitRawKey();
|
|
@@ -201,7 +205,6 @@ export class CLI {
|
|
|
201
205
|
for (const rec of recs) {
|
|
202
206
|
process.stdout.write(this.conversationRow(rec) + "\n");
|
|
203
207
|
}
|
|
204
|
-
process.stdout.write("\n");
|
|
205
208
|
}
|
|
206
209
|
/** Build the interactive picker panel (mirrors Python `_render_picker`). */
|
|
207
210
|
renderPickerPanel(recs, selected, visible = 8) {
|
|
@@ -384,7 +387,6 @@ export class CLI {
|
|
|
384
387
|
else {
|
|
385
388
|
process.stdout.write("\n");
|
|
386
389
|
renderPanel("Usage: /effort none|low|high", "Error", "", true, "31");
|
|
387
|
-
process.stdout.write("\n");
|
|
388
390
|
}
|
|
389
391
|
continue;
|
|
390
392
|
}
|
package/dist/ui.js
CHANGED
|
@@ -24,7 +24,10 @@ export function disableRawStdin() {
|
|
|
24
24
|
catch {
|
|
25
25
|
/* ignore */
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
// Do NOT pause stdin here: askBottomPrompt re-acquires raw mode and
|
|
28
|
+
// resumes the stream itself. Pausing can race with that resume and drop
|
|
29
|
+
// keypress events on some terminals (prompt appearing "locked" after an
|
|
30
|
+
// interactive help/picker).
|
|
28
31
|
showCursor();
|
|
29
32
|
}
|
|
30
33
|
}
|
|
@@ -958,6 +961,22 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
958
961
|
}
|
|
959
962
|
}
|
|
960
963
|
};
|
|
964
|
+
const isNewlineKey = (key) => {
|
|
965
|
+
if (!key)
|
|
966
|
+
return false;
|
|
967
|
+
if (key.name === "enter")
|
|
968
|
+
return true; // bare \n / Ctrl+J
|
|
969
|
+
if (key.name === "return")
|
|
970
|
+
return !!(key.shift || key.ctrl || key.meta);
|
|
971
|
+
// Kitty-keyboard-protocol Shift/Ctrl+Enter (name is "undefined" in Node).
|
|
972
|
+
const seq = key.sequence || "";
|
|
973
|
+
if (seq === "\x1b[13;2u" || seq === "\x1b[13;5u" || seq === "\x1b[13;2~")
|
|
974
|
+
return true;
|
|
975
|
+
// Legacy Shift+Enter decoded as F3 with shift.
|
|
976
|
+
if (key.name === "f3" && key.shift)
|
|
977
|
+
return true;
|
|
978
|
+
return false;
|
|
979
|
+
};
|
|
961
980
|
const onKeypress = (str, key) => {
|
|
962
981
|
if (key && key.ctrl && key.name === "c") {
|
|
963
982
|
settle(new Error("interrupt"), true);
|
|
@@ -967,12 +986,20 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = []) {
|
|
|
967
986
|
settle(new Error("eof"), true);
|
|
968
987
|
return;
|
|
969
988
|
}
|
|
970
|
-
|
|
989
|
+
// Plain Enter submits; any modified Enter (Shift/Ctrl+Enter) inserts a
|
|
990
|
+
// newline, mirroring the Python original's _read_input_event (which maps
|
|
991
|
+
// \x1b[13;2u / \x1b[13;5u / Shift+\r to "\n").
|
|
992
|
+
if (key && key.name === "return" && !(key.shift || key.ctrl || key.meta)) {
|
|
971
993
|
if (buffer.trim()) {
|
|
972
994
|
settle([buffer, pasteSpans], false);
|
|
973
995
|
}
|
|
974
996
|
return;
|
|
975
997
|
}
|
|
998
|
+
if (isNewlineKey(key)) {
|
|
999
|
+
insert("\n");
|
|
1000
|
+
repaint();
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
976
1003
|
if (key && key.name === "backspace") {
|
|
977
1004
|
backspace();
|
|
978
1005
|
repaint();
|