omnius 1.0.864 → 1.0.866
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 +2 -2
- package/dist/tui/native/worker.js +728 -166
- package/dist/update-worker.js +21 -0
- package/docs/DISCOVERY.json +1680 -538
- package/docs/DISCOVERY.md +32 -0
- package/docs/work-orders/2026-10-16-browser-instrument-dashboard.md +91 -0
- package/docs/work-orders/2026-10-16-interface-delivery.md +53 -0
- package/docs/work-orders/desktop-projects.md +9 -3
- package/docs/work-orders/evidence/browser-controls-deployment-20261016.json +28 -0
- package/docs/work-orders/evidence/browser-controls-package-verification-20261016.json +68 -0
- package/docs/work-orders/evidence/desktop-indicator-registration-20261016.json +11 -6
- package/docs/work-orders/evidence/instrument-100x30.png +0 -0
- package/docs/work-orders/evidence/instrument-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-160x48.png +0 -0
- package/docs/work-orders/evidence/instrument-60x20.png +0 -0
- package/docs/work-orders/evidence/instrument-80x24.png +0 -0
- package/docs/work-orders/evidence/instrument-clean-transcript-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-collapse-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-devices-expanded-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-divider-collapsed-160x48.png +0 -0
- package/docs/work-orders/evidence/instrument-divider-resized-160x48.png +0 -0
- package/docs/work-orders/evidence/instrument-help-scroll-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-package-install-20261016-updated.json +149 -0
- package/docs/work-orders/evidence/instrument-popup-api-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-api-input-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-config-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-dark-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-dark-60x20.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-light-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-model-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-popup-network-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-production-terminal-live.json +3521 -2398
- package/docs/work-orders/evidence/instrument-report-broker-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-report-gpu-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-report-stats-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-selection-copied-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-selection-copy-menu-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-sessions-narrow-60x20.png +0 -0
- package/docs/work-orders/evidence/instrument-sessions-restored-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-terminal-light-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-transcript-selection-120x36.png +0 -0
- package/docs/work-orders/evidence/instrument-vim-composer-120x36.png +0 -0
- package/docs/work-orders/evidence/interface-daemon-deployment-20261016.json +56 -0
- package/docs/work-orders/evidence/interface-targeted-verification-20261016-final.json +463 -0
- package/docs/work-orders/evidence/native-session-lifecycle-verification-20261016.json +79 -0
- package/docs/work-orders/evidence/native-session-regression-verification-20261016.json +65 -0
- package/docs/work-orders/evidence/native-session-widget-verification-20261016.json +60 -0
- package/docs/work-orders/evidence/native-sessions-installed-pty-20261016.json +2608 -0
- package/docs/work-orders/evidence/native-sessions-production-pty-20261016.json +3348 -0
- package/docs/work-orders/evidence/native-sessions-production-vte-20261016.json +2032 -0
- package/docs/work-orders/evidence/session-tabs-installation-20261016.json +37 -0
- package/docs/work-orders/evidence/session-tabs-package-verification-20261016.json +50 -0
- package/docs/work-orders/evidence/tray-checked-menu-final.png +0 -0
- package/docs/work-orders/evidence/tray-project-3.png +0 -0
- package/docs/work-orders/evidence/tray-project-4.png +0 -0
- package/docs/work-orders/evidence/tray-project-5.png +0 -0
- package/docs/work-orders/evidence/tray-project-7.png +0 -0
- package/docs/work-orders/evidence/tray-projects-live.json +307 -47
- package/docs/work-orders/evidence/tray-projects-long-menu.png +0 -0
- package/docs/work-orders/evidence/tray-projects-menu.png +0 -0
- package/docs/work-orders/evidence/web-instrument-dark-desktop-20261016.png +0 -0
- package/docs/work-orders/evidence/web-instrument-dark-phone-20261016.png +0 -0
- package/docs/work-orders/evidence/web-instrument-dashboard-live-20261016.json +110 -0
- package/docs/work-orders/evidence/web-instrument-light-desktop-20261016.png +0 -0
- package/docs/work-orders/evidence/web-instrument-light-phone-20261016.png +0 -0
- package/docs/work-orders/evidence/web-media-runtime-verification-20261016.json +75 -0
- package/docs/work-orders/evidence/web-sidebar-send-dark-desktop-20261016.png +0 -0
- package/docs/work-orders/evidence/web-sidebar-send-light-phone-20261016.png +0 -0
- package/docs/work-orders/evidence/web-sidebar-send-repair-20261016.json +163 -0
- package/docs/work-orders/instrument-tui.md +66 -4
- package/npm-shrinkwrap.json +15 -15
- package/package.json +1 -1
|
@@ -2,19 +2,18 @@
|
|
|
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 CliRenderEvents7, NativeSession, RGBA as RGBA3, createCliRenderer } from "@opentui/core";
|
|
6
6
|
|
|
7
7
|
// packages/cli/src/tui/native/components/frontend.ts
|
|
8
8
|
import {
|
|
9
|
-
BoxRenderable as
|
|
10
|
-
CliRenderEvents as
|
|
9
|
+
BoxRenderable as BoxRenderable7,
|
|
10
|
+
CliRenderEvents as CliRenderEvents5,
|
|
11
11
|
EmbeddedTerminalRenderable as EmbeddedTerminalRenderable2,
|
|
12
|
-
ScrollBoxRenderable as
|
|
12
|
+
ScrollBoxRenderable as ScrollBoxRenderable5,
|
|
13
13
|
SyntaxStyle as SyntaxStyle2,
|
|
14
|
-
TabSelectRenderable,
|
|
15
14
|
TextareaRenderable as TextareaRenderable2,
|
|
16
|
-
TextRenderable as
|
|
17
|
-
TextAttributes as
|
|
15
|
+
TextRenderable as TextRenderable6,
|
|
16
|
+
TextAttributes as TextAttributes8,
|
|
18
17
|
createClipboard,
|
|
19
18
|
createHostClipboard,
|
|
20
19
|
createRendererClipboardAdapter
|
|
@@ -799,49 +798,51 @@ function drawDotRail(buffer, x, y, length, horizontal, progress, colors) {
|
|
|
799
798
|
function styleNativeScrollbars(scroll, colors) {
|
|
800
799
|
for (const bar of [scroll.horizontalScrollBar, scroll.verticalScrollBar]) {
|
|
801
800
|
bar.showArrows = false;
|
|
802
|
-
|
|
803
|
-
slider.foregroundColor = colors.foreground;
|
|
804
|
-
slider.backgroundColor = colors.background;
|
|
805
|
-
slider.renderAfter = (buffer) => {
|
|
806
|
-
const horizontal = slider.orientation === "horizontal";
|
|
807
|
-
drawDotRail(
|
|
808
|
-
buffer,
|
|
809
|
-
slider.x,
|
|
810
|
-
slider.y,
|
|
811
|
-
horizontal ? slider.width : slider.height,
|
|
812
|
-
horizontal,
|
|
813
|
-
slider.max > slider.min ? (slider.value - slider.min) / (slider.max - slider.min) : 0,
|
|
814
|
-
colors
|
|
815
|
-
);
|
|
816
|
-
};
|
|
817
|
-
let dragging = false;
|
|
818
|
-
const seek = (event) => {
|
|
819
|
-
const horizontal = slider.orientation === "horizontal";
|
|
820
|
-
const length = horizontal ? slider.width : slider.height;
|
|
821
|
-
const offset = horizontal ? event.x - slider.x : event.y - slider.y;
|
|
822
|
-
const progress = length > 1 ? Math.max(0, Math.min(1, offset / (length - 1))) : 0;
|
|
823
|
-
slider.value = slider.min + progress * (slider.max - slider.min);
|
|
824
|
-
event.preventDefault();
|
|
825
|
-
event.stopPropagation();
|
|
826
|
-
};
|
|
827
|
-
slider.onMouseDown = (event) => {
|
|
828
|
-
if (event.button === 0) {
|
|
829
|
-
dragging = true;
|
|
830
|
-
seek(event);
|
|
831
|
-
}
|
|
832
|
-
};
|
|
833
|
-
slider.onMouseDrag = (event) => {
|
|
834
|
-
if (dragging) seek(event);
|
|
835
|
-
};
|
|
836
|
-
slider.onMouseUp = (event) => {
|
|
837
|
-
if (dragging) seek(event);
|
|
838
|
-
dragging = false;
|
|
839
|
-
};
|
|
840
|
-
slider.onMouseDragEnd = () => {
|
|
841
|
-
dragging = false;
|
|
842
|
-
};
|
|
801
|
+
styleNativeSlider(bar.slider, colors);
|
|
843
802
|
}
|
|
844
803
|
}
|
|
804
|
+
function styleNativeSlider(slider, colors) {
|
|
805
|
+
slider.foregroundColor = colors.foreground;
|
|
806
|
+
slider.backgroundColor = colors.background;
|
|
807
|
+
slider.renderAfter = (buffer) => {
|
|
808
|
+
const horizontal = slider.orientation === "horizontal";
|
|
809
|
+
drawDotRail(
|
|
810
|
+
buffer,
|
|
811
|
+
slider.x,
|
|
812
|
+
slider.y,
|
|
813
|
+
horizontal ? slider.width : slider.height,
|
|
814
|
+
horizontal,
|
|
815
|
+
slider.max > slider.min ? (slider.value - slider.min) / (slider.max - slider.min) : 0,
|
|
816
|
+
colors
|
|
817
|
+
);
|
|
818
|
+
};
|
|
819
|
+
let dragging = false;
|
|
820
|
+
const seek = (event) => {
|
|
821
|
+
const horizontal = slider.orientation === "horizontal";
|
|
822
|
+
const length = horizontal ? slider.width : slider.height;
|
|
823
|
+
const offset = horizontal ? event.x - slider.x : event.y - slider.y;
|
|
824
|
+
const progress = length > 1 ? Math.max(0, Math.min(1, offset / (length - 1))) : 0;
|
|
825
|
+
slider.value = slider.min + progress * (slider.max - slider.min);
|
|
826
|
+
event.preventDefault();
|
|
827
|
+
event.stopPropagation();
|
|
828
|
+
};
|
|
829
|
+
slider.onMouseDown = (event) => {
|
|
830
|
+
if (event.button === 0) {
|
|
831
|
+
dragging = true;
|
|
832
|
+
seek(event);
|
|
833
|
+
}
|
|
834
|
+
};
|
|
835
|
+
slider.onMouseDrag = (event) => {
|
|
836
|
+
if (dragging) seek(event);
|
|
837
|
+
};
|
|
838
|
+
slider.onMouseUp = (event) => {
|
|
839
|
+
if (dragging) seek(event);
|
|
840
|
+
dragging = false;
|
|
841
|
+
};
|
|
842
|
+
slider.onMouseDragEnd = () => {
|
|
843
|
+
dragging = false;
|
|
844
|
+
};
|
|
845
|
+
}
|
|
845
846
|
|
|
846
847
|
// packages/cli/src/tui/native/components/select.ts
|
|
847
848
|
var NativeSelectRenderable = class extends SelectRenderable {
|
|
@@ -1650,6 +1651,58 @@ import {
|
|
|
1650
1651
|
TextRenderable as TextRenderable3
|
|
1651
1652
|
} from "@opentui/core";
|
|
1652
1653
|
|
|
1654
|
+
// packages/cli/src/tui/native/components/device-history.ts
|
|
1655
|
+
var DeviceHistory = class {
|
|
1656
|
+
samples = [];
|
|
1657
|
+
append(sample) {
|
|
1658
|
+
if (!Number.isFinite(sample.at) || sample.at <= (this.samples.at(-1)?.at ?? 0)) return;
|
|
1659
|
+
this.samples.push(sample);
|
|
1660
|
+
if (this.samples.length > 120) this.samples.splice(0, this.samples.length - 120);
|
|
1661
|
+
}
|
|
1662
|
+
};
|
|
1663
|
+
function deviceHistorySparkline(samples, field, width) {
|
|
1664
|
+
const columns = Math.max(0, Math.floor(width));
|
|
1665
|
+
const latest = samples.at(-1)?.at;
|
|
1666
|
+
const values = Array(columns).fill(void 0);
|
|
1667
|
+
if (latest !== void 0) for (const sample of samples) {
|
|
1668
|
+
const x = columns - 1 - Math.round((latest - sample.at) / 2e3);
|
|
1669
|
+
if (x >= 0 && x < columns) values[x] = sample[field];
|
|
1670
|
+
}
|
|
1671
|
+
return values.map((value) => value === void 0 || !Number.isFinite(value) || value < 0 ? " " : "▁▂▃▄▅▆▇█"[Math.round(Math.min(100, value) * 7 / 100)]).join("");
|
|
1672
|
+
}
|
|
1673
|
+
function deviceHistoryGraph(samples, field, width) {
|
|
1674
|
+
const columns = Math.max(0, Math.floor(width) - 5), pixels = columns * 2;
|
|
1675
|
+
if (columns < 2) return "";
|
|
1676
|
+
const cells = Array.from({ length: 3 }, () => Array(columns).fill(0));
|
|
1677
|
+
const latest = samples.at(-1)?.at;
|
|
1678
|
+
const dots = [[1, 8], [2, 16], [4, 32], [64, 128]];
|
|
1679
|
+
const point = (x, y) => {
|
|
1680
|
+
if (x < 0 || x >= pixels || y < 0 || y >= 12) return;
|
|
1681
|
+
cells[Math.floor(y / 4)][Math.floor(x / 2)] |= dots[y % 4][x % 2];
|
|
1682
|
+
};
|
|
1683
|
+
let previous;
|
|
1684
|
+
if (latest !== void 0) for (const sample of samples) {
|
|
1685
|
+
const value = sample[field];
|
|
1686
|
+
const x = pixels - 1 - Math.round((latest - sample.at) / 1e3);
|
|
1687
|
+
if (x < 0) {
|
|
1688
|
+
previous = void 0;
|
|
1689
|
+
continue;
|
|
1690
|
+
}
|
|
1691
|
+
if (value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
1692
|
+
previous = void 0;
|
|
1693
|
+
continue;
|
|
1694
|
+
}
|
|
1695
|
+
const y = Math.round(11 * (1 - Math.min(100, value) / 100));
|
|
1696
|
+
if (previous && sample.at - previous.at <= 5e3) {
|
|
1697
|
+
const distance = Math.max(1, Math.abs(x - previous.x), Math.abs(y - previous.y));
|
|
1698
|
+
for (let step = 0; step <= distance; step++) point(Math.round(previous.x + (x - previous.x) * step / distance), Math.round(previous.y + (y - previous.y) * step / distance));
|
|
1699
|
+
} else point(x, y);
|
|
1700
|
+
previous = { x, y, at: sample.at };
|
|
1701
|
+
}
|
|
1702
|
+
const labels = ["100%│", " 50%│", " 0%└"];
|
|
1703
|
+
return cells.map((row, y) => labels[y] + row.map((bits, x) => bits ? String.fromCodePoint(10240 + bits) : x % 4 === 0 ? "·" : " ").join("")).join("\n");
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1653
1706
|
// packages/cli/src/tui/terminal-cells.ts
|
|
1654
1707
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1655
1708
|
var extendedPictographic = /\p{Extended_Pictographic}/u;
|
|
@@ -1729,6 +1782,20 @@ function terminalCellWidth(value) {
|
|
|
1729
1782
|
|
|
1730
1783
|
// packages/cli/src/tui/native/components/instrument-format.ts
|
|
1731
1784
|
var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1785
|
+
function formatSignalDivider(width, geometry = { direction: "top" }) {
|
|
1786
|
+
const cells = Math.max(0, Math.floor(width));
|
|
1787
|
+
if (cells < 8) return "─".repeat(cells);
|
|
1788
|
+
const buffer = Math.max(1, Math.floor(geometry.buffer ?? 2));
|
|
1789
|
+
const requestedRight = geometry.direction === "bottom" && geometry.sidebarColumn !== void 0 ? geometry.sidebarColumn : (geometry.rightTextStart ?? cells) - buffer - 1;
|
|
1790
|
+
const right = Math.max(4, Math.min(cells - 2, Math.floor(requestedRight)));
|
|
1791
|
+
const requestedLeft = Math.floor(geometry.leftTextEnd ?? 0) + buffer;
|
|
1792
|
+
if (geometry.direction === "top" && requestedLeft > right - 2) return "─".repeat(cells);
|
|
1793
|
+
const left = Math.max(1, Math.min(right - 2, requestedLeft));
|
|
1794
|
+
const outside = geometry.direction === "top" ? "▁" : "▔";
|
|
1795
|
+
const inside = geometry.direction === "top" ? "▔" : "▁";
|
|
1796
|
+
const fall = geometry.direction === "top" ? "╱" : "╲", rise = geometry.direction === "top" ? "╲" : "╱";
|
|
1797
|
+
return outside.repeat(left) + fall + inside.repeat(right - left - 1) + rise + outside.repeat(cells - right - 1);
|
|
1798
|
+
}
|
|
1732
1799
|
function fitInstrumentText(value, cells, marker = "~") {
|
|
1733
1800
|
const text = stripTerminalSequences(normalizeTerminalLine(value));
|
|
1734
1801
|
const width = Math.max(0, Math.floor(cells));
|
|
@@ -1989,13 +2056,17 @@ var InstrumentDivider = class extends TextRenderable3 {
|
|
|
1989
2056
|
};
|
|
1990
2057
|
var DeviceMonitor = class extends BoxRenderable4 {
|
|
1991
2058
|
constructor(renderer2, action) {
|
|
1992
|
-
super(renderer2, { id: "omnius-devices", width: "100%", height:
|
|
2059
|
+
super(renderer2, { id: "omnius-devices", width: "100%", height: 5, minHeight: 5, maxHeight: "60%", flexShrink: 1, flexDirection: "column", visible: false });
|
|
1993
2060
|
this.action = action;
|
|
1994
2061
|
this.heading = new SectionBanner(renderer2, "DEVICES", "omnius-devices:heading", () => this.toggle());
|
|
1995
2062
|
this.heading.update("DEVICES", false);
|
|
1996
2063
|
this.add(this.heading);
|
|
1997
2064
|
this.summary = new TextRenderable3(renderer2, { id: "omnius-devices:summary", content: "--", width: "100%", height: 1, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true });
|
|
1998
2065
|
this.add(this.summary);
|
|
2066
|
+
this.compactLoad = new TextRenderable3(renderer2, { id: "omnius-devices:load-history", content: "", width: "100%", height: 1, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true });
|
|
2067
|
+
this.compactMemory = new TextRenderable3(renderer2, { id: "omnius-devices:memory-history", content: "", width: "100%", height: 1, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true });
|
|
2068
|
+
this.add(this.compactLoad);
|
|
2069
|
+
this.add(this.compactMemory);
|
|
1999
2070
|
this.scroll = new ScrollBoxRenderable3(renderer2, {
|
|
2000
2071
|
id: "omnius-devices:scroll",
|
|
2001
2072
|
width: "100%",
|
|
@@ -2036,11 +2107,15 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2036
2107
|
heading;
|
|
2037
2108
|
scroll;
|
|
2038
2109
|
summary;
|
|
2110
|
+
compactLoad;
|
|
2111
|
+
compactMemory;
|
|
2039
2112
|
policy;
|
|
2040
2113
|
status;
|
|
2041
2114
|
notes;
|
|
2042
2115
|
expanded = false;
|
|
2116
|
+
availableRows = 100;
|
|
2043
2117
|
snapshot;
|
|
2118
|
+
historySource = "";
|
|
2044
2119
|
rows = /* @__PURE__ */ new Map();
|
|
2045
2120
|
button(renderer2, id, label, activate) {
|
|
2046
2121
|
const button = new TextRenderable3(renderer2, {
|
|
@@ -2086,7 +2161,12 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2086
2161
|
}
|
|
2087
2162
|
update(snapshot) {
|
|
2088
2163
|
this.snapshot = snapshot;
|
|
2089
|
-
this.visible = Boolean(snapshot);
|
|
2164
|
+
this.visible = Boolean(snapshot) && this.availableRows >= 3;
|
|
2165
|
+
const historySource = `${snapshot?.source}:${snapshot?.local}`;
|
|
2166
|
+
if (this.historySource !== historySource) {
|
|
2167
|
+
for (const row of this.rows.values()) row.history.samples.splice(0);
|
|
2168
|
+
this.historySource = historySource;
|
|
2169
|
+
}
|
|
2090
2170
|
const allowed = this.canSelect();
|
|
2091
2171
|
if (this.policy.focused && !allowed) this.heading.focus();
|
|
2092
2172
|
this.policy.focusable = allowed;
|
|
@@ -2108,7 +2188,7 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2108
2188
|
flexShrink: 0,
|
|
2109
2189
|
onSizeChange: () => {
|
|
2110
2190
|
if (!row) return;
|
|
2111
|
-
for (const child of [row.title, row.load, row.memory, row.reason]) child.width = row.root.width;
|
|
2191
|
+
for (const child of [row.title, row.load, row.memory, row.reason, row.loadGraph, row.memoryGraph]) child.width = row.root.width;
|
|
2112
2192
|
this.refresh();
|
|
2113
2193
|
}
|
|
2114
2194
|
});
|
|
@@ -2120,6 +2200,8 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2120
2200
|
title.on(RenderableEvents3.FOCUSED, () => this.scroll.scrollChildIntoView(root.id));
|
|
2121
2201
|
const load = new TelemetryRow(this._ctx, "LOAD", `${root.id}:load`, 16);
|
|
2122
2202
|
const memory = new TelemetryRow(this._ctx, "VRAM", `${root.id}:memory`, 16);
|
|
2203
|
+
const plot = (name) => new TextRenderable3(this._ctx, { id: `${root.id}:${name}-history`, content: "", width: "100%", height: 3, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true, selectable: false });
|
|
2204
|
+
const loadGraph = plot("load"), memoryGraph = plot("memory"), history = new DeviceHistory();
|
|
2123
2205
|
const reason = new TextRenderable3(this._ctx, {
|
|
2124
2206
|
id: `${root.id}:reason`,
|
|
2125
2207
|
content: "",
|
|
@@ -2134,12 +2216,19 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2134
2216
|
});
|
|
2135
2217
|
root.add(title);
|
|
2136
2218
|
root.add(load);
|
|
2219
|
+
root.add(loadGraph);
|
|
2137
2220
|
root.add(memory);
|
|
2221
|
+
root.add(memoryGraph);
|
|
2138
2222
|
root.add(reason);
|
|
2139
2223
|
this.scroll.add(root);
|
|
2140
|
-
row = { root, title, load, memory, reason };
|
|
2224
|
+
row = { root, title, load, memory, reason, history, loadGraph, memoryGraph };
|
|
2141
2225
|
this.rows.set(device.uuid, row);
|
|
2142
2226
|
}
|
|
2227
|
+
if (snapshot?.sampledAt !== void 0) row.history.append({
|
|
2228
|
+
at: snapshot.sampledAt,
|
|
2229
|
+
load: device.utilization,
|
|
2230
|
+
memory: device.memoryUsedMB !== void 0 && device.memoryUsedMB >= 0 && device.memoryTotalMB !== void 0 && device.memoryTotalMB > 0 ? device.memoryUsedMB * 100 / device.memoryTotalMB : void 0
|
|
2231
|
+
});
|
|
2143
2232
|
const selectable = this.canSelectDevice(device);
|
|
2144
2233
|
if (row.title.focused && !selectable) this.heading.focus();
|
|
2145
2234
|
row.title.focusable = selectable;
|
|
@@ -2156,11 +2245,20 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2156
2245
|
toggle() {
|
|
2157
2246
|
this.expanded = !this.expanded;
|
|
2158
2247
|
this.scroll.visible = this.expanded;
|
|
2159
|
-
this.minHeight = this.expanded ? 4 : 3;
|
|
2160
2248
|
this.scroll.minHeight = this.expanded ? 1 : 0;
|
|
2161
|
-
this.
|
|
2249
|
+
this.fitHeight(this.availableRows + 2);
|
|
2162
2250
|
this.refresh();
|
|
2163
2251
|
}
|
|
2252
|
+
fitHeight(railRows) {
|
|
2253
|
+
this.availableRows = Math.max(0, railRows - 2);
|
|
2254
|
+
this.visible = Boolean(this.snapshot) && this.availableRows >= 3;
|
|
2255
|
+
this.minHeight = Math.min(5, this.availableRows);
|
|
2256
|
+
this.maxHeight = this.availableRows;
|
|
2257
|
+
this.summary.visible = this.availableRows >= 5;
|
|
2258
|
+
this.compactLoad.visible = !this.expanded;
|
|
2259
|
+
this.compactMemory.visible = !this.expanded && this.availableRows >= 4;
|
|
2260
|
+
this.height = Math.min(this.availableRows, this.expanded ? Math.min(18, Math.max(6, Math.floor(railRows * 0.6))) : 5);
|
|
2261
|
+
}
|
|
2164
2262
|
onResize(width, height) {
|
|
2165
2263
|
super.onResize(width, height);
|
|
2166
2264
|
this.refresh();
|
|
@@ -2176,13 +2274,28 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2176
2274
|
this.notes.content = [
|
|
2177
2275
|
data?.local === false ? "REMOTE" : void 0,
|
|
2178
2276
|
data ? `${data.source.toUpperCase()} · ${data.policy.toUpperCase()} · ${data.broker.toUpperCase()}` : void 0,
|
|
2277
|
+
"2s/col",
|
|
2179
2278
|
data?.warnings.length ? `${data.warnings.length} notices` : void 0
|
|
2180
2279
|
].filter(Boolean).join(" · ");
|
|
2280
|
+
const primary = devices.find((device) => device.preferred) ?? devices.find((device) => device.enabled) ?? devices[0];
|
|
2281
|
+
const compactHistory = primary ? this.rows.get(primary.uuid)?.history.samples ?? [] : [];
|
|
2282
|
+
for (const [element, field, label] of [[this.compactLoad, "load", "UTIL"], [this.compactMemory, "memory", primary?.unifiedMemory ? "UMA" : "VRAM"]]) {
|
|
2283
|
+
const current = primary ? field === "load" ? primary.utilization : primary.memoryUsedMB !== void 0 && primary.memoryTotalMB ? primary.memoryUsedMB / primary.memoryTotalMB * 100 : void 0 : void 0;
|
|
2284
|
+
const value = instrumentNumber(current, 0, "%");
|
|
2285
|
+
const caption = `${label}${primary?.index ?? "-"}`;
|
|
2286
|
+
const plotWidth = Math.max(0, this.width - caption.length - value.length - 2);
|
|
2287
|
+
const next = `${caption} ${deviceHistorySparkline(compactHistory, field, plotWidth)} ${value}`;
|
|
2288
|
+
if (element.plainText !== next) element.content = next;
|
|
2289
|
+
}
|
|
2181
2290
|
for (const device of devices) {
|
|
2182
2291
|
const row = this.rows.get(device.uuid);
|
|
2183
2292
|
if (!row) continue;
|
|
2184
2293
|
const state = device.enabled === void 0 ? "--" : device.enabled ? "ON" : "OFF";
|
|
2185
2294
|
row.title.content = formatTelemetryRow(`GPU ${device.index} ${device.name}`, `${state}${device.preferred ? " *" : ""}`, row.root.width, 6);
|
|
2295
|
+
for (const [plot, field] of [[row.loadGraph, "load"], [row.memoryGraph, "memory"]]) {
|
|
2296
|
+
const next = deviceHistoryGraph(row.history.samples, field, row.root.width);
|
|
2297
|
+
if (plot.plainText !== next) plot.content = next;
|
|
2298
|
+
}
|
|
2186
2299
|
}
|
|
2187
2300
|
}
|
|
2188
2301
|
focusTargets() {
|
|
@@ -2305,6 +2418,10 @@ var InstrumentRail = class extends BoxRenderable4 {
|
|
|
2305
2418
|
contextMeter;
|
|
2306
2419
|
contextHeader;
|
|
2307
2420
|
contextDetails;
|
|
2421
|
+
onResize(width, height) {
|
|
2422
|
+
super.onResize(width, height);
|
|
2423
|
+
this.devices?.fitHeight(height);
|
|
2424
|
+
}
|
|
2308
2425
|
constructor(renderer2, options = {}) {
|
|
2309
2426
|
const id = options.id ?? "omnius-instruments";
|
|
2310
2427
|
super(renderer2, {
|
|
@@ -3964,17 +4081,327 @@ var VimComposer = class {
|
|
|
3964
4081
|
}
|
|
3965
4082
|
};
|
|
3966
4083
|
|
|
4084
|
+
// packages/cli/src/tui/native/components/selection-menu.ts
|
|
4085
|
+
import { BoxRenderable as BoxRenderable5, CliRenderEvents as CliRenderEvents3, TextAttributes as TextAttributes6, TextRenderable as TextRenderable4 } from "@opentui/core";
|
|
4086
|
+
var NativeSelectionMenu = class {
|
|
4087
|
+
constructor(renderer2, colors, copy, restoreFocus) {
|
|
4088
|
+
this.renderer = renderer2;
|
|
4089
|
+
this.colors = colors;
|
|
4090
|
+
this.copy = copy;
|
|
4091
|
+
this.restoreFocus = restoreFocus;
|
|
4092
|
+
renderer2.on(CliRenderEvents3.RESIZE, this.position);
|
|
4093
|
+
}
|
|
4094
|
+
renderer;
|
|
4095
|
+
colors;
|
|
4096
|
+
copy;
|
|
4097
|
+
restoreFocus;
|
|
4098
|
+
overlay;
|
|
4099
|
+
panel;
|
|
4100
|
+
frame;
|
|
4101
|
+
previousFocus;
|
|
4102
|
+
anchor = { x: 0, y: 0 };
|
|
4103
|
+
selectedText = "";
|
|
4104
|
+
get active() {
|
|
4105
|
+
return Boolean(this.overlay);
|
|
4106
|
+
}
|
|
4107
|
+
open(x, y, text) {
|
|
4108
|
+
if (!text) return;
|
|
4109
|
+
this.close();
|
|
4110
|
+
this.selectedText = text;
|
|
4111
|
+
this.anchor = { x, y };
|
|
4112
|
+
this.previousFocus = this.renderer.currentFocusedRenderable;
|
|
4113
|
+
this.overlay = new BoxRenderable5(this.renderer, {
|
|
4114
|
+
id: "omnius-selection-menu",
|
|
4115
|
+
position: "absolute",
|
|
4116
|
+
left: 0,
|
|
4117
|
+
top: 0,
|
|
4118
|
+
width: "100%",
|
|
4119
|
+
height: "100%",
|
|
4120
|
+
backgroundColor: "transparent",
|
|
4121
|
+
shouldFill: false,
|
|
4122
|
+
zIndex: 120,
|
|
4123
|
+
onMouseDown: (event) => {
|
|
4124
|
+
this.close();
|
|
4125
|
+
event.preventDefault();
|
|
4126
|
+
event.stopPropagation();
|
|
4127
|
+
}
|
|
4128
|
+
});
|
|
4129
|
+
this.panel = new BoxRenderable5(this.renderer, {
|
|
4130
|
+
id: "omnius-selection-menu-panel",
|
|
4131
|
+
position: "absolute",
|
|
4132
|
+
width: 14,
|
|
4133
|
+
height: 3,
|
|
4134
|
+
flexDirection: "column",
|
|
4135
|
+
paddingX: 2,
|
|
4136
|
+
paddingY: 1,
|
|
4137
|
+
backgroundColor: this.colors.background,
|
|
4138
|
+
onMouseDown: (event) => {
|
|
4139
|
+
event.preventDefault();
|
|
4140
|
+
event.stopPropagation();
|
|
4141
|
+
}
|
|
4142
|
+
});
|
|
4143
|
+
const action = new TextRenderable4(this.renderer, {
|
|
4144
|
+
id: "omnius-selection-copy",
|
|
4145
|
+
content: "COPY",
|
|
4146
|
+
height: 1,
|
|
4147
|
+
width: "100%",
|
|
4148
|
+
selectable: false,
|
|
4149
|
+
fg: this.colors.foreground,
|
|
4150
|
+
bg: this.colors.background,
|
|
4151
|
+
attributes: TextAttributes6.BOLD | TextAttributes6.INVERSE,
|
|
4152
|
+
onMouseDown: (event) => {
|
|
4153
|
+
if (event.button === 0) this.confirm();
|
|
4154
|
+
event.preventDefault();
|
|
4155
|
+
event.stopPropagation();
|
|
4156
|
+
}
|
|
4157
|
+
});
|
|
4158
|
+
action.focusable = true;
|
|
4159
|
+
this.panel.add(action);
|
|
4160
|
+
this.overlay.add(this.panel);
|
|
4161
|
+
this.frame = new NativeCornerFrame(this.panel, this.colors, this.renderer, this.overlay);
|
|
4162
|
+
this.renderer.root.add(this.overlay);
|
|
4163
|
+
this.position();
|
|
4164
|
+
action.focus();
|
|
4165
|
+
this.renderer.requestRender();
|
|
4166
|
+
}
|
|
4167
|
+
position = () => {
|
|
4168
|
+
if (!this.panel) return;
|
|
4169
|
+
const width = Math.min(14, this.renderer.terminalWidth);
|
|
4170
|
+
this.panel.width = width;
|
|
4171
|
+
this.panel.left = Math.max(0, Math.min(this.anchor.x, this.renderer.terminalWidth - width));
|
|
4172
|
+
this.panel.top = Math.max(0, Math.min(this.anchor.y + 1, this.renderer.terminalHeight - 3));
|
|
4173
|
+
};
|
|
4174
|
+
handleKey(key) {
|
|
4175
|
+
if (key.eventType !== "release") {
|
|
4176
|
+
if (key.name === "return" || key.sequence === " " || key.ctrl && key.shift && key.name.toLowerCase() === "c") this.confirm();
|
|
4177
|
+
else if (key.name === "escape" || key.name === "tab") this.close();
|
|
4178
|
+
}
|
|
4179
|
+
key.preventDefault();
|
|
4180
|
+
key.stopPropagation();
|
|
4181
|
+
}
|
|
4182
|
+
confirm() {
|
|
4183
|
+
const text = this.selectedText;
|
|
4184
|
+
this.close();
|
|
4185
|
+
this.copy(text);
|
|
4186
|
+
}
|
|
4187
|
+
applyTheme(colors) {
|
|
4188
|
+
this.colors = colors;
|
|
4189
|
+
if (!this.panel) return;
|
|
4190
|
+
this.panel.backgroundColor = colors.background;
|
|
4191
|
+
this.frame?.setColors(colors);
|
|
4192
|
+
for (const child of this.panel.getChildren()) if (child instanceof TextRenderable4) {
|
|
4193
|
+
child.fg = colors.foreground;
|
|
4194
|
+
child.bg = colors.background;
|
|
4195
|
+
}
|
|
4196
|
+
}
|
|
4197
|
+
close() {
|
|
4198
|
+
if (!this.overlay) return;
|
|
4199
|
+
const previous = this.previousFocus;
|
|
4200
|
+
this.previousFocus = void 0;
|
|
4201
|
+
this.frame?.destroy();
|
|
4202
|
+
this.frame = void 0;
|
|
4203
|
+
this.overlay.destroyRecursively();
|
|
4204
|
+
this.overlay = void 0;
|
|
4205
|
+
this.panel = void 0;
|
|
4206
|
+
this.selectedText = "";
|
|
4207
|
+
if (previous && !previous.isDestroyed && previous.visible && previous.focusable) previous.focus();
|
|
4208
|
+
else this.restoreFocus();
|
|
4209
|
+
this.renderer.requestRender();
|
|
4210
|
+
}
|
|
4211
|
+
destroy() {
|
|
4212
|
+
this.close();
|
|
4213
|
+
this.renderer.off(CliRenderEvents3.RESIZE, this.position);
|
|
4214
|
+
}
|
|
4215
|
+
};
|
|
4216
|
+
|
|
4217
|
+
// packages/cli/src/tui/native/components/tab-strip.ts
|
|
4218
|
+
import { BoxRenderable as BoxRenderable6, CliRenderEvents as CliRenderEvents4, ScrollBoxRenderable as ScrollBoxRenderable4, SliderRenderable, TextAttributes as TextAttributes7, TextRenderable as TextRenderable5 } from "@opentui/core";
|
|
4219
|
+
var NativeTabStrip = class extends BoxRenderable6 {
|
|
4220
|
+
constructor(renderer2, options) {
|
|
4221
|
+
super(renderer2, {
|
|
4222
|
+
id: options.id,
|
|
4223
|
+
height: 1,
|
|
4224
|
+
minHeight: 1,
|
|
4225
|
+
maxHeight: 1,
|
|
4226
|
+
minWidth: 0,
|
|
4227
|
+
flexGrow: 1,
|
|
4228
|
+
flexShrink: 1,
|
|
4229
|
+
flexDirection: "row",
|
|
4230
|
+
shouldFill: false
|
|
4231
|
+
});
|
|
4232
|
+
this.renderer = renderer2;
|
|
4233
|
+
this.options = options;
|
|
4234
|
+
this.colors = options.colors;
|
|
4235
|
+
this.scroll = new ScrollBoxRenderable4(renderer2, {
|
|
4236
|
+
id: `${options.id}:scroll`,
|
|
4237
|
+
height: 1,
|
|
4238
|
+
minHeight: 1,
|
|
4239
|
+
maxHeight: 1,
|
|
4240
|
+
minWidth: 0,
|
|
4241
|
+
flexGrow: 1,
|
|
4242
|
+
flexShrink: 1,
|
|
4243
|
+
scrollX: true,
|
|
4244
|
+
scrollY: false,
|
|
4245
|
+
viewportCulling: true,
|
|
4246
|
+
viewportOptions: { height: 1, minHeight: 1, maxHeight: 1 },
|
|
4247
|
+
contentOptions: { flexDirection: "row", gap: 1 },
|
|
4248
|
+
horizontalScrollbarOptions: { visible: false },
|
|
4249
|
+
verticalScrollbarOptions: { visible: false }
|
|
4250
|
+
});
|
|
4251
|
+
this.scroll.focusable = false;
|
|
4252
|
+
this.scroll.horizontalScrollBar.visible = this.scroll.verticalScrollBar.visible = false;
|
|
4253
|
+
styleNativeScrollbars(this.scroll, this.colors);
|
|
4254
|
+
this.add(this.scroll);
|
|
4255
|
+
this.rail = new SliderRenderable(renderer2, {
|
|
4256
|
+
id: `${options.id}:rail`,
|
|
4257
|
+
orientation: "horizontal",
|
|
4258
|
+
width: 5,
|
|
4259
|
+
minWidth: 5,
|
|
4260
|
+
height: 1,
|
|
4261
|
+
flexShrink: 0,
|
|
4262
|
+
visible: false,
|
|
4263
|
+
min: 0,
|
|
4264
|
+
max: 0,
|
|
4265
|
+
value: 0,
|
|
4266
|
+
onChange: (value) => {
|
|
4267
|
+
if (!this.syncing) this.scroll.scrollLeft = value;
|
|
4268
|
+
}
|
|
4269
|
+
});
|
|
4270
|
+
this.rail.focusable = false;
|
|
4271
|
+
this.add(this.rail);
|
|
4272
|
+
styleNativeSlider(this.rail, this.colors);
|
|
4273
|
+
renderer2.on(CliRenderEvents4.FRAME, this.syncScroll);
|
|
4274
|
+
}
|
|
4275
|
+
renderer;
|
|
4276
|
+
options;
|
|
4277
|
+
scroll;
|
|
4278
|
+
rail;
|
|
4279
|
+
buttons = /* @__PURE__ */ new Map();
|
|
4280
|
+
activeId;
|
|
4281
|
+
signature = "";
|
|
4282
|
+
syncing = false;
|
|
4283
|
+
reveal;
|
|
4284
|
+
colors;
|
|
4285
|
+
naturalWidth = 0;
|
|
4286
|
+
update(items, activeId, busy = false) {
|
|
4287
|
+
const signature = JSON.stringify([items, activeId, busy]);
|
|
4288
|
+
if (signature === this.signature) return;
|
|
4289
|
+
this.signature = signature;
|
|
4290
|
+
const ids = new Set(items.map((item) => item.id));
|
|
4291
|
+
for (const [id, entry] of this.buttons) if (!ids.has(id)) {
|
|
4292
|
+
entry.button.destroy();
|
|
4293
|
+
this.buttons.delete(id);
|
|
4294
|
+
}
|
|
4295
|
+
for (const [index, action] of items.entries()) {
|
|
4296
|
+
let entry = this.buttons.get(action.id);
|
|
4297
|
+
if (!entry) {
|
|
4298
|
+
const button = new TextRenderable5(this.renderer, {
|
|
4299
|
+
id: `${this.options.prefix}:${action.id}`,
|
|
4300
|
+
content: "",
|
|
4301
|
+
height: 1,
|
|
4302
|
+
flexShrink: 0,
|
|
4303
|
+
wrapMode: "none",
|
|
4304
|
+
selectable: false,
|
|
4305
|
+
fg: this.colors.foreground,
|
|
4306
|
+
bg: this.colors.background,
|
|
4307
|
+
onMouseDown: (event) => {
|
|
4308
|
+
if (event.button === 0) {
|
|
4309
|
+
button.focus();
|
|
4310
|
+
if (!entry.blocked) this.options.activate(action.id);
|
|
4311
|
+
}
|
|
4312
|
+
event.preventDefault();
|
|
4313
|
+
event.stopPropagation();
|
|
4314
|
+
},
|
|
4315
|
+
onKeyDown: (key) => this.handleKey(entry, key)
|
|
4316
|
+
});
|
|
4317
|
+
entry = { action, active: false, blocked: false, button };
|
|
4318
|
+
this.buttons.set(action.id, entry);
|
|
4319
|
+
button.on("focused", () => {
|
|
4320
|
+
this.style(entry);
|
|
4321
|
+
this.scroll.scrollChildIntoView(button.id);
|
|
4322
|
+
this.reveal = button.id;
|
|
4323
|
+
});
|
|
4324
|
+
button.on("blurred", () => this.style(entry));
|
|
4325
|
+
}
|
|
4326
|
+
entry.action = action;
|
|
4327
|
+
entry.active = action.id === activeId;
|
|
4328
|
+
entry.blocked = busy || Boolean(action.disabled);
|
|
4329
|
+
entry.button.focusable = entry.active || !entry.blocked;
|
|
4330
|
+
const label = plainText(action.label);
|
|
4331
|
+
const content = entry.active ? `⟋⟋ ${label} ⟍⟍` : ` ${label} `;
|
|
4332
|
+
if (entry.button.plainText !== content) entry.button.content = content;
|
|
4333
|
+
this.style(entry);
|
|
4334
|
+
if (this.scroll.getChildren()[index] !== entry.button) this.scroll.add(entry.button, index);
|
|
4335
|
+
}
|
|
4336
|
+
this.naturalWidth = Array.from(this.buttons.values()).reduce((width, entry) => width + terminalCellWidth(entry.button.plainText), 0) + Math.max(0, items.length - 1);
|
|
4337
|
+
const focused = this.renderer.currentFocusedRenderable;
|
|
4338
|
+
if (focused && !focused.focusable && Array.from(this.buttons.values()).some((entry) => entry.button === focused)) this.buttons.get(activeId)?.button.focus();
|
|
4339
|
+
if (activeId !== this.activeId) this.reveal = `${this.options.prefix}:${activeId}`;
|
|
4340
|
+
this.activeId = activeId;
|
|
4341
|
+
this.renderer.requestRender();
|
|
4342
|
+
}
|
|
4343
|
+
style(entry) {
|
|
4344
|
+
entry.button.attributes = (entry.active ? TextAttributes7.BOLD | TextAttributes7.UNDERLINE : entry.blocked ? TextAttributes7.DIM : 0) | (entry.button.focused ? TextAttributes7.INVERSE : 0);
|
|
4345
|
+
}
|
|
4346
|
+
handleKey(entry, key) {
|
|
4347
|
+
if (key.eventType === "release") return;
|
|
4348
|
+
if (key.name === "return" || key.sequence === " ") {
|
|
4349
|
+
if (!entry.blocked) this.options.activate(entry.action.id);
|
|
4350
|
+
} else if (["left", "right", "home", "end"].includes(key.name)) {
|
|
4351
|
+
const targets = this.scroll.getChildren().filter((button) => button.focusable);
|
|
4352
|
+
const index = targets.indexOf(entry.button);
|
|
4353
|
+
const next = key.name === "home" ? 0 : key.name === "end" ? targets.length - 1 : (index + (key.name === "left" ? -1 : 1) + targets.length) % targets.length;
|
|
4354
|
+
targets[next]?.focus();
|
|
4355
|
+
} else return;
|
|
4356
|
+
key.preventDefault();
|
|
4357
|
+
key.stopPropagation();
|
|
4358
|
+
}
|
|
4359
|
+
syncScroll = () => {
|
|
4360
|
+
if (!this.visible || this.width < 1) return;
|
|
4361
|
+
const overflow = this.naturalWidth > this.width;
|
|
4362
|
+
if (this.rail.visible !== overflow) {
|
|
4363
|
+
this.rail.visible = overflow;
|
|
4364
|
+
this.renderer.requestRender();
|
|
4365
|
+
}
|
|
4366
|
+
if (this.reveal) {
|
|
4367
|
+
this.scroll.scrollChildIntoView(this.reveal);
|
|
4368
|
+
this.reveal = void 0;
|
|
4369
|
+
}
|
|
4370
|
+
this.syncing = true;
|
|
4371
|
+
this.rail.max = Math.max(0, this.scroll.scrollWidth - this.scroll.viewport.width);
|
|
4372
|
+
this.rail.viewPortSize = this.scroll.viewport.width;
|
|
4373
|
+
this.rail.value = this.scroll.scrollLeft;
|
|
4374
|
+
this.syncing = false;
|
|
4375
|
+
};
|
|
4376
|
+
applyTheme(colors) {
|
|
4377
|
+
this.colors = colors;
|
|
4378
|
+
for (const { button } of this.buttons.values()) {
|
|
4379
|
+
button.fg = colors.foreground;
|
|
4380
|
+
button.bg = colors.background;
|
|
4381
|
+
}
|
|
4382
|
+
styleNativeScrollbars(this.scroll, colors);
|
|
4383
|
+
styleNativeSlider(this.rail, colors);
|
|
4384
|
+
}
|
|
4385
|
+
destroySelf() {
|
|
4386
|
+
this.renderer.off(CliRenderEvents4.FRAME, this.syncScroll);
|
|
4387
|
+
super.destroySelf();
|
|
4388
|
+
}
|
|
4389
|
+
};
|
|
4390
|
+
|
|
3967
4391
|
// packages/cli/src/tui/native/components/frontend.ts
|
|
3968
4392
|
var initialTheme = { mode: "system", bg: -1, accent: -1, textPrimary: -1, textDim: -1, boxColor: -1 };
|
|
3969
4393
|
var NativeFrontend = class {
|
|
3970
|
-
constructor(renderer2, emit) {
|
|
4394
|
+
constructor(renderer2, emit, options = {}) {
|
|
3971
4395
|
this.renderer = renderer2;
|
|
3972
4396
|
this.emit = emit;
|
|
3973
4397
|
const colors = palette(initialTheme);
|
|
3974
4398
|
this.context = { renderer: renderer2, colors, syntax: SyntaxStyle2.fromStyles({}, renderer2.nativeScene), emit, terminals: /* @__PURE__ */ new Map() };
|
|
3975
4399
|
this.disposeSelectionContrast = installDefaultSelectionContrast(renderer2);
|
|
3976
|
-
this.clipboard = createClipboard({ host: createHostClipboard({ timeoutMs: 1500 }), terminal: createRendererClipboardAdapter(renderer2) });
|
|
3977
|
-
this.
|
|
4400
|
+
this.clipboard = options.clipboard ?? createClipboard({ host: createHostClipboard({ timeoutMs: 1500 }), terminal: createRendererClipboardAdapter(renderer2) });
|
|
4401
|
+
this.selectionMenu = new NativeSelectionMenu(renderer2, colors, (text) => {
|
|
4402
|
+
void this.copy(text);
|
|
4403
|
+
}, () => this.restoreFocus());
|
|
4404
|
+
this.root = new BoxRenderable7(renderer2, {
|
|
3978
4405
|
id: "omnius-native",
|
|
3979
4406
|
width: "100%",
|
|
3980
4407
|
height: "100%",
|
|
@@ -3982,7 +4409,7 @@ var NativeFrontend = class {
|
|
|
3982
4409
|
backgroundColor: colors.background
|
|
3983
4410
|
});
|
|
3984
4411
|
renderer2.root.add(this.root);
|
|
3985
|
-
this.header = new
|
|
4412
|
+
this.header = new BoxRenderable7(renderer2, {
|
|
3986
4413
|
id: "omnius-header",
|
|
3987
4414
|
width: "100%",
|
|
3988
4415
|
minWidth: 0,
|
|
@@ -3993,9 +4420,23 @@ var NativeFrontend = class {
|
|
|
3993
4420
|
borderColor: colors.border
|
|
3994
4421
|
});
|
|
3995
4422
|
this.root.add(this.header);
|
|
3996
|
-
|
|
4423
|
+
this.header.renderAfter = (buffer) => {
|
|
4424
|
+
if (this.header.height > 0) buffer.drawText(
|
|
4425
|
+
formatSignalDivider(this.header.width, {
|
|
4426
|
+
direction: "top",
|
|
4427
|
+
leftTextEnd: this.identity.x - this.header.x + Math.min(this.identity.width, terminalCellWidth(this.identity.plainText)),
|
|
4428
|
+
rightTextStart: Math.min(this.detailButton.x, this.headerActions.visible ? this.headerActions.x : this.detailButton.x) - this.header.x
|
|
4429
|
+
}),
|
|
4430
|
+
this.header.x,
|
|
4431
|
+
this.header.y + this.header.height - 1,
|
|
4432
|
+
this.context.colors.foreground,
|
|
4433
|
+
this.context.colors.background,
|
|
4434
|
+
TextAttributes8.DIM
|
|
4435
|
+
);
|
|
4436
|
+
};
|
|
4437
|
+
const headerRow = new BoxRenderable7(renderer2, { id: "omnius-header-row", width: "100%", minWidth: 0, minHeight: 1, flexDirection: "row", gap: 1 });
|
|
3997
4438
|
this.header.add(headerRow);
|
|
3998
|
-
this.identity = new
|
|
4439
|
+
this.identity = new TextRenderable6(renderer2, {
|
|
3999
4440
|
id: "omnius-identity",
|
|
4000
4441
|
content: "Omnius",
|
|
4001
4442
|
fg: colors.foreground,
|
|
@@ -4005,7 +4446,7 @@ var NativeFrontend = class {
|
|
|
4005
4446
|
truncate: true,
|
|
4006
4447
|
minWidth: 18,
|
|
4007
4448
|
selectable: false,
|
|
4008
|
-
attributes:
|
|
4449
|
+
attributes: TextAttributes8.BOLD,
|
|
4009
4450
|
onMouseDown: (event) => {
|
|
4010
4451
|
if (event.button === 0) {
|
|
4011
4452
|
this.toggleHeaderPanel();
|
|
@@ -4020,7 +4461,7 @@ var NativeFrontend = class {
|
|
|
4020
4461
|
}
|
|
4021
4462
|
});
|
|
4022
4463
|
headerRow.add(this.identity);
|
|
4023
|
-
this.headerActions = new
|
|
4464
|
+
this.headerActions = new ScrollBoxRenderable5(renderer2, {
|
|
4024
4465
|
id: "omnius-header-actions",
|
|
4025
4466
|
flexGrow: 0,
|
|
4026
4467
|
flexShrink: 1,
|
|
@@ -4033,16 +4474,16 @@ var NativeFrontend = class {
|
|
|
4033
4474
|
verticalScrollbarOptions: { visible: false }
|
|
4034
4475
|
});
|
|
4035
4476
|
headerRow.add(this.headerActions);
|
|
4036
|
-
this.headerPanel = new
|
|
4477
|
+
this.headerPanel = new TextRenderable6(renderer2, { id: "omnius-header-panel", content: "", width: "100%", wrapMode: "word", visible: false });
|
|
4037
4478
|
this.header.add(this.headerPanel);
|
|
4038
|
-
this.detailButton = new
|
|
4479
|
+
this.detailButton = new TextRenderable6(renderer2, {
|
|
4039
4480
|
id: "omnius-details-toggle",
|
|
4040
4481
|
content: "+ DETAILS",
|
|
4041
4482
|
height: 1,
|
|
4042
4483
|
width: 9,
|
|
4043
4484
|
flexShrink: 0,
|
|
4044
4485
|
fg: colors.foreground,
|
|
4045
|
-
attributes:
|
|
4486
|
+
attributes: TextAttributes8.DIM,
|
|
4046
4487
|
selectable: false,
|
|
4047
4488
|
onMouseDown: (event) => {
|
|
4048
4489
|
if (event.button === 0) {
|
|
@@ -4062,60 +4503,67 @@ var NativeFrontend = class {
|
|
|
4062
4503
|
for (const control of [this.identity, this.detailButton]) {
|
|
4063
4504
|
const attributes = control.attributes;
|
|
4064
4505
|
control.on("focused", () => {
|
|
4065
|
-
control.attributes = attributes |
|
|
4506
|
+
control.attributes = attributes | TextAttributes8.INVERSE;
|
|
4066
4507
|
});
|
|
4067
4508
|
control.on("blurred", () => {
|
|
4068
4509
|
control.attributes = attributes;
|
|
4069
4510
|
});
|
|
4070
4511
|
}
|
|
4071
|
-
this.
|
|
4072
|
-
|
|
4073
|
-
this.tabs = new TabSelectRenderable(renderer2, {
|
|
4074
|
-
id: "omnius-agent-tabs",
|
|
4512
|
+
this.sessionRow = new BoxRenderable7(renderer2, {
|
|
4513
|
+
id: "omnius-sessions-row",
|
|
4075
4514
|
width: "100%",
|
|
4076
|
-
height:
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4515
|
+
height: 1,
|
|
4516
|
+
minWidth: 0,
|
|
4517
|
+
flexShrink: 0,
|
|
4518
|
+
flexDirection: "row",
|
|
4519
|
+
gap: 1,
|
|
4520
|
+
visible: false
|
|
4521
|
+
});
|
|
4522
|
+
this.header.add(this.sessionRow);
|
|
4523
|
+
this.sessions = new NativeTabStrip(renderer2, {
|
|
4524
|
+
id: "omnius-session-tabs",
|
|
4525
|
+
prefix: "session",
|
|
4526
|
+
colors,
|
|
4527
|
+
activate: (id) => this.emitAction("session", id)
|
|
4528
|
+
});
|
|
4529
|
+
this.sessionRow.add(this.sessions);
|
|
4530
|
+
this.newSession = new TextRenderable6(renderer2, {
|
|
4531
|
+
id: "omnius-session-new",
|
|
4532
|
+
content: "+ NEW",
|
|
4533
|
+
width: 5,
|
|
4534
|
+
height: 1,
|
|
4535
|
+
flexShrink: 0,
|
|
4536
|
+
selectable: false,
|
|
4537
|
+
fg: colors.foreground,
|
|
4538
|
+
bg: colors.background,
|
|
4088
4539
|
onMouseDown: (event) => {
|
|
4089
|
-
if (event.button
|
|
4090
|
-
|
|
4091
|
-
const start = Math.max(0, Math.min(this.tabs.getSelectedIndex() - Math.floor(count / 2), this.tabs.options.length - count));
|
|
4092
|
-
this.tabs.setSelectedIndex(start + Math.floor((event.x - this.tabs.x) / this.tabs.getTabWidth()));
|
|
4540
|
+
if (event.button === 0 && !this.state?.sessions?.busy) this.emitAction("session-new");
|
|
4541
|
+
event.preventDefault();
|
|
4093
4542
|
event.stopPropagation();
|
|
4543
|
+
},
|
|
4544
|
+
onKeyDown: (key) => {
|
|
4545
|
+
if (key.eventType !== "release" && (key.name === "return" || key.sequence === " ")) {
|
|
4546
|
+
if (!this.state?.sessions?.busy) this.emitAction("session-new");
|
|
4547
|
+
key.preventDefault();
|
|
4548
|
+
key.stopPropagation();
|
|
4549
|
+
}
|
|
4094
4550
|
}
|
|
4095
4551
|
});
|
|
4096
|
-
this.
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
if (selected) this.emitAction("view", String(selected.value));
|
|
4100
|
-
this.editor.focus();
|
|
4101
|
-
});
|
|
4102
|
-
this.tabs.renderAfter = (buffer) => {
|
|
4103
|
-
if (this.tabs.height < 2) return;
|
|
4104
|
-
const colors2 = this.context.colors;
|
|
4105
|
-
const tabWidth = Math.min(this.tabs.getTabWidth(), this.tabs.width);
|
|
4106
|
-
const count = Math.max(1, Math.floor(this.tabs.width / Math.max(1, tabWidth)));
|
|
4107
|
-
const selected = this.tabs.getSelectedIndex();
|
|
4108
|
-
const start = Math.max(0, Math.min(selected - Math.floor(count / 2), this.tabs.options.length - count));
|
|
4109
|
-
buffer.fillRect(0, 1, this.tabs.width, 1, colors2.background);
|
|
4110
|
-
buffer.drawText("─".repeat(Math.max(0, tabWidth)), (selected - start) * tabWidth, 1, colors2.foreground, colors2.background, TextAttributes6.DIM);
|
|
4552
|
+
this.newSession.focusable = true;
|
|
4553
|
+
const styleNew = () => {
|
|
4554
|
+
this.newSession.attributes = (this.state?.sessions?.busy ? TextAttributes8.DIM : 0) | (this.newSession.focused ? TextAttributes8.INVERSE : 0);
|
|
4111
4555
|
};
|
|
4112
|
-
this.
|
|
4113
|
-
this.
|
|
4556
|
+
this.newSession.on("focused", styleNew);
|
|
4557
|
+
this.newSession.on("blurred", styleNew);
|
|
4558
|
+
this.sessionRow.add(this.newSession);
|
|
4559
|
+
this.routeWarning = new TextRenderable6(renderer2, { id: "omnius-route-warning", content: "", width: "100%", wrapMode: "word", fg: colors.warning, attributes: TextAttributes8.BOLD | TextAttributes8.UNDERLINE, visible: false, flexShrink: 0 });
|
|
4560
|
+
this.root.add(this.routeWarning);
|
|
4561
|
+
this.taskPane = new BoxRenderable7(renderer2, { id: "omnius-tasks", width: "100%", flexDirection: "column", maxHeight: 6, flexShrink: 0, overflow: "hidden", visible: false });
|
|
4114
4562
|
this.tasks = new NativeBlockList(this.context, this.taskPane);
|
|
4115
4563
|
this.root.add(this.taskPane);
|
|
4116
|
-
this.body = new
|
|
4564
|
+
this.body = new BoxRenderable7(renderer2, { id: "omnius-body", width: "100%", flexDirection: "row", flexGrow: 1, minHeight: 1 });
|
|
4117
4565
|
this.root.add(this.body);
|
|
4118
|
-
this.scroll = new
|
|
4566
|
+
this.scroll = new ScrollBoxRenderable5(renderer2, {
|
|
4119
4567
|
id: "omnius-conversation",
|
|
4120
4568
|
flexGrow: 1,
|
|
4121
4569
|
flexShrink: 1,
|
|
@@ -4128,6 +4576,15 @@ var NativeFrontend = class {
|
|
|
4128
4576
|
viewportCulling: true,
|
|
4129
4577
|
verticalScrollbarOptions: { showArrows: false, trackOptions: { foregroundColor: colors.dim, backgroundColor: colors.background } },
|
|
4130
4578
|
contentOptions: { flexDirection: "column", onMouseDown: (event) => {
|
|
4579
|
+
if (event.button === 2) {
|
|
4580
|
+
const selected = this.renderer.getSelection()?.getSelectedText();
|
|
4581
|
+
if (selected) {
|
|
4582
|
+
this.selectionMenu.open(event.x, event.y, selected);
|
|
4583
|
+
event.preventDefault();
|
|
4584
|
+
event.stopPropagation();
|
|
4585
|
+
}
|
|
4586
|
+
return;
|
|
4587
|
+
}
|
|
4131
4588
|
if (!this.selectionArmed || event.button !== 0 || !event.target) return;
|
|
4132
4589
|
this.selectionArmed = false;
|
|
4133
4590
|
let block = event.target;
|
|
@@ -4147,6 +4604,18 @@ var NativeFrontend = class {
|
|
|
4147
4604
|
}
|
|
4148
4605
|
event.preventDefault();
|
|
4149
4606
|
event.stopPropagation();
|
|
4607
|
+
}, onMouseDrag: (event) => {
|
|
4608
|
+
if (!event.isDragging || !event.target || !this.renderer.getSelection()?.isDragging) return;
|
|
4609
|
+
let container = this.renderer.getSelectionContainer();
|
|
4610
|
+
while (container) {
|
|
4611
|
+
let current = event.target;
|
|
4612
|
+
while (current && current !== container) current = current.parent;
|
|
4613
|
+
if (current) break;
|
|
4614
|
+
this.renderer.updateSelection(event.target, event.x, event.y);
|
|
4615
|
+
const next = this.renderer.getSelectionContainer();
|
|
4616
|
+
if (next === container) break;
|
|
4617
|
+
container = next;
|
|
4618
|
+
}
|
|
4150
4619
|
} }
|
|
4151
4620
|
});
|
|
4152
4621
|
this.body.add(this.scroll);
|
|
@@ -4167,7 +4636,7 @@ var NativeFrontend = class {
|
|
|
4167
4636
|
this.root.onMouseUp = (event) => this.instrumentDivider.handleRelease(event);
|
|
4168
4637
|
this.instruments = new InstrumentRail(renderer2, { colors, onInspectAgent: (id) => this.emitAction("view", id), onAction: (command2) => this.emitAction(command2) });
|
|
4169
4638
|
this.body.add(this.instruments);
|
|
4170
|
-
this.embeddedPane = new
|
|
4639
|
+
this.embeddedPane = new BoxRenderable7(renderer2, {
|
|
4171
4640
|
id: "omnius-editor-pane",
|
|
4172
4641
|
width: "50%",
|
|
4173
4642
|
flexShrink: 0,
|
|
@@ -4178,7 +4647,7 @@ var NativeFrontend = class {
|
|
|
4178
4647
|
visible: false
|
|
4179
4648
|
});
|
|
4180
4649
|
this.body.add(this.embeddedPane);
|
|
4181
|
-
this.liveButton = new
|
|
4650
|
+
this.liveButton = new TextRenderable6(renderer2, {
|
|
4182
4651
|
id: "omnius-live-button",
|
|
4183
4652
|
content: "↓ Live",
|
|
4184
4653
|
width: "100%",
|
|
@@ -4201,7 +4670,7 @@ var NativeFrontend = class {
|
|
|
4201
4670
|
});
|
|
4202
4671
|
this.liveButton.focusable = true;
|
|
4203
4672
|
this.root.add(this.liveButton);
|
|
4204
|
-
this.queue = new
|
|
4673
|
+
this.queue = new TextRenderable6(renderer2, { id: "omnius-steering-queue", content: "", width: "100%", height: 1, wrapMode: "none", truncate: true, fg: colors.dim, visible: false, flexShrink: 0 });
|
|
4205
4674
|
this.root.add(this.queue);
|
|
4206
4675
|
this.suggestions = new NativeSelectRenderable(renderer2, {
|
|
4207
4676
|
id: "omnius-suggestions",
|
|
@@ -4220,21 +4689,49 @@ var NativeFrontend = class {
|
|
|
4220
4689
|
this.suggestions.onActivate = () => this.acceptSuggestion();
|
|
4221
4690
|
this.suggestions.on("itemSelected", () => this.acceptSuggestion());
|
|
4222
4691
|
this.root.add(this.suggestions);
|
|
4223
|
-
this.status = new
|
|
4692
|
+
this.status = new BoxRenderable7(renderer2, { id: "omnius-live-status", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 2, visible: false });
|
|
4224
4693
|
this.root.add(this.status);
|
|
4225
|
-
this.footer = new
|
|
4694
|
+
this.footer = new BoxRenderable7(renderer2, {
|
|
4226
4695
|
id: "omnius-input-box",
|
|
4227
4696
|
width: "100%",
|
|
4228
4697
|
flexShrink: 0,
|
|
4229
|
-
border: [
|
|
4230
|
-
borderStyle: "single",
|
|
4698
|
+
border: [],
|
|
4231
4699
|
borderColor: colors.border,
|
|
4232
4700
|
flexDirection: "column"
|
|
4233
4701
|
});
|
|
4234
4702
|
this.root.add(this.footer);
|
|
4235
|
-
|
|
4703
|
+
this.footerRule = new BoxRenderable7(renderer2, {
|
|
4704
|
+
id: "omnius-input-rule",
|
|
4705
|
+
width: "100%",
|
|
4706
|
+
height: 1,
|
|
4707
|
+
minHeight: 1,
|
|
4708
|
+
maxHeight: 1,
|
|
4709
|
+
flexShrink: 0,
|
|
4710
|
+
flexDirection: "row",
|
|
4711
|
+
paddingLeft: 2,
|
|
4712
|
+
shouldFill: false
|
|
4713
|
+
});
|
|
4714
|
+
this.footer.add(this.footerRule);
|
|
4715
|
+
this.tabs = new NativeTabStrip(renderer2, {
|
|
4716
|
+
id: "omnius-agent-tabs",
|
|
4717
|
+
prefix: "agent",
|
|
4718
|
+
colors,
|
|
4719
|
+
activate: (id) => this.emitAction("view", id)
|
|
4720
|
+
});
|
|
4721
|
+
this.tabs.flexGrow = 0;
|
|
4722
|
+
this.tabs.flexShrink = 0;
|
|
4723
|
+
this.tabs.visible = false;
|
|
4724
|
+
this.footerRule.add(this.tabs);
|
|
4725
|
+
this.footerRule.renderBefore = (buffer) => {
|
|
4726
|
+
buffer.drawText(formatSignalDivider(this.footerRule.width, {
|
|
4727
|
+
direction: "bottom",
|
|
4728
|
+
leftTextEnd: this.tabs.visible ? this.tabs.x - this.footerRule.x + this.tabs.width : 0,
|
|
4729
|
+
sidebarColumn: this.instrumentDivider.visible && this.instruments.visible ? this.instrumentDivider.x - this.footerRule.x : void 0
|
|
4730
|
+
}), this.footerRule.x, this.footerRule.y, this.context.colors.foreground, this.context.colors.background, TextAttributes8.DIM);
|
|
4731
|
+
};
|
|
4732
|
+
const inputRow = new BoxRenderable7(renderer2, { id: "omnius-input-row", width: "100%", flexDirection: "row", gap: 1 });
|
|
4236
4733
|
this.footer.add(inputRow);
|
|
4237
|
-
this.prompt = new
|
|
4734
|
+
this.prompt = new TextRenderable6(renderer2, { id: "omnius-prompt", content: "❯", fg: colors.accent, wrapMode: "none", selectable: false, flexShrink: 0 });
|
|
4238
4735
|
inputRow.add(this.prompt);
|
|
4239
4736
|
this.editor = new TextareaRenderable2(renderer2, {
|
|
4240
4737
|
id: "omnius-input",
|
|
@@ -4254,14 +4751,14 @@ var NativeFrontend = class {
|
|
|
4254
4751
|
onCursorChange: () => this.editorChanged(),
|
|
4255
4752
|
onSubmit: () => this.submit()
|
|
4256
4753
|
});
|
|
4257
|
-
this.vimMode = new
|
|
4754
|
+
this.vimMode = new TextRenderable6(renderer2, {
|
|
4258
4755
|
id: "omnius-vim-mode",
|
|
4259
4756
|
content: "INSERT",
|
|
4260
4757
|
height: 1,
|
|
4261
4758
|
maxWidth: 12,
|
|
4262
4759
|
flexShrink: 0,
|
|
4263
4760
|
fg: colors.foreground,
|
|
4264
|
-
attributes:
|
|
4761
|
+
attributes: TextAttributes8.DIM,
|
|
4265
4762
|
wrapMode: "none",
|
|
4266
4763
|
truncate: true,
|
|
4267
4764
|
visible: false,
|
|
@@ -4275,31 +4772,42 @@ var NativeFrontend = class {
|
|
|
4275
4772
|
this.renderer.requestRender();
|
|
4276
4773
|
});
|
|
4277
4774
|
inputRow.add(this.editor);
|
|
4278
|
-
this.enhance = new
|
|
4775
|
+
this.enhance = new BoxRenderable7(renderer2, { id: "omnius-enhance", flexDirection: "row", gap: 1, flexShrink: 0, visible: false });
|
|
4279
4776
|
inputRow.add(this.enhance);
|
|
4280
|
-
this.activity = new
|
|
4777
|
+
this.activity = new TextRenderable6(renderer2, { id: "omnius-activity", content: "", flexGrow: 1, minWidth: 0, height: 1, wrapMode: "none", truncate: true, visible: false, fg: colors.accent });
|
|
4281
4778
|
this.status.add(this.activity);
|
|
4282
|
-
this.media = new
|
|
4283
|
-
this.mediaText = new
|
|
4779
|
+
this.media = new BoxRenderable7(renderer2, { id: "omnius-media", height: 1, minWidth: 0, flexShrink: 1, flexDirection: "row", gap: 1, visible: false });
|
|
4780
|
+
this.mediaText = new TextRenderable6(renderer2, { id: "omnius-media-text", content: "", flexGrow: 1, minWidth: 0, wrapMode: "none", truncate: true, fg: colors.accent });
|
|
4284
4781
|
this.media.add(this.mediaText);
|
|
4285
|
-
this.micTrack = new
|
|
4782
|
+
this.micTrack = new TextRenderable6(renderer2, { id: "omnius-mic-meter", width: 12, height: 1, flexShrink: 0, fg: colors.foreground, visible: false });
|
|
4286
4783
|
this.media.add(this.micTrack);
|
|
4287
4784
|
this.status.add(this.media);
|
|
4288
|
-
this.
|
|
4289
|
-
|
|
4785
|
+
this.copyFeedback = new TextRenderable6(renderer2, {
|
|
4786
|
+
id: "omnius-copy-feedback",
|
|
4787
|
+
content: "",
|
|
4788
|
+
height: 1,
|
|
4789
|
+
flexShrink: 0,
|
|
4790
|
+
fg: colors.foreground,
|
|
4791
|
+
attributes: TextAttributes8.DIM,
|
|
4792
|
+
selectable: false,
|
|
4793
|
+
visible: false
|
|
4794
|
+
});
|
|
4795
|
+
this.status.add(this.copyFeedback);
|
|
4796
|
+
this.metricsRow = new BoxRenderable7(renderer2, { id: "omnius-metrics-row", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 1 });
|
|
4797
|
+
this.keyHints = new TextRenderable6(renderer2, { id: "omnius-key-hints", content: "F1 HELP TAB FOCUS", height: 1, flexShrink: 0, attributes: TextAttributes8.DIM, fg: colors.foreground, selectable: false });
|
|
4290
4798
|
this.metricsRow.add(this.keyHints);
|
|
4291
|
-
this.metricsStartActions = new
|
|
4799
|
+
this.metricsStartActions = new BoxRenderable7(renderer2, { id: "omnius-metrics-start-actions", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
4292
4800
|
this.metricsRow.add(this.metricsStartActions);
|
|
4293
|
-
this.metrics = new
|
|
4801
|
+
this.metrics = new TextRenderable6(renderer2, { id: "omnius-metrics", content: "", height: 1, wrapMode: "none", truncate: true, fg: colors.dim, flexShrink: 1, flexGrow: 1, minWidth: 0 });
|
|
4294
4802
|
this.metricsRow.add(this.metrics);
|
|
4295
|
-
this.metricsEndActions = new
|
|
4803
|
+
this.metricsEndActions = new BoxRenderable7(renderer2, { id: "omnius-metrics-end-actions", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
4296
4804
|
this.metricsRow.add(this.metricsEndActions);
|
|
4297
4805
|
this.root.add(this.metricsRow);
|
|
4298
4806
|
this.modals = new NativeModalStack(this.context, () => this.restoreFocus());
|
|
4299
4807
|
renderer2.keyInput.on("keypress", this.onKey);
|
|
4300
4808
|
renderer2.keyInput.on("paste", this.onPaste);
|
|
4301
|
-
renderer2.on(
|
|
4302
|
-
renderer2.on(
|
|
4809
|
+
renderer2.on(CliRenderEvents5.FRAME, this.onFrame);
|
|
4810
|
+
renderer2.on(CliRenderEvents5.RESIZE, this.onResize);
|
|
4303
4811
|
this.applyTheme(initialTheme);
|
|
4304
4812
|
this.editor.focus();
|
|
4305
4813
|
}
|
|
@@ -4312,12 +4820,16 @@ var NativeFrontend = class {
|
|
|
4312
4820
|
content;
|
|
4313
4821
|
modals;
|
|
4314
4822
|
context;
|
|
4823
|
+
selectionMenu;
|
|
4315
4824
|
header;
|
|
4316
4825
|
identity;
|
|
4317
4826
|
headerActions;
|
|
4318
4827
|
headerPanel;
|
|
4319
4828
|
routeWarning;
|
|
4320
4829
|
tabs;
|
|
4830
|
+
sessionRow;
|
|
4831
|
+
sessions;
|
|
4832
|
+
newSession;
|
|
4321
4833
|
taskPane;
|
|
4322
4834
|
tasks;
|
|
4323
4835
|
body;
|
|
@@ -4329,6 +4841,7 @@ var NativeFrontend = class {
|
|
|
4329
4841
|
queue;
|
|
4330
4842
|
suggestions;
|
|
4331
4843
|
footer;
|
|
4844
|
+
footerRule;
|
|
4332
4845
|
prompt;
|
|
4333
4846
|
vimMode;
|
|
4334
4847
|
enhance;
|
|
@@ -4343,10 +4856,11 @@ var NativeFrontend = class {
|
|
|
4343
4856
|
mediaText;
|
|
4344
4857
|
micTrack;
|
|
4345
4858
|
clipboard;
|
|
4859
|
+
copyFeedback;
|
|
4860
|
+
copyFeedbackTimer;
|
|
4346
4861
|
state;
|
|
4347
4862
|
themeSignature = "";
|
|
4348
4863
|
headerSignature = "";
|
|
4349
|
-
tabsSignature = "";
|
|
4350
4864
|
suggestionSignature = "";
|
|
4351
4865
|
metricsActionsSignature = "";
|
|
4352
4866
|
changing = false;
|
|
@@ -4374,8 +4888,8 @@ var NativeFrontend = class {
|
|
|
4374
4888
|
selectionArmed = false;
|
|
4375
4889
|
update(state, patch) {
|
|
4376
4890
|
const inputWasEnabled = this.state?.input.enabled;
|
|
4377
|
-
const previousView = this.state ? `${this.state.activeViewId}:${this.state.presentation ?? "stack"}` : void 0;
|
|
4378
|
-
const currentView = `${state.activeViewId}:${state.presentation ?? "stack"}`;
|
|
4891
|
+
const previousView = this.state ? `${this.state.sessions?.activeId ?? ""}:${this.state.activeViewId}:${this.state.presentation ?? "stack"}` : void 0;
|
|
4892
|
+
const currentView = `${state.sessions?.activeId ?? ""}:${state.activeViewId}:${state.presentation ?? "stack"}`;
|
|
4379
4893
|
const viewChanged = previousView !== void 0 && previousView !== currentView;
|
|
4380
4894
|
if (viewChanged) {
|
|
4381
4895
|
this.viewScroll.set(previousView, { top: this.scroll.scrollTop, live: this.offset === 0 });
|
|
@@ -4401,14 +4915,13 @@ var NativeFrontend = class {
|
|
|
4401
4915
|
}
|
|
4402
4916
|
this.routeWarning.content = state.routeWarning ? `! ${state.routeWarning}` : "";
|
|
4403
4917
|
this.routeWarning.visible = Boolean(state.routeWarning);
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
this.
|
|
4410
|
-
|
|
4411
|
-
if (activeTab >= 0 && activeTab !== this.tabs.getSelectedIndex()) this.tabs.setSelectedIndex(activeTab);
|
|
4918
|
+
this.tabs.update(state.tabs, state.activeViewId);
|
|
4919
|
+
this.tabs.visible = state.tabs.some((tab) => tab.id !== "main");
|
|
4920
|
+
this.sessionRow.visible = Boolean(state.sessions);
|
|
4921
|
+
this.sessions.update(state.sessions?.items ?? [], state.sessions?.activeId ?? "", state.sessions?.busy);
|
|
4922
|
+
this.newSession.focusable = !state.sessions?.busy;
|
|
4923
|
+
if (state.sessions?.busy && this.newSession.focused) this.getRenderable(`session:${state.sessions.activeId}`)?.focus();
|
|
4924
|
+
this.newSession.attributes = state.sessions?.busy ? TextAttributes8.DIM : this.newSession.focused ? TextAttributes8.INVERSE : 0;
|
|
4412
4925
|
this.tasks.replace(state.tasks);
|
|
4413
4926
|
this.taskPane.visible = state.tasks.length > 0;
|
|
4414
4927
|
if (patch) {
|
|
@@ -4430,7 +4943,7 @@ var NativeFrontend = class {
|
|
|
4430
4943
|
this.prompt.content = styledText(state.prompt.trimEnd() || "❯");
|
|
4431
4944
|
if (!this.editorInitialized) {
|
|
4432
4945
|
this.editor.setText(state.input.text);
|
|
4433
|
-
this.
|
|
4946
|
+
this.placeInputCursor(state.input.text, state.input.cursor);
|
|
4434
4947
|
this.editorInitialized = true;
|
|
4435
4948
|
}
|
|
4436
4949
|
this.editor.focusable = state.input.enabled && !this.paused;
|
|
@@ -4439,6 +4952,7 @@ var NativeFrontend = class {
|
|
|
4439
4952
|
this.metrics.visible = state.metricsVisible;
|
|
4440
4953
|
this.instruments.update(state);
|
|
4441
4954
|
this.layoutInstruments();
|
|
4955
|
+
this.layoutTabStrips();
|
|
4442
4956
|
const metricsActions = JSON.stringify(state.metricsActions ?? []);
|
|
4443
4957
|
if (metricsActions !== this.metricsActionsSignature) {
|
|
4444
4958
|
this.metricsActionsSignature = metricsActions;
|
|
@@ -4461,8 +4975,8 @@ var NativeFrontend = class {
|
|
|
4461
4975
|
for (const child of [...parent.getChildren()]) child.destroy();
|
|
4462
4976
|
for (const action of actions) {
|
|
4463
4977
|
const colors = this.context.colors;
|
|
4464
|
-
const attributes = action.disabled ?
|
|
4465
|
-
const button = new
|
|
4978
|
+
const attributes = action.disabled ? TextAttributes8.DIM : action.active ? TextAttributes8.BOLD | TextAttributes8.UNDERLINE : 0;
|
|
4979
|
+
const button = new TextRenderable6(this.renderer, {
|
|
4466
4980
|
id: `${prefix}:${action.id}`,
|
|
4467
4981
|
content: styledText(action.label),
|
|
4468
4982
|
flexShrink: 0,
|
|
@@ -4485,16 +4999,16 @@ var NativeFrontend = class {
|
|
|
4485
4999
|
button.focusable = !action.disabled;
|
|
4486
5000
|
if (!action.disabled) {
|
|
4487
5001
|
button.on("focused", () => {
|
|
4488
|
-
button.attributes = attributes |
|
|
5002
|
+
button.attributes = attributes | TextAttributes8.INVERSE;
|
|
4489
5003
|
});
|
|
4490
5004
|
button.on("blurred", () => {
|
|
4491
5005
|
button.attributes = attributes;
|
|
4492
5006
|
});
|
|
4493
5007
|
button.onMouseOver = () => {
|
|
4494
|
-
button.attributes = attributes |
|
|
5008
|
+
button.attributes = attributes | TextAttributes8.UNDERLINE | (button.focused ? TextAttributes8.INVERSE : 0);
|
|
4495
5009
|
};
|
|
4496
5010
|
button.onMouseOut = () => {
|
|
4497
|
-
button.attributes = attributes | (button.focused ?
|
|
5011
|
+
button.attributes = attributes | (button.focused ? TextAttributes8.INVERSE : 0);
|
|
4498
5012
|
};
|
|
4499
5013
|
}
|
|
4500
5014
|
parent.add(button);
|
|
@@ -4513,12 +5027,12 @@ var NativeFrontend = class {
|
|
|
4513
5027
|
const reading = activity?.label || stage || this.state?.instruments?.runtimeStatus || "";
|
|
4514
5028
|
this.activity.visible = Boolean(activity?.processing || reading);
|
|
4515
5029
|
this.activity.content = `${activity?.processing ? "RUN · " : ""}${reading}`;
|
|
4516
|
-
this.status.visible = this.activity.visible || this.media.visible;
|
|
5030
|
+
this.status.visible = this.activity.visible || this.media.visible || this.copyFeedback.visible;
|
|
4517
5031
|
}
|
|
4518
5032
|
renderMedia() {
|
|
4519
5033
|
const media = this.state?.media;
|
|
4520
5034
|
this.media.visible = Boolean(media && (media.audio || media.video || media.voiceEnabled || media.recording || media.countdown > 0 || media.label));
|
|
4521
|
-
this.status.visible = this.activity.visible || this.media.visible;
|
|
5035
|
+
this.status.visible = this.activity.visible || this.media.visible || this.copyFeedback.visible;
|
|
4522
5036
|
if (!media) return;
|
|
4523
5037
|
this.mediaText.content = [
|
|
4524
5038
|
media.recording ? "● REC" : void 0,
|
|
@@ -4556,10 +5070,10 @@ var NativeFrontend = class {
|
|
|
4556
5070
|
this.editor.backgroundColor = this.editor.focusedBackgroundColor = colors.background;
|
|
4557
5071
|
this.editor.textColor = this.editor.focusedTextColor = colors.foreground;
|
|
4558
5072
|
this.editor.editorView.setSelectionColors(void 0, void 0);
|
|
4559
|
-
this.tabs.
|
|
4560
|
-
this.
|
|
4561
|
-
this.
|
|
4562
|
-
this.
|
|
5073
|
+
this.tabs.applyTheme(colors);
|
|
5074
|
+
this.sessions.applyTheme(colors);
|
|
5075
|
+
this.newSession.fg = colors.foreground;
|
|
5076
|
+
this.newSession.bg = colors.background;
|
|
4563
5077
|
this.suggestions.backgroundColor = this.suggestions.focusedBackgroundColor = colors.background;
|
|
4564
5078
|
this.suggestions.textColor = colors.dim;
|
|
4565
5079
|
this.suggestions.selectedTextColor = colors.foreground;
|
|
@@ -4569,6 +5083,8 @@ var NativeFrontend = class {
|
|
|
4569
5083
|
this.instruments.applyTheme(colors);
|
|
4570
5084
|
this.instrumentDivider.fg = colors.foreground;
|
|
4571
5085
|
this.instrumentDivider.bg = colors.background;
|
|
5086
|
+
this.copyFeedback.fg = colors.foreground;
|
|
5087
|
+
this.selectionMenu.applyTheme(colors);
|
|
4572
5088
|
this.content.applyTheme();
|
|
4573
5089
|
this.tasks.applyTheme();
|
|
4574
5090
|
this.modals?.applyTheme();
|
|
@@ -4669,6 +5185,7 @@ var NativeFrontend = class {
|
|
|
4669
5185
|
}
|
|
4670
5186
|
const height = Math.max(1, Math.min(8, this.editor.editorView.getTotalVirtualLineCount(), this.renderer.terminalHeight - 8));
|
|
4671
5187
|
if (height !== this.editor.height) this.editor.height = height;
|
|
5188
|
+
this.layoutTabStrips();
|
|
4672
5189
|
const offset = this.offset;
|
|
4673
5190
|
if (offset === 0) this.newEntries = 0;
|
|
4674
5191
|
this.liveButton.visible = offset > 0;
|
|
@@ -4683,8 +5200,16 @@ var NativeFrontend = class {
|
|
|
4683
5200
|
};
|
|
4684
5201
|
onResize = () => {
|
|
4685
5202
|
this.layoutInstruments();
|
|
5203
|
+
this.layoutTabStrips();
|
|
4686
5204
|
this.emit({ type: "resize", columns: this.renderer.terminalWidth, rows: this.renderer.terminalHeight });
|
|
4687
5205
|
};
|
|
5206
|
+
layoutTabStrips() {
|
|
5207
|
+
const width = this.renderer.terminalWidth;
|
|
5208
|
+
const junction = this.instrumentDivider.visible && this.instruments.visible ? this.instrumentDivider.x : width - 3;
|
|
5209
|
+
const available = Math.max(0, junction - 6);
|
|
5210
|
+
const desired = Math.min(this.tabs.naturalWidth, available);
|
|
5211
|
+
if (this.tabs.width !== desired) this.tabs.width = desired;
|
|
5212
|
+
}
|
|
4688
5213
|
editorChanged() {
|
|
4689
5214
|
if (!this.editor || this.changing || this.destroyed || this.inputEventPending) return;
|
|
4690
5215
|
this.inputEventPending = true;
|
|
@@ -4698,7 +5223,7 @@ var NativeFrontend = class {
|
|
|
4698
5223
|
}
|
|
4699
5224
|
flushLatestInput() {
|
|
4700
5225
|
const text = this.editor.plainText;
|
|
4701
|
-
const cursor = this.
|
|
5226
|
+
const cursor = this.inputCursor();
|
|
4702
5227
|
if (text === this.lastInput && cursor === this.lastCursor) return;
|
|
4703
5228
|
this.lastInput = text;
|
|
4704
5229
|
this.lastCursor = cursor;
|
|
@@ -4741,10 +5266,17 @@ var NativeFrontend = class {
|
|
|
4741
5266
|
}
|
|
4742
5267
|
setInput(text, cursor = text.length) {
|
|
4743
5268
|
this.editor.replaceText(text);
|
|
4744
|
-
this.
|
|
5269
|
+
this.placeInputCursor(text, cursor);
|
|
4745
5270
|
this.editorInitialized = true;
|
|
4746
5271
|
this.editorChanged();
|
|
4747
5272
|
}
|
|
5273
|
+
inputCursor() {
|
|
5274
|
+
return this.editor.getTextRange(0, this.editor.cursorOffset).length;
|
|
5275
|
+
}
|
|
5276
|
+
placeInputCursor(text, cursor) {
|
|
5277
|
+
const index = Math.max(0, Math.min(text.length, cursor));
|
|
5278
|
+
this.editor.cursorOffset = this.editor.editBuffer.measureText(text.slice(0, index));
|
|
5279
|
+
}
|
|
4748
5280
|
shortcut(name, key) {
|
|
4749
5281
|
this.flushLatestInput();
|
|
4750
5282
|
this.emit({ type: "shortcut", name });
|
|
@@ -4756,6 +5288,10 @@ var NativeFrontend = class {
|
|
|
4756
5288
|
this.emit({ type: "action", action, ...id === void 0 ? {} : { id } });
|
|
4757
5289
|
}
|
|
4758
5290
|
onKey = (key) => {
|
|
5291
|
+
if (this.selectionMenu.active) {
|
|
5292
|
+
this.selectionMenu.handleKey(key);
|
|
5293
|
+
return;
|
|
5294
|
+
}
|
|
4759
5295
|
if (this.modals.active) {
|
|
4760
5296
|
this.modals.active.handleKey(key);
|
|
4761
5297
|
return;
|
|
@@ -4908,7 +5444,7 @@ var NativeFrontend = class {
|
|
|
4908
5444
|
const targets = [];
|
|
4909
5445
|
const visit = (node) => {
|
|
4910
5446
|
if (!node.visible) return;
|
|
4911
|
-
if (node.focusable && node !== this.scroll && !(node instanceof
|
|
5447
|
+
if (node.focusable && node !== this.scroll && !(node instanceof ScrollBoxRenderable5) && node.height > 0 && node.width > 0) targets.push(node);
|
|
4912
5448
|
for (const child of node.getChildren()) visit(child);
|
|
4913
5449
|
};
|
|
4914
5450
|
visit(this.root);
|
|
@@ -4927,6 +5463,10 @@ var NativeFrontend = class {
|
|
|
4927
5463
|
}
|
|
4928
5464
|
}
|
|
4929
5465
|
onPaste = (event) => {
|
|
5466
|
+
if (this.selectionMenu.active) {
|
|
5467
|
+
event.preventDefault();
|
|
5468
|
+
return;
|
|
5469
|
+
}
|
|
4930
5470
|
if (this.modals.active) {
|
|
4931
5471
|
this.modals.active.handlePaste(event);
|
|
4932
5472
|
return;
|
|
@@ -4943,8 +5483,27 @@ var NativeFrontend = class {
|
|
|
4943
5483
|
else if (!this.paused && this.state?.input.enabled !== false) this.editor.focus();
|
|
4944
5484
|
}
|
|
4945
5485
|
async copy(text) {
|
|
4946
|
-
const value = text ?? this.renderer.getSelection()?.getSelectedText()
|
|
4947
|
-
if (value)
|
|
5486
|
+
const value = text ?? (this.renderer.getSelection()?.getSelectedText() || this.editor.getSelectedText());
|
|
5487
|
+
if (!value) return;
|
|
5488
|
+
let message;
|
|
5489
|
+
try {
|
|
5490
|
+
const result = await this.clipboard.writeText(value, { destination: "best-available" });
|
|
5491
|
+
message = result.host.status === "written" ? "COPIED" : result.terminal.status === "attempted" ? "COPY SENT TO TERMINAL" : "COPY UNAVAILABLE";
|
|
5492
|
+
} catch {
|
|
5493
|
+
message = "COPY FAILED";
|
|
5494
|
+
}
|
|
5495
|
+
if (this.destroyed) return;
|
|
5496
|
+
if (this.copyFeedbackTimer) clearTimeout(this.copyFeedbackTimer);
|
|
5497
|
+
this.copyFeedback.content = message;
|
|
5498
|
+
this.copyFeedback.visible = true;
|
|
5499
|
+
this.status.visible = true;
|
|
5500
|
+
this.renderer.requestRender();
|
|
5501
|
+
this.copyFeedbackTimer = setTimeout(() => {
|
|
5502
|
+
this.copyFeedbackTimer = void 0;
|
|
5503
|
+
this.copyFeedback.visible = false;
|
|
5504
|
+
this.status.visible = this.activity.visible || this.media.visible;
|
|
5505
|
+
this.renderer.requestRender();
|
|
5506
|
+
}, 3e3);
|
|
4948
5507
|
}
|
|
4949
5508
|
async paste() {
|
|
4950
5509
|
const result = await this.clipboard.read({ preferredTypes: ["text/plain;charset=utf-8", "text/plain"] });
|
|
@@ -4967,7 +5526,7 @@ var NativeFrontend = class {
|
|
|
4967
5526
|
break;
|
|
4968
5527
|
}
|
|
4969
5528
|
case "input":
|
|
4970
|
-
if (command2.expectedText !== void 0 && command2.expectedText !== this.editor.plainText || command2.expectedCursor !== void 0 && command2.expectedCursor !== this.
|
|
5529
|
+
if (command2.expectedText !== void 0 && command2.expectedText !== this.editor.plainText || command2.expectedCursor !== void 0 && command2.expectedCursor !== this.inputCursor()) {
|
|
4971
5530
|
this.flushLatestInput();
|
|
4972
5531
|
} else this.setInput(command2.text, command2.cursor);
|
|
4973
5532
|
break;
|
|
@@ -4988,6 +5547,7 @@ var NativeFrontend = class {
|
|
|
4988
5547
|
this.renderer.setTerminalTitle(command2.text);
|
|
4989
5548
|
break;
|
|
4990
5549
|
case "modal-open":
|
|
5550
|
+
this.selectionMenu.close();
|
|
4991
5551
|
this.modals.open(command2.modal);
|
|
4992
5552
|
break;
|
|
4993
5553
|
case "modal-update":
|
|
@@ -5071,11 +5631,13 @@ var NativeFrontend = class {
|
|
|
5071
5631
|
async dispose() {
|
|
5072
5632
|
if (this.destroyed) return;
|
|
5073
5633
|
this.destroyed = true;
|
|
5634
|
+
if (this.copyFeedbackTimer) clearTimeout(this.copyFeedbackTimer);
|
|
5635
|
+
this.selectionMenu.destroy();
|
|
5074
5636
|
this.disposeSelectionContrast();
|
|
5075
5637
|
this.renderer.keyInput.off("keypress", this.onKey);
|
|
5076
5638
|
this.renderer.keyInput.off("paste", this.onPaste);
|
|
5077
|
-
this.renderer.off(
|
|
5078
|
-
this.renderer.off(
|
|
5639
|
+
this.renderer.off(CliRenderEvents5.FRAME, this.onFrame);
|
|
5640
|
+
this.renderer.off(CliRenderEvents5.RESIZE, this.onResize);
|
|
5079
5641
|
this.modals.destroy();
|
|
5080
5642
|
this.content.destroy();
|
|
5081
5643
|
this.tasks.destroy();
|
|
@@ -5086,7 +5648,7 @@ var NativeFrontend = class {
|
|
|
5086
5648
|
};
|
|
5087
5649
|
|
|
5088
5650
|
// packages/cli/src/tui/native/components/cursor.ts
|
|
5089
|
-
import { CliRenderEvents as
|
|
5651
|
+
import { CliRenderEvents as CliRenderEvents6 } from "@opentui/core";
|
|
5090
5652
|
function installTerminalCursorDefaults(renderer2, session) {
|
|
5091
5653
|
const reset = new TextEncoder().encode("\x1B]112\x07");
|
|
5092
5654
|
let disposed = false;
|
|
@@ -5136,11 +5698,11 @@ function installTerminalCursorDefaults(renderer2, session) {
|
|
|
5136
5698
|
const dispose = () => {
|
|
5137
5699
|
if (disposed) return;
|
|
5138
5700
|
disposed = true;
|
|
5139
|
-
renderer2.off(
|
|
5140
|
-
renderer2.off(
|
|
5701
|
+
renderer2.off(CliRenderEvents6.FRAME, afterFrame);
|
|
5702
|
+
renderer2.off(CliRenderEvents6.DESTROY, dispose);
|
|
5141
5703
|
};
|
|
5142
|
-
renderer2.on(
|
|
5143
|
-
renderer2.once(
|
|
5704
|
+
renderer2.on(CliRenderEvents6.FRAME, afterFrame);
|
|
5705
|
+
renderer2.once(CliRenderEvents6.DESTROY, dispose);
|
|
5144
5706
|
return { restore, dispose };
|
|
5145
5707
|
}
|
|
5146
5708
|
|
|
@@ -5216,10 +5778,10 @@ try {
|
|
|
5216
5778
|
maxFps: 60,
|
|
5217
5779
|
clearOnShutdown: false
|
|
5218
5780
|
});
|
|
5219
|
-
renderer.on(
|
|
5781
|
+
renderer.on(CliRenderEvents7.RENDER_ERROR, (event) => {
|
|
5220
5782
|
void fail(event.error);
|
|
5221
5783
|
});
|
|
5222
|
-
renderer.on(
|
|
5784
|
+
renderer.on(CliRenderEvents7.HANDLER_ERROR, (event) => {
|
|
5223
5785
|
void fail(event.error);
|
|
5224
5786
|
});
|
|
5225
5787
|
renderer.on("error", (event) => {
|