@h-rig/cli 0.0.6-alpha.86 → 0.0.6-alpha.88

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.
Files changed (80) hide show
  1. package/dist/bin/rig.js +287 -578
  2. package/dist/src/app-opentui/adapters/common.d.ts +3 -0
  3. package/dist/src/app-opentui/adapters/common.js +4 -0
  4. package/dist/src/app-opentui/adapters/family.js +31 -4
  5. package/dist/src/app-opentui/adapters/pi-attach.d.ts +7 -0
  6. package/dist/src/app-opentui/adapters/pi-attach.js +527 -473
  7. package/dist/src/app-opentui/adapters/tasks.js +82 -468
  8. package/dist/src/app-opentui/bootstrap.js +287 -578
  9. package/dist/src/app-opentui/command-palette.js +1 -0
  10. package/dist/src/app-opentui/drone.js +1 -0
  11. package/dist/src/app-opentui/index.js +127 -446
  12. package/dist/src/app-opentui/keymap.js +2 -387
  13. package/dist/src/app-opentui/list-search.d.ts +5 -1
  14. package/dist/src/app-opentui/list-search.js +2 -2
  15. package/dist/src/app-opentui/pi-host-child.js +31 -4
  16. package/dist/src/app-opentui/pi-pty-host.d.ts +14 -64
  17. package/dist/src/app-opentui/pi-pty-host.js +3 -397
  18. package/dist/src/app-opentui/react/App.js +107 -433
  19. package/dist/src/app-opentui/react/Backdrop.js +1 -0
  20. package/dist/src/app-opentui/react/ChromeHost.js +34 -410
  21. package/dist/src/app-opentui/react/SceneFrameView.js +55 -5
  22. package/dist/src/app-opentui/react/launch.js +171 -472
  23. package/dist/src/app-opentui/react/syntax.js +1 -0
  24. package/dist/src/app-opentui/registry.js +99 -487
  25. package/dist/src/app-opentui/render/graphics.js +1 -0
  26. package/dist/src/app-opentui/render/hover.d.ts +11 -0
  27. package/dist/src/app-opentui/render/hover.js +34 -0
  28. package/dist/src/app-opentui/render/native-host.js +1 -0
  29. package/dist/src/app-opentui/render/panels.js +50 -3
  30. package/dist/src/app-opentui/render/preloader.js +1 -0
  31. package/dist/src/app-opentui/render/scene.js +1 -0
  32. package/dist/src/app-opentui/render/terminal-handoff.d.ts +16 -0
  33. package/dist/src/app-opentui/render/terminal-handoff.js +14 -0
  34. package/dist/src/app-opentui/render/text.d.ts +13 -0
  35. package/dist/src/app-opentui/render/text.js +54 -5
  36. package/dist/src/app-opentui/render/type-bar.js +1 -0
  37. package/dist/src/app-opentui/runtime.js +127 -446
  38. package/dist/src/app-opentui/scenes/command.js +1 -0
  39. package/dist/src/app-opentui/scenes/doctor.js +1 -0
  40. package/dist/src/app-opentui/scenes/error.js +1 -0
  41. package/dist/src/app-opentui/scenes/family-domains/agent.js +1 -0
  42. package/dist/src/app-opentui/scenes/family-domains/browser.js +1 -0
  43. package/dist/src/app-opentui/scenes/family-domains/dist.js +1 -0
  44. package/dist/src/app-opentui/scenes/family-domains/git.js +1 -0
  45. package/dist/src/app-opentui/scenes/family-domains/github.js +1 -0
  46. package/dist/src/app-opentui/scenes/family-domains/harness.js +1 -0
  47. package/dist/src/app-opentui/scenes/family-domains/index.js +1 -0
  48. package/dist/src/app-opentui/scenes/family-domains/kit.js +1 -0
  49. package/dist/src/app-opentui/scenes/family-domains/profile.js +1 -0
  50. package/dist/src/app-opentui/scenes/family-domains/queue.js +1 -0
  51. package/dist/src/app-opentui/scenes/family-domains/remote.js +1 -0
  52. package/dist/src/app-opentui/scenes/family-domains/review.js +1 -0
  53. package/dist/src/app-opentui/scenes/family-domains/setup.js +1 -0
  54. package/dist/src/app-opentui/scenes/family-domains/stats.js +1 -0
  55. package/dist/src/app-opentui/scenes/family.js +1 -0
  56. package/dist/src/app-opentui/scenes/fleet.js +3 -5
  57. package/dist/src/app-opentui/scenes/handoff.js +1 -0
  58. package/dist/src/app-opentui/scenes/help.js +1 -0
  59. package/dist/src/app-opentui/scenes/inbox.js +1 -0
  60. package/dist/src/app-opentui/scenes/init.js +1 -0
  61. package/dist/src/app-opentui/scenes/inspect.js +1 -0
  62. package/dist/src/app-opentui/scenes/main.js +1 -0
  63. package/dist/src/app-opentui/scenes/pi.js +1 -0
  64. package/dist/src/app-opentui/scenes/plugin.js +1 -0
  65. package/dist/src/app-opentui/scenes/repo.js +1 -0
  66. package/dist/src/app-opentui/scenes/run-detail.js +1 -0
  67. package/dist/src/app-opentui/scenes/server.js +1 -0
  68. package/dist/src/app-opentui/scenes/tasks.js +3 -5
  69. package/dist/src/app-opentui/scenes/workspace.js +1 -0
  70. package/dist/src/app-opentui/selectable.js +1 -0
  71. package/dist/src/app-opentui/theme.d.ts +1 -0
  72. package/dist/src/app-opentui/theme.js +1 -0
  73. package/dist/src/commands/_operator-view.js +31 -4
  74. package/dist/src/commands/_pi-frontend.d.ts +25 -0
  75. package/dist/src/commands/_pi-frontend.js +32 -4
  76. package/dist/src/commands/run.js +31 -4
  77. package/dist/src/commands/task.js +31 -4
  78. package/dist/src/commands.js +31 -4
  79. package/dist/src/index.js +31 -4
  80. package/package.json +8 -8
