@h-rig/cli 0.0.6-alpha.82 → 0.0.6-alpha.84

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 (206) hide show
  1. package/dist/bin/build-rig-binaries.js +40 -8
  2. package/dist/bin/rig.js +23402 -14577
  3. package/dist/src/app/board.js +217 -41
  4. package/dist/src/app-opentui/adapters/command.d.ts +2 -0
  5. package/dist/src/app-opentui/adapters/command.js +329 -0
  6. package/dist/src/app-opentui/adapters/common.js +2 -2
  7. package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
  8. package/dist/src/app-opentui/adapters/doctor.js +64 -39
  9. package/dist/src/app-opentui/adapters/family.d.ts +62 -0
  10. package/dist/src/app-opentui/adapters/family.js +14305 -0
  11. package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
  12. package/dist/src/app-opentui/adapters/fleet.js +90 -60
  13. package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
  14. package/dist/src/app-opentui/adapters/inbox.js +137 -78
  15. package/dist/src/app-opentui/adapters/init.d.ts +0 -2
  16. package/dist/src/app-opentui/adapters/init.js +85 -47
  17. package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
  18. package/dist/src/app-opentui/adapters/inspect.js +1024 -0
  19. package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
  20. package/dist/src/app-opentui/adapters/pi-attach.js +442 -125
  21. package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
  22. package/dist/src/app-opentui/adapters/pi.js +363 -0
  23. package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
  24. package/dist/src/app-opentui/adapters/plugin.js +544 -0
  25. package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
  26. package/dist/src/app-opentui/adapters/repo.js +186 -0
  27. package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
  28. package/dist/src/app-opentui/adapters/run-detail.js +180 -63
  29. package/dist/src/app-opentui/adapters/server.d.ts +10 -2
  30. package/dist/src/app-opentui/adapters/server.js +191 -45
  31. package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
  32. package/dist/src/app-opentui/adapters/tasks.js +1123 -143
  33. package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
  34. package/dist/src/app-opentui/adapters/workspace.js +333 -0
  35. package/dist/src/app-opentui/autocomplete.d.ts +20 -0
  36. package/dist/src/app-opentui/autocomplete.js +576 -0
  37. package/dist/src/app-opentui/bootstrap.d.ts +1 -6
  38. package/dist/src/app-opentui/bootstrap.js +25252 -16474
  39. package/dist/src/app-opentui/command-palette.d.ts +3 -0
  40. package/dist/src/app-opentui/command-palette.js +1010 -0
  41. package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
  42. package/dist/src/app-opentui/command-pty-host.js +248 -0
  43. package/dist/src/app-opentui/drone.js +8 -6
  44. package/dist/src/app-opentui/events.js +1 -1
  45. package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
  46. package/dist/src/app-opentui/fleet-stats.js +114 -0
  47. package/dist/src/app-opentui/focus-manager.d.ts +14 -0
  48. package/dist/src/app-opentui/focus-manager.js +24 -0
  49. package/dist/src/app-opentui/index.js +5431 -2797
  50. package/dist/src/app-opentui/intent.js +179 -50
  51. package/dist/src/app-opentui/keymap.d.ts +21 -0
  52. package/dist/src/app-opentui/keymap.js +1748 -0
  53. package/dist/src/app-opentui/launch-routing.d.ts +16 -0
  54. package/dist/src/app-opentui/launch-routing.js +55 -0
  55. package/dist/src/app-opentui/layout.d.ts +7 -0
  56. package/dist/src/app-opentui/layout.js +13 -6
  57. package/dist/src/app-opentui/list-search.d.ts +24 -0
  58. package/dist/src/app-opentui/list-search.js +88 -1
  59. package/dist/src/app-opentui/pi-host-child.js +99 -17
  60. package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
  61. package/dist/src/app-opentui/pi-pty-host.js +30 -14
  62. package/dist/src/app-opentui/react/App.d.ts +9 -0
  63. package/dist/src/app-opentui/react/App.js +5144 -0
  64. package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
  65. package/dist/src/app-opentui/react/Backdrop.js +1834 -0
  66. package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
  67. package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
  68. package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
  69. package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
  70. package/dist/src/app-opentui/react/context.d.ts +17 -0
  71. package/dist/src/app-opentui/react/context.js +37 -0
  72. package/dist/src/app-opentui/react/launch.d.ts +2 -0
  73. package/dist/src/app-opentui/react/launch.js +5743 -0
  74. package/dist/src/app-opentui/react/nav.d.ts +18 -0
  75. package/dist/src/app-opentui/react/nav.js +54 -0
  76. package/dist/src/app-opentui/react/scroll.d.ts +12 -0
  77. package/dist/src/app-opentui/react/scroll.js +21 -0
  78. package/dist/src/app-opentui/react/syntax.d.ts +2 -0
  79. package/dist/src/app-opentui/react/syntax.js +64 -0
  80. package/dist/src/app-opentui/registry.js +20428 -4828
  81. package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
  82. package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
  83. package/dist/src/app-opentui/render/constants.d.ts +31 -0
  84. package/dist/src/app-opentui/render/constants.js +66 -0
  85. package/dist/src/app-opentui/render/graphics.d.ts +2 -1
  86. package/dist/src/app-opentui/render/graphics.js +228 -46
  87. package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
  88. package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
  89. package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
  90. package/dist/src/app-opentui/render/native-host.d.ts +37 -0
  91. package/dist/src/app-opentui/render/native-host.js +179 -0
  92. package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
  93. package/dist/src/app-opentui/render/panel-layout.js +48 -0
  94. package/dist/src/app-opentui/render/panels.d.ts +2 -0
  95. package/dist/src/app-opentui/render/panels.js +78 -38
  96. package/dist/src/app-opentui/render/preloader.d.ts +10 -0
  97. package/dist/src/app-opentui/render/preloader.js +165 -0
  98. package/dist/src/app-opentui/render/scene.d.ts +53 -1
  99. package/dist/src/app-opentui/render/scene.js +195 -6
  100. package/dist/src/app-opentui/render/text.d.ts +7 -1
  101. package/dist/src/app-opentui/render/text.js +15 -8
  102. package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
  103. package/dist/src/app-opentui/render/type-bar.js +113 -39
  104. package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
  105. package/dist/src/app-opentui/runtime-resources.js +62 -0
  106. package/dist/src/app-opentui/runtime.d.ts +44 -1
  107. package/dist/src/app-opentui/runtime.js +5415 -2738
  108. package/dist/src/app-opentui/scenes/command.d.ts +3 -0
  109. package/dist/src/app-opentui/scenes/command.js +117 -0
  110. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
  111. package/dist/src/app-opentui/scenes/doctor.js +221 -17
  112. package/dist/src/app-opentui/scenes/error.js +60 -20
  113. package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
  114. package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
  115. package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
  116. package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
  117. package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
  118. package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
  119. package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
  120. package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
  121. package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
  122. package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
  123. package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
  124. package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
  125. package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
  126. package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
  127. package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
  128. package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
  129. package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
  130. package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
  131. package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
  132. package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
  133. package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
  134. package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
  135. package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
  136. package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
  137. package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
  138. package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
  139. package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
  140. package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
  141. package/dist/src/app-opentui/scenes/family.d.ts +3 -0
  142. package/dist/src/app-opentui/scenes/family.js +2144 -0
  143. package/dist/src/app-opentui/scenes/fleet.js +552 -43
  144. package/dist/src/app-opentui/scenes/handoff.js +342 -35
  145. package/dist/src/app-opentui/scenes/help.js +640 -56
  146. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
  147. package/dist/src/app-opentui/scenes/inbox.js +329 -21
  148. package/dist/src/app-opentui/scenes/init.d.ts +2 -1
  149. package/dist/src/app-opentui/scenes/init.js +120 -34
  150. package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
  151. package/dist/src/app-opentui/scenes/inspect.js +793 -0
  152. package/dist/src/app-opentui/scenes/main.d.ts +2 -1
  153. package/dist/src/app-opentui/scenes/main.js +264 -29
  154. package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
  155. package/dist/src/app-opentui/scenes/pi.js +508 -0
  156. package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
  157. package/dist/src/app-opentui/scenes/plugin.js +486 -0
  158. package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
  159. package/dist/src/app-opentui/scenes/repo.js +424 -0
  160. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
  161. package/dist/src/app-opentui/scenes/run-detail.js +362 -35
  162. package/dist/src/app-opentui/scenes/server.d.ts +2 -1
  163. package/dist/src/app-opentui/scenes/server.js +243 -26
  164. package/dist/src/app-opentui/scenes/tasks.js +518 -41
  165. package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
  166. package/dist/src/app-opentui/scenes/workspace.js +426 -0
  167. package/dist/src/app-opentui/selectable.d.ts +19 -0
  168. package/dist/src/app-opentui/selectable.js +79 -0
  169. package/dist/src/app-opentui/state.js +129 -36
  170. package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
  171. package/dist/src/app-opentui/surface-catalog.js +540 -0
  172. package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
  173. package/dist/src/app-opentui/terminal-capabilities.js +15 -0
  174. package/dist/src/app-opentui/theme.d.ts +28 -6
  175. package/dist/src/app-opentui/theme.js +61 -8
  176. package/dist/src/app-opentui/types.d.ts +130 -5
  177. package/dist/src/commands/_authority-runs.d.ts +1 -1
  178. package/dist/src/commands/_authority-runs.js +2 -12
  179. package/dist/src/commands/_doctor-checks.js +62 -13
  180. package/dist/src/commands/_help-catalog.js +95 -15
  181. package/dist/src/commands/_operator-view.js +97 -15
  182. package/dist/src/commands/_pi-frontend.d.ts +2 -0
  183. package/dist/src/commands/_pi-frontend.js +97 -13
  184. package/dist/src/commands/_preflight.js +64 -14
  185. package/dist/src/commands/_server-client.js +82 -18
  186. package/dist/src/commands/_server-events.d.ts +26 -0
  187. package/dist/src/commands/_server-events.js +310 -0
  188. package/dist/src/commands/_snapshot-upload.js +62 -13
  189. package/dist/src/commands/agent.js +2 -12
  190. package/dist/src/commands/connect.js +7 -1
  191. package/dist/src/commands/doctor.js +62 -13
  192. package/dist/src/commands/github.js +144 -23
  193. package/dist/src/commands/inbox.js +62 -13
  194. package/dist/src/commands/init.js +82 -18
  195. package/dist/src/commands/inspect.js +62 -13
  196. package/dist/src/commands/run.js +100 -15
  197. package/dist/src/commands/server.js +71 -26
  198. package/dist/src/commands/setup.js +62 -13
  199. package/dist/src/commands/stats.js +157 -28
  200. package/dist/src/commands/task-run-driver.js +64 -25
  201. package/dist/src/commands/task.js +196 -43
  202. package/dist/src/commands.js +419 -123
  203. package/dist/src/index.js +426 -130
  204. package/package.json +11 -10
  205. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
  206. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
