@h-rig/cli 0.0.6-alpha.89 → 0.0.6-alpha.90

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 (231) hide show
  1. package/dist/bin/build-rig-binaries.js +8 -40
  2. package/dist/bin/rig.js +12519 -26675
  3. package/dist/src/app/board.js +74 -693
  4. package/dist/src/app/drone-ui.js +1 -1
  5. package/dist/src/app/theme.js +0 -1
  6. package/dist/src/commands/_async-ui.js +1 -1
  7. package/dist/src/commands/_authority-runs.d.ts +1 -1
  8. package/dist/src/commands/_authority-runs.js +12 -2
  9. package/dist/src/commands/_cli-format.d.ts +1 -10
  10. package/dist/src/commands/_cli-format.js +2 -5
  11. package/dist/src/commands/_connection-state.d.ts +1 -11
  12. package/dist/src/commands/_connection-state.js +5 -50
  13. package/dist/src/commands/_doctor-checks.js +40 -501
  14. package/dist/src/commands/_help-catalog.js +17 -99
  15. package/dist/src/commands/_json-output.js +0 -4
  16. package/dist/src/commands/_operator-view.js +54 -575
  17. package/dist/src/commands/_pi-frontend.d.ts +0 -27
  18. package/dist/src/commands/_pi-frontend.js +52 -576
  19. package/dist/src/commands/_preflight.js +66 -553
  20. package/dist/src/commands/_server-client.d.ts +0 -33
  21. package/dist/src/commands/_server-client.js +46 -541
  22. package/dist/src/commands/_snapshot-upload.js +42 -503
  23. package/dist/src/commands/_spinner.js +1 -1
  24. package/dist/src/commands/agent.js +12 -2
  25. package/dist/src/commands/browser.js +1 -1
  26. package/dist/src/commands/connect.js +15 -626
  27. package/dist/src/commands/doctor.js +41 -502
  28. package/dist/src/commands/github.js +51 -584
  29. package/dist/src/commands/inbox.js +41 -502
  30. package/dist/src/commands/init.js +74 -561
  31. package/dist/src/commands/inspect.js +41 -502
  32. package/dist/src/commands/run.js +54 -578
  33. package/dist/src/commands/server.js +163 -692
  34. package/dist/src/commands/setup.js +46 -507
  35. package/dist/src/commands/stats.js +58 -601
  36. package/dist/src/commands/task-run-driver.js +58 -509
  37. package/dist/src/commands/task.js +110 -729
  38. package/dist/src/commands.js +237 -1112
  39. package/dist/src/index.js +244 -1123
  40. package/dist/src/launcher.js +0 -4
  41. package/package.json +9 -13
  42. package/dist/src/app-opentui/adapters/command.d.ts +0 -2
  43. package/dist/src/app-opentui/adapters/command.js +0 -329
  44. package/dist/src/app-opentui/adapters/common.d.ts +0 -56
  45. package/dist/src/app-opentui/adapters/common.js +0 -153
  46. package/dist/src/app-opentui/adapters/doctor.d.ts +0 -9
  47. package/dist/src/app-opentui/adapters/doctor.js +0 -1217
  48. package/dist/src/app-opentui/adapters/family.d.ts +0 -62
  49. package/dist/src/app-opentui/adapters/family.js +0 -14855
  50. package/dist/src/app-opentui/adapters/fleet.d.ts +0 -14
  51. package/dist/src/app-opentui/adapters/fleet.js +0 -1335
  52. package/dist/src/app-opentui/adapters/inbox.d.ts +0 -43
  53. package/dist/src/app-opentui/adapters/inbox.js +0 -1944
  54. package/dist/src/app-opentui/adapters/init.d.ts +0 -11
  55. package/dist/src/app-opentui/adapters/init.js +0 -2818
  56. package/dist/src/app-opentui/adapters/inspect.d.ts +0 -52
  57. package/dist/src/app-opentui/adapters/inspect.js +0 -1455
  58. package/dist/src/app-opentui/adapters/pi-attach.d.ts +0 -32
  59. package/dist/src/app-opentui/adapters/pi-attach.js +0 -2101
  60. package/dist/src/app-opentui/adapters/pi.d.ts +0 -23
  61. package/dist/src/app-opentui/adapters/pi.js +0 -363
  62. package/dist/src/app-opentui/adapters/plugin.d.ts +0 -84
  63. package/dist/src/app-opentui/adapters/plugin.js +0 -544
  64. package/dist/src/app-opentui/adapters/repo.d.ts +0 -37
  65. package/dist/src/app-opentui/adapters/repo.js +0 -186
  66. package/dist/src/app-opentui/adapters/run-detail.d.ts +0 -27
  67. package/dist/src/app-opentui/adapters/run-detail.js +0 -1441
  68. package/dist/src/app-opentui/adapters/server.d.ts +0 -48
  69. package/dist/src/app-opentui/adapters/server.js +0 -1561
  70. package/dist/src/app-opentui/adapters/tasks.d.ts +0 -64
  71. package/dist/src/app-opentui/adapters/tasks.js +0 -4524
  72. package/dist/src/app-opentui/adapters/workspace.d.ts +0 -49
  73. package/dist/src/app-opentui/adapters/workspace.js +0 -333
  74. package/dist/src/app-opentui/autocomplete.d.ts +0 -20
  75. package/dist/src/app-opentui/autocomplete.js +0 -578
  76. package/dist/src/app-opentui/bootstrap.d.ts +0 -11
  77. package/dist/src/app-opentui/bootstrap.js +0 -27833
  78. package/dist/src/app-opentui/command-palette.d.ts +0 -3
  79. package/dist/src/app-opentui/command-palette.js +0 -1038
  80. package/dist/src/app-opentui/command-pty-host.d.ts +0 -62
  81. package/dist/src/app-opentui/command-pty-host.js +0 -248
  82. package/dist/src/app-opentui/drone.d.ts +0 -12
  83. package/dist/src/app-opentui/drone.js +0 -230
  84. package/dist/src/app-opentui/events.d.ts +0 -7
  85. package/dist/src/app-opentui/events.js +0 -28
  86. package/dist/src/app-opentui/fleet-stats.d.ts +0 -32
  87. package/dist/src/app-opentui/fleet-stats.js +0 -114
  88. package/dist/src/app-opentui/focus-manager.d.ts +0 -14
  89. package/dist/src/app-opentui/focus-manager.js +0 -24
  90. package/dist/src/app-opentui/index.d.ts +0 -8
  91. package/dist/src/app-opentui/index.js +0 -5260
  92. package/dist/src/app-opentui/intent.d.ts +0 -3
  93. package/dist/src/app-opentui/intent.js +0 -365
  94. package/dist/src/app-opentui/keymap.d.ts +0 -21
  95. package/dist/src/app-opentui/keymap.js +0 -1377
  96. package/dist/src/app-opentui/launch-routing.d.ts +0 -16
  97. package/dist/src/app-opentui/launch-routing.js +0 -55
  98. package/dist/src/app-opentui/layout.d.ts +0 -22
  99. package/dist/src/app-opentui/layout.js +0 -51
  100. package/dist/src/app-opentui/list-search.d.ts +0 -36
  101. package/dist/src/app-opentui/list-search.js +0 -130
  102. package/dist/src/app-opentui/pi-host-child.d.ts +0 -2
  103. package/dist/src/app-opentui/pi-host-child.js +0 -1299
  104. package/dist/src/app-opentui/pi-pty-host.d.ts +0 -28
  105. package/dist/src/app-opentui/pi-pty-host.js +0 -10
  106. package/dist/src/app-opentui/react/App.d.ts +0 -9
  107. package/dist/src/app-opentui/react/App.js +0 -3866
  108. package/dist/src/app-opentui/react/Backdrop.d.ts +0 -5
  109. package/dist/src/app-opentui/react/Backdrop.js +0 -823
  110. package/dist/src/app-opentui/react/ChromeHost.d.ts +0 -5
  111. package/dist/src/app-opentui/react/ChromeHost.js +0 -1539
  112. package/dist/src/app-opentui/react/SceneFrameView.d.ts +0 -7
  113. package/dist/src/app-opentui/react/SceneFrameView.js +0 -579
  114. package/dist/src/app-opentui/react/context.d.ts +0 -17
  115. package/dist/src/app-opentui/react/context.js +0 -37
  116. package/dist/src/app-opentui/react/launch.d.ts +0 -2
  117. package/dist/src/app-opentui/react/launch.js +0 -4897
  118. package/dist/src/app-opentui/react/nav.d.ts +0 -18
  119. package/dist/src/app-opentui/react/nav.js +0 -54
  120. package/dist/src/app-opentui/react/scroll.d.ts +0 -12
  121. package/dist/src/app-opentui/react/scroll.js +0 -21
  122. package/dist/src/app-opentui/react/syntax.d.ts +0 -2
  123. package/dist/src/app-opentui/react/syntax.js +0 -65
  124. package/dist/src/app-opentui/registry.d.ts +0 -4
  125. package/dist/src/app-opentui/registry.js +0 -22876
  126. package/dist/src/app-opentui/remote-link.d.ts +0 -10
  127. package/dist/src/app-opentui/remote-link.js +0 -47
  128. package/dist/src/app-opentui/render/ascii-fleet.d.ts +0 -15
  129. package/dist/src/app-opentui/render/ascii-fleet.js +0 -82
  130. package/dist/src/app-opentui/render/constants.d.ts +0 -30
  131. package/dist/src/app-opentui/render/constants.js +0 -64
  132. package/dist/src/app-opentui/render/graphics.d.ts +0 -40
  133. package/dist/src/app-opentui/render/graphics.js +0 -713
  134. package/dist/src/app-opentui/render/hover.d.ts +0 -11
  135. package/dist/src/app-opentui/render/hover.js +0 -34
  136. package/dist/src/app-opentui/render/native-host.d.ts +0 -37
  137. package/dist/src/app-opentui/render/native-host.js +0 -180
  138. package/dist/src/app-opentui/render/panel-layout.d.ts +0 -38
  139. package/dist/src/app-opentui/render/panel-layout.js +0 -48
  140. package/dist/src/app-opentui/render/panels.d.ts +0 -12
  141. package/dist/src/app-opentui/render/panels.js +0 -288
  142. package/dist/src/app-opentui/render/preloader.d.ts +0 -10
  143. package/dist/src/app-opentui/render/preloader.js +0 -166
  144. package/dist/src/app-opentui/render/scene.d.ts +0 -68
  145. package/dist/src/app-opentui/render/scene.js +0 -300
  146. package/dist/src/app-opentui/render/terminal-handoff.d.ts +0 -16
  147. package/dist/src/app-opentui/render/terminal-handoff.js +0 -14
  148. package/dist/src/app-opentui/render/text.d.ts +0 -29
  149. package/dist/src/app-opentui/render/text.js +0 -177
  150. package/dist/src/app-opentui/render/type-bar.d.ts +0 -15
  151. package/dist/src/app-opentui/render/type-bar.js +0 -212
  152. package/dist/src/app-opentui/runtime-resources.d.ts +0 -16
  153. package/dist/src/app-opentui/runtime-resources.js +0 -62
  154. package/dist/src/app-opentui/runtime.d.ts +0 -45
  155. package/dist/src/app-opentui/runtime.js +0 -5232
  156. package/dist/src/app-opentui/scenes/command.d.ts +0 -3
  157. package/dist/src/app-opentui/scenes/command.js +0 -118
  158. package/dist/src/app-opentui/scenes/doctor.d.ts +0 -3
  159. package/dist/src/app-opentui/scenes/doctor.js +0 -296
  160. package/dist/src/app-opentui/scenes/error.d.ts +0 -2
  161. package/dist/src/app-opentui/scenes/error.js +0 -277
  162. package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +0 -2
  163. package/dist/src/app-opentui/scenes/family-domains/agent.js +0 -349
  164. package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +0 -2
  165. package/dist/src/app-opentui/scenes/family-domains/browser.js +0 -196
  166. package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +0 -2
  167. package/dist/src/app-opentui/scenes/family-domains/dist.js +0 -244
  168. package/dist/src/app-opentui/scenes/family-domains/git.d.ts +0 -2
  169. package/dist/src/app-opentui/scenes/family-domains/git.js +0 -196
  170. package/dist/src/app-opentui/scenes/family-domains/github.d.ts +0 -2
  171. package/dist/src/app-opentui/scenes/family-domains/github.js +0 -275
  172. package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +0 -2
  173. package/dist/src/app-opentui/scenes/family-domains/harness.js +0 -153
  174. package/dist/src/app-opentui/scenes/family-domains/index.d.ts +0 -4
  175. package/dist/src/app-opentui/scenes/family-domains/index.js +0 -1680
  176. package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +0 -76
  177. package/dist/src/app-opentui/scenes/family-domains/kit.js +0 -306
  178. package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +0 -2
  179. package/dist/src/app-opentui/scenes/family-domains/profile.js +0 -213
  180. package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +0 -2
  181. package/dist/src/app-opentui/scenes/family-domains/queue.js +0 -147
  182. package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +0 -2
  183. package/dist/src/app-opentui/scenes/family-domains/remote.js +0 -519
  184. package/dist/src/app-opentui/scenes/family-domains/review.d.ts +0 -2
  185. package/dist/src/app-opentui/scenes/family-domains/review.js +0 -281
  186. package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +0 -2
  187. package/dist/src/app-opentui/scenes/family-domains/setup.js +0 -268
  188. package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +0 -2
  189. package/dist/src/app-opentui/scenes/family-domains/stats.js +0 -371
  190. package/dist/src/app-opentui/scenes/family.d.ts +0 -3
  191. package/dist/src/app-opentui/scenes/family.js +0 -2199
  192. package/dist/src/app-opentui/scenes/fleet.d.ts +0 -3
  193. package/dist/src/app-opentui/scenes/fleet.js +0 -766
  194. package/dist/src/app-opentui/scenes/handoff.d.ts +0 -2
  195. package/dist/src/app-opentui/scenes/handoff.js +0 -455
  196. package/dist/src/app-opentui/scenes/help.d.ts +0 -3
  197. package/dist/src/app-opentui/scenes/help.js +0 -725
  198. package/dist/src/app-opentui/scenes/inbox.d.ts +0 -3
  199. package/dist/src/app-opentui/scenes/inbox.js +0 -427
  200. package/dist/src/app-opentui/scenes/init.d.ts +0 -3
  201. package/dist/src/app-opentui/scenes/init.js +0 -181
  202. package/dist/src/app-opentui/scenes/inspect.d.ts +0 -3
  203. package/dist/src/app-opentui/scenes/inspect.js +0 -794
  204. package/dist/src/app-opentui/scenes/main.d.ts +0 -3
  205. package/dist/src/app-opentui/scenes/main.js +0 -332
  206. package/dist/src/app-opentui/scenes/pi.d.ts +0 -3
  207. package/dist/src/app-opentui/scenes/pi.js +0 -509
  208. package/dist/src/app-opentui/scenes/plugin.d.ts +0 -3
  209. package/dist/src/app-opentui/scenes/plugin.js +0 -487
  210. package/dist/src/app-opentui/scenes/repo.d.ts +0 -3
  211. package/dist/src/app-opentui/scenes/repo.js +0 -425
  212. package/dist/src/app-opentui/scenes/run-detail.d.ts +0 -3
  213. package/dist/src/app-opentui/scenes/run-detail.js +0 -467
  214. package/dist/src/app-opentui/scenes/server.d.ts +0 -3
  215. package/dist/src/app-opentui/scenes/server.js +0 -378
  216. package/dist/src/app-opentui/scenes/tasks.d.ts +0 -3
  217. package/dist/src/app-opentui/scenes/tasks.js +0 -768
  218. package/dist/src/app-opentui/scenes/workspace.d.ts +0 -3
  219. package/dist/src/app-opentui/scenes/workspace.js +0 -427
  220. package/dist/src/app-opentui/selectable.d.ts +0 -19
  221. package/dist/src/app-opentui/selectable.js +0 -80
  222. package/dist/src/app-opentui/state.d.ts +0 -4
  223. package/dist/src/app-opentui/state.js +0 -399
  224. package/dist/src/app-opentui/surface-catalog.d.ts +0 -20
  225. package/dist/src/app-opentui/surface-catalog.js +0 -542
  226. package/dist/src/app-opentui/theme.d.ts +0 -59
  227. package/dist/src/app-opentui/theme.js +0 -142
  228. package/dist/src/app-opentui/types.d.ts +0 -313
  229. package/dist/src/app-opentui/types.js +0 -1
  230. package/dist/src/commands/_server-events.d.ts +0 -26
  231. package/dist/src/commands/_server-events.js +0 -715
