@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
@@ -1,6 +1,6 @@
1
1
  // @bun
2
2
  // packages/cli/src/app-opentui/react/App.tsx
3
- import { useMemo, useRef as useRef4 } from "react";
3
+ import { useMemo, useRef as useRef4, useSyncExternalStore as useSyncExternalStore2 } from "react";
4
4
  import { useKeyboard, useRenderer as useRenderer4, useTerminalDimensions as useTerminalDimensions2 } from "@opentui/react";
5
5
 
6
6
  // packages/cli/src/app-opentui/layout.ts
@@ -59,6 +59,7 @@ var RIG_UI = {
59
59
  bg2: "#0b0c0e",
60
60
  panel: "#101115",
61
61
  panel2: "#14161b",
62
+ hover: "#181b24",
62
63
  glass: "#1e2230",
63
64
  border: "#2a2e3a",
64
65
  ink: "#f4f5f8",
@@ -1783,395 +1784,10 @@ function intentFromTypeBar(value) {
1783
1784
  }
1784
1785
 
1785
1786
  // packages/cli/src/app-opentui/pi-pty-host.ts
1786
- import { fileURLToPath as fileURLToPath2 } from "url";
1787
- import { basename as basename2 } from "path";
1788
- import { RGBA as RGBA2, StyledText as StyledText2, TextAttributes as TextAttributes3 } from "@opentui/core";
1789
- import { Terminal as XtermTerminal2 } from "@xterm/headless";
1790
- var MIN_COLS2 = 40;
1791
- var MIN_ROWS2 = 12;
1792
- var MAX_ROWS2 = 300;
1793
- var MAX_SNAPSHOT_LINES2 = 360;
1794
- var STYLED_SNAPSHOT_MARGIN = 6;
1795
- var SNAPSHOT_DELAY_MS2 = 120;
1796
- var fallbackChildScriptPath = fileURLToPath2(new URL("./pi-host-child.ts", import.meta.url));
1797
- var activeHost2 = null;
1798
- function clampCols2(cols) {
1799
- return Math.max(MIN_COLS2, Math.trunc(cols || 100));
1800
- }
1801
- function clampRows2(rows) {
1802
- return Math.max(MIN_ROWS2, Math.min(MAX_ROWS2, Math.trunc(rows || 35)));
1803
- }
1804
- var XTERM_COLOR_MODE_INDEXED_16 = 16777216;
1805
- var XTERM_COLOR_MODE_INDEXED_256 = 33554432;
1806
- var XTERM_COLOR_MODE_RGB = 50331648;
1807
- function rgbaFromXtermColor(mode, value) {
1808
- if (mode === 1 || mode === 2 || mode === XTERM_COLOR_MODE_INDEXED_16 || mode === XTERM_COLOR_MODE_INDEXED_256) {
1809
- return RGBA2.fromIndex(value);
1810
- }
1811
- if (mode === 3 || mode === XTERM_COLOR_MODE_RGB) {
1812
- return RGBA2.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255);
1813
- }
1814
- return;
1815
- }
1816
- function textAttributesFromCell(cell) {
1817
- let attributes = TextAttributes3.NONE;
1818
- if (cell.isBold())
1819
- attributes |= TextAttributes3.BOLD;
1820
- if (cell.isDim())
1821
- attributes |= TextAttributes3.DIM;
1822
- if (cell.isItalic())
1823
- attributes |= TextAttributes3.ITALIC;
1824
- if (cell.isUnderline())
1825
- attributes |= TextAttributes3.UNDERLINE;
1826
- if (cell.isBlink())
1827
- attributes |= TextAttributes3.BLINK;
1828
- if (cell.isInverse())
1829
- attributes |= TextAttributes3.INVERSE;
1830
- if (cell.isInvisible())
1831
- attributes |= TextAttributes3.HIDDEN;
1832
- if (cell.isStrikethrough())
1833
- attributes |= TextAttributes3.STRIKETHROUGH;
1834
- return attributes;
1835
- }
1836
- function sameRgba(a, b) {
1837
- if (!a && !b)
1838
- return true;
1839
- return Boolean(a && b && a.equals(b));
1840
- }
1841
- function sameStyle(a, b) {
1842
- return sameRgba(a.fg, b.fg) && sameRgba(a.bg, b.bg) && (a.attributes ?? 0) === (b.attributes ?? 0);
1843
- }
1844
- function styleFromCell(cell) {
1845
- return {
1846
- fg: rgbaFromXtermColor(cell.getFgColorMode(), cell.getFgColor()),
1847
- bg: rgbaFromXtermColor(cell.getBgColorMode(), cell.getBgColor()),
1848
- attributes: textAttributesFromCell(cell)
1849
- };
1850
- }
1851
- function lineToStyledText(line2, cols) {
1852
- if (!line2)
1853
- return new StyledText2([{ __isChunk: true, text: "" }]);
1854
- const chunks = [];
1855
- let run = "";
1856
- let runStyle = null;
1857
- const flush = () => {
1858
- if (!run)
1859
- return;
1860
- chunks.push({
1861
- __isChunk: true,
1862
- text: run,
1863
- ...runStyle?.fg ? { fg: runStyle.fg } : {},
1864
- ...runStyle?.bg ? { bg: runStyle.bg } : {},
1865
- ...(runStyle?.attributes ?? 0) !== 0 ? { attributes: runStyle.attributes } : {}
1866
- });
1867
- run = "";
1868
- };
1869
- for (let index = 0;index < cols; index += 1) {
1870
- const cell = line2.getCell(index);
1871
- if (!cell) {
1872
- if (runStyle !== null)
1873
- flush();
1874
- runStyle = null;
1875
- run += " ";
1876
- continue;
1877
- }
1878
- if (cell.getWidth() === 0)
1879
- continue;
1880
- const style = styleFromCell(cell);
1881
- if (!runStyle || !sameStyle(runStyle, style)) {
1882
- flush();
1883
- runStyle = style;
1884
- }
1885
- run += cell.getChars() || " ";
1886
- }
1887
- flush();
1888
- return new StyledText2(chunks.length > 0 ? chunks : [{ __isChunk: true, text: "" }]);
1889
- }
1890
- function childCommandPrefix2() {
1891
- const execName = basename2(process.execPath).toLowerCase();
1892
- const currentEntry = process.argv[1];
1893
- if (execName === "bun" || execName === "bun.exe") {
1894
- return currentEntry ? [process.execPath, currentEntry, "__opentui-pi-host"] : [process.execPath, fallbackChildScriptPath];
1895
- }
1896
- return [process.execPath, "__opentui-pi-host"];
1897
- }
1898
- function withEnv2(base) {
1899
- const env = {};
1900
- for (const [key, value] of Object.entries(base ?? process.env)) {
1901
- if (key === "RIG_PLAIN" || key === "RIG_CLI_PLAIN_HELP" || key === "NO_COLOR")
1902
- continue;
1903
- if (typeof value === "string")
1904
- env[key] = value;
1905
- }
1906
- return {
1907
- ...env,
1908
- TERM: "xterm-256color",
1909
- COLORTERM: "truecolor",
1910
- FORCE_COLOR: env.FORCE_COLOR ?? "1",
1911
- RIG_OPENTUI_PI_HOST: "1"
1912
- };
1913
- }
1914
1787
  function getActivePiHost() {
1915
- return activeHost2 && !activeHost2.disposed ? activeHost2 : null;
1916
- }
1917
- function stopActivePiHost(reason = "detach") {
1918
- activeHost2?.dispose(reason);
1919
- activeHost2 = null;
1920
- }
1921
-
1922
- class PiPtyHost {
1923
- runId;
1924
- projectRoot;
1925
- onSnapshot;
1926
- onExit;
1927
- onError;
1928
- terminal;
1929
- disposables = [];
1930
- decoder = new TextDecoder("utf-8");
1931
- proc = null;
1932
- pty = null;
1933
- status = "starting";
1934
- cols;
1935
- rows;
1936
- message = "starting bundled Pi";
1937
- lastResizeError = null;
1938
- exitCode;
1939
- signal;
1940
- notifyTimer = null;
1941
- lastStreamKey = "";
1942
- _disposed = false;
1943
- constructor(options) {
1944
- this.runId = options.runId;
1945
- this.projectRoot = options.projectRoot;
1946
- this.cols = clampCols2(options.cols);
1947
- this.rows = clampRows2(options.rows);
1948
- this.onSnapshot = options.onSnapshot;
1949
- this.onExit = options.onExit;
1950
- this.onError = options.onError;
1951
- this.terminal = new XtermTerminal2({
1952
- allowProposedApi: true,
1953
- cols: this.cols,
1954
- rows: this.rows,
1955
- scrollback: 1000
1956
- });
1957
- this.registerTerminalResponders();
1958
- this.disposables.push(this.terminal.onWriteParsed(() => {
1959
- if (this._disposed)
1960
- return;
1961
- const snapshot = this.createSnapshot();
1962
- const key = snapshot.lines.join(`
1963
- `);
1964
- if (key === this.lastStreamKey)
1965
- return;
1966
- this.lastStreamKey = key;
1967
- this.onSnapshot?.(snapshot);
1968
- }));
1969
- }
1970
- get disposed() {
1971
- return this._disposed;
1972
- }
1973
- get snapshot() {
1974
- return this.createSnapshot();
1975
- }
1976
- async start() {
1977
- if (this._disposed)
1978
- throw new Error("Pi PTY host is disposed.");
1979
- if (typeof Bun.Terminal !== "function") {
1980
- throw new Error("Bun native PTY is unavailable in this runtime. Pi host requires Bun.Terminal.");
1981
- }
1982
- const spawnOptions = {
1983
- cwd: this.projectRoot,
1984
- env: withEnv2(process.env),
1985
- terminal: {
1986
- cols: this.cols,
1987
- rows: this.rows,
1988
- name: "xterm-256color",
1989
- data: (_terminal, data) => this.handlePtyData(data)
1990
- }
1991
- };
1992
- const proc = Bun.spawn([
1993
- ...childCommandPrefix2(),
1994
- "--run-id",
1995
- this.runId,
1996
- "--project-root",
1997
- this.projectRoot
1998
- ], spawnOptions);
1999
- if (!proc.terminal)
2000
- throw new Error("Bun did not attach a terminal to the bundled Pi child process.");
2001
- this.proc = proc;
2002
- this.pty = proc.terminal;
2003
- this.status = "running";
2004
- this.message = "bundled Pi running inside this app";
2005
- this.emitSnapshotSoon(0);
2006
- proc.exited.then((exitCode) => {
2007
- if (this._disposed)
2008
- return;
2009
- this.status = exitCode === 0 ? "exited" : "failed";
2010
- this.exitCode = exitCode;
2011
- this.signal = null;
2012
- this.message = exitCode === 0 ? "bundled Pi exited" : `bundled Pi exited with code ${exitCode}`;
2013
- const snapshot = this.createSnapshot();
2014
- this.onSnapshot?.(snapshot);
2015
- this.onExit?.(snapshot);
2016
- if (activeHost2 === this)
2017
- activeHost2 = null;
2018
- this.dispose("exit", { kill: false, notify: false });
2019
- }).catch((error) => {
2020
- if (this._disposed)
2021
- return;
2022
- this.status = "failed";
2023
- this.message = error instanceof Error ? error.message : String(error);
2024
- const snapshot = this.createSnapshot();
2025
- this.onSnapshot?.(snapshot);
2026
- this.onError?.(error, snapshot);
2027
- if (activeHost2 === this)
2028
- activeHost2 = null;
2029
- this.dispose("error", { kill: false, notify: false });
2030
- });
2031
- }
2032
- write(data) {
2033
- if (this._disposed || !this.pty)
2034
- return;
2035
- try {
2036
- this.pty.write(data);
2037
- } catch (error) {
2038
- this.status = "failed";
2039
- this.message = error instanceof Error ? error.message : String(error);
2040
- const snapshot = this.createSnapshot();
2041
- this.onSnapshot?.(snapshot);
2042
- this.onError?.(error, snapshot);
2043
- }
2044
- }
2045
- resize(cols, rows) {
2046
- const nextCols = clampCols2(cols);
2047
- const nextRows = clampRows2(rows);
2048
- if (nextCols === this.cols && nextRows === this.rows)
2049
- return;
2050
- this.cols = nextCols;
2051
- this.rows = nextRows;
2052
- this.terminal.resize(nextCols, nextRows);
2053
- try {
2054
- this.pty?.resize(nextCols, nextRows);
2055
- this.lastResizeError = null;
2056
- } catch (error) {
2057
- this.lastResizeError = error instanceof Error ? error.message : String(error);
2058
- }
2059
- this.emitSnapshotSoon(0);
2060
- }
2061
- detach() {
2062
- this.dispose("detach");
2063
- return this.createSnapshot("detached from bundled Pi");
2064
- }
2065
- dispose(reason = "dispose", options = {}) {
2066
- if (this._disposed)
2067
- return;
2068
- this._disposed = true;
2069
- if (this.notifyTimer)
2070
- clearTimeout(this.notifyTimer);
2071
- this.notifyTimer = null;
2072
- for (const disposable of this.disposables.splice(0)) {
2073
- try {
2074
- disposable.dispose();
2075
- } catch {}
2076
- }
2077
- if (options.kill !== false) {
2078
- try {
2079
- this.proc?.kill("SIGTERM");
2080
- } catch {}
2081
- }
2082
- try {
2083
- this.pty?.close();
2084
- } catch {}
2085
- try {
2086
- this.terminal.dispose();
2087
- } catch {}
2088
- if (activeHost2 === this)
2089
- activeHost2 = null;
2090
- if (options.notify) {
2091
- this.message = reason;
2092
- this.onSnapshot?.(this.createSnapshot(reason));
2093
- }
2094
- }
2095
- handlePtyData(data) {
2096
- if (this._disposed)
2097
- return;
2098
- const text = this.decoder.decode(data, { stream: true });
2099
- this.respondToRawTerminalQueries(text);
2100
- this.terminal.write(data);
2101
- }
2102
- emitSnapshotSoon(delayMs = SNAPSHOT_DELAY_MS2) {
2103
- if (this._disposed || this.notifyTimer)
2104
- return;
2105
- this.notifyTimer = setTimeout(() => {
2106
- this.notifyTimer = null;
2107
- if (this._disposed)
2108
- return;
2109
- this.onSnapshot?.(this.createSnapshot());
2110
- }, delayMs);
2111
- }
2112
- createSnapshot(message = this.message) {
2113
- const buffer = this.terminal.buffer.active;
2114
- const end = buffer.length;
2115
- const start = Math.max(0, end - MAX_SNAPSHOT_LINES2);
2116
- const styledStart = Math.max(start, end - this.rows - STYLED_SNAPSHOT_MARGIN);
2117
- const lines = [];
2118
- const styledLines = [];
2119
- for (let row = start;row < end; row += 1) {
2120
- const line2 = buffer.getLine(row);
2121
- lines.push((line2?.translateToString(false) ?? "").slice(0, this.cols));
2122
- if (row >= styledStart)
2123
- styledLines[lines.length - 1] = lineToStyledText(line2, this.cols);
2124
- }
2125
- while (lines.length < this.rows) {
2126
- lines.push("");
2127
- styledLines[lines.length - 1] = new StyledText2([{ __isChunk: true, text: "" }]);
2128
- }
2129
- const resolvedMessage = this.lastResizeError ? `resize degraded: ${this.lastResizeError}` : message;
2130
- return {
2131
- runId: this.runId,
2132
- status: this.status,
2133
- cols: this.cols,
2134
- rows: this.rows,
2135
- lines,
2136
- styledLines,
2137
- message: resolvedMessage,
2138
- ...this.lastResizeError ? { resizeError: this.lastResizeError } : {},
2139
- ...this.exitCode !== undefined ? { exitCode: this.exitCode } : {},
2140
- ...this.signal !== undefined ? { signal: this.signal } : {}
2141
- };
2142
- }
2143
- registerTerminalResponders() {
2144
- this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "c" }, (params) => {
2145
- if (params.length === 0 || params[0] === 0)
2146
- this.write("\x1B[?62;22c");
2147
- return false;
2148
- }));
2149
- this.disposables.push(this.terminal.parser.registerCsiHandler({ prefix: ">", final: "c" }, (params) => {
2150
- if (params.length === 0 || params[0] === 0)
2151
- this.write("\x1B[>0;0;0c");
2152
- return false;
2153
- }));
2154
- this.disposables.push(this.terminal.parser.registerCsiHandler({ final: "n" }, (params) => {
2155
- if (params[0] === 5) {
2156
- this.write("\x1B[0n");
2157
- } else if (params[0] === 6) {
2158
- const row = this.terminal.buffer.active.cursorY + 1;
2159
- const col = this.terminal.buffer.active.cursorX + 1;
2160
- this.write(`\x1B[${row};${col}R`);
2161
- }
2162
- return false;
2163
- }));
2164
- }
2165
- respondToRawTerminalQueries(text) {
2166
- if (!text)
2167
- return;
2168
- const decrqm = /\x1b\[\?(\d+)\$p/g;
2169
- let match;
2170
- while ((match = decrqm.exec(text)) !== null) {
2171
- this.write(`\x1B[?${match[1]};2$y`);
2172
- }
2173
- }
1788
+ return null;
2174
1789
  }
