@wrongstack/tui 0.10.2 → 0.10.3

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/index.js CHANGED
@@ -35,6 +35,8 @@ var theme = Object.freeze({
35
35
  diffAddBg: "greenBright",
36
36
  diffDelBg: "redBright"
37
37
  });
38
+ var COMPACT_THRESHOLD = 50;
39
+ var COMFORTABLE_THRESHOLD = 90;
38
40
  function StatusBar({
39
41
  model,
40
42
  version,
@@ -58,6 +60,18 @@ function StatusBar({
58
60
  eternalStage,
59
61
  goalSummary
60
62
  }) {
63
+ const { stdout } = useStdout();
64
+ const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
65
+ useEffect(() => {
66
+ const handleResize = () => setTermWidth(stdout?.columns ?? 90);
67
+ handleResize();
68
+ process.stdout.on("resize", handleResize);
69
+ return () => {
70
+ process.stdout.off("resize", handleResize);
71
+ };
72
+ }, [stdout]);
73
+ const isCompact = termWidth < COMPACT_THRESHOLD;
74
+ const isComfortable = termWidth >= COMFORTABLE_THRESHOLD;
61
75
  const hiddenSet = new Set(hiddenItems);
62
76
  const usage = tokenCounter?.total();
63
77
  const cost = tokenCounter?.estimateCost();
@@ -77,74 +91,87 @@ function StatusBar({
77
91
  borderLeft: false,
78
92
  borderRight: false,
79
93
  children: [
80
- /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
81
- version ? /* @__PURE__ */ jsxs(Fragment, { children: [
82
- /* @__PURE__ */ jsxs(Text, { children: [
83
- /* @__PURE__ */ jsx(Text, { color: "blue", bold: true, children: "WS" }),
84
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
85
- " v",
86
- version
87
- ] })
94
+ /* @__PURE__ */ jsx(Box, { flexDirection: "row", gap: 2, children: isCompact ? (
95
+ // Ultra-compact: state · model
96
+ /* @__PURE__ */ jsxs(Fragment, { children: [
97
+ /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
98
+ "\u25CF",
99
+ stateLabel
100
+ ] }),
101
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\xB7" }),
102
+ /* @__PURE__ */ jsx(Text, { color: "magenta", children: model })
103
+ ] })
104
+ ) : (
105
+ // Full mode: version · state · model · context · tokens · cost · queue · processes · hint
106
+ /* @__PURE__ */ jsxs(Fragment, { children: [
107
+ version ? /* @__PURE__ */ jsxs(Fragment, { children: [
108
+ /* @__PURE__ */ jsxs(Text, { children: [
109
+ /* @__PURE__ */ jsx(Text, { color: "blue", bold: true, children: "WS" }),
110
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
111
+ " v",
112
+ version
113
+ ] })
114
+ ] }),
115
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" })
116
+ ] }) : null,
117
+ /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
118
+ "\u25CF ",
119
+ stateLabel
88
120
  ] }),
89
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" })
90
- ] }) : null,
91
- /* @__PURE__ */ jsxs(Text, { color: stateColor, children: [
92
- "\u25CF ",
93
- stateLabel
94
- ] }),
95
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
96
- /* @__PURE__ */ jsx(Text, { color: "magenta", children: model }),
97
- context && context.max > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
98
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
99
- /* @__PURE__ */ jsx(ContextChip, { ctx: context })
100
- ] }) : null,
101
- usage ? /* @__PURE__ */ jsxs(Fragment, { children: [
102
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
103
- /* @__PURE__ */ jsxs(Text, { children: [
104
- "\u2191",
105
- " ",
106
- /* @__PURE__ */ jsx(Text, { color: "cyan", children: fmtTok(usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0)) }),
107
- " ",
108
- "\u2193 ",
109
- /* @__PURE__ */ jsx(Text, { color: "cyan", children: fmtTok(usage.output) })
110
- ] })
111
- ] }) : null,
112
- cache2 && cache2.hitRatio > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
113
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
114
- /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
115
- "cache ",
116
- (cache2.hitRatio * 100).toFixed(0),
117
- "%"
118
- ] })
119
- ] }) : null,
120
- cost && cost.total > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
121
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
122
- /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
123
- "$",
124
- cost.total.toFixed(4)
125
- ] })
126
- ] }) : null,
127
- queueCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
128
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
129
- /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
130
- "\u231B queued: ",
131
- queueCount
132
- ] })
133
- ] }) : null,
134
- typeof processCount === "number" && processCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
135
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
136
- /* @__PURE__ */ jsxs(Text, { color: "red", children: [
137
- "\u26A1 ",
138
- processCount,
139
- " process",
140
- processCount === 1 ? "" : "es"
141
- ] })
142
- ] }) : null,
143
- hint ? /* @__PURE__ */ jsxs(Fragment, { children: [
144
121
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
145
- /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint })
146
- ] }) : null
147
- ] }),
122
+ /* @__PURE__ */ jsx(Text, { color: "magenta", children: model }),
123
+ context && context.max > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
124
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
125
+ /* @__PURE__ */ jsx(ContextChip, { ctx: context })
126
+ ] }) : null,
127
+ usage && isComfortable ? /* @__PURE__ */ jsxs(Fragment, { children: [
128
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
129
+ /* @__PURE__ */ jsxs(Text, { children: [
130
+ "\u2191",
131
+ " ",
132
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: fmtTok(usage.input + (usage.cacheRead ?? 0) + (usage.cacheWrite ?? 0)) }),
133
+ " ",
134
+ "\u2193 ",
135
+ /* @__PURE__ */ jsx(Text, { color: "cyan", children: fmtTok(usage.output) })
136
+ ] })
137
+ ] }) : null,
138
+ cache2 && cache2.hitRatio > 0 && isComfortable ? /* @__PURE__ */ jsxs(Fragment, { children: [
139
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
140
+ /* @__PURE__ */ jsxs(Text, { dimColor: true, children: [
141
+ "cache ",
142
+ (cache2.hitRatio * 100).toFixed(0),
143
+ "%"
144
+ ] })
145
+ ] }) : null,
146
+ cost && cost.total > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
147
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
148
+ /* @__PURE__ */ jsxs(Text, { color: "yellow", children: [
149
+ "$",
150
+ cost.total.toFixed(4)
151
+ ] })
152
+ ] }) : null,
153
+ queueCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
154
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
155
+ /* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
156
+ "\u231B queued: ",
157
+ queueCount
158
+ ] })
159
+ ] }) : null,
160
+ typeof processCount === "number" && processCount > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
161
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
162
+ /* @__PURE__ */ jsxs(Text, { color: "red", children: [
163
+ "\u26A1 ",
164
+ processCount,
165
+ " process",
166
+ processCount === 1 ? "" : "es"
167
+ ] })
168
+ ] }) : null,
169
+ hint ? /* @__PURE__ */ jsxs(Fragment, { children: [
170
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2502" }),
171
+ /* @__PURE__ */ jsx(Text, { dimColor: true, children: hint })
172
+ ] }) : null
173
+ ] })
174
+ ) }),
148
175
  hasSecondLine ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 2, children: [
149
176
  yolo ? /* @__PURE__ */ jsx(Text, { color: "red", bold: true, children: "\u26A0 YOLO" }) : null,
150
177
  autonomy && autonomy !== "off" ? /* @__PURE__ */ jsxs(Fragment, { children: [
@@ -1029,8 +1056,19 @@ function highlight(path3, _query) {
1029
1056
  return path3;
1030
1057
  }
1031
1058
  function FleetPanel({ entries, totalCost, collabSession }) {
1059
+ const { stdout } = useStdout();
1060
+ const [termWidth, setTermWidth] = useState(stdout?.columns ?? 90);
1061
+ useEffect(() => {
1062
+ const handleResize = () => setTermWidth(stdout?.columns ?? 90);
1063
+ handleResize();
1064
+ process.stdout.on("resize", handleResize);
1065
+ return () => {
1066
+ process.stdout.off("resize", handleResize);
1067
+ };
1068
+ }, [stdout]);
1032
1069
  const list = Object.values(entries);
1033
1070
  if (list.length === 0 && !collabSession) return null;
1071
+ const nameMaxLen = Math.max(6, Math.min(14, termWidth - 30));
1034
1072
  const leader = list.find((e) => e.id === "leader");
1035
1073
  const subagents = list.filter((e) => e.id !== "leader");
1036
1074
  const running = subagents.filter((e) => e.status === "running");
@@ -1050,16 +1088,16 @@ function FleetPanel({ entries, totalCost, collabSession }) {
1050
1088
  ] }),
1051
1089
  hasCollab && leader ? /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
1052
1090
  /* @__PURE__ */ jsx(Text, { color: "yellow", children: "\u25CF" }),
1053
- /* @__PURE__ */ jsx(Text, { children: leader.name.slice(0, 14).padEnd(14) }),
1091
+ /* @__PURE__ */ jsx(Text, { children: leader.name.slice(0, nameMaxLen) }),
1054
1092
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2192" }),
1055
1093
  /* @__PURE__ */ jsx(Text, { color: "yellow", children: leaderTool })
1056
1094
  ] }) : null,
