@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.
- package/dist/bin/build-rig-binaries.js +40 -8
- package/dist/bin/rig.js +23402 -14577
- package/dist/src/app/board.js +217 -41
- package/dist/src/app-opentui/adapters/command.d.ts +2 -0
- package/dist/src/app-opentui/adapters/command.js +329 -0
- package/dist/src/app-opentui/adapters/common.js +2 -2
- package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
- package/dist/src/app-opentui/adapters/doctor.js +64 -39
- package/dist/src/app-opentui/adapters/family.d.ts +62 -0
- package/dist/src/app-opentui/adapters/family.js +14305 -0
- package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
- package/dist/src/app-opentui/adapters/fleet.js +90 -60
- package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
- package/dist/src/app-opentui/adapters/inbox.js +137 -78
- package/dist/src/app-opentui/adapters/init.d.ts +0 -2
- package/dist/src/app-opentui/adapters/init.js +85 -47
- package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
- package/dist/src/app-opentui/adapters/inspect.js +1024 -0
- package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
- package/dist/src/app-opentui/adapters/pi-attach.js +442 -125
- package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
- package/dist/src/app-opentui/adapters/pi.js +363 -0
- package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
- package/dist/src/app-opentui/adapters/plugin.js +544 -0
- package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
- package/dist/src/app-opentui/adapters/repo.js +186 -0
- package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
- package/dist/src/app-opentui/adapters/run-detail.js +180 -63
- package/dist/src/app-opentui/adapters/server.d.ts +10 -2
- package/dist/src/app-opentui/adapters/server.js +191 -45
- package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
- package/dist/src/app-opentui/adapters/tasks.js +1123 -143
- package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
- package/dist/src/app-opentui/adapters/workspace.js +333 -0
- package/dist/src/app-opentui/autocomplete.d.ts +20 -0
- package/dist/src/app-opentui/autocomplete.js +576 -0
- package/dist/src/app-opentui/bootstrap.d.ts +1 -6
- package/dist/src/app-opentui/bootstrap.js +25252 -16474
- package/dist/src/app-opentui/command-palette.d.ts +3 -0
- package/dist/src/app-opentui/command-palette.js +1010 -0
- package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
- package/dist/src/app-opentui/command-pty-host.js +248 -0
- package/dist/src/app-opentui/drone.js +8 -6
- package/dist/src/app-opentui/events.js +1 -1
- package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
- package/dist/src/app-opentui/fleet-stats.js +114 -0
- package/dist/src/app-opentui/focus-manager.d.ts +14 -0
- package/dist/src/app-opentui/focus-manager.js +24 -0
- package/dist/src/app-opentui/index.js +5431 -2797
- package/dist/src/app-opentui/intent.js +179 -50
- package/dist/src/app-opentui/keymap.d.ts +21 -0
- package/dist/src/app-opentui/keymap.js +1748 -0
- package/dist/src/app-opentui/launch-routing.d.ts +16 -0
- package/dist/src/app-opentui/launch-routing.js +55 -0
- package/dist/src/app-opentui/layout.d.ts +7 -0
- package/dist/src/app-opentui/layout.js +13 -6
- package/dist/src/app-opentui/list-search.d.ts +24 -0
- package/dist/src/app-opentui/list-search.js +88 -1
- package/dist/src/app-opentui/pi-host-child.js +99 -17
- package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
- package/dist/src/app-opentui/pi-pty-host.js +30 -14
- package/dist/src/app-opentui/react/App.d.ts +9 -0
- package/dist/src/app-opentui/react/App.js +5144 -0
- package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
- package/dist/src/app-opentui/react/Backdrop.js +1834 -0
- package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
- package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
- package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
- package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
- package/dist/src/app-opentui/react/context.d.ts +17 -0
- package/dist/src/app-opentui/react/context.js +37 -0
- package/dist/src/app-opentui/react/launch.d.ts +2 -0
- package/dist/src/app-opentui/react/launch.js +5743 -0
- package/dist/src/app-opentui/react/nav.d.ts +18 -0
- package/dist/src/app-opentui/react/nav.js +54 -0
- package/dist/src/app-opentui/react/scroll.d.ts +12 -0
- package/dist/src/app-opentui/react/scroll.js +21 -0
- package/dist/src/app-opentui/react/syntax.d.ts +2 -0
- package/dist/src/app-opentui/react/syntax.js +64 -0
- package/dist/src/app-opentui/registry.js +20428 -4828
- package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
- package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
- package/dist/src/app-opentui/render/constants.d.ts +31 -0
- package/dist/src/app-opentui/render/constants.js +66 -0
- package/dist/src/app-opentui/render/graphics.d.ts +2 -1
- package/dist/src/app-opentui/render/graphics.js +228 -46
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
- package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
- package/dist/src/app-opentui/render/native-host.d.ts +37 -0
- package/dist/src/app-opentui/render/native-host.js +179 -0
- package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
- package/dist/src/app-opentui/render/panel-layout.js +48 -0
- package/dist/src/app-opentui/render/panels.d.ts +2 -0
- package/dist/src/app-opentui/render/panels.js +78 -38
- package/dist/src/app-opentui/render/preloader.d.ts +10 -0
- package/dist/src/app-opentui/render/preloader.js +165 -0
- package/dist/src/app-opentui/render/scene.d.ts +53 -1
- package/dist/src/app-opentui/render/scene.js +195 -6
- package/dist/src/app-opentui/render/text.d.ts +7 -1
- package/dist/src/app-opentui/render/text.js +15 -8
- package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
- package/dist/src/app-opentui/render/type-bar.js +113 -39
- package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
- package/dist/src/app-opentui/runtime-resources.js +62 -0
- package/dist/src/app-opentui/runtime.d.ts +44 -1
- package/dist/src/app-opentui/runtime.js +5415 -2738
- package/dist/src/app-opentui/scenes/command.d.ts +3 -0
- package/dist/src/app-opentui/scenes/command.js +117 -0
- package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
- package/dist/src/app-opentui/scenes/doctor.js +221 -17
- package/dist/src/app-opentui/scenes/error.js +60 -20
- package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
- package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
- package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
- package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
- package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
- package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
- package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
- package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
- package/dist/src/app-opentui/scenes/family.d.ts +3 -0
- package/dist/src/app-opentui/scenes/family.js +2144 -0
- package/dist/src/app-opentui/scenes/fleet.js +552 -43
- package/dist/src/app-opentui/scenes/handoff.js +342 -35
- package/dist/src/app-opentui/scenes/help.js +640 -56
- package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
- package/dist/src/app-opentui/scenes/inbox.js +329 -21
- package/dist/src/app-opentui/scenes/init.d.ts +2 -1
- package/dist/src/app-opentui/scenes/init.js +120 -34
- package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
- package/dist/src/app-opentui/scenes/inspect.js +793 -0
- package/dist/src/app-opentui/scenes/main.d.ts +2 -1
- package/dist/src/app-opentui/scenes/main.js +264 -29
- package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
- package/dist/src/app-opentui/scenes/pi.js +508 -0
- package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
- package/dist/src/app-opentui/scenes/plugin.js +486 -0
- package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
- package/dist/src/app-opentui/scenes/repo.js +424 -0
- package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
- package/dist/src/app-opentui/scenes/run-detail.js +362 -35
- package/dist/src/app-opentui/scenes/server.d.ts +2 -1
- package/dist/src/app-opentui/scenes/server.js +243 -26
- package/dist/src/app-opentui/scenes/tasks.js +518 -41
- package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
- package/dist/src/app-opentui/scenes/workspace.js +426 -0
- package/dist/src/app-opentui/selectable.d.ts +19 -0
- package/dist/src/app-opentui/selectable.js +79 -0
- package/dist/src/app-opentui/state.js +129 -36
- package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
- package/dist/src/app-opentui/surface-catalog.js +540 -0
- package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
- package/dist/src/app-opentui/terminal-capabilities.js +15 -0
- package/dist/src/app-opentui/theme.d.ts +28 -6
- package/dist/src/app-opentui/theme.js +61 -8
- package/dist/src/app-opentui/types.d.ts +130 -5
- package/dist/src/commands/_authority-runs.d.ts +1 -1
- package/dist/src/commands/_authority-runs.js +2 -12
- package/dist/src/commands/_doctor-checks.js +62 -13
- package/dist/src/commands/_help-catalog.js +95 -15
- package/dist/src/commands/_operator-view.js +97 -15
- package/dist/src/commands/_pi-frontend.d.ts +2 -0
- package/dist/src/commands/_pi-frontend.js +97 -13
- package/dist/src/commands/_preflight.js +64 -14
- package/dist/src/commands/_server-client.js +82 -18
- package/dist/src/commands/_server-events.d.ts +26 -0
- package/dist/src/commands/_server-events.js +310 -0
- package/dist/src/commands/_snapshot-upload.js +62 -13
- package/dist/src/commands/agent.js +2 -12
- package/dist/src/commands/connect.js +7 -1
- package/dist/src/commands/doctor.js +62 -13
- package/dist/src/commands/github.js +144 -23
- package/dist/src/commands/inbox.js +62 -13
- package/dist/src/commands/init.js +82 -18
- package/dist/src/commands/inspect.js +62 -13
- package/dist/src/commands/run.js +100 -15
- package/dist/src/commands/server.js +71 -26
- package/dist/src/commands/setup.js +62 -13
- package/dist/src/commands/stats.js +157 -28
- package/dist/src/commands/task-run-driver.js +64 -25
- package/dist/src/commands/task.js +196 -43
- package/dist/src/commands.js +419 -123
- package/dist/src/index.js +426 -130
- package/package.json +11 -10
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
|
@@ -11,15 +11,17 @@ var RIG_UI = {
|
|
|
11
11
|
bg: "#070809",
|
|
12
12
|
bg2: "#0b0c0e",
|
|
13
13
|
panel: "#101115",
|
|
14
|
-
panel2: "#
|
|
15
|
-
glass: "#
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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"
|
|
@@ -38,11 +40,11 @@ var styles = {
|
|
|
38
40
|
};
|
|
39
41
|
function statusColor(status) {
|
|
40
42
|
switch (status) {
|
|
41
|
-
case "running":
|
|
42
43
|
case "success":
|
|
43
44
|
case "completed":
|
|
44
45
|
case "merged":
|
|
45
46
|
return RIG_UI.lime;
|
|
47
|
+
case "running":
|
|
46
48
|
case "preparing":
|
|
47
49
|
case "created":
|
|
48
50
|
case "validating":
|
|
@@ -63,6 +65,134 @@ function statusColor(status) {
|
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
|
|
68
|
+
// packages/cli/src/app-opentui/drone.ts
|
|
69
|
+
import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
|
|
70
|
+
var MINI_DRONE = [
|
|
71
|
+
"(!!!) (!!!)",
|
|
72
|
+
" \\%==%/ ",
|
|
73
|
+
" %%?%% ",
|
|
74
|
+
" /%==%\\ ",
|
|
75
|
+
"(!!!) (!!!)"
|
|
76
|
+
];
|
|
77
|
+
var LEAD_MARK = [
|
|
78
|
+
" .-=-. ",
|
|
79
|
+
"=%%?%%=",
|
|
80
|
+
" '-=-' "
|
|
81
|
+
];
|
|
82
|
+
var BLADE_FRAMES = ["---", "\\\\\\", "|||", "///"];
|
|
83
|
+
var EYE_FRAMES = ["o", "@", "\u2022", "."];
|
|
84
|
+
var COLOR = {
|
|
85
|
+
body: RGBA.fromHex(RIG_UI.lime),
|
|
86
|
+
mini: RGBA.fromHex(RIG_UI.limeDim),
|
|
87
|
+
rotor: RGBA.fromHex(RIG_UI.cyan),
|
|
88
|
+
path: RGBA.fromHex(RIG_UI.cyan),
|
|
89
|
+
eye: RGBA.fromHex(RIG_UI.ink),
|
|
90
|
+
dim: RGBA.fromHex(RIG_UI.ink4),
|
|
91
|
+
ink: RGBA.fromHex(RIG_UI.ink2)
|
|
92
|
+
};
|
|
93
|
+
function bladeForTick(tick, phase = 0) {
|
|
94
|
+
return BLADE_FRAMES[(Math.floor(tick / 3) + phase) % BLADE_FRAMES.length];
|
|
95
|
+
}
|
|
96
|
+
function eyeForTick(tick, phase = 0) {
|
|
97
|
+
const pulse = Math.sin(tick * 0.09 + phase);
|
|
98
|
+
return pulse > 0.55 ? EYE_FRAMES[1] : pulse > 0.1 ? EYE_FRAMES[0] : pulse > -0.45 ? EYE_FRAMES[2] : EYE_FRAMES[3];
|
|
99
|
+
}
|
|
100
|
+
function chunk(text, fg, bold = false, dim = false) {
|
|
101
|
+
let attributes = TextAttributes2.NONE;
|
|
102
|
+
if (bold)
|
|
103
|
+
attributes |= TextAttributes2.BOLD;
|
|
104
|
+
if (dim)
|
|
105
|
+
attributes |= TextAttributes2.DIM;
|
|
106
|
+
return { __isChunk: true, text, fg, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
|
|
107
|
+
}
|
|
108
|
+
function styledLine(text, colorFor) {
|
|
109
|
+
const chunks = [];
|
|
110
|
+
let run = "";
|
|
111
|
+
let runColor = null;
|
|
112
|
+
const flush = () => {
|
|
113
|
+
if (!run || !runColor)
|
|
114
|
+
return;
|
|
115
|
+
chunks.push(chunk(run, COLOR[runColor], runColor === "body" || runColor === "eye", runColor === "dim"));
|
|
116
|
+
run = "";
|
|
117
|
+
};
|
|
118
|
+
for (const char of text) {
|
|
119
|
+
const next = colorFor(char);
|
|
120
|
+
if (next !== runColor) {
|
|
121
|
+
flush();
|
|
122
|
+
runColor = next;
|
|
123
|
+
}
|
|
124
|
+
run += char;
|
|
125
|
+
}
|
|
126
|
+
flush();
|
|
127
|
+
return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
|
|
128
|
+
}
|
|
129
|
+
function droneColor(char) {
|
|
130
|
+
if (char === "?" || char === "o" || char === "@" || char === "\u2022")
|
|
131
|
+
return "eye";
|
|
132
|
+
if (char === "%" || char === "=")
|
|
133
|
+
return "mini";
|
|
134
|
+
if (char === "$")
|
|
135
|
+
return "body";
|
|
136
|
+
if (char === "(" || char === ")" || char === "/" || char === "\\" || char === "|" || char === "-")
|
|
137
|
+
return "rotor";
|
|
138
|
+
if (char === "\xB7" || char === "\u2022" || char === "'" || char === ".")
|
|
139
|
+
return "path";
|
|
140
|
+
if (char.trim() === "")
|
|
141
|
+
return "dim";
|
|
142
|
+
return "ink";
|
|
143
|
+
}
|
|
144
|
+
function motionColor(char) {
|
|
145
|
+
if (char === "\u25CF" || char === "\u25C6" || char === "\u25C9")
|
|
146
|
+
return "body";
|
|
147
|
+
if (char === "\u2022" || char === "\xB7" || char === "\u2500" || char === "\u2502" || char === "\u2571" || char === "\u2572" || char === "\u256D" || char === "\u256E" || char === "\u2570" || char === "\u256F")
|
|
148
|
+
return "path";
|
|
149
|
+
if (char === "\u258C" || char === "\u2590" || char === "\u2581" || char === "\u2594")
|
|
150
|
+
return "mini";
|
|
151
|
+
return droneColor(char);
|
|
152
|
+
}
|
|
153
|
+
function materializeDrone(lines, tick, phase = 0) {
|
|
154
|
+
const blade = bladeForTick(tick, phase);
|
|
155
|
+
const eye = eyeForTick(tick, phase);
|
|
156
|
+
return lines.map((line) => line.replaceAll("!!!", blade).replaceAll("?", eye));
|
|
157
|
+
}
|
|
158
|
+
function miniDroneLines(tick, align = "left", phase = 0) {
|
|
159
|
+
return materializeDrone(MINI_DRONE, tick, phase).map((text) => ({
|
|
160
|
+
text,
|
|
161
|
+
styledText: styledLine(text, droneColor),
|
|
162
|
+
fg: RIG_UI.limeDim,
|
|
163
|
+
align
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
166
|
+
function brandFleetLines(tick, align = "center") {
|
|
167
|
+
const left = materializeDrone(MINI_DRONE, tick, 0);
|
|
168
|
+
const right = materializeDrone(MINI_DRONE, tick, 2);
|
|
169
|
+
const lead = materializeDrone(LEAD_MARK, tick, 1);
|
|
170
|
+
const packet = ["\xB7", "\u2022", "\u25CF", "\u2022"][Math.floor(tick / 2) % 4];
|
|
171
|
+
const bridge = [
|
|
172
|
+
` ${left[0]} ${lead[0]} ${right[0]}`,
|
|
173
|
+
` ${left[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${lead[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${right[1]}`,
|
|
174
|
+
` ${left[2]} \xB7' '${lead[2]}' '\xB7 ${right[2]}`,
|
|
175
|
+
` ${left[3]} \u2572 signal bus \u2571 ${right[3]}`,
|
|
176
|
+
` ${left[4]} \xB7\u2500\u2500\u2500${packet}\u2500\u2500\u2500\u2500\u2500\u2500${packet}\u2500\u2500\u2500\xB7 ${right[4]}`
|
|
177
|
+
];
|
|
178
|
+
return bridge.map((text) => ({
|
|
179
|
+
text,
|
|
180
|
+
styledText: styledLine(text, motionColor),
|
|
181
|
+
fg: RIG_UI.limeDim,
|
|
182
|
+
align
|
|
183
|
+
}));
|
|
184
|
+
}
|
|
185
|
+
function actionDrone(tick, phase = 0) {
|
|
186
|
+
const blade = bladeForTick(tick, phase);
|
|
187
|
+
const eye = eyeForTick(tick, phase);
|
|
188
|
+
return `(${blade})\u2572${eye}\u2571(${blade})`;
|
|
189
|
+
}
|
|
190
|
+
function actionDroneLine(tick, text, fg = RIG_UI.ink2) {
|
|
191
|
+
const prefix = actionDrone(tick);
|
|
192
|
+
const content = `${prefix} ${text}`;
|
|
193
|
+
return { text: content, styledText: styledLine(content, motionColor), fg, align: "center" };
|
|
194
|
+
}
|
|
195
|
+
|
|
66
196
|
// packages/cli/src/app-opentui/render/scene.ts
|
|
67
197
|
function line(text, options = {}) {
|
|
68
198
|
return { text, ...options };
|
|
@@ -70,9 +200,6 @@ function line(text, options = {}) {
|
|
|
70
200
|
function blank() {
|
|
71
201
|
return { text: "" };
|
|
72
202
|
}
|
|
73
|
-
function center(text, fg = RIG_UI.ink2, bold = false) {
|
|
74
|
-
return { text, fg, bold, align: "center" };
|
|
75
|
-
}
|
|
76
203
|
function deckRow(input) {
|
|
77
204
|
const prefix = input.active ? "\u25B8" : " ";
|
|
78
205
|
const label = input.label.toUpperCase().padEnd(10);
|
|
@@ -86,11 +213,81 @@ function deckRow(input) {
|
|
|
86
213
|
function kv(label, value, fg = RIG_UI.ink2) {
|
|
87
214
|
return line(` ${label.toUpperCase().padEnd(10)} ${value}`, { fg });
|
|
88
215
|
}
|
|
216
|
+
function loadingRows(label, tick = 0, compact = false) {
|
|
217
|
+
const mascot = compact ? miniDroneLines(tick, "center") : brandFleetLines(tick, "center");
|
|
218
|
+
return [
|
|
219
|
+
blank(),
|
|
220
|
+
...mascot,
|
|
221
|
+
blank(),
|
|
222
|
+
{ ...actionDroneLine(tick, `loading ${label}\u2026`, RIG_UI.cyan), align: "center" }
|
|
223
|
+
];
|
|
224
|
+
}
|
|
225
|
+
function errorBanner(message, hint) {
|
|
226
|
+
return [
|
|
227
|
+
line(`\u2717 failed to load \u2014 ${message}`, { fg: RIG_UI.red, bold: true }),
|
|
228
|
+
...hint ? [line(` ${hint}`, { fg: RIG_UI.ink3 })] : [],
|
|
229
|
+
line(" select refresh/retry below", { fg: RIG_UI.ink4 }),
|
|
230
|
+
line("", { fg: RIG_UI.ink3 })
|
|
231
|
+
];
|
|
232
|
+
}
|
|
233
|
+
function lastRefreshError(state) {
|
|
234
|
+
const value = state.data.lastRefreshError;
|
|
235
|
+
return typeof value === "string" && value.trim() ? value : undefined;
|
|
236
|
+
}
|
|
89
237
|
function makeSceneFrame(input) {
|
|
90
238
|
return input;
|
|
91
239
|
}
|
|
92
240
|
|
|
241
|
+
// packages/cli/src/app-opentui/selectable.ts
|
|
242
|
+
function withSelectable(line2, item) {
|
|
243
|
+
return { ...line2, selectable: item, activateOnClick: true };
|
|
244
|
+
}
|
|
245
|
+
|
|
93
246
|
// packages/cli/src/app-opentui/scenes/run-detail.ts
|
|
247
|
+
function actionRow(deck, item) {
|
|
248
|
+
const row = deckRow({ ...deck, activateOnClick: true });
|
|
249
|
+
return item ? withSelectable(row, item) : row;
|
|
250
|
+
}
|
|
251
|
+
function isTerminalRunStatus(status) {
|
|
252
|
+
return ["completed", "complete", "done", "failed", "error", "errored", "merged", "cancelled", "canceled", "stopped", "aborted"].includes(status.toLowerCase());
|
|
253
|
+
}
|
|
254
|
+
function runDetailActions(runId, status) {
|
|
255
|
+
const short = runId ? runId.slice(0, 8) : "";
|
|
256
|
+
const attach = {
|
|
257
|
+
label: "pi",
|
|
258
|
+
detail: "attach bundled Pi \u2014 live or finished transcript",
|
|
259
|
+
item: runId ? { id: "attach", label: "attach", intent: { scene: "handoff", argv: ["attach", runId], action: { kind: "run-attach", payload: { runId }, label: `Attach Pi ${short}` } }, message: "attach real bundled Pi" } : null
|
|
260
|
+
};
|
|
261
|
+
const inspect = {
|
|
262
|
+
label: "inspect",
|
|
263
|
+
detail: "logs/timeline/diff/failures",
|
|
264
|
+
item: runId ? { id: "inspect", label: "inspect", data: { selectedRunId: runId }, intent: { scene: "inspect", argv: ["inspect", runId], action: { kind: "refresh", payload: { runId }, label: `Inspect ${short}` } }, message: "logs/timeline/diff/failures" } : null
|
|
265
|
+
};
|
|
266
|
+
const fleet = {
|
|
267
|
+
label: "runs",
|
|
268
|
+
detail: "return to fleet",
|
|
269
|
+
item: { id: "fleet", label: "fleet", intent: { scene: "fleet", argv: ["fleet"], action: { kind: "refresh", label: "Opening fleet" } }, message: "back to fleet" }
|
|
270
|
+
};
|
|
271
|
+
if (runId && isTerminalRunStatus(status)) {
|
|
272
|
+
const rerun = {
|
|
273
|
+
label: "rerun",
|
|
274
|
+
detail: "re-dispatch this run from a clean runtime",
|
|
275
|
+
item: { id: "rerun", label: "rerun", intent: { scene: "command", argv: ["run", "restart", runId], action: { kind: "command-run", payload: { runId }, label: `Rerun ${short}` } }, message: "re-dispatch this run (rig run restart)" }
|
|
276
|
+
};
|
|
277
|
+
return [attach, rerun, inspect, fleet];
|
|
278
|
+
}
|
|
279
|
+
const steer = {
|
|
280
|
+
label: "steer",
|
|
281
|
+
detail: "send an inline steer message",
|
|
282
|
+
item: runId ? { id: "steer", label: "steer", prompt: { label: `steer ${short}`, scene: "run-detail", argv: ["steer", runId], intentKind: "run-steer", payloadBase: { runId }, payloadKey: "message" }, message: "send an inline steer message" } : null
|
|
283
|
+
};
|
|
284
|
+
const stop = {
|
|
285
|
+
label: "stop",
|
|
286
|
+
detail: "request stop",
|
|
287
|
+
item: runId ? { id: "stop", label: "stop", intent: { scene: "run-detail", argv: ["stop", runId], action: { kind: "run-stop", payload: { runId }, label: `Stop ${short}` } }, message: "request stop" } : null
|
|
288
|
+
};
|
|
289
|
+
return [attach, steer, stop, inspect, fleet];
|
|
290
|
+
}
|
|
94
291
|
function snapshot(state) {
|
|
95
292
|
const value = state.data.runDetail;
|
|
96
293
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -100,37 +297,167 @@ function selectedRunId(state, run) {
|
|
|
100
297
|
return run.runId;
|
|
101
298
|
return typeof state.data.selectedRunId === "string" ? state.data.selectedRunId : undefined;
|
|
102
299
|
}
|
|
103
|
-
|
|
104
|
-
|
|
300
|
+
var ENTRY_ROW_LIMIT = 40;
|
|
301
|
+
function entryField(entry, keys) {
|
|
302
|
+
for (const key of keys) {
|
|
303
|
+
const value = entry[key];
|
|
304
|
+
if (typeof value === "string" && value.trim())
|
|
305
|
+
return value.trim();
|
|
306
|
+
if (typeof value === "number")
|
|
307
|
+
return String(value);
|
|
308
|
+
}
|
|
309
|
+
return "";
|
|
310
|
+
}
|
|
311
|
+
function entryMessage(entry) {
|
|
312
|
+
return String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? entry.type ?? "event").replace(/\s+/g, " ").slice(0, 160);
|
|
313
|
+
}
|
|
314
|
+
function entrySeverityColor(entry, fallback) {
|
|
315
|
+
const token = `${entryField(entry, ["type", "level", "status", "kind"])} ${entryMessage(entry)}`.toLowerCase();
|
|
316
|
+
if (/\b(fail|failed|failure|error|fatal|crash|abort)\b/.test(token))
|
|
317
|
+
return RIG_UI.red;
|
|
318
|
+
if (/\b(warn|warning|attention|degraded|retry)\b/.test(token))
|
|
319
|
+
return RIG_UI.yellow;
|
|
320
|
+
if (/\b(success|succeeded|completed|done|merged|passed)\b/.test(token))
|
|
321
|
+
return RIG_UI.limeDim;
|
|
322
|
+
return fallback;
|
|
323
|
+
}
|
|
324
|
+
function entryRow(entry, fallback) {
|
|
325
|
+
const color = entrySeverityColor(entry, fallback);
|
|
326
|
+
const time = entryField(entry, ["timestamp", "ts", "time", "at"]).replace("T", " ").slice(0, 19);
|
|
327
|
+
const type = entryField(entry, ["type", "level", "kind", "status"]).slice(0, 14);
|
|
328
|
+
const glyph = color === RIG_UI.red ? "\u2717" : color === RIG_UI.yellow ? "\u26A0" : "\xB7";
|
|
329
|
+
const segments = [time, type ? type.toUpperCase() : undefined, entryMessage(entry)].filter((part) => Boolean(part));
|
|
330
|
+
return line(`${glyph} ${segments.join(" \xB7 ")}`, { fg: color, bold: color === RIG_UI.red });
|
|
331
|
+
}
|
|
332
|
+
function entrySection(label, entries, fallback) {
|
|
333
|
+
if (entries.length === 0)
|
|
334
|
+
return [];
|
|
335
|
+
const shown = entries.slice(0, ENTRY_ROW_LIMIT);
|
|
336
|
+
const overflow = entries.length - shown.length;
|
|
337
|
+
return [
|
|
338
|
+
line("", { fg: RIG_UI.ink3 }),
|
|
339
|
+
line(`${label} (${entries.length})`, { fg: RIG_UI.ink3, bold: true }),
|
|
340
|
+
...shown.map((entry) => entryRow(entry, fallback)),
|
|
341
|
+
...overflow > 0 ? [line(` (${overflow} more)`, { fg: RIG_UI.ink4 })] : []
|
|
342
|
+
];
|
|
343
|
+
}
|
|
344
|
+
function primaryError(state) {
|
|
345
|
+
return state.error?.message ?? lastRefreshError(state);
|
|
346
|
+
}
|
|
347
|
+
function optimisticStatus(state, runId) {
|
|
348
|
+
const value = state.data.optimisticRun;
|
|
349
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
350
|
+
return;
|
|
351
|
+
const record = value;
|
|
352
|
+
if (runId && record.runId !== runId)
|
|
353
|
+
return;
|
|
354
|
+
return typeof record.status === "string" ? record.status : undefined;
|
|
355
|
+
}
|
|
356
|
+
function pendingSteer(state, runId) {
|
|
357
|
+
const value = state.data.pendingRunMessage;
|
|
358
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
359
|
+
return null;
|
|
360
|
+
const record = value;
|
|
361
|
+
if (runId && record.runId !== runId)
|
|
362
|
+
return null;
|
|
363
|
+
if (typeof record.text !== "string")
|
|
364
|
+
return null;
|
|
365
|
+
return {
|
|
366
|
+
text: record.text,
|
|
367
|
+
status: typeof record.status === "string" ? record.status : "queued",
|
|
368
|
+
...typeof record.result === "string" && record.result.trim() ? { result: record.result.trim() } : {}
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
function steerBlock(pending) {
|
|
372
|
+
const failed = pending.status === "failed";
|
|
373
|
+
const sent = pending.status === "sent" || pending.status === "delivered";
|
|
374
|
+
const glyph = failed ? "\u2717" : sent ? "\u2713" : "\u27F3";
|
|
375
|
+
const color = failed ? RIG_UI.red : sent ? RIG_UI.lime : RIG_UI.cyan;
|
|
376
|
+
const echoed = pending.text.length > 84 ? `${pending.text.slice(0, 83)}\u2026` : pending.text;
|
|
377
|
+
return [
|
|
378
|
+
line("", { fg: RIG_UI.ink3 }),
|
|
379
|
+
line(`${glyph} STEER \xB7 ${pending.status}`, { fg: color, bold: true }),
|
|
380
|
+
line(` "${echoed}"`, { fg: RIG_UI.ink2 }),
|
|
381
|
+
...pending.result ? [line(` ${failed ? "error" : "result"}: ${pending.result.replace(/\s+/g, " ").slice(0, 120)}`, { fg: failed ? RIG_UI.red : RIG_UI.ink3 })] : []
|
|
382
|
+
];
|
|
105
383
|
}
|
|
106
|
-
function
|
|
384
|
+
function timelineCountLabel(snapshot2) {
|
|
385
|
+
const shown = snapshot2.timeline.length;
|
|
386
|
+
const total = snapshot2.timelineTotal;
|
|
387
|
+
return total !== undefined && total > shown ? `showing ${shown} of ${total}` : `${shown} loaded`;
|
|
388
|
+
}
|
|
389
|
+
function loadMoreItem(runId, cursor) {
|
|
390
|
+
return {
|
|
391
|
+
id: "timeline-load-more",
|
|
392
|
+
label: "load more timeline",
|
|
393
|
+
data: { runDetailLoadMore: { runId, cursor } },
|
|
394
|
+
intent: { scene: "run-detail", argv: ["run", "status", runId], action: { kind: "refresh", payload: { runId }, label: "Load more timeline" } },
|
|
395
|
+
message: "fetch the next page of timeline events"
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
function panelWidth(layout) {
|
|
399
|
+
return layout?.centerWidth ?? 100;
|
|
400
|
+
}
|
|
401
|
+
function panelHeight(layout) {
|
|
402
|
+
return Math.max(10, (layout?.centerHeight ?? 24) - 1);
|
|
403
|
+
}
|
|
404
|
+
function renderRunDetailScene(state, layout) {
|
|
107
405
|
const run = snapshot(state);
|
|
108
406
|
const runId = selectedRunId(state, run);
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
...
|
|
126
|
-
|
|
127
|
-
];
|
|
407
|
+
const status = optimisticStatus(state, runId) ?? run?.status ?? "loading";
|
|
408
|
+
const actions = runDetailActions(runId, status);
|
|
409
|
+
const actionCount = actions.length;
|
|
410
|
+
const canLoadMore = Boolean(run?.timelineCursor && runId);
|
|
411
|
+
const loadMoreIndex = actionCount;
|
|
412
|
+
const maxIndex = canLoadMore ? loadMoreIndex : Math.max(0, actionCount - 1);
|
|
413
|
+
const selected = Math.max(0, Math.min(maxIndex, state.selection.index));
|
|
414
|
+
const timeline = run?.timeline ?? [];
|
|
415
|
+
const logs = run?.logs ?? [];
|
|
416
|
+
const pending = pendingSteer(state, runId);
|
|
417
|
+
const loading = state.status === "loading" && !run;
|
|
418
|
+
const errorText = primaryError(state);
|
|
419
|
+
const timelineSection = run ? [
|
|
420
|
+
line("", { fg: RIG_UI.ink3 }),
|
|
421
|
+
line(`TIMELINE \xB7 ${timelineCountLabel(run)}`, { fg: RIG_UI.ink3, bold: true }),
|
|
422
|
+
...timeline.slice(0, ENTRY_ROW_LIMIT).map((entry) => entryRow(entry, RIG_UI.ink2)),
|
|
423
|
+
...canLoadMore && runId ? [withSelectable(deckRow({ label: "load more", detail: `next page \xB7 ${timelineCountLabel(run)}`, index: loadMoreIndex, active: selected === loadMoreIndex, activateOnClick: true }), loadMoreItem(runId, run.timelineCursor))] : []
|
|
424
|
+
] : [];
|
|
128
425
|
return makeSceneFrame({
|
|
129
426
|
scene: "run-detail",
|
|
130
427
|
title: "Run",
|
|
131
|
-
lines
|
|
132
|
-
|
|
133
|
-
|
|
428
|
+
lines: [
|
|
429
|
+
line("", { fg: RIG_UI.ink4 }),
|
|
430
|
+
line(` run \xB7 ${runId ? `${runId.slice(0, 8)} \xB7 ${status}` : "loading"}`, { fg: run ? statusColor(status) : RIG_UI.ink3 })
|
|
431
|
+
],
|
|
432
|
+
panels: [{
|
|
433
|
+
id: "run-detail",
|
|
434
|
+
top: 0,
|
|
435
|
+
width: panelWidth(layout),
|
|
436
|
+
height: panelHeight(layout),
|
|
437
|
+
lines: [
|
|
438
|
+
...errorText ? errorBanner(errorText, "select inspect/runs below, or retry the action") : [],
|
|
439
|
+
line(run ? run.title : "Run telemetry", { fg: RIG_UI.ink, bold: true }),
|
|
440
|
+
...loading ? loadingRows("run telemetry", state.tick) : runId ? [kv("run", runId, RIG_UI.ink2), kv("status", status, statusColor(status))] : [line("loading run telemetry", { fg: RIG_UI.ink3 })],
|
|
441
|
+
...pending ? steerBlock(pending) : [],
|
|
442
|
+
line("", { fg: RIG_UI.ink3 }),
|
|
443
|
+
line("ACTIONS", { fg: RIG_UI.ink3, bold: true }),
|
|
444
|
+
...actions.map((action, index) => actionRow({ label: action.label, detail: action.detail, index, active: selected === index }, action.item)),
|
|
445
|
+
...timelineSection,
|
|
446
|
+
...entrySection("LOGS", logs, RIG_UI.ink3)
|
|
447
|
+
],
|
|
448
|
+
backgroundColor: RIG_UI.panel,
|
|
449
|
+
backgroundAlpha: 184,
|
|
450
|
+
opacity: 1,
|
|
451
|
+
border: false,
|
|
452
|
+
stickyScroll: true,
|
|
453
|
+
stickyStart: "bottom",
|
|
454
|
+
chrome: "ad-terminal",
|
|
455
|
+
headerText: runId ? `run ${runId.slice(0, 8)}` : "run",
|
|
456
|
+
headerHeight: 3,
|
|
457
|
+
paddingX: layout?.compact ? 2 : 3,
|
|
458
|
+
paddingY: 1
|
|
459
|
+
}],
|
|
460
|
+
footer: { run: runId ? `${runId.slice(0, 8)} ${status}` : undefined, message: "enter/click action" },
|
|
134
461
|
live: state.status === "action" || !run
|
|
135
462
|
});
|
|
136
463
|
}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { AppSceneFrame, AppState } from "../types";
|
|
2
|
-
|
|
2
|
+
import type { StageLayout } from "../layout";
|
|
3
|
+
export declare function renderServerScene(state: AppState, layout?: StageLayout): AppSceneFrame;
|