1790
+ function stopActivePiHost(_reason) {}
2175
1791
 
2176
1792
  // packages/cli/src/app-opentui/keymap.ts
2177
1793
  var autocompleteState;
@@ -2403,7 +2019,7 @@ function handleAppKeyPress(context, key) {
2403
2019
  }
2404
2020
 
2405
2021
  // packages/cli/src/app-opentui/runtime.ts
2406
- import { BoxRenderable as BoxRenderable3, RGBA as RGBA8, StyledText as StyledText4, TextRenderable as TextRenderable4, createCliRenderer } from "@opentui/core";
2022
+ import { BoxRenderable as BoxRenderable3, RGBA as RGBA7, StyledText as StyledText3, TextRenderable as TextRenderable4, createCliRenderer } from "@opentui/core";
2407
2023
 
2408
2024
  // packages/cli/src/commands/_server-events.ts
2409
2025
  import { WsTransport } from "@rig/client";
@@ -2432,7 +2048,7 @@ var RESUMABLE_RUN_STATUSES = new Set([
2432
2048
  ]);
2433
2049
 
2434
2050
  // packages/cli/src/app-opentui/render/graphics.ts
2435
- import { FrameBufferRenderable, RGBA as RGBA3 } from "@opentui/core";
2051
+ import { FrameBufferRenderable, RGBA as RGBA2 } from "@opentui/core";
2436
2052
 
