@oxecli/oxe 1.0.103 → 1.0.105
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/README.md +3 -1
- package/dist/ui.js +33 -33
- package/package.json +1 -1
package/README.md
CHANGED
package/dist/ui.js
CHANGED
|
@@ -667,13 +667,17 @@ export function dockTransientStart(mode = "blank") {
|
|
|
667
667
|
return;
|
|
668
668
|
dockEraseBox();
|
|
669
669
|
if (mode === "flush") {
|
|
670
|
-
// Park
|
|
670
|
+
// Park directly under the preceding content (adjacent, no blank above), but
|
|
671
|
+
// still keep one blank row between the transient and the box — otherwise the
|
|
672
|
+
// working line (and the tool result that replaces it) sits flush against the
|
|
673
|
+
// prompt box. dockRel=2 mirrors the blank mode's spacing below the row.
|
|
671
674
|
process.stdout.write("\x1b[1A\r");
|
|
672
675
|
process.stdout.write("\n");
|
|
676
|
+
process.stdout.write("\n");
|
|
673
677
|
process.stdout.write(dockFrameLines.join("\n"));
|
|
674
678
|
process.stdout.write(`\x1b[${dockBoxRows - 1}A`);
|
|
675
|
-
process.stdout.write("\x1b[
|
|
676
|
-
dockRel =
|
|
679
|
+
process.stdout.write("\x1b[2A\r");
|
|
680
|
+
dockRel = 2;
|
|
677
681
|
}
|
|
678
682
|
else {
|
|
679
683
|
// Park on a fresh spinner row that keeps a blank above and below it.
|
|
@@ -1424,6 +1428,8 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = [], hin
|
|
|
1424
1428
|
: value;
|
|
1425
1429
|
process.stdout.write("\x1b[?2004l");
|
|
1426
1430
|
process.stdin.setRawMode(false);
|
|
1431
|
+
bracketedPaste = false;
|
|
1432
|
+
bracketedPasteBuffer = "";
|
|
1427
1433
|
if (pasteBurstTimer)
|
|
1428
1434
|
clearTimeout(pasteBurstTimer);
|
|
1429
1435
|
if (isErr) {
|
|
@@ -1712,18 +1718,17 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = [], hin
|
|
|
1712
1718
|
const end = "\x1b[201~";
|
|
1713
1719
|
const sequence = key?.sequence || "";
|
|
1714
1720
|
const value = str || "";
|
|
1715
|
-
|
|
1721
|
+
// A new paste-start while already inside a paste means the previous paste
|
|
1722
|
+
// was aborted (its end marker never arrived). Reset and start over so we
|
|
1723
|
+
// never swallow subsequent typing.
|
|
1724
|
+
if ((key?.name === "paste-start" || sequence === start || value === start)) {
|
|
1716
1725
|
bracketedPaste = true;
|
|
1717
1726
|
bracketedPasteBuffer = "";
|
|
1718
1727
|
const inline = value === start ? "" : value.startsWith(start) ? value.slice(start.length) : "";
|
|
1719
1728
|
if (inline)
|
|
1720
1729
|
bracketedPasteBuffer = inline;
|
|
1721
1730
|
if (inline.includes(end)) {
|
|
1722
|
-
const
|
|
1723
|
-
const pasted = inline
|
|
1724
|
-
.slice(0, endAt)
|
|
1725
|
-
.replace(/\r\n/g, "\n")
|
|
1726
|
-
.replace(/\r/g, "\n");
|
|
1731
|
+
const pasted = inline.slice(0, inline.indexOf(end)).replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1727
1732
|
bracketedPaste = false;
|
|
1728
1733
|
bracketedPasteBuffer = "";
|
|
1729
1734
|
if (pasted)
|
|
@@ -1734,7 +1739,12 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = [], hin
|
|
|
1734
1739
|
}
|
|
1735
1740
|
if (!bracketedPaste)
|
|
1736
1741
|
return false;
|
|
1737
|
-
|
|
1742
|
+
// Close on the end marker. readline emits it as a dedicated keypress
|
|
1743
|
+
// (key.name === "paste-end", sequence === \x1b[201~); also scan the raw
|
|
1744
|
+
// value in case a terminal delivers it embedded in a larger chunk.
|
|
1745
|
+
const endAt = value.indexOf(end);
|
|
1746
|
+
if (key?.name === "paste-end" || sequence === end || value === end || endAt >= 0) {
|
|
1747
|
+
bracketedPasteBuffer += endAt >= 0 ? value.slice(0, endAt) : "";
|
|
1738
1748
|
const pasted = bracketedPasteBuffer.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1739
1749
|
bracketedPaste = false;
|
|
1740
1750
|
bracketedPasteBuffer = "";
|
|
@@ -1744,21 +1754,8 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = [], hin
|
|
|
1744
1754
|
return true;
|
|
1745
1755
|
}
|
|
1746
1756
|
const chunk = value || (sequence && !sequence.startsWith("\x1b[") ? sequence : "");
|
|
1747
|
-
if (chunk)
|
|
1748
|
-
|
|
1749
|
-
if (endAt >= 0) {
|
|
1750
|
-
bracketedPasteBuffer += chunk.slice(0, endAt);
|
|
1751
|
-
const pasted = bracketedPasteBuffer.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
1752
|
-
bracketedPaste = false;
|
|
1753
|
-
bracketedPasteBuffer = "";
|
|
1754
|
-
if (pasted)
|
|
1755
|
-
insert(pasted, true);
|
|
1756
|
-
repaint();
|
|
1757
|
-
}
|
|
1758
|
-
else {
|
|
1759
|
-
bracketedPasteBuffer += chunk;
|
|
1760
|
-
}
|
|
1761
|
-
}
|
|
1757
|
+
if (chunk)
|
|
1758
|
+
bracketedPasteBuffer += chunk;
|
|
1762
1759
|
return true;
|
|
1763
1760
|
};
|
|
1764
1761
|
const markPasteBurst = () => {
|
|
@@ -1771,14 +1768,9 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = [], hin
|
|
|
1771
1768
|
}, 500);
|
|
1772
1769
|
};
|
|
1773
1770
|
const onKeypress = (str, key) => {
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
pasteBurst = false;
|
|
1778
|
-
if (pasteBurstTimer)
|
|
1779
|
-
clearTimeout(pasteBurstTimer);
|
|
1780
|
-
pasteBurstTimer = null;
|
|
1781
|
-
}
|
|
1771
|
+
// Interrupts (Ctrl+C/D/Z) must be handled BEFORE bracketed-paste capture so
|
|
1772
|
+
// that even a stuck/interrupted paste can always be escaped — otherwise the
|
|
1773
|
+
// paste handler swallows them and the field appears locked with no way out.
|
|
1782
1774
|
if (key && key.ctrl && key.name === "c") {
|
|
1783
1775
|
settle(new Error("interrupt"), true);
|
|
1784
1776
|
return;
|
|
@@ -1787,6 +1779,14 @@ export function askBottomPrompt(label = "You", prefix = "❯", history = [], hin
|
|
|
1787
1779
|
settle(new Error("eof"), true);
|
|
1788
1780
|
return;
|
|
1789
1781
|
}
|
|
1782
|
+
if (consumeBracketedPaste(str, key))
|
|
1783
|
+
return;
|
|
1784
|
+
if (pasteBurst && str && str.length === 1 && !key?.ctrl && !key?.meta) {
|
|
1785
|
+
pasteBurst = false;
|
|
1786
|
+
if (pasteBurstTimer)
|
|
1787
|
+
clearTimeout(pasteBurstTimer);
|
|
1788
|
+
pasteBurstTimer = null;
|
|
1789
|
+
}
|
|
1790
1790
|
if (key && key.ctrl && key.name === "a") {
|
|
1791
1791
|
cursor = 0;
|
|
1792
1792
|
repaint();
|