omnius 1.0.871 → 1.0.873
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/py-embed.js +3 -0
- package/dist/index.js +2 -2
- package/dist/library.js +3109 -2961
- package/dist/tui/native/worker.js +1363 -219
- package/dist/update-worker.js +3 -0
- package/docs/DISCOVERY.json +168 -0
- package/docs/DISCOVERY.md +5 -0
- package/docs/reference/session-controls.md +11 -0
- package/docs/reference/task-observability.md +25 -0
- package/docs/reference/work-queue.md +40 -0
- package/docs/work-orders/evidence/task-observability-state-verification-20261017.json +74 -0
- package/docs/work-orders/evidence/work-queue-core-verification-20261017.json +56 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
|
@@ -2,18 +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 CliRenderEvents9, 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 BoxRenderable10,
|
|
10
|
+
CliRenderEvents as CliRenderEvents7,
|
|
11
11
|
EmbeddedTerminalRenderable as EmbeddedTerminalRenderable2,
|
|
12
|
-
ScrollBoxRenderable as
|
|
12
|
+
ScrollBoxRenderable as ScrollBoxRenderable7,
|
|
13
13
|
SyntaxStyle as SyntaxStyle2,
|
|
14
14
|
TextareaRenderable as TextareaRenderable2,
|
|
15
|
-
TextRenderable as
|
|
16
|
-
TextAttributes as
|
|
15
|
+
TextRenderable as TextRenderable9,
|
|
16
|
+
TextAttributes as TextAttributes10,
|
|
17
17
|
createClipboard,
|
|
18
18
|
createHostClipboard,
|
|
19
19
|
createRendererClipboardAdapter
|
|
@@ -35,6 +35,16 @@ function sanitizeNativeInterfaceState(value) {
|
|
|
35
35
|
Object.defineProperty(views, key, { value: { top: offset(entry.top), live: entry.live === true, disclosures }, enumerable: true, configurable: true, writable: true });
|
|
36
36
|
}
|
|
37
37
|
const layout = record(value.layout) ? value.layout : {}, instruments = record(value.instruments) ? value.instruments : {}, tabs = record(value.tabs) ? value.tabs : {};
|
|
38
|
+
const taskNotes = record(instruments.taskNotes) ? instruments.taskNotes : void 0;
|
|
39
|
+
const workQueue = record(instruments.workQueue) ? instruments.workQueue : void 0;
|
|
40
|
+
const workDisclosures = {};
|
|
41
|
+
if (workQueue && record(workQueue.disclosures)) for (const [id, open] of Object.entries(workQueue.disclosures).slice(0, 2048)) {
|
|
42
|
+
if (id.length <= 1024 && typeof open === "boolean") Object.defineProperty(workDisclosures, id, { value: open, enumerable: true, configurable: true, writable: true });
|
|
43
|
+
}
|
|
44
|
+
const taskDisclosures = {};
|
|
45
|
+
if (taskNotes && record(taskNotes.disclosures)) for (const [id, open] of Object.entries(taskNotes.disclosures).slice(0, 2048)) {
|
|
46
|
+
if (id.length <= 1024 && typeof open === "boolean") Object.defineProperty(taskDisclosures, id, { value: open, enumerable: true, configurable: true, writable: true });
|
|
47
|
+
}
|
|
38
48
|
return {
|
|
39
49
|
version: 1,
|
|
40
50
|
...typeof value.sessionId === "string" ? { sessionId: value.sessionId.slice(0, 1024) } : {},
|
|
@@ -55,7 +65,9 @@ function sanitizeNativeInterfaceState(value) {
|
|
|
55
65
|
context: instruments.context === true,
|
|
56
66
|
devices: instruments.devices === true,
|
|
57
67
|
scrollTop: offset(instruments.scrollTop),
|
|
58
|
-
deviceScrollTop: offset(instruments.deviceScrollTop)
|
|
68
|
+
deviceScrollTop: offset(instruments.deviceScrollTop),
|
|
69
|
+
...taskNotes ? { taskNotes: { open: taskNotes.open !== false, tasks: taskNotes.tasks !== false, notes: taskNotes.notes !== false, layers: taskNotes.layers !== false, disclosures: taskDisclosures } } : {},
|
|
70
|
+
...workQueue ? { workQueue: { open: workQueue.open !== false, history: workQueue.history === true, disclosures: workDisclosures } } : {}
|
|
59
71
|
},
|
|
60
72
|
tabs: { sessions: offset(tabs.sessions), agents: offset(tabs.agents) }
|
|
61
73
|
};
|
|
@@ -185,14 +197,14 @@ function installDefaultSelectionContrast(renderer2) {
|
|
|
185
197
|
const foreground2 = RGBA.defaultForeground();
|
|
186
198
|
const background2 = RGBA.defaultBackground();
|
|
187
199
|
const paintSelection = (buffer) => {
|
|
188
|
-
const
|
|
200
|
+
const lines2 = buffer.getSpanLines();
|
|
189
201
|
buffer.withBuffers((cells) => {
|
|
190
|
-
for (let y = 0; y <
|
|
202
|
+
for (let y = 0; y < lines2.length; y++) {
|
|
191
203
|
let x = 0;
|
|
192
|
-
for (const span of
|
|
204
|
+
for (const span of lines2[y].spans) {
|
|
193
205
|
if (span.fg.intent === "default" && span.bg.intent === "default" && !(span.attributes & TextAttributes.INVERSE) && span.fg.equals(background2) && span.bg.equals(foreground2)) {
|
|
194
|
-
for (let
|
|
195
|
-
cells.attributes[y * cells.width +
|
|
206
|
+
for (let column3 = x; column3 < x + span.width; column3++)
|
|
207
|
+
cells.attributes[y * cells.width + column3] |= TextAttributes.INVERSE;
|
|
196
208
|
}
|
|
197
209
|
x += span.width;
|
|
198
210
|
}
|
|
@@ -296,7 +308,7 @@ var NativeMediaPlayback = class {
|
|
|
296
308
|
});
|
|
297
309
|
if (spec.kind === "video") {
|
|
298
310
|
const bytes = width * height * 4;
|
|
299
|
-
let pending = Buffer.alloc(0),
|
|
311
|
+
let pending = Buffer.alloc(0), frames2 = 0;
|
|
300
312
|
const offset2 = this.positionSec;
|
|
301
313
|
for await (const chunk of child.stdout) {
|
|
302
314
|
if (epoch !== this.epoch) break;
|
|
@@ -304,8 +316,8 @@ var NativeMediaPlayback = class {
|
|
|
304
316
|
while (pending.length >= bytes && epoch === this.epoch) {
|
|
305
317
|
frame(pending.subarray(0, bytes), width, height);
|
|
306
318
|
pending = pending.subarray(bytes);
|
|
307
|
-
|
|
308
|
-
if (!withAudio) this.positionSec = offset2 +
|
|
319
|
+
frames2++;
|
|
320
|
+
if (!withAudio) this.positionSec = offset2 + frames2 / 8;
|
|
309
321
|
this.changed();
|
|
310
322
|
}
|
|
311
323
|
}
|
|
@@ -396,8 +408,8 @@ function mediaPreviewHeight(width, imageWidth, imageHeight, cellAspectRatio = 2)
|
|
|
396
408
|
function audioWaveform(samples, width) {
|
|
397
409
|
const cells = Math.max(1, Math.min(240, Math.floor(width)));
|
|
398
410
|
const glyphs = "▁▂▃▄▅▆▇█";
|
|
399
|
-
return Array.from({ length: cells }, (_,
|
|
400
|
-
const begin = Math.floor(
|
|
411
|
+
return Array.from({ length: cells }, (_, column3) => {
|
|
412
|
+
const begin = Math.floor(column3 * samples.length / cells), end = Math.max(begin + 1, Math.floor((column3 + 1) * samples.length / cells));
|
|
401
413
|
let peak = 0;
|
|
402
414
|
for (let index = begin; index < end && index < samples.length; index++) if (Number.isFinite(samples[index])) peak = Math.max(peak, Math.abs(samples[index]));
|
|
403
415
|
return glyphs[Math.min(7, Math.floor(Math.min(1, peak) * 7))];
|
|
@@ -465,10 +477,10 @@ var NativeMediaView = class extends BoxRenderable {
|
|
|
465
477
|
pausePlayback() {
|
|
466
478
|
this.playback.pause();
|
|
467
479
|
}
|
|
468
|
-
control(action,
|
|
480
|
+
control(action, label2, operation) {
|
|
469
481
|
const control = new TextRenderable(this.renderer, {
|
|
470
482
|
id: `media-control:${this.mediaId}:${action}`,
|
|
471
|
-
content:
|
|
483
|
+
content: label2,
|
|
472
484
|
fg: this.colors.foreground,
|
|
473
485
|
selectable: false,
|
|
474
486
|
onMouseDown: (event) => {
|
|
@@ -615,14 +627,14 @@ var NativeMediaView = class extends BoxRenderable {
|
|
|
615
627
|
active = ancestor.visible;
|
|
616
628
|
ancestor = ancestor.parent;
|
|
617
629
|
}
|
|
618
|
-
const
|
|
619
|
-
if (!
|
|
620
|
-
if (!
|
|
630
|
+
const visible2 = active && this.y + this.height > viewport.y && this.y < viewport.y + viewport.height;
|
|
631
|
+
if (!visible2 && this.playback.playing) this.playback.pause();
|
|
632
|
+
if (!visible2 && this.probeController && !this.samples) {
|
|
621
633
|
this.probeController.abort();
|
|
622
634
|
this.probeController = void 0;
|
|
623
635
|
this.needsProbe = true;
|
|
624
636
|
}
|
|
625
|
-
if (
|
|
637
|
+
if (visible2) this.startProbe();
|
|
626
638
|
this.refreshGeometry();
|
|
627
639
|
}
|
|
628
640
|
refreshGeometry() {
|
|
@@ -642,8 +654,8 @@ var NativeMediaView = class extends BoxRenderable {
|
|
|
642
654
|
if (this.isDestroyed) return;
|
|
643
655
|
const text = `${this.hovered ? "Open ↗ · " : ""}${this.currentStatus}`;
|
|
644
656
|
if (this.status.plainText !== text) this.status.content = text;
|
|
645
|
-
const
|
|
646
|
-
if (this.playControl.plainText !==
|
|
657
|
+
const label2 = this.playback?.playing ? "Pause" : this.playback?.positionSec ? "Resume" : "Play";
|
|
658
|
+
if (this.playControl.plainText !== label2) this.playControl.content = label2;
|
|
647
659
|
if (this.waveformText) {
|
|
648
660
|
const cursor = this.duration > 0 ? Math.min(this.waveformText.length - 1, Math.floor(this.playback.positionSec / this.duration * this.waveformText.length)) : 0;
|
|
649
661
|
const waveform = this.playback.positionSec > 0 ? this.waveformText.slice(0, cursor) + "│" + this.waveformText.slice(cursor + 1) : this.waveformText;
|
|
@@ -925,7 +937,7 @@ function nativeProgressText(value, working = false) {
|
|
|
925
937
|
if (value === void 0 || !Number.isFinite(value)) return `[············] ${working ? "working" : "pending"}`;
|
|
926
938
|
const ratio = Math.max(0, Math.min(1, value));
|
|
927
939
|
const filled = Math.round(ratio * 12);
|
|
928
|
-
return `[${"
|
|
940
|
+
return `[${"▮".repeat(filled)}${"░".repeat(12 - filled)}] ${Math.round(ratio * 100)}%`;
|
|
929
941
|
}
|
|
930
942
|
function nativeControlFocus(control, baseAttributes = 0) {
|
|
931
943
|
const update = () => {
|
|
@@ -1511,10 +1523,10 @@ var NativeSelectRenderable = class extends SelectRenderable {
|
|
|
1511
1523
|
this.seekRail(event);
|
|
1512
1524
|
return;
|
|
1513
1525
|
}
|
|
1514
|
-
const
|
|
1515
|
-
const count = Math.max(1, Math.floor(this.height /
|
|
1526
|
+
const lines2 = this.showDescription ? 2 : 1;
|
|
1527
|
+
const count = Math.max(1, Math.floor(this.height / lines2));
|
|
1516
1528
|
const start = Math.max(0, Math.min(this.getSelectedIndex() - Math.floor(count / 2), this.options.length - count));
|
|
1517
|
-
const index = start + Math.floor((event.y - this.y) /
|
|
1529
|
+
const index = start + Math.floor((event.y - this.y) / lines2);
|
|
1518
1530
|
if (index >= start && index < Math.min(start + count, this.options.length) && !this.disabled(index)) {
|
|
1519
1531
|
this.setSelectedIndex(index);
|
|
1520
1532
|
this.onActivate?.();
|
|
@@ -1528,7 +1540,7 @@ import { BoxRenderable as BoxRenderable3, CliRenderEvents as CliRenderEvents2, R
|
|
|
1528
1540
|
function drawCornerFrame(buffer, panel, colors, progress = 1) {
|
|
1529
1541
|
const { x, y, width, height } = panel;
|
|
1530
1542
|
if (width <= 0 || height <= 0) return;
|
|
1531
|
-
const draw = (text,
|
|
1543
|
+
const draw = (text, column3, row) => buffer.drawText(text, column3, row, colors.foreground, colors.background, TextAttributes3.DIM);
|
|
1532
1544
|
draw(" ".repeat(width), x, y);
|
|
1533
1545
|
if (height > 1) draw(" ".repeat(width), x, y + height - 1);
|
|
1534
1546
|
for (let row = 1; row < height - 1; row++) {
|
|
@@ -1551,9 +1563,9 @@ function drawCornerFrame(buffer, panel, colors, progress = 1) {
|
|
|
1551
1563
|
draw(`└${"─".repeat(horizontal)}`, x, y + height - 1);
|
|
1552
1564
|
draw(`${"─".repeat(horizontal)}┘`, x + width - horizontal - 1, y + height - 1);
|
|
1553
1565
|
for (let arm = 1; arm <= vertical; arm++) {
|
|
1554
|
-
for (const
|
|
1555
|
-
draw("│",
|
|
1556
|
-
draw("│",
|
|
1566
|
+
for (const column3 of [x, x + width - 1]) {
|
|
1567
|
+
draw("│", column3, y + arm);
|
|
1568
|
+
draw("│", column3, y + height - arm - 1);
|
|
1557
1569
|
}
|
|
1558
1570
|
}
|
|
1559
1571
|
}
|
|
@@ -2043,7 +2055,7 @@ var NativeModalView = class {
|
|
|
2043
2055
|
return consume();
|
|
2044
2056
|
}
|
|
2045
2057
|
if (key.name === "tab") {
|
|
2046
|
-
if (this.spec.deferSelection || this.spec.captureKeys) this.emitAction(key.shift ? "shift-tab" : "tab");
|
|
2058
|
+
if (!this.spec.nativeTabNavigation && (this.spec.deferSelection || this.spec.captureKeys)) this.emitAction(key.shift ? "shift-tab" : "tab");
|
|
2047
2059
|
else this.nextControl(key.shift ? -1 : 1);
|
|
2048
2060
|
return consume();
|
|
2049
2061
|
}
|
|
@@ -2195,9 +2207,9 @@ var NativeModalStack = class {
|
|
|
2195
2207
|
if (!panel || panel.isDestroyed || !panel.visible) return;
|
|
2196
2208
|
const { x, y, width, height } = this.active.frame.bounds;
|
|
2197
2209
|
buffer.withBuffers((cells) => {
|
|
2198
|
-
for (let row = 0; row < cells.height; row++) for (let
|
|
2199
|
-
if (
|
|
2200
|
-
cells.attributes[row * cells.width +
|
|
2210
|
+
for (let row = 0; row < cells.height; row++) for (let column3 = 0; column3 < cells.width; column3++) {
|
|
2211
|
+
if (column3 < x || column3 >= x + width || row < y || row >= y + height)
|
|
2212
|
+
cells.attributes[row * cells.width + column3] |= TextAttributes4.DIM;
|
|
2201
2213
|
}
|
|
2202
2214
|
});
|
|
2203
2215
|
};
|
|
@@ -2251,12 +2263,12 @@ var NativeModalStack = class {
|
|
|
2251
2263
|
|
|
2252
2264
|
// packages/cli/src/tui/native/components/instruments.ts
|
|
2253
2265
|
import {
|
|
2254
|
-
BoxRenderable as
|
|
2266
|
+
BoxRenderable as BoxRenderable7,
|
|
2255
2267
|
RGBA as RGBA2,
|
|
2256
|
-
RenderableEvents as
|
|
2257
|
-
ScrollBoxRenderable as
|
|
2258
|
-
TextAttributes as
|
|
2259
|
-
TextRenderable as
|
|
2268
|
+
RenderableEvents as RenderableEvents5,
|
|
2269
|
+
ScrollBoxRenderable as ScrollBoxRenderable5,
|
|
2270
|
+
TextAttributes as TextAttributes7,
|
|
2271
|
+
TextRenderable as TextRenderable6
|
|
2260
2272
|
} from "@opentui/core";
|
|
2261
2273
|
|
|
2262
2274
|
// packages/cli/src/tui/native/components/device-history.ts
|
|
@@ -2311,6 +2323,16 @@ function deviceHistoryGraph(samples, field, width) {
|
|
|
2311
2323
|
return cells.map((row, y) => labels[y] + row.map((bits, x) => bits ? String.fromCodePoint(10240 + bits) : x % 4 === 0 ? "·" : " ").join("")).join("\n");
|
|
2312
2324
|
}
|
|
2313
2325
|
|
|
2326
|
+
// packages/cli/src/tui/native/components/task-notes.ts
|
|
2327
|
+
import {
|
|
2328
|
+
BoxRenderable as BoxRenderable5,
|
|
2329
|
+
CliRenderEvents as CliRenderEvents3,
|
|
2330
|
+
RenderableEvents as RenderableEvents3,
|
|
2331
|
+
ScrollBoxRenderable as ScrollBoxRenderable3,
|
|
2332
|
+
TextAttributes as TextAttributes5,
|
|
2333
|
+
TextRenderable as TextRenderable4
|
|
2334
|
+
} from "@opentui/core";
|
|
2335
|
+
|
|
2314
2336
|
// packages/cli/src/tui/terminal-cells.ts
|
|
2315
2337
|
var graphemes = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2316
2338
|
var extendedPictographic = /\p{Extended_Pictographic}/u;
|
|
@@ -2392,9 +2414,9 @@ function terminalCellWidth(value) {
|
|
|
2392
2414
|
var graphemes2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2393
2415
|
function formatSignalDivider(width, geometry = { direction: "top" }) {
|
|
2394
2416
|
const cells = Math.max(0, Math.floor(width));
|
|
2395
|
-
const
|
|
2396
|
-
if (!Number.isFinite(
|
|
2397
|
-
return "─".repeat(
|
|
2417
|
+
const column3 = Math.floor(geometry.sidebarColumn ?? -1);
|
|
2418
|
+
if (!Number.isFinite(column3) || column3 < 0 || column3 >= cells) return "─".repeat(cells);
|
|
2419
|
+
return "─".repeat(column3) + (geometry.direction === "top" ? "┬" : "┴") + "─".repeat(cells - column3 - 1);
|
|
2398
2420
|
}
|
|
2399
2421
|
function fitInstrumentText(value, cells, marker = "~") {
|
|
2400
2422
|
const text = stripTerminalSequences(normalizeTerminalLine(value));
|
|
@@ -2411,7 +2433,7 @@ function fitInstrumentText(value, cells, marker = "~") {
|
|
|
2411
2433
|
}
|
|
2412
2434
|
return result + suffix;
|
|
2413
2435
|
}
|
|
2414
|
-
function formatTelemetryRow(
|
|
2436
|
+
function formatTelemetryRow(label2, value, width, reserved = 12) {
|
|
2415
2437
|
const cells = Math.max(0, Math.floor(width));
|
|
2416
2438
|
if (!cells) return "";
|
|
2417
2439
|
const reading = stripTerminalSequences(normalizeTerminalLine(value));
|
|
@@ -2419,7 +2441,7 @@ function formatTelemetryRow(label, value, width, reserved = 12) {
|
|
|
2419
2441
|
if (readingCells >= cells) return fitInstrumentText(reading, cells);
|
|
2420
2442
|
const field = Math.min(cells, Math.max(readingCells, Math.floor(reserved)));
|
|
2421
2443
|
const labelCells = Math.max(0, cells - field - 1);
|
|
2422
|
-
const left = fitInstrumentText(
|
|
2444
|
+
const left = fitInstrumentText(label2.toUpperCase(), labelCells);
|
|
2423
2445
|
const dots = ".".repeat(Math.max(0, cells - field - terminalCellWidth(left)));
|
|
2424
2446
|
return left + dots + " ".repeat(Math.max(0, field - readingCells)) + reading;
|
|
2425
2447
|
}
|
|
@@ -2432,15 +2454,15 @@ function formatSignalMeter(value, maximum, width = 8) {
|
|
|
2432
2454
|
return `[${".".repeat(cells)}] --`;
|
|
2433
2455
|
const ratio = Math.max(0, Math.min(1, value / maximum));
|
|
2434
2456
|
const filled = Math.round(ratio * cells);
|
|
2435
|
-
return `[${"
|
|
2457
|
+
return `[${"▮".repeat(filled)}${"░".repeat(cells - filled)}] ${Math.round(ratio * 100)}%`;
|
|
2436
2458
|
}
|
|
2437
2459
|
function formatSectionBanner(title, width, expanded = true) {
|
|
2438
2460
|
const cells = Math.max(0, Math.floor(width));
|
|
2439
|
-
const
|
|
2461
|
+
const label2 = fitInstrumentText(
|
|
2440
2462
|
`${expanded ? "-" : "+"} ${title.toUpperCase()} `,
|
|
2441
2463
|
cells
|
|
2442
2464
|
);
|
|
2443
|
-
return
|
|
2465
|
+
return label2 + "─".repeat(Math.max(0, cells - terminalCellWidth(label2)));
|
|
2444
2466
|
}
|
|
2445
2467
|
function instrumentStatus(value) {
|
|
2446
2468
|
const status = (value || "unknown").toLowerCase();
|
|
@@ -2453,10 +2475,994 @@ function instrumentStatus(value) {
|
|
|
2453
2475
|
return status.toUpperCase();
|
|
2454
2476
|
}
|
|
2455
2477
|
|
|
2478
|
+
// packages/cli/src/tui/native/components/task-notes.ts
|
|
2479
|
+
var marks = ["▨", "▧", "▥", "▦"];
|
|
2480
|
+
var reducedMotion = () => process.env["OMNIUS_TUI_REDUCE_MOTION"] === "1" || process.env["REDUCE_MOTION"] === "1";
|
|
2481
|
+
var safe = (value) => typeof value === "string" ? plainText(value) : "";
|
|
2482
|
+
var lines = (values) => Array.isArray(values) ? values.filter((value) => typeof value === "string").map(safe) : [];
|
|
2483
|
+
var column = (renderer2, id) => new BoxRenderable5(renderer2, { id, width: "100%", flexDirection: "column", flexShrink: 0, minWidth: 0 });
|
|
2484
|
+
function visible(node, renderer2) {
|
|
2485
|
+
if (node.width < 1 || node.height < 1 || node.y >= renderer2.terminalHeight || node.y + node.height <= 0) return false;
|
|
2486
|
+
for (let current = node; current; current = current.parent) {
|
|
2487
|
+
if (!current.visible) return false;
|
|
2488
|
+
if (current instanceof ScrollBoxRenderable3 && (node.y + node.height <= current.viewport.y || node.y >= current.viewport.y + current.viewport.height || node.x + node.width <= current.viewport.x || node.x >= current.viewport.x + current.viewport.width)) return false;
|
|
2489
|
+
}
|
|
2490
|
+
return true;
|
|
2491
|
+
}
|
|
2492
|
+
var ActiveBlocks = class {
|
|
2493
|
+
constructor(renderer2, active, paint) {
|
|
2494
|
+
this.renderer = renderer2;
|
|
2495
|
+
this.active = active;
|
|
2496
|
+
this.paint = paint;
|
|
2497
|
+
renderer2.on(CliRenderEvents3.FRAME, this.sync);
|
|
2498
|
+
}
|
|
2499
|
+
renderer;
|
|
2500
|
+
active;
|
|
2501
|
+
paint;
|
|
2502
|
+
timer;
|
|
2503
|
+
frame = 0;
|
|
2504
|
+
destroyed = false;
|
|
2505
|
+
get running() {
|
|
2506
|
+
return this.timer !== void 0;
|
|
2507
|
+
}
|
|
2508
|
+
sync = () => {
|
|
2509
|
+
const animate = !this.destroyed && !reducedMotion() && this.active();
|
|
2510
|
+
if (animate && !this.timer) {
|
|
2511
|
+
this.timer = setInterval(() => {
|
|
2512
|
+
if (!this.active() || reducedMotion()) {
|
|
2513
|
+
this.sync();
|
|
2514
|
+
return;
|
|
2515
|
+
}
|
|
2516
|
+
this.paint(marks[++this.frame % marks.length]);
|
|
2517
|
+
}, 250);
|
|
2518
|
+
this.timer.unref?.();
|
|
2519
|
+
} else if (!animate && this.timer) {
|
|
2520
|
+
clearInterval(this.timer);
|
|
2521
|
+
this.timer = void 0;
|
|
2522
|
+
}
|
|
2523
|
+
};
|
|
2524
|
+
destroy() {
|
|
2525
|
+
this.destroyed = true;
|
|
2526
|
+
if (this.timer) clearInterval(this.timer);
|
|
2527
|
+
this.timer = void 0;
|
|
2528
|
+
this.renderer.off(CliRenderEvents3.FRAME, this.sync);
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
var Disclosure = class extends TextRenderable4 {
|
|
2532
|
+
constructor(renderer2, id, activate, colors, ruled = false) {
|
|
2533
|
+
super(renderer2, {
|
|
2534
|
+
id,
|
|
2535
|
+
content: "",
|
|
2536
|
+
width: "100%",
|
|
2537
|
+
height: 1,
|
|
2538
|
+
minWidth: 0,
|
|
2539
|
+
flexShrink: 0,
|
|
2540
|
+
wrapMode: "none",
|
|
2541
|
+
truncate: true,
|
|
2542
|
+
fg: colors.foreground,
|
|
2543
|
+
bg: colors.background,
|
|
2544
|
+
selectable: false,
|
|
2545
|
+
onMouseDown: (event) => {
|
|
2546
|
+
if (event.button === 0) {
|
|
2547
|
+
this.focus();
|
|
2548
|
+
activate();
|
|
2549
|
+
event.preventDefault();
|
|
2550
|
+
event.stopPropagation();
|
|
2551
|
+
}
|
|
2552
|
+
},
|
|
2553
|
+
onKeyDown: (key) => {
|
|
2554
|
+
if (key.eventType === "release") return;
|
|
2555
|
+
if (key.name === "return" || key.sequence === " " || key.name === "right" && !this.open || key.name === "left" && this.open) {
|
|
2556
|
+
activate();
|
|
2557
|
+
key.preventDefault();
|
|
2558
|
+
key.stopPropagation();
|
|
2559
|
+
}
|
|
2560
|
+
}
|
|
2561
|
+
});
|
|
2562
|
+
this.activate = activate;
|
|
2563
|
+
this.colors = colors;
|
|
2564
|
+
this.ruled = ruled;
|
|
2565
|
+
this.focusable = true;
|
|
2566
|
+
this.on(RenderableEvents3.FOCUSED, this.style);
|
|
2567
|
+
this.on(RenderableEvents3.BLURRED, this.style);
|
|
2568
|
+
}
|
|
2569
|
+
activate;
|
|
2570
|
+
colors;
|
|
2571
|
+
ruled;
|
|
2572
|
+
open = true;
|
|
2573
|
+
label = "";
|
|
2574
|
+
base = TextAttributes5.BOLD;
|
|
2575
|
+
update(label2, open, attributes = TextAttributes5.BOLD) {
|
|
2576
|
+
this.label = label2;
|
|
2577
|
+
this.open = open;
|
|
2578
|
+
this.base = attributes;
|
|
2579
|
+
this.refresh();
|
|
2580
|
+
this.style();
|
|
2581
|
+
}
|
|
2582
|
+
applyTheme(colors) {
|
|
2583
|
+
this.colors = colors;
|
|
2584
|
+
this.fg = colors.foreground;
|
|
2585
|
+
this.bg = colors.background;
|
|
2586
|
+
}
|
|
2587
|
+
style = () => {
|
|
2588
|
+
this.attributes = this.base | (this.focused ? TextAttributes5.INVERSE : 0);
|
|
2589
|
+
};
|
|
2590
|
+
onResize(width, height) {
|
|
2591
|
+
super.onResize(width, height);
|
|
2592
|
+
this.refresh();
|
|
2593
|
+
}
|
|
2594
|
+
refresh() {
|
|
2595
|
+
const text = this.ruled ? formatSectionBanner(this.label, this.width, this.open) : fitInstrumentText(`${this.open ? "−" : "+"} ${this.label}`, this.width);
|
|
2596
|
+
if (this.plainText !== text) this.content = text;
|
|
2597
|
+
}
|
|
2598
|
+
};
|
|
2599
|
+
function metadata(item) {
|
|
2600
|
+
const rows = [item.workKind ? `KIND ${safe(item.workKind)}` : "", item.owner ? `OWNER ${safe(item.owner)}` : "", item.blocker ? `BLOCKED ${safe(item.blocker)}` : ""];
|
|
2601
|
+
for (const [label2, values] of [["DEPENDS ON", item.blockedBy], ["BLOCKS", item.blocks], ["REQUIREMENTS", item.requirementIds], ["ACCEPTANCE", item.acceptanceIds], ["SOURCES", item.sourceRefs]])
|
|
2602
|
+
if (lines(values).length) rows.push(`${label2} ${lines(values).join(", ")}`);
|
|
2603
|
+
for (const ref of item.targetRefs ?? []) if (ref && safe(ref.ref)) rows.push(`${safe(ref.kind).toUpperCase()} ${safe(ref.ref)}`);
|
|
2604
|
+
const contract = item.actionContract;
|
|
2605
|
+
if (contract) {
|
|
2606
|
+
for (const [label2, values] of [["PRECONDITIONS", contract.preconditions], ["MUTATIONS", contract.mutations], ["SIDE EFFECTS", contract.sideEffects]])
|
|
2607
|
+
if (lines(values).length) rows.push(`${label2} ${lines(values).join("; ")}`);
|
|
2608
|
+
for (const key of ["authority", "approval", "risk"]) if (safe(contract[key])) rows.push(`${key.toUpperCase()} ${safe(contract[key])}`);
|
|
2609
|
+
}
|
|
2610
|
+
return rows.filter(Boolean).join("\n");
|
|
2611
|
+
}
|
|
2612
|
+
function taskMark(item, frame = marks[0]) {
|
|
2613
|
+
return item.status === "in_progress" ? frame : item.status === "completed" ? "■" : item.status === "blocked" ? "▣" : "□";
|
|
2614
|
+
}
|
|
2615
|
+
function layerStatus(layer) {
|
|
2616
|
+
const status = safe(layer.status).toLowerCase();
|
|
2617
|
+
if (["verified", "integrated"].includes(status)) return `REPORTED ${status.toUpperCase()} · AUTHORITY NOT ATTESTED`;
|
|
2618
|
+
return ["bound", "recorded", "tool complete", "tool failed", "compact", "hold", "accepted", "requested", "held", "incomplete verification", "incomplete_verification", "incomplete", "awaiting_input", "not attached", "proposed", "specified", "ready", "pending", "waiting", "leased", "running", "candidate", "verifying", "blocked", "retryable", "completed", "failed", "rejected", "cancelled", "superseded", "received", "queued", "acknowledged", "visible_in_request", "reconciliation_required", "reconciled", "first_affected_action", "consumed"].includes(status) ? status.replace(/_/g, " ").toUpperCase() : "UNKNOWN";
|
|
2619
|
+
}
|
|
2620
|
+
var NativeTaskNotesView = class extends BoxRenderable5 {
|
|
2621
|
+
constructor(renderer2, colors, reveal) {
|
|
2622
|
+
super(renderer2, { id: "omnius-task-notes", width: "100%", minWidth: 0, flexShrink: 0, flexDirection: "column", visible: false });
|
|
2623
|
+
this.renderer = renderer2;
|
|
2624
|
+
this.colors = colors;
|
|
2625
|
+
this.reveal = reveal;
|
|
2626
|
+
const text = (id, attributes = 0) => new TextRenderable4(renderer2, { id, content: "", width: "100%", minWidth: 0, flexShrink: 0, fg: colors.foreground, bg: colors.background, attributes, wrapMode: "word" });
|
|
2627
|
+
const heading = (id, label2, key) => {
|
|
2628
|
+
const node = new Disclosure(renderer2, id, () => {
|
|
2629
|
+
this.presentation[key] = !this.presentation[key];
|
|
2630
|
+
this.applyPresentation();
|
|
2631
|
+
}, colors, true);
|
|
2632
|
+
node.update(label2, this.presentation[key]);
|
|
2633
|
+
node.on(RenderableEvents3.FOCUSED, () => this.reveal?.(node));
|
|
2634
|
+
return node;
|
|
2635
|
+
};
|
|
2636
|
+
this.header = heading("omnius-task-notes:heading", "TASKS / NOTES", "open");
|
|
2637
|
+
this.add(this.header);
|
|
2638
|
+
this.body = column(renderer2, "omnius-task-notes:body");
|
|
2639
|
+
this.add(this.body);
|
|
2640
|
+
this.scope = text("omnius-task-notes:scope", TextAttributes5.DIM);
|
|
2641
|
+
this.body.add(this.scope);
|
|
2642
|
+
this.warning = text("omnius-task-notes:warning", TextAttributes5.BOLD);
|
|
2643
|
+
this.body.add(this.warning);
|
|
2644
|
+
this.taskHeader = heading("omnius-task-notes:tasks", "TASKS", "tasks");
|
|
2645
|
+
this.body.add(this.taskHeader);
|
|
2646
|
+
this.taskBody = column(renderer2, "omnius-task-notes:task-body");
|
|
2647
|
+
this.body.add(this.taskBody);
|
|
2648
|
+
this.noteHeader = heading("omnius-task-notes:notes", "NOTES", "notes");
|
|
2649
|
+
this.body.add(this.noteHeader);
|
|
2650
|
+
this.noteBody = column(renderer2, "omnius-task-notes:note-body");
|
|
2651
|
+
this.body.add(this.noteBody);
|
|
2652
|
+
this.layerHeader = heading("omnius-task-notes:layers", "RECORDED ORCHESTRATION", "layers");
|
|
2653
|
+
this.body.add(this.layerHeader);
|
|
2654
|
+
this.layerBody = column(renderer2, "omnius-task-notes:layer-body");
|
|
2655
|
+
this.body.add(this.layerBody);
|
|
2656
|
+
this.omitted = text("omnius-task-notes:omitted", TextAttributes5.DIM);
|
|
2657
|
+
this.body.add(this.omitted);
|
|
2658
|
+
this.animation = new ActiveBlocks(renderer2, () => [...this.rows.values()].some((row) => row.item.status === "in_progress" && visible(row.title, renderer2)), (mark) => {
|
|
2659
|
+
this.frame = mark;
|
|
2660
|
+
for (const row of this.rows.values()) if (row.item.status === "in_progress" && visible(row.title, renderer2)) this.refreshRow(row);
|
|
2661
|
+
});
|
|
2662
|
+
renderer2.on(CliRenderEvents3.FRAME, this.finishInspect);
|
|
2663
|
+
}
|
|
2664
|
+
renderer;
|
|
2665
|
+
colors;
|
|
2666
|
+
reveal;
|
|
2667
|
+
header;
|
|
2668
|
+
body;
|
|
2669
|
+
scope;
|
|
2670
|
+
warning;
|
|
2671
|
+
taskHeader;
|
|
2672
|
+
taskBody;
|
|
2673
|
+
noteHeader;
|
|
2674
|
+
noteBody;
|
|
2675
|
+
layerHeader;
|
|
2676
|
+
layerBody;
|
|
2677
|
+
omitted;
|
|
2678
|
+
rows = /* @__PURE__ */ new Map();
|
|
2679
|
+
noteRows = /* @__PURE__ */ new Map();
|
|
2680
|
+
layerRows = /* @__PURE__ */ new Map();
|
|
2681
|
+
disclosures = /* @__PURE__ */ new Map();
|
|
2682
|
+
sessions = /* @__PURE__ */ new Map();
|
|
2683
|
+
state;
|
|
2684
|
+
signature = "";
|
|
2685
|
+
animation;
|
|
2686
|
+
frame = marks[0];
|
|
2687
|
+
taskLabel = "TASKS";
|
|
2688
|
+
pendingInspect;
|
|
2689
|
+
presentation = { open: true, tasks: true, notes: true, layers: true };
|
|
2690
|
+
get animating() {
|
|
2691
|
+
return this.animation.running;
|
|
2692
|
+
}
|
|
2693
|
+
update(state) {
|
|
2694
|
+
const signature = JSON.stringify(state);
|
|
2695
|
+
if (signature === this.signature) return;
|
|
2696
|
+
this.signature = signature;
|
|
2697
|
+
if (this.state?.sessionId !== state?.sessionId) {
|
|
2698
|
+
if (this.state?.sessionId) this.sessions.set(this.state.sessionId, this.capturePresentation());
|
|
2699
|
+
while (this.sessions.size > 64) this.sessions.delete(this.sessions.keys().next().value);
|
|
2700
|
+
const saved = state?.sessionId ? this.sessions.get(state.sessionId) : void 0;
|
|
2701
|
+
this.presentation = saved ? { open: saved.open, tasks: saved.tasks, notes: saved.notes, layers: saved.layers } : { open: true, tasks: true, notes: true, layers: true };
|
|
2702
|
+
this.disclosures.clear();
|
|
2703
|
+
if (saved) for (const [id, open] of Object.entries(saved.disclosures)) this.disclosures.set(id, open);
|
|
2704
|
+
}
|
|
2705
|
+
this.state = state;
|
|
2706
|
+
this.visible = !!state;
|
|
2707
|
+
const items = Array.isArray(state?.todos) ? state.todos.filter((item) => item && typeof item.id === "string" && typeof item.content === "string").slice(0, 512) : [];
|
|
2708
|
+
const byId = new Map(items.map((item) => [item.id, item]));
|
|
2709
|
+
const parents = /* @__PURE__ */ new Map();
|
|
2710
|
+
for (const item of items) if (item.parentId && byId.has(item.parentId) && item.parentId !== item.id) {
|
|
2711
|
+
let cursor = item.parentId;
|
|
2712
|
+
const seen = /* @__PURE__ */ new Set([item.id]);
|
|
2713
|
+
while (cursor && !seen.has(cursor)) {
|
|
2714
|
+
seen.add(cursor);
|
|
2715
|
+
cursor = byId.get(cursor)?.parentId;
|
|
2716
|
+
}
|
|
2717
|
+
if (!cursor) parents.set(item.id, item.parentId);
|
|
2718
|
+
}
|
|
2719
|
+
const ids = new Set(byId.keys());
|
|
2720
|
+
for (const [id, row] of this.rows) if (ids.has(id) && row.root.parent !== this.taskBody) this.taskBody.add(row.root);
|
|
2721
|
+
for (const [id, row] of this.rows) if (!ids.has(id)) {
|
|
2722
|
+
row.root.destroyRecursively();
|
|
2723
|
+
this.rows.delete(id);
|
|
2724
|
+
}
|
|
2725
|
+
for (const item of items) {
|
|
2726
|
+
let row = this.rows.get(item.id);
|
|
2727
|
+
if (!row) {
|
|
2728
|
+
const root = column(this.renderer, `task:${item.id}`), children = column(this.renderer, `task:${item.id}:children`);
|
|
2729
|
+
children.paddingLeft = 2;
|
|
2730
|
+
const title = new Disclosure(this.renderer, `task:${item.id}:title`, () => {
|
|
2731
|
+
const key = `task:${item.id}`;
|
|
2732
|
+
this.disclosures.set(key, !(this.disclosures.get(key) ?? row.hasChildren));
|
|
2733
|
+
this.refreshRow(row);
|
|
2734
|
+
}, this.colors);
|
|
2735
|
+
title.on(RenderableEvents3.FOCUSED, () => this.reveal?.(title));
|
|
2736
|
+
const details = new TextRenderable4(this.renderer, { id: `task:${item.id}:metadata`, content: "", width: "100%", minWidth: 0, wrapMode: "word", flexShrink: 0, fg: this.colors.foreground, bg: this.colors.background, attributes: TextAttributes5.DIM });
|
|
2737
|
+
const detailButton = new Disclosure(this.renderer, `task:${item.id}:details`, () => {
|
|
2738
|
+
const key = `meta:${item.id}`;
|
|
2739
|
+
this.disclosures.set(key, !this.disclosures.get(key));
|
|
2740
|
+
this.refreshRow(row);
|
|
2741
|
+
}, this.colors);
|
|
2742
|
+
detailButton.on(RenderableEvents3.FOCUSED, () => this.reveal?.(detailButton));
|
|
2743
|
+
root.add(title);
|
|
2744
|
+
root.add(detailButton);
|
|
2745
|
+
root.add(details);
|
|
2746
|
+
root.add(children);
|
|
2747
|
+
row = { item, root, title, detailButton, details, children, hasChildren: false };
|
|
2748
|
+
this.rows.set(item.id, row);
|
|
2749
|
+
}
|
|
2750
|
+
row.item = item;
|
|
2751
|
+
row.hasChildren = [...parents.values()].includes(item.id);
|
|
2752
|
+
const parent = parents.get(item.id);
|
|
2753
|
+
const target = parent ? this.rows.get(parent)?.children : this.taskBody;
|
|
2754
|
+
(target ?? this.taskBody).add(row.root);
|
|
2755
|
+
this.refreshRow(row);
|
|
2756
|
+
}
|
|
2757
|
+
for (const item of items) {
|
|
2758
|
+
const parent = parents.get(item.id);
|
|
2759
|
+
if (parent) this.rows.get(parent).children.add(this.rows.get(item.id).root);
|
|
2760
|
+
}
|
|
2761
|
+
const leaves = items.filter((item) => ![...parents.values()].includes(item.id));
|
|
2762
|
+
this.taskLabel = `TASKS ${leaves.filter((item) => item.status === "completed").length}/${leaves.length}`;
|
|
2763
|
+
this.scope.content = state ? `SESSION ${safe(state.sessionLabel || state.sessionId)}` : "";
|
|
2764
|
+
this.warning.content = safe(state?.unavailable);
|
|
2765
|
+
this.warning.visible = !!state?.unavailable;
|
|
2766
|
+
this.updateNotes(Array.isArray(state?.notes) ? state.notes.slice(0, 256) : []);
|
|
2767
|
+
this.updateLayers(Array.isArray(state?.layers) ? state.layers.slice(0, 64) : []);
|
|
2768
|
+
const missingTasks = Math.max(0, (state?.omittedTasks || 0) + (Array.isArray(state?.todos) ? state.todos.length - items.length : 0));
|
|
2769
|
+
const missingNotes = Math.max(0, (state?.omittedNotes || 0) + Math.max(0, (state?.notes?.length || 0) - 256));
|
|
2770
|
+
this.omitted.content = [missingTasks ? `${missingTasks} more tasks omitted` : "", missingNotes ? `${missingNotes} more notes omitted` : ""].filter(Boolean).join("\n");
|
|
2771
|
+
this.omitted.visible = missingTasks > 0 || missingNotes > 0;
|
|
2772
|
+
this.applyPresentation();
|
|
2773
|
+
}
|
|
2774
|
+
refreshRow(row) {
|
|
2775
|
+
const item = row.item, expanded = this.disclosures.get(`task:${item.id}`) ?? row.hasChildren;
|
|
2776
|
+
const state = item.status === "blocked" ? " BLOCKED" : !["pending", "in_progress", "completed"].includes(item.status) ? " UNKNOWN" : "";
|
|
2777
|
+
row.title.update(
|
|
2778
|
+
`${taskMark(item, this.frame)} ${safe(item.status === "in_progress" && item.activeForm ? item.activeForm : item.content)}${state}`,
|
|
2779
|
+
expanded,
|
|
2780
|
+
item.status === "in_progress" || item.status === "blocked" ? TextAttributes5.BOLD : item.status === "pending" || item.status === "completed" ? TextAttributes5.DIM : 0
|
|
2781
|
+
);
|
|
2782
|
+
const detail = metadata(item), metaOpen = row.hasChildren ? this.disclosures.get(`meta:${item.id}`) === true : expanded;
|
|
2783
|
+
row.details.content = detail;
|
|
2784
|
+
row.details.visible = !!detail && metaOpen;
|
|
2785
|
+
row.detailButton.visible = row.hasChildren && !!detail && expanded;
|
|
2786
|
+
row.detailButton.update("DETAILS", metaOpen, TextAttributes5.DIM);
|
|
2787
|
+
row.children.visible = expanded;
|
|
2788
|
+
this.animation?.sync();
|
|
2789
|
+
}
|
|
2790
|
+
updateNotes(notes) {
|
|
2791
|
+
const ids = new Set(notes.map((note) => String(note.id)));
|
|
2792
|
+
for (const [id, row] of this.noteRows) if (!ids.has(id)) {
|
|
2793
|
+
row.destroy();
|
|
2794
|
+
this.noteRows.delete(id);
|
|
2795
|
+
}
|
|
2796
|
+
for (const [index, note] of notes.entries()) {
|
|
2797
|
+
const id = String(note.id);
|
|
2798
|
+
let row = this.noteRows.get(id);
|
|
2799
|
+
if (!row) {
|
|
2800
|
+
row = new TextRenderable4(this.renderer, { id: `note:${id}`, content: "", width: "100%", minWidth: 0, wrapMode: "word", flexShrink: 0, fg: this.colors.foreground, bg: this.colors.background });
|
|
2801
|
+
this.noteRows.set(id, row);
|
|
2802
|
+
}
|
|
2803
|
+
const text = `□ ${safe(note.category).toUpperCase()} · ${safe(note.content)}${note.file ? `
|
|
2804
|
+
${safe(note.file)}${note.line ? `:${note.line}` : ""}` : ""}`;
|
|
2805
|
+
if (row.plainText !== text) row.content = text;
|
|
2806
|
+
if (this.noteBody.getChildren()[index] !== row) this.noteBody.add(row, index);
|
|
2807
|
+
}
|
|
2808
|
+
this.noteHeader.update(`NOTES ${notes.length} · ADVISORY`, this.presentation.notes);
|
|
2809
|
+
this.noteHeader.visible = notes.length > 0;
|
|
2810
|
+
}
|
|
2811
|
+
updateLayers(layers) {
|
|
2812
|
+
const ids = new Set(layers.map((layer) => safe(layer.id)));
|
|
2813
|
+
for (const [id, row] of this.layerRows) if (!ids.has(id)) {
|
|
2814
|
+
row.destroy();
|
|
2815
|
+
this.layerRows.delete(id);
|
|
2816
|
+
}
|
|
2817
|
+
for (const [index, layer] of layers.entries()) {
|
|
2818
|
+
const id = safe(layer.id);
|
|
2819
|
+
let row = this.layerRows.get(id);
|
|
2820
|
+
if (!row) {
|
|
2821
|
+
row = new TextRenderable4(this.renderer, { id: `work-layer:${id}`, content: "", width: "100%", minWidth: 0, wrapMode: "word", flexShrink: 0, fg: this.colors.foreground, bg: this.colors.background });
|
|
2822
|
+
this.layerRows.set(id, row);
|
|
2823
|
+
}
|
|
2824
|
+
const progress = typeof layer.progress === "number" && Number.isFinite(layer.progress) && layer.progress >= 0 && layer.progress <= 1 ? ` · ${Math.round(layer.progress * 100)}%` : "";
|
|
2825
|
+
const text = `□ ${safe(layer.label)} · ${layerStatus(layer)}${progress}${layer.detail ? `
|
|
2826
|
+
${safe(layer.detail)}` : ""}${lines(layer.references).length ? `
|
|
2827
|
+
REF ${lines(layer.references).join(", ")}` : ""}`;
|
|
2828
|
+
if (row.plainText !== text) row.content = text;
|
|
2829
|
+
if (this.layerBody.getChildren()[index] !== row) this.layerBody.add(row, index);
|
|
2830
|
+
}
|
|
2831
|
+
this.layerHeader.visible = layers.length > 0;
|
|
2832
|
+
}
|
|
2833
|
+
applyPresentation() {
|
|
2834
|
+
this.header.update("TASKS / NOTES", this.presentation.open);
|
|
2835
|
+
this.body.visible = this.presentation.open;
|
|
2836
|
+
this.taskBody.visible = this.presentation.tasks;
|
|
2837
|
+
this.taskHeader.update(this.taskLabel, this.presentation.tasks);
|
|
2838
|
+
this.noteBody.visible = this.presentation.notes;
|
|
2839
|
+
this.noteHeader.update(`NOTES ${this.noteRows.size} · ADVISORY`, this.presentation.notes);
|
|
2840
|
+
this.layerBody.visible = this.presentation.layers;
|
|
2841
|
+
this.layerHeader.update("RECORDED ORCHESTRATION", this.presentation.layers);
|
|
2842
|
+
this.animation.sync();
|
|
2843
|
+
}
|
|
2844
|
+
inspect(id) {
|
|
2845
|
+
this.presentation.open = this.presentation.tasks = true;
|
|
2846
|
+
if (id) {
|
|
2847
|
+
const row = this.rows.get(id);
|
|
2848
|
+
let parent = row?.item.parentId;
|
|
2849
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2850
|
+
while (parent && !seen.has(parent)) {
|
|
2851
|
+
seen.add(parent);
|
|
2852
|
+
this.disclosures.set(`task:${parent}`, true);
|
|
2853
|
+
const ancestor = this.rows.get(parent);
|
|
2854
|
+
if (ancestor) this.refreshRow(ancestor);
|
|
2855
|
+
parent = ancestor?.item.parentId;
|
|
2856
|
+
}
|
|
2857
|
+
}
|
|
2858
|
+
this.applyPresentation();
|
|
2859
|
+
const target = id ? this.rows.get(id)?.title : this.header;
|
|
2860
|
+
target?.focus();
|
|
2861
|
+
this.pendingInspect = id ?? "";
|
|
2862
|
+
this.renderer.requestRender();
|
|
2863
|
+
}
|
|
2864
|
+
finishInspect = () => {
|
|
2865
|
+
if (this.pendingInspect === void 0) return;
|
|
2866
|
+
const target = this.pendingInspect ? this.rows.get(this.pendingInspect)?.title : this.header;
|
|
2867
|
+
this.pendingInspect = void 0;
|
|
2868
|
+
if (target) {
|
|
2869
|
+
this.reveal?.(target);
|
|
2870
|
+
this.renderer.requestRender();
|
|
2871
|
+
}
|
|
2872
|
+
};
|
|
2873
|
+
capturePresentation() {
|
|
2874
|
+
return { ...this.presentation, disclosures: Object.fromEntries([...this.disclosures].slice(-2048)) };
|
|
2875
|
+
}
|
|
2876
|
+
restorePresentation(state) {
|
|
2877
|
+
if (!state) return;
|
|
2878
|
+
this.presentation = { open: state.open, tasks: state.tasks, notes: state.notes, layers: state.layers };
|
|
2879
|
+
this.disclosures.clear();
|
|
2880
|
+
for (const [id, open] of Object.entries(state.disclosures)) this.disclosures.set(id, open);
|
|
2881
|
+
for (const row of this.rows.values()) this.refreshRow(row);
|
|
2882
|
+
this.applyPresentation();
|
|
2883
|
+
}
|
|
2884
|
+
focusTargets() {
|
|
2885
|
+
const targets = [];
|
|
2886
|
+
const visit = (node) => {
|
|
2887
|
+
if (!node.visible) return;
|
|
2888
|
+
if (node instanceof TextRenderable4 && node.focusable) targets.push(node);
|
|
2889
|
+
for (const child of node.getChildren()) visit(child);
|
|
2890
|
+
};
|
|
2891
|
+
if (this.visible) visit(this);
|
|
2892
|
+
return targets;
|
|
2893
|
+
}
|
|
2894
|
+
applyTheme(colors) {
|
|
2895
|
+
this.colors = colors;
|
|
2896
|
+
const visit = (node) => {
|
|
2897
|
+
if (node instanceof TextRenderable4) {
|
|
2898
|
+
node.fg = colors.foreground;
|
|
2899
|
+
node.bg = colors.background;
|
|
2900
|
+
}
|
|
2901
|
+
for (const child of node.getChildren()) visit(child);
|
|
2902
|
+
};
|
|
2903
|
+
visit(this);
|
|
2904
|
+
}
|
|
2905
|
+
destroySelf() {
|
|
2906
|
+
this.animation.destroy();
|
|
2907
|
+
this.renderer.off(CliRenderEvents3.FRAME, this.finishInspect);
|
|
2908
|
+
super.destroySelf();
|
|
2909
|
+
}
|
|
2910
|
+
};
|
|
2911
|
+
var NativeTaskStrip = class extends BoxRenderable5 {
|
|
2912
|
+
constructor(renderer2, colors, inspect) {
|
|
2913
|
+
super(renderer2, {
|
|
2914
|
+
id: "omnius-task-strip",
|
|
2915
|
+
width: "100%",
|
|
2916
|
+
minWidth: 0,
|
|
2917
|
+
height: 3,
|
|
2918
|
+
minHeight: 3,
|
|
2919
|
+
maxHeight: 3,
|
|
2920
|
+
flexShrink: 0,
|
|
2921
|
+
border: true,
|
|
2922
|
+
borderStyle: "single",
|
|
2923
|
+
borderColor: colors.border,
|
|
2924
|
+
flexDirection: "row",
|
|
2925
|
+
visible: false
|
|
2926
|
+
});
|
|
2927
|
+
this.renderer = renderer2;
|
|
2928
|
+
this.colors = colors;
|
|
2929
|
+
this.inspect = inspect;
|
|
2930
|
+
this.label = new TextRenderable4(renderer2, {
|
|
2931
|
+
id: "omnius-task-strip:heading",
|
|
2932
|
+
content: "TASKS ",
|
|
2933
|
+
height: 1,
|
|
2934
|
+
width: 6,
|
|
2935
|
+
flexShrink: 0,
|
|
2936
|
+
selectable: false,
|
|
2937
|
+
fg: colors.foreground,
|
|
2938
|
+
bg: colors.background,
|
|
2939
|
+
attributes: TextAttributes5.BOLD,
|
|
2940
|
+
onMouseDown: (event) => {
|
|
2941
|
+
if (event.button === 0) {
|
|
2942
|
+
inspect();
|
|
2943
|
+
event.preventDefault();
|
|
2944
|
+
event.stopPropagation();
|
|
2945
|
+
}
|
|
2946
|
+
},
|
|
2947
|
+
onKeyDown: (key) => {
|
|
2948
|
+
if (key.eventType !== "release" && (key.name === "return" || key.sequence === " ")) {
|
|
2949
|
+
inspect();
|
|
2950
|
+
key.preventDefault();
|
|
2951
|
+
key.stopPropagation();
|
|
2952
|
+
}
|
|
2953
|
+
}
|
|
2954
|
+
});
|
|
2955
|
+
this.label.focusable = true;
|
|
2956
|
+
this.add(this.label);
|
|
2957
|
+
this.scroll = new ScrollBoxRenderable3(renderer2, {
|
|
2958
|
+
id: "omnius-task-strip:scroll",
|
|
2959
|
+
height: 1,
|
|
2960
|
+
minHeight: 1,
|
|
2961
|
+
maxHeight: 1,
|
|
2962
|
+
minWidth: 0,
|
|
2963
|
+
flexGrow: 1,
|
|
2964
|
+
scrollX: true,
|
|
2965
|
+
scrollY: false,
|
|
2966
|
+
viewportOptions: { height: 1, minHeight: 1, maxHeight: 1, flexGrow: 0, flexShrink: 0 },
|
|
2967
|
+
contentOptions: { flexDirection: "row", gap: 3 },
|
|
2968
|
+
horizontalScrollbarOptions: { visible: false },
|
|
2969
|
+
verticalScrollbarOptions: { visible: false }
|
|
2970
|
+
});
|
|
2971
|
+
this.scroll.horizontalScrollBar.visible = this.scroll.verticalScrollBar.visible = false;
|
|
2972
|
+
this.add(this.scroll);
|
|
2973
|
+
styleNativeScrollbars(this.scroll, colors);
|
|
2974
|
+
this.animation = new ActiveBlocks(renderer2, () => [...this.chips.values()].some((chip) => chip.item.status === "in_progress" && visible(chip.label, renderer2)), (mark) => {
|
|
2975
|
+
this.frame = mark;
|
|
2976
|
+
for (const chip of this.chips.values()) if (chip.item.status === "in_progress" && visible(chip.label, renderer2)) this.refreshChip(chip);
|
|
2977
|
+
});
|
|
2978
|
+
}
|
|
2979
|
+
renderer;
|
|
2980
|
+
colors;
|
|
2981
|
+
inspect;
|
|
2982
|
+
scroll;
|
|
2983
|
+
label;
|
|
2984
|
+
chips = /* @__PURE__ */ new Map();
|
|
2985
|
+
animation;
|
|
2986
|
+
frame = marks[0];
|
|
2987
|
+
sessionId;
|
|
2988
|
+
signature = "";
|
|
2989
|
+
hasItems = false;
|
|
2990
|
+
get animating() {
|
|
2991
|
+
return this.animation.running;
|
|
2992
|
+
}
|
|
2993
|
+
update(state) {
|
|
2994
|
+
const signature = JSON.stringify(state);
|
|
2995
|
+
if (signature === this.signature) return;
|
|
2996
|
+
this.signature = signature;
|
|
2997
|
+
const source = Array.isArray(state?.todos) ? state.todos.filter((item) => item && typeof item.id === "string" && typeof item.content === "string").slice(0, 512) : [];
|
|
2998
|
+
const parents = new Set(source.map((item) => item.parentId).filter(Boolean));
|
|
2999
|
+
const children = /* @__PURE__ */ new Map();
|
|
3000
|
+
for (const item of source) if (item.parentId) {
|
|
3001
|
+
const list = children.get(item.parentId) ?? [];
|
|
3002
|
+
list.push(item);
|
|
3003
|
+
children.set(item.parentId, list);
|
|
3004
|
+
}
|
|
3005
|
+
const busy = (item) => item.status === "in_progress" || item.status === "blocked";
|
|
3006
|
+
const activeDescendant = (id) => {
|
|
3007
|
+
const seen = /* @__PURE__ */ new Set([id]), stack = [...children.get(id) ?? []];
|
|
3008
|
+
while (stack.length) {
|
|
3009
|
+
const item = stack.pop();
|
|
3010
|
+
if (seen.has(item.id)) continue;
|
|
3011
|
+
seen.add(item.id);
|
|
3012
|
+
if (busy(item)) return true;
|
|
3013
|
+
stack.push(...children.get(item.id) ?? []);
|
|
3014
|
+
}
|
|
3015
|
+
return false;
|
|
3016
|
+
};
|
|
3017
|
+
let leaves = source.filter((item) => item.status !== "completed" && (!parents.has(item.id) || busy(item) && !activeDescendant(item.id)));
|
|
3018
|
+
if (!leaves.length) leaves = source.filter((item) => item.status !== "completed");
|
|
3019
|
+
const items = [leaves.filter((item) => item.status === "in_progress"), leaves.filter((item) => item.status === "blocked"), leaves.filter((item) => item.status !== "in_progress" && item.status !== "blocked")].flat();
|
|
3020
|
+
const ids = new Set(items.map((item) => item.id));
|
|
3021
|
+
const wasFirst = this.scroll.getChildren()[0]?.id;
|
|
3022
|
+
for (const [id, chip] of this.chips) if (!ids.has(id)) {
|
|
3023
|
+
chip.label.destroy();
|
|
3024
|
+
this.chips.delete(id);
|
|
3025
|
+
}
|
|
3026
|
+
for (const [index, item] of items.entries()) {
|
|
3027
|
+
let chip = this.chips.get(item.id);
|
|
3028
|
+
if (!chip) {
|
|
3029
|
+
const label2 = new TextRenderable4(this.renderer, {
|
|
3030
|
+
id: `task-strip:${item.id}`,
|
|
3031
|
+
content: "",
|
|
3032
|
+
height: 1,
|
|
3033
|
+
flexShrink: 0,
|
|
3034
|
+
wrapMode: "none",
|
|
3035
|
+
selectable: false,
|
|
3036
|
+
fg: this.colors.foreground,
|
|
3037
|
+
bg: this.colors.background,
|
|
3038
|
+
onMouseDown: (event) => {
|
|
3039
|
+
if (event.button === 0) {
|
|
3040
|
+
label2.focus();
|
|
3041
|
+
this.inspect(item.id);
|
|
3042
|
+
event.preventDefault();
|
|
3043
|
+
event.stopPropagation();
|
|
3044
|
+
}
|
|
3045
|
+
},
|
|
3046
|
+
onKeyDown: (key) => {
|
|
3047
|
+
if (key.eventType === "release") return;
|
|
3048
|
+
if (key.name === "return" || key.sequence === " ") this.inspect(item.id);
|
|
3049
|
+
else if (["left", "right", "home", "end"].includes(key.name)) {
|
|
3050
|
+
const targets = this.scroll.getChildren();
|
|
3051
|
+
const index2 = targets.indexOf(label2);
|
|
3052
|
+
const next = key.name === "home" ? 0 : key.name === "end" ? targets.length - 1 : Math.max(0, Math.min(targets.length - 1, index2 + (key.name === "left" ? -1 : 1)));
|
|
3053
|
+
targets[next]?.focus();
|
|
3054
|
+
if (targets[next]) this.scroll.scrollChildIntoView(targets[next].id);
|
|
3055
|
+
} else return;
|
|
3056
|
+
key.preventDefault();
|
|
3057
|
+
key.stopPropagation();
|
|
3058
|
+
}
|
|
3059
|
+
});
|
|
3060
|
+
label2.focusable = true;
|
|
3061
|
+
chip = { item, label: label2 };
|
|
3062
|
+
this.chips.set(item.id, chip);
|
|
3063
|
+
label2.on(RenderableEvents3.FOCUSED, () => {
|
|
3064
|
+
this.refreshChip(chip);
|
|
3065
|
+
this.scroll.scrollChildIntoView(label2.id);
|
|
3066
|
+
});
|
|
3067
|
+
label2.on(RenderableEvents3.BLURRED, () => this.refreshChip(chip));
|
|
3068
|
+
}
|
|
3069
|
+
chip.item = item;
|
|
3070
|
+
this.refreshChip(chip);
|
|
3071
|
+
if (this.scroll.getChildren()[index] !== chip.label) this.scroll.add(chip.label, index);
|
|
3072
|
+
}
|
|
3073
|
+
this.label.content = state ? fitInstrumentText(safe(state.sessionLabel || state.sessionId).toUpperCase(), 12) + " TASKS " : "TASKS ";
|
|
3074
|
+
this.label.width = terminalCellWidth(this.label.plainText);
|
|
3075
|
+
if (this.sessionId !== state?.sessionId || wasFirst !== this.scroll.getChildren()[0]?.id) this.scroll.scrollTo({ x: 0, y: 0 });
|
|
3076
|
+
this.sessionId = state?.sessionId;
|
|
3077
|
+
this.visible = this.hasItems = items.length > 0;
|
|
3078
|
+
this.animation.sync();
|
|
3079
|
+
}
|
|
3080
|
+
refreshChip(chip) {
|
|
3081
|
+
const item = chip.item;
|
|
3082
|
+
const title = safe(item.status === "in_progress" && item.activeForm ? item.activeForm : item.content).replace(/\s+/g, " ");
|
|
3083
|
+
const content = `${taskMark(item, this.frame)} ${fitInstrumentText(title, 34)}${item.status === "blocked" ? " BLOCKED" : ""}`;
|
|
3084
|
+
if (chip.label.plainText !== content) chip.label.content = content;
|
|
3085
|
+
chip.label.attributes = (item.status === "in_progress" || item.status === "blocked" ? TextAttributes5.BOLD : TextAttributes5.DIM) | (chip.label.focused ? TextAttributes5.INVERSE : 0);
|
|
3086
|
+
}
|
|
3087
|
+
applyTheme(colors) {
|
|
3088
|
+
this.colors = colors;
|
|
3089
|
+
this.borderColor = colors.border;
|
|
3090
|
+
this.label.fg = colors.foreground;
|
|
3091
|
+
this.label.bg = colors.background;
|
|
3092
|
+
for (const chip of this.chips.values()) {
|
|
3093
|
+
chip.label.fg = colors.foreground;
|
|
3094
|
+
chip.label.bg = colors.background;
|
|
3095
|
+
}
|
|
3096
|
+
styleNativeScrollbars(this.scroll, colors);
|
|
3097
|
+
}
|
|
3098
|
+
reconcile() {
|
|
3099
|
+
this.animation.sync();
|
|
3100
|
+
}
|
|
3101
|
+
destroySelf() {
|
|
3102
|
+
this.animation.destroy();
|
|
3103
|
+
super.destroySelf();
|
|
3104
|
+
}
|
|
3105
|
+
};
|
|
3106
|
+
|
|
3107
|
+
// packages/cli/src/tui/native/components/work-queue.ts
|
|
3108
|
+
import {
|
|
3109
|
+
BoxRenderable as BoxRenderable6,
|
|
3110
|
+
CliRenderEvents as CliRenderEvents4,
|
|
3111
|
+
RenderableEvents as RenderableEvents4,
|
|
3112
|
+
ScrollBoxRenderable as ScrollBoxRenderable4,
|
|
3113
|
+
TextAttributes as TextAttributes6,
|
|
3114
|
+
TextRenderable as TextRenderable5
|
|
3115
|
+
} from "@opentui/core";
|
|
3116
|
+
var frames = ["▨", "▧", "▥", "▦"];
|
|
3117
|
+
var actionLabels = { queue: "QUEUE", apply: "APPLY", override: "OVERRIDE", cancel: "CANCEL", retry: "RETRY", up: "UP", down: "DOWN" };
|
|
3118
|
+
var safe2 = (value) => typeof value === "string" ? plainText(value) : "";
|
|
3119
|
+
var label = (value) => safe2(value).replace(/[\r\n\t]+/g, " ");
|
|
3120
|
+
var reducedMotion2 = () => process.env["OMNIUS_TUI_REDUCE_MOTION"] === "1" || process.env["REDUCE_MOTION"] === "1";
|
|
3121
|
+
var column2 = (renderer2, id) => new BoxRenderable6(renderer2, { id, width: "100%", minWidth: 0, flexDirection: "column", flexShrink: 0 });
|
|
3122
|
+
var historyStates = /* @__PURE__ */ new Set(["completed", "applied", "failed", "cancelled"]);
|
|
3123
|
+
var activeStates = /* @__PURE__ */ new Set(["claiming", "running", "admitted"]);
|
|
3124
|
+
var receiptTime = (at) => {
|
|
3125
|
+
const date = new Date(typeof at === "number" ? at : NaN);
|
|
3126
|
+
return Number.isFinite(date.getTime()) ? date.toISOString() : "";
|
|
3127
|
+
};
|
|
3128
|
+
var WorkControl = class extends TextRenderable5 {
|
|
3129
|
+
constructor(renderer2, id, activate, colors, disclosure = false, ruled = false, fixedWidth) {
|
|
3130
|
+
super(renderer2, {
|
|
3131
|
+
id,
|
|
3132
|
+
content: "",
|
|
3133
|
+
width: fixedWidth ?? "100%",
|
|
3134
|
+
minWidth: 0,
|
|
3135
|
+
height: 1,
|
|
3136
|
+
flexShrink: 0,
|
|
3137
|
+
wrapMode: "none",
|
|
3138
|
+
truncate: true,
|
|
3139
|
+
fg: colors.foreground,
|
|
3140
|
+
bg: colors.background,
|
|
3141
|
+
selectable: false,
|
|
3142
|
+
onMouseDown: (event) => {
|
|
3143
|
+
if (event.button === 0) {
|
|
3144
|
+
this.focus();
|
|
3145
|
+
activate();
|
|
3146
|
+
event.preventDefault();
|
|
3147
|
+
event.stopPropagation();
|
|
3148
|
+
}
|
|
3149
|
+
},
|
|
3150
|
+
onKeyDown: (key) => {
|
|
3151
|
+
if (key.eventType !== "release" && (key.name === "return" || key.sequence === " " || disclosure && (key.name === "right" && !this.open || key.name === "left" && this.open))) {
|
|
3152
|
+
activate();
|
|
3153
|
+
key.preventDefault();
|
|
3154
|
+
key.stopPropagation();
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
});
|
|
3158
|
+
this.activate = activate;
|
|
3159
|
+
this.disclosure = disclosure;
|
|
3160
|
+
this.ruled = ruled;
|
|
3161
|
+
this.focusable = true;
|
|
3162
|
+
this.on(RenderableEvents4.FOCUSED, this.style);
|
|
3163
|
+
this.on(RenderableEvents4.BLURRED, this.style);
|
|
3164
|
+
}
|
|
3165
|
+
activate;
|
|
3166
|
+
disclosure;
|
|
3167
|
+
ruled;
|
|
3168
|
+
open = false;
|
|
3169
|
+
caption = "";
|
|
3170
|
+
base = 0;
|
|
3171
|
+
update(caption, open = false, attributes = 0) {
|
|
3172
|
+
this.caption = caption;
|
|
3173
|
+
this.open = open;
|
|
3174
|
+
this.base = attributes;
|
|
3175
|
+
this.refresh();
|
|
3176
|
+
this.style();
|
|
3177
|
+
}
|
|
3178
|
+
style = () => {
|
|
3179
|
+
this.attributes = this.base | (this.focused ? TextAttributes6.INVERSE : 0);
|
|
3180
|
+
};
|
|
3181
|
+
onResize(width, height) {
|
|
3182
|
+
super.onResize(width, height);
|
|
3183
|
+
this.refresh();
|
|
3184
|
+
}
|
|
3185
|
+
refresh() {
|
|
3186
|
+
const value = this.ruled ? formatSectionBanner(this.caption, this.width, this.open) : fitInstrumentText(`${this.disclosure ? this.open ? "− " : "+ " : ""}${this.caption}`, this.width);
|
|
3187
|
+
if (this.plainText !== value) this.content = value;
|
|
3188
|
+
}
|
|
3189
|
+
};
|
|
3190
|
+
var NativeWorkQueueView = class extends BoxRenderable6 {
|
|
3191
|
+
constructor(renderer2, colors, onAction, reveal) {
|
|
3192
|
+
super(renderer2, { id: "omnius-work-queue", width: "100%", minWidth: 0, flexDirection: "column", flexShrink: 0, visible: false });
|
|
3193
|
+
this.renderer = renderer2;
|
|
3194
|
+
this.colors = colors;
|
|
3195
|
+
this.onAction = onAction;
|
|
3196
|
+
this.reveal = reveal;
|
|
3197
|
+
this.header = this.control("omnius-work-queue:heading", () => {
|
|
3198
|
+
this.presentation.open = !this.presentation.open;
|
|
3199
|
+
this.applyPresentation();
|
|
3200
|
+
}, true, true);
|
|
3201
|
+
this.add(this.header);
|
|
3202
|
+
this.body = column2(renderer2, "omnius-work-queue:body");
|
|
3203
|
+
this.add(this.body);
|
|
3204
|
+
this.scope = this.text("omnius-work-queue:scope", TextAttributes6.DIM);
|
|
3205
|
+
this.body.add(this.scope);
|
|
3206
|
+
this.warning = this.text("omnius-work-queue:warning", TextAttributes6.BOLD);
|
|
3207
|
+
this.body.add(this.warning);
|
|
3208
|
+
for (const group of ["current", "intake", "upcoming", "held"]) {
|
|
3209
|
+
const heading = this.text(`omnius-work-queue:${group}:heading`, TextAttributes6.DIM | TextAttributes6.BOLD);
|
|
3210
|
+
const body = column2(renderer2, `omnius-work-queue:${group}`);
|
|
3211
|
+
this.groups.set(group, { heading, body });
|
|
3212
|
+
this.body.add(heading);
|
|
3213
|
+
this.body.add(body);
|
|
3214
|
+
}
|
|
3215
|
+
this.historyHeader = this.control("omnius-work-queue:history:heading", () => {
|
|
3216
|
+
this.presentation.history = !this.presentation.history;
|
|
3217
|
+
this.applyPresentation();
|
|
3218
|
+
}, true);
|
|
3219
|
+
const history = column2(renderer2, "omnius-work-queue:history");
|
|
3220
|
+
this.groups.set("history", { heading: this.historyHeader, body: history });
|
|
3221
|
+
this.body.add(this.historyHeader);
|
|
3222
|
+
this.body.add(history);
|
|
3223
|
+
this.empty = this.text("omnius-work-queue:empty", TextAttributes6.DIM);
|
|
3224
|
+
this.empty.content = "No pending work.";
|
|
3225
|
+
this.body.add(this.empty);
|
|
3226
|
+
this.omitted = this.text("omnius-work-queue:omitted", TextAttributes6.DIM);
|
|
3227
|
+
this.body.add(this.omitted);
|
|
3228
|
+
renderer2.on(CliRenderEvents4.FRAME, this.syncAnimation);
|
|
3229
|
+
}
|
|
3230
|
+
renderer;
|
|
3231
|
+
colors;
|
|
3232
|
+
onAction;
|
|
3233
|
+
reveal;
|
|
3234
|
+
header;
|
|
3235
|
+
body;
|
|
3236
|
+
historyHeader;
|
|
3237
|
+
scope;
|
|
3238
|
+
warning;
|
|
3239
|
+
empty;
|
|
3240
|
+
omitted;
|
|
3241
|
+
groups = /* @__PURE__ */ new Map();
|
|
3242
|
+
rows = /* @__PURE__ */ new Map();
|
|
3243
|
+
sessions = /* @__PURE__ */ new Map();
|
|
3244
|
+
state;
|
|
3245
|
+
signature = "";
|
|
3246
|
+
presentation = { open: true, history: false, disclosures: {} };
|
|
3247
|
+
timer;
|
|
3248
|
+
frame = 0;
|
|
3249
|
+
disposed = false;
|
|
3250
|
+
text(id, attributes = 0) {
|
|
3251
|
+
return new TextRenderable5(this.renderer, { id, content: "", width: "100%", minWidth: 0, flexShrink: 0, wrapMode: "word", fg: this.colors.foreground, bg: this.colors.background, attributes });
|
|
3252
|
+
}
|
|
3253
|
+
control(id, activate, disclosure = false, ruled = false, width) {
|
|
3254
|
+
const node = new WorkControl(this.renderer, id, activate, this.colors, disclosure, ruled, width);
|
|
3255
|
+
node.on(RenderableEvents4.FOCUSED, () => this.reveal?.(node));
|
|
3256
|
+
return node;
|
|
3257
|
+
}
|
|
3258
|
+
get animating() {
|
|
3259
|
+
return this.timer !== void 0;
|
|
3260
|
+
}
|
|
3261
|
+
update(state) {
|
|
3262
|
+
if (state && state === this.state) return;
|
|
3263
|
+
const signature = JSON.stringify(state);
|
|
3264
|
+
if (signature === this.signature) return;
|
|
3265
|
+
this.signature = signature;
|
|
3266
|
+
const scope = (value) => value ? `${value.projectRoot}\0${value.sessionId}` : "";
|
|
3267
|
+
if (scope(state) !== scope(this.state)) {
|
|
3268
|
+
if (this.state) this.sessions.set(scope(this.state), this.capturePresentation());
|
|
3269
|
+
while (this.sessions.size > 64) this.sessions.delete(this.sessions.keys().next().value);
|
|
3270
|
+
this.presentation = structuredClone(this.sessions.get(scope(state)) ?? { open: true, history: false, disclosures: {} });
|
|
3271
|
+
for (const row of this.rows.values()) row.root.destroy();
|
|
3272
|
+
this.rows.clear();
|
|
3273
|
+
}
|
|
3274
|
+
this.state = state;
|
|
3275
|
+
this.visible = Boolean(state);
|
|
3276
|
+
if (!state) {
|
|
3277
|
+
this.syncAnimation();
|
|
3278
|
+
return;
|
|
3279
|
+
}
|
|
3280
|
+
this.scope.content = `SESSION ${label(state.sessionLabel || state.sessionId)}`;
|
|
3281
|
+
this.warning.content = safe2(state.unavailable);
|
|
3282
|
+
this.warning.visible = Boolean(state.unavailable);
|
|
3283
|
+
const items = state.items.filter((item) => item && typeof item.id === "string"), ids = new Set(items.map((item) => item.id));
|
|
3284
|
+
for (const [id, row] of this.rows) if (!ids.has(id)) {
|
|
3285
|
+
row.root.destroy();
|
|
3286
|
+
this.rows.delete(id);
|
|
3287
|
+
delete this.presentation.disclosures[id];
|
|
3288
|
+
}
|
|
3289
|
+
const order = (a, b) => a.order - b.order || a.id.localeCompare(b.id);
|
|
3290
|
+
const groups = { current: [], intake: [], upcoming: [], held: [], history: [] };
|
|
3291
|
+
for (const item of items) {
|
|
3292
|
+
const group = item.id === state.activeId || activeStates.has(item.state) ? "current" : historyStates.has(item.state) ? "history" : item.state === "needs_review" || item.state === "interrupted" ? "held" : item.state === "reviewing" || item.state === "received" ? "intake" : "upcoming";
|
|
3293
|
+
groups[group].push(item);
|
|
3294
|
+
}
|
|
3295
|
+
groups.current.sort((a, b) => Number(b.id === state.activeId) - Number(a.id === state.activeId) || order(a, b));
|
|
3296
|
+
groups.intake.sort(order);
|
|
3297
|
+
groups.upcoming.sort(order);
|
|
3298
|
+
groups.held.sort(order);
|
|
3299
|
+
groups.history.sort((a, b) => (b.receivedAt ?? 0) - (a.receivedAt ?? 0) || order(a, b));
|
|
3300
|
+
const titles = { current: "CURRENT", intake: "INTAKE", upcoming: "QUEUED", held: "HELD / REVIEW", history: "HISTORY" };
|
|
3301
|
+
for (const group of ["current", "intake", "upcoming", "held", "history"]) {
|
|
3302
|
+
const target = this.groups.get(group);
|
|
3303
|
+
target.heading.visible = groups[group].length > 0;
|
|
3304
|
+
target.body.visible = groups[group].length > 0;
|
|
3305
|
+
if (group !== "history") target.heading.content = `${titles[group]} ${groups[group].length}`;
|
|
3306
|
+
for (const [index, item] of groups[group].entries()) {
|
|
3307
|
+
const row = this.rows.get(item.id) ?? this.createRow(item);
|
|
3308
|
+
row.item = item;
|
|
3309
|
+
row.position = group === "upcoming" ? index + 1 : void 0;
|
|
3310
|
+
this.refreshRow(row);
|
|
3311
|
+
if (row.root.parent !== target.body || target.body.getChildren()[index] !== row.root) target.body.add(row.root, index);
|
|
3312
|
+
}
|
|
3313
|
+
}
|
|
3314
|
+
this.empty.visible = items.length === 0 && !state.unavailable;
|
|
3315
|
+
this.omitted.content = state.omitted ? `${state.omitted} more work items omitted` : "";
|
|
3316
|
+
this.omitted.visible = Boolean(state.omitted);
|
|
3317
|
+
this.applyPresentation();
|
|
3318
|
+
}
|
|
3319
|
+
createRow(item) {
|
|
3320
|
+
const id = `work:${item.id}`, root = column2(this.renderer, id);
|
|
3321
|
+
const title = this.control(`${id}:title`, () => {
|
|
3322
|
+
this.presentation.disclosures[item.id] = !this.presentation.disclosures[item.id];
|
|
3323
|
+
this.refreshRow(this.rows.get(item.id));
|
|
3324
|
+
this.renderer.requestRender();
|
|
3325
|
+
}, true);
|
|
3326
|
+
root.add(title);
|
|
3327
|
+
const details = column2(this.renderer, `${id}:details`);
|
|
3328
|
+
details.paddingLeft = 2;
|
|
3329
|
+
root.add(details);
|
|
3330
|
+
const metadata2 = this.text(`${id}:metadata`, TextAttributes6.DIM), original = this.text(`${id}:original`);
|
|
3331
|
+
details.add(original);
|
|
3332
|
+
details.add(metadata2);
|
|
3333
|
+
const controls = new BoxRenderable6(this.renderer, { id: `${id}:actions`, width: "100%", minWidth: 0, flexDirection: "row", flexWrap: "wrap", flexShrink: 0 });
|
|
3334
|
+
details.add(controls);
|
|
3335
|
+
const row = { item, root, title, details, original, metadata: metadata2, controls, actions: /* @__PURE__ */ new Map() };
|
|
3336
|
+
this.rows.set(item.id, row);
|
|
3337
|
+
return row;
|
|
3338
|
+
}
|
|
3339
|
+
refreshRow(row) {
|
|
3340
|
+
const item = row.item, open = this.presentation.disclosures[item.id] === true;
|
|
3341
|
+
const state = label(item.state).replace(/_/g, " ").toUpperCase();
|
|
3342
|
+
const mark = item.state === "reviewing" || item.state === "claiming" ? frames[this.frame % frames.length] : item.state === "running" ? "▨" : item.state === "needs_review" || item.state === "interrupted" ? "▣" : historyStates.has(item.state) ? "■" : "□";
|
|
3343
|
+
row.title.update(
|
|
3344
|
+
`${mark} ${row.position === void 0 ? "" : `${row.position}. `}${state} · ${label(item.title) || "Untitled request"}`,
|
|
3345
|
+
open,
|
|
3346
|
+
item.state === "queued" ? TextAttributes6.DIM : item.state === "running" || item.state === "needs_review" ? TextAttributes6.BOLD : 0
|
|
3347
|
+
);
|
|
3348
|
+
row.details.visible = open;
|
|
3349
|
+
const original = `ORIGINAL
|
|
3350
|
+
${safe2(item.originalText)}`;
|
|
3351
|
+
if (row.original.plainText !== original) row.original.content = original;
|
|
3352
|
+
const metadata2 = [
|
|
3353
|
+
item.source ? `SOURCE ${label(item.source)}` : "",
|
|
3354
|
+
`PROJECT ${safe2(this.state?.projectRoot)}`,
|
|
3355
|
+
item.parentWorkId ? `PARENT ${label(item.parentWorkId)}` : "",
|
|
3356
|
+
item.runId ? `RUN ${label(item.runId)}` : "",
|
|
3357
|
+
...(item.attachments ?? []).map((attachment) => [`ATTACHMENT ${label(attachment.kind)} · ${label(attachment.label)}`, attachment.path ? `PATH ${safe2(attachment.path)}` : "", attachment.reference ? `REFERENCE ${safe2(attachment.reference)}` : "", attachment.mimeType ? `MIME ${label(attachment.mimeType)}` : ""].filter(Boolean).join("\n")),
|
|
3358
|
+
...item.review ? [`RECOMMENDATION ${label(item.review.disposition).replace(/_/g, " ")}`, item.review.summary ? `SUMMARY ${safe2(item.review.summary)}` : "", item.review.rationale ? `RATIONALE ${safe2(item.review.rationale)}` : "", item.review.relationship ? `RELATIONSHIP ${safe2(item.review.relationship)}` : "", ...(item.review.questions ?? []).map((question) => `QUESTION ${safe2(question)}`)] : [],
|
|
3359
|
+
...(item.receipts ?? []).map((receipt) => `RECEIPT ${label(receipt.kind).replace(/_/g, " ")}${receiptTime(receipt.at) ? ` · ${receiptTime(receipt.at)}` : ""}${receipt.message ? `
|
|
3360
|
+
${safe2(receipt.message)}` : ""}${receipt.runId ? `
|
|
3361
|
+
RUN ${label(receipt.runId)}` : ""}`)
|
|
3362
|
+
].filter(Boolean).join("\n");
|
|
3363
|
+
if (row.metadata.plainText !== metadata2) row.metadata.content = metadata2;
|
|
3364
|
+
const allowed = [...new Set(item.actions ?? [])].filter((action) => Object.hasOwn(actionLabels, action));
|
|
3365
|
+
for (const [action, button] of row.actions) if (!allowed.includes(action)) {
|
|
3366
|
+
button.destroy();
|
|
3367
|
+
row.actions.delete(action);
|
|
3368
|
+
}
|
|
3369
|
+
for (const [index, action] of allowed.entries()) {
|
|
3370
|
+
let button = row.actions.get(action);
|
|
3371
|
+
if (!button) {
|
|
3372
|
+
button = this.control(`work:${item.id}:action:${action}`, () => this.dispatch(item.id, action), false, false, terminalCellWidth(actionLabels[action]) + 2);
|
|
3373
|
+
button.update(`[${actionLabels[action]}]`);
|
|
3374
|
+
row.actions.set(action, button);
|
|
3375
|
+
}
|
|
3376
|
+
if (row.controls.getChildren()[index] !== button) row.controls.add(button, index);
|
|
3377
|
+
}
|
|
3378
|
+
row.controls.visible = allowed.length > 0;
|
|
3379
|
+
}
|
|
3380
|
+
dispatch(id, action) {
|
|
3381
|
+
const item = this.rows.get(id)?.item, state = this.state;
|
|
3382
|
+
if (!state || !item?.actions?.includes(action)) return;
|
|
3383
|
+
this.onAction?.({ type: "work-action", action, id, expectedRevision: item.revision, expectedQueueRevision: state.revision, sessionId: state.sessionId, projectRoot: state.projectRoot });
|
|
3384
|
+
}
|
|
3385
|
+
applyPresentation() {
|
|
3386
|
+
const count = this.state?.items.filter((item) => !historyStates.has(item.state)).length ?? 0;
|
|
3387
|
+
this.header.update(`WORK / QUEUE ${count}`, this.presentation.open, TextAttributes6.BOLD);
|
|
3388
|
+
this.body.visible = this.presentation.open;
|
|
3389
|
+
const history = this.groups.get("history");
|
|
3390
|
+
this.historyHeader.update(`HISTORY ${history.body.getChildren().length}`, this.presentation.history, TextAttributes6.DIM);
|
|
3391
|
+
history.body.visible = history.body.getChildren().length > 0 && this.presentation.history;
|
|
3392
|
+
this.syncAnimation();
|
|
3393
|
+
this.renderer.requestRender();
|
|
3394
|
+
}
|
|
3395
|
+
isVisible(node) {
|
|
3396
|
+
if (node.width < 1 || node.height < 1 || node.y >= this.renderer.terminalHeight || node.y + node.height <= 0) return false;
|
|
3397
|
+
for (let ancestor = node; ancestor; ancestor = ancestor.parent) {
|
|
3398
|
+
if (!ancestor.visible) return false;
|
|
3399
|
+
if (ancestor instanceof ScrollBoxRenderable4 && (node.y + node.height <= ancestor.viewport.y || node.y >= ancestor.viewport.y + ancestor.viewport.height)) return false;
|
|
3400
|
+
}
|
|
3401
|
+
return true;
|
|
3402
|
+
}
|
|
3403
|
+
syncAnimation = () => {
|
|
3404
|
+
const active = !this.disposed && !reducedMotion2() && [...this.rows.values()].some((row) => ["reviewing", "claiming"].includes(row.item.state) && this.isVisible(row.title));
|
|
3405
|
+
if (active && !this.timer) {
|
|
3406
|
+
this.timer = setInterval(() => {
|
|
3407
|
+
if (reducedMotion2() || ![...this.rows.values()].some((row) => ["reviewing", "claiming"].includes(row.item.state) && this.isVisible(row.title))) {
|
|
3408
|
+
this.syncAnimation();
|
|
3409
|
+
return;
|
|
3410
|
+
}
|
|
3411
|
+
this.frame++;
|
|
3412
|
+
for (const row of this.rows.values()) if (["reviewing", "claiming"].includes(row.item.state) && this.isVisible(row.title)) this.refreshTitle(row);
|
|
3413
|
+
}, 250);
|
|
3414
|
+
this.timer.unref?.();
|
|
3415
|
+
} else if (!active && this.timer) {
|
|
3416
|
+
clearInterval(this.timer);
|
|
3417
|
+
this.timer = void 0;
|
|
3418
|
+
}
|
|
3419
|
+
};
|
|
3420
|
+
refreshTitle(row) {
|
|
3421
|
+
row.title.update(`${frames[this.frame % frames.length]} ${row.position === void 0 ? "" : `${row.position}. `}${label(row.item.state).toUpperCase()} · ${label(row.item.title) || "Untitled request"}`, this.presentation.disclosures[row.item.id] === true);
|
|
3422
|
+
}
|
|
3423
|
+
capturePresentation() {
|
|
3424
|
+
return { open: this.presentation.open, history: this.presentation.history, disclosures: Object.fromEntries(Object.entries(this.presentation.disclosures).slice(-2048)) };
|
|
3425
|
+
}
|
|
3426
|
+
restorePresentation(state) {
|
|
3427
|
+
if (!state) return;
|
|
3428
|
+
this.presentation = { open: state.open, history: state.history, disclosures: { ...state.disclosures } };
|
|
3429
|
+
for (const row of this.rows.values()) this.refreshRow(row);
|
|
3430
|
+
this.applyPresentation();
|
|
3431
|
+
}
|
|
3432
|
+
focusTargets() {
|
|
3433
|
+
const targets = [];
|
|
3434
|
+
const visit = (node) => {
|
|
3435
|
+
if (!node.visible) return;
|
|
3436
|
+
if (node instanceof TextRenderable5 && node.focusable) targets.push(node);
|
|
3437
|
+
for (const child of node.getChildren()) visit(child);
|
|
3438
|
+
};
|
|
3439
|
+
if (this.visible) visit(this);
|
|
3440
|
+
return targets;
|
|
3441
|
+
}
|
|
3442
|
+
applyTheme(colors) {
|
|
3443
|
+
this.colors = colors;
|
|
3444
|
+
const visit = (node) => {
|
|
3445
|
+
if (node instanceof TextRenderable5) {
|
|
3446
|
+
node.fg = colors.foreground;
|
|
3447
|
+
node.bg = colors.background;
|
|
3448
|
+
}
|
|
3449
|
+
for (const child of node.getChildren()) visit(child);
|
|
3450
|
+
};
|
|
3451
|
+
visit(this);
|
|
3452
|
+
}
|
|
3453
|
+
destroySelf() {
|
|
3454
|
+
this.disposed = true;
|
|
3455
|
+
if (this.timer) clearInterval(this.timer);
|
|
3456
|
+
this.timer = void 0;
|
|
3457
|
+
this.renderer.off(CliRenderEvents4.FRAME, this.syncAnimation);
|
|
3458
|
+
super.destroySelf();
|
|
3459
|
+
}
|
|
3460
|
+
};
|
|
3461
|
+
|
|
2456
3462
|
// packages/cli/src/tui/native/components/instruments.ts
|
|
2457
3463
|
var foreground = RGBA2.defaultForeground();
|
|
2458
3464
|
var background = RGBA2.defaultBackground();
|
|
2459
|
-
var SectionBanner = class extends
|
|
3465
|
+
var SectionBanner = class extends TextRenderable6 {
|
|
2460
3466
|
constructor(renderer2, title, id, activate) {
|
|
2461
3467
|
super(renderer2, {
|
|
2462
3468
|
id,
|
|
@@ -2466,7 +3472,7 @@ var SectionBanner = class extends TextRenderable4 {
|
|
|
2466
3472
|
flexShrink: 0,
|
|
2467
3473
|
fg: foreground,
|
|
2468
3474
|
bg: background,
|
|
2469
|
-
attributes:
|
|
3475
|
+
attributes: TextAttributes7.BOLD,
|
|
2470
3476
|
selectable: false,
|
|
2471
3477
|
wrapMode: "none",
|
|
2472
3478
|
truncate: true,
|
|
@@ -2487,11 +3493,11 @@ var SectionBanner = class extends TextRenderable4 {
|
|
|
2487
3493
|
this.activate = activate;
|
|
2488
3494
|
this.heading = title;
|
|
2489
3495
|
this.focusable = true;
|
|
2490
|
-
this.on(
|
|
2491
|
-
this.attributes =
|
|
3496
|
+
this.on(RenderableEvents5.FOCUSED, () => {
|
|
3497
|
+
this.attributes = TextAttributes7.BOLD | TextAttributes7.INVERSE;
|
|
2492
3498
|
});
|
|
2493
|
-
this.on(
|
|
2494
|
-
this.attributes =
|
|
3499
|
+
this.on(RenderableEvents5.BLURRED, () => {
|
|
3500
|
+
this.attributes = TextAttributes7.BOLD;
|
|
2495
3501
|
});
|
|
2496
3502
|
}
|
|
2497
3503
|
activate;
|
|
@@ -2511,8 +3517,8 @@ var SectionBanner = class extends TextRenderable4 {
|
|
|
2511
3517
|
if (this.plainText !== next) this.content = next;
|
|
2512
3518
|
}
|
|
2513
3519
|
};
|
|
2514
|
-
var TelemetryRow = class extends
|
|
2515
|
-
constructor(renderer2,
|
|
3520
|
+
var TelemetryRow = class extends TextRenderable6 {
|
|
3521
|
+
constructor(renderer2, label2, id, reserved = 12) {
|
|
2516
3522
|
super(renderer2, {
|
|
2517
3523
|
id,
|
|
2518
3524
|
content: "",
|
|
@@ -2525,7 +3531,7 @@ var TelemetryRow = class extends TextRenderable4 {
|
|
|
2525
3531
|
truncate: true
|
|
2526
3532
|
});
|
|
2527
3533
|
this.reserved = reserved;
|
|
2528
|
-
this.label =
|
|
3534
|
+
this.label = label2;
|
|
2529
3535
|
}
|
|
2530
3536
|
reserved;
|
|
2531
3537
|
label;
|
|
@@ -2534,8 +3540,8 @@ var TelemetryRow = class extends TextRenderable4 {
|
|
|
2534
3540
|
super.onResize(width, height);
|
|
2535
3541
|
this.refresh();
|
|
2536
3542
|
}
|
|
2537
|
-
update(value,
|
|
2538
|
-
this.label =
|
|
3543
|
+
update(value, label2 = this.label) {
|
|
3544
|
+
this.label = label2;
|
|
2539
3545
|
this.value = value;
|
|
2540
3546
|
this.refresh();
|
|
2541
3547
|
}
|
|
@@ -2550,14 +3556,14 @@ var TelemetryRow = class extends TextRenderable4 {
|
|
|
2550
3556
|
}
|
|
2551
3557
|
};
|
|
2552
3558
|
var SignalMeter = class extends TelemetryRow {
|
|
2553
|
-
constructor(renderer2,
|
|
2554
|
-
super(renderer2,
|
|
3559
|
+
constructor(renderer2, label2, id) {
|
|
3560
|
+
super(renderer2, label2, id, 18);
|
|
2555
3561
|
}
|
|
2556
3562
|
updateReading(value, maximum) {
|
|
2557
3563
|
this.update(formatSignalMeter(value, maximum));
|
|
2558
3564
|
}
|
|
2559
3565
|
};
|
|
2560
|
-
var InstrumentDivider = class extends
|
|
3566
|
+
var InstrumentDivider = class extends TextRenderable6 {
|
|
2561
3567
|
constructor(renderer2, actions) {
|
|
2562
3568
|
super(renderer2, {
|
|
2563
3569
|
id: "omnius-instrument-divider",
|
|
@@ -2571,14 +3577,14 @@ var InstrumentDivider = class extends TextRenderable4 {
|
|
|
2571
3577
|
bg: background,
|
|
2572
3578
|
selectable: false,
|
|
2573
3579
|
wrapMode: "none",
|
|
2574
|
-
attributes:
|
|
3580
|
+
attributes: TextAttributes7.DIM,
|
|
2575
3581
|
onMouseDown: (event) => {
|
|
2576
3582
|
if (event.button !== 0) return;
|
|
2577
3583
|
this.held = true;
|
|
2578
3584
|
this.moved = false;
|
|
2579
3585
|
this.startX = event.x;
|
|
2580
3586
|
this.actions.start?.();
|
|
2581
|
-
this.attributes =
|
|
3587
|
+
this.attributes = TextAttributes7.BOLD;
|
|
2582
3588
|
event.preventDefault();
|
|
2583
3589
|
event.stopPropagation();
|
|
2584
3590
|
},
|
|
@@ -2592,10 +3598,10 @@ var InstrumentDivider = class extends TextRenderable4 {
|
|
|
2592
3598
|
this.handleRelease(event);
|
|
2593
3599
|
},
|
|
2594
3600
|
onMouseOver: () => {
|
|
2595
|
-
this.attributes =
|
|
3601
|
+
this.attributes = TextAttributes7.BOLD;
|
|
2596
3602
|
},
|
|
2597
3603
|
onMouseOut: () => {
|
|
2598
|
-
if (!this.held) this.attributes = this.focused ?
|
|
3604
|
+
if (!this.held) this.attributes = this.focused ? TextAttributes7.INVERSE : TextAttributes7.DIM;
|
|
2599
3605
|
},
|
|
2600
3606
|
onKeyDown: (key) => {
|
|
2601
3607
|
if (key.eventType === "release") return;
|
|
@@ -2608,11 +3614,11 @@ var InstrumentDivider = class extends TextRenderable4 {
|
|
|
2608
3614
|
});
|
|
2609
3615
|
this.actions = actions;
|
|
2610
3616
|
this.focusable = true;
|
|
2611
|
-
this.on(
|
|
2612
|
-
this.attributes =
|
|
3617
|
+
this.on(RenderableEvents5.FOCUSED, () => {
|
|
3618
|
+
this.attributes = TextAttributes7.INVERSE;
|
|
2613
3619
|
});
|
|
2614
|
-
this.on(
|
|
2615
|
-
this.attributes =
|
|
3620
|
+
this.on(RenderableEvents5.BLURRED, () => {
|
|
3621
|
+
this.attributes = TextAttributes7.DIM;
|
|
2616
3622
|
});
|
|
2617
3623
|
}
|
|
2618
3624
|
actions;
|
|
@@ -2646,28 +3652,28 @@ var InstrumentDivider = class extends TextRenderable4 {
|
|
|
2646
3652
|
const text = rows.join("\n");
|
|
2647
3653
|
if (this.plainText !== text) this.content = text;
|
|
2648
3654
|
}
|
|
2649
|
-
release(
|
|
2650
|
-
if (this.moved) this.actions.resize(
|
|
3655
|
+
release(column3) {
|
|
3656
|
+
if (this.moved) this.actions.resize(column3);
|
|
2651
3657
|
else this.actions.toggle();
|
|
2652
3658
|
this.held = false;
|
|
2653
3659
|
this.actions.finish?.();
|
|
2654
|
-
this.attributes = this.focused ?
|
|
3660
|
+
this.attributes = this.focused ? TextAttributes7.INVERSE : TextAttributes7.DIM;
|
|
2655
3661
|
}
|
|
2656
3662
|
};
|
|
2657
|
-
var DeviceMonitor = class extends
|
|
3663
|
+
var DeviceMonitor = class extends BoxRenderable7 {
|
|
2658
3664
|
constructor(renderer2, action) {
|
|
2659
3665
|
super(renderer2, { id: "omnius-devices", width: "100%", height: 5, minHeight: 5, maxHeight: "60%", flexShrink: 1, flexDirection: "column", visible: false });
|
|
2660
3666
|
this.action = action;
|
|
2661
3667
|
this.heading = new SectionBanner(renderer2, "DEVICES", "omnius-devices:heading", () => this.toggle());
|
|
2662
3668
|
this.heading.update("DEVICES", false);
|
|
2663
3669
|
this.add(this.heading);
|
|
2664
|
-
this.summary = new
|
|
3670
|
+
this.summary = new TextRenderable6(renderer2, { id: "omnius-devices:summary", content: "--", width: "100%", height: 1, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true });
|
|
2665
3671
|
this.add(this.summary);
|
|
2666
|
-
this.compactLoad = new
|
|
2667
|
-
this.compactMemory = new
|
|
3672
|
+
this.compactLoad = new TextRenderable6(renderer2, { id: "omnius-devices:load-history", content: "", width: "100%", height: 1, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true });
|
|
3673
|
+
this.compactMemory = new TextRenderable6(renderer2, { id: "omnius-devices:memory-history", content: "", width: "100%", height: 1, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true });
|
|
2668
3674
|
this.add(this.compactLoad);
|
|
2669
3675
|
this.add(this.compactMemory);
|
|
2670
|
-
this.scroll = new
|
|
3676
|
+
this.scroll = new ScrollBoxRenderable5(renderer2, {
|
|
2671
3677
|
id: "omnius-devices:scroll",
|
|
2672
3678
|
width: "100%",
|
|
2673
3679
|
flexGrow: 1,
|
|
@@ -2682,7 +3688,7 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2682
3688
|
contentOptions: { flexDirection: "column" }
|
|
2683
3689
|
});
|
|
2684
3690
|
this.add(this.scroll);
|
|
2685
|
-
this.notes = new
|
|
3691
|
+
this.notes = new TextRenderable6(renderer2, {
|
|
2686
3692
|
id: "omnius-devices:notes",
|
|
2687
3693
|
content: "",
|
|
2688
3694
|
width: "100%",
|
|
@@ -2694,7 +3700,7 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2694
3700
|
truncate: true
|
|
2695
3701
|
});
|
|
2696
3702
|
this.scroll.add(this.notes);
|
|
2697
|
-
const controls = new
|
|
3703
|
+
const controls = new BoxRenderable7(renderer2, { id: "omnius-devices:controls", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 2 });
|
|
2698
3704
|
this.add(controls);
|
|
2699
3705
|
this.policy = this.button(renderer2, "omnius-devices:policy", "GPU POLICY", () => {
|
|
2700
3706
|
if (this.canSelect()) this.action?.("/gpu");
|
|
@@ -2717,10 +3723,10 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2717
3723
|
snapshot;
|
|
2718
3724
|
historySource = "";
|
|
2719
3725
|
rows = /* @__PURE__ */ new Map();
|
|
2720
|
-
button(renderer2, id,
|
|
2721
|
-
const button = new
|
|
3726
|
+
button(renderer2, id, label2, activate) {
|
|
3727
|
+
const button = new TextRenderable6(renderer2, {
|
|
2722
3728
|
id,
|
|
2723
|
-
content:
|
|
3729
|
+
content: label2,
|
|
2724
3730
|
height: 1,
|
|
2725
3731
|
flexShrink: 0,
|
|
2726
3732
|
fg: foreground,
|
|
@@ -2745,11 +3751,11 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2745
3751
|
}
|
|
2746
3752
|
});
|
|
2747
3753
|
button.focusable = Boolean(this.action);
|
|
2748
|
-
button.on(
|
|
2749
|
-
button.attributes =
|
|
3754
|
+
button.on(RenderableEvents5.FOCUSED, () => {
|
|
3755
|
+
button.attributes = TextAttributes7.INVERSE;
|
|
2750
3756
|
});
|
|
2751
|
-
button.on(
|
|
2752
|
-
button.attributes = button.focusable ? 0 :
|
|
3757
|
+
button.on(RenderableEvents5.BLURRED, () => {
|
|
3758
|
+
button.attributes = button.focusable ? 0 : TextAttributes7.DIM;
|
|
2753
3759
|
});
|
|
2754
3760
|
return button;
|
|
2755
3761
|
}
|
|
@@ -2771,7 +3777,7 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2771
3777
|
if (this.policy.focused && !allowed) this.heading.focus();
|
|
2772
3778
|
this.policy.focusable = allowed;
|
|
2773
3779
|
this.policy.content = snapshot?.selectionLocked ? "POLICY LOCKED" : "GPU POLICY";
|
|
2774
|
-
this.policy.attributes = allowed ? this.policy.focused ?
|
|
3780
|
+
this.policy.attributes = allowed ? this.policy.focused ? TextAttributes7.INVERSE : 0 : TextAttributes7.DIM;
|
|
2775
3781
|
const keep = new Set(snapshot?.devices.map((device) => device.uuid) ?? []);
|
|
2776
3782
|
for (const [uuid, row] of this.rows) if (!keep.has(uuid)) {
|
|
2777
3783
|
if (row.title.focused) this.heading.focus();
|
|
@@ -2781,7 +3787,7 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2781
3787
|
for (const device of snapshot?.devices ?? []) {
|
|
2782
3788
|
let row = this.rows.get(device.uuid);
|
|
2783
3789
|
if (!row) {
|
|
2784
|
-
const root = new
|
|
3790
|
+
const root = new BoxRenderable7(this._ctx, {
|
|
2785
3791
|
id: `omnius-device:${device.uuid}`,
|
|
2786
3792
|
width: "100%",
|
|
2787
3793
|
flexDirection: "column",
|
|
@@ -2797,19 +3803,19 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2797
3803
|
if (current && this.canSelectDevice(current)) this.action?.(`/gpu select ${current.uuid}`);
|
|
2798
3804
|
});
|
|
2799
3805
|
title.width = "100%";
|
|
2800
|
-
title.on(
|
|
3806
|
+
title.on(RenderableEvents5.FOCUSED, () => this.scroll.scrollChildIntoView(root.id));
|
|
2801
3807
|
const load = new TelemetryRow(this._ctx, "LOAD", `${root.id}:load`, 16);
|
|
2802
3808
|
const memory = new TelemetryRow(this._ctx, "VRAM", `${root.id}:memory`, 16);
|
|
2803
|
-
const plot = (name) => new
|
|
3809
|
+
const plot = (name) => new TextRenderable6(this._ctx, { id: `${root.id}:${name}-history`, content: "", width: "100%", height: 3, flexShrink: 0, fg: foreground, bg: background, wrapMode: "none", truncate: true, selectable: false });
|
|
2804
3810
|
const loadGraph = plot("load"), memoryGraph = plot("memory"), history = new DeviceHistory();
|
|
2805
|
-
const reason = new
|
|
3811
|
+
const reason = new TextRenderable6(this._ctx, {
|
|
2806
3812
|
id: `${root.id}:reason`,
|
|
2807
3813
|
content: "",
|
|
2808
3814
|
width: "100%",
|
|
2809
3815
|
height: 1,
|
|
2810
3816
|
fg: foreground,
|
|
2811
3817
|
bg: background,
|
|
2812
|
-
attributes:
|
|
3818
|
+
attributes: TextAttributes7.DIM,
|
|
2813
3819
|
wrapMode: "none",
|
|
2814
3820
|
truncate: true,
|
|
2815
3821
|
visible: false
|
|
@@ -2832,7 +3838,7 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2832
3838
|
const selectable = this.canSelectDevice(device);
|
|
2833
3839
|
if (row.title.focused && !selectable) this.heading.focus();
|
|
2834
3840
|
row.title.focusable = selectable;
|
|
2835
|
-
row.title.attributes = row.title.focused ?
|
|
3841
|
+
row.title.attributes = row.title.focused ? TextAttributes7.INVERSE : device.preferred ? TextAttributes7.BOLD : selectable ? 0 : TextAttributes7.DIM;
|
|
2836
3842
|
row.load.update(formatSignalMeter(device.utilization, 100, 6));
|
|
2837
3843
|
const used = device.memoryUsedMB === void 0 ? "--" : instrumentNumber(device.memoryUsedMB / 1024, 1);
|
|
2838
3844
|
const total = device.memoryTotalMB === void 0 || device.memoryTotalMB <= 0 ? "--" : instrumentNumber(device.memoryTotalMB / 1024, 1);
|
|
@@ -2885,10 +3891,10 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2885
3891
|
].filter(Boolean).join(" · ");
|
|
2886
3892
|
const primary = devices.find((device) => device.preferred) ?? devices.find((device) => device.enabled) ?? devices[0];
|
|
2887
3893
|
const compactHistory = primary ? this.rows.get(primary.uuid)?.history.samples ?? [] : [];
|
|
2888
|
-
for (const [element, field,
|
|
3894
|
+
for (const [element, field, label2] of [[this.compactLoad, "load", "UTIL"], [this.compactMemory, "memory", primary?.unifiedMemory ? "UMA" : "VRAM"]]) {
|
|
2889
3895
|
const current = primary ? field === "load" ? primary.utilization : primary.memoryUsedMB !== void 0 && primary.memoryTotalMB ? primary.memoryUsedMB / primary.memoryTotalMB * 100 : void 0 : void 0;
|
|
2890
3896
|
const value = instrumentNumber(current, 0, "%");
|
|
2891
|
-
const caption = `${
|
|
3897
|
+
const caption = `${label2}${primary?.index ?? "-"}`;
|
|
2892
3898
|
const plotWidth = Math.max(0, this.width - caption.length - value.length - 2);
|
|
2893
3899
|
const next = `${caption} ${deviceHistorySparkline(compactHistory, field, plotWidth)} ${value}`;
|
|
2894
3900
|
if (element.plainText !== next) element.content = next;
|
|
@@ -2913,7 +3919,7 @@ var DeviceMonitor = class extends BoxRenderable5 {
|
|
|
2913
3919
|
];
|
|
2914
3920
|
}
|
|
2915
3921
|
};
|
|
2916
|
-
var ChannelMap = class extends
|
|
3922
|
+
var ChannelMap = class extends BoxRenderable7 {
|
|
2917
3923
|
constructor(renderer2, id, inspect, reveal) {
|
|
2918
3924
|
super(renderer2, {
|
|
2919
3925
|
id,
|
|
@@ -2945,7 +3951,7 @@ var ChannelMap = class extends BoxRenderable5 {
|
|
|
2945
3951
|
if (!this.channels.has(agent.id))
|
|
2946
3952
|
this.channels.set(agent.id, this.channels.size + 1);
|
|
2947
3953
|
if (!this.rows.has(agent.id)) {
|
|
2948
|
-
const row = new
|
|
3954
|
+
const row = new TextRenderable6(this._ctx, {
|
|
2949
3955
|
id: `${this.id}:channel:${agent.id}`,
|
|
2950
3956
|
content: "",
|
|
2951
3957
|
width: "100%",
|
|
@@ -2977,11 +3983,11 @@ var ChannelMap = class extends BoxRenderable5 {
|
|
|
2977
3983
|
}
|
|
2978
3984
|
});
|
|
2979
3985
|
row.focusable = !!this.inspect;
|
|
2980
|
-
row.on(
|
|
2981
|
-
row.attributes =
|
|
3986
|
+
row.on(RenderableEvents5.FOCUSED, () => {
|
|
3987
|
+
row.attributes = TextAttributes7.INVERSE;
|
|
2982
3988
|
this.reveal?.(row);
|
|
2983
3989
|
});
|
|
2984
|
-
row.on(
|
|
3990
|
+
row.on(RenderableEvents5.BLURRED, () => {
|
|
2985
3991
|
row.attributes = 0;
|
|
2986
3992
|
});
|
|
2987
3993
|
this.rows.set(agent.id, row);
|
|
@@ -3011,7 +4017,9 @@ var ChannelMap = class extends BoxRenderable5 {
|
|
|
3011
4017
|
}
|
|
3012
4018
|
}
|
|
3013
4019
|
};
|
|
3014
|
-
var InstrumentRail = class extends
|
|
4020
|
+
var InstrumentRail = class extends BoxRenderable7 {
|
|
4021
|
+
workQueue;
|
|
4022
|
+
taskNotes;
|
|
3015
4023
|
scroll;
|
|
3016
4024
|
inferenceHeader;
|
|
3017
4025
|
sessionHeader;
|
|
@@ -3040,7 +4048,7 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3040
4048
|
flexGrow: 1,
|
|
3041
4049
|
flexShrink: 1
|
|
3042
4050
|
});
|
|
3043
|
-
this.scroll = new
|
|
4051
|
+
this.scroll = new ScrollBoxRenderable5(renderer2, {
|
|
3044
4052
|
id: `${id}:scroll`,
|
|
3045
4053
|
width: "100%",
|
|
3046
4054
|
flexGrow: 1,
|
|
@@ -3054,6 +4062,31 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3054
4062
|
contentOptions: { flexDirection: "column", paddingRight: 1 }
|
|
3055
4063
|
});
|
|
3056
4064
|
this.add(this.scroll);
|
|
4065
|
+
const colors = options.colors ?? {
|
|
4066
|
+
foreground,
|
|
4067
|
+
background,
|
|
4068
|
+
accent: foreground,
|
|
4069
|
+
dim: foreground,
|
|
4070
|
+
border: foreground,
|
|
4071
|
+
warning: foreground,
|
|
4072
|
+
error: foreground,
|
|
4073
|
+
success: foreground,
|
|
4074
|
+
selection: background
|
|
4075
|
+
};
|
|
4076
|
+
this.workQueue = new NativeWorkQueueView(renderer2, colors, options.onWorkQueueAction, (target) => this.reveal(target));
|
|
4077
|
+
this.scroll.add(this.workQueue);
|
|
4078
|
+
this.taskNotes = new NativeTaskNotesView(renderer2, options.colors ?? {
|
|
4079
|
+
foreground,
|
|
4080
|
+
background,
|
|
4081
|
+
accent: foreground,
|
|
4082
|
+
dim: foreground,
|
|
4083
|
+
border: foreground,
|
|
4084
|
+
warning: foreground,
|
|
4085
|
+
error: foreground,
|
|
4086
|
+
success: foreground,
|
|
4087
|
+
selection: background
|
|
4088
|
+
}, (target) => this.reveal(target));
|
|
4089
|
+
this.scroll.add(this.taskNotes);
|
|
3057
4090
|
this.inferenceHeader = new SectionBanner(
|
|
3058
4091
|
renderer2,
|
|
3059
4092
|
"INFERENCE",
|
|
@@ -3061,26 +4094,26 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3061
4094
|
() => this.toggleSection("inference")
|
|
3062
4095
|
);
|
|
3063
4096
|
this.inferenceHeader.on(
|
|
3064
|
-
|
|
4097
|
+
RenderableEvents5.FOCUSED,
|
|
3065
4098
|
() => this.reveal(this.inferenceHeader)
|
|
3066
4099
|
);
|
|
3067
4100
|
this.scroll.add(this.inferenceHeader);
|
|
3068
|
-
this.inference = new
|
|
4101
|
+
this.inference = new BoxRenderable7(renderer2, {
|
|
3069
4102
|
id: `${id}:inference-body`,
|
|
3070
4103
|
width: "100%",
|
|
3071
4104
|
flexDirection: "column",
|
|
3072
4105
|
flexShrink: 0
|
|
3073
4106
|
});
|
|
3074
4107
|
this.scroll.add(this.inference);
|
|
3075
|
-
const addRow = (parent, key,
|
|
3076
|
-
const row = new TelemetryRow(renderer2,
|
|
4108
|
+
const addRow = (parent, key, label2, reserved = 12) => {
|
|
4109
|
+
const row = new TelemetryRow(renderer2, label2, `${id}:${key}`, reserved);
|
|
3077
4110
|
this.rows.set(key, row);
|
|
3078
4111
|
parent.add(row);
|
|
3079
4112
|
return row;
|
|
3080
4113
|
};
|
|
3081
4114
|
addRow(this.inference, "route", "ROUTE");
|
|
3082
4115
|
addRow(this.inference, "backend", "BACKEND");
|
|
3083
|
-
this.model = new
|
|
4116
|
+
this.model = new TextRenderable6(renderer2, {
|
|
3084
4117
|
id: `${id}:model`,
|
|
3085
4118
|
content: "MODEL --",
|
|
3086
4119
|
width: "100%",
|
|
@@ -3107,9 +4140,9 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3107
4140
|
this.contextDetails.visible = !this.contextDetails.visible;
|
|
3108
4141
|
this.contextHeader.update("CONTEXT DETAILS", this.contextDetails.visible);
|
|
3109
4142
|
});
|
|
3110
|
-
this.contextHeader.on(
|
|
4143
|
+
this.contextHeader.on(RenderableEvents5.FOCUSED, () => this.reveal(this.contextHeader));
|
|
3111
4144
|
this.inference.add(this.contextHeader);
|
|
3112
|
-
this.contextDetails = new
|
|
4145
|
+
this.contextDetails = new BoxRenderable7(renderer2, { id: `${id}:context-detail-body`, width: "100%", flexDirection: "column", flexShrink: 0, visible: false });
|
|
3113
4146
|
this.inference.add(this.contextDetails);
|
|
3114
4147
|
this.contextHeader.update("CONTEXT DETAILS", false);
|
|
3115
4148
|
addRow(this.contextDetails, "messages", "MESSAGES");
|
|
@@ -3124,11 +4157,11 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3124
4157
|
() => this.toggleSection("session")
|
|
3125
4158
|
);
|
|
3126
4159
|
this.sessionHeader.on(
|
|
3127
|
-
|
|
4160
|
+
RenderableEvents5.FOCUSED,
|
|
3128
4161
|
() => this.reveal(this.sessionHeader)
|
|
3129
4162
|
);
|
|
3130
4163
|
this.scroll.add(this.sessionHeader);
|
|
3131
|
-
this.session = new
|
|
4164
|
+
this.session = new BoxRenderable7(renderer2, {
|
|
3132
4165
|
id: `${id}:session-body`,
|
|
3133
4166
|
width: "100%",
|
|
3134
4167
|
flexDirection: "column",
|
|
@@ -3155,6 +4188,8 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3155
4188
|
if (options.colors) this.applyTheme(options.colors);
|
|
3156
4189
|
}
|
|
3157
4190
|
update(state) {
|
|
4191
|
+
this.workQueue.update(state.workQueue);
|
|
4192
|
+
this.taskNotes.update(state.taskNotes);
|
|
3158
4193
|
const data = state.instruments;
|
|
3159
4194
|
const inference = data?.inference;
|
|
3160
4195
|
const session = data?.session;
|
|
@@ -3211,13 +4246,15 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3211
4246
|
applyTheme(colors) {
|
|
3212
4247
|
this.backgroundColor = colors.background;
|
|
3213
4248
|
const visit = (node) => {
|
|
3214
|
-
if (node instanceof
|
|
4249
|
+
if (node instanceof TextRenderable6) {
|
|
3215
4250
|
node.fg = colors.foreground;
|
|
3216
4251
|
node.bg = colors.background;
|
|
3217
4252
|
}
|
|
3218
4253
|
for (const child of node.getChildren()) visit(child);
|
|
3219
4254
|
};
|
|
3220
4255
|
visit(this);
|
|
4256
|
+
this.workQueue.applyTheme(colors);
|
|
4257
|
+
this.taskNotes.applyTheme(colors);
|
|
3221
4258
|
styleNativeScrollbars(this.scroll, colors);
|
|
3222
4259
|
styleNativeScrollbars(this.devices.scroll, colors);
|
|
3223
4260
|
}
|
|
@@ -3237,10 +4274,14 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3237
4274
|
context: this.contextHeader.expanded,
|
|
3238
4275
|
devices: this.devices.isExpanded,
|
|
3239
4276
|
scrollTop: this.scroll.scrollTop,
|
|
3240
|
-
deviceScrollTop: this.devices.scroll.scrollTop
|
|
4277
|
+
deviceScrollTop: this.devices.scroll.scrollTop,
|
|
4278
|
+
taskNotes: this.taskNotes.capturePresentation(),
|
|
4279
|
+
workQueue: this.workQueue.capturePresentation()
|
|
3241
4280
|
};
|
|
3242
4281
|
}
|
|
3243
4282
|
restorePresentation(state) {
|
|
4283
|
+
this.workQueue.restorePresentation(state.workQueue);
|
|
4284
|
+
this.taskNotes.restorePresentation(state.taskNotes);
|
|
3244
4285
|
if (this.inference.visible !== state.inference) this.toggleSection("inference");
|
|
3245
4286
|
if (this.session.visible !== state.session) this.toggleSection("session");
|
|
3246
4287
|
this.contextHeader.update("CONTEXT DETAILS", state.context);
|
|
@@ -3252,6 +4293,8 @@ var InstrumentRail = class extends BoxRenderable5 {
|
|
|
3252
4293
|
focusTargets() {
|
|
3253
4294
|
if (!this.visible) return [];
|
|
3254
4295
|
return [
|
|
4296
|
+
...this.workQueue.focusTargets(),
|
|
4297
|
+
...this.taskNotes.focusTargets(),
|
|
3255
4298
|
this.inferenceHeader,
|
|
3256
4299
|
...this.inference.visible && this.contextHeader.visible ? [this.contextHeader] : [],
|
|
3257
4300
|
this.sessionHeader,
|
|
@@ -4708,14 +5751,14 @@ var VimComposer = class {
|
|
|
4708
5751
|
};
|
|
4709
5752
|
|
|
4710
5753
|
// packages/cli/src/tui/native/components/selection-menu.ts
|
|
4711
|
-
import { BoxRenderable as
|
|
5754
|
+
import { BoxRenderable as BoxRenderable8, CliRenderEvents as CliRenderEvents5, TextAttributes as TextAttributes8, TextRenderable as TextRenderable7 } from "@opentui/core";
|
|
4712
5755
|
var NativeSelectionMenu = class {
|
|
4713
5756
|
constructor(renderer2, colors, copy, restoreFocus) {
|
|
4714
5757
|
this.renderer = renderer2;
|
|
4715
5758
|
this.colors = colors;
|
|
4716
5759
|
this.copy = copy;
|
|
4717
5760
|
this.restoreFocus = restoreFocus;
|
|
4718
|
-
renderer2.on(
|
|
5761
|
+
renderer2.on(CliRenderEvents5.RESIZE, this.position);
|
|
4719
5762
|
}
|
|
4720
5763
|
renderer;
|
|
4721
5764
|
colors;
|
|
@@ -4736,7 +5779,7 @@ var NativeSelectionMenu = class {
|
|
|
4736
5779
|
this.selectedText = text;
|
|
4737
5780
|
this.anchor = { x, y };
|
|
4738
5781
|
this.previousFocus = this.renderer.currentFocusedRenderable;
|
|
4739
|
-
this.overlay = new
|
|
5782
|
+
this.overlay = new BoxRenderable8(this.renderer, {
|
|
4740
5783
|
id: "omnius-selection-menu",
|
|
4741
5784
|
position: "absolute",
|
|
4742
5785
|
left: 0,
|
|
@@ -4752,7 +5795,7 @@ var NativeSelectionMenu = class {
|
|
|
4752
5795
|
event.stopPropagation();
|
|
4753
5796
|
}
|
|
4754
5797
|
});
|
|
4755
|
-
this.panel = new
|
|
5798
|
+
this.panel = new BoxRenderable8(this.renderer, {
|
|
4756
5799
|
id: "omnius-selection-menu-panel",
|
|
4757
5800
|
position: "absolute",
|
|
4758
5801
|
width: 14,
|
|
@@ -4766,7 +5809,7 @@ var NativeSelectionMenu = class {
|
|
|
4766
5809
|
event.stopPropagation();
|
|
4767
5810
|
}
|
|
4768
5811
|
});
|
|
4769
|
-
const action = new
|
|
5812
|
+
const action = new TextRenderable7(this.renderer, {
|
|
4770
5813
|
id: "omnius-selection-copy",
|
|
4771
5814
|
content: "COPY",
|
|
4772
5815
|
height: 1,
|
|
@@ -4774,7 +5817,7 @@ var NativeSelectionMenu = class {
|
|
|
4774
5817
|
selectable: false,
|
|
4775
5818
|
fg: this.colors.foreground,
|
|
4776
5819
|
bg: this.colors.background,
|
|
4777
|
-
attributes:
|
|
5820
|
+
attributes: TextAttributes8.BOLD | TextAttributes8.INVERSE,
|
|
4778
5821
|
onMouseDown: (event) => {
|
|
4779
5822
|
if (event.button === 0) this.confirm();
|
|
4780
5823
|
event.preventDefault();
|
|
@@ -4815,7 +5858,7 @@ var NativeSelectionMenu = class {
|
|
|
4815
5858
|
if (!this.panel) return;
|
|
4816
5859
|
this.panel.backgroundColor = colors.background;
|
|
4817
5860
|
this.frame?.setColors(colors);
|
|
4818
|
-
for (const child of this.panel.getChildren()) if (child instanceof
|
|
5861
|
+
for (const child of this.panel.getChildren()) if (child instanceof TextRenderable7) {
|
|
4819
5862
|
child.fg = colors.foreground;
|
|
4820
5863
|
child.bg = colors.background;
|
|
4821
5864
|
}
|
|
@@ -4836,13 +5879,13 @@ var NativeSelectionMenu = class {
|
|
|
4836
5879
|
}
|
|
4837
5880
|
destroy() {
|
|
4838
5881
|
this.close();
|
|
4839
|
-
this.renderer.off(
|
|
5882
|
+
this.renderer.off(CliRenderEvents5.RESIZE, this.position);
|
|
4840
5883
|
}
|
|
4841
5884
|
};
|
|
4842
5885
|
|
|
4843
5886
|
// packages/cli/src/tui/native/components/tab-strip.ts
|
|
4844
|
-
import { BoxRenderable as
|
|
4845
|
-
var NativeTabStrip = class extends
|
|
5887
|
+
import { BoxRenderable as BoxRenderable9, CliRenderEvents as CliRenderEvents6, ScrollBoxRenderable as ScrollBoxRenderable6, SliderRenderable, TextAttributes as TextAttributes9, TextRenderable as TextRenderable8 } from "@opentui/core";
|
|
5888
|
+
var NativeTabStrip = class extends BoxRenderable9 {
|
|
4846
5889
|
constructor(renderer2, options) {
|
|
4847
5890
|
super(renderer2, {
|
|
4848
5891
|
id: options.id,
|
|
@@ -4858,7 +5901,7 @@ var NativeTabStrip = class extends BoxRenderable7 {
|
|
|
4858
5901
|
this.renderer = renderer2;
|
|
4859
5902
|
this.options = options;
|
|
4860
5903
|
this.colors = options.colors;
|
|
4861
|
-
this.scroll = new
|
|
5904
|
+
this.scroll = new ScrollBoxRenderable6(renderer2, {
|
|
4862
5905
|
id: `${options.id}:scroll`,
|
|
4863
5906
|
height: 1,
|
|
4864
5907
|
minHeight: 1,
|
|
@@ -4896,7 +5939,7 @@ var NativeTabStrip = class extends BoxRenderable7 {
|
|
|
4896
5939
|
this.rail.focusable = false;
|
|
4897
5940
|
this.add(this.rail);
|
|
4898
5941
|
styleNativeSlider(this.rail, this.colors);
|
|
4899
|
-
renderer2.on(
|
|
5942
|
+
renderer2.on(CliRenderEvents6.FRAME, this.syncScroll);
|
|
4900
5943
|
}
|
|
4901
5944
|
renderer;
|
|
4902
5945
|
options;
|
|
@@ -4913,15 +5956,19 @@ var NativeTabStrip = class extends BoxRenderable7 {
|
|
|
4913
5956
|
const signature = JSON.stringify([items, activeId, busy]);
|
|
4914
5957
|
if (signature === this.signature) return;
|
|
4915
5958
|
this.signature = signature;
|
|
5959
|
+
const previousFocus = this.renderer.currentFocusedRenderable;
|
|
5960
|
+
const ownedFocus = Boolean(previousFocus) && [...this.buttons.values()].some((entry) => previousFocus === entry.button || previousFocus === entry.close);
|
|
4916
5961
|
const ids = new Set(items.map((item) => item.id));
|
|
4917
5962
|
for (const [id, entry] of this.buttons) if (!ids.has(id)) {
|
|
4918
5963
|
entry.button.destroy();
|
|
5964
|
+
entry.close?.destroy();
|
|
4919
5965
|
this.buttons.delete(id);
|
|
4920
5966
|
}
|
|
4921
|
-
|
|
5967
|
+
const controls = [];
|
|
5968
|
+
for (const action of items) {
|
|
4922
5969
|
let entry = this.buttons.get(action.id);
|
|
4923
5970
|
if (!entry) {
|
|
4924
|
-
const button = new
|
|
5971
|
+
const button = new TextRenderable8(this.renderer, {
|
|
4925
5972
|
id: `${this.options.prefix}:${action.id}`,
|
|
4926
5973
|
content: "",
|
|
4927
5974
|
height: 1,
|
|
@@ -4948,35 +5995,73 @@ var NativeTabStrip = class extends BoxRenderable7 {
|
|
|
4948
5995
|
this.reveal = button.id;
|
|
4949
5996
|
});
|
|
4950
5997
|
button.on("blurred", () => this.style(entry));
|
|
5998
|
+
if (this.options.close) {
|
|
5999
|
+
const close2 = new TextRenderable8(this.renderer, {
|
|
6000
|
+
id: `${this.options.prefix}-close:${action.id}`,
|
|
6001
|
+
content: "×",
|
|
6002
|
+
width: 1,
|
|
6003
|
+
height: 1,
|
|
6004
|
+
flexShrink: 0,
|
|
6005
|
+
wrapMode: "none",
|
|
6006
|
+
selectable: false,
|
|
6007
|
+
fg: this.colors.foreground,
|
|
6008
|
+
bg: this.colors.background,
|
|
6009
|
+
onMouseDown: (event) => {
|
|
6010
|
+
if (event.button === 0 && !entry.blocked) {
|
|
6011
|
+
close2.focus();
|
|
6012
|
+
this.options.close(entry.action.id);
|
|
6013
|
+
}
|
|
6014
|
+
event.preventDefault();
|
|
6015
|
+
event.stopPropagation();
|
|
6016
|
+
},
|
|
6017
|
+
onKeyDown: (key) => this.handleKey(entry, key, true)
|
|
6018
|
+
});
|
|
6019
|
+
entry.close = close2;
|
|
6020
|
+
close2.on("focused", () => {
|
|
6021
|
+
this.style(entry);
|
|
6022
|
+
this.scroll.scrollChildIntoView(close2.id);
|
|
6023
|
+
this.reveal = close2.id;
|
|
6024
|
+
});
|
|
6025
|
+
close2.on("blurred", () => this.style(entry));
|
|
6026
|
+
}
|
|
4951
6027
|
}
|
|
4952
6028
|
entry.action = action;
|
|
4953
6029
|
entry.active = action.id === activeId;
|
|
4954
6030
|
entry.blocked = busy || Boolean(action.disabled);
|
|
4955
6031
|
entry.button.focusable = entry.active || !entry.blocked;
|
|
4956
|
-
|
|
4957
|
-
const
|
|
6032
|
+
if (entry.close) entry.close.focusable = !entry.blocked;
|
|
6033
|
+
const label2 = plainText(action.label);
|
|
6034
|
+
const content = ` ${label2} `;
|
|
4958
6035
|
if (entry.button.plainText !== content) entry.button.content = content;
|
|
4959
6036
|
this.style(entry);
|
|
4960
|
-
|
|
6037
|
+
controls.push(entry.button);
|
|
6038
|
+
if (entry.close) controls.push(entry.close);
|
|
4961
6039
|
}
|
|
4962
|
-
|
|
4963
|
-
|
|
4964
|
-
if (
|
|
6040
|
+
for (const [index, control] of controls.entries()) if (this.scroll.getChildren()[index] !== control) this.scroll.add(control, index);
|
|
6041
|
+
this.naturalWidth = controls.reduce((width, control) => width + terminalCellWidth(control.plainText), 0) + Math.max(0, controls.length - 1);
|
|
6042
|
+
if (ownedFocus && (!previousFocus || previousFocus.isDestroyed || !previousFocus.focusable))
|
|
6043
|
+
(this.buttons.get(activeId)?.button ?? controls.find((control) => control.focusable))?.focus();
|
|
4965
6044
|
if (activeId !== this.activeId) this.reveal = `${this.options.prefix}:${activeId}`;
|
|
4966
6045
|
this.activeId = activeId;
|
|
4967
6046
|
this.renderer.requestRender();
|
|
4968
6047
|
}
|
|
4969
6048
|
style(entry) {
|
|
4970
|
-
entry.button.attributes = (entry.active ?
|
|
6049
|
+
entry.button.attributes = (entry.active ? TextAttributes9.BOLD | TextAttributes9.UNDERLINE : entry.blocked ? TextAttributes9.DIM : 0) | (entry.button.focused ? TextAttributes9.INVERSE : 0);
|
|
6050
|
+
if (entry.close) entry.close.attributes = (entry.blocked || !entry.close.focused ? TextAttributes9.DIM : 0) | (entry.close.focused ? TextAttributes9.INVERSE : 0);
|
|
4971
6051
|
}
|
|
4972
|
-
handleKey(entry, key) {
|
|
6052
|
+
handleKey(entry, key, close2 = false) {
|
|
4973
6053
|
if (key.eventType === "release") return;
|
|
4974
6054
|
if (key.name === "return" || key.sequence === " ") {
|
|
4975
|
-
if (!entry.blocked)
|
|
6055
|
+
if (!entry.blocked) {
|
|
6056
|
+
if (close2) this.options.close?.(entry.action.id);
|
|
6057
|
+
else this.options.activate(entry.action.id);
|
|
6058
|
+
}
|
|
6059
|
+
} else if (this.options.close && (key.name === "delete" || key.ctrl && key.name.toLowerCase() === "w")) {
|
|
6060
|
+
if (!entry.blocked) this.options.close(entry.action.id);
|
|
4976
6061
|
} else if (["left", "right", "home", "end"].includes(key.name)) {
|
|
4977
|
-
const targets = this.scroll.getChildren().filter((button) => button.focusable);
|
|
6062
|
+
const targets = this.scroll.getChildren().filter((button) => button.focusable && button.id.startsWith(`${this.options.prefix}:`));
|
|
4978
6063
|
const index = targets.indexOf(entry.button);
|
|
4979
|
-
const next = key.name === "home" ? 0 : key.name === "end" ? targets.length - 1 : (index + (key.name === "left" ? -1 : 1) + targets.length) % targets.length;
|
|
6064
|
+
const next = key.name === "home" ? 0 : key.name === "end" ? targets.length - 1 : (index + (key.name === "left" ? close2 ? 0 : -1 : 1) + targets.length) % targets.length;
|
|
4980
6065
|
targets[next]?.focus();
|
|
4981
6066
|
} else return;
|
|
4982
6067
|
key.preventDefault();
|
|
@@ -5001,9 +6086,13 @@ var NativeTabStrip = class extends BoxRenderable7 {
|
|
|
5001
6086
|
};
|
|
5002
6087
|
applyTheme(colors) {
|
|
5003
6088
|
this.colors = colors;
|
|
5004
|
-
for (const { button } of this.buttons.values()) {
|
|
6089
|
+
for (const { button, close: close2 } of this.buttons.values()) {
|
|
5005
6090
|
button.fg = colors.foreground;
|
|
5006
6091
|
button.bg = colors.background;
|
|
6092
|
+
if (close2) {
|
|
6093
|
+
close2.fg = colors.foreground;
|
|
6094
|
+
close2.bg = colors.background;
|
|
6095
|
+
}
|
|
5007
6096
|
}
|
|
5008
6097
|
styleNativeScrollbars(this.scroll, colors);
|
|
5009
6098
|
styleNativeSlider(this.rail, colors);
|
|
@@ -5013,7 +6102,7 @@ var NativeTabStrip = class extends BoxRenderable7 {
|
|
|
5013
6102
|
this.scroll.scrollLeft = offset2;
|
|
5014
6103
|
}
|
|
5015
6104
|
destroySelf() {
|
|
5016
|
-
this.renderer.off(
|
|
6105
|
+
this.renderer.off(CliRenderEvents6.FRAME, this.syncScroll);
|
|
5017
6106
|
super.destroySelf();
|
|
5018
6107
|
}
|
|
5019
6108
|
};
|
|
@@ -5031,7 +6120,7 @@ var NativeFrontend = class {
|
|
|
5031
6120
|
this.selectionMenu = new NativeSelectionMenu(renderer2, colors, (text) => {
|
|
5032
6121
|
void this.copy(text);
|
|
5033
6122
|
}, () => this.restoreFocus());
|
|
5034
|
-
this.root = new
|
|
6123
|
+
this.root = new BoxRenderable10(renderer2, {
|
|
5035
6124
|
id: "omnius-native",
|
|
5036
6125
|
width: "100%",
|
|
5037
6126
|
height: "100%",
|
|
@@ -5039,7 +6128,7 @@ var NativeFrontend = class {
|
|
|
5039
6128
|
backgroundColor: colors.background
|
|
5040
6129
|
});
|
|
5041
6130
|
renderer2.root.add(this.root);
|
|
5042
|
-
this.header = new
|
|
6131
|
+
this.header = new BoxRenderable10(renderer2, {
|
|
5043
6132
|
id: "omnius-header",
|
|
5044
6133
|
width: "100%",
|
|
5045
6134
|
minWidth: 0,
|
|
@@ -5060,12 +6149,12 @@ var NativeFrontend = class {
|
|
|
5060
6149
|
this.header.y + this.header.height - 1,
|
|
5061
6150
|
this.context.colors.foreground,
|
|
5062
6151
|
this.context.colors.background,
|
|
5063
|
-
|
|
6152
|
+
TextAttributes10.DIM
|
|
5064
6153
|
);
|
|
5065
6154
|
};
|
|
5066
|
-
const headerRow = new
|
|
6155
|
+
const headerRow = new BoxRenderable10(renderer2, { id: "omnius-header-row", width: "100%", minWidth: 0, minHeight: 1, flexDirection: "row", gap: 1 });
|
|
5067
6156
|
this.header.add(headerRow);
|
|
5068
|
-
this.identity = new
|
|
6157
|
+
this.identity = new TextRenderable9(renderer2, {
|
|
5069
6158
|
id: "omnius-identity",
|
|
5070
6159
|
content: "Omnius",
|
|
5071
6160
|
fg: colors.foreground,
|
|
@@ -5075,7 +6164,7 @@ var NativeFrontend = class {
|
|
|
5075
6164
|
truncate: true,
|
|
5076
6165
|
minWidth: 18,
|
|
5077
6166
|
selectable: false,
|
|
5078
|
-
attributes:
|
|
6167
|
+
attributes: TextAttributes10.BOLD,
|
|
5079
6168
|
onMouseDown: (event) => {
|
|
5080
6169
|
if (event.button === 0) {
|
|
5081
6170
|
this.toggleHeaderPanel();
|
|
@@ -5090,7 +6179,7 @@ var NativeFrontend = class {
|
|
|
5090
6179
|
}
|
|
5091
6180
|
});
|
|
5092
6181
|
headerRow.add(this.identity);
|
|
5093
|
-
this.headerActions = new
|
|
6182
|
+
this.headerActions = new ScrollBoxRenderable7(renderer2, {
|
|
5094
6183
|
id: "omnius-header-actions",
|
|
5095
6184
|
flexGrow: 0,
|
|
5096
6185
|
flexShrink: 1,
|
|
@@ -5103,16 +6192,16 @@ var NativeFrontend = class {
|
|
|
5103
6192
|
verticalScrollbarOptions: { visible: false }
|
|
5104
6193
|
});
|
|
5105
6194
|
headerRow.add(this.headerActions);
|
|
5106
|
-
this.headerPanel = new
|
|
6195
|
+
this.headerPanel = new TextRenderable9(renderer2, { id: "omnius-header-panel", content: "", width: "100%", wrapMode: "word", visible: false });
|
|
5107
6196
|
this.header.add(this.headerPanel);
|
|
5108
|
-
this.detailButton = new
|
|
6197
|
+
this.detailButton = new TextRenderable9(renderer2, {
|
|
5109
6198
|
id: "omnius-details-toggle",
|
|
5110
6199
|
content: "+ DETAILS",
|
|
5111
6200
|
height: 1,
|
|
5112
6201
|
width: 9,
|
|
5113
6202
|
flexShrink: 0,
|
|
5114
6203
|
fg: colors.foreground,
|
|
5115
|
-
attributes:
|
|
6204
|
+
attributes: TextAttributes10.DIM,
|
|
5116
6205
|
selectable: false,
|
|
5117
6206
|
onMouseDown: (event) => {
|
|
5118
6207
|
if (event.button === 0) {
|
|
@@ -5132,13 +6221,13 @@ var NativeFrontend = class {
|
|
|
5132
6221
|
for (const control of [this.identity, this.detailButton]) {
|
|
5133
6222
|
const attributes = control.attributes;
|
|
5134
6223
|
control.on("focused", () => {
|
|
5135
|
-
control.attributes = attributes |
|
|
6224
|
+
control.attributes = attributes | TextAttributes10.INVERSE;
|
|
5136
6225
|
});
|
|
5137
6226
|
control.on("blurred", () => {
|
|
5138
6227
|
control.attributes = attributes;
|
|
5139
6228
|
});
|
|
5140
6229
|
}
|
|
5141
|
-
this.sessionRow = new
|
|
6230
|
+
this.sessionRow = new BoxRenderable10(renderer2, {
|
|
5142
6231
|
id: "omnius-sessions-row",
|
|
5143
6232
|
width: "100%",
|
|
5144
6233
|
height: 1,
|
|
@@ -5153,10 +6242,11 @@ var NativeFrontend = class {
|
|
|
5153
6242
|
id: "omnius-session-tabs",
|
|
5154
6243
|
prefix: "session",
|
|
5155
6244
|
colors,
|
|
5156
|
-
activate: (id) => this.emitAction("session", id)
|
|
6245
|
+
activate: (id) => this.emitAction("session", id),
|
|
6246
|
+
close: (id) => this.emitAction("session-close", id)
|
|
5157
6247
|
});
|
|
5158
6248
|
this.sessionRow.add(this.sessions);
|
|
5159
|
-
this.newSession = new
|
|
6249
|
+
this.newSession = new TextRenderable9(renderer2, {
|
|
5160
6250
|
id: "omnius-session-new",
|
|
5161
6251
|
content: "+ NEW",
|
|
5162
6252
|
width: 5,
|
|
@@ -5180,21 +6270,58 @@ var NativeFrontend = class {
|
|
|
5180
6270
|
});
|
|
5181
6271
|
this.newSession.focusable = true;
|
|
5182
6272
|
const styleNew = () => {
|
|
5183
|
-
this.newSession.attributes = (this.state?.sessions?.busy ?
|
|
6273
|
+
this.newSession.attributes = (this.state?.sessions?.busy ? TextAttributes10.DIM : 0) | (this.newSession.focused ? TextAttributes10.INVERSE : 0);
|
|
5184
6274
|
};
|
|
5185
6275
|
this.newSession.on("focused", styleNew);
|
|
5186
6276
|
this.newSession.on("blurred", styleNew);
|
|
5187
6277
|
this.sessionRow.add(this.newSession);
|
|
5188
|
-
this.
|
|
6278
|
+
this.sessionPicker = new TextRenderable9(renderer2, {
|
|
6279
|
+
id: "omnius-session-picker",
|
|
6280
|
+
content: "SESSIONS",
|
|
6281
|
+
width: 8,
|
|
6282
|
+
height: 1,
|
|
6283
|
+
flexShrink: 0,
|
|
6284
|
+
selectable: false,
|
|
6285
|
+
fg: colors.foreground,
|
|
6286
|
+
bg: colors.background,
|
|
6287
|
+
onMouseDown: (event) => {
|
|
6288
|
+
if (event.button === 0 && !this.state?.sessions?.busy) this.emitAction("session-picker");
|
|
6289
|
+
event.preventDefault();
|
|
6290
|
+
event.stopPropagation();
|
|
6291
|
+
},
|
|
6292
|
+
onKeyDown: (key) => {
|
|
6293
|
+
if (key.eventType !== "release" && (key.name === "return" || key.sequence === " ")) {
|
|
6294
|
+
if (!this.state?.sessions?.busy) this.emitAction("session-picker");
|
|
6295
|
+
key.preventDefault();
|
|
6296
|
+
key.stopPropagation();
|
|
6297
|
+
}
|
|
6298
|
+
}
|
|
6299
|
+
});
|
|
6300
|
+
this.sessionPicker.focusable = true;
|
|
6301
|
+
const stylePicker = () => {
|
|
6302
|
+
this.sessionPicker.attributes = (this.state?.sessions?.busy ? TextAttributes10.DIM : 0) | (this.sessionPicker.focused ? TextAttributes10.INVERSE : 0);
|
|
6303
|
+
};
|
|
6304
|
+
this.sessionPicker.on("focused", stylePicker);
|
|
6305
|
+
this.sessionPicker.on("blurred", stylePicker);
|
|
6306
|
+
this.sessionRow.add(this.sessionPicker);
|
|
6307
|
+
this.routeWarning = new TextRenderable9(renderer2, { id: "omnius-route-warning", content: "", width: "100%", wrapMode: "word", fg: colors.warning, attributes: TextAttributes10.BOLD | TextAttributes10.UNDERLINE, visible: false, flexShrink: 0 });
|
|
5189
6308
|
this.root.add(this.routeWarning);
|
|
5190
|
-
this.taskPane = new
|
|
6309
|
+
this.taskPane = new BoxRenderable10(renderer2, { id: "omnius-tasks", width: "100%", flexDirection: "column", maxHeight: 6, flexShrink: 0, overflow: "hidden", visible: false });
|
|
5191
6310
|
this.tasks = new NativeBlockList(this.context, this.taskPane);
|
|
5192
6311
|
this.root.add(this.taskPane);
|
|
5193
|
-
this.
|
|
6312
|
+
this.taskStrip = new NativeTaskStrip(renderer2, colors, (id) => {
|
|
6313
|
+
if (renderer2.terminalWidth >= 110) this.detailsOpen = true;
|
|
6314
|
+
else this.narrowDetailsOpen = true;
|
|
6315
|
+
this.layoutInstruments();
|
|
6316
|
+
this.instruments.taskNotes.inspect(id);
|
|
6317
|
+
renderer2.requestRender();
|
|
6318
|
+
});
|
|
6319
|
+
this.root.add(this.taskStrip);
|
|
6320
|
+
this.body = new BoxRenderable10(renderer2, { id: "omnius-body", width: "100%", flexDirection: "row", flexGrow: 1, minHeight: 1 });
|
|
5194
6321
|
this.root.add(this.body);
|
|
5195
|
-
this.transcriptPane = new
|
|
6322
|
+
this.transcriptPane = new BoxRenderable10(renderer2, { id: "omnius-transcript-pane", flexDirection: "column", flexGrow: 1, flexShrink: 1, minWidth: 0, minHeight: 1 });
|
|
5196
6323
|
this.body.add(this.transcriptPane);
|
|
5197
|
-
this.scroll = new
|
|
6324
|
+
this.scroll = new ScrollBoxRenderable7(renderer2, {
|
|
5198
6325
|
id: "omnius-conversation",
|
|
5199
6326
|
flexGrow: 1,
|
|
5200
6327
|
flexShrink: 1,
|
|
@@ -5252,7 +6379,7 @@ var NativeFrontend = class {
|
|
|
5252
6379
|
this.transcriptPane.add(this.scroll);
|
|
5253
6380
|
this.content = new NativeBlockList(this.context, this.scroll);
|
|
5254
6381
|
this.instrumentDivider = new InstrumentDivider(renderer2, {
|
|
5255
|
-
resize: (
|
|
6382
|
+
resize: (column3) => this.resizeInstruments(column3),
|
|
5256
6383
|
toggle: () => this.toggleDetails(),
|
|
5257
6384
|
start: () => {
|
|
5258
6385
|
this.sidebarDragWidth = this.sidebarWidth ?? Math.floor(this.renderer.terminalWidth * 0.38);
|
|
@@ -5265,9 +6392,17 @@ var NativeFrontend = class {
|
|
|
5265
6392
|
this.root.onMouseDrag = (event) => this.instrumentDivider.handleDrag(event);
|
|
5266
6393
|
this.root.onMouseDragEnd = (event) => this.instrumentDivider.handleRelease(event);
|
|
5267
6394
|
this.root.onMouseUp = (event) => this.instrumentDivider.handleRelease(event);
|
|
5268
|
-
this.instruments = new InstrumentRail(renderer2, {
|
|
6395
|
+
this.instruments = new InstrumentRail(renderer2, {
|
|
6396
|
+
colors,
|
|
6397
|
+
onInspectAgent: (id) => this.emitAction("view", id),
|
|
6398
|
+
onAction: (command2) => this.emitAction(command2),
|
|
6399
|
+
onWorkQueueAction: (event) => {
|
|
6400
|
+
this.flushLatestInput();
|
|
6401
|
+
this.emit(event);
|
|
6402
|
+
}
|
|
6403
|
+
});
|
|
5269
6404
|
this.body.add(this.instruments);
|
|
5270
|
-
this.embeddedPane = new
|
|
6405
|
+
this.embeddedPane = new BoxRenderable10(renderer2, {
|
|
5271
6406
|
id: "omnius-editor-pane",
|
|
5272
6407
|
width: "50%",
|
|
5273
6408
|
flexShrink: 0,
|
|
@@ -5278,7 +6413,7 @@ var NativeFrontend = class {
|
|
|
5278
6413
|
visible: false
|
|
5279
6414
|
});
|
|
5280
6415
|
this.body.add(this.embeddedPane);
|
|
5281
|
-
this.liveButton = new
|
|
6416
|
+
this.liveButton = new TextRenderable9(renderer2, {
|
|
5282
6417
|
id: "omnius-live-button",
|
|
5283
6418
|
content: "↓ Live",
|
|
5284
6419
|
width: "100%",
|
|
@@ -5301,7 +6436,7 @@ var NativeFrontend = class {
|
|
|
5301
6436
|
});
|
|
5302
6437
|
this.liveButton.focusable = true;
|
|
5303
6438
|
this.transcriptPane.add(this.liveButton);
|
|
5304
|
-
this.queue = new
|
|
6439
|
+
this.queue = new TextRenderable9(renderer2, { id: "omnius-steering-queue", content: "", width: "100%", height: 1, wrapMode: "none", truncate: true, fg: colors.dim, visible: false, flexShrink: 0 });
|
|
5305
6440
|
this.transcriptPane.add(this.queue);
|
|
5306
6441
|
this.suggestions = new NativeSelectRenderable(renderer2, {
|
|
5307
6442
|
id: "omnius-suggestions",
|
|
@@ -5320,9 +6455,9 @@ var NativeFrontend = class {
|
|
|
5320
6455
|
this.suggestions.onActivate = () => this.acceptSuggestion();
|
|
5321
6456
|
this.suggestions.on("itemSelected", () => this.acceptSuggestion());
|
|
5322
6457
|
this.transcriptPane.add(this.suggestions);
|
|
5323
|
-
this.status = new
|
|
6458
|
+
this.status = new BoxRenderable10(renderer2, { id: "omnius-live-status", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 2, visible: false });
|
|
5324
6459
|
this.transcriptPane.add(this.status);
|
|
5325
|
-
this.footer = new
|
|
6460
|
+
this.footer = new BoxRenderable10(renderer2, {
|
|
5326
6461
|
id: "omnius-input-box",
|
|
5327
6462
|
width: "100%",
|
|
5328
6463
|
flexShrink: 0,
|
|
@@ -5331,7 +6466,7 @@ var NativeFrontend = class {
|
|
|
5331
6466
|
flexDirection: "column"
|
|
5332
6467
|
});
|
|
5333
6468
|
this.root.add(this.footer);
|
|
5334
|
-
this.footerRule = new
|
|
6469
|
+
this.footerRule = new BoxRenderable10(renderer2, {
|
|
5335
6470
|
id: "omnius-input-rule",
|
|
5336
6471
|
width: "100%",
|
|
5337
6472
|
height: 1,
|
|
@@ -5357,11 +6492,11 @@ var NativeFrontend = class {
|
|
|
5357
6492
|
buffer.drawText(formatSignalDivider(this.footerRule.width, {
|
|
5358
6493
|
direction: "bottom",
|
|
5359
6494
|
sidebarColumn: this.instrumentDivider.visible ? this.instrumentDivider.x - this.footerRule.x : void 0
|
|
5360
|
-
}), this.footerRule.x, this.footerRule.y, this.context.colors.foreground, this.context.colors.background,
|
|
6495
|
+
}), this.footerRule.x, this.footerRule.y, this.context.colors.foreground, this.context.colors.background, TextAttributes10.DIM);
|
|
5361
6496
|
};
|
|
5362
|
-
const inputRow = new
|
|
6497
|
+
const inputRow = new BoxRenderable10(renderer2, { id: "omnius-input-row", width: "100%", flexDirection: "row", gap: 1 });
|
|
5363
6498
|
this.footer.add(inputRow);
|
|
5364
|
-
this.prompt = new
|
|
6499
|
+
this.prompt = new TextRenderable9(renderer2, { id: "omnius-prompt", content: "❯", fg: colors.accent, wrapMode: "none", selectable: false, flexShrink: 0 });
|
|
5365
6500
|
inputRow.add(this.prompt);
|
|
5366
6501
|
this.editor = new TextareaRenderable2(renderer2, {
|
|
5367
6502
|
id: "omnius-input",
|
|
@@ -5381,14 +6516,14 @@ var NativeFrontend = class {
|
|
|
5381
6516
|
onCursorChange: () => this.editorChanged(),
|
|
5382
6517
|
onSubmit: () => this.submit()
|
|
5383
6518
|
});
|
|
5384
|
-
this.vimMode = new
|
|
6519
|
+
this.vimMode = new TextRenderable9(renderer2, {
|
|
5385
6520
|
id: "omnius-vim-mode",
|
|
5386
6521
|
content: "INSERT",
|
|
5387
6522
|
height: 1,
|
|
5388
6523
|
maxWidth: 12,
|
|
5389
6524
|
flexShrink: 0,
|
|
5390
6525
|
fg: colors.foreground,
|
|
5391
|
-
attributes:
|
|
6526
|
+
attributes: TextAttributes10.DIM,
|
|
5392
6527
|
wrapMode: "none",
|
|
5393
6528
|
truncate: true,
|
|
5394
6529
|
visible: false,
|
|
@@ -5402,42 +6537,42 @@ var NativeFrontend = class {
|
|
|
5402
6537
|
this.renderer.requestRender();
|
|
5403
6538
|
});
|
|
5404
6539
|
inputRow.add(this.editor);
|
|
5405
|
-
this.enhance = new
|
|
6540
|
+
this.enhance = new BoxRenderable10(renderer2, { id: "omnius-enhance", flexDirection: "row", gap: 1, flexShrink: 0, visible: false });
|
|
5406
6541
|
inputRow.add(this.enhance);
|
|
5407
|
-
this.activity = new
|
|
6542
|
+
this.activity = new TextRenderable9(renderer2, { id: "omnius-activity", content: "", flexGrow: 1, minWidth: 0, height: 1, wrapMode: "none", truncate: true, visible: false, fg: colors.accent });
|
|
5408
6543
|
this.status.add(this.activity);
|
|
5409
|
-
this.media = new
|
|
5410
|
-
this.mediaText = new
|
|
6544
|
+
this.media = new BoxRenderable10(renderer2, { id: "omnius-media", height: 1, minWidth: 0, flexShrink: 1, flexDirection: "row", gap: 1, visible: false });
|
|
6545
|
+
this.mediaText = new TextRenderable9(renderer2, { id: "omnius-media-text", content: "", flexGrow: 1, minWidth: 0, wrapMode: "none", truncate: true, fg: colors.accent });
|
|
5411
6546
|
this.media.add(this.mediaText);
|
|
5412
|
-
this.micTrack = new
|
|
6547
|
+
this.micTrack = new TextRenderable9(renderer2, { id: "omnius-mic-meter", width: 12, height: 1, flexShrink: 0, fg: colors.foreground, visible: false });
|
|
5413
6548
|
this.media.add(this.micTrack);
|
|
5414
6549
|
this.status.add(this.media);
|
|
5415
|
-
this.copyFeedback = new
|
|
6550
|
+
this.copyFeedback = new TextRenderable9(renderer2, {
|
|
5416
6551
|
id: "omnius-copy-feedback",
|
|
5417
6552
|
content: "",
|
|
5418
6553
|
height: 1,
|
|
5419
6554
|
flexShrink: 0,
|
|
5420
6555
|
fg: colors.foreground,
|
|
5421
|
-
attributes:
|
|
6556
|
+
attributes: TextAttributes10.DIM,
|
|
5422
6557
|
selectable: false,
|
|
5423
6558
|
visible: false
|
|
5424
6559
|
});
|
|
5425
6560
|
this.status.add(this.copyFeedback);
|
|
5426
|
-
this.metricsRow = new
|
|
5427
|
-
this.keyHints = new
|
|
6561
|
+
this.metricsRow = new BoxRenderable10(renderer2, { id: "omnius-metrics-row", width: "100%", height: 1, flexShrink: 0, flexDirection: "row", gap: 1 });
|
|
6562
|
+
this.keyHints = new TextRenderable9(renderer2, { id: "omnius-key-hints", content: "F1 HELP TAB FOCUS", height: 1, flexShrink: 0, attributes: TextAttributes10.DIM, fg: colors.foreground, selectable: false });
|
|
5428
6563
|
this.metricsRow.add(this.keyHints);
|
|
5429
|
-
this.metricsStartActions = new
|
|
6564
|
+
this.metricsStartActions = new BoxRenderable10(renderer2, { id: "omnius-metrics-start-actions", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
5430
6565
|
this.metricsRow.add(this.metricsStartActions);
|
|
5431
|
-
this.metrics = new
|
|
6566
|
+
this.metrics = new TextRenderable9(renderer2, { id: "omnius-metrics", content: "", height: 1, wrapMode: "none", truncate: true, fg: colors.dim, flexShrink: 1, flexGrow: 1, minWidth: 0 });
|
|
5432
6567
|
this.metricsRow.add(this.metrics);
|
|
5433
|
-
this.metricsEndActions = new
|
|
6568
|
+
this.metricsEndActions = new BoxRenderable10(renderer2, { id: "omnius-metrics-end-actions", flexDirection: "row", gap: 1, flexShrink: 0 });
|
|
5434
6569
|
this.metricsRow.add(this.metricsEndActions);
|
|
5435
6570
|
this.root.add(this.metricsRow);
|
|
5436
6571
|
this.modals = new NativeModalStack(this.context, () => this.restoreFocus());
|
|
5437
6572
|
renderer2.keyInput.on("keypress", this.onKey);
|
|
5438
6573
|
renderer2.keyInput.on("paste", this.onPaste);
|
|
5439
|
-
renderer2.on(
|
|
5440
|
-
renderer2.on(
|
|
6574
|
+
renderer2.on(CliRenderEvents7.FRAME, this.onFrame);
|
|
6575
|
+
renderer2.on(CliRenderEvents7.RESIZE, this.onResize);
|
|
5441
6576
|
this.applyTheme(initialTheme);
|
|
5442
6577
|
this.editor.focus();
|
|
5443
6578
|
}
|
|
@@ -5460,7 +6595,9 @@ var NativeFrontend = class {
|
|
|
5460
6595
|
sessionRow;
|
|
5461
6596
|
sessions;
|
|
5462
6597
|
newSession;
|
|
6598
|
+
sessionPicker;
|
|
5463
6599
|
taskPane;
|
|
6600
|
+
taskStrip;
|
|
5464
6601
|
tasks;
|
|
5465
6602
|
body;
|
|
5466
6603
|
transcriptPane;
|
|
@@ -5520,7 +6657,8 @@ var NativeFrontend = class {
|
|
|
5520
6657
|
pendingInterface;
|
|
5521
6658
|
embeddedId;
|
|
5522
6659
|
selectionArmed = false;
|
|
5523
|
-
update(
|
|
6660
|
+
update(frame, patch) {
|
|
6661
|
+
const state = { ...frame, workQueue: Object.hasOwn(frame, "workQueue") ? frame.workQueue ?? void 0 : this.state?.workQueue };
|
|
5524
6662
|
const inputWasEnabled = this.state?.input.enabled;
|
|
5525
6663
|
const previousView = this.state ? `${this.state.sessions?.activeId ?? ""}:${this.state.activeViewId}:${this.state.presentation ?? "stack"}` : void 0;
|
|
5526
6664
|
const currentView = `${state.sessions?.activeId ?? ""}:${state.activeViewId}:${state.presentation ?? "stack"}`;
|
|
@@ -5556,10 +6694,13 @@ var NativeFrontend = class {
|
|
|
5556
6694
|
this.sessionRow.visible = Boolean(state.sessions);
|
|
5557
6695
|
this.sessions.update(state.sessions?.items ?? [], state.sessions?.activeId ?? "", state.sessions?.busy);
|
|
5558
6696
|
this.newSession.focusable = !state.sessions?.busy;
|
|
5559
|
-
|
|
5560
|
-
|
|
5561
|
-
this.
|
|
5562
|
-
this.
|
|
6697
|
+
this.sessionPicker.focusable = !state.sessions?.busy;
|
|
6698
|
+
if (state.sessions?.busy && (this.newSession.focused || this.sessionPicker.focused)) this.getRenderable(`session:${state.sessions.activeId}`)?.focus();
|
|
6699
|
+
this.newSession.attributes = state.sessions?.busy ? TextAttributes10.DIM : this.newSession.focused ? TextAttributes10.INVERSE : 0;
|
|
6700
|
+
this.sessionPicker.attributes = state.sessions?.busy ? TextAttributes10.DIM : this.sessionPicker.focused ? TextAttributes10.INVERSE : 0;
|
|
6701
|
+
this.tasks.replace(state.taskNotes ? [] : state.tasks);
|
|
6702
|
+
this.taskPane.visible = !state.taskNotes && state.tasks.length > 0;
|
|
6703
|
+
this.taskStrip.update(state.taskNotes);
|
|
5563
6704
|
if (patch) {
|
|
5564
6705
|
if (this.offset > 0 && !viewChanged && !patch.reset) this.newEntries += patch.upsert.filter((block) => !this.content.views.has(block.id)).length;
|
|
5565
6706
|
this.content.patch(patch);
|
|
@@ -5570,7 +6711,7 @@ var NativeFrontend = class {
|
|
|
5570
6711
|
this.pendingDisclosures = void 0;
|
|
5571
6712
|
}
|
|
5572
6713
|
this.queue.content = state.queued.length ? `Queued (${state.queued.length}) · ${state.queued.join(" · ")}` : "";
|
|
5573
|
-
this.queue.visible = state.queued.length > 0;
|
|
6714
|
+
this.queue.visible = !state.workQueue && state.queued.length > 0;
|
|
5574
6715
|
const suggestionSignature = JSON.stringify(state.suggestions);
|
|
5575
6716
|
if (suggestionSignature !== this.suggestionSignature) {
|
|
5576
6717
|
this.suggestionSignature = suggestionSignature;
|
|
@@ -5616,8 +6757,8 @@ var NativeFrontend = class {
|
|
|
5616
6757
|
for (const child of [...parent.getChildren()]) child.destroy();
|
|
5617
6758
|
for (const action of actions) {
|
|
5618
6759
|
const colors = this.context.colors;
|
|
5619
|
-
const attributes = action.disabled ?
|
|
5620
|
-
const button = new
|
|
6760
|
+
const attributes = action.disabled ? TextAttributes10.DIM : action.active ? TextAttributes10.BOLD | TextAttributes10.UNDERLINE : 0;
|
|
6761
|
+
const button = new TextRenderable9(this.renderer, {
|
|
5621
6762
|
id: `${prefix}:${action.id}`,
|
|
5622
6763
|
content: styledText(action.label),
|
|
5623
6764
|
flexShrink: 0,
|
|
@@ -5640,16 +6781,16 @@ var NativeFrontend = class {
|
|
|
5640
6781
|
button.focusable = !action.disabled;
|
|
5641
6782
|
if (!action.disabled) {
|
|
5642
6783
|
button.on("focused", () => {
|
|
5643
|
-
button.attributes = attributes |
|
|
6784
|
+
button.attributes = attributes | TextAttributes10.INVERSE;
|
|
5644
6785
|
});
|
|
5645
6786
|
button.on("blurred", () => {
|
|
5646
6787
|
button.attributes = attributes;
|
|
5647
6788
|
});
|
|
5648
6789
|
button.onMouseOver = () => {
|
|
5649
|
-
button.attributes = attributes |
|
|
6790
|
+
button.attributes = attributes | TextAttributes10.UNDERLINE | (button.focused ? TextAttributes10.INVERSE : 0);
|
|
5650
6791
|
};
|
|
5651
6792
|
button.onMouseOut = () => {
|
|
5652
|
-
button.attributes = attributes | (button.focused ?
|
|
6793
|
+
button.attributes = attributes | (button.focused ? TextAttributes10.INVERSE : 0);
|
|
5653
6794
|
};
|
|
5654
6795
|
}
|
|
5655
6796
|
parent.add(button);
|
|
@@ -5665,10 +6806,10 @@ var NativeFrontend = class {
|
|
|
5665
6806
|
renderActivity() {
|
|
5666
6807
|
const activity = this.state?.activity;
|
|
5667
6808
|
const stage = activity?.stage === "idle" ? void 0 : activity?.stage?.replace(/_/g, " ").toUpperCase();
|
|
5668
|
-
const
|
|
6809
|
+
const label2 = activity?.label && activity.label.toUpperCase() !== stage ? activity.label : void 0;
|
|
5669
6810
|
const elapsed = activity?.elapsedMs === void 0 ? void 0 : `${Math.max(0, Math.floor(activity.elapsedMs / 1e3))}s`;
|
|
5670
6811
|
const progress = activity?.progress === void 0 ? void 0 : `${Math.round(activity.progress * 100)}% source accounted`;
|
|
5671
|
-
const reading = [stage,
|
|
6812
|
+
const reading = [stage, label2, elapsed, progress].filter(Boolean).join(" · ") || this.state?.instruments?.runtimeStatus || "";
|
|
5672
6813
|
this.activity.visible = Boolean(activity?.processing || reading);
|
|
5673
6814
|
this.activity.content = `${activity?.processing ? "RUN · " : ""}${reading}`;
|
|
5674
6815
|
this.status.visible = this.activity.visible || this.media.visible || this.copyFeedback.visible;
|
|
@@ -5691,7 +6832,7 @@ var NativeFrontend = class {
|
|
|
5691
6832
|
this.mediaText.fg = media.recording ? this.context.colors.warning : this.context.colors.accent;
|
|
5692
6833
|
this.micTrack.visible = media.recording && media.levelDb !== void 0;
|
|
5693
6834
|
const level = Math.round(Math.max(0, Math.min(1, ((media.levelDb ?? -60) + 60) / 60)) * 8);
|
|
5694
|
-
this.micTrack.content = `[${"
|
|
6835
|
+
this.micTrack.content = `[${"▮".repeat(level)}${"░".repeat(8 - level)}]`;
|
|
5695
6836
|
}
|
|
5696
6837
|
applyTheme(theme) {
|
|
5697
6838
|
const signature = JSON.stringify(theme);
|
|
@@ -5725,6 +6866,7 @@ var NativeFrontend = class {
|
|
|
5725
6866
|
styleNativeScrollbars(this.headerActions, colors);
|
|
5726
6867
|
styleNativeScrollbars(this.scroll, colors);
|
|
5727
6868
|
this.instruments.applyTheme(colors);
|
|
6869
|
+
this.taskStrip.applyTheme(colors);
|
|
5728
6870
|
this.instrumentDivider.fg = colors.foreground;
|
|
5729
6871
|
this.instrumentDivider.bg = colors.background;
|
|
5730
6872
|
this.copyFeedback.fg = colors.foreground;
|
|
@@ -5745,10 +6887,10 @@ var NativeFrontend = class {
|
|
|
5745
6887
|
this.layoutInstruments();
|
|
5746
6888
|
this.renderer.requestRender();
|
|
5747
6889
|
}
|
|
5748
|
-
resizeInstruments(
|
|
6890
|
+
resizeInstruments(column3) {
|
|
5749
6891
|
if (this.renderer.terminalWidth < 110 || this.embeddedPane.visible) return;
|
|
5750
6892
|
const width = this.renderer.terminalWidth;
|
|
5751
|
-
const requested = Math.max(0, this.body.x + width - Math.round(
|
|
6893
|
+
const requested = Math.max(0, this.body.x + width - Math.round(column3) - 1);
|
|
5752
6894
|
if (requested <= 4) {
|
|
5753
6895
|
this.detailsOpen = false;
|
|
5754
6896
|
if (this.sidebarDragWidth !== void 0) this.sidebarWidth = this.sidebarDragWidth;
|
|
@@ -5771,6 +6913,8 @@ var NativeFrontend = class {
|
|
|
5771
6913
|
this.scroll.height = "auto";
|
|
5772
6914
|
this.scroll.flexBasis = 0;
|
|
5773
6915
|
this.instruments.visible = shown;
|
|
6916
|
+
this.taskStrip.visible = Boolean(this.state?.taskNotes && this.taskStrip.hasItems && (!wide || !shown) && !this.embeddedPane.visible);
|
|
6917
|
+
this.taskStrip.reconcile();
|
|
5774
6918
|
this.instrumentDivider.visible = wide && !this.embeddedPane.visible;
|
|
5775
6919
|
this.instrumentDivider.setCollapsed(!shown);
|
|
5776
6920
|
const railWidth = Math.max(24, Math.min(width - 41, this.sidebarWidth ?? Math.floor(width * 0.38)));
|
|
@@ -5832,12 +6976,12 @@ var NativeFrontend = class {
|
|
|
5832
6976
|
this.tabs.restoreOffset(state.tabs.agents);
|
|
5833
6977
|
const focus = state.focusId && !this.modals.active ? this.getRenderable(state.focusId) : void 0;
|
|
5834
6978
|
if (focus?.focusable) {
|
|
5835
|
-
let ancestor = focus,
|
|
6979
|
+
let ancestor = focus, visible2 = true;
|
|
5836
6980
|
while (ancestor) {
|
|
5837
|
-
|
|
6981
|
+
visible2 &&= ancestor.visible;
|
|
5838
6982
|
ancestor = ancestor.parent;
|
|
5839
6983
|
}
|
|
5840
|
-
if (
|
|
6984
|
+
if (visible2) focus.focus();
|
|
5841
6985
|
}
|
|
5842
6986
|
}
|
|
5843
6987
|
if (this.pendingScrollRestore) {
|
|
@@ -6108,7 +7252,7 @@ var NativeFrontend = class {
|
|
|
6108
7252
|
const targets = [];
|
|
6109
7253
|
const visit = (node) => {
|
|
6110
7254
|
if (!node.visible) return;
|
|
6111
|
-
if (node.focusable && node !== this.scroll && !(node instanceof
|
|
7255
|
+
if (node.focusable && node !== this.scroll && !(node instanceof ScrollBoxRenderable7) && node.height > 0 && node.width > 0) targets.push(node);
|
|
6112
7256
|
for (const child of node.getChildren()) visit(child);
|
|
6113
7257
|
};
|
|
6114
7258
|
visit(this.root);
|
|
@@ -6347,8 +7491,8 @@ var NativeFrontend = class {
|
|
|
6347
7491
|
this.disposeSelectionContrast();
|
|
6348
7492
|
this.renderer.keyInput.off("keypress", this.onKey);
|
|
6349
7493
|
this.renderer.keyInput.off("paste", this.onPaste);
|
|
6350
|
-
this.renderer.off(
|
|
6351
|
-
this.renderer.off(
|
|
7494
|
+
this.renderer.off(CliRenderEvents7.FRAME, this.onFrame);
|
|
7495
|
+
this.renderer.off(CliRenderEvents7.RESIZE, this.onResize);
|
|
6352
7496
|
const mediaClosed = [...this.context.mediaViews ?? []].map((media) => {
|
|
6353
7497
|
media.pausePlayback();
|
|
6354
7498
|
return media.closed;
|
|
@@ -6364,7 +7508,7 @@ var NativeFrontend = class {
|
|
|
6364
7508
|
};
|
|
6365
7509
|
|
|
6366
7510
|
// packages/cli/src/tui/native/components/cursor.ts
|
|
6367
|
-
import { CliRenderEvents as
|
|
7511
|
+
import { CliRenderEvents as CliRenderEvents8 } from "@opentui/core";
|
|
6368
7512
|
function installTerminalCursorDefaults(renderer2, session) {
|
|
6369
7513
|
const reset = new TextEncoder().encode("\x1B]112\x07");
|
|
6370
7514
|
let disposed = false;
|
|
@@ -6414,11 +7558,11 @@ function installTerminalCursorDefaults(renderer2, session) {
|
|
|
6414
7558
|
const dispose = () => {
|
|
6415
7559
|
if (disposed) return;
|
|
6416
7560
|
disposed = true;
|
|
6417
|
-
renderer2.off(
|
|
6418
|
-
renderer2.off(
|
|
7561
|
+
renderer2.off(CliRenderEvents8.FRAME, afterFrame);
|
|
7562
|
+
renderer2.off(CliRenderEvents8.DESTROY, dispose);
|
|
6419
7563
|
};
|
|
6420
|
-
renderer2.on(
|
|
6421
|
-
renderer2.once(
|
|
7564
|
+
renderer2.on(CliRenderEvents8.FRAME, afterFrame);
|
|
7565
|
+
renderer2.once(CliRenderEvents8.DESTROY, dispose);
|
|
6422
7566
|
return { restore, dispose };
|
|
6423
7567
|
}
|
|
6424
7568
|
|
|
@@ -6507,10 +7651,10 @@ try {
|
|
|
6507
7651
|
maxFps: 60,
|
|
6508
7652
|
clearOnShutdown: false
|
|
6509
7653
|
});
|
|
6510
|
-
renderer.on(
|
|
7654
|
+
renderer.on(CliRenderEvents9.RENDER_ERROR, (event) => {
|
|
6511
7655
|
void fail(event.error);
|
|
6512
7656
|
});
|
|
6513
|
-
renderer.on(
|
|
7657
|
+
renderer.on(CliRenderEvents9.HANDLER_ERROR, (event) => {
|
|
6514
7658
|
void fail(event.error);
|
|
6515
7659
|
});
|
|
6516
7660
|
renderer.on("error", (event) => {
|