@h-rig/cli 0.0.6-alpha.8 → 0.0.6-alpha.81

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 (198) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/build-rig-binaries.d.ts +2 -0
  3. package/dist/bin/rig.d.ts +2 -0
  4. package/dist/bin/rig.js +18374 -8205
  5. package/dist/src/app/board.d.ts +23 -0
  6. package/dist/src/app/board.js +1815 -0
  7. package/dist/src/app/drone-ui.d.ts +37 -0
  8. package/dist/src/app/drone-ui.js +294 -0
  9. package/dist/src/app/theme.d.ts +47 -0
  10. package/dist/src/app/theme.js +151 -0
  11. package/dist/src/app-opentui/adapters/common.d.ts +53 -0
  12. package/dist/src/app-opentui/adapters/common.js +149 -0
  13. package/dist/src/app-opentui/adapters/doctor.d.ts +11 -0
  14. package/dist/src/app-opentui/adapters/doctor.js +780 -0
  15. package/dist/src/app-opentui/adapters/fleet.d.ts +16 -0
  16. package/dist/src/app-opentui/adapters/fleet.js +874 -0
  17. package/dist/src/app-opentui/adapters/inbox.d.ts +33 -0
  18. package/dist/src/app-opentui/adapters/inbox.js +1454 -0
  19. package/dist/src/app-opentui/adapters/init.d.ts +13 -0
  20. package/dist/src/app-opentui/adapters/init.js +2357 -0
  21. package/dist/src/app-opentui/adapters/pi-attach.d.ts +16 -0
  22. package/dist/src/app-opentui/adapters/pi-attach.js +1295 -0
  23. package/dist/src/app-opentui/adapters/run-detail.d.ts +20 -0
  24. package/dist/src/app-opentui/adapters/run-detail.js +893 -0
  25. package/dist/src/app-opentui/adapters/server.d.ts +14 -0
  26. package/dist/src/app-opentui/adapters/server.js +798 -0
  27. package/dist/src/app-opentui/adapters/tasks.d.ts +55 -0
  28. package/dist/src/app-opentui/adapters/tasks.js +3472 -0
  29. package/dist/src/app-opentui/bootstrap.d.ts +16 -0
  30. package/dist/src/app-opentui/bootstrap.js +19509 -0
  31. package/dist/src/app-opentui/drone.d.ts +12 -0
  32. package/dist/src/app-opentui/drone.js +227 -0
  33. package/dist/src/app-opentui/events.d.ts +7 -0
  34. package/dist/src/app-opentui/events.js +28 -0
  35. package/dist/src/app-opentui/index.d.ts +8 -0
  36. package/dist/src/app-opentui/index.js +3477 -0
  37. package/dist/src/app-opentui/intent.d.ts +3 -0
  38. package/dist/src/app-opentui/intent.js +211 -0
  39. package/dist/src/app-opentui/layout.d.ts +15 -0
  40. package/dist/src/app-opentui/layout.js +44 -0
  41. package/dist/src/app-opentui/list-search.d.ts +8 -0
  42. package/dist/src/app-opentui/list-search.js +43 -0
  43. package/dist/src/app-opentui/pi-host-child.d.ts +2 -0
  44. package/dist/src/app-opentui/pi-host-child.js +778 -0
  45. package/dist/src/app-opentui/pi-pty-host.d.ts +64 -0
  46. package/dist/src/app-opentui/pi-pty-host.js +384 -0
  47. package/dist/src/app-opentui/registry.d.ts +4 -0
  48. package/dist/src/app-opentui/registry.js +6835 -0
  49. package/dist/src/app-opentui/render/graphics.d.ts +39 -0
  50. package/dist/src/app-opentui/render/graphics.js +537 -0
  51. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +2 -0
  52. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +1480 -0
  53. package/dist/src/app-opentui/render/image-visual-layer-worker.d.ts +1 -0
  54. package/dist/src/app-opentui/render/image-visual-layer-worker.js +1541 -0
  55. package/dist/src/app-opentui/render/image-visual-layer.d.ts +93 -0
  56. package/dist/src/app-opentui/render/image-visual-layer.js +945 -0
  57. package/dist/src/app-opentui/render/panels.d.ts +10 -0
  58. package/dist/src/app-opentui/render/panels.js +201 -0
  59. package/dist/src/app-opentui/render/scene.d.ts +16 -0
  60. package/dist/src/app-opentui/render/scene.js +110 -0
  61. package/dist/src/app-opentui/render/text.d.ts +10 -0
  62. package/dist/src/app-opentui/render/text.js +121 -0
  63. package/dist/src/app-opentui/render/type-bar.d.ts +14 -0
  64. package/dist/src/app-opentui/render/type-bar.js +137 -0
  65. package/dist/src/app-opentui/runtime.d.ts +2 -0
  66. package/dist/src/app-opentui/runtime.js +3406 -0
  67. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -0
  68. package/dist/src/app-opentui/scenes/doctor.js +91 -0
  69. package/dist/src/app-opentui/scenes/error.d.ts +2 -0
  70. package/dist/src/app-opentui/scenes/error.js +190 -0
  71. package/dist/src/app-opentui/scenes/fleet.d.ts +3 -0
  72. package/dist/src/app-opentui/scenes/fleet.js +207 -0
  73. package/dist/src/app-opentui/scenes/handoff.d.ts +2 -0
  74. package/dist/src/app-opentui/scenes/handoff.js +147 -0
  75. package/dist/src/app-opentui/scenes/help.d.ts +3 -0
  76. package/dist/src/app-opentui/scenes/help.js +138 -0
  77. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -0
  78. package/dist/src/app-opentui/scenes/inbox.js +118 -0
  79. package/dist/src/app-opentui/scenes/init.d.ts +2 -0
  80. package/dist/src/app-opentui/scenes/init.js +94 -0
  81. package/dist/src/app-opentui/scenes/main.d.ts +2 -0
  82. package/dist/src/app-opentui/scenes/main.js +96 -0
  83. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -0
  84. package/dist/src/app-opentui/scenes/run-detail.js +139 -0
  85. package/dist/src/app-opentui/scenes/server.d.ts +2 -0
  86. package/dist/src/app-opentui/scenes/server.js +88 -0
  87. package/dist/src/app-opentui/scenes/tasks.d.ts +3 -0
  88. package/dist/src/app-opentui/scenes/tasks.js +230 -0
  89. package/dist/src/app-opentui/state.d.ts +4 -0
  90. package/dist/src/app-opentui/state.js +286 -0
  91. package/dist/src/app-opentui/theme.d.ts +36 -0
  92. package/dist/src/app-opentui/theme.js +88 -0
  93. package/dist/src/app-opentui/types.d.ts +188 -0
  94. package/dist/src/app-opentui/types.js +1 -0
  95. package/dist/src/commands/_async-ui.d.ts +13 -0
  96. package/dist/src/commands/_async-ui.js +223 -0
  97. package/dist/src/commands/_authority-runs.d.ts +22 -0
  98. package/dist/src/commands/_authority-runs.js +2 -3
  99. package/dist/src/commands/_cli-format.d.ts +49 -0
  100. package/dist/src/commands/_cli-format.js +447 -0
  101. package/dist/src/commands/_connection-state.d.ts +44 -0
  102. package/dist/src/commands/_connection-state.js +30 -11
  103. package/dist/src/commands/_doctor-checks.d.ts +52 -0
  104. package/dist/src/commands/_doctor-checks.js +180 -44
  105. package/dist/src/commands/_help-catalog.d.ts +51 -0
  106. package/dist/src/commands/_help-catalog.js +442 -0
  107. package/dist/src/commands/_json-output.d.ts +11 -0
  108. package/dist/src/commands/_json-output.js +56 -0
  109. package/dist/src/commands/_operator-surface.d.ts +34 -0
  110. package/dist/src/commands/_operator-surface.js +220 -0
  111. package/dist/src/commands/_operator-view.d.ts +30 -0
  112. package/dist/src/commands/_operator-view.js +803 -73
  113. package/dist/src/commands/_parsers.d.ts +15 -0
  114. package/dist/src/commands/_parsers.js +18 -11
  115. package/dist/src/commands/_paths.d.ts +11 -0
  116. package/dist/src/commands/_pi-frontend.d.ts +27 -0
  117. package/dist/src/commands/_pi-frontend.js +742 -0
  118. package/dist/src/commands/_pi-install.d.ts +42 -0
  119. package/dist/src/commands/_pi-install.js +5 -4
  120. package/dist/src/commands/_policy.d.ts +8 -0
  121. package/dist/src/commands/_policy.js +12 -5
  122. package/dist/src/commands/_preflight.d.ts +22 -0
  123. package/dist/src/commands/_preflight.js +190 -128
  124. package/dist/src/commands/_probes.d.ts +1 -0
  125. package/dist/src/commands/_run-driver-helpers.d.ts +99 -0
  126. package/dist/src/commands/_run-driver-helpers.js +75 -22
  127. package/dist/src/commands/_run-replay.d.ts +24 -0
  128. package/dist/src/commands/_run-replay.js +142 -0
  129. package/dist/src/commands/_server-client.d.ts +186 -0
  130. package/dist/src/commands/_server-client.js +360 -61
  131. package/dist/src/commands/_snapshot-upload.d.ts +39 -0
  132. package/dist/src/commands/_snapshot-upload.js +163 -39
  133. package/dist/src/commands/_spinner.d.ts +25 -0
  134. package/dist/src/commands/_spinner.js +65 -0
  135. package/dist/src/commands/_task-picker.d.ts +9 -0
  136. package/dist/src/commands/_task-picker.js +172 -19
  137. package/dist/src/commands/agent.d.ts +3 -0
  138. package/dist/src/commands/agent.js +39 -20
  139. package/dist/src/commands/browser.d.ts +65 -0
  140. package/dist/src/commands/browser.js +334 -51
  141. package/dist/src/commands/connect.d.ts +7 -0
  142. package/dist/src/commands/connect.js +272 -33
  143. package/dist/src/commands/dist.d.ts +28 -0
  144. package/dist/src/commands/dist.js +19 -12
  145. package/dist/src/commands/doctor.d.ts +3 -0
  146. package/dist/src/commands/doctor.js +378 -45
  147. package/dist/src/commands/github.d.ts +3 -0
  148. package/dist/src/commands/github.js +375 -53
  149. package/dist/src/commands/inbox.d.ts +30 -0
  150. package/dist/src/commands/inbox.js +760 -70
  151. package/dist/src/commands/init.d.ts +74 -0
  152. package/dist/src/commands/init.js +963 -119
  153. package/dist/src/commands/inspect.d.ts +3 -0
  154. package/dist/src/commands/inspect.js +588 -32
  155. package/dist/src/commands/inspector.d.ts +3 -0
  156. package/dist/src/commands/inspector.js +20 -13
  157. package/dist/src/commands/pi.d.ts +3 -0
  158. package/dist/src/commands/pi.js +177 -0
  159. package/dist/src/commands/plugin.d.ts +16 -0
  160. package/dist/src/commands/plugin.js +95 -27
  161. package/dist/src/commands/profile-and-review.d.ts +4 -0
  162. package/dist/src/commands/profile-and-review.js +26 -19
  163. package/dist/src/commands/queue.d.ts +3 -0
  164. package/dist/src/commands/queue.js +32 -12
  165. package/dist/src/commands/remote.d.ts +3 -0
  166. package/dist/src/commands/remote.js +43 -36
  167. package/dist/src/commands/repo-git-harness.d.ts +5 -0
  168. package/dist/src/commands/repo-git-harness.js +22 -15
  169. package/dist/src/commands/run.d.ts +3 -0
  170. package/dist/src/commands/run.js +1379 -159
  171. package/dist/src/commands/server.d.ts +7 -0
  172. package/dist/src/commands/server.js +502 -57
  173. package/dist/src/commands/setup.d.ts +16 -0
  174. package/dist/src/commands/setup.js +390 -63
  175. package/dist/src/commands/stats.d.ts +12 -0
  176. package/dist/src/commands/stats.js +1051 -0
  177. package/dist/src/commands/task-report-bug.d.ts +19 -0
  178. package/dist/src/commands/task-report-bug.js +260 -62
  179. package/dist/src/commands/task-run-driver.d.ts +132 -0
  180. package/dist/src/commands/task-run-driver.js +886 -130
  181. package/dist/src/commands/task.d.ts +14 -0
  182. package/dist/src/commands/task.js +1644 -314
  183. package/dist/src/commands/test.d.ts +3 -0
  184. package/dist/src/commands/test.js +15 -8
  185. package/dist/src/commands/workspace.d.ts +3 -0
  186. package/dist/src/commands/workspace.js +18 -11
  187. package/dist/src/commands.d.ts +29 -0
  188. package/dist/src/commands.js +10996 -6637
  189. package/dist/src/index.d.ts +4 -0
  190. package/dist/src/index.js +10197 -5787
  191. package/dist/src/launcher.d.ts +61 -0
  192. package/dist/src/launcher.js +77 -13
  193. package/dist/src/report-bug.d.ts +44 -0
  194. package/dist/src/report-bug.js +3 -3
  195. package/dist/src/runner.d.ts +47 -0
  196. package/dist/src/runner.js +16 -22
  197. package/dist/src/withMutedConsole.d.ts +2 -0
  198. package/package.json +16 -6