@@ -2,7 +2,7 @@
2
2
  // packages/cli/src/app-opentui/runtime.ts
3
3
  import { existsSync as existsSync3 } from "fs";
4
4
  import { resolve as resolve3 } from "path";
5
- import { BoxRenderable as BoxRenderable3, RGBA as RGBA8, StyledText as StyledText4, TextRenderable as TextRenderable4, createCliRenderer } from "@opentui/core";
5
+ import { BoxRenderable as BoxRenderable3, RGBA as RGBA7, StyledText as StyledText3, TextRenderable as TextRenderable4, createCliRenderer } from "@opentui/core";
6
6
 
7
7
  // packages/cli/src/app-opentui/events.ts
8
8
  function createAppEventBus() {
@@ -1205,395 +1205,10 @@ function intentFromTypeBar(value) {
1205
1205
  }
1206
1206
 
1207
1207
  // packages/cli/src/app-opentui/pi-pty-host.ts
1208
- import { fileURLToPath as fileURLToPath2 } from "url";
1209
- import { basename as basename2 } from "path";
1210
- import { RGBA, StyledText, TextAttributes } from "@opentui/core";
1211
- import { Terminal as XtermTerminal2 } from "@xterm/headless";
1212
- var MIN_COLS2 = 40;
1213
- var MIN_ROWS2 = 12;
1214
- var MAX_ROWS2 = 300;
1215
- var MAX_SNAPSHOT_LINES2 = 360;
1216
- var STYLED_SNAPSHOT_MARGIN = 6;
1217
- var SNAPSHOT_DELAY_MS2 = 120;
1218
- var fallbackChildScriptPath = fileURLToPath2(new URL("./pi-host-child.ts", import.meta.url));
1219
- var activeHost2 = null;
1220
- function clampCols2(cols) {
1221
- return Math.max(MIN_COLS2, Math.trunc(cols || 100));
1222
- }
1223
- function clampRows2(rows) {
1224
- return Math.max(MIN_ROWS2, Math.min(MAX_ROWS2, Math.trunc(rows || 35)));
1225
- }
1226
- var XTERM_COLOR_MODE_INDEXED_16 = 16777216;
1227
- var XTERM_COLOR_MODE_INDEXED_256 = 33554432;
1228
- var XTERM_COLOR_MODE_RGB = 50331648;
1229
- function rgbaFromXtermColor(mode, value) {
1230
- if (mode === 1 || mode === 2 || mode === XTERM_COLOR_MODE_INDEXED_16 || mode === XTERM_COLOR_MODE_INDEXED_256) {
1231
- return RGBA.fromIndex(value);
1232
- }
1233
- if (mode === 3 || mode === XTERM_COLOR_MODE_RGB) {
1234
- return RGBA.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255);
1235
- }
1236
- return;
1237
- }
1238
- function textAttributesFromCell(cell) {
1239
- let attributes = TextAttributes.NONE;
1240
- if (cell.isBold())
1241
- attributes |= TextAttributes.BOLD;
1242
- if (cell.isDim())
1243
- attributes |= TextAttributes.DIM;
1244
- if (cell.isItalic())
1245
- attributes |= TextAttributes.ITALIC;
1246
- if (cell.isUnderline())
1247
- attributes |= TextAttributes.UNDERLINE;
1248
- if (cell.isBlink())
1249
- attributes |= TextAttributes.BLINK;
1250
- if (cell.isInverse())
1251
- attributes |= TextAttributes.INVERSE;
1252
- if (cell.isInvisible())
1253
- attributes |= TextAttributes.HIDDEN;
1254
- if (cell.isStrikethrough())
1255
- attributes |= TextAttributes.STRIKETHROUGH;
1256
- return attributes;
1257
- }
1258
- function sameRgba(a, b) {
1259
- if (!a && !b)
1260
- return true;
1261
- return Boolean(a && b && a.equals(b));
1262
- }
1263
- function sameStyle(a, b) {
1264
- return sameRgba(a.fg, b.fg) && sameRgba(a.bg, b.bg) && (a.attributes ?? 0) === (b.attributes ?? 0);
1265
- }
1266
- function styleFromCell(cell) {
1267
- return {
1268
- fg: rgbaFromXtermColor(cell.getFgColorMode(), cell.getFgColor()),
1269
- bg: rgbaFromXtermColor(cell.getBgColorMode(), cell.getBgColor()),
1270
- attributes: textAttributesFromCell(cell)
1271
- };
1272
- }
1273
- function lineToStyledText(line, cols) {
1274
- if (!line)
1275
- return new StyledText([{ __isChunk: true, text: "" }]);
1276
- const chunks = [];
1277
- let run = "";
1278
- let runStyle = null;
1279
- const flush = () => {
1280
- if (!run)
1281
- return;
1282
- chunks.push({
1283
- __isChunk: true,
1284
- text: run,
1285
- ...runStyle?.fg ? { fg: runStyle.fg } : {},
1286
- ...runStyle?.bg ? { bg: runStyle.bg } : {},
1287
- ...(runStyle?.attributes ?? 0) !== 0 ? { attributes: runStyle.attributes } : {}
1288
- });
1289
- run = "";
1290
- };
1291
- for (let index = 0;index < cols; index += 1) {
1292
- const cell = line.getCell(index);
1293
- if (!cell) {
1294
- if (runStyle !== null)
1295
- flush();
1296
- runStyle = null;
1297
- run += " ";
1298
- continue;
1299
- }
1300
- if (cell.getWidth() === 0)
1301
- continue;
1302
- const style = styleFromCell(cell);
1303
- if (!runStyle || !sameStyle(runStyle, style)) {
1304
- flush();
1305
- runStyle = style;
1306
- }
1307
- run += cell.getChars() || " ";
1308
- }
1309
- flush();
1310
- return new StyledText(chunks.length > 0 ? chunks : [{ __isChunk: true, text: "" }]);
1311
- }
1312
- function childCommandPrefix2() {
1313
- const execName = basename2(process.execPath).toLowerCase();
1314
- const currentEntry = process.argv[1];
1315
- if (execName === "bun" || execName === "bun.exe") {
1316
- return currentEntry ? [process.execPath, currentEntry, "__opentui-pi-host"] : [process.execPath, fallbackChildScriptPath];
1317
- }
1318
- return [process.execPath, "__opentui-pi-host"];
1319
- }
1320
- function withEnv2(base) {
1321
- const env = {};
1322
- for (const [key, value] of Object.entries(base ?? process.env)) {
1323
- if (key === "RIG_PLAIN" || key === "RIG_CLI_PLAIN_HELP" || key === "NO_COLOR")
1324
- continue;
1325
- if (typeof value === "string")
1326
- env[key] = value;
1327
- }
1328
- return {
1329
- ...env,
1330
- TERM: "xterm-256color",
1331
- COLORTERM: "truecolor",
1332
- FORCE_COLOR: env.FORCE_COLOR ?? "1",
1333
- RIG_OPENTUI_PI_HOST: "1"
1334
- };
1335
- }
1336
1208
  function getActivePiHost() {
1337
- return activeHost2 && !activeHost2.disposed ? activeHost2 : null;
1338
- }
1339
- function stopActivePiHost(reason = "detach") {
1340
- activeHost2?.dispose(reason);
1341
- activeHost2 = null;
1342
- }
1343
-
1344
- class PiPtyHost {
1345
- runId;
1346
- projectRoot;
1347
- onSnapshot;
1348
- onExit;
1349
- onError;
1350
- terminal;
1351
- disposables = [];
1352
- decoder = new TextDecoder("utf-8");
1353
- proc = null;
1354
- pty = null;
1355
- status = "starting";
1356
- cols;
1357
- rows;
1358
- message = "starting bundled Pi";
1359
- lastResizeError = null;
1360
- exitCode;
1361
- signal;
1362
- notifyTimer = null;
1363
- lastStreamKey = "";
1364
- _disposed = false;
1365
- constructor(options) {
1366
- this.runId = options.runId;
1367
- this.projectRoot = options.projectRoot;
1368
- this.cols = clampCols2(options.cols);
1369
- this.rows = clampRows2(options.rows);
1370
- this.onSnapshot = options.onSnapshot;
1371
- this.onExit = options.onExit;
1372
- this.onError = options.onError;
1373
- this.terminal = new XtermTerminal2({
1374
- allowProposedApi: true,
1375
- cols: this.cols,
1376
- rows: this.rows,
1377
- scrollback: 1000
1378
- });
1379
- this.registerTerminalResponders();
1380
- this.disposables.push(this.terminal.onWriteParsed(() => {
1381
- if (this._disposed)
1382
- return;
1383
- const snapshot = this.createSnapshot();
1384
- const key = snapshot.lines.join(`
1385
- `);
1386
- if (key === this.lastStreamKey)
1387
- return;
1388
- this.lastStreamKey = key;
1389
- this.onSnapshot?.(snapshot);
1390
- }));
1391
- }
1392
- get disposed() {
1393
- return this._disposed;
1394
- }
1395
- get snapshot() {
1396
- return this.createSnapshot();
1397
- }
1398
- async start() {
1399
- if (this._disposed)
1400
- throw new Error("Pi PTY host is disposed.");
1401
- if (typeof Bun.Terminal !== "function") {
1402
- throw new Error("Bun native PTY is unavailable in this runtime. Pi host requires Bun.Terminal.");
1403
- }
1404
- const spawnOptions = {
1405
- cwd: this.projectRoot,
1406
- env: withEnv2(process.env),
1407
- terminal: {
1408
- cols: this.cols,
1409
- rows: this.rows,
1410
- name: "xterm-256color",
1411
- data: (_terminal, data) => this.handlePtyData(data)
1412
- }
1413
- };
1414
- const proc = Bun.spawn([
1415
- ...childCommandPrefix2(),
1416
- "--run-id",
1417
- this.runId,
1418
- "--project-root",
1419
- this.projectRoot
1420
- ], spawnOptions);
1421
- if (!proc.terminal)
1422
- throw new Error("Bun did not attach a terminal to the bundled Pi child process.");
1423
- this.proc = proc;
1424
- this.pty = proc.terminal;
1425
- this.status = "running";
1426
- this.message = "bundled Pi running inside this app";
1427
- this.emitSnapshotSoon(0);
1428
- proc.exited.then((exitCode) => {
1429
- if (this._disposed)
1430
- return;
1431
- this.status = exitCode === 0 ? "exited" : "failed";
1432
- this.exitCode = exitCode;
1433
- this.signal = null;
1434
- this.message = exitCode === 0 ? "bundled Pi exited" : `bundled Pi exited with code ${exitCode}`;
1435
- const snapshot = this.createSnapshot();
1436
- this.onSnapshot?.(snapshot);
1437
- this.onExit?.(snapshot);
1438
- if (activeHost2 === this)
1439
- activeHost2 = null;
1440
- this.dispose("exit", { kill: false, notify: false });
1441
- }).catch((error) => {
1442
- if (this._disposed)
1443
- return;
1444
- this.status = "failed";
1445
- this.message = error instanceof Error ? error.message : String(error);
1446
- const snapshot = this.createSnapshot();
1447
- this.onSnapshot?.(snapshot);
1448
- this.onError?.(error, snapshot);
1449
- if (activeHost2 === this)
1450
- activeHost2 = null;
1451
- this.dispose("error", { kill: false, notify: false });
1452
- });
1453
- }
1454
- write(data) {
1455
- if (this._disposed || !this.pty)
1456
- return;
1457
- try {
1458
- this.pty.write(data);
1459
- } catch (error) {
1460
- this.status = "failed";
1461
- this.message = error instanceof Error ? error.message : String(error);
1462
- const snapshot = this.createSnapshot();
1463
- this.onSnapshot?.(snapshot);
1464
- this.onError?.(error, snapshot);
1465
- }
1466
- }
1467
- resize(cols, rows) {
1468
- const nextCols = clampCols2(cols);
1469
- const nextRows = clampRows2(rows);
1470
- if (nextCols === this.cols && nextRows === this.rows)
1471
- return;
1472
- this.cols = nextCols;
1473
- this.rows = nextRows;
1474
- this.terminal.resize(nextCols, nextRows);
1475
- try {
1476
- this.pty?.resize(nextCols, nextRows);
1477
- this.lastResizeError = null;
1478
- } catch (error) {
1479
- this.lastResizeError = error instanceof Error ? error.message : String(error);
1480
- }
1481
- this.emitSnapshotSoon(0);
1482
- }
1483
- detach() {
1484
- this.dispose("detach");
1485
- return this.createSnapshot("detached from bundled Pi");
1486
- }
1487
- dispose(reason = "dispose", options = {}) {
1488
- if (this._disposed)
1489
- return;
1490
- this._disposed = true;
1491
- if (this.notifyTimer)
1492
- clearTimeout(this.notifyTimer);
1493
- this.notifyTimer = null;
1494
- for (const disposable of this.disposables.splice(0)) {
1495
- try {
1496
- disposable.dispose();
1497
- } catch {}
1498
- }
1499
- if (options.kill !== false) {
1500
- try {
1501
- this.proc?.kill("SIGTERM");
1502
- } catch {}
1503
- }
1504
- try {
1505
- this.pty?.close();
1506
- } catch {}
1507
- try {
1508
- this.terminal.dispose();
1509
- } catch {}
1510
- if (activeHost2 === this)
1511
- activeHost2 = null;
1512
- if (options.notify) {
1513
- this.message = reason;
1514
- this.onSnapshot?.(this.createSnapshot(reason));
1515
- }
1516
- }
1517
- handlePtyData(data) {
1518
- if (this._disposed)
1519
- return;
1520
- const text = this.decoder.decode(data, { stream: true });
1521
- this.respondToRawTerminalQueries(text);
1522
- this.terminal.write(data);
1523
- }
1524
- emitSnapshotSoon(delayMs = SNAPSHOT_DELAY_MS2) {
1525
- if (this._disposed || this.notifyTimer)
1526
- return;
1527
- this.notifyTimer = setTimeout(() => {
1528
- this.notifyTimer = null;
1529
- if (this._disposed)
1530
- return;
1531
- this.onSnapshot?.(this.createSnapshot());
1532
- }, delayMs);
1533
- }
1534
- createSnapshot(message = this.message) {
1535
- const buffer = this.terminal.buffer.active;
1536
- const end = buffer.length;
1537
- const start = Math.max(0, end - MAX_SNAPSHOT_LINES2);
1538
- const styledStart = Math.max(start, end - this.rows - STYLED_SNAPSHOT_MARGIN);
1539
- const lines = [];
1540
- const styledLines = [];
1541
- for (let row = start;row < end; row += 1) {
1542
- const line = buffer.getLine(row);
1543
- lines.push((line?.translateToString(false) ?? "").slice(0, this.cols));
1544
- if (row >= styledStart)
1545
- styledLines[lines.length - 1] = lineToStyledText(line, this.cols);
1546
- }
1547
- while (lines.length < this.rows) {
1548
- lines.push("");
1549
- styledLines[lines.length - 1] = new StyledText([{ __isChunk: true, text: "" }]);
1550
- }
1551
- const resolvedMessage = this.lastResizeError ? `resize degraded: ${this.lastResizeError}` : message;
1552
- return {
1553
- runId: this.runId,
1554
- status: this.status,
1555
- cols: this.cols,
1556
- rows: this.rows,
1557
- lines,
1558
- styledLines,
1559
- message: resolvedMessage,
1560
- ...this.lastResizeError ? { resizeError: this.lastResizeError } : {},
1561
- ...this.exitCode !== undefined ? { exitCode: this.exitCode } : {},
1562
- ...this.signal !== undefined ? { signal: this.signal } : {}
1563
- };
1564
- }
1565
- registerTerminalResponders() {
1566
- this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "c" }, (params) => {
1567
- if (params.length === 0 || params[0] === 0)
1568
- this.write("\x1B[?62;22c");
1569
- return false;
1570
- }));
1571
- this.disposables.push(this.terminal.parser.registerCsiHandler({ prefix: ">", final: "c" }, (params) => {
1572
- if (params.length === 0 || params[0] === 0)
1573
- this.write("\x1B[>0;0;0c");
1574
- return false;
1575
- }));
1576
- this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "n" }, (params) => {
1577
- if (params[0] === 5) {
1578
- this.write("\x1B[0n");
1579
- } else if (params[0] === 6) {
1580
- const row = this.terminal.buffer.active.cursorY + 1;
1581
- const col = this.terminal.buffer.active.cursorX + 1;
1582
- this.write(`\x1B[${row};${col}R`);
1583
- }
1584
- return false;
1585
- }));
1586
- }
1587
- respondToRawTerminalQueries(text) {
1588
- if (!text)
1589
- return;
1590
- const decrqm = /\x1b\[\?(\d+)\$p/g;
1591
- let match;
1592
- while ((match = decrqm.exec(text)) !== null) {
1593
- this.write(`\x1B[?${match[1]};2$y`);
1594
- }
1595
- }
1209
+ return null;
1596
1210
  }
