@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,3 @@
1
+ import type { AppSceneFrame, AppState } from "../types";
2
+ import type { StageLayout } from "../layout";
3
+ export declare function renderCommandScene(state: AppState, layout?: StageLayout): AppSceneFrame;
@@ -0,0 +1,117 @@
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
+
42
+ // packages/cli/src/app-opentui/drone.ts
43
+ import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
44
+ var COLOR = {
45
+ body: RGBA.fromHex(RIG_UI.lime),
46
+ mini: RGBA.fromHex(RIG_UI.limeDim),
47
+ rotor: RGBA.fromHex(RIG_UI.cyan),
48
+ path: RGBA.fromHex(RIG_UI.cyan),
49
+ eye: RGBA.fromHex(RIG_UI.ink),
50
+ dim: RGBA.fromHex(RIG_UI.ink4),
51
+ ink: RGBA.fromHex(RIG_UI.ink2)
52
+ };
53
+
54
+ // packages/cli/src/app-opentui/render/scene.ts
55
+ function line(text, options = {}) {
56
+ return { text, ...options };
57
+ }
58
+ function makeSceneFrame(input) {
59
+ return input;
60
+ }
61
+
62
+ // packages/cli/src/app-opentui/scenes/command.ts
63
+ function terminalState(state) {
64
+ const value = state.data.commandTerminal;
65
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
66
+ }
67
+ function panelWidth(layout) {
68
+ return layout?.centerWidth ?? 118;
69
+ }
70
+ function panelHeight(layout, top = 0) {
71
+ return Math.max(14, (layout?.centerHeight ?? 36) - top);
72
+ }
73
+ function header(snapshot, state) {
74
+ const label = snapshot?.label ?? (state.argv.length > 0 ? `rig ${state.argv.join(" ")}` : "rig");
75
+ const suffix = snapshot?.message ? ` \xB7 ${snapshot.message}` : "";
76
+ return `${label}${suffix}`;
77
+ }
78
+ function commandLines(snapshot) {
79
+ if (!snapshot) {
80
+ return [line("starting command\u2026", { fg: RIG_UI.ink3 })];
81
+ }
82
+ const rows = snapshot.lines.length > 0 ? snapshot.lines : ["starting command\u2026"];
83
+ return rows.map((text) => line(text, { fg: text.trim() ? RIG_UI.ink2 : RIG_UI.ink4 }));
84
+ }
85
+ function renderCommandScene(state, layout) {
86
+ const terminal = terminalState(state);
87
+ const width = panelWidth(layout);
88
+ const panelTop = 0;
89
+ return makeSceneFrame({
90
+ scene: "command",
91
+ title: "Command",
92
+ lines: [],
93
+ panels: [{
94
+ id: "command-terminal",
95
+ top: panelTop,
96
+ width,
97
+ height: panelHeight(layout, panelTop),
98
+ lines: commandLines(terminal),
99
+ backgroundColor: RIG_UI.panel,
100
+ backgroundAlpha: 184,
101
+ opacity: 0.98,
102
+ border: false,
103
+ chrome: "ad-terminal",
104
+ headerText: header(terminal, state),
105
+ stickyScroll: true,
106
+ stickyStart: "bottom",
107
+ paddingX: 5,
108
+ paddingY: 2
109
+ }],
110
+ footer: { message: terminal?.message ?? "command" },
111
+ live: terminal?.status === "starting" || terminal?.status === "running" || state.status === "action",
112
+ hideTypeBar: true
113
+ });
114
+ }
115
+ export {
116
+ renderCommandScene
117
+ };
@@ -1,2 +1,3 @@
1
+ import type { StageLayout } from "../layout";
1
2
  import type { AppSceneFrame, AppState } from "../types";