@@ -0,0 +1,2 @@
1
+ import type { AppSceneFrame, AppState } from "../types";
2
+ export declare function renderDoctorScene(state: AppState): AppSceneFrame;
@@ -0,0 +1,91 @@
1
+ // @bun
2
+ // packages/cli/src/app-opentui/theme.ts
3
+ import {
4
+ bold as otuiBold,
5
+ dim as otuiDim,
6
+ fg as otuiFg,
7
+ t,
8
+ TextAttributes
9
+ } from "@opentui/core";
10
+ var RIG_UI = {
11
+ bg: "#070809",
12
+ bg2: "#0b0c0e",
13
+ panel: "#101115",
14
+ panel2: "#101115",
15
+ glass: "#14161b",
16
+ ink: "#f2f3f6",
17
+ ink2: "#aeb0ba",
18
+ ink3: "#6c6e79",
19
+ ink4: "#44464f",
20
+ lime: "#ccff4d",
21
+ limeDim: "#a9d63f",
22
+ cyan: "#56d8ff",
23
+ red: "#ff5d5d",
24
+ yellow: "#ffd24d",
25
+ magenta: "#ff79b0"
26
+ };
27
+ var styles = {
28
+ ink: otuiFg(RIG_UI.ink),
29
+ ink2: otuiFg(RIG_UI.ink2),
30
+ ink3: otuiFg(RIG_UI.ink3),
31
+ ink4: otuiFg(RIG_UI.ink4),
32
+ lime: otuiFg(RIG_UI.lime),
33
+ limeDim: otuiFg(RIG_UI.limeDim),
34
+ cyan: otuiFg(RIG_UI.cyan),
35
+ red: otuiFg(RIG_UI.red),
36
+ yellow: otuiFg(RIG_UI.yellow),
37
+ magenta: otuiFg(RIG_UI.magenta)
38
+ };
39
+
40
+ // packages/cli/src/app-opentui/render/scene.ts
41
+ function line(text, options = {}) {
42
+ return { text, ...options };
43
+ }
44
+ function blank() {
45
+ return { text: "" };
46
+ }
47
+ function center(text, fg = RIG_UI.ink2, bold = false) {
48
+ return { text, fg, bold, align: "center" };
49
+ }
50
+ function makeSceneFrame(input) {
51
+ return input;
52
+ }
53
+
54
+ // packages/cli/src/app-opentui/scenes/doctor.ts
55
+ function checks(state) {
56
+ const doctor = state.data.doctor;
57
+ if (!doctor || typeof doctor !== "object" || Array.isArray(doctor))
58
+ return [];
59
+ const checks2 = doctor.checks;
60
+ return Array.isArray(checks2) ? checks2 : [];
61
+ }
62
+ function glyph(status) {
63
+ return status === "pass" ? "\u25CF" : status === "warn" ? "\u25B2" : "\u2715";
64
+ }
65
+ function doctorColor(status) {
66
+ return status === "pass" ? RIG_UI.limeDim : status === "warn" ? RIG_UI.yellow : RIG_UI.red;
67
+ }
68
+ function renderDoctorScene(state) {
69
+ const records = checks(state);
70
+ const failures = records.filter((check) => check.status === "fail").length;
71
+ const warnings = records.filter((check) => check.status === "warn").length;
72
+ const firstRemediation = records.find((check) => check.status !== "pass" && check.remediation)?.remediation;
73
+ return makeSceneFrame({
74
+ scene: "doctor",
75
+ title: "Doctor",
76
+ lines: [
77
+ center("doctor", RIG_UI.ink, true),
78
+ center(records.length > 0 ? `${failures} fail \xB7 ${warnings} warn` : "diagnostics ready", RIG_UI.ink3),
79
+ blank(),
80
+ ...records.length > 0 ? records.slice(0, 14).map((check) => line(`${glyph(check.status)} ${check.label}${check.detail ? ` \u2014 ${check.detail}` : ""}`, { fg: doctorColor(check.status), align: "center" })) : [line("type doctor to run checks", { fg: RIG_UI.ink3, align: "center" })],
81
+ blank(),
82
+ line(firstRemediation ? `next: ${firstRemediation}` : records.length > 0 ? "ready" : "idle", { fg: firstRemediation ? RIG_UI.yellow : RIG_UI.ink4, align: "center" })
83
+ ],
84
+ footer: { message: records.length > 0 ? `${records.length} checks` : "doctor idle" },
85
+ typeBarPlaceholder: "doctor \xB7 server \xB7 tasks \xB7 init",
86
+ live: state.status === "action" || records.length === 0
87
+ });
88
+ }
89
+ export {
90
+ renderDoctorScene
91
+ };
@@ -0,0 +1,2 @@
1
+ import type { AppSceneFrame, AppState } from "../types";
2
+ export declare function renderErrorScene(state: AppState): AppSceneFrame;
@@ -0,0 +1,190 @@
1
+ // @bun
2
+ // packages/cli/src/app-opentui/drone.ts
3
+ import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
4
+
5
+ // packages/cli/src/app-opentui/theme.ts
6
+ import {
7
+ bold as otuiBold,
8
+ dim as otuiDim,
9
+ fg as otuiFg,
10
+ t,
11
+ TextAttributes
12
+ } from "@opentui/core";
13
+ var RIG_UI = {
14
+ bg: "#070809",
15
+ bg2: "#0b0c0e",
16
+ panel: "#101115",
17
+ panel2: "#101115",
18
+ glass: "#14161b",
19
+ ink: "#f2f3f6",
20
+ ink2: "#aeb0ba",
21
+ ink3: "#6c6e79",
22
+ ink4: "#44464f",
23
+ lime: "#ccff4d",
24
+ limeDim: "#a9d63f",
25
+ cyan: "#56d8ff",
26
+ red: "#ff5d5d",
27
+ yellow: "#ffd24d",
28
+ magenta: "#ff79b0"
29
+ };
30
+ var styles = {
31
+ ink: otuiFg(RIG_UI.ink),
32
+ ink2: otuiFg(RIG_UI.ink2),
33
+ ink3: otuiFg(RIG_UI.ink3),
34
+ ink4: otuiFg(RIG_UI.ink4),
35
+ lime: otuiFg(RIG_UI.lime),
36
+ limeDim: otuiFg(RIG_UI.limeDim),
37
+ cyan: otuiFg(RIG_UI.cyan),
38
+ red: otuiFg(RIG_UI.red),
39
+ yellow: otuiFg(RIG_UI.yellow),
40
+ magenta: otuiFg(RIG_UI.magenta)
41
+ };
42
+
43
+ // packages/cli/src/app-opentui/drone.ts
44
+ var MINI_DRONE = [
45
+ "(!!!) (!!!)",
46
+ " \\%==%/ ",
47
+ " %%?%% ",
48
+ " /%==%\\ ",
49
+ "(!!!) (!!!)"
50
+ ];
51
+ var LEAD_MARK = [
52
+ " .-=-. ",
53
+ "=%%?%%=",
54
+ " '-=-' "
55
+ ];
56
+ var BLADE_FRAMES = ["---", "\\\\\\", "|||", "///"];
57
+ var EYE_FRAMES = ["o", "@", "\u2022", "."];
58
+ var COLOR = {
59
+ body: RGBA.fromHex(RIG_UI.lime),
60
+ mini: RGBA.fromHex(RIG_UI.limeDim),
61
+ rotor: RGBA.fromHex(RIG_UI.cyan),
62
+ path: RGBA.fromHex(RIG_UI.cyan),
63
+ eye: RGBA.fromHex(RIG_UI.ink),
64
+ dim: RGBA.fromHex(RIG_UI.ink4),
65
+ ink: RGBA.fromHex(RIG_UI.ink2)
66
+ };
67
+ function bladeForTick(tick, phase = 0) {
68
+ return BLADE_FRAMES[(Math.floor(tick / 3) + phase) % BLADE_FRAMES.length];
69
+ }
70
+ function eyeForTick(tick, phase = 0) {
71
+ const pulse = Math.sin(tick * 0.09 + phase);
72
+ return pulse > 0.55 ? EYE_FRAMES[1] : pulse > 0.1 ? EYE_FRAMES[0] : pulse > -0.45 ? EYE_FRAMES[2] : EYE_FRAMES[3];
73
+ }
74
+ function chunk(text, fg, bold = false, dim = false) {
75
+ let attributes = TextAttributes2.NONE;
76
+ if (bold)
77
+ attributes |= TextAttributes2.BOLD;
78
+ if (dim)
79
+ attributes |= TextAttributes2.DIM;
80
+ return { __isChunk: true, text, fg, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
81
+ }
82
+ function styledLine(text, colorFor) {
83
+ const chunks = [];
84
+ let run = "";
85
+ let runColor = null;
86
+ const flush = () => {
87
+ if (!run || !runColor)
88
+ return;
89
+ chunks.push(chunk(run, COLOR[runColor], runColor === "body" || runColor === "eye", runColor === "dim"));
90
+ run = "";
91
+ };
92
+ for (const char of text) {
93
+ const next = colorFor(char);
94
+ if (next !== runColor) {
95
+ flush();
96
+ runColor = next;
97
+ }
98
+ run += char;
99
+ }
100
+ flush();
101
+ return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
102
+ }
103
+ function droneColor(char) {
104
+ if (char === "?" || char === "o" || char === "@" || char === "\u2022")
105
+ return "eye";
106
+ if (char === "%" || char === "=")
107
+ return "mini";
108
+ if (char === "$")
109
+ return "body";
110
+ if (char === "(" || char === ")" || char === "/" || char === "\\" || char === "|" || char === "-")
111
+ return "rotor";
112
+ if (char === "\xB7" || char === "\u2022" || char === "'" || char === ".")
113
+ return "path";
114
+ if (char.trim() === "")
115
+ return "dim";
116
+ return "ink";
117
+ }
118
+ function motionColor(char) {
119
+ if (char === "\u25CF" || char === "\u25C6" || char === "\u25C9")
120
+ return "body";
121
+ if (char === "\u2022" || char === "\xB7" || char === "\u2500" || char === "\u2502" || char === "\u2571" || char === "\u2572" || char === "\u256D" || char === "\u256E" || char === "\u2570" || char === "\u256F")
122
+ return "path";
123
+ if (char === "\u258C" || char === "\u2590" || char === "\u2581" || char === "\u2594")
124
+ return "mini";
125
+ return droneColor(char);
126
+ }
127
+ function materializeDrone(lines, tick, phase = 0) {
128
+ const blade = bladeForTick(tick, phase);
129
+ const eye = eyeForTick(tick, phase);
130
+ return lines.map((line) => line.replaceAll("!!!", blade).replaceAll("?", eye));
131
+ }
132
+ function brandFleetLines(tick, align = "center") {
133
+ const left = materializeDrone(MINI_DRONE, tick, 0);
134
+ const right = materializeDrone(MINI_DRONE, tick, 2);
135
+ const lead = materializeDrone(LEAD_MARK, tick, 1);
136
+ const packet = ["\xB7", "\u2022", "\u25CF", "\u2022"][Math.floor(tick / 2) % 4];
137
+ const bridge = [
138
+ ` ${left[0]} ${lead[0]} ${right[0]}`,
139
+ ` ${left[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${lead[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${right[1]}`,
140
+ ` ${left[2]} \xB7' '${lead[2]}' '\xB7 ${right[2]}`,
141
+ ` ${left[3]} \u2572 signal bus \u2571 ${right[3]}`,
142
+ ` ${left[4]} \xB7\u2500\u2500\u2500${packet}\u2500\u2500\u2500\u2500\u2500\u2500${packet}\u2500\u2500\u2500\xB7 ${right[4]}`
143
+ ];
144
+ return bridge.map((text) => ({
145
+ text,
146
+ styledText: styledLine(text, motionColor),
147
+ fg: RIG_UI.limeDim,
148
+ align
149
+ }));
150
+ }
151
+ function errorDrone(tick) {
152
+ return brandFleetLines(tick).map((line, index) => ({
153
+ ...line,
154
+ fg: index % 2 === 0 ? RIG_UI.red : line.fg
155
+ }));
156
+ }
157
+
158
+ // packages/cli/src/app-opentui/render/scene.ts
159
+ function blank() {
160
+ return { text: "" };
161
+ }
162
+ function center(text, fg = RIG_UI.ink2, bold = false) {
163
+ return { text, fg, bold, align: "center" };
164
+ }
165
+ function makeSceneFrame(input) {
166
+ return input;
167
+ }
168
+
169
+ // packages/cli/src/app-opentui/scenes/error.ts
170
+ function renderErrorScene(state) {
171
+ const message = state.error?.message ?? "Unknown Rig app error";
172
+ const hint = state.error?.hint ?? "type main, help, or retry after fixing the issue";
173
+ return makeSceneFrame({
174
+ scene: "error",
175
+ title: "Rig error",
176
+ lines: [
177
+ ...errorDrone(state.tick).slice(2, 16),
178
+ blank(),
179
+ center("DRONE SIGNAL DEGRADED", RIG_UI.red, true),
180
+ center(message, RIG_UI.ink2),
181
+ blank(),
182
+ center(hint, RIG_UI.limeDim)
183
+ ],
184
+ typeBarPlaceholder: hint,
185
+ live: true
186
+ });
187
+ }
188
+ export {
189
+ renderErrorScene
190
+ };
@@ -0,0 +1,3 @@
1
+ import type { StageLayout } from "../layout";
2
+ import type { AppSceneFrame, AppState } from "../types";
3
+ export declare function renderFleetScene(state: AppState, layout?: StageLayout): AppSceneFrame;
@@ -0,0 +1,207 @@
1
+ // @bun
2
+ // packages/cli/src/app-opentui/theme.ts
3
+ import {
4
+ bold as otuiBold,
5
+ dim as otuiDim,
6
+ fg as otuiFg,
7
+ t,
8
+ TextAttributes
9
+ } from "@opentui/core";
10
+ var RIG_UI = {
11
+ bg: "#070809",
12
+ bg2: "#0b0c0e",
13
+ panel: "#101115",
14
+ panel2: "#101115",
15
+ glass: "#14161b",
16
+ ink: "#f2f3f6",
17
+ ink2: "#aeb0ba",
18
+ ink3: "#6c6e79",
19
+ ink4: "#44464f",
20
+ lime: "#ccff4d",
21
+ limeDim: "#a9d63f",
22
+ cyan: "#56d8ff",
23
+ red: "#ff5d5d",
24
+ yellow: "#ffd24d",
25
+ magenta: "#ff79b0"
26
+ };
27
+ var styles = {
28
+ ink: otuiFg(RIG_UI.ink),
29
+ ink2: otuiFg(RIG_UI.ink2),
30
+ ink3: otuiFg(RIG_UI.ink3),
31
+ ink4: otuiFg(RIG_UI.ink4),
32
+ lime: otuiFg(RIG_UI.lime),
33
+ limeDim: otuiFg(RIG_UI.limeDim),
34
+ cyan: otuiFg(RIG_UI.cyan),
35
+ red: otuiFg(RIG_UI.red),
36
+ yellow: otuiFg(RIG_UI.yellow),
37
+ magenta: otuiFg(RIG_UI.magenta)
38
+ };
39
+ function statusColor(status) {
40
+ switch (status) {
41
+ case "running":
42
+ case "success":
43
+ case "completed":
44
+ case "merged":
45
+ return RIG_UI.lime;
46
+ case "preparing":
47
+ case "created":
48
+ case "validating":
49
+ case "reviewing":
50
+ case "closing-out":
51
+ case "stopping":
52
+ case "loading":
53
+ case "action":
54
+ return RIG_UI.cyan;
55
+ case "needs-attention":
56
+ case "needs_attention":
57
+ return RIG_UI.yellow;
58
+ case "failed":
59
+ case "error":
60
+ return RIG_UI.red;
61
+ default:
62
+ return RIG_UI.ink3;
63
+ }
64
+ }
65
+
66
+ // packages/cli/src/app-opentui/render/scene.ts
67
+ function line(text, options = {}) {
68
+ return { text, ...options };
69
+ }
70
+ function makeSceneFrame(input) {
71
+ return input;
72
+ }
73
+
74
+ // packages/cli/src/app-opentui/list-search.ts
75
+ function isListSearchScene(scene) {
76
+ return scene === "fleet" || scene === "tasks";
77
+ }
78
+ function listSearchQuery(state) {
79
+ return isListSearchScene(state.scene) ? state.typeBar.value.trim() : "";
80
+ }
81
+ function valueText(value) {
82
+ if (value === undefined || value === null)
83
+ return "";
84
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
85
+ return String(value);
86
+ if (Array.isArray(value))
87
+ return value.map(valueText).join(" ");
88
+ if (typeof value === "object") {
89
+ const record = value;
90
+ return ["id", "runId", "taskId", "number", "title", "name", "summary", "status", "state", "label", "labels", "assignee", "assignees", "url"].map((key) => valueText(record[key])).join(" ");
91
+ }
92
+ return "";
93
+ }
94
+ function includesQuery(haystack, query) {
95
+ const needle = query.trim().toLowerCase();
96
+ if (!needle)
97
+ return true;
98
+ return haystack.map(valueText).join(" ").toLowerCase().includes(needle);
99
+ }
100
+ function filterRunsForSearch(runs, query) {
101
+ return query.trim() ? runs.filter((run) => includesQuery([run.runId, run.status, run.title, run.taskId, run.raw], query)) : [...runs];
102
+ }
103
+ function searchSummary(kind, query, visible, total) {
104
+ return query.trim() ? `search ${JSON.stringify(query)} \xB7 ${visible}/${total} ${kind}` : `${total} ${kind}`;
105
+ }
106
+
107
+ // packages/cli/src/app-opentui/scenes/fleet.ts
108
+ function asRuns(state) {
109
+ const fleet = state.data.fleet;
110
+ if (!fleet || typeof fleet !== "object" || Array.isArray(fleet))
111
+ return [];
112
+ const runs = fleet.runs;
113
+ return Array.isArray(runs) ? runs : [];
114
+ }
115
+ function panelWidth(layout) {
116
+ return layout?.centerWidth ?? 100;
117
+ }
118
+ function panelHeight(layout, top = 3) {
119
+ return Math.max(4, (layout?.centerHeight ?? 24) - top);
120
+ }
121
+ function clip(value, width) {
122
+ if (width <= 0)
123
+ return "";
124
+ return value.length <= width ? value : `${value.slice(0, Math.max(0, width - 1))}\u2026`;
125
+ }
126
+ function runRow(width, run, index, active) {
127
+ const id = run.runId.slice(0, 8).padEnd(9);
128
+ const status = run.status.replace(/[_-]/g, " ").slice(0, 13).padEnd(14);
129
+ const marker = active ? "\u258C" : " ";
130
+ const prefix = `${marker} ${id} ${status}`;
131
+ const titleWidth = Math.max(12, width - prefix.length - 2);
132
+ return line(`${prefix}${clip(run.title, titleWidth)}`, {
133
+ fg: active ? RIG_UI.ink : statusColor(run.status),
134
+ bold: active,
135
+ selectableIndex: index
136
+ });
137
+ }
138
+ function emptyRows(query, total) {
139
+ if (query.trim() && total > 0) {
140
+ return [
141
+ line("No matching runs.", { fg: RIG_UI.ink2, bold: true }),
142
+ line(`search ${JSON.stringify(query)} returned 0/${total}`, { fg: RIG_UI.ink3 }),
143
+ line("escape clears search", { fg: RIG_UI.ink4 })
144
+ ];
145
+ }
146
+ return [
147
+ line("No runs yet.", { fg: RIG_UI.ink2, bold: true }),
148
+ line("Open Tasks and dispatch work; live and completed runs appear here.", { fg: RIG_UI.ink3 }),
149
+ line("tab switches screens", { fg: RIG_UI.ink4 })
150
+ ];
151
+ }
152
+ function degradedRows(state) {
153
+ if (!state.error)
154
+ return [];
155
+ return [
156
+ line(`status: ${state.error.message}`, { fg: RIG_UI.red, bold: true }),
157
+ ...state.error.hint ? [line(state.error.hint, { fg: RIG_UI.yellow })] : [],
158
+ line("", { fg: RIG_UI.ink3 })
159
+ ];
160
+ }
161
+ function renderFleetScene(state, layout) {
162
+ const width = panelWidth(layout);
163
+ const allRuns = asRuns(state);
164
+ const query = listSearchQuery(state);
165
+ const runs = filterRunsForSearch(allRuns, query);
166
+ const selectedRun = typeof state.data.selectedRunId === "string" && runs.some((run) => run.runId === state.data.selectedRunId) ? state.data.selectedRunId : runs[0]?.runId;
167
+ const selectedIndex = Math.max(0, runs.findIndex((run) => run.runId === selectedRun));
168
+ const panelTop = 0;
169
+ const contentWidth = Math.max(12, width - (layout?.compact ? 8 : 10));
170
+ const panelLines = [
171
+ line(`RUN STATUS TITLE`, { fg: RIG_UI.ink3, bold: true }),
172
+ line("", { fg: RIG_UI.ink3 }),
173
+ ...degradedRows(state),
174
+ ...query.trim() ? [line(searchSummary("runs", query, runs.length, allRuns.length), { fg: RIG_UI.ink4 }), line("", { fg: RIG_UI.ink3 })] : [],
175
+ ...runs.length > 0 ? runs.map((run, index) => runRow(contentWidth, run, index, index === selectedIndex)) : emptyRows(query, allRuns.length)
176
+ ];
177
+ return makeSceneFrame({
178
+ scene: "fleet",
179
+ title: "Runs",
180
+ lines: [
181
+ line("", { fg: RIG_UI.ink4 }),
182
+ line(query.trim() ? ` rig runs --search ${JSON.stringify(query)}` : " rig runs", { fg: RIG_UI.ink3 })
183
+ ],
184
+ panels: [{
185
+ id: "runs-list",
186
+ top: panelTop,
187
+ width,
188
+ height: panelHeight(layout, panelTop),
189
+ lines: panelLines,
190
+ backgroundColor: RIG_UI.panel,
191
+ backgroundAlpha: 184,
192
+ opacity: 1,
193
+ border: false,
194
+ chrome: "ad-terminal",
195
+ headerText: query.trim() ? `rig runs --search ${JSON.stringify(query)}` : "rig runs",
196
+ headerHeight: 3,
197
+ paddingX: layout?.compact ? 2 : 3,
198
+ paddingY: 1
199
+ }],
200
+ footer: { run: selectedRun ? selectedRun.slice(0, 8) : "no runs", message: searchSummary("runs", query, runs.length, allRuns.length) },
201
+ typeBarPlaceholder: "search runs\u2026",
202
+ live: true
203
+ });
204
+ }
205
+ export {
206
+ renderFleetScene
207
+ };
@@ -0,0 +1,2 @@
1
+ import type { AppSceneFrame, AppState } from "../types";
2
+ export declare function renderHandoffScene(state: AppState): AppSceneFrame;
@@ -0,0 +1,147 @@
1
+ // @bun
2
+ // packages/cli/src/app-opentui/theme.ts
3
+ import {
4
+ bold as otuiBold,
5
+ dim as otuiDim,
6
+ fg as otuiFg,
7
+ t,
8
+ TextAttributes
9
+ } from "@opentui/core";
10
+ var RIG_UI = {
11
+ bg: "#070809",
12
+ bg2: "#0b0c0e",
13
+ panel: "#101115",
14
+ panel2: "#101115",
15
+ glass: "#14161b",
16
+ ink: "#f2f3f6",
17
+ ink2: "#aeb0ba",
18
+ ink3: "#6c6e79",
19
+ ink4: "#44464f",
20
+ lime: "#ccff4d",
21
+ limeDim: "#a9d63f",
22
+ cyan: "#56d8ff",
23
+ red: "#ff5d5d",
24
+ yellow: "#ffd24d",
25
+ magenta: "#ff79b0"
26
+ };
27
+ var styles = {
28
+ ink: otuiFg(RIG_UI.ink),
29
+ ink2: otuiFg(RIG_UI.ink2),
30
+ ink3: otuiFg(RIG_UI.ink3),
31
+ ink4: otuiFg(RIG_UI.ink4),
32
+ lime: otuiFg(RIG_UI.lime),
33
+ limeDim: otuiFg(RIG_UI.limeDim),
34
+ cyan: otuiFg(RIG_UI.cyan),
35
+ red: otuiFg(RIG_UI.red),
36
+ yellow: otuiFg(RIG_UI.yellow),
37
+ magenta: otuiFg(RIG_UI.magenta)
38
+ };
39
+
40
+ // packages/cli/src/app-opentui/render/scene.ts
41
+ function line(text, options = {}) {
42
+ return { text, ...options };
43
+ }
44
+ function blank() {
45
+ return { text: "" };
46
+ }
47
+ function center(text, fg = RIG_UI.ink2, bold = false) {
48
+ return { text, fg, bold, align: "center" };
49
+ }
50
+ function deckRow(input) {
51
+ const prefix = input.active ? "\u25B8" : " ";
52
+ const label = input.label.toUpperCase().padEnd(10);
53
+ return line(`${prefix} ${label} ${input.detail}`, {
54
+ fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
55
+ bold: input.active,
56
+ selectableIndex: input.index,
57
+ activateOnClick: input.activateOnClick
58
+ });
59
+ }
60
+ function makeSceneFrame(input) {
61
+ return input;
62
+ }
63
+
64
+ // packages/cli/src/app-opentui/scenes/handoff.ts
65
+ function handoffState(state) {
66
+ const value = state.data.piAttach ?? state.data.handoff;
67
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
68
+ }
69
+ function terminalState(state) {
70
+ const value = state.data.piTerminal;
71
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
72
+ }
73
+ function clip(value, width) {
74
+ if (width <= 0)
75
+ return "";
76
+ return value.length <= width ? value : `${value.slice(0, Math.max(0, width - 1))}\u2026`;
77
+ }
78
+ function terminalRail(snapshot) {
79
+ const text = ` run ${snapshot.runId.slice(0, 8)} \xB7 bundled Pi \xB7 mouse wheel scroll \xB7 ctrl-] detach \xB7 ${snapshot.message ?? snapshot.status}`;
80
+ return line(clip(text, snapshot.cols), { fg: RIG_UI.limeDim });
81
+ }
82
+ function terminalLines(snapshot) {
83
+ const hasVisibleOutput = snapshot.lines.some((entry) => entry.trim().length > 0);
84
+ const body = !hasVisibleOutput && snapshot.status === "running" ? [line(`starting bundled Pi for ${snapshot.runId.slice(0, 8)}\u2026`, { fg: RIG_UI.ink3 })] : snapshot.lines.map((text, index) => line(text, { fg: RIG_UI.ink, styledText: snapshot.styledLines?.[index] }));
85
+ return [...body, terminalRail(snapshot)];
86
+ }
87
+ function renderHandoffScene(state) {
88
+ const terminal = terminalState(state);
89
+ if (terminal && (terminal.status === "starting" || terminal.status === "running")) {
90
+ return makeSceneFrame({
91
+ scene: "handoff",
92
+ title: "Pi",
93
+ lines: [],
94
+ panels: [{
95
+ id: `pi-terminal-${terminal.runId}`,
96
+ top: 0,
97
+ left: 0,
98
+ width: terminal.cols,
99
+ height: terminal.rows,
100
+ lines: terminalLines(terminal),
101
+ backgroundColor: "#050607",
102
+ backgroundAlpha: 128,
103
+ opacity: 1,
104
+ border: false,
105
+ stickyScroll: true,
106
+ stickyStart: "bottom"
107
+ }],
108
+ footer: { run: terminal.runId.slice(0, 8), message: terminal.message ?? "bundled Pi" },
109
+ live: true,
110
+ fullScreen: true,
111
+ hideTypeBar: true,
112
+ terminalActive: true
113
+ });
114
+ }
115
+ const handoff = handoffState(state);
116
+ const runId = handoff?.runId ?? terminal?.runId ?? (typeof state.data.selectedRunId === "string" ? state.data.selectedRunId : undefined);
117
+ const status = handoff?.status ?? (runId ? "preparing" : "select-run");
118
+ const message = handoff?.message ?? (runId ? "ready to start bundled Pi inside Rig" : "choose a run before entering Pi");
119
+ const hasRun = Boolean(runId);
120
+ return makeSceneFrame({
121
+ scene: "handoff",
122
+ title: "Pi handoff",
123
+ lines: [
124
+ center(hasRun ? "PI" : "ATTACH", RIG_UI.ink, true),
125
+ center("Bundled Pi runs in this terminal. Rig only hosts the PTY.", RIG_UI.ink3),
126
+ blank(),
127
+ ...hasRun ? [
128
+ line(` run ${runId}`, { fg: RIG_UI.limeDim }),
129
+ line(` status ${status}`, { fg: status === "failed" ? RIG_UI.red : RIG_UI.cyan }),
130
+ line(` message ${message}`, { fg: RIG_UI.ink2 }),
131
+ blank(),
132
+ deckRow({ label: "attach", detail: "open bundled Pi", index: 0, active: true })
133
+ ] : [
134
+ line(" run none selected", { fg: RIG_UI.yellow }),
135
+ line(` message ${message}`, { fg: RIG_UI.ink2 }),
136
+ blank(),
137
+ deckRow({ label: "runs", detail: "select a run first", index: 0, active: true })
138
+ ]
139
+ ],
140
+ footer: { run: runId ? `${runId.slice(0, 8)} handoff` : "select run", message: "real Pi only" },
141
+ typeBarPlaceholder: runId ? `attach ${runId.slice(0, 8)} \xB7 runs` : "runs \xB7 attach <run>",
142
+ live: true
143
+ });
144
+ }
145
+ export {
146
+ renderHandoffScene
147
+ };
@@ -0,0 +1,3 @@
1
+ import type { StageLayout } from "../layout";
2
+ import type { AppSceneFrame, AppState } from "../types";
3
+ export declare function renderHelpScene(state: AppState, layout?: StageLayout): AppSceneFrame;