1211
+ function stopActivePiHost(_reason) {}
1597
1212
 
1598
1213
  // packages/cli/src/app-opentui/keymap.ts
1599
1214
  var autocompleteState;
@@ -2238,13 +1853,14 @@ import {
2238
1853
  dim as otuiDim,
2239
1854
  fg as otuiFg,
2240
1855
  t,
2241
- TextAttributes as TextAttributes2
1856
+ TextAttributes
2242
1857
  } from "@opentui/core";
2243
1858
  var RIG_UI = {
2244
1859
  bg: "#070809",
2245
1860
  bg2: "#0b0c0e",
2246
1861
  panel: "#101115",
2247
1862
  panel2: "#14161b",
1863
+ hover: "#181b24",
2248
1864
  glass: "#1e2230",
2249
1865
  border: "#2a2e3a",
2250
1866
  ink: "#f4f5f8",
@@ -2273,7 +1889,7 @@ var styles = {
2273
1889
  };
2274
1890
 
2275
1891
  // packages/cli/src/app-opentui/drone.ts
2276
- import { RGBA as RGBA2, StyledText as StyledText2, TextAttributes as TextAttributes3 } from "@opentui/core";
1892
+ import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
2277
1893
  var MINI_DRONE = [
2278
1894
  "(!!!) (!!!)",
2279
1895
  " \\%==%/ ",
@@ -2289,13 +1905,13 @@ var LEAD_MARK = [
2289
1905
  var BLADE_FRAMES = ["---", "\\\\\\", "|||", "///"];
2290
1906
  var EYE_FRAMES = ["o", "@", "\u2022", "."];
2291
1907
  var COLOR = {
2292
- body: RGBA2.fromHex(RIG_UI.lime),
2293
- mini: RGBA2.fromHex(RIG_UI.limeDim),
2294
- rotor: RGBA2.fromHex(RIG_UI.cyan),
2295
- path: RGBA2.fromHex(RIG_UI.cyan),
2296
- eye: RGBA2.fromHex(RIG_UI.ink),
2297
- dim: RGBA2.fromHex(RIG_UI.ink4),
2298
- ink: RGBA2.fromHex(RIG_UI.ink2)
1908
+ body: RGBA.fromHex(RIG_UI.lime),
1909
+ mini: RGBA.fromHex(RIG_UI.limeDim),
1910
+ rotor: RGBA.fromHex(RIG_UI.cyan),
1911
+ path: RGBA.fromHex(RIG_UI.cyan),
1912
+ eye: RGBA.fromHex(RIG_UI.ink),
1913
+ dim: RGBA.fromHex(RIG_UI.ink4),
1914
+ ink: RGBA.fromHex(RIG_UI.ink2)
2299
1915
  };
2300
1916
  function bladeForTick(tick, phase = 0) {
2301
1917
  return BLADE_FRAMES[(Math.floor(tick / 3) + phase) % BLADE_FRAMES.length];
@@ -2305,12 +1921,12 @@ function eyeForTick(tick, phase = 0) {
2305
1921
  return pulse > 0.55 ? EYE_FRAMES[1] : pulse > 0.1 ? EYE_FRAMES[0] : pulse > -0.45 ? EYE_FRAMES[2] : EYE_FRAMES[3];
2306
1922
  }
2307
1923
  function chunk(text, fg, bold = false, dim = false) {
2308
- let attributes = TextAttributes3.NONE;
1924
+ let attributes = TextAttributes2.NONE;
2309
1925
  if (bold)
2310
- attributes |= TextAttributes3.BOLD;
1926
+ attributes |= TextAttributes2.BOLD;
2311
1927
  if (dim)
2312
- attributes |= TextAttributes3.DIM;
2313
- return { __isChunk: true, text, fg, ...attributes !== TextAttributes3.NONE ? { attributes } : {} };
1928
+ attributes |= TextAttributes2.DIM;
1929
+ return { __isChunk: true, text, fg, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
2314
1930
  }
2315
1931
  function styledLine(text, colorFor) {
2316
1932
  const chunks = [];
@@ -2331,7 +1947,7 @@ function styledLine(text, colorFor) {
2331
1947
  run += char;
2332
1948
  }
2333
1949
  flush();
2334
- return new StyledText2(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
1950
+ return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
2335
1951
  }
2336
1952
  function droneColor(char) {
2337
1953
  if (char === "?" || char === "o" || char === "@" || char === "\u2022")
@@ -2611,7 +2227,7 @@ function reduceAppEvent(state, event) {
2611
2227
  }
2612
2228
 
2613
2229
  // packages/cli/src/app-opentui/render/graphics.ts
2614
- import { FrameBufferRenderable, RGBA as RGBA3 } from "@opentui/core";
2230
+ import { FrameBufferRenderable, RGBA as RGBA2 } from "@opentui/core";
2615
2231
 
2616
2232
  // packages/cli/src/app-opentui/render/ascii-fleet.ts
2617
2233
  var LEAD_DRONE = [
@@ -2755,13 +2371,13 @@ var GLOW_FALLOFF_EXP_ASCII = 2.2;
2755
2371
  // packages/cli/src/app-opentui/render/graphics.ts
2756
2372
  var BRAILLE_SAMPLES_X = 2;
2757
2373
  var BRAILLE_SAMPLES_Y = 4;
2758
- var TRANSPARENT = RGBA3.fromValues(0, 0, 0, 0);
2759
- var BACKDROP = RGBA3.fromHex(RIG_UI.bg);
2760
- var PANEL_BG = RGBA3.fromInts(16, 17, 21, 184);
2761
- var PANEL_HEADER_BG = RGBA3.fromInts(16, 17, 21, 188);
2762
- var PANEL_LINE = RGBA3.fromInts(255, 255, 255, 20);
2763
- var PANEL_LINE_DIM = RGBA3.fromInts(255, 255, 255, 8);
2764
- var PANEL_TEXT_DIM = RGBA3.fromInts(108, 110, 121, 255);
2374
+ var TRANSPARENT = RGBA2.fromValues(0, 0, 0, 0);
2375
+ var BACKDROP = RGBA2.fromHex(RIG_UI.bg);
2376
+ var PANEL_BG = RGBA2.fromInts(16, 17, 21, 184);
2377
+ var PANEL_HEADER_BG = RGBA2.fromInts(16, 17, 21, 188);
2378
+ var PANEL_LINE = RGBA2.fromInts(255, 255, 255, 20);
2379
+ var PANEL_LINE_DIM = RGBA2.fromInts(255, 255, 255, 8);
2380
+ var PANEL_TEXT_DIM = RGBA2.fromInts(108, 110, 121, 255);
2765
2381
  var AC_RGB = [204, 255, 77];
2766
2382
  var C2_RGB = [86, 216, 255];
2767
2383
  var MG_RGB = [255, 121, 176];
@@ -2866,7 +2482,7 @@ function paletteColor(ac, c2, mg, ink) {
2866
2482
  const b = (AC_RGB[2] * ac + C2_RGB[2] * c2 + MG_RGB[2] * mg + INK_RGB[2] * ink) / total;
2867
2483
  const intensity = Math.min(1, total / 4);
2868
2484
  const lift = 0.34 + intensity * 0.66;
2869
- return RGBA3.fromInts(Math.round(r * lift), Math.round(g * lift), Math.round(b * lift), 255);
2485
+ return RGBA2.fromInts(Math.round(r * lift), Math.round(g * lift), Math.round(b * lift), 255);
2870
2486
  }
2871
2487
  function clearCanvas(canvas) {
2872
2488
  canvas.ac.fill(0);
@@ -3221,8 +2837,8 @@ function staticFleetTick(scene) {
3221
2837
  }
3222
2838
  function withAlpha(hex, alpha) {
3223
2839
  const a = Math.max(0, Math.min(255, Math.round(alpha * 255)));
3224
- const [r, g, b] = RGBA3.fromHex(hex).toInts();
3225
- return RGBA3.fromInts(r, g, b, a);
2840
+ const [r, g, b] = RGBA2.fromHex(hex).toInts();
2841
+ return RGBA2.fromInts(r, g, b, a);
3226
2842
  }
3227
2843
  function asciiFleetColor(char, row, alpha) {
3228
2844
  if (char === "@" || char === "$" || char === "o")
@@ -3230,7 +2846,7 @@ function asciiFleetColor(char, row, alpha) {
3230
2846
  if (char === "%" || char === "!" || char === "/" || char === "\\" || char === "|")
3231
2847
  return withAlpha(RIG_UI.cyan, alpha);
3232
2848
  if (char === "." || char === "'" || char === "_" || row < 3 || row > FLEET_GRID_HEIGHT - 4) {
3233
- return RGBA3.fromInts(108, 110, 121, Math.min(170, Math.max(0, Math.min(255, Math.round(alpha * 255)))));
2849
+ return RGBA2.fromInts(108, 110, 121, Math.min(170, Math.max(0, Math.min(255, Math.round(alpha * 255)))));
3234
2850
  }
3235
2851
  return withAlpha(RIG_UI.limeDim, alpha);
3236
2852
  }
@@ -3343,16 +2959,67 @@ function sparklineString(values, width) {
3343
2959
  }
3344
2960
 
3345
2961
  // packages/cli/src/app-opentui/render/text.ts
3346
- import { RGBA as RGBA4, TextAttributes as TextAttributes4, TextRenderable } from "@opentui/core";
3347
- var TRANSPARENT2 = RGBA4.fromInts(0, 0, 0, 0);
2962
+ import { RGBA as RGBA3, TextAttributes as TextAttributes3, TextRenderable } from "@opentui/core";
2963
+
2964
+ // packages/cli/src/app-opentui/render/hover.ts
2965
+ var hoveredId;
2966
+ var listeners = new Set;
2967
+ function isHovered(id) {
2968
+ return id !== undefined && id === hoveredId;
2969
+ }
2970
+ function setHoveredSelectableId(id) {
2971
+ if (hoveredId === id)
2972
+ return;
2973
+ hoveredId = id;
2974
+ for (const listener of listeners)
2975
+ listener();
2976
+ }
2977
+ function clearHoveredSelectableId(id) {
2978
+ if (id !== undefined && hoveredId === id)
2979
+ setHoveredSelectableId(undefined);
2980
+ }
2981
+ function subscribeHover(listener) {
2982
+ listeners.add(listener);
2983
+ return () => {
2984
+ listeners.delete(listener);
2985
+ };
2986
+ }
2987
+
2988
+ // packages/cli/src/app-opentui/render/text.ts
2989
+ var TRANSPARENT2 = RGBA3.fromInts(0, 0, 0, 0);
2990
+ var HOVER_BG = RGBA3.fromHex(RIG_UI.hover);
2991
+ function lineIsClickable(line2) {
2992
+ return line2?.selectable !== undefined || line2?.selectableIndex !== undefined;
2993
+ }
2994
+ function lineSelectableId(line2) {
2995
+ return line2?.selectable?.id ?? line2?.selectableId;
2996
+ }
2997
+ function lineBackground(line2) {
2998
+ if (line2?.bg)
2999
+ return RGBA3.fromHex(line2.bg);
3000
+ const id = lineSelectableId(line2);
3001
+ if (id !== undefined && isHovered(id))
3002
+ return HOVER_BG;
3003
+ return TRANSPARENT2;
3004
+ }
3348
3005
  function selectableMouseHandler(currentLineRef, onLineMouseDown) {
3349
3006
  return (event) => {
3350
3007
  const currentLine = currentLineRef();
3351
- if (currentLine?.selectableIndex === undefined)
3008
+ if (!lineIsClickable(currentLine))
3352
3009
  return;
3353
3010
  onLineMouseDown?.(currentLine, event);
3354
3011
  };
3355
3012
  }
3013
+ function hoverHandlers(currentLineRef) {
3014
+ return {
3015
+ onMouseOver: () => {
3016
+ const id = lineSelectableId(currentLineRef());
3017
+ if (id !== undefined)
3018
+ setHoveredSelectableId(id);
3019
+ },
3020
+ onMouseOut: () => clearHoveredSelectableId(lineSelectableId(currentLineRef()))
3021
+ };
3022
+ }
3356
3023
  function createTextLine(renderer, id, top, onLineMouseDown) {
3357
3024
  let currentLine;
3358
3025
  const renderable = new TextRenderable(renderer, {
@@ -3364,7 +3031,8 @@ function createTextLine(renderer, id, top, onLineMouseDown) {
3364
3031
  width: 1,
3365
3032
  fg: RIG_UI.ink2,
3366
3033
  selectable: true,
3367
- onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
3034
+ onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
3035
+ ...hoverHandlers(() => currentLine)
3368
3036
  });
3369
3037
  renderable.setRigSceneLine = (line2) => {
3370
3038
  currentLine = line2;
@@ -3381,7 +3049,8 @@ function createFlowTextLine(renderer, id, onLineMouseDown) {
3381
3049
  flexShrink: 0,
3382
3050
  fg: RIG_UI.ink2,
3383
3051
  selectable: true,
3384
- onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
3052
+ onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
3053
+ ...hoverHandlers(() => currentLine)
3385
3054
  });
3386
3055
  renderable.setRigSceneLine = (line2) => {
3387
3056
  currentLine = line2;
@@ -3395,8 +3064,8 @@ function applyTextLine(renderable, line2, top, left, width) {
3395
3064
  renderable.width = width;
3396
3065
  renderable.content = line2?.styledText ?? line2?.text ?? "";
3397
3066
  renderable.fg = line2?.fg ?? RIG_UI.ink2;
3398
- renderable.bg = line2?.bg ?? TRANSPARENT2;
3399
- renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
3067
+ renderable.bg = lineBackground(line2);
3068
+ renderable.attributes = line2?.bold ? TextAttributes3.BOLD : line2?.dim ? TextAttributes3.DIM : 0;
3400
3069
  }
3401
3070
  function applyFlowTextLine(renderable, line2, width) {
3402
3071
  renderable.setRigSceneLine?.(line2);
@@ -3405,8 +3074,8 @@ function applyFlowTextLine(renderable, line2, width) {
3405
3074
  renderable.width = Math.max(1, width);
3406
3075
  renderable.content = line2?.styledText ?? line2?.text ?? "";
3407
3076
  renderable.fg = line2?.fg ?? RIG_UI.ink2;
3408
- renderable.bg = line2?.bg ?? TRANSPARENT2;
3409
- renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
3077
+ renderable.bg = lineBackground(line2);
3078
+ renderable.attributes = line2?.bold ? TextAttributes3.BOLD : line2?.dim ? TextAttributes3.DIM : 0;
3410
3079
  }
3411
3080
  function clearTextLines(renderables, from = 0) {
3412
3081
  for (let index = from;index < renderables.length; index += 1) {
@@ -3420,9 +3089,20 @@ function clearTextLines(renderables, from = 0) {
3420
3089
  }
3421
3090
  }
3422
3091
 
3092
+ // packages/cli/src/app-opentui/render/terminal-handoff.ts
3093
+ function resumeRendererClean(renderer) {
3094
+ try {
3095
+ renderer.pendingSuspendedTerminalSetup = true;
3096
+ } catch {}
3097
+ renderer.resume();
3098
+ try {
3099
+ renderer.requestRender?.();
3100
+ } catch {}
3101
+ }
3102
+
3423
3103
  // packages/cli/src/app-opentui/render/panels.ts
3424
- import { RGBA as RGBA5, ScrollBoxRenderable } from "@opentui/core";
3425
- var TRANSPARENT3 = RGBA5.fromInts(0, 0, 0, 0);
3104
+ import { RGBA as RGBA4, ScrollBoxRenderable } from "@opentui/core";
3105
+ var TRANSPARENT3 = RGBA4.fromInts(0, 0, 0, 0);
3426
3106
  var MAX_PANEL_LINES = 420;
3427
3107
  var PANEL_OPAQUE_ALPHA = 255;
3428
3108
  var PANEL_BORDER = hexToRgba(RIG_UI.border, 255);
@@ -3431,8 +3111,8 @@ function hexToRgba(hex, alpha) {
3431
3111
  const full = clean.length === 3 ? clean.split("").map((part) => `${part}${part}`).join("") : clean;
3432
3112
  const value = Number.parseInt(full, 16);
3433
3113
  if (!Number.isFinite(value))
3434
- return RGBA5.fromInts(14, 15, 17, alpha);
3435
- return RGBA5.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255, alpha);
3114
+ return RGBA4.fromInts(14, 15, 17, alpha);
3115
+ return RGBA4.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255, alpha);
3436
3116
  }
3437
3117
  function panelBackground(panel) {
3438
3118
  return hexToRgba(panel.backgroundColor ?? RIG_UI.panel, PANEL_OPAQUE_ALPHA);
@@ -3547,9 +3227,9 @@ function applyScrollPanels(panels, layout, scenePanels) {
3547
3227
  }
3548
3228
 
3549
3229
  // packages/cli/src/app-opentui/render/type-bar.ts
3550
- import { BoxRenderable, InputRenderable, InputRenderableEvents, RGBA as RGBA6, StyledText as StyledText3, TextRenderable as TextRenderable2 } from "@opentui/core";
3551
- var TYPEBAR_BG = RGBA6.fromInts(20, 25, 14, 224);
3552
- var TYPEBAR_BORDER = RGBA6.fromInts(204, 255, 77, 92);
3230
+ import { BoxRenderable, InputRenderable, InputRenderableEvents, RGBA as RGBA5, StyledText as StyledText2, TextRenderable as TextRenderable2 } from "@opentui/core";
3231
+ var TYPEBAR_BG = RGBA5.fromInts(20, 25, 14, 224);
3232
+ var TYPEBAR_BORDER = RGBA5.fromInts(204, 255, 77, 92);
3553
3233
  function createTypeBar(renderer) {
3554
3234
  const background = new BoxRenderable(renderer, {
3555
3235
  id: "typebar-card",
@@ -3697,7 +3377,7 @@ function formatFooter(footer, width) {
3697
3377
  chunks.push(cell.style(text));
3698
3378
  used += visibleWidth(text);
3699
3379
  });
3700
- return new StyledText3(chunks);
3380
+ return new StyledText2(chunks);
3701
3381
  }
3702
3382
 
3703
3383
  // packages/cli/src/app-opentui/render/native-host.ts
@@ -3705,7 +3385,7 @@ import {
3705
3385
  BoxRenderable as BoxRenderable2,
3706
3386
  CodeRenderable,
3707
3387
  DiffRenderable,
3708
- RGBA as RGBA7,
3388
+ RGBA as RGBA6,
3709
3389
  ScrollBoxRenderable as ScrollBoxRenderable2,
3710
3390
  SyntaxStyle,
3711
3391
  TextRenderable as TextRenderable3,
@@ -3716,19 +3396,19 @@ function rigSyntaxStyle() {
3716
3396
  if (syntaxStyle)
3717
3397
  return syntaxStyle;
3718
3398
  syntaxStyle = SyntaxStyle.fromStyles({
3719
- keyword: { fg: RGBA7.fromHex(RIG_UI.magenta), bold: true },
3720
- string: { fg: RGBA7.fromHex(RIG_UI.lime) },
3721
- number: { fg: RGBA7.fromHex(RIG_UI.cyan) },
3722
- comment: { fg: RGBA7.fromHex(RIG_UI.ink4), italic: true },
3723
- function: { fg: RGBA7.fromHex(RIG_UI.cyan) },
3724
- type: { fg: RGBA7.fromHex(RIG_UI.limeDim) },
3725
- constant: { fg: RGBA7.fromHex(RIG_UI.yellow) },
3726
- default: { fg: RGBA7.fromHex(RIG_UI.ink2) }
3399
+ keyword: { fg: RGBA6.fromHex(RIG_UI.magenta), bold: true },
3400
+ string: { fg: RGBA6.fromHex(RIG_UI.lime) },
3401
+ number: { fg: RGBA6.fromHex(RIG_UI.cyan) },
3402
+ comment: { fg: RGBA6.fromHex(RIG_UI.ink4), italic: true },
3403
+ function: { fg: RGBA6.fromHex(RIG_UI.cyan) },
3404
+ type: { fg: RGBA6.fromHex(RIG_UI.limeDim) },
3405
+ constant: { fg: RGBA6.fromHex(RIG_UI.yellow) },
3406
+ default: { fg: RGBA6.fromHex(RIG_UI.ink2) }
3727
3407
  });
3728
3408
  return syntaxStyle;
3729
3409
  }
3730
3410
  function tableContent(rows) {
3731
- return rows.map((row, rowIndex) => row.map((cell) => [{ __isChunk: true, text: cell, fg: RGBA7.fromHex(rowIndex === 0 ? RIG_UI.ink3 : RIG_UI.ink2) }]));
3411
+ return rows.map((row, rowIndex) => row.map((cell) => [{ __isChunk: true, text: cell, fg: RGBA6.fromHex(rowIndex === 0 ? RIG_UI.ink3 : RIG_UI.ink2) }]));
3732
3412
  }
3733
3413
  function createNativeHost(renderer) {
3734
3414
  try {
@@ -4218,7 +3898,7 @@ function renderMainScene(state, layout) {
4218
3898
  var MAX_SCENE_LINES = 200;
4219
3899
  var MAX_SCENE_PANELS = 5;
4220
3900
  var ANIMATION_SLOWDOWN = 1;
4221
- var PRELOADER_BACKDROP = RGBA8.fromHex(RIG_UI.bg);
3901
+ var PRELOADER_BACKDROP = RGBA7.fromHex(RIG_UI.bg);
4222
3902
  function inboxPendingCount(state) {
4223
3903
  const inbox = state.data.inbox;
4224
3904
  if (!inbox || typeof inbox !== "object" || Array.isArray(inbox))
@@ -4423,7 +4103,7 @@ function buildNavStrip(state) {
4423
4103
  chunks.push(otuiBold(styles.yellow(String(badgeCount))));
4424
4104
  }
4425
4105
  });
4426
- return new StyledText4(chunks);
4106
+ return new StyledText3(chunks);
4427
4107
  }
4428
4108
  function requestRender(renderer) {
4429
4109
  renderer.requestRender?.();
@@ -4652,7 +4332,8 @@ async function launchRigOpenTuiApp(options) {
4652
4332
  },
4653
4333
  suspend: () => renderer?.suspend(),
4654
4334
  resume: () => {
4655
- renderer?.resume();
4335
+ if (renderer)
4336
+ resumeRendererClean(renderer);
4656
4337
  renderApp();
4657
4338
  },
4658
4339
  destroy: () => renderer?.destroy()
@@ -4759,8 +4440,7 @@ async function launchRigOpenTuiApp(options) {
4759
4440
  } else if (!selectById(store, id, renderedSelectableItems)) {
4760
4441
  return;
4761
4442
  }
4762
- if (line2.activateOnClick)
4763
- runAppAction("Activate selection", () => activateSelection(runtime, renderedSelectableItems));
4443
+ runAppAction("Activate selection", () => activateSelection(runtime, renderedSelectableItems));
4764
4444
  };
4765
4445
  for (let index = 0;index < MAX_SCENE_PANELS; index += 1) {
4766
4446
  const panel = createScrollPanelLayer(renderer, `rig-scroll-panel-${index}`, onLineClick);
@@ -4827,6 +4507,7 @@ async function launchRigOpenTuiApp(options) {
4827
4507
  };
4828
4508
  renderer.keyInput.on("keypress", onKeyPress);
4829
4509
  resources.add(() => renderer?.keyInput.off("keypress", onKeyPress));
4510
+ resources.add(subscribeHover(() => scheduleAppRender(0)));
4830
4511
  const onPaste = (event) => {
4831
4512
  const state = store.getState();
4832
4513
  if (state.scene === "handoff") {