@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
|
@@ -11,19 +11,25 @@ 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"
|
|
26
28
|
};
|
|
29
|
+
var SELECTION_MARKER = "\u258C";
|
|
30
|
+
var SELECTION_MARKER_IDLE = " ";
|
|
31
|
+
var LABEL_WIDTH = 14;
|
|
32
|
+
var COLUMN_GUTTER = " ";
|
|
27
33
|
var RIG_SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
28
34
|
var styles = {
|
|
29
35
|
ink: otuiFg(RIG_UI.ink),
|
|
@@ -39,11 +45,11 @@ var styles = {
|
|
|
39
45
|
};
|
|
40
46
|
function statusColor(status) {
|
|
41
47
|
switch (status) {
|
|
42
|
-
case "running":
|
|
43
48
|
case "success":
|
|
44
49
|
case "completed":
|
|
45
50
|
case "merged":
|
|
46
51
|
return RIG_UI.lime;
|
|
52
|
+
case "running":
|
|
47
53
|
case "preparing":
|
|
48
54
|
case "created":
|
|
49
55
|
case "validating":
|
|
@@ -63,6 +69,46 @@ function statusColor(status) {
|
|
|
63
69
|
return RIG_UI.ink3;
|
|
64
70
|
}
|
|
65
71
|
}
|
|
72
|
+
function statusGlyph(status) {
|
|
73
|
+
switch (status) {
|
|
74
|
+
case "success":
|
|
75
|
+
case "completed":
|
|
76
|
+
case "merged":
|
|
77
|
+
return "\u2713";
|
|
78
|
+
case "running":
|
|
79
|
+
return "\u25CF";
|
|
80
|
+
case "preparing":
|
|
81
|
+
case "created":
|
|
82
|
+
case "validating":
|
|
83
|
+
case "reviewing":
|
|
84
|
+
case "closing-out":
|
|
85
|
+
case "stopping":
|
|
86
|
+
case "loading":
|
|
87
|
+
case "action":
|
|
88
|
+
return "\u25D0";
|
|
89
|
+
case "needs-attention":
|
|
90
|
+
case "needs_attention":
|
|
91
|
+
return "\u26A0";
|
|
92
|
+
case "failed":
|
|
93
|
+
case "error":
|
|
94
|
+
return "\u2717";
|
|
95
|
+
default:
|
|
96
|
+
return "\xB7";
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function noColorActive() {
|
|
100
|
+
const noColor = process.env.NO_COLOR;
|
|
101
|
+
if (noColor !== undefined && noColor !== "") {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return process.env.RIG_NO_COLOR !== undefined;
|
|
105
|
+
}
|
|
106
|
+
function statusLabel(status) {
|
|
107
|
+
return {
|
|
108
|
+
glyph: statusGlyph(status),
|
|
109
|
+
color: noColorActive() ? RIG_UI.ink : statusColor(status)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
66
112
|
function sceneTitle(title) {
|
|
67
113
|
return t`${otuiBold(styles.ink(title))}`;
|
|
68
114
|
}
|
|
@@ -75,14 +121,21 @@ function faint(text) {
|
|
|
75
121
|
export {
|
|
76
122
|
t,
|
|
77
123
|
styles,
|
|
124
|
+
statusLabel,
|
|
125
|
+
statusGlyph,
|
|
78
126
|
statusColor,
|
|
79
127
|
sceneTitle,
|
|
128
|
+
noColorActive,
|
|
80
129
|
otuiFg as fg,
|
|
81
130
|
faint,
|
|
82
131
|
otuiDim as dim,
|
|
83
132
|
commandText,
|
|
84
133
|
otuiBold as bold,
|
|
85
134
|
TextAttributes,
|
|
135
|
+
SELECTION_MARKER_IDLE,
|
|
136
|
+
SELECTION_MARKER,
|
|
86
137
|
RIG_UI,
|
|
87
|
-
RIG_SPINNER_FRAMES
|
|
138
|
+
RIG_SPINNER_FRAMES,
|
|
139
|
+
LABEL_WIDTH,
|
|
140
|
+
COLUMN_GUTTER
|
|
88
141
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { StyledText } from "@opentui/core";
|
|
2
2
|
import type { RunnerContext } from "../runner";
|
|
3
3
|
import type { StageLayout } from "./layout";
|
|
4
|
-
export type AppSceneId = "main" | "fleet" | "tasks" | "inbox" | "server" | "init" | "doctor" | "command" | "run-detail" | "handoff" | "help" | "error";
|
|
4
|
+
export type AppSceneId = "main" | "fleet" | "tasks" | "inbox" | "server" | "init" | "doctor" | "command" | "run-detail" | "handoff" | "pi" | "plugin" | "repo" | "workspace" | "inspect" | "family" | "help" | "error";
|
|
5
5
|
export type AppActionKind = "none" | "refresh" | "navigate" | "task-run-next" | "task-run-id" | "run-stop" | "run-attach" | "run-steer" | "inbox-approve" | "inbox-reject" | "inbox-answer" | "init-start" | "command-run" | "doctor-run";
|
|
6
6
|
export type AppIntent = {
|
|
7
7
|
readonly scene: AppSceneId;
|
|
@@ -22,10 +22,37 @@ export type AppFooterState = {
|
|
|
22
22
|
readonly message?: string;
|
|
23
23
|
readonly [key: string]: string | undefined;
|
|
24
24
|
};
|
|
25
|
+
/** Modal input model for the bottom command bar. nav = vim navigation
|
|
26
|
+
* (printable keys are shortcuts); search = live-filter the current list scene;
|
|
27
|
+
* command = type a full `rig …` command; prompt = capture one value for a
|
|
28
|
+
* pending inline action (inbox answer, run steer) without dropping to a PTY. */
|
|
29
|
+
export type AppTypeBarMode = "nav" | "search" | "command" | "prompt";
|
|
30
|
+
/** Describes an inline prompt: the next submitted value is folded into this
|
|
31
|
+
* intent under `payloadKey`, then dispatched. Keeps answer/steer in-app. */
|
|
32
|
+
export type AppInlinePrompt = {
|
|
33
|
+
readonly label: string;
|
|
34
|
+
readonly scene: AppSceneId;
|
|
35
|
+
readonly argv: readonly string[];
|
|
36
|
+
readonly intentKind: AppActionKind;
|
|
37
|
+
readonly payloadBase: Record<string, unknown>;
|
|
38
|
+
readonly payloadKey: string;
|
|
39
|
+
/** When true, the typed value is tokenized and appended to `argv` (for
|
|
40
|
+
* collecting a parameterized command's args before running it) rather than
|
|
41
|
+
* folded into the action payload. Used by the actionable command catalog (#21). */
|
|
42
|
+
readonly appendValueToArgv?: boolean;
|
|
43
|
+
};
|
|
25
44
|
export type AppTypeBarState = {
|
|
26
45
|
readonly value: string;
|
|
27
46
|
readonly placeholder: string;
|
|
28
47
|
readonly message?: string;
|
|
48
|
+
readonly mode?: AppTypeBarMode;
|
|
49
|
+
readonly prompt?: AppInlinePrompt;
|
|
50
|
+
};
|
|
51
|
+
/** A pending confirmation gate for a destructive action (#16). The held intent
|
|
52
|
+
* only dispatches on an explicit second Enter; esc cancels. */
|
|
53
|
+
export type AppConfirmState = {
|
|
54
|
+
readonly label: string;
|
|
55
|
+
readonly intent: AppIntent;
|
|
29
56
|
};
|
|
30
57
|
export type AppErrorState = {
|
|
31
58
|
readonly message: string;
|
|
@@ -42,6 +69,55 @@ export type AppSelectableItem = {
|
|
|
42
69
|
readonly data?: Record<string, unknown>;
|
|
43
70
|
readonly intent?: AppIntent;
|
|
44
71
|
readonly message?: string;
|
|
72
|
+
/** Activating this item opens an inline prompt instead of dispatching an
|
|
73
|
+
* intent — the typed value is folded into the action (#15). */
|
|
74
|
+
readonly prompt?: AppInlinePrompt;
|
|
75
|
+
};
|
|
76
|
+
/** Typed state.data slices (#7). Scalar selections/flags are precisely typed so
|
|
77
|
+
* their reads don't need casts; heterogeneous server-record slices stay `unknown`
|
|
78
|
+
* (consumers narrow them) and the index signature keeps dynamic writes compiling.
|
|
79
|
+
* This retires the untyped `Record<string, unknown>` bag while staying compatible
|
|
80
|
+
* with every existing patch site. */
|
|
81
|
+
export type AppData = {
|
|
82
|
+
readonly selectedRunId?: string;
|
|
83
|
+
readonly selectedTaskId?: string;
|
|
84
|
+
/** When set, the tasks scene shows that task's dedicated DETAIL screen
|
|
85
|
+
* (native-markdown body + actions) instead of the list (#3/#5/#7). */
|
|
86
|
+
readonly taskDetailId?: string;
|
|
87
|
+
readonly selectedInboxRequestId?: string;
|
|
88
|
+
readonly projectConfigured?: boolean;
|
|
89
|
+
readonly lastRefreshError?: string;
|
|
90
|
+
readonly fleet?: unknown;
|
|
91
|
+
readonly tasks?: unknown;
|
|
92
|
+
readonly inbox?: unknown;
|
|
93
|
+
readonly inboxOptimistic?: unknown;
|
|
94
|
+
readonly server?: unknown;
|
|
95
|
+
readonly runDetail?: unknown;
|
|
96
|
+
readonly inspect?: unknown;
|
|
97
|
+
/** Active sub-view of the inspect scene (logs/timeline/diff/failures). */
|
|
98
|
+
readonly inspectView?: string;
|
|
99
|
+
readonly pi?: unknown;
|
|
100
|
+
readonly plugin?: unknown;
|
|
101
|
+
readonly repo?: unknown;
|
|
102
|
+
readonly workspace?: unknown;
|
|
103
|
+
readonly piTerminal?: unknown;
|
|
104
|
+
readonly commandTerminal?: unknown;
|
|
105
|
+
/** Generic family-browser slice: the active family's catalog + live state. */
|
|
106
|
+
readonly family?: unknown;
|
|
107
|
+
/** Which CLI family the family scene is currently showing. */
|
|
108
|
+
readonly familyName?: string;
|
|
109
|
+
/** In-progress command-form state (selected subcommand + adapted field values). */
|
|
110
|
+
readonly familyForm?: unknown;
|
|
111
|
+
/** The drilled-into item id within the active family's bespoke surface — when
|
|
112
|
+
* set, the renderer shows that item's dedicated DETAIL screen (#5). */
|
|
113
|
+
readonly familyDrillId?: string;
|
|
114
|
+
readonly piAttach?: unknown;
|
|
115
|
+
readonly handoff?: unknown;
|
|
116
|
+
readonly doctor?: unknown;
|
|
117
|
+
readonly init?: unknown;
|
|
118
|
+
readonly dispatchingRun?: unknown;
|
|
119
|
+
readonly latestSubmittedRun?: unknown;
|
|
120
|
+
readonly [key: string]: unknown;
|
|
45
121
|
};
|
|
46
122
|
export type AppState = {
|
|
47
123
|
readonly projectRoot: string;
|
|
@@ -53,16 +129,22 @@ export type AppState = {
|
|
|
53
129
|
readonly typeBar: AppTypeBarState;
|
|
54
130
|
readonly footer: AppFooterState;
|
|
55
131
|
readonly selection: AppSelectionState;
|
|
56
|
-
readonly data:
|
|
132
|
+
readonly data: AppData;
|
|
57
133
|
readonly runtimeReady: boolean;
|
|
58
134
|
readonly actionLabel?: string;
|
|
59
135
|
readonly error?: AppErrorState;
|
|
136
|
+
/** Scene back-stack for esc-pops-one-level navigation (#13). */
|
|
137
|
+
readonly history: readonly AppSceneId[];
|
|
138
|
+
/** Pending destructive-action confirmation gate (#16). */
|
|
139
|
+
readonly confirm?: AppConfirmState;
|
|
140
|
+
/** Wall-clock ms of the last successful data refresh, for "updated Ns ago" (#14). */
|
|
141
|
+
readonly dataUpdatedAtMs?: number;
|
|
60
142
|
};
|
|
61
143
|
export type AppStatePatch = Omit<Partial<AppState>, "typeBar" | "footer" | "selection" | "data"> & {
|
|
62
144
|
readonly typeBar?: Partial<AppTypeBarState>;
|
|
63
145
|
readonly footer?: Partial<AppFooterState>;
|
|
64
146
|
readonly selection?: Partial<AppSelectionState>;
|
|
65
|
-
readonly data?:
|
|
147
|
+
readonly data?: AppData;
|
|
66
148
|
};
|
|
67
149
|
export type AppEvent = {
|
|
68
150
|
readonly type: "scene.change";
|
|
@@ -104,6 +186,11 @@ export type AppEvent = {
|
|
|
104
186
|
readonly message: string;
|
|
105
187
|
readonly hint?: string;
|
|
106
188
|
readonly cause?: unknown;
|
|
189
|
+
} | {
|
|
190
|
+
readonly type: "confirm.request";
|
|
191
|
+
readonly confirm: AppConfirmState;
|
|
192
|
+
} | {
|
|
193
|
+
readonly type: "confirm.cancel";
|
|
107
194
|
};
|
|
108
195
|
export type AppStore = {
|
|
109
196
|
getState(): AppState;
|
|
@@ -123,8 +210,15 @@ export type AppSceneLine = {
|
|
|
123
210
|
readonly bold?: boolean;
|
|
124
211
|
readonly dim?: boolean;
|
|
125
212
|
readonly align?: "left" | "center" | "right";
|
|
126
|
-
/**
|
|
213
|
+
/** Compacted selectable index into the rendered item list. Derived by the
|
|
214
|
+
* runtime at render time from `selectable`; scenes never set this directly. */
|
|
127
215
|
readonly selectableIndex?: number;
|
|
216
|
+
/** Stable id of the selectable item this line activates. Derived from
|
|
217
|
+
* `selectable.id` at render time so clicks match by id, not position (#12). */
|
|
218
|
+
readonly selectableId?: string;
|
|
219
|
+
/** The full selectable item this line activates. The runtime DERIVES the
|
|
220
|
+
* scene's selectable list from these (single source of truth, #6/#12). */
|
|
221
|
+
readonly selectable?: AppSelectableItem;
|
|
128
222
|
/** Activate on single click instead of only selecting/double-clicking. */
|
|
129
223
|
readonly activateOnClick?: boolean;
|
|
130
224
|
};
|
|
@@ -164,6 +258,27 @@ export type AppSceneFrame = {
|
|
|
164
258
|
readonly hideTypeBar?: boolean;
|
|
165
259
|
/** Raw keypresses should be forwarded to the embedded terminal host. */
|
|
166
260
|
readonly terminalActive?: boolean;
|
|
261
|
+
/** Render this content with a NATIVE OpenTUI component (Tree-sitter code,
|
|
262
|
+
* diff, or markdown) inside a scrollbox, instead of the AppSceneLine pipeline
|
|
263
|
+
* (#7). The scene's own `lines` still render around it (header/tabs). */
|
|
264
|
+
readonly native?: AppNativeMount;
|
|
265
|
+
};
|
|
266
|
+
/** A scene's request to mount a native OpenTUI renderable in a panel rectangle. */
|
|
267
|
+
export type AppNativeMount = {
|
|
268
|
+
readonly kind: "code" | "diff" | "markdown" | "table";
|
|
269
|
+
/** Source/diff/markdown text for code/diff/markdown kinds. */
|
|
270
|
+
readonly content: string;
|
|
271
|
+
/** Rows for `kind: "table"` — the first row is the header. Rendered with the
|
|
272
|
+
* native TextTableRenderable (read-only dense tables). */
|
|
273
|
+
readonly rows?: readonly (readonly string[])[];
|
|
274
|
+
/** Tree-sitter filetype for `kind: "code"` (e.g. "typescript", "json"). */
|
|
275
|
+
readonly filetype?: string;
|
|
276
|
+
readonly top?: number;
|
|
277
|
+
readonly left?: number;
|
|
278
|
+
readonly width?: number;
|
|
279
|
+
readonly height?: number;
|
|
280
|
+
/** Pin scroll to the bottom (log/diff tails). */
|
|
281
|
+
readonly stickyBottom?: boolean;
|
|
167
282
|
};
|
|
168
283
|
export type AppSceneRenderer = (state: AppState, layout?: StageLayout) => AppSceneFrame;
|
|
169
284
|
export type AppRuntime = {
|
|
@@ -172,6 +287,8 @@ export type AppRuntime = {
|
|
|
172
287
|
emit(event: AppEvent): void;
|
|
173
288
|
setScene(scene: AppSceneId, intent?: AppIntent): void;
|
|
174
289
|
runIntent(intent: AppIntent): Promise<void>;
|
|
290
|
+
/** Pop the scene back-stack one level (esc), refreshing the target (#13). */
|
|
291
|
+
goBack(): Promise<void>;
|
|
175
292
|
getRunnerContext(): Promise<RunnerContext>;
|
|
176
293
|
suspend(): void;
|
|
177
294
|
resume(): void;
|
|
@@ -2,7 +2,7 @@ import { type AuthorityRunRecord } from "@rig/runtime/control-plane/authority-fi
|
|
|
2
2
|
import type { RunStatus } from "@rig/contracts";
|
|
3
3
|
export declare const RIG_WORKSPACE_ID = "rig-local-workspace";
|
|
4
4
|
export type RuntimeAdapter = "claude-code" | "codex" | "pi";
|
|
5
|
-
export declare function normalizeRuntimeAdapter(
|
|
5
|
+
export declare function normalizeRuntimeAdapter(_value: string | undefined): RuntimeAdapter;
|
|
6
6
|
export declare function readLatestBeadRecord(projectRoot: string, taskId: string): Record<string, unknown> | null;
|
|
7
7
|
export declare function upsertAgentAuthorityRun(projectRoot: string, input: {
|
|
8
8
|
runId: string;
|
|
@@ -16,18 +16,8 @@ function resolveControlPlaneMonorepoRoot(projectRoot) {
|
|
|
16
16
|
|
|
17
17
|
// packages/cli/src/commands/_authority-runs.ts
|
|
18
18
|
var RIG_WORKSPACE_ID = "rig-local-workspace";
|
|
19
|
-
function normalizeRuntimeAdapter(
|
|
20
|
-
|
|
21
|
-
if (!normalized) {
|
|
22
|
-
return "pi";
|
|
23
|
-
}
|
|
24
|
-
if (normalized === "codex" || normalized === "codex-cli" || normalized === "codex-app-server" || normalized === "gpt-codex") {
|
|
25
|
-
return "codex";
|
|
26
|
-
}
|
|
27
|
-
if (normalized === "pi" || normalized === "rig-pi" || normalized === "@rig/pi") {
|
|
28
|
-
return "pi";
|
|
29
|
-
}
|
|
30
|
-
return "claude-code";
|
|
19
|
+
function normalizeRuntimeAdapter(_value) {
|
|
20
|
+
return "pi";
|
|
31
21
|
}
|
|
32
22
|
function readLatestBeadRecord(projectRoot, taskId) {
|
|
33
23
|
const issuesPath = resolve(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
|
|
@@ -254,30 +254,62 @@ var PRIMARY_GROUPS = [
|
|
|
254
254
|
}
|
|
255
255
|
];
|
|
256
256
|
var ADVANCED_GROUPS = [
|
|
257
|
-
{
|
|
258
|
-
|
|
257
|
+
{
|
|
258
|
+
name: "setup",
|
|
259
|
+
summary: "Bootstrap/check local setup.",
|
|
260
|
+
usage: ["rig setup <bootstrap|check|preflight>"],
|
|
261
|
+
commands: [
|
|
262
|
+
{ command: "bootstrap", description: "Bootstrap local setup dependencies.", primary: true },
|
|
263
|
+
{ command: "check", description: "Check local setup state (toolchain, deps, config).", primary: true },
|
|
264
|
+
{ command: "preflight", description: "Run preflight checks before a run.", primary: true }
|
|
265
|
+
]
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "profile",
|
|
269
|
+
summary: "Runtime profile/model defaults.",
|
|
270
|
+
usage: ["rig profile <show|set>"],
|
|
271
|
+
commands: [
|
|
272
|
+
{ command: "show", description: "Show the active execution profile.", primary: true },
|
|
273
|
+
{ command: "set [--model <model>] [--runtime <runtime>] [--plugin <plugin>]", description: "Set model/runtime/plugin profile defaults.", primary: true }
|
|
274
|
+
]
|
|
275
|
+
},
|
|
259
276
|
{
|
|
260
277
|
name: "review",
|
|
261
278
|
summary: "Inspect or change completion review gate policy.",
|
|
262
279
|
usage: ["rig review <show|set>"],
|
|
263
280
|
commands: [
|
|
264
281
|
{ command: "show", description: "Show current review gate settings." },
|
|
265
|
-
{ command: "set <off|advisory|required> [--provider
|
|
282
|
+
{ command: "set <off|advisory|required> [--provider <provider>]", description: "Change review strictness/provider (e.g. --provider greptile)." }
|
|
266
283
|
],
|
|
267
284
|
examples: ["rig review show", "rig review set required --provider greptile"],
|
|
268
285
|
next: ["Use `rig inbox approvals` for blocked run handoffs."]
|
|
269
286
|
},
|
|
270
287
|
{
|
|
271
288
|
name: "browser",
|
|
272
|
-
summary: "Browser
|
|
273
|
-
usage: ["rig browser <help|explain|demo|
|
|
289
|
+
summary: "Browser workstation actions for browser-required tasks: launch, check, CDP probe, profile reset, and app-specific smokes.",
|
|
290
|
+
usage: ["rig browser <help|explain|demo|hp-next|cdp-probe|profile-persistence|profile-lock-check|smoke-test> [options]"],
|
|
274
291
|
commands: [
|
|
275
|
-
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
|
|
276
|
-
{ command: "explain", description: "Explain the browser-required task contract." },
|
|
277
|
-
{ command: "demo", description: "Run
|
|
278
|
-
{ command: "
|
|
279
|
-
{ command: "hp-next
|
|
280
|
-
|
|
292
|
+
{ command: "help", description: "Rich browser command help (canonical: `rig browser help`).", primary: true },
|
|
293
|
+
{ command: "explain", description: "Explain the browser-required task contract and runtime helper commands.", primary: true },
|
|
294
|
+
{ command: "demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]", description: "Run a guided real browser/agent demo flow.", primary: true },
|
|
295
|
+
{ command: "hp-next dev", description: "Start hp-next Rig Browser in dev/watch mode.", primary: true },
|
|
296
|
+
{ command: "hp-next start", description: "Build/start the hp-next browser workstation without watch mode.", primary: true },
|
|
297
|
+
{ command: "hp-next check", description: "Validate the hp-next CDP endpoint on the configured port.", primary: true },
|
|
298
|
+
{ command: "hp-next e2e", description: "Run hp-next browser e2e smoke checks through Rig Browser.", primary: true },
|
|
299
|
+
{ command: "hp-next reset", description: "Reset the hp-next browser profile when stale browser state is suspected.", primary: true },
|
|
300
|
+
{ command: "cdp-probe", description: "Run an isolated CDP attach/evaluate/layout probe." },
|
|
301
|
+
{ command: "profile-persistence", description: "Verify a named browser profile persists browser state." },
|
|
302
|
+
{ command: "profile-lock-check", description: "Verify concurrent launches reject the same profile." },
|
|
303
|
+
{ command: "smoke-test", description: "Run the browser package smoke test." }
|
|
304
|
+
],
|
|
305
|
+
examples: [
|
|
306
|
+
"rig browser help",
|
|
307
|
+
"rig browser hp-next check",
|
|
308
|
+
"rig browser hp-next e2e",
|
|
309
|
+
"rig browser cdp-probe",
|
|
310
|
+
"rig browser profile-lock-check"
|
|
311
|
+
],
|
|
312
|
+
next: ["Inside a task run, use rig-browser-launch, rig-browser-check, and rig-browser-attach-info from the worker PATH."]
|
|
281
313
|
},
|
|
282
314
|
{
|
|
283
315
|
name: "pi",
|
|
@@ -292,12 +324,60 @@ var ADVANCED_GROUPS = [
|
|
|
292
324
|
examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
|
|
293
325
|
next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
|
|
294
326
|
},
|
|
295
|
-
{
|
|
296
|
-
|
|
327
|
+
{
|
|
328
|
+
name: "queue",
|
|
329
|
+
summary: "Run task queues locally.",
|
|
330
|
+
usage: ["rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]"],
|
|
331
|
+
commands: [
|
|
332
|
+
{ command: "run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]", description: "Process queue work: drain matching tasks with N workers, optional per-task action and isolation.", primary: true }
|
|
333
|
+
]
|
|
334
|
+
},
|
|
335
|
+
{
|
|
336
|
+
name: "agent",
|
|
337
|
+
summary: "Runtime agent workspace helpers.",
|
|
338
|
+
usage: ["rig agent <list|prepare|run|cleanup>"],
|
|
339
|
+
commands: [
|
|
340
|
+
{ command: "list", description: "List prepared agent runtimes.", primary: true },
|
|
341
|
+
{ command: "prepare [--id <id>] [--mode <mode>] [--task <task>]", description: "Prepare an isolated agent runtime workspace.", primary: true },
|
|
342
|
+
{ command: "run [--id <id>] [--mode <mode>] [--task <task>] [--skip-project-sync]", description: "Prepare (if needed) and run an agent in its workspace.", primary: true },
|
|
343
|
+
{ command: "cleanup [--all] [--id <id>]", description: "Remove prepared agent workspaces.", primary: true }
|
|
344
|
+
]
|
|
345
|
+
},
|
|
297
346
|
{ name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
|
|
298
|
-
{
|
|
347
|
+
{
|
|
348
|
+
name: "dist",
|
|
349
|
+
summary: "Build/install packaged Rig CLI.",
|
|
350
|
+
usage: ["rig dist <build|install|doctor|rebuild-agent>"],
|
|
351
|
+
commands: [
|
|
352
|
+
{ command: "build [--output-dir <dir>]", description: "Build the distributable Rig CLI.", primary: true },
|
|
353
|
+
{ command: "install [--scope <scope>] [--path <path>]", description: "Install the built CLI to a scope/path.", primary: true },
|
|
354
|
+
{ command: "doctor", description: "Diagnose the dist toolchain and install state.", primary: true },
|
|
355
|
+
{ command: "rebuild-agent", description: "Rebuild the agent runtime image, pruning stale images.", primary: true }
|
|
356
|
+
]
|
|
357
|
+
},
|
|
299
358
|
{ name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
|
|
300
|
-
{
|
|
359
|
+
{
|
|
360
|
+
name: "remote",
|
|
361
|
+
summary: "Compatibility remote orchestration controls.",
|
|
362
|
+
usage: ["rig remote <status|tasks|watch|pause|resume|continue|stop|refresh|add-iterations|remove-iterations|endpoint ...>"],
|
|
363
|
+
commands: [
|
|
364
|
+
{ command: "status [--remote <alias>]", description: "Show the remote orchestration state.", primary: true },
|
|
365
|
+
{ command: "tasks [--remote <alias>]", description: "List the remote's tracked tasks.", primary: true },
|
|
366
|
+
{ command: "watch [--remote <alias>] [--seconds <n>] [--event <type>]", description: "Stream remote orchestration events.", primary: true },
|
|
367
|
+
{ command: "pause [--remote <alias>]", description: "Pause the running remote orchestration.", primary: true },
|
|
368
|
+
{ command: "resume [--remote <alias>] [--max-workers <n>] [--max-iterations <n>] [--direct-merge]", description: "Resume the remote with optional tuning.", primary: true },
|
|
369
|
+
{ command: "continue [--remote <alias>]", description: "Continue a paused remote orchestration.", primary: true },
|
|
370
|
+
{ command: "stop [--remote <alias>]", description: "Stop the remote orchestration.", primary: true },
|
|
371
|
+
{ command: "refresh [--remote <alias>]", description: "Refresh remote state.", primary: true },
|
|
372
|
+
{ command: "add-iterations [--count <n>] [--remote <alias>]", description: "Grant the remote more iterations.", primary: true },
|
|
373
|
+
{ command: "remove-iterations [--count <n>] [--remote <alias>]", description: "Reduce the remote's iteration budget.", primary: true },
|
|
374
|
+
{ command: "endpoint list", description: "List configured remote endpoints.", primary: true },
|
|
375
|
+
{ command: "endpoint add --alias <alias> --host <host> --port <n> [--token <token>]", description: "Register a remote endpoint.", primary: true },
|
|
376
|
+
{ command: "endpoint remove --alias <alias>", description: "Remove a remote endpoint.", primary: true },
|
|
377
|
+
{ command: "endpoint test [--alias <alias>]", description: "Test connectivity to a remote endpoint.", primary: true },
|
|
378
|
+
{ command: "endpoint doctor", description: "Diagnose remote endpoint configuration.", primary: true }
|
|
379
|
+
]
|
|
380
|
+
},
|
|
301
381
|
{ name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
|
|
302
382
|
{ name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
|
|
303
383
|
{ name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
|
|
@@ -819,6 +819,14 @@ async function withSpinner(label, work, options = {}) {
|
|
|
819
819
|
}
|
|
820
820
|
|
|
821
821
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
822
|
+
var TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
823
|
+
|
|
824
|
+
class OperatorTranscriptUnavailableError extends Error {
|
|
825
|
+
constructor(message) {
|
|
826
|
+
super(message);
|
|
827
|
+
this.name = "OperatorTranscriptUnavailableError";
|
|
828
|
+
}
|
|
829
|
+
}
|
|
822
830
|
function setTemporaryEnv(updates) {
|
|
823
831
|
const previous = new Map;
|
|
824
832
|
for (const [key, value] of Object.entries(updates)) {
|
|
@@ -846,6 +854,23 @@ function buildOperatorPiEnv(input) {
|
|
|
846
854
|
...input.serverProjectRoot ? { RIG_PROJECT_ROOT: input.serverProjectRoot } : {}
|
|
847
855
|
};
|
|
848
856
|
}
|
|
857
|
+
function shouldRequireOperatorTranscript(status) {
|
|
858
|
+
return typeof status === "string" && TERMINAL_RUN_STATUSES.has(status.trim().toLowerCase());
|
|
859
|
+
}
|
|
860
|
+
function missingOperatorTranscriptMessage(runId, status) {
|
|
861
|
+
const shortRun = runId.trim().slice(0, 8) || "unknown";
|
|
862
|
+
const statusText = typeof status === "string" && status.trim() ? status.trim() : "terminal";
|
|
863
|
+
return `Run ${shortRun} is ${statusText}, but no worker Pi session transcript is recorded for this run. It likely failed before Pi started or predates full-session capture. Use \`rig run show ${runId}\` and \`rig run logs ${runId}\` for the lifecycle details.`;
|
|
864
|
+
}
|
|
865
|
+
function statusFromRunDetails(run) {
|
|
866
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
867
|
+
return;
|
|
868
|
+
const record = run;
|
|
869
|
+
if (typeof record.status === "string")
|
|
870
|
+
return record.status;
|
|
871
|
+
const nested = record.run;
|
|
872
|
+
return nested && typeof nested === "object" && !Array.isArray(nested) ? nested.status : undefined;
|
|
873
|
+
}
|
|
849
874
|
async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
850
875
|
const server = await ensureServerForCli(context.projectRoot);
|
|
851
876
|
const localCwd = join(homedir2(), ".rig", "drones", runId.slice(0, 8));
|
|
@@ -875,6 +900,13 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
875
900
|
sessionFileArg = ["--session", localSessionPath];
|
|
876
901
|
}
|
|
877
902
|
} catch {}
|
|
903
|
+
if (sessionFileArg.length === 0) {
|
|
904
|
+
const run = await getRunDetailsViaServer(context, runId).catch(() => null);
|
|
905
|
+
const status = statusFromRunDetails(run);
|
|
906
|
+
if (shouldRequireOperatorTranscript(status)) {
|
|
907
|
+
throw new OperatorTranscriptUnavailableError(missingOperatorTranscriptMessage(runId, status));
|
|
908
|
+
}
|
|
909
|
+
}
|
|
878
910
|
return { server, sessionFileArg };
|
|
879
911
|
}
|
|
880
912
|
var RIG_PI_THEME = {
|
|
@@ -1022,7 +1054,7 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1022
1054
|
}
|
|
1023
1055
|
|
|
1024
1056
|
// packages/cli/src/commands/_operator-view.ts
|
|
1025
|
-
var
|
|
1057
|
+
var TERMINAL_RUN_STATUSES2 = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
1026
1058
|
function runStatusFromPayload(payload) {
|
|
1027
1059
|
const run = payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
|
|
1028
1060
|
return String(run.status ?? "unknown").toLowerCase();
|
|
@@ -1100,7 +1132,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
1100
1132
|
}
|
|
1101
1133
|
const pollMs = Math.max(250, Math.trunc(input.pollMs ?? 2000));
|
|
1102
1134
|
let timelineCursor = snapshot.timelineCursor;
|
|
1103
|
-
while (!detached && !
|
|
1135
|
+
while (!detached && !TERMINAL_RUN_STATUSES2.has(runStatusFromPayload(snapshot.run))) {
|
|
1104
1136
|
await Bun.sleep(pollMs);
|
|
1105
1137
|
snapshot = await readOperatorSnapshot(context, input.runId, { timelineCursor });
|
|
1106
1138
|
timelineCursor = snapshot.timelineCursor;
|
|
@@ -20,6 +20,8 @@ export declare function buildOperatorPiEnv(input: {
|
|
|
20
20
|
readonly serverProjectRoot?: string | null;
|
|
21
21
|
readonly sessionDir: string;
|
|
22
22
|
}): Record<string, string>;
|
|
23
|
+
export declare function shouldRequireOperatorTranscript(status: unknown): boolean;
|
|
24
|
+
export declare function missingOperatorTranscriptMessage(runId: string, status: unknown): string;
|
|
23
25
|
export declare function attachRunBundledPiFrontend(context: Pick<RunnerContext, "projectRoot" | "outputMode">, input: {
|
|
24
26
|
readonly runId: string;
|
|
25
27
|
readonly steered?: boolean;
|
|
@@ -585,6 +585,14 @@ async function withSpinner(label, work, options = {}) {
|
|
|
585
585
|
}
|
|
586
586
|
|
|
587
587
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
588
|
+
var TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
|
|
589
|
+
|
|
590
|
+
class OperatorTranscriptUnavailableError extends Error {
|
|
591
|
+
constructor(message) {
|
|
592
|
+
super(message);
|
|
593
|
+
this.name = "OperatorTranscriptUnavailableError";
|
|
594
|
+
}
|
|
595
|
+
}
|
|
588
596
|
function setTemporaryEnv(updates) {
|
|
589
597
|
const previous = new Map;
|
|
590
598
|
for (const [key, value] of Object.entries(updates)) {
|
|
@@ -612,6 +620,23 @@ function buildOperatorPiEnv(input) {
|
|
|
612
620
|
...input.serverProjectRoot ? { RIG_PROJECT_ROOT: input.serverProjectRoot } : {}
|
|
613
621
|
};
|
|
614
622
|
}
|
|
623
|
+
function shouldRequireOperatorTranscript(status) {
|
|
624
|
+
return typeof status === "string" && TERMINAL_RUN_STATUSES.has(status.trim().toLowerCase());
|
|
625
|
+
}
|
|
626
|
+
function missingOperatorTranscriptMessage(runId, status) {
|
|
627
|
+
const shortRun = runId.trim().slice(0, 8) || "unknown";
|
|
628
|
+
const statusText = typeof status === "string" && status.trim() ? status.trim() : "terminal";
|
|
629
|
+
return `Run ${shortRun} is ${statusText}, but no worker Pi session transcript is recorded for this run. It likely failed before Pi started or predates full-session capture. Use \`rig run show ${runId}\` and \`rig run logs ${runId}\` for the lifecycle details.`;
|
|
630
|
+
}
|
|
631
|
+
function statusFromRunDetails(run) {
|
|
632
|
+
if (!run || typeof run !== "object" || Array.isArray(run))
|
|
633
|
+
return;
|
|
634
|
+
const record = run;
|
|
635
|
+
if (typeof record.status === "string")
|
|
636
|
+
return record.status;
|
|
637
|
+
const nested = record.run;
|
|
638
|
+
return nested && typeof nested === "object" && !Array.isArray(nested) ? nested.status : undefined;
|
|
639
|
+
}
|
|
615
640
|
async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
616
641
|
const server = await ensureServerForCli(context.projectRoot);
|
|
617
642
|
const localCwd = join(homedir2(), ".rig", "drones", runId.slice(0, 8));
|
|
@@ -641,6 +666,13 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
|
|
|
641
666
|
sessionFileArg = ["--session", localSessionPath];
|
|
642
667
|
}
|
|
643
668
|
} catch {}
|
|
669
|
+
if (sessionFileArg.length === 0) {
|
|
670
|
+
const run = await getRunDetailsViaServer(context, runId).catch(() => null);
|
|
671
|
+
const status = statusFromRunDetails(run);
|
|
672
|
+
if (shouldRequireOperatorTranscript(status)) {
|
|
673
|
+
throw new OperatorTranscriptUnavailableError(missingOperatorTranscriptMessage(runId, status));
|
|
674
|
+
}
|
|
675
|
+
}
|
|
644
676
|
return { server, sessionFileArg };
|
|
645
677
|
}
|
|
646
678
|
var RIG_PI_THEME = {
|
|
@@ -787,6 +819,8 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
787
819
|
};
|
|
788
820
|
}
|
|
789
821
|
export {
|
|
822
|
+
shouldRequireOperatorTranscript,
|
|
823
|
+
missingOperatorTranscriptMessage,
|
|
790
824
|
buildOperatorPiEnv,
|
|
791
825
|
attachRunBundledPiFrontend
|
|
792
826
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type RigLiveStatus = "connecting" | "connected" | "disconnected";
|
|
2
|
+
export type RigLiveHandlers = {
|
|
3
|
+
/** Any snapshot-affecting change (run/task/inbox state). The canonical
|
|
4
|
+
* "something changed, re-pull what you show" signal. */
|
|
5
|
+
readonly onSnapshotInvalidated?: (payload: unknown) => void;
|
|
6
|
+
/** A run appended a log/timeline line — for live run-detail tails. */
|
|
7
|
+
readonly onRunLogAppended?: (payload: unknown) => void;
|
|
8
|
+
/** Sequence-numbered engine domain events. */
|
|
9
|
+
readonly onEngineEvent?: (payload: unknown) => void;
|
|
10
|
+
/** Socket health transitions; callers gate their polling fallback on this. */
|
|
11
|
+
readonly onStatus?: (status: RigLiveStatus) => void;
|
|
12
|
+
};
|
|
13
|
+
export type RigLiveSubscription = {
|
|
14
|
+
/** True while the push socket is connected — gate HTTP fallback polling on it. */
|
|
15
|
+
readonly connected: () => boolean;
|
|
16
|
+
readonly close: () => void;
|
|
17
|
+
};
|
|
18
|
+
/** http(s):// → ws(s)://, with the auth token as the `token` query param the
|
|
19
|
+
* server's upgrade handler authenticates against (packages/server/src/
|
|
20
|
+
* websocket.ts). Mirrors pi-rig's buildRigWebSocketUrl so every surface speaks
|
|
21
|
+
* the same dialect. */
|
|
22
|
+
export declare function buildRigWebSocketUrl(baseUrl: string, authToken: string | null): string;
|
|
23
|
+
/** Open a reconnecting push subscription to the Rig server for a project root.
|
|
24
|
+
* Resolves the same connection (local/remote + auth) the HTTP `…ViaServer`
|
|
25
|
+
* calls use, so the socket targets the exact server the surface reads from. */
|
|
26
|
+
export declare function connectRigServerEvents(projectRoot: string, handlers: RigLiveHandlers): Promise<RigLiveSubscription>;
|