omnius 1.0.864 → 1.0.865
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 +397 -65
- package/dist/update-worker.js +21 -0
- package/docs/DISCOVERY.json +604 -0
- package/docs/DISCOVERY.md +17 -0
- package/docs/work-orders/2026-10-16-browser-instrument-dashboard.md +74 -0
- package/docs/work-orders/2026-10-16-interface-delivery.md +47 -0
- package/docs/work-orders/desktop-projects.md +9 -3
- 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 +110 -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-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/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/instrument-tui.md +36 -4
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -2,19 +2,19 @@
|
|
|
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 CliRenderEvents6, 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 BoxRenderable6,
|
|
10
|
+
CliRenderEvents as CliRenderEvents4,
|
|
11
11
|
EmbeddedTerminalRenderable as EmbeddedTerminalRenderable2,
|
|
12
12
|
ScrollBoxRenderable as ScrollBoxRenderable4,
|
|
13
13
|
SyntaxStyle as SyntaxStyle2,
|
|
14
14
|
TabSelectRenderable,
|
|
15
15
|
TextareaRenderable as TextareaRenderable2,
|
|
16
|
-
TextRenderable as
|
|
17
|
-
TextAttributes as
|
|
16
|
+
TextRenderable as TextRenderable5,
|
|
17
|
+
TextAttributes as TextAttributes7,
|
|
18
18
|
createClipboard,
|
|
19
19
|
createHostClipboard,
|
|
20
20
|
createRendererClipboardAdapter
|
|
@@ -1650,6 +1650,58 @@ import {
|
|
|
1650
1650
|
TextRenderable as TextRenderable3
|
|
1651
1651
|
} from "@opentui/core";
|
|
1652
1652
|
|
|
1653
|
+
// packages/cli/src/tui/native/components/device-history.ts
|
|
1654
|
+
var DeviceHistory = class {
|
|
1655
|
+
samples = [];
|
|
1656
|
+
append(sample) {
|
|
1657
|
+
if (!Number.isFinite(sample.at) || sample.at <= (this.samples.at(-1)?.at ?? 0)) return;
|
|
1658
|
+
this.samples.push(sample);
|
|
1659
|
+
if (this.samples.length > 120) this.samples.splice(0, this.samples.length - 120);
|
|
1660
|
+
}
|
|
1661
|
+
};
|
|
1662
|
+
function deviceHistorySparkline(samples, field, width) {
|
|
1663
|
+
const columns = Math.max(0, Math.floor(width));
|
|
1664
|
+
const latest = samples.at(-1)?.at;
|
|
1665
|
+
const values = Array(columns).fill(void 0);
|
|
1666
|
+
if (latest !== void 0) for (const sample of samples) {
|
|
1667
|
+
const x = columns - 1 - Math.round((latest - sample.at) / 2e3);
|
|
1668
|
+
if (x >= 0 && x < columns) values[x] = sample[field];
|
|
1669
|
+
}
|
|
1670
|
+
return values.map((value) => value === void 0 || !Number.isFinite(value) || value < 0 ? " " : "▁▂▃▄▅▆▇█"[Math.round(Math.min(100, value) * 7 / 100)]).join("");
|
|
1671
|
+
}
|
|
1672
|
+
function deviceHistoryGraph(samples, field, width) {
|
|
1673
|
+
const columns = Math.max(0, Math.floor(width) - 5), pixels = columns * 2;
|
|
1674
|
+
if (columns < 2) return "";
|
|
1675
|
+
const cells = Array.from({ length: 3 }, () => Array(columns).fill(0));
|
|
1676
|
+
const latest = samples.at(-1)?.at;
|
|
1677
|
+
const dots = [[1, 8], [2, 16], [4, 32], [64, 128]];
|
|
1678
|
+
const point = (x, y) => {
|
|
1679
|
+
if (x < 0 || x >= pixels || y < 0 || y >= 12) return;
|
|
1680
|
+
cells[Math.floor(y / 4)][Math.floor(x / 2)] |= dots[y % 4][x % 2];
|
|
1681
|
+
};
|
|
1682
|
+
let previous;
|
|
1683
|
+
if (latest !== void 0) for (const sample of samples) {
|
|
1684
|
+
const value = sample[field];
|
|
1685
|
+
const x = pixels - 1 - Math.round((latest - sample.at) / 1e3);
|
|
1686
|
+
if (x < 0) {
|
|
1687
|
+
previous = void 0;
|
|
1688
|
+
continue;
|
|
1689
|
+
}
|
|
1690
|
+
if (value === void 0 || !Number.isFinite(value) || value < 0) {
|
|
1691
|
+
previous = void 0;
|
|
1692
|
+
continue;
|
|
1693
|
+
}
|
|
1694
|
+
const y = Math.round(11 * (1 - Math.min(100, value) / 100));
|
|
1695
|
+
if (previous && sample.at - previous.at <= 5e3) {
|
|
1696
|
+
const distance = Math.max(1, Math.abs(x - previous.x), Math.abs(y - previous.y));
|
|
1697
|
+
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));
|
|
1698
|
+
} else point(x, y);
|
|
1699
|
+
previous = { x, y, at: sample.at };
|
|
1700
|
+
}
|
|
1701
|
+
const labels = ["100%│", " 50%│", " 0%└"];
|
|
1702
|
+
return cells.map((row, y) => labels[y] + row.map((bits, x) => bits ? String.fromCodePoint(10240 + bits) : x % 4 === 0 ? "·" : " ").join("")).join("\n");
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1653
1705
|
// packages/cli/src/tui/terminal-cells.ts
|
|
1654
1706
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1655
1707
|
var extendedPictographic = /\p{Extended_Pictographic}/u;
|
|
@@ -1729,6 +1781,13 @@ function terminalCellWidth(value) {
|
|
|
1729
1781
|
|
|
1730
1782
|
// packages/cli/src/tui/native/components/instrument-format.ts
|
|
1731
1783
|
var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
1784
|
+
function formatSignalDivider(width) {
|
|
1785
|
+
const cells = Math.max(0, Math.floor(width));
|
|
1786
|
+
if (cells < 32) return "─".repeat(cells);
|
|
1787
|
+
const plateau = Math.min(12, Math.max(6, Math.floor(cells / 8)));
|
|
1788
|
+
const left = Math.floor((cells - plateau - 2) / 2);
|
|
1789
|
+
return "▁".repeat(left) + "╱" + "▔".repeat(plateau) + "╲" + "▁".repeat(cells - left - plateau - 2);
|
|
1790
|
+
}
|
|
1732
1791
|
function fitInstrumentText(value, cells, marker = "~") {
|
|
1733
1792
|
const text = stripTerminalSequences(normalizeTerminalLine(value));
|
|
1734
1793
|
const width = Math.max(0, Math.floor(cells));
|
|
@@ -1989,13 +2048,17 @@ var InstrumentDivider = class extends TextRenderable3 {
|
|
|
1989
2048
|
};
|
|
1990
2049
|
var DeviceMonitor = class extends BoxRenderable4 {
|
|
1991
2050
|
constructor(renderer2, action) {
|
|
1992
|
-
super(renderer2, { id: "omnius-devices", width: "100%", height:
|
|
2051
|
+
super(renderer2, { id: "omnius-devices", width: "100%", height: 5, minHeight: 5, maxHeight: "60%", flexShrink: 1, flexDirection: "column", visible: false });
|
|
1993
2052
|
this.action = action;
|
|
1994
2053
|
this.heading = new SectionBanner(renderer2, "DEVICES", "omnius-devices:heading", () => this.toggle());
|
|
1995
2054
|
this.heading.update("DEVICES", false);
|
|
1996
2055
|
this.add(this.heading);
|
|
1997
2056
|
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
2057
|
this.add(this.summary);
|
|
2058
|
+
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 });
|
|
2059
|
+
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 });
|
|
2060
|
+
this.add(this.compactLoad);
|
|
2061
|
+
this.add(this.compactMemory);
|
|
1999
2062
|
this.scroll = new ScrollBoxRenderable3(renderer2, {
|
|
2000
2063
|
id: "omnius-devices:scroll",
|
|
2001
2064
|
width: "100%",
|
|
@@ -2036,11 +2099,15 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2036
2099
|
heading;
|
|
2037
2100
|
scroll;
|
|
2038
2101
|
summary;
|
|
2102
|
+
compactLoad;
|
|
2103
|
+
compactMemory;
|
|
2039
2104
|
policy;
|
|
2040
2105
|
status;
|
|
2041
2106
|
notes;
|
|
2042
2107
|
expanded = false;
|
|
2108
|
+
availableRows = 100;
|
|
2043
2109
|
snapshot;
|
|
2110
|
+
historySource = "";
|
|
2044
2111
|
rows = /* @__PURE__ */ new Map();
|
|
2045
2112
|
button(renderer2, id, label, activate) {
|
|
2046
2113
|
const button = new TextRenderable3(renderer2, {
|
|
@@ -2086,7 +2153,12 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2086
2153
|
}
|
|
2087
2154
|
update(snapshot) {
|
|
2088
2155
|
this.snapshot = snapshot;
|
|
2089
|
-
this.visible = Boolean(snapshot);
|
|
2156
|
+
this.visible = Boolean(snapshot) && this.availableRows >= 3;
|
|
2157
|
+
const historySource = `${snapshot?.source}:${snapshot?.local}`;
|
|
2158
|
+
if (this.historySource !== historySource) {
|
|
2159
|
+
for (const row of this.rows.values()) row.history.samples.splice(0);
|
|
2160
|
+
this.historySource = historySource;
|
|
2161
|
+
}
|
|
2090
2162
|
const allowed = this.canSelect();
|
|
2091
2163
|
if (this.policy.focused && !allowed) this.heading.focus();
|
|
2092
2164
|
this.policy.focusable = allowed;
|
|
@@ -2108,7 +2180,7 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2108
2180
|
flexShrink: 0,
|
|
2109
2181
|
onSizeChange: () => {
|
|
2110
2182
|
if (!row) return;
|
|
2111
|
-
for (const child of [row.title, row.load, row.memory, row.reason]) child.width = row.root.width;
|
|
2183
|
+
for (const child of [row.title, row.load, row.memory, row.reason, row.loadGraph, row.memoryGraph]) child.width = row.root.width;
|
|
2112
2184
|
this.refresh();
|
|
2113
2185
|
}
|
|
2114
2186
|
});
|
|
@@ -2120,6 +2192,8 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2120
2192
|
title.on(RenderableEvents3.FOCUSED, () => this.scroll.scrollChildIntoView(root.id));
|
|
2121
2193
|
const load = new TelemetryRow(this._ctx, "LOAD", `${root.id}:load`, 16);
|
|
2122
2194
|
const memory = new TelemetryRow(this._ctx, "VRAM", `${root.id}:memory`, 16);
|
|
2195
|
+
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 });
|
|
2196
|
+
const loadGraph = plot("load"), memoryGraph = plot("memory"), history = new DeviceHistory();
|
|
2123
2197
|
const reason = new TextRenderable3(this._ctx, {
|
|
2124
2198
|
id: `${root.id}:reason`,
|
|
2125
2199
|
content: "",
|
|
@@ -2134,12 +2208,19 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2134
2208
|
});
|
|
2135
2209
|
root.add(title);
|
|
2136
2210
|
root.add(load);
|
|
2211
|
+
root.add(loadGraph);
|
|
2137
2212
|
root.add(memory);
|
|
2213
|
+
root.add(memoryGraph);
|
|
2138
2214
|
root.add(reason);
|
|
2139
2215
|
this.scroll.add(root);
|
|
2140
|
-
row = { root, title, load, memory, reason };
|
|
2216
|
+
row = { root, title, load, memory, reason, history, loadGraph, memoryGraph };
|
|
2141
2217
|
this.rows.set(device.uuid, row);
|
|
2142
2218
|
}
|
|
2219
|
+
if (snapshot?.sampledAt !== void 0) row.history.append({
|
|
2220
|
+
at: snapshot.sampledAt,
|
|
2221
|
+
load: device.utilization,
|
|
2222
|
+
memory: device.memoryUsedMB !== void 0 && device.memoryUsedMB >= 0 && device.memoryTotalMB !== void 0 && device.memoryTotalMB > 0 ? device.memoryUsedMB * 100 / device.memoryTotalMB : void 0
|
|
2223
|
+
});
|
|
2143
2224
|
const selectable = this.canSelectDevice(device);
|
|
2144
2225
|
if (row.title.focused && !selectable) this.heading.focus();
|
|
2145
2226
|
row.title.focusable = selectable;
|
|
@@ -2156,11 +2237,20 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2156
2237
|
toggle() {
|
|
2157
2238
|
this.expanded = !this.expanded;
|
|
2158
2239
|
this.scroll.visible = this.expanded;
|
|
2159
|
-
this.minHeight = this.expanded ? 4 : 3;
|
|
2160
2240
|
this.scroll.minHeight = this.expanded ? 1 : 0;
|
|
2161
|
-
this.
|
|
2241
|
+
this.fitHeight(this.availableRows + 2);
|
|
2162
2242
|
this.refresh();
|
|
2163
2243
|
}
|
|
2244
|
+
fitHeight(railRows) {
|
|
2245
|
+
this.availableRows = Math.max(0, railRows - 2);
|
|
2246
|
+
this.visible = Boolean(this.snapshot) && this.availableRows >= 3;
|
|
2247
|
+
this.minHeight = Math.min(5, this.availableRows);
|
|
2248
|
+
this.maxHeight = this.availableRows;
|
|
2249
|
+
this.summary.visible = this.availableRows >= 5;
|
|
2250
|
+
this.compactLoad.visible = !this.expanded;
|
|
2251
|
+
this.compactMemory.visible = !this.expanded && this.availableRows >= 4;
|
|
2252
|
+
this.height = Math.min(this.availableRows, this.expanded ? Math.min(18, Math.max(6, Math.floor(railRows * 0.6))) : 5);
|
|
2253
|
+
}
|
|
2164
2254
|
onResize(width, height) {
|
|
2165
2255
|
super.onResize(width, height);
|
|
2166
2256
|
this.refresh();
|
|
@@ -2176,13 +2266,28 @@ var DeviceMonitor = class extends BoxRenderable4 {
|
|
|
2176
2266
|
this.notes.content = [
|
|
2177
2267
|
data?.local === false ? "REMOTE" : void 0,
|
|
2178
2268
|
data ? `${data.source.toUpperCase()} · ${data.policy.toUpperCase()} · ${data.broker.toUpperCase()}` : void 0,
|
|
2269
|
+
"2s/col",
|
|
2179
2270
|
data?.warnings.length ? `${data.warnings.length} notices` : void 0
|
|
2180
2271
|
].filter(Boolean).join(" · ");
|
|
2272
|
+
const primary = devices.find((device) => device.preferred) ?? devices.find((device) => device.enabled) ?? devices[0];
|
|
2273
|
+
const compactHistory = primary ? this.rows.get(primary.uuid)?.history.samples ?? [] : [];
|
|
2274
|
+
for (const [element, field, label] of [[this.compactLoad, "load", "UTIL"], [this.compactMemory, "memory", primary?.unifiedMemory ? "UMA" : "VRAM"]]) {
|
|
2275
|
+
const current = primary ? field === "load" ? primary.utilization : primary.memoryUsedMB !== void 0 && primary.memoryTotalMB ? primary.memoryUsedMB / primary.memoryTotalMB * 100 : void 0 : void 0;
|
|
2276
|
+
const value = instrumentNumber(current, 0, "%");
|
|
2277
|
+
const caption = `${label}${primary?.index ?? "-"}`;
|
|
2278
|
+
const plotWidth = Math.max(0, this.width - caption.length - value.length - 2);
|
|
2279
|
+
const next = `${caption} ${deviceHistorySparkline(compactHistory, field, plotWidth)} ${value}`;
|
|
2280
|
+
if (element.plainText !== next) element.content = next;
|
|
2281
|
+
}
|
|
2181
2282
|
for (const device of devices) {
|
|
2182
2283
|
const row = this.rows.get(device.uuid);
|
|
2183
2284
|
if (!row) continue;
|
|
2184
2285
|
const state = device.enabled === void 0 ? "--" : device.enabled ? "ON" : "OFF";
|
|
2185
2286
|
row.title.content = formatTelemetryRow(`GPU ${device.index} ${device.name}`, `${state}${device.preferred ? " *" : ""}`, row.root.width, 6);
|
|
2287
|
+
for (const [plot, field] of [[row.loadGraph, "load"], [row.memoryGraph, "memory"]]) {
|
|
2288
|
+
const next = deviceHistoryGraph(row.history.samples, field, row.root.width);
|
|
2289
|
+
if (plot.plainText !== next) plot.content = next;
|
|
2290
|
+
}
|
|
2186
2291
|
}
|
|
2187
2292
|
}
|
|
2188
2293
|
focusTargets() {
|
|
@@ -2305,6 +2410,10 @@ var InstrumentRail = class extends BoxRenderable4 {
|
|
|
2305
2410
|
contextMeter;
|
|
2306
2411
|
contextHeader;
|
|
2307
2412
|
contextDetails;
|
|
2413
|
+
onResize(width, height) {
|
|
2414
|
+
super.onResize(width, height);
|
|
2415
|
+
this.devices?.fitHeight(height);
|
|
2416
|
+
}
|
|
2308
2417
|
constructor(renderer2, options = {}) {
|
|
2309
2418
|
const id = options.id ?? "omnius-instruments";
|
|
2310
2419
|
super(renderer2, {
|
|
@@ -3964,17 +4073,153 @@ var VimComposer = class {
|
|
|
3964
4073
|
}
|
|
3965
4074
|
};
|
|
3966
4075
|
|
|
4076
|
+
// packages/cli/src/tui/native/components/selection-menu.ts
|
|
4077
|
+
import { BoxRenderable as BoxRenderable5, CliRenderEvents as CliRenderEvents3, TextAttributes as TextAttributes6, TextRenderable as TextRenderable4 } from "@opentui/core";
|
|
4078
|
+
var NativeSelectionMenu = class {
|
|
4079
|
+
constructor(renderer2, colors, copy, restoreFocus) {
|
|
4080
|
+
this.renderer = renderer2;
|
|
4081
|
+
this.colors = colors;
|
|
4082
|
+
this.copy = copy;
|
|
4083
|
+
this.restoreFocus = restoreFocus;
|
|
4084
|
+
renderer2.on(CliRenderEvents3.RESIZE, this.position);
|
|
4085
|
+
}
|
|
4086
|
+
renderer;
|
|
4087
|
+
colors;
|
|
4088
|
+
copy;
|
|
4089
|
+
restoreFocus;
|
|
4090
|
+
overlay;
|
|
4091
|
+
panel;
|
|
4092
|
+
frame;
|
|
4093
|
+
previousFocus;
|
|
4094
|
+
anchor = { x: 0, y: 0 };
|
|
4095
|
+
selectedText = "";
|
|
4096
|
+
get active() {
|
|
4097
|
+
return Boolean(this.overlay);
|
|
4098
|
+
}
|
|
4099
|
+
open(x, y, text) {
|
|
4100
|
+
if (!text) return;
|
|
4101
|
+
this.close();
|
|
4102
|
+
this.selectedText = text;
|
|
4103
|
+
this.anchor = { x, y };
|
|
4104
|
+
this.previousFocus = this.renderer.currentFocusedRenderable;
|
|
4105
|
+
this.overlay = new BoxRenderable5(this.renderer, {
|
|
4106
|
+
id: "omnius-selection-menu",
|
|
4107
|
+
position: "absolute",
|
|
4108
|
+
left: 0,
|
|
4109
|
+
top: 0,
|
|
4110
|
+
width: "100%",
|
|
4111
|
+
height: "100%",
|
|
4112
|
+
backgroundColor: "transparent",
|
|
4113
|
+
shouldFill: false,
|
|
4114
|
+
zIndex: 120,
|
|
4115
|
+
onMouseDown: (event) => {
|
|
4116
|
+
this.close();
|
|
4117
|
+
event.preventDefault();
|
|
4118
|
+
event.stopPropagation();
|
|
4119
|
+
}
|
|
4120
|
+
});
|
|
4121
|
+
this.panel = new BoxRenderable5(this.renderer, {
|
|
4122
|
+
id: "omnius-selection-menu-panel",
|
|
4123
|
+
position: "absolute",
|
|
4124
|
+
width: 14,
|
|
4125
|
+
height: 3,
|
|
4126
|
+
flexDirection: "column",
|
|
4127
|
+
paddingX: 2,
|
|
4128
|
+
paddingY: 1,
|
|
4129
|
+
backgroundColor: this.colors.background,
|
|
4130
|
+
onMouseDown: (event) => {
|
|
4131
|
+
event.preventDefault();
|
|
4132
|
+
event.stopPropagation();
|
|
4133
|
+
}
|
|
4134
|
+
});
|
|
4135
|
+
const action = new TextRenderable4(this.renderer, {
|
|
4136
|
+
id: "omnius-selection-copy",
|
|
4137
|
+
content: "COPY",
|
|
4138
|
+
height: 1,
|
|
4139
|
+
width: "100%",
|
|
4140
|
+
selectable: false,
|
|
4141
|
+
fg: this.colors.foreground,
|
|
4142
|
+
bg: this.colors.background,
|
|
4143
|
+
attributes: TextAttributes6.BOLD | TextAttributes6.INVERSE,
|
|
4144
|
+
onMouseDown: (event) => {
|
|
4145
|
+
if (event.button === 0) this.confirm();
|
|
4146
|
+
event.preventDefault();
|
|
4147
|
+
event.stopPropagation();
|
|
4148
|
+
}
|
|
4149
|
+
});
|
|
4150
|
+
action.focusable = true;
|
|
4151
|
+
this.panel.add(action);
|
|
4152
|
+
this.overlay.add(this.panel);
|
|
4153
|
+
this.frame = new NativeCornerFrame(this.panel, this.colors, this.renderer, this.overlay);
|
|
4154
|
+
this.renderer.root.add(this.overlay);
|
|
4155
|
+
this.position();
|
|
4156
|
+
action.focus();
|
|
4157
|
+
this.renderer.requestRender();
|
|
4158
|
+
}
|
|
4159
|
+
position = () => {
|
|
4160
|
+
if (!this.panel) return;
|
|
4161
|
+
const width = Math.min(14, this.renderer.terminalWidth);
|
|
4162
|
+
this.panel.width = width;
|
|
4163
|
+
this.panel.left = Math.max(0, Math.min(this.anchor.x, this.renderer.terminalWidth - width));
|
|
4164
|
+
this.panel.top = Math.max(0, Math.min(this.anchor.y + 1, this.renderer.terminalHeight - 3));
|
|
4165
|
+
};
|
|
4166
|
+
handleKey(key) {
|
|
4167
|
+
if (key.eventType !== "release") {
|
|
4168
|
+
if (key.name === "return" || key.sequence === " " || key.ctrl && key.shift && key.name.toLowerCase() === "c") this.confirm();
|
|
4169
|
+
else if (key.name === "escape" || key.name === "tab") this.close();
|
|
4170
|
+
}
|
|
4171
|
+
key.preventDefault();
|
|
4172
|
+
key.stopPropagation();
|
|
4173
|
+
}
|
|
4174
|
+
confirm() {
|
|
4175
|
+
const text = this.selectedText;
|
|
4176
|
+
this.close();
|
|
4177
|
+
this.copy(text);
|
|
4178
|
+
}
|
|
4179
|
+
applyTheme(colors) {
|
|
4180
|
+
this.colors = colors;
|
|
4181
|
+
if (!this.panel) return;
|
|
4182
|
+
this.panel.backgroundColor = colors.background;
|
|
4183
|
+
this.frame?.setColors(colors);
|
|
4184
|
+
for (const child of this.panel.getChildren()) if (child instanceof TextRenderable4) {
|
|
4185
|
+
child.fg = colors.foreground;
|
|
4186
|
+
child.bg = colors.background;
|
|
4187
|
+
}
|
|
4188
|
+
}
|
|
4189
|
+
close() {
|
|
4190
|
+
if (!this.overlay) return;
|
|
4191
|
+
const previous = this.previousFocus;
|
|
4192
|
+
this.previousFocus = void 0;
|
|
4193
|
+
this.frame?.destroy();
|
|
4194
|
+
this.frame = void 0;
|
|
4195
|
+
this.overlay.destroyRecursively();
|
|
4196
|
+
this.overlay = void 0;
|
|
4197
|
+
this.panel = void 0;
|
|
4198
|
+
this.selectedText = "";
|
|
4199
|
+
if (previous && !previous.isDestroyed && previous.visible && previous.focusable) previous.focus();
|
|
4200
|
+
else this.restoreFocus();
|
|
4201
|
+
this.renderer.requestRender();
|
|
4202
|
+
}
|
|
4203
|
+
destroy() {
|
|
4204
|
+
this.close();
|
|
4205
|
+
this.renderer.off(CliRenderEvents3.RESIZE, this.position);
|
|
4206
|
+
}
|
|
4207
|
+
};
|
|
4208
|
+
|
|
3967
4209
|
// packages/cli/src/tui/native/components/frontend.ts
|
|
3968
4210
|
var initialTheme = { mode: "system", bg: -1, accent: -1, textPrimary: -1, textDim: -1, boxColor: -1 };
|
|
3969
4211
|
var NativeFrontend = class {
|
|
3970
|
-
constructor(renderer2, emit) {
|
|
4212
|
+
constructor(renderer2, emit, options = {}) {
|
|
3971
4213
|
this.renderer = renderer2;
|
|
3972
4214
|
this.emit = emit;
|
|
3973
4215
|
const colors = palette(initialTheme);
|
|
3974
4216
|
this.context = { renderer: renderer2, colors, syntax: SyntaxStyle2.fromStyles({}, renderer2.nativeScene), emit, terminals: /* @__PURE__ */ new Map() };
|
|
3975
4217
|
this.disposeSelectionContrast = installDefaultSelectionContrast(renderer2);
|
|
3976
|
-
this.clipboard = createClipboard({ host: createHostClipboard({ timeoutMs: 1500 }), terminal: createRendererClipboardAdapter(renderer2) });
|
|
3977
|
-
this.
|
|
4218
|
+
this.clipboard = options.clipboard ?? createClipboard({ host: createHostClipboard({ timeoutMs: 1500 }), terminal: createRendererClipboardAdapter(renderer2) });
|
|
4219
|
+
this.selectionMenu = new NativeSelectionMenu(renderer2, colors, (text) => {
|
|
4220
|
+
void this.copy(text);
|
|
4221
|
+
}, () => this.restoreFocus());
|
|
4222
|
+
this.root = new BoxRenderable6(renderer2, {
|
|
3978
4223
|
id: "omnius-native",
|
|
3979
4224
|
width: "100%",
|
|
3980
4225
|
height: "100%",
|
|
@@ -3982,7 +4227,7 @@ var NativeFrontend = class {
|
|
|
3982
4227
|
backgroundColor: colors.background
|
|
3983
4228
|
});
|
|
3984
4229
|
renderer2.root.add(this.root);
|
|
3985
|
-
this.header = new
|
|
4230
|
+
this.header = new BoxRenderable6(renderer2, {
|
|
3986
4231
|
id: "omnius-header",
|
|
3987
4232
|
width: "100%",
|
|
3988
4233
|
minWidth: 0,
|
|
@@ -3993,9 +4238,19 @@ var NativeFrontend = class {
|
|
|
3993
4238
|
borderColor: colors.border
|
|
3994
4239
|
});
|
|
3995
4240
|
this.root.add(this.header);
|
|
3996
|
-
|
|
4241
|
+
this.header.renderAfter = (buffer) => {
|
|
4242
|
+
if (this.header.height > 0) buffer.drawText(
|
|
4243
|
+
formatSignalDivider(this.header.width),
|
|
4244
|
+
this.header.x,
|
|
4245
|
+
this.header.y + this.header.height - 1,
|
|
4246
|
+
this.context.colors.foreground,
|
|
4247
|
+
this.context.colors.background,
|
|
4248
|
+
TextAttributes7.DIM
|
|
4249
|
+
);
|
|
4250
|
+
};
|
|
4251
|
+
const headerRow = new BoxRenderable6(renderer2, { id: "omnius-header-row", width: "100%", minWidth: 0, minHeight: 1, flexDirection: "row", gap: 1 });
|
|
3997
4252
|
this.header.add(headerRow);
|
|
3998
|
-
this.identity = new
|
|
4253
|
+
this.identity = new TextRenderable5(renderer2, {
|
|
3999
4254
|
id: "omnius-identity",
|
|
4000
4255
|
content: "Omnius",
|
|
4001
4256
|
fg: colors.foreground,
|
|
@@ -4005,7 +4260,7 @@ var NativeFrontend = class {
|
|
|
4005
4260
|
truncate: true,
|
|
4006
4261
|
minWidth: 18,
|
|
4007
4262
|
selectable: false,
|
|
4008
|
-
attributes:
|
|
4263
|
+
attributes: TextAttributes7.BOLD,
|
|
4009
4264
|
onMouseDown: (event) => {
|
|
4010
4265
|
if (event.button === 0) {
|
|
4011
4266
|
this.toggleHeaderPanel();
|
|
@@ -4033,16 +4288,16 @@ var NativeFrontend = class {
|
|
|
4033
4288
|
verticalScrollbarOptions: { visible: false }
|
|
4034
4289
|
});
|
|
4035
4290
|
headerRow.add(this.headerActions);
|
|
4036
|
-
this.headerPanel = new
|
|
4291
|
+
this.headerPanel = new TextRenderable5(renderer2, { id: "omnius-header-panel", content: "", width: "100%", wrapMode: "word", visible: false });
|
|
4037
4292
|
this.header.add(this.headerPanel);
|
|
4038
|
-
this.detailButton = new
|
|
4293
|
+
this.detailButton = new TextRenderable5(renderer2, {
|
|
4039
4294
|
id: "omnius-details-toggle",
|
|
4040
4295
|
content: "+ DETAILS",
|
|
4041
4296
|
height: 1,
|
|
4042
4297
|
width: 9,
|
|
4043
4298
|
flexShrink: 0,
|
|
4044
4299
|
fg: colors.foreground,
|
|
4045
|
-
attributes:
|
|
4300
|
+
attributes: TextAttributes7.DIM,
|
|
4046
4301
|
selectable: false,
|
|
4047
4302
|
onMouseDown: (event) => {
|
|
4048
4303
|
if (event.button === 0) {
|
|
@@ -4062,13 +4317,13 @@ var NativeFrontend = class {
|
|
|
4062
4317
|
for (const control of [this.identity, this.detailButton]) {
|
|
4063
4318
|
const attributes = control.attributes;
|
|
4064
4319
|
control.on("focused", () => {
|
|
4065
|
-
control.attributes = attributes |
|
|
4320
|
+
control.attributes = attributes | TextAttributes7.INVERSE;
|
|
4066
4321
|
});
|
|
4067
4322
|
control.on("blurred", () => {
|
|
4068
4323
|
control.attributes = attributes;
|
|
4069
4324
|
});
|
|
4070
4325
|
}
|
|
4071
|
-
this.routeWarning = new
|
|
4326
|
+
this.routeWarning = new TextRenderable5(renderer2, { id: "omnius-route-warning", content: "", width: "100%", wrapMode: "word", fg: colors.warning, attributes: TextAttributes7.BOLD | TextAttributes7.UNDERLINE, visible: false, flexShrink: 0 });
|
|
4072
4327
|
this.root.add(this.routeWarning);
|
|
4073
4328
|
this.tabs = new TabSelectRenderable(renderer2, {
|
|
4074
4329
|
id: "omnius-agent-tabs",
|
|
@@ -4107,13 +4362,13 @@ var NativeFrontend = class {
|
|
|
4107
4362
|
const selected = this.tabs.getSelectedIndex();
|
|
4108
4363
|
const start = Math.max(0, Math.min(selected - Math.floor(count / 2), this.tabs.options.length - count));
|
|
4109
4364
|
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,
|
|
4365
|
+
buffer.drawText("─".repeat(Math.max(0, tabWidth)), (selected - start) * tabWidth, 1, colors2.foreground, colors2.background, TextAttributes7.DIM);
|
|
4111
4366
|
};
|
|
4112
4367
|
this.root.add(this.tabs);
|
|
4113
|
-
this.taskPane = new
|
|
4368
|
+
this.taskPane = new BoxRenderable6(renderer2, { id: "omnius-tasks", width: "100%", flexDirection: "column", maxHeight: 6, flexShrink: 0, overflow: "hidden", visible: false });
|
|
4114
4369
|
this.tasks = new NativeBlockList(this.context, this.taskPane);
|
|
4115
4370
|
this.root.add(this.taskPane);
|
|
4116
|
-
this.body = new
|
|
4371
|
+
this.body = new BoxRenderable6(renderer2, { id: "omnius-body", width: "100%", flexDirection: "row", flexGrow: 1, minHeight: 1 });
|
|
4117
4372
|
this.root.add(this.body);
|
|
4118
4373
|
this.scroll = new ScrollBoxRenderable4(renderer2, {
|
|
4119
4374
|
id: "omnius-conversation",
|
|
@@ -4128,6 +4383,15 @@ var NativeFrontend = class {
|
|
|
4128
4383
|
viewportCulling: true,
|
|
4129
4384
|
verticalScrollbarOptions: { showArrows: false, trackOptions: { foregroundColor: colors.dim, backgroundColor: colors.background } },
|
|
4130
4385
|
contentOptions: { flexDirection: "column", onMouseDown: (event) => {
|
|
4386
|
+
if (event.button === 2) {
|
|
4387
|
+
const selected = this.renderer.getSelection()?.getSelectedText();
|
|
4388
|
+
if (selected) {
|
|
4389
|
+
this.selectionMenu.open(event.x, event.y, selected);
|
|
4390
|
+
event.preventDefault();
|
|
4391
|
+
event.stopPropagation();
|
|
4392
|
+
}
|
|
4393
|
+
return;
|
|
4394
|
+
}
|
|
4131
4395
|
if (!this.selectionArmed || event.button !== 0 || !event.target) return;
|
|
4132
4396
|
this.selectionArmed = false;
|
|
4133
4397
|
let block = event.target;
|
|
@@ -4147,6 +4411,18 @@ var NativeFrontend = class {
|
|
|
4147
4411
|
}
|
|
4148
4412
|
event.preventDefault();
|
|
4149
4413
|
event.stopPropagation();
|
|
4414
|
+
}, onMouseDrag: (event) => {
|
|
4415
|
+
if (!event.isDragging || !event.target || !this.renderer.getSelection()?.isDragging) return;
|
|
4416
|
+
let container = this.renderer.getSelectionContainer();
|
|
4417
|
+
while (container) {
|
|
4418
|
+
let current = event.target;
|
|
4419
|
+
while (current && current !== container) current = current.parent;
|
|
4420
|
+
if (current) break;
|
|
4421
|
+
this.renderer.updateSelection(event.target, event.x, event.y);
|
|
4422
|
+
const next = this.renderer.getSelectionContainer();
|
|
4423
|
+
if (next === container) break;
|
|
4424
|
+
container = next;
|
|
4425
|
+
}
|
|
4150
4426
|
} }
|
|
4151
4427
|
});
|
|
4152
4428
|
this.body.add(this.scroll);
|
|
@@ -4167,7 +4443,7 @@ var NativeFrontend = class {
|
|
|
4167
4443
|
this.root.onMouseUp = (event) => this.instrumentDivider.handleRelease(event);
|
|
4168
4444
|
this.instruments = new InstrumentRail(renderer2, { colors, onInspectAgent: (id) => this.emitAction("view", id), onAction: (command2) => this.emitAction(command2) });
|
|
4169
4445
|
this.body.add(this.instruments);
|
|
4170
|
-
this.embeddedPane = new
|
|
4446
|
+
this.embeddedPane = new BoxRenderable6(renderer2, {
|
|
4171
4447
|
id: "omnius-editor-pane",
|
|
4172
4448
|
width: "50%",
|
|
4173
4449
|
flexShrink: 0,
|
|
@@ -4178,7 +4454,7 @@ var NativeFrontend = class {
|
|
|
4178
4454
|
visible: false
|
|
4179
4455
|
});
|
|
4180
4456
|
this.body.add(this.embeddedPane);
|
|
4181
|
-
this.liveButton = new
|
|
4457
|
+
this.liveButton = new TextRenderable5(renderer2, {
|
|
4182
4458
|
id: "omnius-live-button",
|
|
4183
4459
|
content: "↓ Live",
|
|
4184
4460
|
width: "100%",
|
|
@@ -4201,7 +4477,7 @@ var NativeFrontend = class {
|
|
|
4201
4477
|
});
|
|
4202
4478
|
this.liveButton.focusable = true;
|
|
4203
4479
|
this.root.add(this.liveButton);
|
|
4204
|
-
this.queue = new
|
|
4480
|
+
this.queue = new TextRenderable5(renderer2, { id: "omnius-steering-queue", content: "", width: "100%", height: 1, wrapMode: "none", truncate: true, fg: colors.dim, visible: false, flexShrink: 0 });
|
|
4205
4481
|
this.root.add(this.queue);
|
|
4206
4482
|
this.suggestions = new NativeSelectRenderable(renderer2, {
|
|
4207
4483
|
id: "omnius-suggestions",
|
|
@@ -4220,9 +4496,9 @@ var NativeFrontend = class {
|
|
|
4220
4496
|
this.suggestions.onActivate = () => this.acceptSuggestion();
|
|
4221
4497
|
this.suggestions.on("itemSelected", () => this.acceptSuggestion());
|
|
4222
4498
|
this.root.add(this.suggestions);
|
|
4223
|
-
this.status = new
|
|
4499
|
+
this.status = new BoxRenderable6(renderer2, { id: "omnius-live-status", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 2, visible: false });
|
|
4224
4500
|
this.root.add(this.status);
|
|
4225
|
-
this.footer = new
|
|
4501
|
+
this.footer = new BoxRenderable6(renderer2, {
|
|
4226
4502
|
id: "omnius-input-box",
|
|
4227
4503
|
width: "100%",
|
|
4228
4504
|
flexShrink: 0,
|
|
@@ -4232,9 +4508,19 @@ var NativeFrontend = class {
|
|
|
4232
4508
|
flexDirection: "column"
|
|
4233
4509
|
});
|
|
4234
4510
|
this.root.add(this.footer);
|
|
4235
|
-
|
|
4511
|
+
this.footer.renderAfter = (buffer) => {
|
|
4512
|
+
if (this.footer.height > 0) buffer.drawText(
|
|
4513
|
+
formatSignalDivider(this.footer.width),
|
|
4514
|
+
this.footer.x,
|
|
4515
|
+
this.footer.y,
|
|
4516
|
+
this.context.colors.foreground,
|
|
4517
|
+
this.context.colors.background,
|
|
4518
|
+
TextAttributes7.DIM
|
|
4519
|
+
);
|
|
4520
|
+
};
|
|
4521
|
+
const inputRow = new BoxRenderable6(renderer2, { id: "omnius-input-row", width: "100%", flexDirection: "row", gap: 1 });
|
|
4236
4522
|
this.footer.add(inputRow);
|
|
4237
|
-
this.prompt = new
|
|
4523
|
+
this.prompt = new TextRenderable5(renderer2, { id: "omnius-prompt", content: "❯", fg: colors.accent, wrapMode: "none", selectable: false, flexShrink: 0 });
|
|
4238
4524
|
inputRow.add(this.prompt);
|
|
4239
4525
|
this.editor = new TextareaRenderable2(renderer2, {
|
|
4240
4526
|
id: "omnius-input",
|
|
@@ -4254,14 +4540,14 @@ var NativeFrontend = class {
|
|
|
4254
4540
|
onCursorChange: () => this.editorChanged(),
|
|
4255
4541
|
onSubmit: () => this.submit()
|
|
4256
4542
|
});
|
|
4257
|
-
this.vimMode = new
|
|
4543
|
+
this.vimMode = new TextRenderable5(renderer2, {
|
|
4258
4544
|
id: "omnius-vim-mode",
|
|
4259
4545
|
content: "INSERT",
|
|
4260
4546
|
height: 1,
|
|
4261
4547
|
maxWidth: 12,
|
|
4262
4548
|
flexShrink: 0,
|
|
4263
4549
|
fg: colors.foreground,
|
|
4264
|
-
attributes:
|
|
4550
|
+
attributes: TextAttributes7.DIM,
|
|
4265
4551
|
wrapMode: "none",
|
|
4266
4552
|
truncate: true,
|
|
4267
4553
|
visible: false,
|
|
@@ -4275,31 +4561,42 @@ var NativeFrontend = class {
|
|
|
4275
4561
|
this.renderer.requestRender();
|
|
4276
4562
|
});
|
|
4277
4563
|
inputRow.add(this.editor);
|
|
4278
|
-
this.enhance = new
|
|
4564
|
+
this.enhance = new BoxRenderable6(renderer2, { id: "omnius-enhance", flexDirection: "row", gap: 1, flexShrink: 0, visible: false });
|
|
4279
4565
|
inputRow.add(this.enhance);
|
|
4280
|
-
this.activity = new
|
|
4566
|
+
this.activity = new TextRenderable5(renderer2, { id: "omnius-activity", content: "", flexGrow: 1, minWidth: 0, height: 1, wrapMode: "none", truncate: true, visible: false, fg: colors.accent });
|
|
4281
4567
|
this.status.add(this.activity);
|
|
4282
|
-
this.media = new
|
|
4283
|
-
this.mediaText = new
|
|
4568
|
+
this.media = new BoxRenderable6(renderer2, { id: "omnius-media", height: 1, minWidth: 0, flexShrink: 1, flexDirection: "row", gap: 1, visible: false });
|
|
4569
|
+
this.mediaText = new TextRenderable5(renderer2, { id: "omnius-media-text", content: "", flexGrow: 1, minWidth: 0, wrapMode: "none", truncate: true, fg: colors.accent });
|
|
4284
4570
|
this.media.add(this.mediaText);
|
|
4285
|
-
this.micTrack = new
|
|
4571
|
+
this.micTrack = new TextRenderable5(renderer2, { id: "omnius-mic-meter", width: 12, height: 1, flexShrink: 0, fg: colors.foreground, visible: false });
|
|
4286
4572
|
this.media.add(this.micTrack);
|
|
4287
4573
|
this.status.add(this.media);
|
|
4288
|
-
this.
|
|
4289
|
-
|
|
4574
|
+
this.copyFeedback = new TextRenderable5(renderer2, {
|
|
4575
|
+
id: "omnius-copy-feedback",
|
|
4576
|
+
content: "",
|
|
4577
|
+
height: 1,
|
|
4578
|
+
flexShrink: 0,
|
|
4579
|
+
fg: colors.foreground,
|
|
4580
|
+
attributes: TextAttributes7.DIM,
|
|
4581
|
+
selectable: false,
|
|
4582
|
+
visible: false
|
|
4583
|
+
});
|
|
4584
|
+
this.status.add(this.copyFeedback);
|
|
4585
|
+
this.metricsRow = new BoxRenderable6(renderer2, { id: "omnius-metrics-row", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 1 });
|
|
4586
|
+
this.keyHints = new TextRenderable5(renderer2, { id: "omnius-key-hints", content: "F1 HELP TAB FOCUS", height: 1, flexShrink: 0, attributes: TextAttributes7.DIM, fg: colors.foreground, selectable: false });
|
|
4290
4587
|
this.metricsRow.add(this.keyHints);
|
|
4291
|
-
this.metricsStartActions = new
|
|
4588
|
+
this.metricsStartActions = new BoxRenderable6(renderer2, { id: "omnius-metrics-start-actions", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
4292
4589
|
this.metricsRow.add(this.metricsStartActions);
|
|
4293
|
-
this.metrics = new
|
|
4590
|
+
this.metrics = new TextRenderable5(renderer2, { id: "omnius-metrics", content: "", height: 1, wrapMode: "none", truncate: true, fg: colors.dim, flexShrink: 1, flexGrow: 1, minWidth: 0 });
|
|
4294
4591
|
this.metricsRow.add(this.metrics);
|
|
4295
|
-
this.metricsEndActions = new
|
|
4592
|
+
this.metricsEndActions = new BoxRenderable6(renderer2, { id: "omnius-metrics-end-actions", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
4296
4593
|
this.metricsRow.add(this.metricsEndActions);
|
|
4297
4594
|
this.root.add(this.metricsRow);
|
|
4298
4595
|
this.modals = new NativeModalStack(this.context, () => this.restoreFocus());
|
|
4299
4596
|
renderer2.keyInput.on("keypress", this.onKey);
|
|
4300
4597
|
renderer2.keyInput.on("paste", this.onPaste);
|
|
4301
|
-
renderer2.on(
|
|
4302
|
-
renderer2.on(
|
|
4598
|
+
renderer2.on(CliRenderEvents4.FRAME, this.onFrame);
|
|
4599
|
+
renderer2.on(CliRenderEvents4.RESIZE, this.onResize);
|
|
4303
4600
|
this.applyTheme(initialTheme);
|
|
4304
4601
|
this.editor.focus();
|
|
4305
4602
|
}
|
|
@@ -4312,6 +4609,7 @@ var NativeFrontend = class {
|
|
|
4312
4609
|
content;
|
|
4313
4610
|
modals;
|
|
4314
4611
|
context;
|
|
4612
|
+
selectionMenu;
|
|
4315
4613
|
header;
|
|
4316
4614
|
identity;
|
|
4317
4615
|
headerActions;
|
|
@@ -4343,6 +4641,8 @@ var NativeFrontend = class {
|
|
|
4343
4641
|
mediaText;
|
|
4344
4642
|
micTrack;
|
|
4345
4643
|
clipboard;
|
|
4644
|
+
copyFeedback;
|
|
4645
|
+
copyFeedbackTimer;
|
|
4346
4646
|
state;
|
|
4347
4647
|
themeSignature = "";
|
|
4348
4648
|
headerSignature = "";
|
|
@@ -4461,8 +4761,8 @@ var NativeFrontend = class {
|
|
|
4461
4761
|
for (const child of [...parent.getChildren()]) child.destroy();
|
|
4462
4762
|
for (const action of actions) {
|
|
4463
4763
|
const colors = this.context.colors;
|
|
4464
|
-
const attributes = action.disabled ?
|
|
4465
|
-
const button = new
|
|
4764
|
+
const attributes = action.disabled ? TextAttributes7.DIM : action.active ? TextAttributes7.BOLD | TextAttributes7.UNDERLINE : 0;
|
|
4765
|
+
const button = new TextRenderable5(this.renderer, {
|
|
4466
4766
|
id: `${prefix}:${action.id}`,
|
|
4467
4767
|
content: styledText(action.label),
|
|
4468
4768
|
flexShrink: 0,
|
|
@@ -4485,16 +4785,16 @@ var NativeFrontend = class {
|
|
|
4485
4785
|
button.focusable = !action.disabled;
|
|
4486
4786
|
if (!action.disabled) {
|
|
4487
4787
|
button.on("focused", () => {
|
|
4488
|
-
button.attributes = attributes |
|
|
4788
|
+
button.attributes = attributes | TextAttributes7.INVERSE;
|
|
4489
4789
|
});
|
|
4490
4790
|
button.on("blurred", () => {
|
|
4491
4791
|
button.attributes = attributes;
|
|
4492
4792
|
});
|
|
4493
4793
|
button.onMouseOver = () => {
|
|
4494
|
-
button.attributes = attributes |
|
|
4794
|
+
button.attributes = attributes | TextAttributes7.UNDERLINE | (button.focused ? TextAttributes7.INVERSE : 0);
|
|
4495
4795
|
};
|
|
4496
4796
|
button.onMouseOut = () => {
|
|
4497
|
-
button.attributes = attributes | (button.focused ?
|
|
4797
|
+
button.attributes = attributes | (button.focused ? TextAttributes7.INVERSE : 0);
|
|
4498
4798
|
};
|
|
4499
4799
|
}
|
|
4500
4800
|
parent.add(button);
|
|
@@ -4513,12 +4813,12 @@ var NativeFrontend = class {
|
|
|
4513
4813
|
const reading = activity?.label || stage || this.state?.instruments?.runtimeStatus || "";
|
|
4514
4814
|
this.activity.visible = Boolean(activity?.processing || reading);
|
|
4515
4815
|
this.activity.content = `${activity?.processing ? "RUN · " : ""}${reading}`;
|
|
4516
|
-
this.status.visible = this.activity.visible || this.media.visible;
|
|
4816
|
+
this.status.visible = this.activity.visible || this.media.visible || this.copyFeedback.visible;
|
|
4517
4817
|
}
|
|
4518
4818
|
renderMedia() {
|
|
4519
4819
|
const media = this.state?.media;
|
|
4520
4820
|
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;
|
|
4821
|
+
this.status.visible = this.activity.visible || this.media.visible || this.copyFeedback.visible;
|
|
4522
4822
|
if (!media) return;
|
|
4523
4823
|
this.mediaText.content = [
|
|
4524
4824
|
media.recording ? "● REC" : void 0,
|
|
@@ -4569,6 +4869,8 @@ var NativeFrontend = class {
|
|
|
4569
4869
|
this.instruments.applyTheme(colors);
|
|
4570
4870
|
this.instrumentDivider.fg = colors.foreground;
|
|
4571
4871
|
this.instrumentDivider.bg = colors.background;
|
|
4872
|
+
this.copyFeedback.fg = colors.foreground;
|
|
4873
|
+
this.selectionMenu.applyTheme(colors);
|
|
4572
4874
|
this.content.applyTheme();
|
|
4573
4875
|
this.tasks.applyTheme();
|
|
4574
4876
|
this.modals?.applyTheme();
|
|
@@ -4756,6 +5058,10 @@ var NativeFrontend = class {
|
|
|
4756
5058
|
this.emit({ type: "action", action, ...id === void 0 ? {} : { id } });
|
|
4757
5059
|
}
|
|
4758
5060
|
onKey = (key) => {
|
|
5061
|
+
if (this.selectionMenu.active) {
|
|
5062
|
+
this.selectionMenu.handleKey(key);
|
|
5063
|
+
return;
|
|
5064
|
+
}
|
|
4759
5065
|
if (this.modals.active) {
|
|
4760
5066
|
this.modals.active.handleKey(key);
|
|
4761
5067
|
return;
|
|
@@ -4927,6 +5233,10 @@ var NativeFrontend = class {
|
|
|
4927
5233
|
}
|
|
4928
5234
|
}
|
|
4929
5235
|
onPaste = (event) => {
|
|
5236
|
+
if (this.selectionMenu.active) {
|
|
5237
|
+
event.preventDefault();
|
|
5238
|
+
return;
|
|
5239
|
+
}
|
|
4930
5240
|
if (this.modals.active) {
|
|
4931
5241
|
this.modals.active.handlePaste(event);
|
|
4932
5242
|
return;
|
|
@@ -4943,8 +5253,27 @@ var NativeFrontend = class {
|
|
|
4943
5253
|
else if (!this.paused && this.state?.input.enabled !== false) this.editor.focus();
|
|
4944
5254
|
}
|
|
4945
5255
|
async copy(text) {
|
|
4946
|
-
const value = text ?? this.renderer.getSelection()?.getSelectedText()
|
|
4947
|
-
if (value)
|
|
5256
|
+
const value = text ?? (this.renderer.getSelection()?.getSelectedText() || this.editor.getSelectedText());
|
|
5257
|
+
if (!value) return;
|
|
5258
|
+
let message;
|
|
5259
|
+
try {
|
|
5260
|
+
const result = await this.clipboard.writeText(value, { destination: "best-available" });
|
|
5261
|
+
message = result.host.status === "written" ? "COPIED" : result.terminal.status === "attempted" ? "COPY SENT TO TERMINAL" : "COPY UNAVAILABLE";
|
|
5262
|
+
} catch {
|
|
5263
|
+
message = "COPY FAILED";
|
|
5264
|
+
}
|
|
5265
|
+
if (this.destroyed) return;
|
|
5266
|
+
if (this.copyFeedbackTimer) clearTimeout(this.copyFeedbackTimer);
|
|
5267
|
+
this.copyFeedback.content = message;
|
|
5268
|
+
this.copyFeedback.visible = true;
|
|
5269
|
+
this.status.visible = true;
|
|
5270
|
+
this.renderer.requestRender();
|
|
5271
|
+
this.copyFeedbackTimer = setTimeout(() => {
|
|
5272
|
+
this.copyFeedbackTimer = void 0;
|
|
5273
|
+
this.copyFeedback.visible = false;
|
|
5274
|
+
this.status.visible = this.activity.visible || this.media.visible;
|
|
5275
|
+
this.renderer.requestRender();
|
|
5276
|
+
}, 3e3);
|
|
4948
5277
|
}
|
|
4949
5278
|
async paste() {
|
|
4950
5279
|
const result = await this.clipboard.read({ preferredTypes: ["text/plain;charset=utf-8", "text/plain"] });
|
|
@@ -4988,6 +5317,7 @@ var NativeFrontend = class {
|
|
|
4988
5317
|
this.renderer.setTerminalTitle(command2.text);
|
|
4989
5318
|
break;
|
|
4990
5319
|
case "modal-open":
|
|
5320
|
+
this.selectionMenu.close();
|
|
4991
5321
|
this.modals.open(command2.modal);
|
|
4992
5322
|
break;
|
|
4993
5323
|
case "modal-update":
|
|
@@ -5071,11 +5401,13 @@ var NativeFrontend = class {
|
|
|
5071
5401
|
async dispose() {
|
|
5072
5402
|
if (this.destroyed) return;
|
|
5073
5403
|
this.destroyed = true;
|
|
5404
|
+
if (this.copyFeedbackTimer) clearTimeout(this.copyFeedbackTimer);
|
|
5405
|
+
this.selectionMenu.destroy();
|
|
5074
5406
|
this.disposeSelectionContrast();
|
|
5075
5407
|
this.renderer.keyInput.off("keypress", this.onKey);
|
|
5076
5408
|
this.renderer.keyInput.off("paste", this.onPaste);
|
|
5077
|
-
this.renderer.off(
|
|
5078
|
-
this.renderer.off(
|
|
5409
|
+
this.renderer.off(CliRenderEvents4.FRAME, this.onFrame);
|
|
5410
|
+
this.renderer.off(CliRenderEvents4.RESIZE, this.onResize);
|
|
5079
5411
|
this.modals.destroy();
|
|
5080
5412
|
this.content.destroy();
|
|
5081
5413
|
this.tasks.destroy();
|
|
@@ -5086,7 +5418,7 @@ var NativeFrontend = class {
|
|
|
5086
5418
|
};
|
|
5087
5419
|
|
|
5088
5420
|
// packages/cli/src/tui/native/components/cursor.ts
|
|
5089
|
-
import { CliRenderEvents as
|
|
5421
|
+
import { CliRenderEvents as CliRenderEvents5 } from "@opentui/core";
|
|
5090
5422
|
function installTerminalCursorDefaults(renderer2, session) {
|
|
5091
5423
|
const reset = new TextEncoder().encode("\x1B]112\x07");
|
|
5092
5424
|
let disposed = false;
|
|
@@ -5136,11 +5468,11 @@ function installTerminalCursorDefaults(renderer2, session) {
|
|
|
5136
5468
|
const dispose = () => {
|
|
5137
5469
|
if (disposed) return;
|
|
5138
5470
|
disposed = true;
|
|
5139
|
-
renderer2.off(
|
|
5140
|
-
renderer2.off(
|
|
5471
|
+
renderer2.off(CliRenderEvents5.FRAME, afterFrame);
|
|
5472
|
+
renderer2.off(CliRenderEvents5.DESTROY, dispose);
|
|
5141
5473
|
};
|
|
5142
|
-
renderer2.on(
|
|
5143
|
-
renderer2.once(
|
|
5474
|
+
renderer2.on(CliRenderEvents5.FRAME, afterFrame);
|
|
5475
|
+
renderer2.once(CliRenderEvents5.DESTROY, dispose);
|
|
5144
5476
|
return { restore, dispose };
|
|
5145
5477
|
}
|
|
5146
5478
|
|
|
@@ -5216,10 +5548,10 @@ try {
|
|
|
5216
5548
|
maxFps: 60,
|
|
5217
5549
|
clearOnShutdown: false
|
|
5218
5550
|
});
|
|
5219
|
-
renderer.on(
|
|
5551
|
+
renderer.on(CliRenderEvents6.RENDER_ERROR, (event) => {
|
|
5220
5552
|
void fail(event.error);
|
|
5221
5553
|
});
|
|
5222
|
-
renderer.on(
|
|
5554
|
+
renderer.on(CliRenderEvents6.HANDLER_ERROR, (event) => {
|
|
5223
5555
|
void fail(event.error);
|
|
5224
5556
|
});
|
|
5225
5557
|
renderer.on("error", (event) => {
|