1057
1095
  shown.map((entry) => {
1058
- const name = entry.name && entry.name !== entry.id ? entry.name : entry.id.slice(0, 8);
1096
+ const name = entry.name && entry.name !== entry.id ? entry.name : entry.id.slice(0, nameMaxLen);
1059
1097
  const tool = entry.currentTool?.name ?? "\u2014";
1060
1098
  return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 1, children: [
1061
1099
  /* @__PURE__ */ jsx(Text, { color: "green", children: "\u25CF" }),
1062
- /* @__PURE__ */ jsx(Text, { children: name.slice(0, 14).padEnd(14) }),
1100
+ /* @__PURE__ */ jsx(Text, { children: name.slice(0, nameMaxLen) }),
1063
1101
  /* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2192" }),
1064
1102
  /* @__PURE__ */ jsx(Text, { color: "cyan", children: tool })
1065
1103
  ] }, entry.id);
@@ -1069,7 +1107,7 @@ function FleetPanel({ entries, totalCost, collabSession }) {
1069
1107
  "+",
1070
1108
  overflow,
1071
1109
  ": ",
1072
- running[3]?.name?.slice(0, 12) ?? "agent",
1110
+ running[3]?.name?.slice(0, nameMaxLen - 2) ?? "agent",
1073
1111
  "\u2026"
1074
1112
  ] }) : null