@@ -1,794 +0,0 @@
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
- hover: "#181b24",
16
- glass: "#1e2230",
17
- border: "#2a2e3a",
18
- ink: "#f4f5f8",
19
- ink2: "#c7c9d3",
20
- ink3: "#9aa0ae",
21
- ink4: "#787b86",
22
- lime: "#ccff4d",
23
- limeDim: "#a9d63f",
24
- cyan: "#56d8ff",
25
- cyanDim: "#3f9fbd",
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
- function statusColor(status) {
43
- switch (status) {
44
- case "success":
45
- case "completed":
46
- case "merged":
47
- return RIG_UI.lime;
48
- case "running":
49
- case "preparing":
50
- case "created":
51
- case "validating":
52
- case "reviewing":
53
- case "closing-out":
54
- case "stopping":
55
- case "loading":
56
- case "action":
57
- return RIG_UI.cyan;
58
- case "needs-attention":
59
- case "needs_attention":
60
- return RIG_UI.yellow;
61
- case "failed":
62
- case "error":
63
- return RIG_UI.red;
64
- default:
65
- return RIG_UI.ink3;
66
- }
67
- }
68
- function statusGlyph(status) {
69
- switch (status) {
70
- case "success":
71
- case "completed":
72
- case "merged":
73
- return "\u2713";
74
- case "running":
75
- return "\u25CF";
76
- case "preparing":
77
- case "created":
78
- case "validating":
79
- case "reviewing":
80
- case "closing-out":
81
- case "stopping":
82
- case "loading":
83
- case "action":
84
- return "\u25D0";
85
- case "needs-attention":
86
- case "needs_attention":
87
- return "\u26A0";
88
- case "failed":
89
- case "error":
90
- return "\u2717";
91
- default:
92
- return "\xB7";
93
- }
94
- }
95
- function noColorActive() {
96
- const noColor = process.env.NO_COLOR;
97
- if (noColor !== undefined && noColor !== "") {
98
- return true;
99
- }
100
- return process.env.RIG_NO_COLOR !== undefined;
101
- }
102
- function statusLabel(status) {
103
- return {
104
- glyph: statusGlyph(status),
105
- color: noColorActive() ? RIG_UI.ink : statusColor(status)
106
- };
107
- }
108
-
109
- // packages/cli/src/app-opentui/drone.ts
110
- import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
111
- var MINI_DRONE = [
112
- "(!!!) (!!!)",
113
- " \\%==%/ ",
114
- " %%?%% ",
115
- " /%==%\\ ",
116
- "(!!!) (!!!)"
117
- ];
118
- var LEAD_MARK = [
119
- " .-=-. ",
120
- "=%%?%%=",
121
- " '-=-' "
122
- ];
123
- var BLADE_FRAMES = ["---", "\\\\\\", "|||", "///"];
124
- var EYE_FRAMES = ["o", "@", "\u2022", "."];
125
- var COLOR = {
126
- body: RGBA.fromHex(RIG_UI.lime),
127
- mini: RGBA.fromHex(RIG_UI.limeDim),
128
- rotor: RGBA.fromHex(RIG_UI.cyan),
129
- path: RGBA.fromHex(RIG_UI.cyan),
130
- eye: RGBA.fromHex(RIG_UI.ink),
131
- dim: RGBA.fromHex(RIG_UI.ink4),
132
- ink: RGBA.fromHex(RIG_UI.ink2)
133
- };
134
- function bladeForTick(tick, phase = 0) {
135
- return BLADE_FRAMES[(Math.floor(tick / 3) + phase) % BLADE_FRAMES.length];
136
- }
137
- function eyeForTick(tick, phase = 0) {
138
- const pulse = Math.sin(tick * 0.09 + phase);
139
- return pulse > 0.55 ? EYE_FRAMES[1] : pulse > 0.1 ? EYE_FRAMES[0] : pulse > -0.45 ? EYE_FRAMES[2] : EYE_FRAMES[3];
140
- }
141
- function chunk(text, fg, bold = false, dim = false) {
142
- let attributes = TextAttributes2.NONE;
143
- if (bold)
144
- attributes |= TextAttributes2.BOLD;
145
- if (dim)
146
- attributes |= TextAttributes2.DIM;
147
- return { __isChunk: true, text, fg, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
148
- }
149
- function styledLine(text, colorFor) {
150
- const chunks = [];
151
- let run = "";
152
- let runColor = null;
153
- const flush = () => {
154
- if (!run || !runColor)
155
- return;
156
- chunks.push(chunk(run, COLOR[runColor], runColor === "body" || runColor === "eye", runColor === "dim"));
157
- run = "";
158
- };
159
- for (const char of text) {
160
- const next = colorFor(char);
161
- if (next !== runColor) {
162
- flush();
163
- runColor = next;
164
- }
165
- run += char;
166
- }
167
- flush();
168
- return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
169
- }
170
- function droneColor(char) {
171
- if (char === "?" || char === "o" || char === "@" || char === "\u2022")
172
- return "eye";
173
- if (char === "%" || char === "=")
174
- return "mini";
175
- if (char === "$")
176
- return "body";
177
- if (char === "(" || char === ")" || char === "/" || char === "\\" || char === "|" || char === "-")
178
- return "rotor";
179
- if (char === "\xB7" || char === "\u2022" || char === "'" || char === ".")
180
- return "path";
181
- if (char.trim() === "")
182
- return "dim";
183
- return "ink";
184
- }
185
- function motionColor(char) {
186
- if (char === "\u25CF" || char === "\u25C6" || char === "\u25C9")
187
- return "body";
188
- if (char === "\u2022" || char === "\xB7" || char === "\u2500" || char === "\u2502" || char === "\u2571" || char === "\u2572" || char === "\u256D" || char === "\u256E" || char === "\u2570" || char === "\u256F")
189
- return "path";
190
- if (char === "\u258C" || char === "\u2590" || char === "\u2581" || char === "\u2594")
191
- return "mini";
192
- return droneColor(char);
193
- }
194
- function materializeDrone(lines, tick, phase = 0) {
195
- const blade = bladeForTick(tick, phase);
196
- const eye = eyeForTick(tick, phase);
197
- return lines.map((line) => line.replaceAll("!!!", blade).replaceAll("?", eye));
198
- }
199
- function miniDroneLines(tick, align = "left", phase = 0) {
200
- return materializeDrone(MINI_DRONE, tick, phase).map((text) => ({
201
- text,
202
- styledText: styledLine(text, droneColor),
203
- fg: RIG_UI.limeDim,
204
- align
205
- }));
206
- }
207
- function brandFleetLines(tick, align = "center") {
208
- const left = materializeDrone(MINI_DRONE, tick, 0);
209
- const right = materializeDrone(MINI_DRONE, tick, 2);
210
- const lead = materializeDrone(LEAD_MARK, tick, 1);
211
- const packet = ["\xB7", "\u2022", "\u25CF", "\u2022"][Math.floor(tick / 2) % 4];
212
- const bridge = [
213
- ` ${left[0]} ${lead[0]} ${right[0]}`,
214
- ` ${left[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${lead[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${right[1]}`,
215
- ` ${left[2]} \xB7' '${lead[2]}' '\xB7 ${right[2]}`,
216
- ` ${left[3]} \u2572 signal bus \u2571 ${right[3]}`,
217
- ` ${left[4]} \xB7\u2500\u2500\u2500${packet}\u2500\u2500\u2500\u2500\u2500\u2500${packet}\u2500\u2500\u2500\xB7 ${right[4]}`
218
- ];
219
- return bridge.map((text) => ({
220
- text,
221
- styledText: styledLine(text, motionColor),
222
- fg: RIG_UI.limeDim,
223
- align
224
- }));
225
- }
226
- function actionDrone(tick, phase = 0) {
227
- const blade = bladeForTick(tick, phase);
228
- const eye = eyeForTick(tick, phase);
229
- return `(${blade})\u2572${eye}\u2571(${blade})`;
230
- }
231
- function actionDroneLine(tick, text, fg = RIG_UI.ink2) {
232
- const prefix = actionDrone(tick);
233
- const content = `${prefix} ${text}`;
234
- return { text: content, styledText: styledLine(content, motionColor), fg, align: "center" };
235
- }
236
-
237
- // packages/cli/src/app-opentui/render/scene.ts
238
- function line(text, options = {}) {
239
- return { text, ...options };
240
- }
241
- function blank() {
242
- return { text: "" };
243
- }
244
- function deckRow(input) {
245
- const prefix = input.active ? "\u25B8" : " ";
246
- const label = input.label.toUpperCase().padEnd(10);
247
- return line(`${prefix} ${label} ${input.detail}`, {
248
- fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
249
- bold: input.active,
250
- selectableIndex: input.index,
251
- activateOnClick: input.activateOnClick
252
- });
253
- }
254
- function loadingRows(label, tick = 0, compact = false) {
255
- const mascot = compact ? miniDroneLines(tick, "center") : brandFleetLines(tick, "center");
256
- return [
257
- blank(),
258
- ...mascot,
259
- blank(),
260
- { ...actionDroneLine(tick, `loading ${label}\u2026`, RIG_UI.cyan), align: "center" }
261
- ];
262
- }
263
- function errorBanner(message, hint) {
264
- return [
265
- line(`\u2717 failed to load \u2014 ${message}`, { fg: RIG_UI.red, bold: true }),
266
- ...hint ? [line(` ${hint}`, { fg: RIG_UI.ink3 })] : [],
267
- line(" select refresh/retry below", { fg: RIG_UI.ink4 }),
268
- line("", { fg: RIG_UI.ink3 })
269
- ];
270
- }
271
- function lastRefreshError(state) {
272
- const value = state.data.lastRefreshError;
273
- return typeof value === "string" && value.trim() ? value : undefined;
274
- }
275
- function makeSceneFrame(input) {
276
- return input;
277
- }
278
-
279
- // packages/cli/src/app-opentui/selectable.ts
280
- function selectableDeckRow(deck, item) {
281
- return { ...deckRow({ ...deck, activateOnClick: true }), selectable: item };
282
- }
283
- function withSelectable(line2, item) {
284
- return { ...line2, selectable: item, activateOnClick: true };
285
- }
286
-
287
- // packages/cli/src/app-opentui/adapters/inspect.ts
288
- import { execFile } from "child_process";
289
- import { promisify } from "util";
290
- import { resolveTaskArtifactDirs } from "@rig/runtime/control-plane/authority-files";
291
- import { readTaskArtifactPreview } from "@rig/runtime/control-plane/native/workspace-ops";
292
- import { resolveHarnessPaths, resolveMonorepoRoot, runCapture } from "@rig/runtime/control-plane/native/utils";
293
- var execFileAsync = promisify(execFile);
294
- var INSPECT_VIEWS = [
295
- "logs",
296
- "timeline",
297
- "artifacts",
298
- "artifact",
299
- "diff",
300
- "failures",
301
- "graph",
302
- "audit"
303
- ];
304
-
305
- // packages/cli/src/app-opentui/scenes/inspect.ts
306
- function artifactFiletype(name) {
307
- const ext = name.slice(name.lastIndexOf(".") + 1).toLowerCase();
308
- const byExt = {
309
- ts: "typescript",
310
- tsx: "tsx",
311
- js: "javascript",
312
- jsx: "javascript",
313
- mjs: "javascript",
314
- cjs: "javascript",
315
- json: "json",
316
- md: "markdown",
317
- markdown: "markdown",
318
- py: "python",
319
- rs: "rust",
320
- go: "go",
321
- sh: "bash",
322
- bash: "bash",
323
- zsh: "bash",
324
- yml: "yaml",
325
- yaml: "yaml",
326
- toml: "toml",
327
- html: "html",
328
- css: "css",
329
- sql: "sql",
330
- c: "c",
331
- h: "c",
332
- cpp: "cpp",
333
- java: "java",
334
- rb: "ruby",
335
- zig: "zig"
336
- };
337
- return byExt[ext] ?? "text";
338
- }
339
- var VIEW_DETAIL = {
340
- logs: "raw run log entries",
341
- timeline: "timeline events",
342
- artifacts: "artifact files produced by the run",
343
- artifact: "view a chosen artifact file",
344
- diff: "working-tree git diff",
345
- failures: "failed log/timeline entries",
346
- graph: "task graph (br list --pretty)",
347
- audit: "audit.jsonl entries"
348
- };
349
- var VIEW_COUNT_UNIT = {
350
- logs: { one: "entry", many: "entries" },
351
- timeline: { one: "event", many: "events" },
352
- artifacts: { one: "file", many: "files" },
353
- artifact: { one: "file", many: "files" },
354
- diff: { one: "line", many: "lines" },
355
- failures: { one: "failure", many: "failures" },
356
- graph: { one: "line", many: "lines" },
357
- audit: { one: "entry", many: "entries" }
358
- };
359
- var TAB_COUNT = INSPECT_VIEWS.length;
360
- function snapshot(state) {
361
- const value = state.data.inspect;
362
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
363
- }
364
- function primaryError(state) {
365
- return state.error?.message ?? lastRefreshError(state);
366
- }
367
- function runOptions(state) {
368
- const value = state.data.inspectRuns;
369
- if (Array.isArray(value) && value.length > 0)
370
- return value;
371
- const fleet = state.data.fleet;
372
- if (fleet && typeof fleet === "object" && !Array.isArray(fleet)) {
373
- const runs = fleet.runs;
374
- if (Array.isArray(runs)) {
375
- return runs.flatMap((entry) => {
376
- if (!entry || typeof entry !== "object" || Array.isArray(entry))
377
- return [];
378
- const record = entry;
379
- const runId = typeof record.runId === "string" ? record.runId : undefined;
380
- if (!runId)
381
- return [];
382
- return [{
383
- runId,
384
- status: typeof record.status === "string" ? record.status : "unknown",
385
- title: typeof record.title === "string" ? record.title : runId,
386
- ...typeof record.taskId === "string" ? { taskId: record.taskId } : {},
387
- ...typeof record.updatedAt === "string" ? { updatedAt: record.updatedAt } : {}
388
- }];
389
- });
390
- }
391
- }
392
- return [];
393
- }
394
- function activeView(state) {
395
- const value = state.data.inspectView;
396
- return INSPECT_VIEWS.includes(value) ? value : INSPECT_VIEWS[0];
397
- }
398
- function selectedRunId(state, inspect) {
399
- if (inspect?.runId)
400
- return inspect.runId;
401
- return typeof state.data.selectedRunId === "string" && state.data.selectedRunId.trim() ? state.data.selectedRunId.trim() : undefined;
402
- }
403
- function panelWidth(layout) {
404
- return layout?.centerWidth ?? 118;
405
- }
406
- function panelHeight(layout) {
407
- return Math.max(18, layout?.centerHeight ?? 34);
408
- }
409
- function entryText(entry) {
410
- return String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? entry.type ?? "event").replace(/\s+/g, " ").slice(0, 200);
411
- }
412
- function entryField(entry, keys) {
413
- for (const key of keys) {
414
- const value = entry[key];
415
- if (typeof value === "string" && value.trim())
416
- return value.trim();
417
- if (typeof value === "number")
418
- return String(value);
419
- }
420
- return "";
421
- }
422
- function entryTableRows(entries) {
423
- const rows = [["TIME", "TYPE", "DETAIL"]];
424
- for (const entry of entries.slice(0, 200)) {
425
- const time = entryField(entry, ["timestamp", "ts", "time", "at"]).replace("T", " ").slice(0, 19);
426
- const type = entryField(entry, ["type", "level", "kind", "status"]).slice(0, 16) || "\u2014";
427
- const detail = entryText(entry);
428
- rows.push([time || "\u2014", type, detail]);
429
- }
430
- return rows;
431
- }
432
- var TABLE_VIEWS = ["timeline", "failures", "audit", "logs"];
433
- function humanBytes(bytes) {
434
- if (bytes < 1024)
435
- return `${bytes} B`;
436
- if (bytes < 1024 * 1024)
437
- return `${(bytes / 1024).toFixed(1)} KB`;
438
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
439
- }
440
- function diffLine(text) {
441
- if (text.startsWith("+++") || text.startsWith("---"))
442
- return line(text, { fg: RIG_UI.ink, bold: true });
443
- if (text.startsWith("@@"))
444
- return line(text, { fg: RIG_UI.cyan });
445
- if (text.startsWith("diff ") || text.startsWith("index "))
446
- return line(text, { fg: RIG_UI.ink3, bold: true });
447
- if (text.startsWith("+"))
448
- return line(text, { fg: RIG_UI.lime });
449
- if (text.startsWith("-"))
450
- return line(text, { fg: RIG_UI.red });
451
- return line(text, { fg: RIG_UI.ink3 });
452
- }
453
- function artifactRow(artifact, active) {
454
- const glyph = artifact.isDir ? "\u25B8" : "\xB7";
455
- const meta = artifact.isDir ? "dir" : humanBytes(artifact.sizeBytes);
456
- const marker = active ? "\u258C" : " ";
457
- const row = line(`${marker} ${glyph} ${artifact.name.padEnd(40).slice(0, 40)} ${meta}`, { fg: active ? RIG_UI.ink : artifact.isDir ? RIG_UI.cyan : RIG_UI.ink2, bold: active });
458
- if (artifact.isDir)
459
- return row;
460
- const open = {
461
- id: `inspect-artifact:${artifact.name}`,
462
- label: `open ${artifact.name}`,
463
- data: { inspectArtifact: artifact.name, inspectView: "artifact" },
464
- intent: { scene: "inspect", argv: ["inspect"], action: { kind: "refresh", label: `Open ${artifact.name}` } },
465
- message: `view artifact ${artifact.name}`
466
- };
467
- return withSelectable(row, open);
468
- }
469
- function openArtifactItem(name, label, message) {
470
- return {
471
- id: `inspect-artifact:${name}`,
472
- label,
473
- data: { inspectArtifact: name, inspectView: "artifact" },
474
- intent: { scene: "inspect", argv: ["inspect"], action: { kind: "refresh", label: `Open ${name}` } },
475
- message
476
- };
477
- }
478
- function fileArtifacts(inspect) {
479
- return inspect.artifacts.filter((entry) => !entry.isDir);
480
- }
481
- var ARTIFACT_HEADER_ROWS = 7;
482
- function artifactHeaderRows(inspect, currentName) {
483
- const files = fileArtifacts(inspect);
484
- const index = files.findIndex((entry) => entry.name === currentName);
485
- const prev = index > 0 ? files[index - 1] : undefined;
486
- const next = index >= 0 && index < files.length - 1 ? files[index + 1] : undefined;
487
- const view_ = inspect.artifactView;
488
- const sizeLabel = view_ ? `${humanBytes(view_.sizeBytes)}${view_.truncated ? " \xB7 truncated preview" : ""}` : "loading file";
489
- const position = index >= 0 && files.length > 0 ? ` \xB7 file ${index + 1}/${files.length}` : "";
490
- const backItem = {
491
- id: "inspect-artifact-back",
492
- label: "back to artifacts",
493
- data: { inspectArtifact: undefined, inspectView: "artifacts" },
494
- intent: { scene: "inspect", argv: ["inspect"], action: { kind: "refresh", label: "Back to artifacts" } },
495
- message: "back to the artifact list"
496
- };
497
- const prevRow = prev ? withSelectable(line(` \u25C2 prev ${prev.name}`, { fg: RIG_UI.ink2 }), openArtifactItem(prev.name, `open ${prev.name}`, `prev file ${prev.name}`)) : line(" \u25C2 prev \u2014 first file", { fg: RIG_UI.ink4 });
498
- const nextRow = next ? withSelectable(line(` \u25B8 next ${next.name}`, { fg: RIG_UI.ink2 }), openArtifactItem(next.name, `open ${next.name}`, `next file ${next.name}`)) : line(" \u25B8 next \u2014 last file", { fg: RIG_UI.ink4 });
499
- return [
500
- line(`artifacts / ${currentName}${position}`, { fg: RIG_UI.cyan, bold: true }),
501
- withSelectable(line(" \u21A9 back return to the artifact list", { fg: RIG_UI.ink2 }), backItem),
502
- prevRow,
503
- nextRow,
504
- blank(),
505
- line(`${currentName} \xB7 ${sizeLabel}`, { fg: RIG_UI.ink, bold: true }),
506
- blank()
507
- ];
508
- }
509
- function viewBody(view, inspect, bodyCursor) {
510
- switch (view) {
511
- case "diff": {
512
- if (inspect.diffError)
513
- return [line(`diff unavailable \u2014 ${inspect.diffError}`, { fg: RIG_UI.yellow })];
514
- if (inspect.diff.trim() === "")
515
- return [line("no working-tree changes", { fg: RIG_UI.ink4 })];
516
- return inspect.diff.split(`
517
- `).slice(0, 600).map((text) => diffLine(text));
518
- }
519
- case "logs": {
520
- if (inspect.logs.length === 0)
521
- return [line("no log entries", { fg: RIG_UI.ink4 })];
522
- return inspect.logs.map((entry) => line(`\xB7 ${entryText(entry)}`, { fg: RIG_UI.ink3 }));
523
- }
524
- case "timeline": {
525
- if (inspect.timeline.length === 0)
526
- return [line("no timeline events", { fg: RIG_UI.ink4 })];
527
- return inspect.timeline.map((entry) => line(`\xB7 ${entryText(entry)}`, { fg: RIG_UI.ink2 }));
528
- }
529
- case "failures": {
530
- if (inspect.failures.length === 0)
531
- return [line("no failures detected", { fg: RIG_UI.limeDim })];
532
- return inspect.failures.map((entry) => line(`\u2717 ${entryText(entry)}`, { fg: RIG_UI.red }));
533
- }
534
- case "artifacts": {
535
- if (inspect.artifactsError)
536
- return [line(`artifacts unavailable \u2014 ${inspect.artifactsError}`, { fg: RIG_UI.yellow })];
537
- if (inspect.artifacts.length === 0)
538
- return [line("no artifact files for this run", { fg: RIG_UI.ink4 })];
539
- let selectableSeen = 0;
540
- const rows = inspect.artifacts.map((artifact) => {
541
- if (artifact.isDir)
542
- return artifactRow(artifact, false);
543
- const active = selectableSeen === bodyCursor;
544
- selectableSeen += 1;
545
- return artifactRow(artifact, active);
546
- });
547
- return [
548
- line("enter/click a file to view its contents", { fg: RIG_UI.ink4 }),
549
- blank(),
550
- ...rows
551
- ];
552
- }
553
- case "artifact": {
554
- const view_ = inspect.artifactView;
555
- const currentName = view_?.name;
556
- if (!currentName)
557
- return [line("no artifact selected \u2014 pick one from the artifacts view", { fg: RIG_UI.ink4 })];
558
- return [
559
- ...artifactHeaderRows(inspect, currentName),
560
- ...view_.contents.split(`
561
- `).slice(0, 800).map((text) => line(text, { fg: RIG_UI.ink2 }))
562
- ];
563
- }
564
- case "graph": {
565
- if (inspect.graphError)
566
- return [line(`graph unavailable \u2014 ${inspect.graphError}`, { fg: RIG_UI.yellow })];
567
- if (inspect.graph.trim() === "")
568
- return [line("graph is empty", { fg: RIG_UI.ink4 })];
569
- return inspect.graph.split(`
570
- `).slice(0, 600).map((text) => line(text, { fg: RIG_UI.ink2 }));
571
- }
572
- case "audit": {
573
- if (inspect.audit.length === 0)
574
- return [line("no audit entries", { fg: RIG_UI.ink4 })];
575
- return inspect.audit.map((entry) => line(`\xB7 ${entryText(entry)}`, { fg: RIG_UI.ink3 }));
576
- }
577
- }
578
- }
579
- function viewCount(view, inspect) {
580
- if (!inspect)
581
- return 0;
582
- switch (view) {
583
- case "diff":
584
- return inspect.diff.trim() === "" ? 0 : inspect.diff.split(`
585
- `).length;
586
- case "logs":
587
- return inspect.logs.length;
588
- case "timeline":
589
- return inspect.timeline.length;
590
- case "failures":
591
- return inspect.failures.length;
592
- case "artifacts":
593
- return inspect.artifacts.length;
594
- case "artifact":
595
- return inspect.artifactView ? 1 : 0;
596
- case "graph":
597
- return inspect.graph.trim() === "" ? 0 : inspect.graph.split(`
598
- `).length;
599
- case "audit":
600
- return inspect.audit.length;
601
- }
602
- }
603
- function viewCountLabel(view, inspect) {
604
- const count = viewCount(view, inspect);
605
- const unit = VIEW_COUNT_UNIT[view];
606
- return `${count} ${count === 1 ? unit.one : unit.many}`;
607
- }
608
- function tabItem(view) {
609
- return { id: `inspect-view:${view}`, label: view, data: { inspectView: view }, message: `inspect ${VIEW_DETAIL[view]}` };
610
- }
611
- function runPickerRow(width, option, active) {
612
- const { glyph, color } = statusLabel(option.status);
613
- const id = option.runId.slice(0, 8).padEnd(9);
614
- const status = option.status.replace(/[_-]/g, " ").slice(0, 13).padEnd(14);
615
- const marker = active ? "\u258C" : " ";
616
- const prefix = `${marker} ${glyph} ${id} ${status}`;
617
- const titleWidth = Math.max(12, width - prefix.length - 2);
618
- const title = option.title.length <= titleWidth ? option.title : `${option.title.slice(0, Math.max(0, titleWidth - 1))}\u2026`;
619
- const row = line(`${prefix}${title}`, { fg: active ? RIG_UI.ink : color, bold: active });
620
- const item = {
621
- id: `inspect-pick:${option.runId}`,
622
- label: option.title,
623
- data: { selectedRunId: option.runId, inspectArtifact: undefined, inspectView: "logs" },
624
- intent: { scene: "inspect", argv: ["inspect"], action: { kind: "refresh", label: `Inspect ${option.runId.slice(0, 8)}` } },
625
- message: `inspect run ${option.runId.slice(0, 8)}`
626
- };
627
- return withSelectable(row, item);
628
- }
629
- function pickerSelectedIndex(state, options) {
630
- if (options.length === 0)
631
- return 0;
632
- const selectedId = typeof state.data.selectedRunId === "string" && state.data.selectedRunId.trim() ? state.data.selectedRunId.trim() : undefined;
633
- if (selectedId) {
634
- const matched = options.findIndex((option) => option.runId === selectedId);
635
- if (matched >= 0)
636
- return matched;
637
- }
638
- return Math.max(0, Math.min(options.length - 1, state.selection.index));
639
- }
640
- function renderPicker(state, layout) {
641
- const options = runOptions(state);
642
- const loading = state.status === "loading" && options.length === 0;
643
- const errorText = primaryError(state);
644
- const width = Math.max(40, panelWidth(layout) - (layout?.compact ? 8 : 10));
645
- const selected = pickerSelectedIndex(state, options);
646
- const panelLines = [
647
- ...errorText ? errorBanner(errorText, "select a run below to retry, or open runs") : [],
648
- line("Pick a run to investigate.", { fg: RIG_UI.ink3 }),
649
- line("logs \xB7 timeline \xB7 artifacts \xB7 diff \xB7 failures \xB7 graph \xB7 audit \u2014 all in-place.", { fg: RIG_UI.ink4 }),
650
- blank(),
651
- line(`RECENT RUNS \xB7 ${options.length}`, { fg: RIG_UI.ink3, bold: true }),
652
- line("RUN STATUS TITLE", { fg: RIG_UI.ink4, bold: true }),
653
- blank(),
654
- ...loading ? loadingRows("runs", state.tick) : options.length > 0 ? options.map((option, index) => runPickerRow(width, option, index === selected)) : [
655
- line("No runs available from the selected server.", { fg: RIG_UI.ink4 }),
656
- blank(),
657
- selectableDeckRow({ label: "runs", detail: "open the runs scene to dispatch or find a run", index: 0, active: true }, { id: "inspect-open-runs", label: "runs", intent: { scene: "fleet", argv: ["runs"], action: { kind: "refresh", label: "Open runs" } }, message: "open runs to find a run" })
658
- ]
659
- ];
660
- return makeSceneFrame({
661
- scene: "inspect",
662
- title: "Inspect",
663
- lines: [],
664
- panels: [{
665
- id: "inspect-picker",
666
- top: 0,
667
- width: panelWidth(layout),
668
- height: panelHeight(layout),
669
- lines: panelLines,
670
- backgroundColor: RIG_UI.panel,
671
- backgroundAlpha: 184,
672
- opacity: 0.98,
673
- border: false,
674
- stickyScroll: true,
675
- stickyStart: "top",
676
- chrome: "ad-terminal",
677
- headerText: "rig inspect \xB7 pick a run",
678
- headerHeight: 3,
679
- paddingX: layout?.compact ? 3 : 5,
680
- paddingY: 2
681
- }],
682
- footer: { message: options.length > 0 ? `${options.length} runs \u2014 enter to inspect` : "no runs to inspect" },
683
- live: state.status === "action" || loading
684
- });
685
- }
686
- function changeRunItem() {
687
- return {
688
- id: "inspect-change-run",
689
- label: "change run",
690
- data: { selectedRunId: undefined, inspect: undefined, inspectArtifact: undefined, inspectView: "logs" },
691
- intent: { scene: "inspect", argv: ["inspect"], action: { kind: "refresh", label: "Pick another run" } },
692
- message: "pick another run to inspect"
693
- };
694
- }
695
- function renderInspectScene(state, layout) {
696
- const inspect = snapshot(state);
697
- const runId = selectedRunId(state, inspect);
698
- const loadingSnapshot = state.status === "loading" && !inspect;
699
- if (!inspect && !loadingSnapshot && runOptions(state).length > 0) {
700
- return renderPicker(state, layout);
701
- }
702
- if (!runId && !loadingSnapshot) {
703
- return renderPicker(state, layout);
704
- }
705
- const view = activeView(state);
706
- const loading = loadingSnapshot;
707
- const errorText = primaryError(state);
708
- const tabBandCount = TAB_COUNT + 1;
709
- const rawIndex = state.selection.index < 0 ? 0 : state.selection.index;
710
- const region = rawIndex < tabBandCount ? "tab" : "body";
711
- const bodyCursor = region === "body" ? rawIndex - tabBandCount : -1;
712
- const activeTabIndex = Math.max(0, INSPECT_VIEWS.indexOf(view));
713
- const tabCursor = region === "tab" ? Math.min(rawIndex, TAB_COUNT) : -1;
714
- const tabRow = INSPECT_VIEWS.map((entry, index) => selectableDeckRow({
715
- label: entry,
716
- detail: `${VIEW_DETAIL[entry]} \xB7 ${viewCountLabel(entry, inspect)}`,
717
- index,
718
- active: region === "tab" ? index === tabCursor : index === activeTabIndex
719
- }, tabItem(entry)));
720
- const changeRunActive = region === "tab" && tabCursor === TAB_COUNT;
721
- const changeRunRow = selectableDeckRow({ label: "change run", detail: "switch to another run (back to the in-place picker)", index: TAB_COUNT, active: changeRunActive }, changeRunItem());
722
- const tabsHeader = region === "tab" ? line("\u258C VIEWS \xB7 \u2191\u2193 switch view \xB7 enter opens \xB7 \u25B8 change run \xB7 esc back", { fg: RIG_UI.lime, bold: true }) : line(" VIEWS \xB7 \u2191\u2193 to return to the tab strip \xB7 change run to re-pick \xB7 esc back", { fg: RIG_UI.ink3, bold: true });
723
- const bodyHeader = region === "body" ? line(`\u258C ${view.toUpperCase()} \xB7 browsing content \u2014 \u2191\u2193 moves here`, { fg: RIG_UI.lime, bold: true }) : line(` ${view.toUpperCase()}`, { fg: RIG_UI.ink3, bold: true });
724
- const panelLines = [
725
- ...errorText ? errorBanner(errorText, "click a view tab to retry, or change run below") : [],
726
- line(inspect ? `${inspect.title} \xB7 ${inspect.status}${inspect.taskId ? ` \xB7 task ${inspect.taskId}` : ""}` : "loading run", { fg: inspect ? statusLabel(inspect.status).color : RIG_UI.ink3, bold: true }),
727
- blank(),
728
- tabsHeader,
729
- ...tabRow,
730
- changeRunRow,
731
- blank(),
732
- bodyHeader,
733
- ...loading || !inspect ? loadingRows("run inspection", state.tick) : viewBody(view, inspect, bodyCursor)
734
- ];
735
- const paddingX = layout?.compact ? 2 : 3;
736
- const chromeTopInset = 3 + 1;
737
- const bannerLines = errorText ? 4 : 0;
738
- const headerLines = bannerLines + 6 + TAB_COUNT;
739
- const bodyTop = (layout?.centerTop ?? 1) + chromeTopInset + headerLines;
740
- const left = (layout?.centerLeft ?? 2) + paddingX;
741
- const width = Math.max(20, panelWidth(layout) - paddingX * 2);
742
- const bodyHeight = Math.max(6, panelHeight(layout) - chromeTopInset - headerLines - 1);
743
- let native;
744
- if (view === "diff" && inspect && inspect.diff.trim() && !inspect.diffError) {
745
- native = { kind: "diff", content: inspect.diff, top: bodyTop, left, width, height: bodyHeight };
746
- } else if (view === "artifact" && inspect?.artifactView?.contents.trim()) {
747
- native = {
748
- kind: "code",
749
- content: inspect.artifactView.contents,
750
- filetype: artifactFiletype(inspect.artifactView.name),
751
- top: bodyTop + ARTIFACT_HEADER_ROWS,
752
- left,
753
- width,
754
- height: Math.max(6, bodyHeight - ARTIFACT_HEADER_ROWS)
755
- };
756
- } else if (inspect && TABLE_VIEWS.includes(view)) {
757
- const entries = view === "timeline" ? inspect.timeline : view === "failures" ? inspect.failures : view === "audit" ? inspect.audit : inspect.logs;
758
- if (entries.length > 0) {
759
- native = { kind: "table", content: "", rows: entryTableRows(entries), top: bodyTop, left, width, height: bodyHeight };
760
- }
761
- }
762
- return makeSceneFrame({
763
- scene: "inspect",
764
- title: "Inspect",
765
- lines: [],
766
- ...native ? { native } : {},
767
- panels: [{
768
- id: "inspect-body",
769
- top: 0,
770
- width: panelWidth(layout),
771
- height: panelHeight(layout),
772
- lines: panelLines,
773
- backgroundColor: RIG_UI.panel,
774
- backgroundAlpha: 184,
775
- opacity: 0.98,
776
- border: false,
777
- stickyScroll: true,
778
- stickyStart: "top",
779
- chrome: "ad-terminal",
780
- headerText: runId ? `rig inspect ${runId.slice(0, 8)} \xB7 ${view}` : "rig inspect",
781
- headerHeight: 3,
782
- paddingX: layout?.compact ? 2 : 3,
783
- paddingY: 1
784
- }],
785
- footer: {
786
- run: runId ? `${runId.slice(0, 8)} ${view}` : undefined,
787
- message: "\u2191\u2193 select \xB7 enter open \xB7 change run to re-pick \xB7 esc back"
788
- },
789
- live: state.status === "action" || !inspect
790
- });
791
- }
792
- export {
793
- renderInspectScene
794
- };