@@ -0,0 +1,486 @@
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: "#14161b",
15
+ glass: "#1e2230",
16
+ border: "#2a2e3a",
17
+ ink: "#f4f5f8",
18
+ ink2: "#c7c9d3",
19
+ ink3: "#9aa0ae",
20
+ ink4: "#787b86",
21
+ lime: "#ccff4d",
22
+ limeDim: "#a9d63f",
23
+ cyan: "#56d8ff",
24
+ cyanDim: "#3f9fbd",
25
+ red: "#ff5d5d",
26
+ yellow: "#ffd24d",
27
+ magenta: "#ff79b0"
28
+ };
29
+ var styles = {
30
+ ink: otuiFg(RIG_UI.ink),
31
+ ink2: otuiFg(RIG_UI.ink2),
32
+ ink3: otuiFg(RIG_UI.ink3),
33
+ ink4: otuiFg(RIG_UI.ink4),
34
+ lime: otuiFg(RIG_UI.lime),
35
+ limeDim: otuiFg(RIG_UI.limeDim),
36
+ cyan: otuiFg(RIG_UI.cyan),
37
+ red: otuiFg(RIG_UI.red),
38
+ yellow: otuiFg(RIG_UI.yellow),
39
+ magenta: otuiFg(RIG_UI.magenta)
40
+ };
41
+ function statusColor(status) {
42
+ switch (status) {
43
+ case "success":
44
+ case "completed":
45
+ case "merged":
46
+ return RIG_UI.lime;
47
+ case "running":
48
+ case "preparing":
49
+ case "created":
50
+ case "validating":
51
+ case "reviewing":
52
+ case "closing-out":
53
+ case "stopping":
54
+ case "loading":
55
+ case "action":
56
+ return RIG_UI.cyan;
57
+ case "needs-attention":
58
+ case "needs_attention":
59
+ return RIG_UI.yellow;
60
+ case "failed":
61
+ case "error":
62
+ return RIG_UI.red;
63
+ default:
64
+ return RIG_UI.ink3;
65
+ }
66
+ }
67
+ function statusGlyph(status) {
68
+ switch (status) {
69
+ case "success":
70
+ case "completed":
71
+ case "merged":
72
+ return "\u2713";
73
+ case "running":
74
+ return "\u25CF";
75
+ case "preparing":
76
+ case "created":
77
+ case "validating":
78
+ case "reviewing":
79
+ case "closing-out":
80
+ case "stopping":
81
+ case "loading":
82
+ case "action":
83
+ return "\u25D0";
84
+ case "needs-attention":
85
+ case "needs_attention":
86
+ return "\u26A0";
87
+ case "failed":
88
+ case "error":
89
+ return "\u2717";
90
+ default:
91
+ return "\xB7";
92
+ }
93
+ }
94
+ function noColorActive() {
95
+ const noColor = process.env.NO_COLOR;
96
+ if (noColor !== undefined && noColor !== "") {
97
+ return true;
98
+ }
99
+ return process.env.RIG_NO_COLOR !== undefined;
100
+ }
101
+ function statusLabel(status) {
102
+ return {
103
+ glyph: statusGlyph(status),
104
+ color: noColorActive() ? RIG_UI.ink : statusColor(status)
105
+ };
106
+ }
107
+
108
+ // packages/cli/src/app-opentui/drone.ts
109
+ import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
110
+ var MINI_DRONE = [
111
+ "(!!!) (!!!)",
112
+ " \\%==%/ ",
113
+ " %%?%% ",
114
+ " /%==%\\ ",
115
+ "(!!!) (!!!)"
116
+ ];
117
+ var LEAD_MARK = [
118
+ " .-=-. ",
119
+ "=%%?%%=",
120
+ " '-=-' "
121
+ ];
122
+ var BLADE_FRAMES = ["---", "\\\\\\", "|||", "///"];
123
+ var EYE_FRAMES = ["o", "@", "\u2022", "."];
124
+ var COLOR = {
125
+ body: RGBA.fromHex(RIG_UI.lime),
126
+ mini: RGBA.fromHex(RIG_UI.limeDim),
127
+ rotor: RGBA.fromHex(RIG_UI.cyan),
128
+ path: RGBA.fromHex(RIG_UI.cyan),
129
+ eye: RGBA.fromHex(RIG_UI.ink),
130
+ dim: RGBA.fromHex(RIG_UI.ink4),
131
+ ink: RGBA.fromHex(RIG_UI.ink2)
132
+ };
133
+ function bladeForTick(tick, phase = 0) {
134
+ return BLADE_FRAMES[(Math.floor(tick / 3) + phase) % BLADE_FRAMES.length];
135
+ }
136
+ function eyeForTick(tick, phase = 0) {
137
+ const pulse = Math.sin(tick * 0.09 + phase);
138
+ return pulse > 0.55 ? EYE_FRAMES[1] : pulse > 0.1 ? EYE_FRAMES[0] : pulse > -0.45 ? EYE_FRAMES[2] : EYE_FRAMES[3];
139
+ }
140
+ function chunk(text, fg, bold = false, dim = false) {
141
+ let attributes = TextAttributes2.NONE;
142
+ if (bold)
143
+ attributes |= TextAttributes2.BOLD;
144
+ if (dim)
145
+ attributes |= TextAttributes2.DIM;
146
+ return { __isChunk: true, text, fg, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
147
+ }
148
+ function styledLine(text, colorFor) {
149
+ const chunks = [];
150
+ let run = "";
151
+ let runColor = null;
152
+ const flush = () => {
153
+ if (!run || !runColor)
154
+ return;
155
+ chunks.push(chunk(run, COLOR[runColor], runColor === "body" || runColor === "eye", runColor === "dim"));
156
+ run = "";
157
+ };
158
+ for (const char of text) {
159
+ const next = colorFor(char);
160
+ if (next !== runColor) {
161
+ flush();
162
+ runColor = next;
163
+ }
164
+ run += char;
165
+ }
166
+ flush();
167
+ return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
168
+ }
169
+ function droneColor(char) {
170
+ if (char === "?" || char === "o" || char === "@" || char === "\u2022")
171
+ return "eye";
172
+ if (char === "%" || char === "=")
173
+ return "mini";
174
+ if (char === "$")
175
+ return "body";
176
+ if (char === "(" || char === ")" || char === "/" || char === "\\" || char === "|" || char === "-")
177
+ return "rotor";
178
+ if (char === "\xB7" || char === "\u2022" || char === "'" || char === ".")
179
+ return "path";
180
+ if (char.trim() === "")
181
+ return "dim";
182
+ return "ink";
183
+ }
184
+ function motionColor(char) {
185
+ if (char === "\u25CF" || char === "\u25C6" || char === "\u25C9")
186
+ return "body";
187
+ if (char === "\u2022" || char === "\xB7" || char === "\u2500" || char === "\u2502" || char === "\u2571" || char === "\u2572" || char === "\u256D" || char === "\u256E" || char === "\u2570" || char === "\u256F")
188
+ return "path";
189
+ if (char === "\u258C" || char === "\u2590" || char === "\u2581" || char === "\u2594")
190
+ return "mini";
191
+ return droneColor(char);
192
+ }
193
+ function materializeDrone(lines, tick, phase = 0) {
194
+ const blade = bladeForTick(tick, phase);
195
+ const eye = eyeForTick(tick, phase);
196
+ return lines.map((line) => line.replaceAll("!!!", blade).replaceAll("?", eye));
197
+ }
198
+ function miniDroneLines(tick, align = "left", phase = 0) {
199
+ return materializeDrone(MINI_DRONE, tick, phase).map((text) => ({
200
+ text,
201
+ styledText: styledLine(text, droneColor),
202
+ fg: RIG_UI.limeDim,
203
+ align
204
+ }));
205
+ }
206
+ function brandFleetLines(tick, align = "center") {
207
+ const left = materializeDrone(MINI_DRONE, tick, 0);
208
+ const right = materializeDrone(MINI_DRONE, tick, 2);
209
+ const lead = materializeDrone(LEAD_MARK, tick, 1);
210
+ const packet = ["\xB7", "\u2022", "\u25CF", "\u2022"][Math.floor(tick / 2) % 4];
211
+ const bridge = [
212
+ ` ${left[0]} ${lead[0]} ${right[0]}`,
213
+ ` ${left[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${lead[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${right[1]}`,
214
+ ` ${left[2]} \xB7' '${lead[2]}' '\xB7 ${right[2]}`,
215
+ ` ${left[3]} \u2572 signal bus \u2571 ${right[3]}`,
216
+ ` ${left[4]} \xB7\u2500\u2500\u2500${packet}\u2500\u2500\u2500\u2500\u2500\u2500${packet}\u2500\u2500\u2500\xB7 ${right[4]}`
217
+ ];
218
+ return bridge.map((text) => ({
219
+ text,
220
+ styledText: styledLine(text, motionColor),
221
+ fg: RIG_UI.limeDim,
222
+ align
223
+ }));
224
+ }
225
+ function actionDrone(tick, phase = 0) {
226
+ const blade = bladeForTick(tick, phase);
227
+ const eye = eyeForTick(tick, phase);
228
+ return `(${blade})\u2572${eye}\u2571(${blade})`;
229
+ }
230
+ function actionDroneLine(tick, text, fg = RIG_UI.ink2) {
231
+ const prefix = actionDrone(tick);
232
+ const content = `${prefix} ${text}`;
233
+ return { text: content, styledText: styledLine(content, motionColor), fg, align: "center" };
234
+ }
235
+
236
+ // packages/cli/src/app-opentui/render/scene.ts
237
+ function line(text, options = {}) {
238
+ return { text, ...options };
239
+ }
240
+ function blank() {
241
+ return { text: "" };
242
+ }
243
+ function deckRow(input) {
244
+ const prefix = input.active ? "\u25B8" : " ";
245
+ const label = input.label.toUpperCase().padEnd(10);
246
+ return line(`${prefix} ${label} ${input.detail}`, {
247
+ fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
248
+ bold: input.active,
249
+ selectableIndex: input.index,
250
+ activateOnClick: input.activateOnClick
251
+ });
252
+ }
253
+ function loadingRows(label, tick = 0, compact = false) {
254
+ const mascot = compact ? miniDroneLines(tick, "center") : brandFleetLines(tick, "center");
255
+ return [
256
+ blank(),
257
+ ...mascot,
258
+ blank(),
259
+ { ...actionDroneLine(tick, `loading ${label}\u2026`, RIG_UI.cyan), align: "center" }
260
+ ];
261
+ }
262
+ function errorBanner(message, hint) {
263
+ return [
264
+ line(`\u2717 failed to load \u2014 ${message}`, { fg: RIG_UI.red, bold: true }),
265
+ ...hint ? [line(` ${hint}`, { fg: RIG_UI.ink3 })] : [],
266
+ line(" select refresh/retry below", { fg: RIG_UI.ink4 }),
267
+ line("", { fg: RIG_UI.ink3 })
268
+ ];
269
+ }
270
+ function lastRefreshError(state) {
271
+ const value = state.data.lastRefreshError;
272
+ return typeof value === "string" && value.trim() ? value : undefined;
273
+ }
274
+ function makeSceneFrame(input) {
275
+ return input;
276
+ }
277
+
278
+ // packages/cli/src/app-opentui/selectable.ts
279
+ function selectableDeckRow(deck, item) {
280
+ return { ...deckRow({ ...deck, activateOnClick: true }), selectable: item };
281
+ }
282
+ function withSelectable(line2, item) {
283
+ return { ...line2, selectable: item, activateOnClick: true };
284
+ }
285
+
286
+ // packages/cli/src/app-opentui/scenes/plugin.ts
287
+ var PLUGIN_ACTIONS = [
288
+ { detail: "run plugin validators against a task id (renders an in-app pass/fail board)", item: { id: "plugin-validate", label: "validate", prompt: { label: "plugin validate --task", scene: "plugin", argv: ["plugin", "validate"], intentKind: "refresh", payloadBase: {}, payloadKey: "task" }, message: "validate plugins against a task" } },
289
+ { detail: "reload rig.config plugin contributions", item: { id: "plugin-refresh", label: "refresh", intent: { scene: "plugin", argv: ["plugin", "list"], action: { kind: "refresh", label: "Refresh plugins" } }, message: "reload plugins" } }
290
+ ];
291
+ function snapshot(state) {
292
+ const value = state.data.plugin;
293
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
294
+ }
295
+ function validation(state) {
296
+ const value = state.data.pluginValidation;
297
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
298
+ }
299
+ var PLUGIN_VALIDATION_CLEAR_ITEM = {
300
+ id: "plugin-validate-clear",
301
+ label: "clear",
302
+ data: { pluginValidation: undefined },
303
+ message: "clear the validate board"
304
+ };
305
+ function selectedPlugin(state) {
306
+ const value = state.data.selectedPlugin;
307
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
308
+ }
309
+ var PLUGIN_BACK_ITEM = {
310
+ id: "plugin-back",
311
+ label: "back",
312
+ data: { selectedPlugin: undefined },
313
+ message: "back to plugin list"
314
+ };
315
+ function panelWidth(layout) {
316
+ return layout?.centerWidth ?? 118;
317
+ }
318
+ function panelHeight(layout) {
319
+ return Math.max(18, layout?.centerHeight ?? 34);
320
+ }
321
+ function contributionLines(label, ids, meta) {
322
+ if (ids.length === 0)
323
+ return [];
324
+ const byId = new Map(meta.map((entry) => [entry.id, entry]));
325
+ const rows = [line(` ${label.padEnd(14)}`, { fg: RIG_UI.ink3, bold: true })];
326
+ for (const id of ids) {
327
+ const entry = byId.get(id);
328
+ const tag = entry?.tag ?? "\u2014";
329
+ rows.push(line(` \xB7 ${id.padEnd(26).slice(0, 26)} [${tag}]`, { fg: RIG_UI.ink2 }));
330
+ if (entry?.description) {
331
+ rows.push(line(` ${entry.description}`, { fg: RIG_UI.ink4 }));
332
+ }
333
+ }
334
+ return rows;
335
+ }
336
+ function validationRow(result) {
337
+ const { glyph, color } = statusLabel(result.passed ? "success" : "failed");
338
+ const summary = result.summary.replace(/\s+/g, " ").trim();
339
+ const rows = [
340
+ line(` ${glyph} ${result.id.padEnd(28).slice(0, 28)} ${summary}`, { fg: color, bold: !result.passed })
341
+ ];
342
+ if (!result.passed && result.details) {
343
+ for (const detailLine of result.details.split(`
344
+ `).slice(0, 12)) {
345
+ rows.push(line(` ${detailLine}`, { fg: RIG_UI.ink4 }));
346
+ }
347
+ }
348
+ return rows;
349
+ }
350
+ function validationBoard(report) {
351
+ const allPassed = report.failed === 0 && report.results.length > 0;
352
+ const headColor = report.results.length === 0 ? RIG_UI.ink4 : allPassed ? statusLabel("success").color : statusLabel("failed").color;
353
+ const rows = [
354
+ line(`VALIDATE \xB7 ${report.taskId} \xB7 ${report.passed} passed / ${report.failed} failed`, { fg: headColor, bold: true }),
355
+ blank()
356
+ ];
357
+ if (report.results.length === 0) {
358
+ rows.push(line(" No plugin validators are registered for this project.", { fg: RIG_UI.ink4 }));
359
+ } else {
360
+ for (const result of report.results)
361
+ rows.push(...validationRow(result));
362
+ }
363
+ rows.push(blank(), selectableDeckRow({ label: "clear", detail: "dismiss the validate board", index: 0, active: false }, PLUGIN_VALIDATION_CLEAR_ITEM));
364
+ return rows;
365
+ }
366
+ function contributionCount(plugin) {
367
+ return plugin.validators.length + plugin.hooks.length + plugin.agentRoles.length + plugin.repoSources.length + plugin.taskSources.length + plugin.skills.length + plugin.taskFieldExtensions.length + plugin.cliCommands.length;
368
+ }
369
+ function pluginListRow(plugin) {
370
+ const { glyph, color } = statusLabel("success");
371
+ const row = line(` ${glyph} ${`${plugin.name}@${plugin.version}`.padEnd(34).slice(0, 34)} ${contributionCount(plugin)} contributions \u203A`, { fg: color, bold: true });
372
+ const drill = {
373
+ id: `plugin-detail:${plugin.name}`,
374
+ label: plugin.name,
375
+ data: { selectedPlugin: plugin.name },
376
+ message: `open ${plugin.name} detail`
377
+ };
378
+ return withSelectable(row, drill);
379
+ }
380
+ function pluginDetail(plugin, meta) {
381
+ const { glyph, color } = statusLabel("success");
382
+ const cliById = new Map(meta.cliCommands.map((entry) => [entry.id, entry]));
383
+ const rows = [
384
+ line(`${glyph} ${plugin.name}@${plugin.version}`, { fg: color, bold: true }),
385
+ blank(),
386
+ line("CONTRIBUTIONS", { fg: RIG_UI.ink3, bold: true }),
387
+ ...contributionLines("validators", plugin.validators, meta.validators),
388
+ ...contributionLines("hooks", plugin.hooks, meta.hooks),
389
+ ...contributionLines("agent-roles", plugin.agentRoles, meta.agentRoles),
390
+ ...contributionLines("repo-sources", plugin.repoSources, meta.repoSources),
391
+ ...contributionLines("task-sources", plugin.taskSources, meta.taskSources),
392
+ ...contributionLines("skills", plugin.skills, meta.skills),
393
+ ...contributionLines("task-fields", plugin.taskFieldExtensions, meta.taskFieldExtensions),
394
+ ...contributionCount(plugin) === 0 ? [line(" (no contributions)", { fg: RIG_UI.ink4 })] : [],
395
+ blank(),
396
+ line(`CLI COMMANDS \xB7 ${plugin.cliCommands.length}`, { fg: RIG_UI.ink3, bold: true })
397
+ ];
398
+ if (plugin.cliCommands.length === 0) {
399
+ rows.push(line(" (none)", { fg: RIG_UI.ink4 }));
400
+ } else {
401
+ plugin.cliCommands.forEach((id, index) => {
402
+ const entry = cliById.get(id);
403
+ const detail = entry?.tag ? `${entry.tag}${entry.description ? ` \u2014 ${entry.description}` : ""}` : `plugin run ${id}`;
404
+ rows.push(selectableDeckRow({ label: "run", detail, index, active: false }, { id: `plugin-run:${id}`, label: `plugin run ${id}`, intent: { scene: "command", argv: ["plugin", "run", id], action: { kind: "command-run", label: `Run plugin command ${id}` } }, message: `run plugin command ${id}` }));
405
+ });
406
+ }
407
+ rows.push(blank(), selectableDeckRow({ label: "back", detail: "return to the plugin list", index: Math.max(0, plugin.cliCommands.length), active: false }, PLUGIN_BACK_ITEM));
408
+ return rows;
409
+ }
410
+ function renderPluginScene(state, layout) {
411
+ const plugin = snapshot(state);
412
+ const selected = Math.max(0, Math.min(PLUGIN_ACTIONS.length - 1, state.selection.index));
413
+ const loading = state.status === "loading" && !plugin;
414
+ const refreshError = lastRefreshError(state);
415
+ const plugins = plugin?.plugins ?? [];
416
+ const contributionMeta = plugin?.contributionMeta ?? {
417
+ validators: [],
418
+ hooks: [],
419
+ agentRoles: [],
420
+ repoSources: [],
421
+ taskSources: [],
422
+ skills: [],
423
+ taskFieldExtensions: [],
424
+ cliCommands: []
425
+ };
426
+ const drilled = selectedPlugin(state);
427
+ const detailPlugin = drilled ? plugins.find((entry) => entry.name === drilled) : undefined;
428
+ const report = validation(state);
429
+ const panelLines = detailPlugin ? [
430
+ ...refreshError && !state.error ? errorBanner(refreshError) : [],
431
+ line(`PLUGIN \xB7 ${detailPlugin.name}`, { fg: RIG_UI.ink3, bold: true }),
432
+ blank(),
433
+ ...pluginDetail(detailPlugin, contributionMeta)
434
+ ] : report ? [
435
+ ...refreshError && !state.error ? errorBanner(refreshError) : [],
436
+ line("plugin validators (in-app pass/fail board)", { fg: RIG_UI.ink3 }),
437
+ blank(),
438
+ ...validationBoard(report)
439
+ ] : [
440
+ ...refreshError && !state.error ? errorBanner(refreshError) : [],
441
+ line("plugin contributions (rig.config.ts)", { fg: RIG_UI.ink3 }),
442
+ blank(),
443
+ line("ACTIONS", { fg: RIG_UI.ink3, bold: true }),
444
+ ...PLUGIN_ACTIONS.map(({ detail, item }, index) => selectableDeckRow({ label: item.label, detail, index, active: selected === index }, item)),
445
+ blank(),
446
+ ...loading ? loadingRows("plugins", state.tick) : [
447
+ line(`PLUGINS \xB7 ${plugins.length}`, { fg: RIG_UI.ink3, bold: true }),
448
+ ...plugins.length > 0 ? plugins.map((entry) => pluginListRow(entry)) : [
449
+ line(" No plugins loaded.", { fg: RIG_UI.ink4 }),
450
+ line(" Declare plugins in rig.config.ts (and run bun install if it imports @rig/* packages).", { fg: RIG_UI.ink4 })
451
+ ]
452
+ ],
453
+ blank(),
454
+ line("enter/click a plugin to drill into its contributions \xB7 validate runs the validators in-app", { fg: RIG_UI.ink4 })
455
+ ];
456
+ const headerText = detailPlugin ? `rig plugin \xB7 ${detailPlugin.name}` : report ? `rig plugin validate \xB7 ${report.taskId} \xB7 ${report.passed}/${report.results.length} passed` : `rig plugin \xB7 ${plugins.length} loaded`;
457
+ const footerMessage = detailPlugin ? `${detailPlugin.name} \u2014 back returns to list` : report ? `validate ${report.taskId} \u2014 ${report.passed} passed, ${report.failed} failed \xB7 clear returns to list` : plugin ? `${plugins.length} plugins` : "loading plugins";
458
+ return makeSceneFrame({
459
+ scene: "plugin",
460
+ title: "Plugins",
461
+ lines: [],
462
+ panels: [{
463
+ id: "plugin-list",
464
+ top: 0,
465
+ width: panelWidth(layout),
466
+ height: panelHeight(layout),
467
+ lines: panelLines,
468
+ backgroundColor: RIG_UI.panel,
469
+ backgroundAlpha: 184,
470
+ opacity: 0.98,
471
+ border: false,
472
+ stickyScroll: true,
473
+ stickyStart: "top",
474
+ chrome: "ad-terminal",
475
+ headerText,
476
+ headerHeight: 3,
477
+ paddingX: layout?.compact ? 3 : 5,
478
+ paddingY: 2
479
+ }],
480
+ footer: { message: footerMessage },
481
+ live: state.status === "action" || !plugin
482
+ });
483
+ }
484
+ export {
485
+ renderPluginScene
486
+ };
@@ -0,0 +1,3 @@
1
+ import type { AppSceneFrame, AppState } from "../types";
2
+ import type { StageLayout } from "../layout";
3
+ export declare function renderRepoScene(state: AppState, layout?: StageLayout): AppSceneFrame;