@h-rig/cli 0.0.6-alpha.80 → 0.0.6-alpha.81
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 +17034 -11249
- package/dist/src/app/board.js +32 -3
- package/dist/src/app/drone-ui.js +1 -1
- package/dist/src/app/theme.js +1 -0
- package/dist/src/app-opentui/adapters/common.d.ts +53 -0
- package/dist/src/app-opentui/adapters/common.js +149 -0
- package/dist/src/app-opentui/adapters/doctor.d.ts +11 -0
- package/dist/src/app-opentui/adapters/doctor.js +780 -0
- package/dist/src/app-opentui/adapters/fleet.d.ts +16 -0
- package/dist/src/app-opentui/adapters/fleet.js +874 -0
- package/dist/src/app-opentui/adapters/inbox.d.ts +33 -0
- package/dist/src/app-opentui/adapters/inbox.js +1454 -0
- package/dist/src/app-opentui/adapters/init.d.ts +13 -0
- package/dist/src/app-opentui/adapters/init.js +2357 -0
- package/dist/src/app-opentui/adapters/pi-attach.d.ts +16 -0
- package/dist/src/app-opentui/adapters/pi-attach.js +1295 -0
- package/dist/src/app-opentui/adapters/run-detail.d.ts +20 -0
- package/dist/src/app-opentui/adapters/run-detail.js +893 -0
- package/dist/src/app-opentui/adapters/server.d.ts +14 -0
- package/dist/src/app-opentui/adapters/server.js +798 -0
- package/dist/src/app-opentui/adapters/tasks.d.ts +55 -0
- package/dist/src/app-opentui/adapters/tasks.js +3472 -0
- package/dist/src/app-opentui/bootstrap.d.ts +16 -0
- package/dist/src/app-opentui/bootstrap.js +19509 -0
- package/dist/src/app-opentui/drone.d.ts +12 -0
- package/dist/src/app-opentui/drone.js +227 -0
- package/dist/src/app-opentui/events.d.ts +7 -0
- package/dist/src/app-opentui/events.js +28 -0
- package/dist/src/app-opentui/index.d.ts +8 -0
- package/dist/src/app-opentui/index.js +3477 -0
- package/dist/src/app-opentui/intent.d.ts +3 -0
- package/dist/src/app-opentui/intent.js +211 -0
- package/dist/src/app-opentui/layout.d.ts +15 -0
- package/dist/src/app-opentui/layout.js +44 -0
- package/dist/src/app-opentui/list-search.d.ts +8 -0
- package/dist/src/app-opentui/list-search.js +43 -0
- package/dist/src/app-opentui/pi-host-child.d.ts +2 -0
- package/dist/src/app-opentui/pi-host-child.js +778 -0
- package/dist/src/app-opentui/pi-pty-host.d.ts +64 -0
- package/dist/src/app-opentui/pi-pty-host.js +384 -0
- package/dist/src/app-opentui/registry.d.ts +4 -0
- package/dist/src/app-opentui/registry.js +6835 -0
- package/dist/src/app-opentui/render/graphics.d.ts +39 -0
- package/dist/src/app-opentui/render/graphics.js +537 -0
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +2 -0
- package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +1480 -0
- package/dist/src/app-opentui/render/image-visual-layer-worker.d.ts +1 -0
- package/dist/src/app-opentui/render/image-visual-layer-worker.js +1541 -0
- package/dist/src/app-opentui/render/image-visual-layer.d.ts +93 -0
- package/dist/src/app-opentui/render/image-visual-layer.js +945 -0
- package/dist/src/app-opentui/render/panels.d.ts +10 -0
- package/dist/src/app-opentui/render/panels.js +201 -0
- package/dist/src/app-opentui/render/scene.d.ts +16 -0
- package/dist/src/app-opentui/render/scene.js +110 -0
- package/dist/src/app-opentui/render/text.d.ts +10 -0
- package/dist/src/app-opentui/render/text.js +121 -0
- package/dist/src/app-opentui/render/type-bar.d.ts +14 -0
- package/dist/src/app-opentui/render/type-bar.js +137 -0
- package/dist/src/app-opentui/runtime.d.ts +2 -0
- package/dist/src/app-opentui/runtime.js +3406 -0
- package/dist/src/app-opentui/scenes/doctor.d.ts +2 -0
- package/dist/src/app-opentui/scenes/doctor.js +91 -0
- package/dist/src/app-opentui/scenes/error.d.ts +2 -0
- package/dist/src/app-opentui/scenes/error.js +190 -0
- package/dist/src/app-opentui/scenes/fleet.d.ts +3 -0
- package/dist/src/app-opentui/scenes/fleet.js +207 -0
- package/dist/src/app-opentui/scenes/handoff.d.ts +2 -0
- package/dist/src/app-opentui/scenes/handoff.js +147 -0
- package/dist/src/app-opentui/scenes/help.d.ts +3 -0
- package/dist/src/app-opentui/scenes/help.js +138 -0
- package/dist/src/app-opentui/scenes/inbox.d.ts +2 -0
- package/dist/src/app-opentui/scenes/inbox.js +118 -0
- package/dist/src/app-opentui/scenes/init.d.ts +2 -0
- package/dist/src/app-opentui/scenes/init.js +94 -0
- package/dist/src/app-opentui/scenes/main.d.ts +2 -0
- package/dist/src/app-opentui/scenes/main.js +96 -0
- package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -0
- package/dist/src/app-opentui/scenes/run-detail.js +139 -0
- package/dist/src/app-opentui/scenes/server.d.ts +2 -0
- package/dist/src/app-opentui/scenes/server.js +88 -0
- package/dist/src/app-opentui/scenes/tasks.d.ts +3 -0
- package/dist/src/app-opentui/scenes/tasks.js +230 -0
- package/dist/src/app-opentui/state.d.ts +4 -0
- package/dist/src/app-opentui/state.js +286 -0
- package/dist/src/app-opentui/theme.d.ts +36 -0
- package/dist/src/app-opentui/theme.js +88 -0
- package/dist/src/app-opentui/types.d.ts +188 -0
- package/dist/src/app-opentui/types.js +1 -0
- package/dist/src/commands/_async-ui.js +1 -1
- package/dist/src/commands/_operator-view.js +1 -1
- package/dist/src/commands/_pi-frontend.js +1 -1
- package/dist/src/commands/_spinner.js +1 -1
- package/dist/src/commands/browser.js +1 -1
- package/dist/src/commands/doctor.js +1 -1
- package/dist/src/commands/github.js +1 -1
- package/dist/src/commands/inbox.js +1 -1
- package/dist/src/commands/init.js +1 -1
- package/dist/src/commands/inspect.js +1 -1
- package/dist/src/commands/run.js +1 -1
- package/dist/src/commands/setup.js +1 -1
- package/dist/src/commands/stats.js +1 -1
- package/dist/src/commands/task.js +1 -1
- package/dist/src/commands.js +33 -4
- package/dist/src/index.js +33 -4
- package/package.json +11 -8
|
@@ -0,0 +1,138 @@
|
|
|
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: "#101115",
|
|
15
|
+
glass: "#14161b",
|
|
16
|
+
ink: "#f2f3f6",
|
|
17
|
+
ink2: "#aeb0ba",
|
|
18
|
+
ink3: "#6c6e79",
|
|
19
|
+
ink4: "#44464f",
|
|
20
|
+
lime: "#ccff4d",
|
|
21
|
+
limeDim: "#a9d63f",
|
|
22
|
+
cyan: "#56d8ff",
|
|
23
|
+
red: "#ff5d5d",
|
|
24
|
+
yellow: "#ffd24d",
|
|
25
|
+
magenta: "#ff79b0"
|
|
26
|
+
};
|
|
27
|
+
var styles = {
|
|
28
|
+
ink: otuiFg(RIG_UI.ink),
|
|
29
|
+
ink2: otuiFg(RIG_UI.ink2),
|
|
30
|
+
ink3: otuiFg(RIG_UI.ink3),
|
|
31
|
+
ink4: otuiFg(RIG_UI.ink4),
|
|
32
|
+
lime: otuiFg(RIG_UI.lime),
|
|
33
|
+
limeDim: otuiFg(RIG_UI.limeDim),
|
|
34
|
+
cyan: otuiFg(RIG_UI.cyan),
|
|
35
|
+
red: otuiFg(RIG_UI.red),
|
|
36
|
+
yellow: otuiFg(RIG_UI.yellow),
|
|
37
|
+
magenta: otuiFg(RIG_UI.magenta)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// packages/cli/src/app-opentui/render/scene.ts
|
|
41
|
+
function line(text, options = {}) {
|
|
42
|
+
return { text, ...options };
|
|
43
|
+
}
|
|
44
|
+
function makeSceneFrame(input) {
|
|
45
|
+
return input;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// packages/cli/src/app-opentui/scenes/help.ts
|
|
49
|
+
var COMMANDS = [
|
|
50
|
+
["runs", "show runs"],
|
|
51
|
+
["tasks", "show task source"],
|
|
52
|
+
["type in Runs", "search loaded runs"],
|
|
53
|
+
["type in Tasks", "search loaded tasks"],
|
|
54
|
+
["tasks open", "filter to open tasks"],
|
|
55
|
+
["tasks all", "show every task returned by the source"],
|
|
56
|
+
["tasks mine", "show tasks assigned to @me"],
|
|
57
|
+
["tasks blocked", "show blocked work"],
|
|
58
|
+
["tasks closed", "show closed work"],
|
|
59
|
+
["tasks sort priority", "rank by priority"],
|
|
60
|
+
["tasks sort recency", "rank by update time"],
|
|
61
|
+
["tasks sort status", "group by status"],
|
|
62
|
+
["run <task-id>", "dispatch selected task id"],
|
|
63
|
+
["run next", "dispatch next runnable task"],
|
|
64
|
+
["attach <run>", "open bundled Pi for a run"],
|
|
65
|
+
["tab / \u2192", "next screen"],
|
|
66
|
+
["\u2190", "previous screen"],
|
|
67
|
+
["\u2191 \u2193", "move selection in Runs/Tasks"],
|
|
68
|
+
["j k", "move selection outside search-first list screens"],
|
|
69
|
+
["enter", "activate selected row"],
|
|
70
|
+
["mouse wheel", "scroll panel under cursor"],
|
|
71
|
+
["ctrl-]", "detach from embedded Pi"],
|
|
72
|
+
["ctrl-c / q", "exit"]
|
|
73
|
+
];
|
|
74
|
+
function panelWidth(layout) {
|
|
75
|
+
return layout?.centerWidth ?? 100;
|
|
76
|
+
}
|
|
77
|
+
function panelHeight(layout, top = 3) {
|
|
78
|
+
return Math.max(4, (layout?.centerHeight ?? 24) - top);
|
|
79
|
+
}
|
|
80
|
+
function clip(value, width) {
|
|
81
|
+
if (width <= 0)
|
|
82
|
+
return "";
|
|
83
|
+
return value.length <= width ? value : `${value.slice(0, Math.max(0, width - 1))}\u2026`;
|
|
84
|
+
}
|
|
85
|
+
function commandRow(width, label, detail, index) {
|
|
86
|
+
const keyWidth = Math.min(22, Math.max(12, Math.floor(width * 0.28)));
|
|
87
|
+
const key = clip(label, keyWidth).padEnd(keyWidth);
|
|
88
|
+
return line(`${key} ${clip(detail, Math.max(8, width - keyWidth - 4))}`, { fg: index < 3 ? RIG_UI.ink : RIG_UI.ink2 });
|
|
89
|
+
}
|
|
90
|
+
function unsupportedCommand(state) {
|
|
91
|
+
const value = state.intent.action.payload?.unsupported ?? state.intent.action.payload?.unknown;
|
|
92
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
93
|
+
}
|
|
94
|
+
function renderHelpScene(state, layout) {
|
|
95
|
+
const width = panelWidth(layout);
|
|
96
|
+
const unsupported = unsupportedCommand(state);
|
|
97
|
+
const panelTop = 0;
|
|
98
|
+
const panelLines = [
|
|
99
|
+
...unsupported ? [
|
|
100
|
+
line(`${unsupported} uses the plain CLI path.`, { fg: RIG_UI.yellow, bold: true }),
|
|
101
|
+
line("Exit and rerun with RIG_PLAIN=1 if you want legacy text output.", { fg: RIG_UI.ink3 }),
|
|
102
|
+
line("", { fg: RIG_UI.ink3 })
|
|
103
|
+
] : [],
|
|
104
|
+
line("COMMAND ACTION", { fg: RIG_UI.ink3, bold: true }),
|
|
105
|
+
line("", { fg: RIG_UI.ink3 }),
|
|
106
|
+
...COMMANDS.map(([label, detail], index) => commandRow(width - 6, label, detail, index))
|
|
107
|
+
];
|
|
108
|
+
return makeSceneFrame({
|
|
109
|
+
scene: "help",
|
|
110
|
+
title: "Rig help",
|
|
111
|
+
lines: [
|
|
112
|
+
line("", { fg: RIG_UI.ink4 }),
|
|
113
|
+
line(" rig help", { fg: RIG_UI.ink3 })
|
|
114
|
+
],
|
|
115
|
+
panels: [{
|
|
116
|
+
id: "help-reference",
|
|
117
|
+
top: panelTop,
|
|
118
|
+
width,
|
|
119
|
+
height: panelHeight(layout, panelTop),
|
|
120
|
+
lines: panelLines,
|
|
121
|
+
backgroundColor: RIG_UI.panel,
|
|
122
|
+
backgroundAlpha: 184,
|
|
123
|
+
opacity: 1,
|
|
124
|
+
border: false,
|
|
125
|
+
chrome: "ad-terminal",
|
|
126
|
+
headerText: "rig help",
|
|
127
|
+
headerHeight: 3,
|
|
128
|
+
paddingX: layout?.compact ? 2 : 3,
|
|
129
|
+
paddingY: 1
|
|
130
|
+
}],
|
|
131
|
+
typeBarPlaceholder: "runs \xB7 tasks \xB7 help \xB7 attach <run>",
|
|
132
|
+
footer: { message: "help" },
|
|
133
|
+
live: true
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
export {
|
|
137
|
+
renderHelpScene
|
|
138
|
+
};
|
|
@@ -0,0 +1,118 @@
|
|
|
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: "#101115",
|
|
15
|
+
glass: "#14161b",
|
|
16
|
+
ink: "#f2f3f6",
|
|
17
|
+
ink2: "#aeb0ba",
|
|
18
|
+
ink3: "#6c6e79",
|
|
19
|
+
ink4: "#44464f",
|
|
20
|
+
lime: "#ccff4d",
|
|
21
|
+
limeDim: "#a9d63f",
|
|
22
|
+
cyan: "#56d8ff",
|
|
23
|
+
red: "#ff5d5d",
|
|
24
|
+
yellow: "#ffd24d",
|
|
25
|
+
magenta: "#ff79b0"
|
|
26
|
+
};
|
|
27
|
+
var styles = {
|
|
28
|
+
ink: otuiFg(RIG_UI.ink),
|
|
29
|
+
ink2: otuiFg(RIG_UI.ink2),
|
|
30
|
+
ink3: otuiFg(RIG_UI.ink3),
|
|
31
|
+
ink4: otuiFg(RIG_UI.ink4),
|
|
32
|
+
lime: otuiFg(RIG_UI.lime),
|
|
33
|
+
limeDim: otuiFg(RIG_UI.limeDim),
|
|
34
|
+
cyan: otuiFg(RIG_UI.cyan),
|
|
35
|
+
red: otuiFg(RIG_UI.red),
|
|
36
|
+
yellow: otuiFg(RIG_UI.yellow),
|
|
37
|
+
magenta: otuiFg(RIG_UI.magenta)
|
|
38
|
+
};
|
|
39
|
+
function statusColor(status) {
|
|
40
|
+
switch (status) {
|
|
41
|
+
case "running":
|
|
42
|
+
case "success":
|
|
43
|
+
case "completed":
|
|
44
|
+
case "merged":
|
|
45
|
+
return RIG_UI.lime;
|
|
46
|
+
case "preparing":
|
|
47
|
+
case "created":
|
|
48
|
+
case "validating":
|
|
49
|
+
case "reviewing":
|
|
50
|
+
case "closing-out":
|
|
51
|
+
case "stopping":
|
|
52
|
+
case "loading":
|
|
53
|
+
case "action":
|
|
54
|
+
return RIG_UI.cyan;
|
|
55
|
+
case "needs-attention":
|
|
56
|
+
case "needs_attention":
|
|
57
|
+
return RIG_UI.yellow;
|
|
58
|
+
case "failed":
|
|
59
|
+
case "error":
|
|
60
|
+
return RIG_UI.red;
|
|
61
|
+
default:
|
|
62
|
+
return RIG_UI.ink3;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// packages/cli/src/app-opentui/render/scene.ts
|
|
67
|
+
function line(text, options = {}) {
|
|
68
|
+
return { text, ...options };
|
|
69
|
+
}
|
|
70
|
+
function blank() {
|
|
71
|
+
return { text: "" };
|
|
72
|
+
}
|
|
73
|
+
function center(text, fg = RIG_UI.ink2, bold = false) {
|
|
74
|
+
return { text, fg, bold, align: "center" };
|
|
75
|
+
}
|
|
76
|
+
function makeSceneFrame(input) {
|
|
77
|
+
return input;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// packages/cli/src/app-opentui/scenes/inbox.ts
|
|
81
|
+
function inboxRecords(state) {
|
|
82
|
+
const inbox = state.data.inbox;
|
|
83
|
+
if (!inbox || typeof inbox !== "object" || Array.isArray(inbox))
|
|
84
|
+
return { approvals: [], inputs: [] };
|
|
85
|
+
const record = inbox;
|
|
86
|
+
return {
|
|
87
|
+
approvals: Array.isArray(record.approvals) ? record.approvals : [],
|
|
88
|
+
inputs: Array.isArray(record.inputs) ? record.inputs : []
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function row(record) {
|
|
92
|
+
const prefix = record.kind === "approvals" ? "approve" : "answer";
|
|
93
|
+
return `\u25B8 ${prefix.padEnd(7)} ${record.requestId.slice(0, 10).padEnd(10)} run ${record.runId.slice(0, 8)} ${record.title}`;
|
|
94
|
+
}
|
|
95
|
+
function renderInboxScene(state) {
|
|
96
|
+
const inbox = inboxRecords(state);
|
|
97
|
+
const all = [...inbox.approvals, ...inbox.inputs];
|
|
98
|
+
const optimistic = state.data.inboxOptimistic;
|
|
99
|
+
const optimisticLine = optimistic && typeof optimistic === "object" && !Array.isArray(optimistic) ? `${optimistic.requestId ?? "request"} ${optimistic.status ?? "pending"}` : "idle";
|
|
100
|
+
return makeSceneFrame({
|
|
101
|
+
scene: "inbox",
|
|
102
|
+
title: "Inbox",
|
|
103
|
+
lines: [
|
|
104
|
+
center("inbox", RIG_UI.ink, true),
|
|
105
|
+
center(`${inbox.approvals.length} approvals \xB7 ${inbox.inputs.length} inputs`, RIG_UI.ink3),
|
|
106
|
+
blank(),
|
|
107
|
+
...all.length > 0 ? all.slice(0, 14).map((record, index) => line(row(record), { fg: statusColor(record.status), align: "center", selectableIndex: index })) : [line("no pending approvals or answers", { fg: RIG_UI.ink3, align: "center" })],
|
|
108
|
+
blank(),
|
|
109
|
+
line(`status ${optimisticLine}`, { fg: RIG_UI.ink4, align: "center" })
|
|
110
|
+
],
|
|
111
|
+
footer: { message: `${all.length} pending` },
|
|
112
|
+
typeBarPlaceholder: "approve <request> \xB7 reject <request> \xB7 answer <request>",
|
|
113
|
+
live: state.status === "action" || all.length === 0
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
export {
|
|
117
|
+
renderInboxScene
|
|
118
|
+
};
|
|
@@ -0,0 +1,94 @@
|
|
|
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: "#101115",
|
|
15
|
+
glass: "#14161b",
|
|
16
|
+
ink: "#f2f3f6",
|
|
17
|
+
ink2: "#aeb0ba",
|
|
18
|
+
ink3: "#6c6e79",
|
|
19
|
+
ink4: "#44464f",
|
|
20
|
+
lime: "#ccff4d",
|
|
21
|
+
limeDim: "#a9d63f",
|
|
22
|
+
cyan: "#56d8ff",
|
|
23
|
+
red: "#ff5d5d",
|
|
24
|
+
yellow: "#ffd24d",
|
|
25
|
+
magenta: "#ff79b0"
|
|
26
|
+
};
|
|
27
|
+
var styles = {
|
|
28
|
+
ink: otuiFg(RIG_UI.ink),
|
|
29
|
+
ink2: otuiFg(RIG_UI.ink2),
|
|
30
|
+
ink3: otuiFg(RIG_UI.ink3),
|
|
31
|
+
ink4: otuiFg(RIG_UI.ink4),
|
|
32
|
+
lime: otuiFg(RIG_UI.lime),
|
|
33
|
+
limeDim: otuiFg(RIG_UI.limeDim),
|
|
34
|
+
cyan: otuiFg(RIG_UI.cyan),
|
|
35
|
+
red: otuiFg(RIG_UI.red),
|
|
36
|
+
yellow: otuiFg(RIG_UI.yellow),
|
|
37
|
+
magenta: otuiFg(RIG_UI.magenta)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// packages/cli/src/app-opentui/render/scene.ts
|
|
41
|
+
function line(text, options = {}) {
|
|
42
|
+
return { text, ...options };
|
|
43
|
+
}
|
|
44
|
+
function blank() {
|
|
45
|
+
return { text: "" };
|
|
46
|
+
}
|
|
47
|
+
function center(text, fg = RIG_UI.ink2, bold = false) {
|
|
48
|
+
return { text, fg, bold, align: "center" };
|
|
49
|
+
}
|
|
50
|
+
function makeSceneFrame(input) {
|
|
51
|
+
return input;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// packages/cli/src/app-opentui/scenes/init.ts
|
|
55
|
+
function initData(state) {
|
|
56
|
+
const init = state.data.init;
|
|
57
|
+
return init && typeof init === "object" && !Array.isArray(init) ? init : {};
|
|
58
|
+
}
|
|
59
|
+
function facts(state) {
|
|
60
|
+
const value = initData(state).facts;
|
|
61
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
62
|
+
}
|
|
63
|
+
function renderInitScene(state) {
|
|
64
|
+
const factState = facts(state);
|
|
65
|
+
const init = initData(state);
|
|
66
|
+
const status = typeof init.status === "string" ? init.status : factState?.hasConfig ? "configured" : "needs-init";
|
|
67
|
+
const configured = factState?.hasConfig === true;
|
|
68
|
+
return makeSceneFrame({
|
|
69
|
+
scene: "init",
|
|
70
|
+
title: "Init",
|
|
71
|
+
lines: [
|
|
72
|
+
center(configured ? "project configured" : "project init", RIG_UI.ink, true),
|
|
73
|
+
center(configured ? "configuration detected" : "create config, server link, auth, and task source", RIG_UI.ink3),
|
|
74
|
+
blank(),
|
|
75
|
+
...configured ? [
|
|
76
|
+
line(`config ${factState.configPath ?? "present"}`, { fg: RIG_UI.ink2, align: "center" }),
|
|
77
|
+
line(`git ${factState.hasGit ? "present" : "missing"}`, { fg: RIG_UI.ink3, align: "center" }),
|
|
78
|
+
blank(),
|
|
79
|
+
line("ready", { fg: RIG_UI.ink4, align: "center" })
|
|
80
|
+
] : [
|
|
81
|
+
line(`git ${factState?.hasGit ? "present" : "missing"}`, { fg: RIG_UI.ink3, align: "center" }),
|
|
82
|
+
line(`status ${status}`, { fg: RIG_UI.limeDim, align: "center" }),
|
|
83
|
+
blank(),
|
|
84
|
+
line("type init --yes", { fg: RIG_UI.ink4, align: "center" })
|
|
85
|
+
]
|
|
86
|
+
],
|
|
87
|
+
footer: { message: configured ? "configured" : "not configured" },
|
|
88
|
+
typeBarPlaceholder: configured ? "doctor \xB7 tasks \xB7 server" : "init --yes \xB7 init --server remote \xB7 help",
|
|
89
|
+
live: !configured || state.status === "action"
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
export {
|
|
93
|
+
renderInitScene
|
|
94
|
+
};
|
|
@@ -0,0 +1,96 @@
|
|
|
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: "#101115",
|
|
15
|
+
glass: "#14161b",
|
|
16
|
+
ink: "#f2f3f6",
|
|
17
|
+
ink2: "#aeb0ba",
|
|
18
|
+
ink3: "#6c6e79",
|
|
19
|
+
ink4: "#44464f",
|
|
20
|
+
lime: "#ccff4d",
|
|
21
|
+
limeDim: "#a9d63f",
|
|
22
|
+
cyan: "#56d8ff",
|
|
23
|
+
red: "#ff5d5d",
|
|
24
|
+
yellow: "#ffd24d",
|
|
25
|
+
magenta: "#ff79b0"
|
|
26
|
+
};
|
|
27
|
+
var styles = {
|
|
28
|
+
ink: otuiFg(RIG_UI.ink),
|
|
29
|
+
ink2: otuiFg(RIG_UI.ink2),
|
|
30
|
+
ink3: otuiFg(RIG_UI.ink3),
|
|
31
|
+
ink4: otuiFg(RIG_UI.ink4),
|
|
32
|
+
lime: otuiFg(RIG_UI.lime),
|
|
33
|
+
limeDim: otuiFg(RIG_UI.limeDim),
|
|
34
|
+
cyan: otuiFg(RIG_UI.cyan),
|
|
35
|
+
red: otuiFg(RIG_UI.red),
|
|
36
|
+
yellow: otuiFg(RIG_UI.yellow),
|
|
37
|
+
magenta: otuiFg(RIG_UI.magenta)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// packages/cli/src/app-opentui/render/scene.ts
|
|
41
|
+
function line(text, options = {}) {
|
|
42
|
+
return { text, ...options };
|
|
43
|
+
}
|
|
44
|
+
function blank() {
|
|
45
|
+
return { text: "" };
|
|
46
|
+
}
|
|
47
|
+
function center(text, fg = RIG_UI.ink2, bold = false) {
|
|
48
|
+
return { text, fg, bold, align: "center" };
|
|
49
|
+
}
|
|
50
|
+
function deckRow(input) {
|
|
51
|
+
const prefix = input.active ? "\u25B8" : " ";
|
|
52
|
+
const label = input.label.toUpperCase().padEnd(10);
|
|
53
|
+
return line(`${prefix} ${label} ${input.detail}`, {
|
|
54
|
+
fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
|
|
55
|
+
bold: input.active,
|
|
56
|
+
selectableIndex: input.index,
|
|
57
|
+
activateOnClick: input.activateOnClick
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function makeSceneFrame(input) {
|
|
61
|
+
return input;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// packages/cli/src/app-opentui/scenes/main.ts
|
|
65
|
+
var CONFIGURED_OPTIONS = [
|
|
66
|
+
["runs", "run list and attach"],
|
|
67
|
+
["tasks", "task source and dispatch"],
|
|
68
|
+
["help", "command reference"]
|
|
69
|
+
];
|
|
70
|
+
function renderMainScene(state) {
|
|
71
|
+
const configured = state.data.projectConfigured === true;
|
|
72
|
+
const selected = configured ? Math.max(0, Math.min(CONFIGURED_OPTIONS.length - 1, state.selection.index)) : Math.max(0, Math.min(1, state.selection.index));
|
|
73
|
+
const lines = [
|
|
74
|
+
center(configured ? "rig" : "rig setup", RIG_UI.ink, true),
|
|
75
|
+
center(configured ? "runs \xB7 tasks \xB7 help" : "initialize this repo", RIG_UI.ink3),
|
|
76
|
+
blank()
|
|
77
|
+
];
|
|
78
|
+
if (!configured) {
|
|
79
|
+
lines.push(deckRow({ label: "init", detail: "create config and server link", index: 0, active: selected === 0 }), deckRow({ label: "help", detail: "show command reference", index: 1, active: selected === 1 }), blank(), line("enter opens selection", { fg: RIG_UI.ink4, align: "center" }));
|
|
80
|
+
} else {
|
|
81
|
+
CONFIGURED_OPTIONS.forEach(([label, detail], index) => {
|
|
82
|
+
lines.push(deckRow({ label, detail, index, active: index === selected }));
|
|
83
|
+
});
|
|
84
|
+
lines.push(blank(), line(` ${state.actionLabel ?? "ready"}`, { fg: state.status === "action" ? RIG_UI.cyan : RIG_UI.ink4 }));
|
|
85
|
+
}
|
|
86
|
+
return makeSceneFrame({
|
|
87
|
+
scene: "main",
|
|
88
|
+
title: "Rig",
|
|
89
|
+
lines,
|
|
90
|
+
typeBarPlaceholder: configured ? "runs \xB7 tasks \xB7 help" : "init \xB7 help",
|
|
91
|
+
live: true
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export {
|
|
95
|
+
renderMainScene
|
|
96
|
+
};
|
|
@@ -0,0 +1,139 @@
|
|
|
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: "#101115",
|
|
15
|
+
glass: "#14161b",
|
|
16
|
+
ink: "#f2f3f6",
|
|
17
|
+
ink2: "#aeb0ba",
|
|
18
|
+
ink3: "#6c6e79",
|
|
19
|
+
ink4: "#44464f",
|
|
20
|
+
lime: "#ccff4d",
|
|
21
|
+
limeDim: "#a9d63f",
|
|
22
|
+
cyan: "#56d8ff",
|
|
23
|
+
red: "#ff5d5d",
|
|
24
|
+
yellow: "#ffd24d",
|
|
25
|
+
magenta: "#ff79b0"
|
|
26
|
+
};
|
|
27
|
+
var styles = {
|
|
28
|
+
ink: otuiFg(RIG_UI.ink),
|
|
29
|
+
ink2: otuiFg(RIG_UI.ink2),
|
|
30
|
+
ink3: otuiFg(RIG_UI.ink3),
|
|
31
|
+
ink4: otuiFg(RIG_UI.ink4),
|
|
32
|
+
lime: otuiFg(RIG_UI.lime),
|
|
33
|
+
limeDim: otuiFg(RIG_UI.limeDim),
|
|
34
|
+
cyan: otuiFg(RIG_UI.cyan),
|
|
35
|
+
red: otuiFg(RIG_UI.red),
|
|
36
|
+
yellow: otuiFg(RIG_UI.yellow),
|
|
37
|
+
magenta: otuiFg(RIG_UI.magenta)
|
|
38
|
+
};
|
|
39
|
+
function statusColor(status) {
|
|
40
|
+
switch (status) {
|
|
41
|
+
case "running":
|
|
42
|
+
case "success":
|
|
43
|
+
case "completed":
|
|
44
|
+
case "merged":
|
|
45
|
+
return RIG_UI.lime;
|
|
46
|
+
case "preparing":
|
|
47
|
+
case "created":
|
|
48
|
+
case "validating":
|
|
49
|
+
case "reviewing":
|
|
50
|
+
case "closing-out":
|
|
51
|
+
case "stopping":
|
|
52
|
+
case "loading":
|
|
53
|
+
case "action":
|
|
54
|
+
return RIG_UI.cyan;
|
|
55
|
+
case "needs-attention":
|
|
56
|
+
case "needs_attention":
|
|
57
|
+
return RIG_UI.yellow;
|
|
58
|
+
case "failed":
|
|
59
|
+
case "error":
|
|
60
|
+
return RIG_UI.red;
|
|
61
|
+
default:
|
|
62
|
+
return RIG_UI.ink3;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// packages/cli/src/app-opentui/render/scene.ts
|
|
67
|
+
function line(text, options = {}) {
|
|
68
|
+
return { text, ...options };
|
|
69
|
+
}
|
|
70
|
+
function blank() {
|
|
71
|
+
return { text: "" };
|
|
72
|
+
}
|
|
73
|
+
function center(text, fg = RIG_UI.ink2, bold = false) {
|
|
74
|
+
return { text, fg, bold, align: "center" };
|
|
75
|
+
}
|
|
76
|
+
function deckRow(input) {
|
|
77
|
+
const prefix = input.active ? "\u25B8" : " ";
|
|
78
|
+
const label = input.label.toUpperCase().padEnd(10);
|
|
79
|
+
return line(`${prefix} ${label} ${input.detail}`, {
|
|
80
|
+
fg: input.active ? RIG_UI.lime : RIG_UI.ink2,
|
|
81
|
+
bold: input.active,
|
|
82
|
+
selectableIndex: input.index,
|
|
83
|
+
activateOnClick: input.activateOnClick
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
function kv(label, value, fg = RIG_UI.ink2) {
|
|
87
|
+
return line(` ${label.toUpperCase().padEnd(10)} ${value}`, { fg });
|
|
88
|
+
}
|
|
89
|
+
function makeSceneFrame(input) {
|
|
90
|
+
return input;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// packages/cli/src/app-opentui/scenes/run-detail.ts
|
|
94
|
+
function snapshot(state) {
|
|
95
|
+
const value = state.data.runDetail;
|
|
96
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
97
|
+
}
|
|
98
|
+
function selectedRunId(state, run) {
|
|
99
|
+
if (run?.runId)
|
|
100
|
+
return run.runId;
|
|
101
|
+
return typeof state.data.selectedRunId === "string" ? state.data.selectedRunId : undefined;
|
|
102
|
+
}
|
|
103
|
+
function entryText(entry) {
|
|
104
|
+
return String(entry.detail ?? entry.message ?? entry.text ?? entry.title ?? entry.type ?? "event").replace(/\s+/g, " ").slice(0, 96);
|
|
105
|
+
}
|
|
106
|
+
function renderRunDetailScene(state) {
|
|
107
|
+
const run = snapshot(state);
|
|
108
|
+
const runId = selectedRunId(state, run);
|
|
109
|
+
const selected = Math.max(0, Math.min(2, state.selection.index));
|
|
110
|
+
const timeline = run?.timeline.slice(-5).map((entry) => entryText(entry)) ?? [];
|
|
111
|
+
const logs = run?.logs.slice(-3).map((entry) => entryText(entry)) ?? [];
|
|
112
|
+
const status = run?.status ?? "loading";
|
|
113
|
+
const lines = [
|
|
114
|
+
center(run ? run.title : "run", RIG_UI.ink, true),
|
|
115
|
+
center(runId ? `${runId.slice(0, 8)} \xB7 ${status}` : "loading run", run ? statusColor(status) : RIG_UI.ink3),
|
|
116
|
+
blank(),
|
|
117
|
+
...runId ? [
|
|
118
|
+
deckRow({ label: "pi", detail: "attach bundled Pi", index: 0, active: selected === 0, activateOnClick: true }),
|
|
119
|
+
deckRow({ label: "stop", detail: "request stop", index: 1, active: selected === 1, activateOnClick: true }),
|
|
120
|
+
deckRow({ label: "runs", detail: "return to list", index: 2, active: selected === 2, activateOnClick: true }),
|
|
121
|
+
blank(),
|
|
122
|
+
kv("status", status, statusColor(status)),
|
|
123
|
+
kv("run", runId, RIG_UI.ink2)
|
|
124
|
+
] : [line("loading run telemetry", { fg: RIG_UI.ink3, align: "center" })],
|
|
125
|
+
...timeline.length > 0 ? [blank(), line(" timeline", { fg: RIG_UI.ink4, bold: true }), ...timeline.map((entry) => line(` \xB7 ${entry}`, { fg: RIG_UI.ink2 }))] : [],
|
|
126
|
+
...logs.length > 0 ? [blank(), line(" logs", { fg: RIG_UI.ink4, bold: true }), ...logs.map((entry) => line(` \xB7 ${entry}`, { fg: RIG_UI.ink4 }))] : []
|
|
127
|
+
];
|
|
128
|
+
return makeSceneFrame({
|
|
129
|
+
scene: "run-detail",
|
|
130
|
+
title: "Run",
|
|
131
|
+
lines,
|
|
132
|
+
footer: { run: runId ? `${runId.slice(0, 8)} ${status}` : undefined },
|
|
133
|
+
typeBarPlaceholder: runId ? `attach ${runId.slice(0, 8)} \xB7 stop ${runId.slice(0, 8)} \xB7 runs` : "runs \xB7 tasks",
|
|
134
|
+
live: state.status === "action" || !run
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
export {
|
|
138
|
+
renderRunDetailScene
|
|
139
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
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: "#101115",
|
|
15
|
+
glass: "#14161b",
|
|
16
|
+
ink: "#f2f3f6",
|
|
17
|
+
ink2: "#aeb0ba",
|
|
18
|
+
ink3: "#6c6e79",
|
|
19
|
+
ink4: "#44464f",
|
|
20
|
+
lime: "#ccff4d",
|
|
21
|
+
limeDim: "#a9d63f",
|
|
22
|
+
cyan: "#56d8ff",
|
|
23
|
+
red: "#ff5d5d",
|
|
24
|
+
yellow: "#ffd24d",
|
|
25
|
+
magenta: "#ff79b0"
|
|
26
|
+
};
|
|
27
|
+
var styles = {
|
|
28
|
+
ink: otuiFg(RIG_UI.ink),
|
|
29
|
+
ink2: otuiFg(RIG_UI.ink2),
|
|
30
|
+
ink3: otuiFg(RIG_UI.ink3),
|
|
31
|
+
ink4: otuiFg(RIG_UI.ink4),
|
|
32
|
+
lime: otuiFg(RIG_UI.lime),
|
|
33
|
+
limeDim: otuiFg(RIG_UI.limeDim),
|
|
34
|
+
cyan: otuiFg(RIG_UI.cyan),
|
|
35
|
+
red: otuiFg(RIG_UI.red),
|
|
36
|
+
yellow: otuiFg(RIG_UI.yellow),
|
|
37
|
+
magenta: otuiFg(RIG_UI.magenta)
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// packages/cli/src/app-opentui/render/scene.ts
|
|
41
|
+
function line(text, options = {}) {
|
|
42
|
+
return { text, ...options };
|
|
43
|
+
}
|
|
44
|
+
function blank() {
|
|
45
|
+
return { text: "" };
|
|
46
|
+
}
|
|
47
|
+
function center(text, fg = RIG_UI.ink2, bold = false) {
|
|
48
|
+
return { text, fg, bold, align: "center" };
|
|
49
|
+
}
|
|
50
|
+
function makeSceneFrame(input) {
|
|
51
|
+
return input;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// packages/cli/src/app-opentui/scenes/server.ts
|
|
55
|
+
function serverState(state) {
|
|
56
|
+
const server = state.data.server;
|
|
57
|
+
return server && typeof server === "object" && !Array.isArray(server) ? server : null;
|
|
58
|
+
}
|
|
59
|
+
function renderServerScene(state) {
|
|
60
|
+
const server = serverState(state);
|
|
61
|
+
const auth = server?.auth;
|
|
62
|
+
const signedIn = auth && (auth.signedIn === true || auth.authenticated === true || auth.status === "authenticated") ? "authenticated" : "auth unknown";
|
|
63
|
+
return makeSceneFrame({
|
|
64
|
+
scene: "server",
|
|
65
|
+
title: "Server",
|
|
66
|
+
lines: [
|
|
67
|
+
center("server", RIG_UI.ink, true),
|
|
68
|
+
center(server?.label ?? "loading connection", RIG_UI.ink3),
|
|
69
|
+
blank(),
|
|
70
|
+
...server ? [
|
|
71
|
+
line(`selected ${server.label}`, { fg: RIG_UI.ink2, align: "center" }),
|
|
72
|
+
line(`target ${server.baseUrl ?? "unknown"}`, { fg: RIG_UI.ink3, align: "center" }),
|
|
73
|
+
line(`mode ${server.kind ?? "unknown"}`, { fg: RIG_UI.ink3, align: "center" }),
|
|
74
|
+
line(`health ${server.reachable ? "reachable" : "unreachable"}`, { fg: server.reachable ? RIG_UI.limeDim : RIG_UI.red, align: "center" }),
|
|
75
|
+
line(`latency ${server.latencyMs ?? "\u2014"}ms`, { fg: RIG_UI.cyan, align: "center" }),
|
|
76
|
+
line(`github ${signedIn}`, { fg: RIG_UI.ink4, align: "center" }),
|
|
77
|
+
blank(),
|
|
78
|
+
line(server.error ? `attention ${server.error}` : "ready", { fg: server.error ? RIG_UI.yellow : RIG_UI.ink4, align: "center" })
|
|
79
|
+
] : [line("loading server status", { fg: RIG_UI.ink3, align: "center" })]
|
|
80
|
+
],
|
|
81
|
+
footer: { server: server?.label, message: server?.latencyMs !== undefined ? `${server.latencyMs}ms` : undefined },
|
|
82
|
+
typeBarPlaceholder: "server \xB7 doctor \xB7 tasks \xB7 runs",
|
|
83
|
+
live: state.status === "action" || !server
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
export {
|
|
87
|
+
renderServerScene
|
|
88
|
+
};
|