1075
1113
  ] });
@@ -1631,6 +1669,14 @@ function parseAlign(sep2) {
1631
1669
  if (right) return "right";
1632
1670
  return "left";
1633
1671
  }
1672
+ function parseSeparatorWidths(sepCells) {
1673
+ return sepCells.map((cell) => {
1674
+ const trimmed = cell.trim();
1675
+ const dashes = trimmed.replace(/:/g, "");
1676
+ if (/^-+$/.test(dashes)) return dashes.length;
1677
+ return null;
1678
+ });
1679
+ }
1634
1680
  function renderTable(tableLines, maxWidth) {
1635
1681
  const header = parseCells(tableLines[0] ?? "");
1636
1682
  const sepCells = parseCells(tableLines[1] ?? "");
@@ -1644,7 +1690,8 @@ function renderTable(tableLines, maxWidth) {
1644
1690
  while (row.length < cols) row.push("");
1645
1691
  row.length = cols;
1646
1692
  }
1647
- const widths = computeWidths([header, ...dataRows], cols, maxWidth);
1693
+ const sepWidths = parseSeparatorWidths(sepCells);
1694
+ const widths = computeWidths([header, ...dataRows], cols, maxWidth, sepWidths);
1648
1695
  const lines = [];
1649
1696
  lines.push(border("\u250C", "\u252C", "\u2510", widths));
1650
1697
  lines.push(...renderRow(header, widths, aligns));
@@ -1655,7 +1702,7 @@ function renderTable(tableLines, maxWidth) {
1655
1702
  lines.push(border("\u2514", "\u2534", "\u2518", widths));
1656
1703
  return lines.join("\n");
1657
1704
  }
1658
- function computeWidths(allRows, cols, maxWidth) {
1705
+ function computeWidths(allRows, cols, maxWidth, sepWidths) {
1659
1706
  const overhead = 3 * cols + 1;
1660
1707
  const avail = Math.max(cols * MIN_COL_WIDTH, maxWidth - overhead);
1661
1708
  const natural = new Array(cols).fill(0);
@@ -1663,9 +1710,16 @@ function computeWidths(allRows, cols, maxWidth) {
1663
1710
  for (let c = 0; c < cols; c++) {
1664
1711
  const cell = row[c] ?? "";
1665
1712
  const w = longestWord(cell);
1666
- const total = cell.length;
1667
- natural[c] = Math.max(natural[c], total);
1668
- if (w > natural[c]) natural[c] = Math.min(total + 1, w);
1713
+ const total = strWidth(cell);
1714
+ natural[c] = Math.max(natural[c], w, total);
1715
+ }
1716
+ }
1717
+ if (sepWidths) {
1718
+ for (let c = 0; c < cols && c < sepWidths.length; c++) {
1719
+ const sepW = sepWidths[c];
1720
+ if (sepW != null) {
1721
+ natural[c] = Math.max(natural[c], sepW);
1722
+ }
1669
1723
  }
1670
1724
  }
1671
1725
  const sumNatural = natural.reduce((s2, n) => s2 + n, 0);
@@ -1689,9 +1743,51 @@ function computeWidths(allRows, cols, maxWidth) {
1689
1743
  return widths;
1690
1744
  }
1691
1745
  var MIN_COL_WIDTH = 4;
1746
+ function strWidth(s2) {
1747
+ let width = 0;
1748
+ for (const cp of s2) {
1749
+ const code = cp.codePointAt(0);
1750
+ if (code < 32 || code >= 127 && code < 160) {
1751
+ continue;
1752
+ }
1753
+ if (code >= 126976 || // Supplementary Pictographs (U+1F000-U+1FFFF)
1754
+ code >= 9728 && code <= 10175 || // Miscellaneous Symbols, Dingbats
1755
+ code >= 8960 && code <= 9215 || // Miscellaneous Technical
1756
+ code >= 11088 && code <= 11093 || // Stars and similar
1757
+ code >= 10548 && code <= 10549 || // Arrow forms
1758
+ code >= 8592 && code <= 8703 || // Arrows
1759
+ code >= 9632 && code <= 9727 || // Geometric Shapes
1760
+ code >= 9664 && code <= 9726 || // More Geometric Shapes (includes ▶)
1761
+ code >= 9984 && code <= 10175) {
1762
+ width += 2;
1763
+ continue;
1764
+ }
1765
+ if (code >= 4352 && code <= 4447 || // Hangul Jamo
1766
+ code === 9001 || // LEFT-POINTING ANGLE BRACKET
1767
+ code === 9002 || // RIGHT-POINTING ANGLE BRACKET
1768
+ code >= 11904 && code <= 12350 || // CJK Radicals Supplement
1769
+ code >= 12352 && code <= 42191 || // Hiragana, Katakana, CJK
1770
+ code >= 44032 && code <= 55203 || // Hangul Syllables
1771
+ code >= 63744 && code <= 64249 || // CJK Compatibility Ideographs
1772
+ code >= 65040 && code <= 65055 || // Vertical forms
1773
+ code >= 65072 && code <= 65135 || // CJK Compatibility Forms
1774
+ code >= 65280 && code <= 65376 || // Fullwidth Forms
1775
+ code >= 65504 && code <= 65510 || // Halfwidth and Fullwidth Forms
1776
+ code >= 131072 && code <= 196605 || // CJK Extension B+
1777
+ code >= 196608 && code <= 262141) {
1778
+ width += 2;
1779
+ continue;
1780
+ }
1781
+ width += 1;
1782
+ }
1783
+ return width;
1784
+ }
1692
1785
  function longestWord(s2) {
1693
1786
  let max = 0;
1694
- for (const w of s2.split(/\s+/)) if (w.length > max) max = w.length;
1787
+ for (const w of s2.split(/\s+/)) {
1788
+ const visualWidth = strWidth(w);
1789
+ if (visualWidth > max) max = visualWidth;
1790
+ }
1695
1791
  return max;
1696
1792
  }
1697
1793
  function border(left, mid, right, widths) {
@@ -1713,43 +1809,86 @@ function renderRow(cells, widths, aligns) {
1713
1809
  return out;
1714
1810
  }
1715
1811
  function wrapCell(text, width) {
1716
- if (text.length <= width) return [text];
1812
+ if (strWidth(text) <= width) return [text];
1717
1813
  const out = [];
1718
1814
  const words = text.split(/(\s+)/);
1719
1815
  let cur = "";
1816
+ let curWidth = 0;
1720
1817
  for (const word of words) {
1721
1818
  if (!word) continue;
1722
- if (cur.length + word.length <= width) {
1819
+ const wordWidth = strWidth(word);
1820
+ if (curWidth + wordWidth <= width) {
1723
1821
  cur += word;
1822
+ curWidth += wordWidth;
1724
1823
  continue;
1725
1824
  }
1726
1825
  if (cur) {
1727
- out.push(cur.trimEnd());
1826
+ out.push(padVisual(cur, width));
1728
1827
  cur = "";
1828
+ curWidth = 0;
1729
1829
  }
1730
- if (word.length > width) {
1830
+ if (wordWidth > width) {
1731
1831
  let rest = word;
1732
- while (rest.length > width) {
1733
- out.push(rest.slice(0, width));
1734
- rest = rest.slice(width);
1832
+ let restWidth = wordWidth;
1833
+ while (restWidth > width) {
1834
+ let collected = "";
1835
+ let collectedWidth = 0;
1836
+ for (const cp of rest) {
1837
+ const cpWidth = strWidth(cp);
1838
+ if (collectedWidth + cpWidth > width) break;
1839
+ collected += cp;
1840
+ collectedWidth += cpWidth;
1841
+ }
1842
+ out.push(padVisual(collected, width));
1843
+ rest = rest.slice([...collected].join("").length);
1844
+ restWidth = strWidth(rest);
1735
1845
  }
1736
1846
  cur = rest;
1847
+ curWidth = strWidth(rest);
1737
1848
  } else if (!/^\s+$/.test(word)) {
1738
1849
  cur = word;
1850
+ curWidth = wordWidth;
1739
1851
  }
1740
1852
  }
1741
- if (cur) out.push(cur.trimEnd());
1853
+ if (cur) out.push(padVisual(cur, width));
1742
1854
  return out.length === 0 ? [""] : out;
1743
1855
  }
1856
+ function padVisual(text, targetWidth) {
1857
+ const w = strWidth(text);
1858
+ if (w >= targetWidth) {
1859
+ let taken = 0;
1860
+ let endIdx = 0;
1861
+ for (const cp of text) {
1862
+ const cpw = strWidth(cp);
1863
+ if (taken + cpw > targetWidth) break;
1864
+ taken += cpw;
1865
+ endIdx += [...cp].join("").length;
1866
+ }
1867
+ return text.slice(0, endIdx);
1868
+ }
1869
+ return text + " ".repeat(targetWidth - w);
1870
+ }
1744
1871
  function padCell(text, width, align) {
1745
- if (text.length >= width) return text.slice(0, width);
1746
- const pad = width - text.length;
1747
- if (align === "right") return " ".repeat(pad) + text;
1872
+ const visualLen = strWidth(text);
1873
+ let displayText = text;
1874
+ if (visualLen > width) {
1875
+ let takenWidth = 0;
1876
+ let endIdx = 0;
1877
+ for (const cp of text) {
1878
+ const cpWidth = strWidth(cp);
1879
+ if (takenWidth + cpWidth > width) break;
1880
+ takenWidth += cpWidth;
1881
+ endIdx += [...cp].join("").length;
1882
+ }
1883
+ displayText = text.slice(0, endIdx);
1884
+ }
1885
+ const pad = width - strWidth(displayText);
1886
+ if (align === "right") return " ".repeat(pad) + displayText;
1748
1887
  if (align === "center") {
1749
1888
  const l = Math.floor(pad / 2);
1750
- return " ".repeat(l) + text + " ".repeat(pad - l);
1889
+ return " ".repeat(l) + displayText + " ".repeat(pad - l);
1751
1890
  }
1752
- return text + " ".repeat(pad);
1891
+ return displayText + " ".repeat(pad);
1753
1892
  }
1754
1893
  function parseInline(text) {
1755
1894
  const tokens = [];
@@ -5760,6 +5899,12 @@ function App({
5760
5899
  }, [agent.ctx.meta]);
5761
5900
  const prevAnyOverlayOpen = useRef(false);
5762
5901
  const prevEntriesCount = useRef(0);
5902
+ const eraseLiveRegion = () => {
5903
+ try {
5904
+ process.stdout.write("\x1B[J");
5905
+ } catch {
5906
+ }
5907
+ };
5763
5908
  useEffect(() => {
5764
5909
  const anyOpenNow = state.picker.open || state.slashPicker.open || state.modelPicker.open || state.autonomyPicker.open || state.settingsPicker.open || state.confirmQueue.length > 0;
5765
5910
  const overlayClosed = prevAnyOverlayOpen.current && !anyOpenNow;
@@ -5767,10 +5912,7 @@ function App({
5767
5912
  prevAnyOverlayOpen.current = anyOpenNow;
5768
5913
  prevEntriesCount.current = state.entries.length;
5769
5914
  if (overlayClosed || newEntryCommitted) {
5770
- try {
5771
- process.stdout.write("\x1B[J");
5772
- } catch {
5773
- }
5915
+ eraseLiveRegion();
5774
5916
  }
5775
5917
  }, [
5776
5918
  state.picker.open,
@@ -5781,6 +5923,13 @@ function App({
5781
5923
  state.confirmQueue.length,
5782
5924
  state.entries.length
5783
5925
  ]);
5926
+ useEffect(() => {
5927
+ const handleResize = () => eraseLiveRegion();
5928
+ process.stdout.on("resize", handleResize);
5929
+ return () => {
5930
+ process.stdout.off("resize", handleResize);
5931
+ };
5932
+ }, []);
5784
5933
  useEffect(() => {
5785
5934
  const detected = detectAtToken(state.buffer, state.cursor);
5786
5935
  if (!detected) {