@h-rig/cli 0.0.6-alpha.83 → 0.0.6-alpha.85
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/rig.js +22060 -14620
- package/dist/src/app/board.js +155 -28
- package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
- package/dist/src/app-opentui/adapters/doctor.js +1 -25
- 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 +6 -40
- package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
- package/dist/src/app-opentui/adapters/inbox.js +54 -59
- package/dist/src/app-opentui/adapters/init.d.ts +0 -2
- package/dist/src/app-opentui/adapters/init.js +0 -26
- 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 +348 -93
- 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 +97 -44
- package/dist/src/app-opentui/adapters/server.d.ts +10 -2
- package/dist/src/app-opentui/adapters/server.js +96 -27
- package/dist/src/app-opentui/adapters/tasks.d.ts +0 -2
- package/dist/src/app-opentui/adapters/tasks.js +437 -105
- 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.js +24313 -16963
- 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/drone.js +8 -6
- 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/index.js +3438 -1724
- package/dist/src/app-opentui/intent.js +71 -48
- package/dist/src/app-opentui/keymap.d.ts +6 -5
- package/dist/src/app-opentui/keymap.js +1064 -23
- 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 +33 -1
- package/dist/src/app-opentui/pi-pty-host.d.ts +5 -0
- package/dist/src/app-opentui/pi-pty-host.js +21 -3
- package/dist/src/app-opentui/react/App.d.ts +9 -0
- package/dist/src/app-opentui/react/App.js +5099 -0
- package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
- package/dist/src/app-opentui/react/Backdrop.js +829 -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 +5698 -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 +19923 -5151
- 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 +106 -39
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +108 -20
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +7 -0
- package/dist/src/app-opentui/render/image-visual-layer.js +109 -20
- 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/panels.js +18 -11
- package/dist/src/app-opentui/render/preloader.js +8 -6
- package/dist/src/app-opentui/render/scene.d.ts +50 -1
- package/dist/src/app-opentui/render/scene.js +183 -6
- package/dist/src/app-opentui/render/text.d.ts +7 -1
- package/dist/src/app-opentui/render/text.js +10 -7
- package/dist/src/app-opentui/render/type-bar.js +69 -30
- package/dist/src/app-opentui/runtime.d.ts +44 -1
- package/dist/src/app-opentui/runtime.js +3231 -1363
- package/dist/src/app-opentui/scenes/command.js +20 -6
- package/dist/src/app-opentui/scenes/doctor.js +176 -11
- package/dist/src/app-opentui/scenes/error.js +20 -10
- 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 +521 -31
- package/dist/src/app-opentui/scenes/handoff.js +204 -12
- package/dist/src/app-opentui/scenes/help.js +609 -40
- package/dist/src/app-opentui/scenes/inbox.js +278 -17
- package/dist/src/app-opentui/scenes/init.js +84 -39
- 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.js +218 -39
- 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.js +333 -20
- package/dist/src/app-opentui/scenes/server.js +181 -15
- package/dist/src/app-opentui/scenes/tasks.js +486 -31
- 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 +83 -30
- 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/theme.d.ts +28 -6
- package/dist/src/app-opentui/theme.js +61 -8
- package/dist/src/app-opentui/types.d.ts +121 -4
- package/dist/src/commands/_authority-runs.d.ts +1 -1
- package/dist/src/commands/_authority-runs.js +2 -12
- package/dist/src/commands/_help-catalog.js +95 -15
- package/dist/src/commands/_operator-view.js +34 -2
- package/dist/src/commands/_pi-frontend.d.ts +2 -0
- package/dist/src/commands/_pi-frontend.js +34 -0
- package/dist/src/commands/_server-events.d.ts +26 -0
- package/dist/src/commands/_server-events.js +310 -0
- package/dist/src/commands/agent.js +2 -12
- package/dist/src/commands/run.js +34 -2
- package/dist/src/commands/server.js +2 -12
- package/dist/src/commands/stats.js +95 -15
- package/dist/src/commands/task-run-driver.js +2 -12
- package/dist/src/commands/task.js +131 -29
- package/dist/src/commands.js +192 -31
- package/dist/src/index.js +192 -31
- package/package.json +11 -9
|
@@ -36,19 +36,25 @@ var RIG_UI = {
|
|
|
36
36
|
bg: "#070809",
|
|
37
37
|
bg2: "#0b0c0e",
|
|
38
38
|
panel: "#101115",
|
|
39
|
-
panel2: "#
|
|
40
|
-
glass: "#
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
panel2: "#14161b",
|
|
40
|
+
glass: "#1e2230",
|
|
41
|
+
border: "#2a2e3a",
|
|
42
|
+
ink: "#f4f5f8",
|
|
43
|
+
ink2: "#c7c9d3",
|
|
44
|
+
ink3: "#9aa0ae",
|
|
45
|
+
ink4: "#787b86",
|
|
45
46
|
lime: "#ccff4d",
|
|
46
47
|
limeDim: "#a9d63f",
|
|
47
48
|
cyan: "#56d8ff",
|
|
49
|
+
cyanDim: "#3f9fbd",
|
|
48
50
|
red: "#ff5d5d",
|
|
49
51
|
yellow: "#ffd24d",
|
|
50
52
|
magenta: "#ff79b0"
|
|
51
53
|
};
|
|
54
|
+
var SELECTION_MARKER = "\u258C";
|
|
55
|
+
var SELECTION_MARKER_IDLE = " ";
|
|
56
|
+
var LABEL_WIDTH = 14;
|
|
57
|
+
var COLUMN_GUTTER = " ";
|
|
52
58
|
var styles = {
|
|
53
59
|
ink: otuiFg(RIG_UI.ink),
|
|
54
60
|
ink2: otuiFg(RIG_UI.ink2),
|
|
@@ -62,6 +68,134 @@ var styles = {
|
|
|
62
68
|
magenta: otuiFg(RIG_UI.magenta)
|
|
63
69
|
};
|
|
64
70
|
|
|
71
|
+
// packages/cli/src/app-opentui/drone.ts
|
|
72
|
+
import { RGBA, StyledText, TextAttributes as TextAttributes2 } from "@opentui/core";
|
|
73
|
+
var MINI_DRONE = [
|
|
74
|
+
"(!!!) (!!!)",
|
|
75
|
+
" \\%==%/ ",
|
|
76
|
+
" %%?%% ",
|
|
77
|
+
" /%==%\\ ",
|
|
78
|
+
"(!!!) (!!!)"
|
|
79
|
+
];
|
|
80
|
+
var LEAD_MARK = [
|
|
81
|
+
" .-=-. ",
|
|
82
|
+
"=%%?%%=",
|
|
83
|
+
" '-=-' "
|
|
84
|
+
];
|
|
85
|
+
var BLADE_FRAMES = ["---", "\\\\\\", "|||", "///"];
|
|
86
|
+
var EYE_FRAMES = ["o", "@", "\u2022", "."];
|
|
87
|
+
var COLOR = {
|
|
88
|
+
body: RGBA.fromHex(RIG_UI.lime),
|
|
89
|
+
mini: RGBA.fromHex(RIG_UI.limeDim),
|
|
90
|
+
rotor: RGBA.fromHex(RIG_UI.cyan),
|
|
91
|
+
path: RGBA.fromHex(RIG_UI.cyan),
|
|
92
|
+
eye: RGBA.fromHex(RIG_UI.ink),
|
|
93
|
+
dim: RGBA.fromHex(RIG_UI.ink4),
|
|
94
|
+
ink: RGBA.fromHex(RIG_UI.ink2)
|
|
95
|
+
};
|
|
96
|
+
function bladeForTick(tick, phase = 0) {
|
|
97
|
+
return BLADE_FRAMES[(Math.floor(tick / 3) + phase) % BLADE_FRAMES.length];
|
|
98
|
+
}
|
|
99
|
+
function eyeForTick(tick, phase = 0) {
|
|
100
|
+
const pulse = Math.sin(tick * 0.09 + phase);
|
|
101
|
+
return pulse > 0.55 ? EYE_FRAMES[1] : pulse > 0.1 ? EYE_FRAMES[0] : pulse > -0.45 ? EYE_FRAMES[2] : EYE_FRAMES[3];
|
|
102
|
+
}
|
|
103
|
+
function chunk(text, fg, bold = false, dim = false) {
|
|
104
|
+
let attributes = TextAttributes2.NONE;
|
|
105
|
+
if (bold)
|
|
106
|
+
attributes |= TextAttributes2.BOLD;
|
|
107
|
+
if (dim)
|
|
108
|
+
attributes |= TextAttributes2.DIM;
|
|
109
|
+
return { __isChunk: true, text, fg, ...attributes !== TextAttributes2.NONE ? { attributes } : {} };
|
|
110
|
+
}
|
|
111
|
+
function styledLine(text, colorFor) {
|
|
112
|
+
const chunks = [];
|
|
113
|
+
let run = "";
|
|
114
|
+
let runColor = null;
|
|
115
|
+
const flush = () => {
|
|
116
|
+
if (!run || !runColor)
|
|
117
|
+
return;
|
|
118
|
+
chunks.push(chunk(run, COLOR[runColor], runColor === "body" || runColor === "eye", runColor === "dim"));
|
|
119
|
+
run = "";
|
|
120
|
+
};
|
|
121
|
+
for (const char of text) {
|
|
122
|
+
const next = colorFor(char);
|
|
123
|
+
if (next !== runColor) {
|
|
124
|
+
flush();
|
|
125
|
+
runColor = next;
|
|
126
|
+
}
|
|
127
|
+
run += char;
|
|
128
|
+
}
|
|
129
|
+
flush();
|
|
130
|
+
return new StyledText(chunks.length > 0 ? chunks : [chunk("", COLOR.ink)]);
|
|
131
|
+
}
|
|
132
|
+
function droneColor(char) {
|
|
133
|
+
if (char === "?" || char === "o" || char === "@" || char === "\u2022")
|
|
134
|
+
return "eye";
|
|
135
|
+
if (char === "%" || char === "=")
|
|
136
|
+
return "mini";
|
|
137
|
+
if (char === "$")
|
|
138
|
+
return "body";
|
|
139
|
+
if (char === "(" || char === ")" || char === "/" || char === "\\" || char === "|" || char === "-")
|
|
140
|
+
return "rotor";
|
|
141
|
+
if (char === "\xB7" || char === "\u2022" || char === "'" || char === ".")
|
|
142
|
+
return "path";
|
|
143
|
+
if (char.trim() === "")
|
|
144
|
+
return "dim";
|
|
145
|
+
return "ink";
|
|
146
|
+
}
|
|
147
|
+
function motionColor(char) {
|
|
148
|
+
if (char === "\u25CF" || char === "\u25C6" || char === "\u25C9")
|
|
149
|
+
return "body";
|
|
150
|
+
if (char === "\u2022" || char === "\xB7" || char === "\u2500" || char === "\u2502" || char === "\u2571" || char === "\u2572" || char === "\u256D" || char === "\u256E" || char === "\u2570" || char === "\u256F")
|
|
151
|
+
return "path";
|
|
152
|
+
if (char === "\u258C" || char === "\u2590" || char === "\u2581" || char === "\u2594")
|
|
153
|
+
return "mini";
|
|
154
|
+
return droneColor(char);
|
|
155
|
+
}
|
|
156
|
+
function materializeDrone(lines, tick, phase = 0) {
|
|
157
|
+
const blade = bladeForTick(tick, phase);
|
|
158
|
+
const eye = eyeForTick(tick, phase);
|
|
159
|
+
return lines.map((line) => line.replaceAll("!!!", blade).replaceAll("?", eye));
|
|
160
|
+
}
|
|
161
|
+
function miniDroneLines(tick, align = "left", phase = 0) {
|
|
162
|
+
return materializeDrone(MINI_DRONE, tick, phase).map((text) => ({
|
|
163
|
+
text,
|
|
164
|
+
styledText: styledLine(text, droneColor),
|
|
165
|
+
fg: RIG_UI.limeDim,
|
|
166
|
+
align
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
function brandFleetLines(tick, align = "center") {
|
|
170
|
+
const left = materializeDrone(MINI_DRONE, tick, 0);
|
|
171
|
+
const right = materializeDrone(MINI_DRONE, tick, 2);
|
|
172
|
+
const lead = materializeDrone(LEAD_MARK, tick, 1);
|
|
173
|
+
const packet = ["\xB7", "\u2022", "\u25CF", "\u2022"][Math.floor(tick / 2) % 4];
|
|
174
|
+
const bridge = [
|
|
175
|
+
` ${left[0]} ${lead[0]} ${right[0]}`,
|
|
176
|
+
` ${left[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${lead[1]} \xB7\u2500\u2500${packet}\u2500\u2500\xB7 ${right[1]}`,
|
|
177
|
+
` ${left[2]} \xB7' '${lead[2]}' '\xB7 ${right[2]}`,
|
|
178
|
+
` ${left[3]} \u2572 signal bus \u2571 ${right[3]}`,
|
|
179
|
+
` ${left[4]} \xB7\u2500\u2500\u2500${packet}\u2500\u2500\u2500\u2500\u2500\u2500${packet}\u2500\u2500\u2500\xB7 ${right[4]}`
|
|
180
|
+
];
|
|
181
|
+
return bridge.map((text) => ({
|
|
182
|
+
text,
|
|
183
|
+
styledText: styledLine(text, motionColor),
|
|
184
|
+
fg: RIG_UI.limeDim,
|
|
185
|
+
align
|
|
186
|
+
}));
|
|
187
|
+
}
|
|
188
|
+
function actionDrone(tick, phase = 0) {
|
|
189
|
+
const blade = bladeForTick(tick, phase);
|
|
190
|
+
const eye = eyeForTick(tick, phase);
|
|
191
|
+
return `(${blade})\u2572${eye}\u2571(${blade})`;
|
|
192
|
+
}
|
|
193
|
+
function actionDroneLine(tick, text, fg = RIG_UI.ink2) {
|
|
194
|
+
const prefix = actionDrone(tick);
|
|
195
|
+
const content = `${prefix} ${text}`;
|
|
196
|
+
return { text: content, styledText: styledLine(content, motionColor), fg, align: "center" };
|
|
197
|
+
}
|
|
198
|
+
|
|
65
199
|
// packages/cli/src/app-opentui/render/scene.ts
|
|
66
200
|
function line(text, options = {}) {
|
|
67
201
|
return { text, ...options };
|
|
@@ -85,6 +219,22 @@ function deckRow(input) {
|
|
|
85
219
|
function kv(label, value, fg = RIG_UI.ink2) {
|
|
86
220
|
return line(` ${label.toUpperCase().padEnd(10)} ${value}`, { fg });
|
|
87
221
|
}
|
|
222
|
+
function selectionLine(input) {
|
|
223
|
+
const marker = input.active ? SELECTION_MARKER : SELECTION_MARKER_IDLE;
|
|
224
|
+
return line(`${marker} ${input.text}`, {
|
|
225
|
+
fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
|
|
226
|
+
bold: input.active,
|
|
227
|
+
bg: input.active ? RIG_UI.glass : undefined,
|
|
228
|
+
selectableIndex: input.index,
|
|
229
|
+
activateOnClick: input.activateOnClick
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
function tableHeaderLine(columns) {
|
|
233
|
+
return line(columns.join(COLUMN_GUTTER), { fg: RIG_UI.ink, bold: true, bg: RIG_UI.glass });
|
|
234
|
+
}
|
|
235
|
+
function labeledLine(label, value, fg = RIG_UI.ink2) {
|
|
236
|
+
return line(`${COLUMN_GUTTER}${label.toUpperCase().padEnd(LABEL_WIDTH)}${COLUMN_GUTTER}${value}`, { fg });
|
|
237
|
+
}
|
|
88
238
|
function loadingLine(message = "loading") {
|
|
89
239
|
return line(` \u27F2 ${message}`, { fg: RIG_UI.limeDim });
|
|
90
240
|
}
|
|
@@ -94,6 +244,27 @@ function emptyLine(message = "nothing here yet") {
|
|
|
94
244
|
function errorLine(message) {
|
|
95
245
|
return line(` ! ${message}`, { fg: RIG_UI.magenta, bold: true });
|
|
96
246
|
}
|
|
247
|
+
function loadingRows(label, tick = 0, compact = false) {
|
|
248
|
+
const mascot = compact ? miniDroneLines(tick, "center") : brandFleetLines(tick, "center");
|
|
249
|
+
return [
|
|
250
|
+
blank(),
|
|
251
|
+
...mascot,
|
|
252
|
+
blank(),
|
|
253
|
+
{ ...actionDroneLine(tick, `loading ${label}\u2026`, RIG_UI.cyan), align: "center" }
|
|
254
|
+
];
|
|
255
|
+
}
|
|
256
|
+
function errorBanner(message, hint) {
|
|
257
|
+
return [
|
|
258
|
+
line(`\u2717 failed to load \u2014 ${message}`, { fg: RIG_UI.red, bold: true }),
|
|
259
|
+
...hint ? [line(` ${hint}`, { fg: RIG_UI.ink3 })] : [],
|
|
260
|
+
line(" select refresh/retry below", { fg: RIG_UI.ink4 }),
|
|
261
|
+
line("", { fg: RIG_UI.ink3 })
|
|
262
|
+
];
|
|
263
|
+
}
|
|
264
|
+
function lastRefreshError(state) {
|
|
265
|
+
const value = state.data.lastRefreshError;
|
|
266
|
+
return typeof value === "string" && value.trim() ? value : undefined;
|
|
267
|
+
}
|
|
97
268
|
function fitSceneLine(input, layout) {
|
|
98
269
|
const fitted = truncateText(input.text, layout.centerWidth);
|
|
99
270
|
return {
|
|
@@ -108,13 +279,19 @@ function makeSceneFrame(input) {
|
|
|
108
279
|
return input;
|
|
109
280
|
}
|
|
110
281
|
export {
|
|
282
|
+
tableHeaderLine,
|
|
283
|
+
selectionLine,
|
|
111
284
|
makeSceneFrame,
|
|
285
|
+
loadingRows,
|
|
112
286
|
loadingLine,
|
|
113
287
|
line,
|
|
288
|
+
lastRefreshError,
|
|
289
|
+
labeledLine,
|
|
114
290
|
kv,
|
|
115
291
|
fitSceneLines,
|
|
116
292
|
fitSceneLine,
|
|
117
293
|
errorLine,
|
|
294
|
+
errorBanner,
|
|
118
295
|
emptyLine,
|
|
119
296
|
deckRow,
|
|
120
297
|
center,
|
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { TextRenderable, type CliRenderer, type MouseEvent } from "@opentui/core";
|
|
1
|
+
import { RGBA, TextRenderable, type CliRenderer, type MouseEvent } from "@opentui/core";
|
|
2
2
|
import type { AppSceneLine } from "../types";
|
|
3
|
+
/** The "no background" sentinel: a line with no `bg` paints nothing and lets the
|
|
4
|
+
* opaque panel ground (render/panels.ts) show through. A line WITH a `bg` (e.g.
|
|
5
|
+
* a selected row, set via RIG_UI.glass) paints a raised bar on that ground —
|
|
6
|
+
* this is the one selection-highlight mechanism, plumbed end-to-end here so
|
|
7
|
+
* scenes only set `bg` on the AppSceneLine and never touch RGBA. */
|
|
8
|
+
export declare const TRANSPARENT: RGBA;
|
|
3
9
|
export type TextLineRenderable = TextRenderable & {
|
|
4
10
|
setRigSceneLine?(line: AppSceneLine | undefined): void;
|
|
5
11
|
};
|
|
@@ -14,15 +14,17 @@ var RIG_UI = {
|
|
|
14
14
|
bg: "#070809",
|
|
15
15
|
bg2: "#0b0c0e",
|
|
16
16
|
panel: "#101115",
|
|
17
|
-
panel2: "#
|
|
18
|
-
glass: "#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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"
|
|
@@ -121,5 +123,6 @@ export {
|
|
|
121
123
|
createFlowTextLine,
|
|
122
124
|
clearTextLines,
|
|
123
125
|
applyTextLine,
|
|
124
|
-
applyFlowTextLine
|
|
126
|
+
applyFlowTextLine,
|
|
127
|
+
TRANSPARENT
|
|
125
128
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/cli/src/app-opentui/render/type-bar.ts
|
|
3
|
-
import { BoxRenderable, InputRenderable, InputRenderableEvents, RGBA, TextRenderable } from "@opentui/core";
|
|
3
|
+
import { BoxRenderable, InputRenderable, InputRenderableEvents, RGBA, StyledText, TextRenderable } from "@opentui/core";
|
|
4
4
|
|
|
5
5
|
// packages/cli/src/app-opentui/theme.ts
|
|
6
6
|
import {
|
|
@@ -14,15 +14,17 @@ var RIG_UI = {
|
|
|
14
14
|
bg: "#070809",
|
|
15
15
|
bg2: "#0b0c0e",
|
|
16
16
|
panel: "#101115",
|
|
17
|
-
panel2: "#
|
|
18
|
-
glass: "#
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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"
|
|
@@ -44,13 +46,6 @@ var styles = {
|
|
|
44
46
|
function visibleWidth(text) {
|
|
45
47
|
return [...text].length;
|
|
46
48
|
}
|
|
47
|
-
function truncateText(text, width) {
|
|
48
|
-
if (visibleWidth(text) <= width)
|
|
49
|
-
return text;
|
|
50
|
-
if (width <= 1)
|
|
51
|
-
return "\u2026";
|
|
52
|
-
return `${[...text].slice(0, Math.max(0, width - 1)).join("")}\u2026`;
|
|
53
|
-
}
|
|
54
49
|
|
|
55
50
|
// packages/cli/src/app-opentui/render/type-bar.ts
|
|
56
51
|
var TYPEBAR_BG = RGBA.fromInts(20, 25, 14, 224);
|
|
@@ -99,33 +94,49 @@ function createTypeBar(renderer) {
|
|
|
99
94
|
left: 0,
|
|
100
95
|
top: 1,
|
|
101
96
|
width: "100%",
|
|
102
|
-
fg: RIG_UI.
|
|
97
|
+
fg: RIG_UI.ink3,
|
|
103
98
|
zIndex: 7,
|
|
104
99
|
selectable: true
|
|
105
100
|
});
|
|
106
|
-
input.focus();
|
|
107
101
|
return { background, input, prefix, footer };
|
|
108
102
|
}
|
|
103
|
+
function modePrefix(mode) {
|
|
104
|
+
switch (mode) {
|
|
105
|
+
case "search":
|
|
106
|
+
return { glyph: " /", color: RIG_UI.cyan };
|
|
107
|
+
case "command":
|
|
108
|
+
return { glyph: " /", color: RIG_UI.lime };
|
|
109
|
+
case "prompt":
|
|
110
|
+
return { glyph: " ?", color: RIG_UI.yellow };
|
|
111
|
+
default:
|
|
112
|
+
return { glyph: " \u203A", color: RIG_UI.ink3 };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
109
115
|
function positionTypeBar(renderables, input, footer, width, typeBarTop, footerTop) {
|
|
116
|
+
const mode = input.mode ?? "nav";
|
|
117
|
+
const editing = mode !== "nav";
|
|
118
|
+
const { glyph, color } = modePrefix(mode);
|
|
110
119
|
renderables.background.visible = true;
|
|
111
120
|
const cardTop = Math.max(0, typeBarTop - 1);
|
|
112
121
|
renderables.background.left = 0;
|
|
113
122
|
renderables.background.top = cardTop;
|
|
114
123
|
renderables.background.width = width;
|
|
115
124
|
renderables.background.height = Math.max(3, footerTop - cardTop + 1);
|
|
116
|
-
renderables.prefix.content =
|
|
125
|
+
renderables.prefix.content = glyph;
|
|
126
|
+
renderables.prefix.fg = color;
|
|
117
127
|
renderables.prefix.left = 2;
|
|
118
128
|
renderables.prefix.top = typeBarTop;
|
|
119
129
|
renderables.input.top = typeBarTop;
|
|
120
130
|
renderables.input.left = 5;
|
|
121
131
|
renderables.input.width = Math.max(10, width - 8);
|
|
122
|
-
renderables.input.
|
|
123
|
-
renderables.input.
|
|
132
|
+
renderables.input.value = editing ? input.value : "";
|
|
133
|
+
renderables.input.placeholder = editing ? mode === "prompt" ? input.prompt?.label ?? "type a value" : mode === "command" ? "rig \u2026" : "filter\u2026" : input.placeholder;
|
|
134
|
+
renderables.input.showCursor = editing;
|
|
135
|
+
if (renderables.input.focused)
|
|
136
|
+
renderables.input.blur();
|
|
124
137
|
renderables.footer.top = footerTop;
|
|
125
138
|
renderables.footer.width = "100%";
|
|
126
139
|
renderables.footer.content = formatFooter(footer, width);
|
|
127
|
-
if (!renderables.input.focused)
|
|
128
|
-
renderables.input.focus();
|
|
129
140
|
}
|
|
130
141
|
function hideTypeBar(renderables, height) {
|
|
131
142
|
renderables.background.visible = false;
|
|
@@ -153,16 +164,44 @@ function safeFooterMessage(message) {
|
|
|
153
164
|
return null;
|
|
154
165
|
return trimmed;
|
|
155
166
|
}
|
|
156
|
-
function
|
|
167
|
+
function liveCell(live) {
|
|
168
|
+
const connected = live.trimStart().startsWith("\u25CF");
|
|
169
|
+
return { text: live, style: connected ? styles.cyan : styles.ink3 };
|
|
170
|
+
}
|
|
171
|
+
function footerCells(footer) {
|
|
157
172
|
const safeMessage = safeFooterMessage(footer.message);
|
|
158
|
-
const
|
|
159
|
-
footer.
|
|
160
|
-
footer.
|
|
161
|
-
footer.
|
|
162
|
-
footer.
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
const cells = [
|
|
174
|
+
footer.section ? { text: `\u25B8 ${footer.section}`, style: (s) => otuiBold(styles.ink2(s)) } : null,
|
|
175
|
+
footer.live ? liveCell(footer.live) : null,
|
|
176
|
+
footer.project ? { text: "workspace", style: styles.ink3 } : null,
|
|
177
|
+
footer.server ? { text: "server selected", style: styles.ink3 } : null,
|
|
178
|
+
footer.auth ? { text: "auth ready", style: styles.ink3 } : null,
|
|
179
|
+
footer.run ? { text: `run ${footer.run}`, style: styles.ink3 } : null,
|
|
180
|
+
safeMessage ? { text: safeMessage, style: styles.ink2 } : null,
|
|
181
|
+
footer.updated ? { text: footer.updated, style: styles.ink3 } : null
|
|
182
|
+
];
|
|
183
|
+
return cells.filter((cell) => cell !== null);
|
|
184
|
+
}
|
|
185
|
+
var FOOTER_SEPARATOR = " \xB7 ";
|
|
186
|
+
function formatFooter(footer, width) {
|
|
187
|
+
const budget = Math.max(8, width - 2);
|
|
188
|
+
const chunks = [styles.ink3(" ")];
|
|
189
|
+
let used = 1;
|
|
190
|
+
footerCells(footer).forEach((cell, index) => {
|
|
191
|
+
const sep = index === 0 ? "" : FOOTER_SEPARATOR;
|
|
192
|
+
const remaining = budget - used - visibleWidth(sep);
|
|
193
|
+
if (remaining <= 0)
|
|
194
|
+
return;
|
|
195
|
+
if (sep) {
|
|
196
|
+
chunks.push(styles.ink4(sep));
|
|
197
|
+
used += visibleWidth(sep);
|
|
198
|
+
}
|
|
199
|
+
const fits = visibleWidth(cell.text) <= remaining;
|
|
200
|
+
const text = fits ? cell.text : remaining <= 1 ? "\u2026" : `${[...cell.text].slice(0, Math.max(0, remaining - 1)).join("")}\u2026`;
|
|
201
|
+
chunks.push(cell.style(text));
|
|
202
|
+
used += visibleWidth(text);
|
|
203
|
+
});
|
|
204
|
+
return new StyledText(chunks);
|
|
166
205
|
}
|
|
167
206
|
export {
|
|
168
207
|
positionTypeBar,
|
|
@@ -1,2 +1,45 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { StyledText, type CliRenderer } from "@opentui/core";
|
|
2
|
+
import { createAppStore } from "./state";
|
|
3
|
+
import type { AppIntent, AppLaunchOptions, AppRuntime, AppSceneId, AppSelectableItem, AppState } from "./types";
|
|
4
|
+
import { type NativeHost } from "./render/native-host";
|
|
5
|
+
/** Total per-scene entry intent for back-navigation (#13). Every AppSceneId
|
|
6
|
+
* resolves to an intent that re-enters THAT scene with its real data refresh —
|
|
7
|
+
* so popping the back-stack restores the exact prior scene, never dumping home
|
|
8
|
+
* from an unrelated origin. Transient PTY scenes (command/handoff) can't be
|
|
9
|
+
* "restored" from a closed terminal, so they re-enter their owning section. */
|
|
10
|
+
export declare function entryIntentForScene(scene: AppSceneId): AppIntent;
|
|
11
|
+
/** Readable section name for the persistent footer breadcrumb. */
|
|
12
|
+
export declare function sceneSectionLabel(scene: AppSceneId): string;
|
|
13
|
+
/** Footer freshness indicator (#6): push-connected vs polling fallback, so the
|
|
14
|
+
* UI never silently lies about whether it is live. */
|
|
15
|
+
export declare function liveLinkLabel(status: "connecting" | "connected" | "disconnected"): string;
|
|
16
|
+
/** Build the persistent top-nav strip as styled text: every section label with
|
|
17
|
+
* the ACTIVE one highlighted (lime + bold), Inbox carrying a live pending-count
|
|
18
|
+
* badge. Rendered on every scene so the operator always sees the sections and
|
|
19
|
+
* where they are (#2). Returns a StyledText for a single absolute TextRenderable. */
|
|
20
|
+
export declare function buildNavStrip(state: AppState): StyledText;
|
|
21
|
+
/** Test-only: the id of the nav section that should light up for a scene (#2). */
|
|
22
|
+
export declare function __activeNavSectionIdForTest(scene: AppSceneId): string;
|
|
23
|
+
/** Test-only: the intent esc/back resolves to given a back-stack — proving back
|
|
24
|
+
* restores the ACTUAL prior scene, never dumping home from an unrelated origin
|
|
25
|
+
* (#13). Mirrors runtime.goBack's resolution (pop → entryIntentForScene). */
|
|
26
|
+
export declare function __backTargetIntentForTest(history: readonly AppSceneId[]): AppIntent;
|
|
27
|
+
/** Test-only: whether a scene resolves to a REAL renderer (false ⇒ it would hit
|
|
28
|
+
* the redirect stub). Asserts the stub is unreachable for every real scene (#3). */
|
|
29
|
+
export declare function __sceneHasRendererForTest(scene: AppSceneId, sceneRenderers?: AppLaunchOptions["sceneRenderers"]): boolean;
|
|
30
|
+
export declare function selectIndex(store: ReturnType<typeof createAppStore>, index: number, renderedItems?: readonly AppSelectableItem[]): boolean;
|
|
31
|
+
export declare function moveSelection(store: ReturnType<typeof createAppStore>, delta: number, renderedItems?: readonly AppSelectableItem[]): boolean;
|
|
32
|
+
/** Select the item with this stable id (#12). Clicks resolve by id so a render
|
|
33
|
+
* between mouse-down and the click callback can't misfire on a shifted row. */
|
|
34
|
+
export declare function selectById(store: ReturnType<typeof createAppStore>, id: string, renderedItems?: readonly AppSelectableItem[]): boolean;
|
|
35
|
+
export declare function activateSelection(runtime: AppRuntime, renderedItems?: readonly AppSelectableItem[]): Promise<boolean>;
|
|
36
|
+
/** Test-only: render a single scene's state to a renderer headlessly so the
|
|
37
|
+
* FULL scene render path (scene renderer → panels + lines + native mounts) can
|
|
38
|
+
* be snapshot-verified via @opentui/core's createTestRenderer + captureCharFrame,
|
|
39
|
+
* without launching the live app. Mirrors the renderable pool the live app
|
|
40
|
+
* builds, then calls the real `renderNow`. Returns the derived selectable list. */
|
|
41
|
+
export declare function __renderSceneForTest(renderer: CliRenderer, state: AppState, sceneRenderers?: AppLaunchOptions["sceneRenderers"]): {
|
|
42
|
+
readonly selectables: readonly AppSelectableItem[];
|
|
43
|
+
readonly nativeHost: NativeHost | null;
|
|
44
|
+
};
|
|
2
45
|
export declare function launchRigOpenTuiApp(options: AppLaunchOptions): Promise<void>;
|