2
- export declare function renderDoctorScene(state: AppState): AppSceneFrame;
3
+ export declare function renderDoctorScene(state: AppState, layout?: StageLayout): AppSceneFrame;
@@ -11,15 +11,17 @@ var RIG_UI = {
11
11
  bg: "#070809",
12
12
  bg2: "#0b0c0e",
13
13
  panel: "#101115",
14
- panel2: "#101115",
15
- glass: "#14161b",
16
- ink: "#f2f3f6",
17
- ink2: "#aeb0ba",
18
- ink3: "#6c6e79",
19
- ink4: "#44464f",
14
+ panel2: "#14161b",
15
+ glass: "#1e2230",
16
+ border: "#2a2e3a",
17
+ ink: "#f4f5f8",
18
+ ink2: "#c7c9d3",
19
+ ink3: "#9aa0ae",
20
+ ink4: "#787b86",
20
21
  lime: "#ccff4d",
21
22
  limeDim: "#a9d63f",
22
23
  cyan: "#56d8ff",
24
+ cyanDim: "#3f9fbd",
23
25
  red: "#ff5d5d",
24
26
  yellow: "#ffd24d",
25
27
  magenta: "#ff79b0"
@@ -37,6 +39,134 @@ var styles = {
37
39
  magenta: otuiFg(RIG_UI.magenta)
38
40
  };
39
41
 
42
+ // packages/cli/src/app-opentui/drone.ts
43
+ import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
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 miniDroneLines(tick, align = "left", phase = 0) {
133
+ return materializeDrone(MINI_DRONE, tick, phase).map((text) => ({
134
+ text,
135
+ styledText: styledLine(text, droneColor),
136
+ fg: RIG_UI.limeDim,
137
+ align
138
+ }));
139
+ }
140
+ function brandFleetLines(tick, align = "center") {
141
+ const left = materializeDrone(MINI_DRONE, tick, 0);
142
+ const right = materializeDrone(MINI_DRONE, tick, 2);
143
+ const lead = materializeDrone(LEAD_MARK, tick, 1);
144
+ const packet = ["\xB7", "\u2022", "\u25CF", "\u2022"][Math.floor(tick / 2) % 4];
145
+ const bridge = [
146
+ ` ${left[0]} ${lead[0]} ${right[0]}`,
147
+ ` ${left[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${lead[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${right[1]}`,
148
+ ` ${left[2]} \xB7' '${lead[2]}' '\xB7 ${right[2]}`,
149
+ ` ${left[3]} \u2572 signal bus \u2571 ${right[3]}`,
150
+ ` ${left[4]} \xB7\u2500\u2500\u2500${packet}\u2500\u2500\u2500\u2500\u2500\u2500${packet}\u2500\u2500\u2500\xB7 ${right[4]}`
151
+ ];
152
+ return bridge.map((text) => ({
153
+ text,
154
+ styledText: styledLine(text, motionColor),
155
+ fg: RIG_UI.limeDim,
156
+ align
157
+ }));
158
+ }
159
+ function actionDrone(tick, phase = 0) {
160
+ const blade = bladeForTick(tick, phase);
161
+ const eye = eyeForTick(tick, phase);
162
+ return `(${blade})\u2572${eye}\u2571(${blade})`;
163
+ }
164
+ function actionDroneLine(tick, text, fg = RIG_UI.ink2) {
165
+ const prefix = actionDrone(tick);
166
+ const content = `${prefix} ${text}`;
167
+ return { text: content, styledText: styledLine(content, motionColor), fg, align: "center" };
168
+ }
169
+
40
170
  // packages/cli/src/app-opentui/render/scene.ts
41
171
  function line(text, options = {}) {
42
172
  return { text, ...options };
@@ -44,14 +174,53 @@ function line(text, options = {}) {
44
174
  function blank() {
45
175
  return { text: "" };
46
176
  }
47
- function center(text, fg = RIG_UI.ink2, bold = false) {
48
- return { text, fg, bold, align: "center" };
177
+ function deckRow(input) {
178
+ const prefix = input.active ? "\u25B8" : " ";
179
+ const label = input.label.toUpperCase().padEnd(10);
180
+ return line(`${prefix} ${label} ${input.detail}`, {
181
+ fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
182
+ bold: input.active,
183
+ selectableIndex: input.index,
184
+ activateOnClick: input.activateOnClick
185
+ });
186
+ }
187
+ function loadingRows(label, tick = 0, compact = false) {
188
+ const mascot = compact ? miniDroneLines(tick, "center") : brandFleetLines(tick, "center");
189
+ return [
190
+ blank(),
191
+ ...mascot,
192
+ blank(),
193
+ { ...actionDroneLine(tick, `loading ${label}\u2026`, RIG_UI.cyan), align: "center" }
194
+ ];
195
+ }
196
+ function errorBanner(message, hint) {
197
+ return [
198
+ line(`\u2717 failed to load \u2014 ${message}`, { fg: RIG_UI.red, bold: true }),
199
+ ...hint ? [line(` ${hint}`, { fg: RIG_UI.ink3 })] : [],
200
+ line(" select refresh/retry below", { fg: RIG_UI.ink4 }),
201
+ line("", { fg: RIG_UI.ink3 })
202
+ ];
203
+ }
204
+ function lastRefreshError(state) {
205
+ const value = state.data.lastRefreshError;
206
+ return typeof value === "string" && value.trim() ? value : undefined;
49
207
  }
50
208
  function makeSceneFrame(input) {
51
209
  return input;
52
210
  }
53
211
 
212
+ // packages/cli/src/app-opentui/selectable.ts
213
+ function selectableDeckRow(deck, item) {
214
+ return { ...deckRow({ ...deck, activateOnClick: true }), selectable: item };
215
+ }
216
+
54
217
  // packages/cli/src/app-opentui/scenes/doctor.ts
218
+ var DOCTOR_ACTIONS = [
219
+ { detail: "run diagnostics now", item: { id: "run", label: "run", intent: { scene: "doctor", argv: ["doctor"], action: { kind: "doctor-run", label: "Run doctor" } }, message: "run diagnostics" } },
220
+ { detail: "open server controls", item: { id: "server", label: "server", intent: { scene: "server", argv: ["server", "status"], action: { kind: "refresh", label: "Open server controls" } }, message: "open server controls" } },
221
+ { detail: "repair project/server/auth link", item: { id: "repair", label: "repair", intent: { scene: "command", argv: ["init", "--repair"], action: { kind: "command-run", label: "Repair project link" } }, message: "repair project link" } },
222
+ { detail: "open tasks", item: { id: "tasks", label: "tasks", intent: { scene: "tasks", argv: ["tasks"], action: { kind: "refresh", label: "Open tasks" } }, message: "open tasks" } }
223
+ ];
55
224
  function checks(state) {
56
225
  const doctor = state.data.doctor;
57
226
  if (!doctor || typeof doctor !== "object" || Array.isArray(doctor))
@@ -65,24 +234,59 @@ function glyph(status) {
65
234
  function doctorColor(status) {
66
235
  return status === "pass" ? RIG_UI.limeDim : status === "warn" ? RIG_UI.yellow : RIG_UI.red;
67
236
  }
68
- function renderDoctorScene(state) {
237
+ function panelWidth(layout) {
238
+ return layout?.centerWidth ?? 100;
239
+ }
240
+ function panelHeight(layout) {
241
+ return Math.max(10, (layout?.centerHeight ?? 24) - 1);
242
+ }
243
+ function actionRows(selected) {
244
+ return [
245
+ line("ACTIONS", { fg: RIG_UI.ink3, bold: true }),
246
+ ...DOCTOR_ACTIONS.map(({ detail, item }, index) => selectableDeckRow({ label: item.label, detail, index, active: selected === index }, item))
247
+ ];
248
+ }
249
+ function renderDoctorScene(state, layout) {
69
250
  const records = checks(state);
251
+ const selected = Math.max(0, Math.min(3, state.selection.index));
70
252
  const failures = records.filter((check) => check.status === "fail").length;
71
253
  const warnings = records.filter((check) => check.status === "warn").length;
72
254
  const firstRemediation = records.find((check) => check.status !== "pass" && check.remediation)?.remediation;
255
+ const loading = state.status === "loading" && records.length === 0;
256
+ const refreshError = lastRefreshError(state);
257
+ const checkLines = records.length > 0 ? records.slice(0, 12).map((check) => line(`${glyph(check.status)} ${check.label}${check.detail ? ` \u2014 ${check.detail}` : ""}`, { fg: doctorColor(check.status) })) : loading ? loadingRows("diagnostics", state.tick) : [line("Diagnostics have not run in this session.", { fg: RIG_UI.ink3 })];
73
258
  return makeSceneFrame({
74
259
  scene: "doctor",
75
260
  title: "Doctor",
76
261
  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" })
262
+ line("", { fg: RIG_UI.ink4 }),
263
+ line(` doctor \xB7 ${records.length > 0 ? `${failures} fail \xB7 ${warnings} warn` : "ready"}`, { fg: RIG_UI.ink3 })
83
264
  ],
84
- footer: { message: records.length > 0 ? `${records.length} checks` : "doctor idle" },
85
- typeBarPlaceholder: "doctor \xB7 server \xB7 tasks \xB7 init",
265
+ panels: [{
266
+ id: "doctor-actions",
267
+ top: 0,
268
+ width: panelWidth(layout),
269
+ height: panelHeight(layout),
270
+ lines: [
271
+ ...refreshError && !state.error ? errorBanner(refreshError) : [],
272
+ ...actionRows(selected),
273
+ line("", { fg: RIG_UI.ink3 }),
274
+ line("CHECKS", { fg: RIG_UI.ink3, bold: true }),
275
+ ...checkLines,
276
+ ...firstRemediation ? [line("", { fg: RIG_UI.ink3 }), line(`next: ${firstRemediation}`, { fg: RIG_UI.yellow })] : []
277
+ ],
278
+ backgroundColor: RIG_UI.panel,
279
+ backgroundAlpha: 184,
280
+ opacity: 1,
281
+ border: false,
282
+ chrome: "ad-terminal",
283
+ headerText: `doctor \xB7 ${records.length} checks`,
284
+ headerHeight: 3,
285
+ paddingX: layout?.compact ? 2 : 3,
286
+ paddingY: 1
287
+ }],
288
+ footer: { message: records.length > 0 ? `${records.length} checks` : "enter/click run to diagnose" },
289
+ hideTypeBar: true,
86
290
  live: state.status === "action" || records.length === 0
87
291
  });
88
292
  }
@@ -14,15 +14,17 @@ var RIG_UI = {
14
14
  bg: "#070809",
15
15
  bg2: "#0b0c0e",
16
16
  panel: "#101115",
17
- panel2: "#101115",
18
- glass: "#14161b",
19
- ink: "#f2f3f6",
20
- ink2: "#aeb0ba",
21
- ink3: "#6c6e79",
22
- ink4: "#44464f",
17
+ panel2: "#14161b",
18
+ glass: "#1e2230",
19
+ border: "#2a2e3a",
20
+ ink: "#f4f5f8",
21
+ ink2: "#c7c9d3",
22
+ ink3: "#9aa0ae",
23
+ ink4: "#787b86",
23
24
  lime: "#ccff4d",
24
25
  limeDim: "#a9d63f",
25
26
  cyan: "#56d8ff",
27
+ cyanDim: "#3f9fbd",
26
28
  red: "#ff5d5d",
27
29
  yellow: "#ffd24d",
28
30
  magenta: "#ff79b0"
@@ -156,32 +158,70 @@ function errorDrone(tick) {
156
158
  }
157
159
 
158
160
  // packages/cli/src/app-opentui/render/scene.ts
159
- function blank() {
160
- return { text: "" };
161
+ function line(text, options = {}) {
162
+ return { text, ...options };
161
163
  }
162
- function center(text, fg = RIG_UI.ink2, bold = false) {
163
- return { text, fg, bold, align: "center" };
164
+ function deckRow(input) {
165
+ const prefix = input.active ? "\u25B8" : " ";
166
+ const label = input.label.toUpperCase().padEnd(10);
167
+ return line(`${prefix} ${label} ${input.detail}`, {
168
+ fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
169
+ bold: input.active,
170
+ selectableIndex: input.index,
171
+ activateOnClick: input.activateOnClick
172
+ });
164
173
  }
165
174
  function makeSceneFrame(input) {
166
175
  return input;
167
176
  }
168
177
 
178
+ // packages/cli/src/app-opentui/selectable.ts
179
+ function selectableDeckRow(deck, item) {
180
+ return { ...deckRow({ ...deck, activateOnClick: true }), selectable: item };
181
+ }
182
+
169
183
  // packages/cli/src/app-opentui/scenes/error.ts
184
+ var ERROR_ACTIONS = [
185
+ { detail: "return to dashboard", item: { id: "main", label: "main", intent: { scene: "main", argv: [], action: { kind: "refresh", label: "Back to dashboard" } }, message: "back to dashboard" } },
186
+ { detail: "run diagnostics", item: { id: "doctor", label: "doctor", intent: { scene: "doctor", argv: ["doctor"], action: { kind: "doctor-run", label: "Run doctor" } }, message: "run diagnostics" } },
187
+ { detail: "open server controls", item: { id: "server", label: "server", intent: { scene: "server", argv: ["server", "status"], action: { kind: "refresh", label: "Open server controls" } }, message: "open server controls" } },
188
+ { detail: "repair project/server/auth link", item: { id: "repair", label: "repair", intent: { scene: "command", argv: ["init", "--repair"], action: { kind: "command-run", label: "Repair project link" } }, message: "repair project link" } }
189
+ ];
170
190
  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";
191
+ const message = state.error?.message ?? "Unknown app error";
192
+ const hint = state.error?.hint ?? "Use the actions below to recover.";
193
+ const selected = Math.max(0, Math.min(3, state.selection.index));
173
194
  return makeSceneFrame({
174
195
  scene: "error",
175
- title: "Rig error",
196
+ title: "Error",
176
197
  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)
198
+ ...errorDrone(state.tick).slice(2, 10)
183
199
  ],
184
- typeBarPlaceholder: hint,
200
+ panels: [{
201
+ id: "error-recovery",
202
+ top: 2,
203
+ width: 96,
204
+ height: 18,
205
+ lines: [
206
+ line("DRONE SIGNAL DEGRADED", { fg: RIG_UI.red, bold: true }),
207
+ line(message, { fg: RIG_UI.ink2 }),
208
+ ...hint ? [line(hint, { fg: RIG_UI.yellow })] : [],
209
+ line("", { fg: RIG_UI.ink3 }),
210
+ line("ACTIONS", { fg: RIG_UI.ink3, bold: true }),
211
+ ...ERROR_ACTIONS.map(({ detail, item }, index) => selectableDeckRow({ label: item.label, detail, index, active: selected === index }, item))
212
+ ],
213
+ backgroundColor: RIG_UI.panel,
214
+ backgroundAlpha: 184,
215
+ opacity: 1,
216
+ border: false,
217
+ chrome: "ad-terminal",
218
+ headerText: "recovery",
219
+ headerHeight: 3,
220
+ paddingX: 3,
221
+ paddingY: 1
222
+ }],
223
+ footer: { message: "enter/click a recovery action" },
224
+ hideTypeBar: true,
185
225
  live: true
186
226
  });
187
227
  }
@@ -0,0 +1,2 @@
1
+ import type { DomainRenderer } from "./kit";
2
+ export declare const renderAgent: DomainRenderer;