omnius 1.0.878 → 1.0.879
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/api/py-embed.js +4 -1
- package/dist/index.js +2 -2
- package/dist/library.js +126 -132
- package/dist/omni-setup-worker.js +4 -1
- package/dist/tui/native/worker.js +406 -155
- package/dist/update-worker-runtime.js +4 -1
- package/docs/DISCOVERY.json +108 -0
- package/docs/DISCOVERY.md +3 -0
- package/docs/work-orders/evidence/explicit-shell-run-views-20261018.json +212 -0
- package/docs/work-orders/evidence/explicit-shell-runs-verification-20261018.json +288 -0
- package/docs/work-orders/evidence/native-space-allocation-verification-20261017.json +177 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
import { createWriteStream } from "node:fs";
|
|
3
3
|
import { createInterface } from "node:readline";
|
|
4
4
|
import { PassThrough } from "node:stream";
|
|
5
|
-
import { CliRenderEvents as
|
|
5
|
+
import { CliRenderEvents as CliRenderEvents10, NativeSession, RGBA as RGBA3, createCliRenderer } from "@opentui/core";
|
|
6
6
|
|
|
7
7
|
// packages/cli/src/tui/native/components/frontend.ts
|
|
8
8
|
import {
|
|
9
9
|
BoxRenderable as BoxRenderable11,
|
|
10
|
-
CliRenderEvents as
|
|
10
|
+
CliRenderEvents as CliRenderEvents8,
|
|
11
11
|
EmbeddedTerminalRenderable as EmbeddedTerminalRenderable2,
|
|
12
12
|
ScrollBoxRenderable as ScrollBoxRenderable8,
|
|
13
13
|
SyntaxStyle as SyntaxStyle2,
|
|
@@ -1396,6 +1396,7 @@ var NativeBlockList = class {
|
|
|
1396
1396
|
// packages/cli/src/tui/native/components/modals.ts
|
|
1397
1397
|
import {
|
|
1398
1398
|
BoxRenderable as BoxRenderable4,
|
|
1399
|
+
CliRenderEvents as CliRenderEvents3,
|
|
1399
1400
|
InputRenderable,
|
|
1400
1401
|
ScrollBoxRenderable as ScrollBoxRenderable2,
|
|
1401
1402
|
TextareaRenderable,
|
|
@@ -1715,6 +1716,123 @@ var NativeCornerFrame = class {
|
|
|
1715
1716
|
};
|
|
1716
1717
|
};
|
|
1717
1718
|
|
|
1719
|
+
// packages/cli/src/tui/terminal-cells.ts
|
|
1720
|
+
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1721
|
+
var extendedPictographic = /\p{Extended_Pictographic}/u;
|
|
1722
|
+
var emojiPresentation = /\p{Emoji_Presentation}/u;
|
|
1723
|
+
var zeroWidthGrapheme = /^[\p{Mark}\p{Cf}\u200c\u200d\ufe0e\ufe0f]+$/u;
|
|
1724
|
+
function escapeEnd(value, start) {
|
|
1725
|
+
if (value[start] !== "\x1B") return start + 1;
|
|
1726
|
+
const kind = value[start + 1];
|
|
1727
|
+
if (kind === "[") {
|
|
1728
|
+
for (let i = start + 2; i < value.length; i++) {
|
|
1729
|
+
const code = value.charCodeAt(i);
|
|
1730
|
+
if (code >= 64 && code <= 126) return i + 1;
|
|
1731
|
+
}
|
|
1732
|
+
return value.length;
|
|
1733
|
+
}
|
|
1734
|
+
if (kind === "]") {
|
|
1735
|
+
for (let i = start + 2; i < value.length; i++) {
|
|
1736
|
+
if (value[i] === "\x07") return i + 1;
|
|
1737
|
+
if (value[i] === "\x1B" && value[i + 1] === "\\") return i + 2;
|
|
1738
|
+
}
|
|
1739
|
+
return value.length;
|
|
1740
|
+
}
|
|
1741
|
+
if (kind === "P" || kind === "X" || kind === "^" || kind === "_") {
|
|
1742
|
+
for (let i = start + 2; i < value.length; i++) {
|
|
1743
|
+
if (value[i] === "\x1B" && value[i + 1] === "\\") return i + 2;
|
|
1744
|
+
}
|
|
1745
|
+
return value.length;
|
|
1746
|
+
}
|
|
1747
|
+
return Math.min(value.length, start + 2);
|
|
1748
|
+
}
|
|
1749
|
+
function stripTerminalSequences(value) {
|
|
1750
|
+
let out = "";
|
|
1751
|
+
for (let i = 0; i < value.length; ) {
|
|
1752
|
+
if (value[i] === "\x1B") {
|
|
1753
|
+
i = escapeEnd(value, i);
|
|
1754
|
+
continue;
|
|
1755
|
+
}
|
|
1756
|
+
const code = value.charCodeAt(i);
|
|
1757
|
+
if (code >= 0 && code < 32 || code === 127) {
|
|
1758
|
+
i++;
|
|
1759
|
+
continue;
|
|
1760
|
+
}
|
|
1761
|
+
const cp = value.codePointAt(i);
|
|
1762
|
+
out += String.fromCodePoint(cp);
|
|
1763
|
+
i += cp > 65535 ? 2 : 1;
|
|
1764
|
+
}
|
|
1765
|
+
return out;
|
|
1766
|
+
}
|
|
1767
|
+
function normalizeTerminalLine(value) {
|
|
1768
|
+
return value.replace(/\r\n|\r|\n/g, " ").replace(/\t/g, " ");
|
|
1769
|
+
}
|
|
1770
|
+
function isWideCodePoint(cp) {
|
|
1771
|
+
return cp >= 4352 && cp <= 4447 || cp === 9001 || cp === 9002 || cp >= 11904 && cp <= 12350 || cp >= 12352 && cp <= 42191 || cp >= 44032 && cp <= 55203 || cp >= 63744 && cp <= 64255 || cp >= 65040 && cp <= 65049 || cp >= 65072 && cp <= 65135 || cp >= 65280 && cp <= 65376 || cp >= 65504 && cp <= 65510 || cp >= 110592 && cp <= 111359 || cp >= 131072 && cp <= 262141;
|
|
1772
|
+
}
|
|
1773
|
+
function graphemeCellWidth(value) {
|
|
1774
|
+
if (!value || zeroWidthGrapheme.test(value)) return 0;
|
|
1775
|
+
const cp = value.codePointAt(0);
|
|
1776
|
+
if (cp < 32 || cp >= 127 && cp < 160) return 0;
|
|
1777
|
+
if (emojiPresentation.test(value) || value.includes("️") || value.includes("") && extendedPictographic.test(value) || cp >= 127462 && cp <= 127487) {
|
|
1778
|
+
return 2;
|
|
1779
|
+
}
|
|
1780
|
+
return isWideCodePoint(cp) ? 2 : 1;
|
|
1781
|
+
}
|
|
1782
|
+
function plainGraphemes(value) {
|
|
1783
|
+
return Array.from(
|
|
1784
|
+
graphemes.segment(stripTerminalSequences(value)),
|
|
1785
|
+
(part) => part.segment
|
|
1786
|
+
);
|
|
1787
|
+
}
|
|
1788
|
+
function terminalCellWidth(value) {
|
|
1789
|
+
let width = 0;
|
|
1790
|
+
for (const grapheme of plainGraphemes(normalizeTerminalLine(value))) {
|
|
1791
|
+
width += graphemeCellWidth(grapheme);
|
|
1792
|
+
}
|
|
1793
|
+
return width;
|
|
1794
|
+
}
|
|
1795
|
+
|
|
1796
|
+
// packages/cli/src/tui/native/components/modal-fit.ts
|
|
1797
|
+
function nativeModalWidth(spec, columns) {
|
|
1798
|
+
const limit = Math.max(1, Math.min(spec.kind === "document" ? Infinity : 100, columns - (columns >= 12 ? 4 : 0)));
|
|
1799
|
+
const longest = (text) => {
|
|
1800
|
+
let width = 0;
|
|
1801
|
+
for (const line of text.split(/\r\n|\r|\n/)) {
|
|
1802
|
+
width = Math.max(width, terminalCellWidth(line));
|
|
1803
|
+
if (width >= limit) break;
|
|
1804
|
+
}
|
|
1805
|
+
return Math.min(limit, width);
|
|
1806
|
+
};
|
|
1807
|
+
const actions = (items = spec.actions) => (items ?? []).reduce((width, item, index) => width + longest(item.label) + (index ? 1 : 0), 0);
|
|
1808
|
+
const blockWidth = (block, depth) => {
|
|
1809
|
+
if (depth > 16) return 0;
|
|
1810
|
+
const children = (block.children ?? []).slice(0, 256).map((child) => blockWidth(child, depth + 1));
|
|
1811
|
+
return Math.min(limit, Math.max(
|
|
1812
|
+
longest(plainText(block.text)),
|
|
1813
|
+
longest(block.title ?? ""),
|
|
1814
|
+
actions(block.actions),
|
|
1815
|
+
block.kind === "row" ? children.reduce((total, width) => total + width + 1, 0) : Math.max(0, ...children)
|
|
1816
|
+
) + (block.kind === "card" ? 2 : 0));
|
|
1817
|
+
};
|
|
1818
|
+
let content = Math.max(
|
|
1819
|
+
spec.kind === "input" || spec.kind === "progress" ? 28 : 18,
|
|
1820
|
+
longest(spec.title) + actions(spec.headerActions) + (spec.headerActions?.length ? 1 : 0),
|
|
1821
|
+
longest(plainText(spec.description)),
|
|
1822
|
+
longest((spec.breadcrumbs ?? []).join(" › ")),
|
|
1823
|
+
longest(spec.validationError ?? ""),
|
|
1824
|
+
longest(spec.placeholder ?? ""),
|
|
1825
|
+
actions()
|
|
1826
|
+
);
|
|
1827
|
+
for (const item of spec.items ?? []) content = Math.max(content, longest(plainText(item.label)) + 4, Math.min(72, longest(plainText(item.description))) + 4);
|
|
1828
|
+
for (const block of (spec.blocks ?? []).slice(0, 256)) content = Math.max(content, blockWidth(block, 0));
|
|
1829
|
+
return Math.min(limit, content + 5);
|
|
1830
|
+
}
|
|
1831
|
+
function nativeModalTextRows(value, width) {
|
|
1832
|
+
if (!value) return 0;
|
|
1833
|
+
return value.split(/\r\n|\r|\n/).reduce((rows, line) => rows + Math.max(1, Math.ceil(terminalCellWidth(line) / Math.max(1, width))), 0);
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1718
1836
|
// packages/cli/src/tui/native/components/modals.ts
|
|
1719
1837
|
var NativeModalView = class {
|
|
1720
1838
|
constructor(context, spec, close2) {
|
|
@@ -1747,7 +1865,7 @@ var NativeModalView = class {
|
|
|
1747
1865
|
this.panel = new BoxRenderable4(renderer2, {
|
|
1748
1866
|
id: `modal-panel:${spec.id}`,
|
|
1749
1867
|
flexDirection: "column",
|
|
1750
|
-
width:
|
|
1868
|
+
width: nativeModalWidth(spec, renderer2.terminalWidth),
|
|
1751
1869
|
maxHeight: "94%",
|
|
1752
1870
|
border: false,
|
|
1753
1871
|
backgroundColor: colors.background,
|
|
@@ -1759,29 +1877,36 @@ var NativeModalView = class {
|
|
|
1759
1877
|
});
|
|
1760
1878
|
this.root.add(this.panel);
|
|
1761
1879
|
this.frame = new NativeCornerFrame(this.panel, colors, renderer2, this.root);
|
|
1880
|
+
this.body = new ScrollBoxRenderable2(renderer2, {
|
|
1881
|
+
id: spec.kind === "document" ? `modal-document:${spec.id}` : `modal-body:${spec.id}`,
|
|
1882
|
+
width: "100%",
|
|
1883
|
+
height: 1,
|
|
1884
|
+
minHeight: 1,
|
|
1885
|
+
flexShrink: 0,
|
|
1886
|
+
scrollY: true,
|
|
1887
|
+
scrollX: false,
|
|
1888
|
+
viewportCulling: true,
|
|
1889
|
+
horizontalScrollbarOptions: { visible: false },
|
|
1890
|
+
contentOptions: { flexDirection: "column", minHeight: 0 }
|
|
1891
|
+
});
|
|
1892
|
+
this.panel.add(this.body);
|
|
1893
|
+
styleNativeScrollbars(this.body, colors);
|
|
1762
1894
|
this.breadcrumb = this.addText(`modal-breadcrumb:${spec.id}`);
|
|
1763
1895
|
const header = new BoxRenderable4(renderer2, { id: `modal-heading:${spec.id}`, width: "100%", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
1764
1896
|
this.heading = new TextRenderable3(renderer2, { id: `modal-title:${spec.id}`, content: "", width: 0, flexGrow: 1, flexShrink: 1, wrapMode: "word", fg: colors.foreground });
|
|
1765
|
-
this.
|
|
1897
|
+
this.heading.maxHeight = 2;
|
|
1898
|
+
this.headerActions = new BoxRenderable4(renderer2, { id: `modal-header-actions:${spec.id}`, flexDirection: "row", gap: 1, flexShrink: 1, minWidth: 0, maxWidth: "60%" });
|
|
1766
1899
|
header.add(this.heading);
|
|
1767
1900
|
header.add(this.headerActions);
|
|
1768
|
-
this.panel.add(header);
|
|
1901
|
+
this.panel.add(header, 0);
|
|
1769
1902
|
this.description = this.addText(`modal-description:${spec.id}`);
|
|
1770
1903
|
if (spec.kind === "select") this.buildSelect();
|
|
1771
1904
|
else if (spec.kind === "input") this.buildInput();
|
|
1772
1905
|
else if (spec.kind === "document") {
|
|
1773
|
-
this.document =
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
scrollY: true,
|
|
1778
|
-
scrollX: false,
|
|
1779
|
-
viewportCulling: true,
|
|
1780
|
-
contentOptions: { flexDirection: "column" }
|
|
1781
|
-
});
|
|
1782
|
-
styleNativeScrollbars(this.document, colors);
|
|
1783
|
-
this.blocks = new NativeBlockList(this.modalContext(), this.document);
|
|
1784
|
-
this.panel.add(this.document);
|
|
1906
|
+
this.document = this.body;
|
|
1907
|
+
const documentBlocks = new BoxRenderable4(renderer2, { id: `modal-document-blocks:${spec.id}`, width: "100%", flexDirection: "column", flexShrink: 0 });
|
|
1908
|
+
this.body.add(documentBlocks);
|
|
1909
|
+
this.blocks = new NativeBlockList(this.modalContext(), documentBlocks);
|
|
1785
1910
|
} else {
|
|
1786
1911
|
this.progress = new TextRenderable3(renderer2, {
|
|
1787
1912
|
id: `modal-progress:${spec.id}`,
|
|
@@ -1794,16 +1919,21 @@ var NativeModalView = class {
|
|
|
1794
1919
|
wrapMode: "none",
|
|
1795
1920
|
selectable: false
|
|
1796
1921
|
});
|
|
1797
|
-
this.
|
|
1922
|
+
this.body.add(this.progress);
|
|
1798
1923
|
const progressBlocks = new BoxRenderable4(renderer2, { id: `modal-progress-blocks:${spec.id}`, flexDirection: "column", width: "100%" });
|
|
1799
|
-
this.
|
|
1924
|
+
this.body.add(progressBlocks);
|
|
1800
1925
|
this.blocks = new NativeBlockList(this.modalContext(), progressBlocks);
|
|
1801
1926
|
}
|
|
1802
1927
|
this.error = this.addText(`modal-error:${spec.id}`);
|
|
1803
|
-
this.hints = this.addText(`modal-hints:${spec.id}
|
|
1804
|
-
this.
|
|
1928
|
+
this.hints = this.addText(`modal-hints:${spec.id}`, this.panel);
|
|
1929
|
+
this.hints.maxHeight = 2;
|
|
1930
|
+
this.actions = new BoxRenderable4(renderer2, { id: `modal-actions:${spec.id}`, flexDirection: "row", flexWrap: "wrap", flexShrink: 0, gap: 1, width: "100%", marginTop: 0 });
|
|
1805
1931
|
this.panel.add(this.actions);
|
|
1806
1932
|
this.update(spec);
|
|
1933
|
+
renderer2.on(CliRenderEvents3.RESIZE, this.fit);
|
|
1934
|
+
this.panel.on("resize", this.fit);
|
|
1935
|
+
for (const child of this.panel.getChildren()) child.on("resize", this.fit);
|
|
1936
|
+
this.body.content.on("resize", this.fit);
|
|
1807
1937
|
}
|
|
1808
1938
|
context;
|
|
1809
1939
|
close;
|
|
@@ -1822,6 +1952,8 @@ var NativeModalView = class {
|
|
|
1822
1952
|
editor;
|
|
1823
1953
|
secretMask;
|
|
1824
1954
|
select;
|
|
1955
|
+
choiceDescription;
|
|
1956
|
+
body;
|
|
1825
1957
|
document;
|
|
1826
1958
|
blocks;
|
|
1827
1959
|
progress;
|
|
@@ -1830,9 +1962,14 @@ var NativeModalView = class {
|
|
|
1830
1962
|
changing = false;
|
|
1831
1963
|
actionsSignature = "";
|
|
1832
1964
|
headerActionsSignature = "";
|
|
1833
|
-
|
|
1965
|
+
sizing = false;
|
|
1966
|
+
sizeSignature = "";
|
|
1967
|
+
optionSignature = "";
|
|
1968
|
+
disposed = false;
|
|
1969
|
+
revealFocused = false;
|
|
1970
|
+
addText(id, parent = this.body) {
|
|
1834
1971
|
const text = new TextRenderable3(this.context.renderer, { id, content: "", width: "100%", wrapMode: "word", flexShrink: 0, fg: this.context.colors.foreground, selectable: true });
|
|
1835
|
-
|
|
1972
|
+
parent.add(text);
|
|
1836
1973
|
return text;
|
|
1837
1974
|
}
|
|
1838
1975
|
replaceActions(container, actions, prefix = "") {
|
|
@@ -1841,6 +1978,10 @@ var NativeModalView = class {
|
|
|
1841
1978
|
const button = new TextRenderable3(this.context.renderer, {
|
|
1842
1979
|
id: `modal-action:${this.spec.id}:${prefix}${action.id}`,
|
|
1843
1980
|
content: plainText(action.label),
|
|
1981
|
+
minWidth: 0,
|
|
1982
|
+
flexShrink: 1,
|
|
1983
|
+
maxHeight: 2,
|
|
1984
|
+
wrapMode: "word",
|
|
1844
1985
|
fg: this.context.colors.foreground,
|
|
1845
1986
|
bg: this.context.colors.background,
|
|
1846
1987
|
attributes: action.disabled ? 2 : action.active ? 1 : 0,
|
|
@@ -1882,7 +2023,7 @@ var NativeModalView = class {
|
|
|
1882
2023
|
}
|
|
1883
2024
|
});
|
|
1884
2025
|
this.filter = this.spec.filter ?? "";
|
|
1885
|
-
this.
|
|
2026
|
+
this.body.add(this.filterInput);
|
|
1886
2027
|
this.select = new NativeSelectRenderable(renderer2, {
|
|
1887
2028
|
id: `modal-select:${this.spec.id}`,
|
|
1888
2029
|
width: "100%",
|
|
@@ -1901,10 +2042,16 @@ var NativeModalView = class {
|
|
|
1901
2042
|
});
|
|
1902
2043
|
this.select.onActivate = () => this.confirm();
|
|
1903
2044
|
this.select.on("selectionChanged", () => {
|
|
1904
|
-
if (!this.changing)
|
|
2045
|
+
if (!this.changing) {
|
|
2046
|
+
this.fit();
|
|
2047
|
+
this.body.scrollChildIntoView(this.select.id);
|
|
2048
|
+
this.emitAction("focus");
|
|
2049
|
+
}
|
|
1905
2050
|
});
|
|
1906
2051
|
this.select.on("itemSelected", () => this.confirm());
|
|
1907
|
-
this.
|
|
2052
|
+
this.body.add(this.select);
|
|
2053
|
+
this.choiceDescription = this.addText(`modal-choice-description:${this.spec.id}`);
|
|
2054
|
+
this.choiceDescription.visible = false;
|
|
1908
2055
|
}
|
|
1909
2056
|
buildInput() {
|
|
1910
2057
|
const { renderer: renderer2, colors } = this.context;
|
|
@@ -1921,6 +2068,7 @@ var NativeModalView = class {
|
|
|
1921
2068
|
onContentChange: () => {
|
|
1922
2069
|
if (!this.editor || this.changing) return;
|
|
1923
2070
|
this.refreshMask();
|
|
2071
|
+
if (!this.spec.secret) this.fit();
|
|
1924
2072
|
if (!this.spec.secret) this.emitAction("change", this.editor.plainText);
|
|
1925
2073
|
},
|
|
1926
2074
|
onSubmit: () => this.confirm()
|
|
@@ -1935,8 +2083,11 @@ var NativeModalView = class {
|
|
|
1935
2083
|
if (this.spec.secret) {
|
|
1936
2084
|
this.secretMask = this.addText(`modal-secret:${this.spec.id}`);
|
|
1937
2085
|
this.secretMask.selectable = false;
|
|
2086
|
+
this.secretMask.height = 1;
|
|
2087
|
+
this.secretMask.wrapMode = "none";
|
|
2088
|
+
this.secretMask.truncate = true;
|
|
1938
2089
|
this.editor.showCursor = false;
|
|
1939
|
-
} else this.
|
|
2090
|
+
} else this.body.add(this.editor);
|
|
1940
2091
|
}
|
|
1941
2092
|
refreshMask() {
|
|
1942
2093
|
if (this.secretMask && this.editor) this.secretMask.content = "•".repeat(Array.from(this.editor.plainText).length);
|
|
@@ -1977,6 +2128,7 @@ var NativeModalView = class {
|
|
|
1977
2128
|
} finally {
|
|
1978
2129
|
this.changing = false;
|
|
1979
2130
|
}
|
|
2131
|
+
this.fit();
|
|
1980
2132
|
this.applyTheme();
|
|
1981
2133
|
}
|
|
1982
2134
|
refreshOptions(selectedIndex) {
|
|
@@ -1990,12 +2142,88 @@ var NativeModalView = class {
|
|
|
1990
2142
|
value: { key: item.key, index, disabled: item.disabled || item.heading }
|
|
1991
2143
|
}));
|
|
1992
2144
|
this.select.showDescription = this.filtered.some(({ item }) => Boolean(plainText(item.description)));
|
|
1993
|
-
|
|
1994
|
-
this.select.height = Math.max(1, Math.min(Math.max(3, Math.floor(this.context.renderer.terminalHeight * 0.55)), this.filtered.length * rowCount));
|
|
2145
|
+
this.optionSignature = "";
|
|
1995
2146
|
const preferred = selectedIndex !== void 0 ? this.filtered.findIndex((entry) => entry.index === selectedIndex) : this.filtered.findIndex((entry) => entry.item.key === previousKey);
|
|
1996
2147
|
const firstEnabled = this.filtered.findIndex((entry) => !entry.item.disabled && !entry.item.heading);
|
|
1997
2148
|
this.select.setSelectedIndex(preferred >= 0 && !this.filtered[preferred].item.disabled && !this.filtered[preferred].item.heading ? preferred : Math.max(0, firstEnabled));
|
|
1998
|
-
|
|
2149
|
+
this.fit();
|
|
2150
|
+
}
|
|
2151
|
+
/** Geometry writes are idempotent: native resize observes wrapping without
|
|
2152
|
+
* creating a render loop through unchanged flex/min/max setters. */
|
|
2153
|
+
fit = () => {
|
|
2154
|
+
if (this.disposed || this.sizing || !this.actions) return;
|
|
2155
|
+
this.sizing = true;
|
|
2156
|
+
const wasChanging = this.changing;
|
|
2157
|
+
this.changing = true;
|
|
2158
|
+
try {
|
|
2159
|
+
const renderer2 = this.context.renderer, spec = this.spec;
|
|
2160
|
+
const width = nativeModalWidth({ ...spec, validationError: this.error.visible ? this.error.plainText : void 0 }, renderer2.terminalWidth), padding = width >= 8 ? 2 : 0;
|
|
2161
|
+
const inner = Math.max(1, width - padding * 2), bodyWidth = Math.max(1, inner - 1), maximum = Math.max(1, renderer2.terminalHeight - (renderer2.terminalHeight >= 8 ? 2 : 0));
|
|
2162
|
+
const signature = `${width}:${maximum}:${padding}`;
|
|
2163
|
+
if (signature !== this.sizeSignature) {
|
|
2164
|
+
this.sizeSignature = signature;
|
|
2165
|
+
this.panel.width = width;
|
|
2166
|
+
this.panel.maxHeight = maximum;
|
|
2167
|
+
this.panel.paddingX = padding;
|
|
2168
|
+
}
|
|
2169
|
+
if (this.select) {
|
|
2170
|
+
const descriptions = this.filtered.map(({ item }) => plainText(item.description));
|
|
2171
|
+
const long = descriptions.map((value) => /[\r\n]/.test(value) || nativeModalTextRows(value, Math.max(1, bodyWidth - 3)) > 1);
|
|
2172
|
+
const options = this.filtered.map(({ item, index: index2 }, position) => ({
|
|
2173
|
+
name: `${item.heading ? "── " : ""}${plainText(item.label)}`,
|
|
2174
|
+
description: long[position] ? "" : descriptions[position],
|
|
2175
|
+
value: { key: item.key, index: index2, disabled: item.disabled || item.heading }
|
|
2176
|
+
}));
|
|
2177
|
+
const optionSignature = JSON.stringify(options);
|
|
2178
|
+
if (optionSignature !== this.optionSignature) {
|
|
2179
|
+
this.optionSignature = optionSignature;
|
|
2180
|
+
const index2 = this.select.getSelectedIndex();
|
|
2181
|
+
this.select.options = options;
|
|
2182
|
+
this.select.setSelectedIndex(index2);
|
|
2183
|
+
}
|
|
2184
|
+
const show = options.some((item) => Boolean(item.description));
|
|
2185
|
+
if (this.select.showDescription !== show) this.select.showDescription = show;
|
|
2186
|
+
const index = this.select.getSelectedIndex(), detail = long[index] ? descriptions[index] ?? "" : "";
|
|
2187
|
+
if (this.choiceDescription.plainText !== detail) this.choiceDescription.content = detail;
|
|
2188
|
+
this.choiceDescription.visible = Boolean(detail);
|
|
2189
|
+
}
|
|
2190
|
+
const textRows = (node, text, availableWidth = bodyWidth) => node.visible ? node.width === availableWidth && node.height > 0 ? node.height : nativeModalTextRows(text, availableWidth) : 0;
|
|
2191
|
+
const headerActions = (spec.headerActions ?? []).reduce((total, action) => total + terminalCellWidth(plainText(action.label)) + 1, 0);
|
|
2192
|
+
const headingRows = Math.min(2, nativeModalTextRows(spec.title, Math.max(1, inner - Math.min(Math.floor(inner * 0.6), headerActions))));
|
|
2193
|
+
let fallbackActions = 0, rowWidth = 0, rowHeight = 0;
|
|
2194
|
+
for (const action of spec.actions ?? []) {
|
|
2195
|
+
const cells = Math.max(1, terminalCellWidth(plainText(action.label))), childWidth = Math.min(inner, cells);
|
|
2196
|
+
if (rowWidth && rowWidth + 1 + childWidth > inner) {
|
|
2197
|
+
fallbackActions += rowHeight + 1;
|
|
2198
|
+
rowWidth = 0;
|
|
2199
|
+
rowHeight = 0;
|
|
2200
|
+
}
|
|
2201
|
+
rowWidth += (rowWidth ? 1 : 0) + childWidth;
|
|
2202
|
+
rowHeight = Math.max(rowHeight, Math.min(2, Math.ceil(cells / inner)));
|
|
2203
|
+
}
|
|
2204
|
+
fallbackActions += rowHeight;
|
|
2205
|
+
const actionRows = this.actions.visible && this.actions.width === inner && this.actions.height > 0 ? this.actions.height : fallbackActions;
|
|
2206
|
+
const header = this.heading.parent;
|
|
2207
|
+
const headerRows = header.width === inner && header.height > 0 ? header.height : Math.max(1, headingRows);
|
|
2208
|
+
const chrome = 2 + headerRows + Math.min(2, textRows(this.hints, this.hints.plainText, inner)) + actionRows;
|
|
2209
|
+
const available = Math.max(1, maximum - chrome);
|
|
2210
|
+
if (this.select) {
|
|
2211
|
+
const details = textRows(this.breadcrumb, (spec.breadcrumbs ?? []).join(" › ")) + textRows(this.description, plainText(spec.description)) + textRows(this.error, spec.validationError ?? "") + textRows(this.choiceDescription, this.choiceDescription.plainText) + 1;
|
|
2212
|
+
this.select.height = Math.max(1, Math.min(Math.max(1, available - Math.min(details, Math.floor(available / 2))), this.filtered.length * (this.select.showDescription ? 2 : 1)));
|
|
2213
|
+
} else if (this.editor && spec.multiline && !spec.secret) {
|
|
2214
|
+
this.editor.height = Math.max(1, Math.min(available, Math.max(3, nativeModalTextRows(this.editor.plainText, bodyWidth))));
|
|
2215
|
+
}
|
|
2216
|
+
this.body.height = Math.max(1, Math.min(available, this.body.content.height || 1));
|
|
2217
|
+
const focused = renderer2.currentFocusedRenderable;
|
|
2218
|
+
if (this.revealFocused && focused && focused.width > 0 && this.body.viewport.width > 0) {
|
|
2219
|
+
this.revealFocused = false;
|
|
2220
|
+
this.body.scrollChildIntoView(focused.id);
|
|
2221
|
+
}
|
|
2222
|
+
} finally {
|
|
2223
|
+
this.changing = wasChanging;
|
|
2224
|
+
this.sizing = false;
|
|
2225
|
+
}
|
|
2226
|
+
};
|
|
1999
2227
|
current() {
|
|
2000
2228
|
return this.filtered[this.select?.getSelectedIndex() ?? -1];
|
|
2001
2229
|
}
|
|
@@ -2036,10 +2264,12 @@ var NativeModalView = class {
|
|
|
2036
2264
|
}
|
|
2037
2265
|
focus() {
|
|
2038
2266
|
if (this.frame.closing) return;
|
|
2267
|
+
this.revealFocused = true;
|
|
2039
2268
|
if (this.filterInput) this.filterInput.focus();
|
|
2040
2269
|
else if (this.editor && !this.spec.secret) this.editor.focus();
|
|
2041
2270
|
else if (this.document) this.document.focus();
|
|
2042
2271
|
else this.panel.focus();
|
|
2272
|
+
this.fit();
|
|
2043
2273
|
}
|
|
2044
2274
|
nextControl(direction) {
|
|
2045
2275
|
const controls = [];
|
|
@@ -2057,7 +2287,7 @@ var NativeModalView = class {
|
|
|
2057
2287
|
const current = focused ? controls.indexOf(focused) : -1;
|
|
2058
2288
|
const next = controls[current < 0 ? direction > 0 ? 0 : controls.length - 1 : (current + direction + controls.length) % controls.length];
|
|
2059
2289
|
next.focus();
|
|
2060
|
-
this.
|
|
2290
|
+
this.body.scrollChildIntoView(next.id);
|
|
2061
2291
|
}
|
|
2062
2292
|
handleKey(key) {
|
|
2063
2293
|
const consume = () => {
|
|
@@ -2123,8 +2353,8 @@ var NativeModalView = class {
|
|
|
2123
2353
|
this.confirm();
|
|
2124
2354
|
return consume();
|
|
2125
2355
|
}
|
|
2126
|
-
if (
|
|
2127
|
-
this.
|
|
2356
|
+
if (key.name === "pageup" || key.name === "pagedown" || key.name === "up" || key.name === "down") {
|
|
2357
|
+
this.body.scrollBy(key.name === "up" ? -1 : key.name === "down" ? 1 : key.name === "pageup" ? -1 : 1, key.name.startsWith("page") ? "viewport" : "absolute");
|
|
2128
2358
|
return consume();
|
|
2129
2359
|
}
|
|
2130
2360
|
if (key.sequence.length === 1 && !key.ctrl && !key.meta) {
|
|
@@ -2159,6 +2389,7 @@ var NativeModalView = class {
|
|
|
2159
2389
|
if (Buffer.byteLength(text, "utf8") + Buffer.byteLength(current, "utf8") <= budget) return false;
|
|
2160
2390
|
this.error.content = `Input exceeds the ${budget.toLocaleString()} byte limit.`;
|
|
2161
2391
|
this.error.visible = true;
|
|
2392
|
+
this.fit();
|
|
2162
2393
|
return true;
|
|
2163
2394
|
}
|
|
2164
2395
|
applyTheme() {
|
|
@@ -2168,6 +2399,7 @@ var NativeModalView = class {
|
|
|
2168
2399
|
this.heading.fg = colors.foreground;
|
|
2169
2400
|
this.heading.attributes = 1;
|
|
2170
2401
|
this.description.fg = colors.foreground;
|
|
2402
|
+
if (this.choiceDescription) this.choiceDescription.fg = colors.dim;
|
|
2171
2403
|
this.breadcrumb.fg = colors.dim;
|
|
2172
2404
|
this.breadcrumb.attributes = 2;
|
|
2173
2405
|
this.error.fg = colors.foreground;
|
|
@@ -2178,7 +2410,7 @@ var NativeModalView = class {
|
|
|
2178
2410
|
this.progress.fg = colors.foreground;
|
|
2179
2411
|
this.progress.bg = colors.background;
|
|
2180
2412
|
}
|
|
2181
|
-
|
|
2413
|
+
styleNativeScrollbars(this.body, colors);
|
|
2182
2414
|
if (this.select) {
|
|
2183
2415
|
this.select.backgroundColor = this.select.focusedBackgroundColor = colors.background;
|
|
2184
2416
|
this.select.textColor = this.select.focusedTextColor = colors.foreground;
|
|
@@ -2203,6 +2435,8 @@ var NativeModalView = class {
|
|
|
2203
2435
|
this.blocks?.applyTheme();
|
|
2204
2436
|
}
|
|
2205
2437
|
destroy() {
|
|
2438
|
+
this.disposed = true;
|
|
2439
|
+
this.context.renderer.off(CliRenderEvents3.RESIZE, this.fit);
|
|
2206
2440
|
this.frame.destroy();
|
|
2207
2441
|
this.blocks?.destroy();
|
|
2208
2442
|
if (this.spec.secret) this.editor?.destroy();
|
|
@@ -2343,90 +2577,13 @@ function deviceHistoryGraph(samples, field, width) {
|
|
|
2343
2577
|
// packages/cli/src/tui/native/components/task-notes.ts
|
|
2344
2578
|
import {
|
|
2345
2579
|
BoxRenderable as BoxRenderable5,
|
|
2346
|
-
CliRenderEvents as
|
|
2580
|
+
CliRenderEvents as CliRenderEvents4,
|
|
2347
2581
|
RenderableEvents as RenderableEvents3,
|
|
2348
2582
|
ScrollBoxRenderable as ScrollBoxRenderable3,
|
|
2349
2583
|
TextAttributes as TextAttributes5,
|
|
2350
2584
|
TextRenderable as TextRenderable4
|
|
2351
2585
|
} from "@opentui/core";
|
|
2352
2586
|
|
|
2353
|
-
// packages/cli/src/tui/terminal-cells.ts
|
|
2354
|
-
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2355
|
-
var extendedPictographic = /\p{Extended_Pictographic}/u;
|
|
2356
|
-
var emojiPresentation = /\p{Emoji_Presentation}/u;
|
|
2357
|
-
var zeroWidthGrapheme = /^[\p{Mark}\p{Cf}\u200c\u200d\ufe0e\ufe0f]+$/u;
|
|
2358
|
-
function escapeEnd(value, start) {
|
|
2359
|
-
if (value[start] !== "\x1B") return start + 1;
|
|
2360
|
-
const kind = value[start + 1];
|
|
2361
|
-
if (kind === "[") {
|
|
2362
|
-
for (let i = start + 2; i < value.length; i++) {
|
|
2363
|
-
const code = value.charCodeAt(i);
|
|
2364
|
-
if (code >= 64 && code <= 126) return i + 1;
|
|
2365
|
-
}
|
|
2366
|
-
return value.length;
|
|
2367
|
-
}
|
|
2368
|
-
if (kind === "]") {
|
|
2369
|
-
for (let i = start + 2; i < value.length; i++) {
|
|
2370
|
-
if (value[i] === "\x07") return i + 1;
|
|
2371
|
-
if (value[i] === "\x1B" && value[i + 1] === "\\") return i + 2;
|
|
2372
|
-
}
|
|
2373
|
-
return value.length;
|
|
2374
|
-
}
|
|
2375
|
-
if (kind === "P" || kind === "X" || kind === "^" || kind === "_") {
|
|
2376
|
-
for (let i = start + 2; i < value.length; i++) {
|
|
2377
|
-
if (value[i] === "\x1B" && value[i + 1] === "\\") return i + 2;
|
|
2378
|
-
}
|
|
2379
|
-
return value.length;
|
|
2380
|
-
}
|
|
2381
|
-
return Math.min(value.length, start + 2);
|
|
2382
|
-
}
|
|
2383
|
-
function stripTerminalSequences(value) {
|
|
2384
|
-
let out = "";
|
|
2385
|
-
for (let i = 0; i < value.length; ) {
|
|
2386
|
-
if (value[i] === "\x1B") {
|
|
2387
|
-
i = escapeEnd(value, i);
|
|
2388
|
-
continue;
|
|
2389
|
-
}
|
|
2390
|
-
const code = value.charCodeAt(i);
|
|
2391
|
-
if (code >= 0 && code < 32 || code === 127) {
|
|
2392
|
-
i++;
|
|
2393
|
-
continue;
|
|
2394
|
-
}
|
|
2395
|
-
const cp = value.codePointAt(i);
|
|
2396
|
-
out += String.fromCodePoint(cp);
|
|
2397
|
-
i += cp > 65535 ? 2 : 1;
|
|
2398
|
-
}
|
|
2399
|
-
return out;
|
|
2400
|
-
}
|
|
2401
|
-
function normalizeTerminalLine(value) {
|
|
2402
|
-
return value.replace(/\r\n|\r|\n/g, " ").replace(/\t/g, " ");
|
|
2403
|
-
}
|
|
2404
|
-
function isWideCodePoint(cp) {
|
|
2405
|
-
return cp >= 4352 && cp <= 4447 || cp === 9001 || cp === 9002 || cp >= 11904 && cp <= 12350 || cp >= 12352 && cp <= 42191 || cp >= 44032 && cp <= 55203 || cp >= 63744 && cp <= 64255 || cp >= 65040 && cp <= 65049 || cp >= 65072 && cp <= 65135 || cp >= 65280 && cp <= 65376 || cp >= 65504 && cp <= 65510 || cp >= 110592 && cp <= 111359 || cp >= 131072 && cp <= 262141;
|
|
2406
|
-
}
|
|
2407
|
-
function graphemeCellWidth(value) {
|
|
2408
|
-
if (!value || zeroWidthGrapheme.test(value)) return 0;
|
|
2409
|
-
const cp = value.codePointAt(0);
|
|
2410
|
-
if (cp < 32 || cp >= 127 && cp < 160) return 0;
|
|
2411
|
-
if (emojiPresentation.test(value) || value.includes("️") || value.includes("") && extendedPictographic.test(value) || cp >= 127462 && cp <= 127487) {
|
|
2412
|
-
return 2;
|
|
2413
|
-
}
|
|
2414
|
-
return isWideCodePoint(cp) ? 2 : 1;
|
|
2415
|
-
}
|
|
2416
|
-
function plainGraphemes(value) {
|
|
2417
|
-
return Array.from(
|
|
2418
|
-
graphemes.segment(stripTerminalSequences(value)),
|
|
2419
|
-
(part) => part.segment
|
|
2420
|
-
);
|
|
2421
|
-
}
|
|
2422
|
-
function terminalCellWidth(value) {
|
|
2423
|
-
let width = 0;
|
|
2424
|
-
for (const grapheme of plainGraphemes(normalizeTerminalLine(value))) {
|
|
2425
|
-
width += graphemeCellWidth(grapheme);
|
|
2426
|
-
}
|
|
2427
|
-
return width;
|
|
2428
|
-
}
|
|
2429
|
-
|
|
2430
2587
|
// packages/cli/src/tui/native/components/instrument-format.ts
|
|
2431
2588
|
var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2432
2589
|
function formatSignalDivider(width, geometry = { direction: "top" }) {
|
|
@@ -2511,7 +2668,7 @@ var ActiveBlocks = class {
|
|
|
2511
2668
|
this.renderer = renderer2;
|
|
2512
2669
|
this.active = active;
|
|
2513
2670
|
this.paint = paint;
|
|
2514
|
-
renderer2.on(
|
|
2671
|
+
renderer2.on(CliRenderEvents4.FRAME, this.sync);
|
|
2515
2672
|
}
|
|
2516
2673
|
renderer;
|
|
2517
2674
|
active;
|
|
@@ -2542,7 +2699,7 @@ var ActiveBlocks = class {
|
|
|
2542
2699
|
this.destroyed = true;
|
|
2543
2700
|
if (this.timer) clearInterval(this.timer);
|
|
2544
2701
|
this.timer = void 0;
|
|
2545
|
-
this.renderer.off(
|
|
2702
|
+
this.renderer.off(CliRenderEvents4.FRAME, this.sync);
|
|
2546
2703
|
}
|
|
2547
2704
|
};
|
|
2548
2705
|
var Disclosure = class extends TextRenderable4 {
|
|
@@ -2676,7 +2833,7 @@ var NativeTaskNotesView = class extends BoxRenderable5 {
|
|
|
2676
2833
|
this.frame = mark;
|
|
2677
2834
|
for (const row of this.rows.values()) if (row.item.status === "in_progress" && visible(row.title, renderer2)) this.refreshRow(row);
|
|
2678
2835
|
});
|
|
2679
|
-
renderer2.on(
|
|
2836
|
+
renderer2.on(CliRenderEvents4.FRAME, this.finishInspect);
|
|
2680
2837
|
}
|
|
2681
2838
|
renderer;
|
|
2682
2839
|
colors;
|
|
@@ -2921,7 +3078,7 @@ var NativeTaskNotesView = class extends BoxRenderable5 {
|
|
|
2921
3078
|
}
|
|
2922
3079
|
destroySelf() {
|
|
2923
3080
|
this.animation.destroy();
|
|
2924
|
-
this.renderer.off(
|
|
3081
|
+
this.renderer.off(CliRenderEvents4.FRAME, this.finishInspect);
|
|
2925
3082
|
super.destroySelf();
|
|
2926
3083
|
}
|
|
2927
3084
|
};
|
|
@@ -3124,7 +3281,7 @@ var NativeTaskStrip = class extends BoxRenderable5 {
|
|
|
3124
3281
|
// packages/cli/src/tui/native/components/work-queue.ts
|
|
3125
3282
|
import {
|
|
3126
3283
|
BoxRenderable as BoxRenderable6,
|
|
3127
|
-
CliRenderEvents as
|
|
3284
|
+
CliRenderEvents as CliRenderEvents5,
|
|
3128
3285
|
RenderableEvents as RenderableEvents4,
|
|
3129
3286
|
ScrollBoxRenderable as ScrollBoxRenderable4,
|
|
3130
3287
|
TextAttributes as TextAttributes6,
|
|
@@ -3242,7 +3399,7 @@ var NativeWorkQueueView = class extends BoxRenderable6 {
|
|
|
3242
3399
|
this.body.add(this.empty);
|
|
3243
3400
|
this.omitted = this.text("omnius-work-queue:omitted", TextAttributes6.DIM);
|
|
3244
3401
|
this.body.add(this.omitted);
|
|
3245
|
-
renderer2.on(
|
|
3402
|
+
renderer2.on(CliRenderEvents5.FRAME, this.syncAnimation);
|
|
3246
3403
|
}
|
|
3247
3404
|
renderer;
|
|
3248
3405
|
colors;
|
|
@@ -3471,7 +3628,7 @@ RUN ${label(receipt.runId)}` : ""}`)
|
|
|
3471
3628
|
this.disposed = true;
|
|
3472
3629
|
if (this.timer) clearInterval(this.timer);
|
|
3473
3630
|
this.timer = void 0;
|
|
3474
|
-
this.renderer.off(
|
|
3631
|
+
this.renderer.off(CliRenderEvents5.FRAME, this.syncAnimation);
|
|
3475
3632
|
super.destroySelf();
|
|
3476
3633
|
}
|
|
3477
3634
|
};
|
|
@@ -3558,7 +3715,7 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3558
3715
|
this.reveal = reveal;
|
|
3559
3716
|
this.header = new FileControl(renderer2, "omnius-workspace-files:heading", colors, () => this.setOpen(!this.open), true);
|
|
3560
3717
|
this.add(this.header);
|
|
3561
|
-
this.body = new BoxRenderable7(renderer2, { id: "omnius-workspace-files:body", width: "100%", minWidth: 0, flexDirection: "column",
|
|
3718
|
+
this.body = new BoxRenderable7(renderer2, { id: "omnius-workspace-files:body", width: "100%", minWidth: 0, minHeight: 0, flexDirection: "column", flexGrow: 1, flexBasis: 0, flexShrink: 1, visible: false });
|
|
3562
3719
|
this.add(this.body);
|
|
3563
3720
|
const heading = new BoxRenderable7(renderer2, { id: "omnius-workspace-files:location", width: "100%", minWidth: 0, height: 1, flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
3564
3721
|
this.body.add(heading);
|
|
@@ -3581,14 +3738,17 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3581
3738
|
id: "omnius-workspace-files:scroll",
|
|
3582
3739
|
width: "100%",
|
|
3583
3740
|
minWidth: 0,
|
|
3584
|
-
height:
|
|
3585
|
-
|
|
3741
|
+
height: "auto",
|
|
3742
|
+
minHeight: 1,
|
|
3743
|
+
flexGrow: 1,
|
|
3744
|
+
flexBasis: 0,
|
|
3745
|
+
flexShrink: 1,
|
|
3586
3746
|
scrollY: true,
|
|
3587
3747
|
scrollX: false,
|
|
3588
3748
|
viewportCulling: true,
|
|
3589
3749
|
horizontalScrollbarOptions: { visible: false },
|
|
3590
3750
|
verticalScrollbarOptions: { showArrows: false },
|
|
3591
|
-
contentOptions: { flexDirection: "column" }
|
|
3751
|
+
contentOptions: { flexDirection: "column", paddingRight: 1 }
|
|
3592
3752
|
});
|
|
3593
3753
|
this.body.add(this.scroll);
|
|
3594
3754
|
this.rootPages = new BoxRenderable7(renderer2, { id: "omnius-workspace-files:pages", width: "100%", height: 1, flexDirection: "row", gap: 2, flexShrink: 0 });
|
|
@@ -3637,6 +3797,8 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3637
3797
|
selectedPath;
|
|
3638
3798
|
lastClick;
|
|
3639
3799
|
restoredTop;
|
|
3800
|
+
layoutMinimum = 0;
|
|
3801
|
+
layoutExpanded = false;
|
|
3640
3802
|
text(id) {
|
|
3641
3803
|
return new TextRenderable6(this.renderer, { id, content: "", width: "100%", minWidth: 0, flexShrink: 0, wrapMode: "word", fg: this.colors.foreground, bg: this.colors.background });
|
|
3642
3804
|
}
|
|
@@ -3715,8 +3877,7 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3715
3877
|
page = { root, start, next };
|
|
3716
3878
|
this.pagination.set(item.path, page);
|
|
3717
3879
|
for (const target of [start, next]) target.on(RenderableEvents5.FOCUSED, () => {
|
|
3718
|
-
this.
|
|
3719
|
-
this.reveal?.(this.scroll);
|
|
3880
|
+
this.revealRow(root);
|
|
3720
3881
|
});
|
|
3721
3882
|
}
|
|
3722
3883
|
page.start.visible = (item.page ?? 0) > 0;
|
|
@@ -3742,7 +3903,6 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3742
3903
|
this.rootNext.visible = state.hasMore === true;
|
|
3743
3904
|
this.rootNext.focusable = this.rootNext.visible;
|
|
3744
3905
|
this.rootPages.visible = this.rootStart.visible || this.rootNext.visible;
|
|
3745
|
-
this.scroll.height = Math.max(1, Math.min(10, position));
|
|
3746
3906
|
this.applyPresentation();
|
|
3747
3907
|
this.updateDetail();
|
|
3748
3908
|
if (this.restoredTop !== void 0) {
|
|
@@ -3790,8 +3950,7 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3790
3950
|
const row = { root, disclosure, name, item };
|
|
3791
3951
|
name.on(RenderableEvents5.FOCUSED, () => {
|
|
3792
3952
|
this.select(item.path);
|
|
3793
|
-
this.
|
|
3794
|
-
this.reveal?.(this.scroll);
|
|
3953
|
+
this.revealRow(root);
|
|
3795
3954
|
this.updateRow(row);
|
|
3796
3955
|
});
|
|
3797
3956
|
name.on(RenderableEvents5.BLURRED, () => {
|
|
@@ -3801,6 +3960,19 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3801
3960
|
root.add(name);
|
|
3802
3961
|
return row;
|
|
3803
3962
|
}
|
|
3963
|
+
revealRow(target) {
|
|
3964
|
+
const viewport = this.scroll.viewport;
|
|
3965
|
+
if (target.y < viewport.y) this.scroll.scrollBy(target.y - viewport.y);
|
|
3966
|
+
else if (target.y + target.height > viewport.y + viewport.height) this.scroll.scrollBy(target.y + target.height - viewport.y - viewport.height);
|
|
3967
|
+
this.reveal?.(target);
|
|
3968
|
+
}
|
|
3969
|
+
revealFocused() {
|
|
3970
|
+
const focused = this.renderer.currentFocusedRenderable;
|
|
3971
|
+
for (let node = focused; node; node = node.parent) if (node === this.scroll) {
|
|
3972
|
+
this.revealRow(focused);
|
|
3973
|
+
break;
|
|
3974
|
+
}
|
|
3975
|
+
}
|
|
3804
3976
|
updateRow(row) {
|
|
3805
3977
|
const marker = activityLabel(row.item), text = label2(row.item.name) + (row.item.kind === "directory" ? "/" : "");
|
|
3806
3978
|
const content = marker ? `${marker} ${text}` : text;
|
|
@@ -3861,9 +4033,30 @@ var NativeWorkspaceFilesView = class extends BoxRenderable7 {
|
|
|
3861
4033
|
this.action("visibility", "");
|
|
3862
4034
|
if (open) this.reveal?.(this.header);
|
|
3863
4035
|
}
|
|
4036
|
+
get isOpen() {
|
|
4037
|
+
return this.open;
|
|
4038
|
+
}
|
|
4039
|
+
/** Natural chrome plus one usable tree row; independent of directory size. */
|
|
4040
|
+
get minimumRows() {
|
|
4041
|
+
if (!this.visible) return 0;
|
|
4042
|
+
if (!this.open) return 1;
|
|
4043
|
+
return 2 + this.body.getChildren().filter((node) => node !== this.scroll && node.visible).reduce((rows, node) => rows + Math.max(1, node.height), 0);
|
|
4044
|
+
}
|
|
4045
|
+
syncLayoutMinimum() {
|
|
4046
|
+
const minimum = this.minimumRows;
|
|
4047
|
+
if (minimum === this.layoutMinimum) return;
|
|
4048
|
+
this.layoutMinimum = minimum;
|
|
4049
|
+
this.minHeight = minimum;
|
|
4050
|
+
}
|
|
3864
4051
|
applyPresentation() {
|
|
3865
4052
|
this.header.setLabel("FILES / FOLDERS", this.open);
|
|
3866
4053
|
this.body.visible = this.open;
|
|
4054
|
+
if (this.layoutExpanded !== this.open) {
|
|
4055
|
+
this.layoutExpanded = this.open;
|
|
4056
|
+
this.flexGrow = this.open ? 1 : 0;
|
|
4057
|
+
this.flexBasis = this.open ? 0 : "auto";
|
|
4058
|
+
}
|
|
4059
|
+
this.syncLayoutMinimum();
|
|
3867
4060
|
}
|
|
3868
4061
|
capturePresentation() {
|
|
3869
4062
|
return { open: this.open, scrollTop: this.scroll.scrollTop, ...this.state ? { projectRoot: this.state.projectRoot, sessionId: this.state.sessionId, selectedPath: this.selectedPath, expandedPaths: (this.state.expandedPaths ?? this.state.entries.filter((item) => item.expanded).map((item) => item.path)).slice(0, 256) } : {} };
|
|
@@ -4160,7 +4353,7 @@ var InstrumentDivider = class extends TextRenderable7 {
|
|
|
4160
4353
|
};
|
|
4161
4354
|
var DeviceMonitor = class extends BoxRenderable8 {
|
|
4162
4355
|
constructor(renderer2, action) {
|
|
4163
|
-
super(renderer2, { id: "omnius-devices", width: "100%", height: 5, minHeight:
|
|
4356
|
+
super(renderer2, { id: "omnius-devices", width: "100%", height: 5, minHeight: 3, flexShrink: 0, flexDirection: "column", visible: false });
|
|
4164
4357
|
this.action = action;
|
|
4165
4358
|
this.heading = new SectionBanner(renderer2, "DEVICES", "omnius-devices:heading", () => this.toggle());
|
|
4166
4359
|
this.heading.update("DEVICES", false);
|
|
@@ -4222,6 +4415,9 @@ var DeviceMonitor = class extends BoxRenderable8 {
|
|
|
4222
4415
|
sectionState = { cpu: false, memory: false, disk: false, network: false, gpu: true };
|
|
4223
4416
|
sections = /* @__PURE__ */ new Map();
|
|
4224
4417
|
availableRows = 100;
|
|
4418
|
+
railRows = 102;
|
|
4419
|
+
reservedUpperRows = 2;
|
|
4420
|
+
allocation = "";
|
|
4225
4421
|
snapshot;
|
|
4226
4422
|
historySource = "";
|
|
4227
4423
|
rows = /* @__PURE__ */ new Map();
|
|
@@ -4241,7 +4437,7 @@ var DeviceMonitor = class extends BoxRenderable8 {
|
|
|
4241
4437
|
}
|
|
4242
4438
|
});
|
|
4243
4439
|
const header = new SectionBanner(renderer2, title, `${root.id}:heading`, () => this.toggleDeviceSection(key));
|
|
4244
|
-
header.on(RenderableEvents6.FOCUSED, () => this.
|
|
4440
|
+
header.on(RenderableEvents6.FOCUSED, () => this.revealReading(header));
|
|
4245
4441
|
const body = new BoxRenderable8(renderer2, { id: `${root.id}:body`, width: "100%", minWidth: 0, flexShrink: 0, flexDirection: "column", visible: this.sectionState[key] });
|
|
4246
4442
|
root.add(header);
|
|
4247
4443
|
root.add(body);
|
|
@@ -4412,7 +4608,7 @@ var DeviceMonitor = class extends BoxRenderable8 {
|
|
|
4412
4608
|
if (current && this.canSelectDevice(current)) this.action?.(`/gpu select ${current.uuid}`);
|
|
4413
4609
|
});
|
|
4414
4610
|
title.width = "100%";
|
|
4415
|
-
title.on(RenderableEvents6.FOCUSED, () => this.
|
|
4611
|
+
title.on(RenderableEvents6.FOCUSED, () => this.revealReading(title));
|
|
4416
4612
|
const load = new TelemetryRow(this._ctx, "LOAD", `${root.id}:load`, 16);
|
|
4417
4613
|
const memory = new TelemetryRow(this._ctx, "VRAM", `${root.id}:memory`, 16);
|
|
4418
4614
|
const plot = (name) => new TextRenderable7(this._ctx, { id: `${root.id}:${name}-history`, content: "", width: "100%", height: 3, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true, selectable: false });
|
|
@@ -4467,24 +4663,45 @@ var DeviceMonitor = class extends BoxRenderable8 {
|
|
|
4467
4663
|
this.expanded = !this.expanded;
|
|
4468
4664
|
this.scroll.visible = this.expanded;
|
|
4469
4665
|
this.scroll.minHeight = this.expanded ? 1 : 0;
|
|
4470
|
-
this.fitHeight(this.
|
|
4666
|
+
this.fitHeight(this.railRows, this.reservedUpperRows);
|
|
4471
4667
|
this.refresh();
|
|
4472
4668
|
}
|
|
4669
|
+
revealReading(target) {
|
|
4670
|
+
const viewport = this.scroll.viewport;
|
|
4671
|
+
if (target.y < viewport.y) this.scroll.scrollBy(target.y - viewport.y);
|
|
4672
|
+
else if (target.y + target.height > viewport.y + viewport.height) this.scroll.scrollBy(target.y + target.height - viewport.y - viewport.height);
|
|
4673
|
+
}
|
|
4674
|
+
revealFocused() {
|
|
4675
|
+
const focused = this._ctx.currentFocusedRenderable;
|
|
4676
|
+
for (let node = focused; node; node = node.parent) if (node === this.scroll) {
|
|
4677
|
+
this.revealReading(focused);
|
|
4678
|
+
break;
|
|
4679
|
+
}
|
|
4680
|
+
}
|
|
4473
4681
|
get isExpanded() {
|
|
4474
4682
|
return this.expanded;
|
|
4475
4683
|
}
|
|
4476
4684
|
setExpanded(expanded) {
|
|
4477
4685
|
if (this.expanded !== expanded) this.toggle();
|
|
4478
4686
|
}
|
|
4479
|
-
fitHeight(railRows) {
|
|
4480
|
-
this.
|
|
4687
|
+
fitHeight(railRows, reservedUpperRows = this.reservedUpperRows) {
|
|
4688
|
+
this.railRows = railRows;
|
|
4689
|
+
this.reservedUpperRows = reservedUpperRows;
|
|
4690
|
+
this.availableRows = Math.max(0, railRows - reservedUpperRows);
|
|
4481
4691
|
this.visible = Boolean(this.snapshot) && this.availableRows >= 3;
|
|
4482
|
-
this.minHeight = Math.min(5, this.availableRows);
|
|
4483
|
-
this.maxHeight = this.availableRows;
|
|
4484
4692
|
this.summary.visible = this.availableRows >= 5;
|
|
4485
4693
|
this.compactLoad.visible = !this.expanded;
|
|
4486
4694
|
this.compactMemory.visible = !this.expanded && this.availableRows >= 4;
|
|
4487
|
-
|
|
4695
|
+
const chrome = this.getChildren().filter((node) => node !== this.scroll && node.visible).reduce((rows, node) => rows + Math.max(1, node.height), 0);
|
|
4696
|
+
const content = this.scroll.getChildren().filter((node) => node.visible).reduce((rows, node) => rows + Math.max(1, node.height), 0);
|
|
4697
|
+
const demand = this.expanded ? chrome + Math.max(1, content) : 5;
|
|
4698
|
+
const height = Math.min(this.availableRows, demand), minimum = Math.min(this.expanded ? 3 : 5, this.availableRows);
|
|
4699
|
+
const signature = `${height}:${minimum}:${this.availableRows}`;
|
|
4700
|
+
if (signature === this.allocation) return;
|
|
4701
|
+
this.allocation = signature;
|
|
4702
|
+
this.minHeight = minimum;
|
|
4703
|
+
this.maxHeight = this.availableRows;
|
|
4704
|
+
this.height = height;
|
|
4488
4705
|
}
|
|
4489
4706
|
onResize(width, height) {
|
|
4490
4707
|
super.onResize(width, height);
|
|
@@ -4657,9 +4874,11 @@ var InstrumentRail = class extends BoxRenderable8 {
|
|
|
4657
4874
|
routeAttemptsHeader;
|
|
4658
4875
|
routeAttempts;
|
|
4659
4876
|
routeAttemptRows = [];
|
|
4877
|
+
layoutSignature = "";
|
|
4878
|
+
contentMinimum = 0;
|
|
4660
4879
|
onResize(width, height) {
|
|
4661
4880
|
super.onResize(width, height);
|
|
4662
|
-
this.
|
|
4881
|
+
this.reconcileLayout();
|
|
4663
4882
|
}
|
|
4664
4883
|
constructor(renderer2, options = {}) {
|
|
4665
4884
|
const id = options.id ?? "omnius-instruments";
|
|
@@ -4822,6 +5041,7 @@ var InstrumentRail = class extends BoxRenderable8 {
|
|
|
4822
5041
|
this.scroll.add(this.workspaceFiles);
|
|
4823
5042
|
this.devices = new DeviceMonitor(renderer2, options.onAction);
|
|
4824
5043
|
this.add(this.devices);
|
|
5044
|
+
this.renderAfter = this.reconcileLayout;
|
|
4825
5045
|
if (options.colors) this.applyTheme(options.colors);
|
|
4826
5046
|
}
|
|
4827
5047
|
update(state) {
|
|
@@ -4990,6 +5210,37 @@ var InstrumentRail = class extends BoxRenderable8 {
|
|
|
4990
5210
|
target.focus();
|
|
4991
5211
|
return true;
|
|
4992
5212
|
}
|
|
5213
|
+
/** Read the small retained section list after native layout. Only changed
|
|
5214
|
+
* budgets stage styles, so a settled sidebar does not schedule idle frames. */
|
|
5215
|
+
reconcileLayout = () => {
|
|
5216
|
+
if (this.isDestroyed || !this.visible || !this.scroll || !this.devices || !this.workspaceFiles) return;
|
|
5217
|
+
this.workspaceFiles.syncLayoutMinimum();
|
|
5218
|
+
const upper = this.scroll.getChildren().filter((node) => node !== this.workspaceFiles && node.visible).reduce((rows, node) => rows + node.height, 0) + this.workspaceFiles.minimumRows;
|
|
5219
|
+
const contentMinimum = Math.max(this.scroll.viewport.height, upper);
|
|
5220
|
+
if (contentMinimum !== this.contentMinimum) {
|
|
5221
|
+
this.contentMinimum = contentMinimum;
|
|
5222
|
+
this.scroll.content.minHeight = contentMinimum;
|
|
5223
|
+
}
|
|
5224
|
+
const border = this.border === true ? 2 : Array.isArray(this.border) ? Number(this.border.includes("top")) + Number(this.border.includes("bottom")) : 0;
|
|
5225
|
+
const available = Math.max(0, this.height - border);
|
|
5226
|
+
const reserved = Math.min(upper, Math.max(1, available - 3));
|
|
5227
|
+
this.devices.fitHeight(available, reserved);
|
|
5228
|
+
const signature = `${this.width}:${available}:${upper}:${this.devices.getHeight()}:${this.scroll.content.height}:${this.scroll.viewport.height}`;
|
|
5229
|
+
if (signature === this.layoutSignature) return;
|
|
5230
|
+
this.layoutSignature = signature;
|
|
5231
|
+
const focused = this._ctx.currentFocusedRenderable;
|
|
5232
|
+
for (let node = focused; node; node = node.parent) {
|
|
5233
|
+
if (node === this.scroll) {
|
|
5234
|
+
this.workspaceFiles.revealFocused();
|
|
5235
|
+
this.reveal(focused);
|
|
5236
|
+
break;
|
|
5237
|
+
}
|
|
5238
|
+
if (node === this.devices) {
|
|
5239
|
+
this.devices.revealFocused();
|
|
5240
|
+
break;
|
|
5241
|
+
}
|
|
5242
|
+
}
|
|
5243
|
+
};
|
|
4993
5244
|
reveal(target) {
|
|
4994
5245
|
const viewport = this.scroll.viewport;
|
|
4995
5246
|
if (target.y < viewport.y) this.scroll.scrollBy(target.y - viewport.y);
|
|
@@ -6440,14 +6691,14 @@ var VimComposer = class {
|
|
|
6440
6691
|
};
|
|
6441
6692
|
|
|
6442
6693
|
// packages/cli/src/tui/native/components/selection-menu.ts
|
|
6443
|
-
import { BoxRenderable as BoxRenderable9, CliRenderEvents as
|
|
6694
|
+
import { BoxRenderable as BoxRenderable9, CliRenderEvents as CliRenderEvents6, TextAttributes as TextAttributes9, TextRenderable as TextRenderable8 } from "@opentui/core";
|
|
6444
6695
|
var NativeSelectionMenu = class {
|
|
6445
6696
|
constructor(renderer2, colors, copy, restoreFocus) {
|
|
6446
6697
|
this.renderer = renderer2;
|
|
6447
6698
|
this.colors = colors;
|
|
6448
6699
|
this.copy = copy;
|
|
6449
6700
|
this.restoreFocus = restoreFocus;
|
|
6450
|
-
renderer2.on(
|
|
6701
|
+
renderer2.on(CliRenderEvents6.RESIZE, this.position);
|
|
6451
6702
|
}
|
|
6452
6703
|
renderer;
|
|
6453
6704
|
colors;
|
|
@@ -6568,12 +6819,12 @@ var NativeSelectionMenu = class {
|
|
|
6568
6819
|
}
|
|
6569
6820
|
destroy() {
|
|
6570
6821
|
this.close();
|
|
6571
|
-
this.renderer.off(
|
|
6822
|
+
this.renderer.off(CliRenderEvents6.RESIZE, this.position);
|
|
6572
6823
|
}
|
|
6573
6824
|
};
|
|
6574
6825
|
|
|
6575
6826
|
// packages/cli/src/tui/native/components/tab-strip.ts
|
|
6576
|
-
import { BoxRenderable as BoxRenderable10, CliRenderEvents as
|
|
6827
|
+
import { BoxRenderable as BoxRenderable10, CliRenderEvents as CliRenderEvents7, ScrollBoxRenderable as ScrollBoxRenderable7, SliderRenderable, TextAttributes as TextAttributes10, TextRenderable as TextRenderable9 } from "@opentui/core";
|
|
6577
6828
|
var NativeTabStrip = class extends BoxRenderable10 {
|
|
6578
6829
|
constructor(renderer2, options) {
|
|
6579
6830
|
super(renderer2, {
|
|
@@ -6628,7 +6879,7 @@ var NativeTabStrip = class extends BoxRenderable10 {
|
|
|
6628
6879
|
this.rail.focusable = false;
|
|
6629
6880
|
this.add(this.rail);
|
|
6630
6881
|
styleNativeSlider(this.rail, this.colors);
|
|
6631
|
-
renderer2.on(
|
|
6882
|
+
renderer2.on(CliRenderEvents7.FRAME, this.syncScroll);
|
|
6632
6883
|
}
|
|
6633
6884
|
renderer;
|
|
6634
6885
|
options;
|
|
@@ -6791,7 +7042,7 @@ var NativeTabStrip = class extends BoxRenderable10 {
|
|
|
6791
7042
|
this.scroll.scrollLeft = offset2;
|
|
6792
7043
|
}
|
|
6793
7044
|
destroySelf() {
|
|
6794
|
-
this.renderer.off(
|
|
7045
|
+
this.renderer.off(CliRenderEvents7.FRAME, this.syncScroll);
|
|
6795
7046
|
super.destroySelf();
|
|
6796
7047
|
}
|
|
6797
7048
|
};
|
|
@@ -7304,8 +7555,8 @@ var NativeFrontend = class {
|
|
|
7304
7555
|
this.modals = new NativeModalStack(this.context, () => this.restoreFocus());
|
|
7305
7556
|
renderer2.keyInput.on("keypress", this.onKey);
|
|
7306
7557
|
renderer2.keyInput.on("paste", this.onPaste);
|
|
7307
|
-
renderer2.on(
|
|
7308
|
-
renderer2.on(
|
|
7558
|
+
renderer2.on(CliRenderEvents8.FRAME, this.onFrame);
|
|
7559
|
+
renderer2.on(CliRenderEvents8.RESIZE, this.onResize);
|
|
7309
7560
|
this.applyTheme(initialTheme);
|
|
7310
7561
|
this.editor.focus();
|
|
7311
7562
|
}
|
|
@@ -8235,8 +8486,8 @@ var NativeFrontend = class {
|
|
|
8235
8486
|
this.disposeSelectionContrast();
|
|
8236
8487
|
this.renderer.keyInput.off("keypress", this.onKey);
|
|
8237
8488
|
this.renderer.keyInput.off("paste", this.onPaste);
|
|
8238
|
-
this.renderer.off(
|
|
8239
|
-
this.renderer.off(
|
|
8489
|
+
this.renderer.off(CliRenderEvents8.FRAME, this.onFrame);
|
|
8490
|
+
this.renderer.off(CliRenderEvents8.RESIZE, this.onResize);
|
|
8240
8491
|
const mediaClosed = [...this.context.mediaViews ?? []].map((media) => {
|
|
8241
8492
|
media.pausePlayback();
|
|
8242
8493
|
return media.closed;
|
|
@@ -8252,7 +8503,7 @@ var NativeFrontend = class {
|
|
|
8252
8503
|
};
|
|
8253
8504
|
|
|
8254
8505
|
// packages/cli/src/tui/native/components/cursor.ts
|
|
8255
|
-
import { CliRenderEvents as
|
|
8506
|
+
import { CliRenderEvents as CliRenderEvents9 } from "@opentui/core";
|
|
8256
8507
|
function installTerminalCursorDefaults(renderer2, session) {
|
|
8257
8508
|
const reset = new TextEncoder().encode("\x1B]112\x07");
|
|
8258
8509
|
let disposed = false;
|
|
@@ -8302,11 +8553,11 @@ function installTerminalCursorDefaults(renderer2, session) {
|
|
|
8302
8553
|
const dispose = () => {
|
|
8303
8554
|
if (disposed) return;
|
|
8304
8555
|
disposed = true;
|
|
8305
|
-
renderer2.off(
|
|
8306
|
-
renderer2.off(
|
|
8556
|
+
renderer2.off(CliRenderEvents9.FRAME, afterFrame);
|
|
8557
|
+
renderer2.off(CliRenderEvents9.DESTROY, dispose);
|
|
8307
8558
|
};
|
|
8308
|
-
renderer2.on(
|
|
8309
|
-
renderer2.once(
|
|
8559
|
+
renderer2.on(CliRenderEvents9.FRAME, afterFrame);
|
|
8560
|
+
renderer2.once(CliRenderEvents9.DESTROY, dispose);
|
|
8310
8561
|
return { restore, dispose };
|
|
8311
8562
|
}
|
|
8312
8563
|
|
|
@@ -8395,10 +8646,10 @@ try {
|
|
|
8395
8646
|
maxFps: 60,
|
|
8396
8647
|
clearOnShutdown: false
|
|
8397
8648
|
});
|
|
8398
|
-
renderer.on(
|
|
8649
|
+
renderer.on(CliRenderEvents10.RENDER_ERROR, (event) => {
|
|
8399
8650
|
void fail(event.error);
|
|
8400
8651
|
});
|
|
8401
|
-
renderer.on(
|
|
8652
|
+
renderer.on(CliRenderEvents10.HANDLER_ERROR, (event) => {
|
|
8402
8653
|
void fail(event.error);
|
|
8403
8654
|
});
|
|
8404
8655
|
renderer.on("error", (event) => {
|