2437
2053
  // packages/cli/src/app-opentui/render/ascii-fleet.ts
2438
2054
  var LEAD_DRONE = [
@@ -2576,13 +2192,13 @@ var GLOW_FALLOFF_EXP_ASCII = 2.2;
2576
2192
  // packages/cli/src/app-opentui/render/graphics.ts
2577
2193
  var BRAILLE_SAMPLES_X = 2;
2578
2194
  var BRAILLE_SAMPLES_Y = 4;
2579
- var TRANSPARENT = RGBA3.fromValues(0, 0, 0, 0);
2580
- var BACKDROP = RGBA3.fromHex(RIG_UI.bg);
2581
- var PANEL_BG = RGBA3.fromInts(16, 17, 21, 184);
2582
- var PANEL_HEADER_BG = RGBA3.fromInts(16, 17, 21, 188);
2583
- var PANEL_LINE = RGBA3.fromInts(255, 255, 255, 20);
2584
- var PANEL_LINE_DIM = RGBA3.fromInts(255, 255, 255, 8);
2585
- var PANEL_TEXT_DIM = RGBA3.fromInts(108, 110, 121, 255);
2195
+ var TRANSPARENT = RGBA2.fromValues(0, 0, 0, 0);
2196
+ var BACKDROP = RGBA2.fromHex(RIG_UI.bg);
2197
+ var PANEL_BG = RGBA2.fromInts(16, 17, 21, 184);
2198
+ var PANEL_HEADER_BG = RGBA2.fromInts(16, 17, 21, 188);
2199
+ var PANEL_LINE = RGBA2.fromInts(255, 255, 255, 20);
2200
+ var PANEL_LINE_DIM = RGBA2.fromInts(255, 255, 255, 8);
2201
+ var PANEL_TEXT_DIM = RGBA2.fromInts(108, 110, 121, 255);
2586
2202
  var AC_RGB = [204, 255, 77];
2587
2203
  var C2_RGB = [86, 216, 255];
2588
2204
  var MG_RGB = [255, 121, 176];
@@ -2687,7 +2303,7 @@ function paletteColor(ac, c2, mg, ink) {
2687
2303
  const b = (AC_RGB[2] * ac + C2_RGB[2] * c2 + MG_RGB[2] * mg + INK_RGB[2] * ink) / total;
2688
2304
  const intensity = Math.min(1, total / 4);
2689
2305
  const lift = 0.34 + intensity * 0.66;
2690
- return RGBA3.fromInts(Math.round(r * lift), Math.round(g * lift), Math.round(b * lift), 255);
2306
+ return RGBA2.fromInts(Math.round(r * lift), Math.round(g * lift), Math.round(b * lift), 255);
2691
2307
  }
2692
2308
  function clearCanvas(canvas) {
2693
2309
  canvas.ac.fill(0);
@@ -3042,8 +2658,8 @@ function staticFleetTick(scene) {
3042
2658
  }
3043
2659
  function withAlpha(hex, alpha) {
3044
2660
  const a = Math.max(0, Math.min(255, Math.round(alpha * 255)));
3045
- const [r, g, b] = RGBA3.fromHex(hex).toInts();
3046
- return RGBA3.fromInts(r, g, b, a);
2661
+ const [r, g, b] = RGBA2.fromHex(hex).toInts();
2662
+ return RGBA2.fromInts(r, g, b, a);
3047
2663
  }
3048
2664
  function asciiFleetColor(char, row, alpha) {
3049
2665
  if (char === "@" || char === "$" || char === "o")
@@ -3051,7 +2667,7 @@ function asciiFleetColor(char, row, alpha) {
3051
2667
  if (char === "%" || char === "!" || char === "/" || char === "\\" || char === "|")
3052
2668
  return withAlpha(RIG_UI.cyan, alpha);
3053
2669
  if (char === "." || char === "'" || char === "_" || row < 3 || row > FLEET_GRID_HEIGHT - 4) {
3054
- return RGBA3.fromInts(108, 110, 121, Math.min(170, Math.max(0, Math.min(255, Math.round(alpha * 255)))));
2670
+ return RGBA2.fromInts(108, 110, 121, Math.min(170, Math.max(0, Math.min(255, Math.round(alpha * 255)))));
3055
2671
  }
3056
2672
  return withAlpha(RIG_UI.limeDim, alpha);
3057
2673
  }
@@ -3103,16 +2719,70 @@ function drawAmbientField(layer, layout, _tick, scene = "fleet", load = 0, activ
3103
2719
  }
3104
2720
 
3105
2721
  // packages/cli/src/app-opentui/render/text.ts
3106
- import { RGBA as RGBA4, TextAttributes as TextAttributes4, TextRenderable } from "@opentui/core";
3107
- var TRANSPARENT2 = RGBA4.fromInts(0, 0, 0, 0);
2722
+ import { RGBA as RGBA3, TextAttributes as TextAttributes3, TextRenderable } from "@opentui/core";
2723
+
2724
+ // packages/cli/src/app-opentui/render/hover.ts
2725
+ var hoveredId;
2726
+ var listeners = new Set;
2727
+ function getHoveredSelectableId() {
2728
+ return hoveredId;
2729
+ }
2730
+ function isHovered(id) {
2731
+ return id !== undefined && id === hoveredId;
2732
+ }
2733
+ function setHoveredSelectableId(id) {
2734
+ if (hoveredId === id)
2735
+ return;
2736
+ hoveredId = id;
2737
+ for (const listener of listeners)
2738
+ listener();
2739
+ }
2740
+ function clearHoveredSelectableId(id) {
2741
+ if (id !== undefined && hoveredId === id)
2742
+ setHoveredSelectableId(undefined);
2743
+ }
2744
+ function subscribeHover(listener) {
2745
+ listeners.add(listener);
2746
+ return () => {
2747
+ listeners.delete(listener);
2748
+ };
2749
+ }
2750
+
2751
+ // packages/cli/src/app-opentui/render/text.ts
2752
+ var TRANSPARENT2 = RGBA3.fromInts(0, 0, 0, 0);
2753
+ var HOVER_BG = RGBA3.fromHex(RIG_UI.hover);
2754
+ function lineIsClickable(line2) {
2755
+ return line2?.selectable !== undefined || line2?.selectableIndex !== undefined;
2756
+ }
2757
+ function lineSelectableId(line2) {
2758
+ return line2?.selectable?.id ?? line2?.selectableId;
2759
+ }
2760
+ function lineBackground(line2) {
2761
+ if (line2?.bg)
2762
+ return RGBA3.fromHex(line2.bg);
2763
+ const id = lineSelectableId(line2);
2764
+ if (id !== undefined && isHovered(id))
2765
+ return HOVER_BG;
2766
+ return TRANSPARENT2;
2767
+ }
3108
2768
  function selectableMouseHandler(currentLineRef, onLineMouseDown) {
3109
2769
  return (event) => {
3110
2770
  const currentLine = currentLineRef();
3111
- if (currentLine?.selectableIndex === undefined)
2771
+ if (!lineIsClickable(currentLine))
3112
2772
  return;
3113
2773
  onLineMouseDown?.(currentLine, event);
3114
2774
  };
3115
2775
  }
2776
+ function hoverHandlers(currentLineRef) {
2777
+ return {
2778
+ onMouseOver: () => {
2779
+ const id = lineSelectableId(currentLineRef());
2780
+ if (id !== undefined)
2781
+ setHoveredSelectableId(id);
2782
+ },
2783
+ onMouseOut: () => clearHoveredSelectableId(lineSelectableId(currentLineRef()))
2784
+ };
2785
+ }
3116
2786
  function createFlowTextLine(renderer, id, onLineMouseDown) {
3117
2787
  let currentLine;
3118
2788
  const renderable = new TextRenderable(renderer, {
@@ -3123,7 +2793,8 @@ function createFlowTextLine(renderer, id, onLineMouseDown) {
3123
2793
  flexShrink: 0,
3124
2794
  fg: RIG_UI.ink2,
3125
2795
  selectable: true,
3126
- onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown)
2796
+ onMouseDown: selectableMouseHandler(() => currentLine, onLineMouseDown),
2797
+ ...hoverHandlers(() => currentLine)
3127
2798
  });
3128
2799
  renderable.setRigSceneLine = (line2) => {
3129
2800
  currentLine = line2;
@@ -3137,13 +2808,13 @@ function applyFlowTextLine(renderable, line2, width) {
3137
2808
  renderable.width = Math.max(1, width);
3138
2809
  renderable.content = line2?.styledText ?? line2?.text ?? "";
3139
2810
  renderable.fg = line2?.fg ?? RIG_UI.ink2;
3140
- renderable.bg = line2?.bg ?? TRANSPARENT2;
3141
- renderable.attributes = line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
2811
+ renderable.bg = lineBackground(line2);
2812
+ renderable.attributes = line2?.bold ? TextAttributes3.BOLD : line2?.dim ? TextAttributes3.DIM : 0;
3142
2813
  }
3143
2814
 
3144
2815
  // packages/cli/src/app-opentui/render/panels.ts
3145
- import { RGBA as RGBA5, ScrollBoxRenderable } from "@opentui/core";
3146
- var TRANSPARENT3 = RGBA5.fromInts(0, 0, 0, 0);
2816
+ import { RGBA as RGBA4, ScrollBoxRenderable } from "@opentui/core";
2817
+ var TRANSPARENT3 = RGBA4.fromInts(0, 0, 0, 0);
3147
2818
  var MAX_PANEL_LINES = 420;
3148
2819
  var PANEL_OPAQUE_ALPHA = 255;
3149
2820
  var PANEL_BORDER = hexToRgba(RIG_UI.border, 255);
@@ -3152,8 +2823,8 @@ function hexToRgba(hex, alpha) {
3152
2823
  const full = clean.length === 3 ? clean.split("").map((part) => `${part}${part}`).join("") : clean;
3153
2824
  const value = Number.parseInt(full, 16);
3154
2825
  if (!Number.isFinite(value))
3155
- return RGBA5.fromInts(14, 15, 17, alpha);
3156
- return RGBA5.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255, alpha);
2826
+ return RGBA4.fromInts(14, 15, 17, alpha);
2827
+ return RGBA4.fromInts(value >> 16 & 255, value >> 8 & 255, value & 255, alpha);
3157
2828
  }
3158
2829
  function panelBackground(panel) {
3159
2830
  return hexToRgba(panel.backgroundColor ?? RIG_UI.panel, PANEL_OPAQUE_ALPHA);
@@ -3268,9 +2939,9 @@ function applyScrollPanels(panels, layout, scenePanels) {
3268
2939
  }
3269
2940
 
3270
2941
  // packages/cli/src/app-opentui/render/type-bar.ts
3271
- import { BoxRenderable, InputRenderable, InputRenderableEvents, RGBA as RGBA6, StyledText as StyledText3, TextRenderable as TextRenderable2 } from "@opentui/core";
3272
- var TYPEBAR_BG = RGBA6.fromInts(20, 25, 14, 224);
3273
- var TYPEBAR_BORDER = RGBA6.fromInts(204, 255, 77, 92);
2942
+ import { BoxRenderable, InputRenderable, InputRenderableEvents, RGBA as RGBA5, StyledText as StyledText2, TextRenderable as TextRenderable2 } from "@opentui/core";
2943
+ var TYPEBAR_BG = RGBA5.fromInts(20, 25, 14, 224);
2944
+ var TYPEBAR_BORDER = RGBA5.fromInts(204, 255, 77, 92);
3274
2945
  function createTypeBar(renderer) {
3275
2946
  const background = new BoxRenderable(renderer, {
3276
2947
  id: "typebar-card",
@@ -3418,7 +3089,7 @@ function formatFooter(footer, width) {
3418
3089
  chunks.push(cell.style(text));
3419
3090
  used += visibleWidth(text);
3420
3091
  });
3421
- return new StyledText3(chunks);
3092
+ return new StyledText2(chunks);
3422
3093
  }
3423
3094
 
3424
3095
  // packages/cli/src/app-opentui/render/native-host.ts
@@ -3426,7 +3097,7 @@ import {
3426
3097
  BoxRenderable as BoxRenderable2,
3427
3098
  CodeRenderable,
3428
3099
  DiffRenderable,
3429
- RGBA as RGBA7,
3100
+ RGBA as RGBA6,
3430
3101
  ScrollBoxRenderable as ScrollBoxRenderable2,
3431
3102
  SyntaxStyle,
3432
3103
  TextRenderable as TextRenderable3,
@@ -3437,19 +3108,19 @@ function rigSyntaxStyle() {
3437
3108
  if (syntaxStyle)
3438
3109
  return syntaxStyle;
3439
3110
  syntaxStyle = SyntaxStyle.fromStyles({
3440
- keyword: { fg: RGBA7.fromHex(RIG_UI.magenta), bold: true },
3441
- string: { fg: RGBA7.fromHex(RIG_UI.lime) },
3442
- number: { fg: RGBA7.fromHex(RIG_UI.cyan) },
3443
- comment: { fg: RGBA7.fromHex(RIG_UI.ink4), italic: true },
3444
- function: { fg: RGBA7.fromHex(RIG_UI.cyan) },
3445
- type: { fg: RGBA7.fromHex(RIG_UI.limeDim) },
3446
- constant: { fg: RGBA7.fromHex(RIG_UI.yellow) },
3447
- default: { fg: RGBA7.fromHex(RIG_UI.ink2) }
3111
+ keyword: { fg: RGBA6.fromHex(RIG_UI.magenta), bold: true },
3112
+ string: { fg: RGBA6.fromHex(RIG_UI.lime) },
3113
+ number: { fg: RGBA6.fromHex(RIG_UI.cyan) },
3114
+ comment: { fg: RGBA6.fromHex(RIG_UI.ink4), italic: true },
3115
+ function: { fg: RGBA6.fromHex(RIG_UI.cyan) },
3116
+ type: { fg: RGBA6.fromHex(RIG_UI.limeDim) },
3117
+ constant: { fg: RGBA6.fromHex(RIG_UI.yellow) },
3118
+ default: { fg: RGBA6.fromHex(RIG_UI.ink2) }
3448
3119
  });
3449
3120
  return syntaxStyle;
3450
3121
  }
3451
3122
  function tableContent(rows) {
3452
- return rows.map((row, rowIndex) => row.map((cell) => [{ __isChunk: true, text: cell, fg: RGBA7.fromHex(rowIndex === 0 ? RIG_UI.ink3 : RIG_UI.ink2) }]));
3123
+ return rows.map((row, rowIndex) => row.map((cell) => [{ __isChunk: true, text: cell, fg: RGBA6.fromHex(rowIndex === 0 ? RIG_UI.ink3 : RIG_UI.ink2) }]));
3453
3124
  }
3454
3125
  function createNativeHost(renderer) {
3455
3126
  try {
@@ -3548,7 +3219,7 @@ function destroyNativeHost(host) {
3548
3219
  }
3549
3220
 
3550
3221
  // packages/cli/src/app-opentui/runtime.ts
3551
- var PRELOADER_BACKDROP = RGBA8.fromHex(RIG_UI.bg);
3222
+ var PRELOADER_BACKDROP = RGBA7.fromHex(RIG_UI.bg);
3552
3223
  function inboxPendingCount(state) {
3553
3224
  const inbox = state.data.inbox;
3554
3225
  if (!inbox || typeof inbox !== "object" || Array.isArray(inbox))
@@ -3645,7 +3316,7 @@ function buildNavStrip(state) {
3645
3316
  chunks.push(otuiBold(styles.yellow(String(badgeCount))));
3646
3317
  }
3647
3318
  });
3648
- return new StyledText4(chunks);
3319
+ return new StyledText3(chunks);
3649
3320
  }
3650
3321
  function renderedItemsOrStateItems(_state, renderedItems) {
3651
3322
  return renderedItems ? [...renderedItems] : [];
@@ -3781,7 +3452,7 @@ function Backdrop(props) {
3781
3452
  // packages/cli/src/app-opentui/react/SceneFrameView.tsx
3782
3453
  import { useEffect as useEffect2, useRef as useRef2 } from "react";
3783
3454
  import { useRenderer as useRenderer2 } from "@opentui/react";
3784
- import { TextAttributes as TextAttributes5 } from "@opentui/core";
3455
+ import { TextAttributes as TextAttributes4 } from "@opentui/core";
3785
3456
 
3786
3457
  // packages/cli/src/app-opentui/react/scroll.ts
3787
3458
  var registries = new Set;
@@ -3803,20 +3474,23 @@ function scrollActiveBody(delta) {
3803
3474
  // packages/cli/src/app-opentui/react/SceneFrameView.tsx
3804
3475
  import { jsxDEV, Fragment } from "@opentui/react/jsx-dev-runtime";
3805
3476
  function lineAttributes(line2) {
3806
- return line2?.bold ? TextAttributes5.BOLD : line2?.dim ? TextAttributes5.DIM : 0;
3477
+ return line2?.bold ? TextAttributes4.BOLD : line2?.dim ? TextAttributes4.DIM : 0;
3807
3478
  }
3808
3479
  function lineContent(line2) {
3809
3480
  return line2.styledText ?? line2.text ?? "";
3810
3481
  }
3811
3482
  function LineView(props) {
3812
3483
  const { line: line2, onLineClick } = props;
3484
+ const id = lineSelectableId(line2);
3813
3485
  return /* @__PURE__ */ jsxDEV("text", {
3814
3486
  style: { position: "absolute", left: props.left, top: props.top, width: props.width, zIndex: 5 },
3815
3487
  fg: line2.fg ?? RIG_UI.ink2,
3816
- bg: line2.bg ?? TRANSPARENT2,
3488
+ bg: lineBackground(line2),
3817
3489
  attributes: lineAttributes(line2),
3818
3490
  content: lineContent(line2),
3819
- onMouseDown: onLineClick ? () => onLineClick(line2) : undefined
3491
+ onMouseDown: onLineClick ? () => onLineClick(line2) : undefined,
3492
+ onMouseOver: id !== undefined ? () => setHoveredSelectableId(id) : undefined,
3493
+ onMouseOut: id !== undefined ? () => clearHoveredSelectableId(id) : undefined
3820
3494
  }, undefined, false, undefined, this);
3821
3495
  }
3822
3496
  function PanelHost(props) {
@@ -4052,6 +3726,7 @@ function App(props) {
4052
3726
  const runAppAction = useRunAppAction();
4053
3727
  const store = useStore();
4054
3728
  const renderer = useRenderer4();
3729
+ useSyncExternalStore2(subscribeHover, getHoveredSelectableId, getHoveredSelectableId);
4055
3730
  const dims = useTerminalDimensions2();
4056
3731
  const layout = computeStageLayout(dims.width, dims.height);
4057
3732
  const registry = useMemo(() => ({ ...BUILTIN, ...props.sceneRenderers ?? {} }), [props.sceneRenderers]);
@@ -4086,8 +3761,7 @@ function App(props) {
4086
3761
  } else {
4087
3762
  return;
4088
3763
  }
4089
- if (line2.activateOnClick)
4090
- runAppAction("Activate selection", () => activateSelection(runtime, items));
3764
+ runAppAction("Activate selection", () => activateSelection(runtime, items));
4091
3765
  };
4092
3766
  return /* @__PURE__ */ jsxDEV3("box", {
4093
3767
  style: { position: "absolute", left: 0, top: 0, width: "100%", height: "100%" },