@h-rig/cli 0.0.6-alpha.9 → 0.0.6-alpha.90
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/README.md +1 -1
- package/dist/bin/build-rig-binaries.d.ts +2 -0
- package/dist/bin/rig.d.ts +2 -0
- package/dist/bin/rig.js +11052 -6668
- package/dist/src/app/board.d.ts +23 -0
- package/dist/src/app/board.js +1786 -0
- package/dist/src/app/drone-ui.d.ts +37 -0
- package/dist/src/app/drone-ui.js +294 -0
- package/dist/src/app/theme.d.ts +47 -0
- package/dist/src/app/theme.js +150 -0
- package/dist/src/commands/_async-ui.d.ts +13 -0
- package/dist/src/commands/_async-ui.js +223 -0
- package/dist/src/commands/_authority-runs.d.ts +22 -0
- package/dist/src/commands/_authority-runs.js +2 -3
- package/dist/src/commands/_cli-format.d.ts +49 -0
- package/dist/src/commands/_cli-format.js +447 -0
- package/dist/src/commands/_connection-state.d.ts +44 -0
- package/dist/src/commands/_connection-state.js +30 -11
- package/dist/src/commands/_doctor-checks.d.ts +52 -0
- package/dist/src/commands/_doctor-checks.js +180 -44
- package/dist/src/commands/_help-catalog.d.ts +51 -0
- package/dist/src/commands/_help-catalog.js +442 -0
- package/dist/src/commands/_json-output.d.ts +11 -0
- package/dist/src/commands/_json-output.js +56 -0
- package/dist/src/commands/_operator-surface.d.ts +34 -0
- package/dist/src/commands/_operator-surface.js +220 -0
- package/dist/src/commands/_operator-view.d.ts +30 -0
- package/dist/src/commands/_operator-view.js +803 -73
- package/dist/src/commands/_parsers.d.ts +15 -0
- package/dist/src/commands/_parsers.js +18 -11
- package/dist/src/commands/_paths.d.ts +11 -0
- package/dist/src/commands/_pi-frontend.d.ts +27 -0
- package/dist/src/commands/_pi-frontend.js +742 -0
- package/dist/src/commands/_pi-install.d.ts +42 -0
- package/dist/src/commands/_pi-install.js +5 -4
- package/dist/src/commands/_policy.d.ts +8 -0
- package/dist/src/commands/_policy.js +12 -5
- package/dist/src/commands/_preflight.d.ts +22 -0
- package/dist/src/commands/_preflight.js +190 -128
- package/dist/src/commands/_probes.d.ts +1 -0
- package/dist/src/commands/_run-driver-helpers.d.ts +99 -0
- package/dist/src/commands/_run-driver-helpers.js +75 -22
- package/dist/src/commands/_run-replay.d.ts +24 -0
- package/dist/src/commands/_run-replay.js +142 -0
- package/dist/src/commands/_server-client.d.ts +186 -0
- package/dist/src/commands/_server-client.js +360 -61
- package/dist/src/commands/_snapshot-upload.d.ts +39 -0
- package/dist/src/commands/_snapshot-upload.js +163 -39
- package/dist/src/commands/_spinner.d.ts +25 -0
- package/dist/src/commands/_spinner.js +65 -0
- package/dist/src/commands/_task-picker.d.ts +9 -0
- package/dist/src/commands/_task-picker.js +172 -19
- package/dist/src/commands/agent.d.ts +3 -0
- package/dist/src/commands/agent.js +39 -20
- package/dist/src/commands/browser.d.ts +65 -0
- package/dist/src/commands/browser.js +334 -51
- package/dist/src/commands/connect.d.ts +7 -0
- package/dist/src/commands/connect.js +272 -33
- package/dist/src/commands/dist.d.ts +28 -0
- package/dist/src/commands/dist.js +19 -12
- package/dist/src/commands/doctor.d.ts +3 -0
- package/dist/src/commands/doctor.js +378 -45
- package/dist/src/commands/github.d.ts +3 -0
- package/dist/src/commands/github.js +375 -53
- package/dist/src/commands/inbox.d.ts +30 -0
- package/dist/src/commands/inbox.js +760 -70
- package/dist/src/commands/init.d.ts +74 -0
- package/dist/src/commands/init.js +963 -119
- package/dist/src/commands/inspect.d.ts +3 -0
- package/dist/src/commands/inspect.js +588 -32
- package/dist/src/commands/inspector.d.ts +3 -0
- package/dist/src/commands/inspector.js +20 -13
- package/dist/src/commands/pi.d.ts +3 -0
- package/dist/src/commands/pi.js +177 -0
- package/dist/src/commands/plugin.d.ts +16 -0
- package/dist/src/commands/plugin.js +95 -27
- package/dist/src/commands/profile-and-review.d.ts +4 -0
- package/dist/src/commands/profile-and-review.js +26 -19
- package/dist/src/commands/queue.d.ts +3 -0
- package/dist/src/commands/queue.js +32 -12
- package/dist/src/commands/remote.d.ts +3 -0
- package/dist/src/commands/remote.js +43 -36
- package/dist/src/commands/repo-git-harness.d.ts +5 -0
- package/dist/src/commands/repo-git-harness.js +22 -15
- package/dist/src/commands/run.d.ts +3 -0
- package/dist/src/commands/run.js +1379 -159
- package/dist/src/commands/server.d.ts +7 -0
- package/dist/src/commands/server.js +502 -57
- package/dist/src/commands/setup.d.ts +16 -0
- package/dist/src/commands/setup.js +390 -63
- package/dist/src/commands/stats.d.ts +12 -0
- package/dist/src/commands/stats.js +1051 -0
- package/dist/src/commands/task-report-bug.d.ts +19 -0
- package/dist/src/commands/task-report-bug.js +260 -62
- package/dist/src/commands/task-run-driver.d.ts +132 -0
- package/dist/src/commands/task-run-driver.js +886 -130
- package/dist/src/commands/task.d.ts +14 -0
- package/dist/src/commands/task.js +1644 -314
- package/dist/src/commands/test.d.ts +3 -0
- package/dist/src/commands/test.js +15 -8
- package/dist/src/commands/workspace.d.ts +3 -0
- package/dist/src/commands/workspace.js +18 -11
- package/dist/src/commands.d.ts +29 -0
- package/dist/src/commands.js +10967 -6637
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +10168 -5787
- package/dist/src/launcher.d.ts +61 -0
- package/dist/src/launcher.js +77 -13
- package/dist/src/report-bug.d.ts +44 -0
- package/dist/src/report-bug.js +3 -3
- package/dist/src/runner.d.ts +47 -0
- package/dist/src/runner.js +16 -22
- package/dist/src/withMutedConsole.d.ts +2 -0
- package/package.json +13 -6
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// packages/cli/src/runner.ts
|
|
3
3
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
4
|
-
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
4
|
+
import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
|
|
5
5
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
6
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
7
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
8
6
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
9
|
-
|
|
7
|
+
|
|
8
|
+
class CliError extends RuntimeCliError {
|
|
9
|
+
hint;
|
|
10
|
+
constructor(message, exitCode = 1, options = {}) {
|
|
11
|
+
super(message, exitCode);
|
|
12
|
+
if (options.hint?.trim()) {
|
|
13
|
+
this.hint = options.hint.trim();
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
10
17
|
function takeOption(args, option) {
|
|
11
18
|
const rest = [];
|
|
12
19
|
let value;
|
|
@@ -15,7 +22,7 @@ function takeOption(args, option) {
|
|
|
15
22
|
if (current === option) {
|
|
16
23
|
const next = args[index + 1];
|
|
17
24
|
if (!next || next.startsWith("-")) {
|
|
18
|
-
throw new CliError(`Missing value for ${option}`);
|
|
25
|
+
throw new CliError(`Missing value for ${option}`, 1, { hint: `Provide a value after ${option}, e.g. \`${option} <value>\`.` });
|
|
19
26
|
}
|
|
20
27
|
value = next;
|
|
21
28
|
index += 1;
|
|
@@ -34,12 +41,14 @@ Usage: ${usage}`);
|
|
|
34
41
|
}
|
|
35
42
|
}
|
|
36
43
|
|
|
44
|
+
// packages/cli/src/commands/server.ts
|
|
45
|
+
import { resolveRigServerCommand } from "@rig/runtime/local-server";
|
|
46
|
+
|
|
37
47
|
// packages/cli/src/commands/_authority-runs.ts
|
|
38
48
|
import {
|
|
39
49
|
readAuthorityRun,
|
|
40
50
|
readJsonlFile,
|
|
41
|
-
|
|
42
|
-
writeJsonFile
|
|
51
|
+
writeAuthorityRunRecord
|
|
43
52
|
} from "@rig/runtime/control-plane/authority-files";
|
|
44
53
|
|
|
45
54
|
// packages/cli/src/commands/_paths.ts
|
|
@@ -60,11 +69,133 @@ function normalizeRuntimeAdapter(value) {
|
|
|
60
69
|
return "claude-code";
|
|
61
70
|
}
|
|
62
71
|
|
|
63
|
-
// packages/cli/src/
|
|
64
|
-
import {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
// packages/cli/src/app/drone-ui.ts
|
|
73
|
+
import { ProcessTerminal, TUI, Text, Input, SelectList, matchesKey } from "@earendil-works/pi-tui";
|
|
74
|
+
|
|
75
|
+
// packages/cli/src/app/theme.ts
|
|
76
|
+
var RIG_PALETTE = {
|
|
77
|
+
ink: "#f2f3f6",
|
|
78
|
+
ink2: "#aeb0ba",
|
|
79
|
+
ink3: "#6c6e79",
|
|
80
|
+
ink4: "#44464f",
|
|
81
|
+
accent: "#ccff4d",
|
|
82
|
+
accentDim: "#a9d63f",
|
|
83
|
+
cyan: "#56d8ff",
|
|
84
|
+
red: "#ff5d5d",
|
|
85
|
+
yellow: "#ffd24d"
|
|
86
|
+
};
|
|
87
|
+
function hexToRgb(hex) {
|
|
88
|
+
const value = hex.replace("#", "");
|
|
89
|
+
return [
|
|
90
|
+
Number.parseInt(value.slice(0, 2), 16),
|
|
91
|
+
Number.parseInt(value.slice(2, 4), 16),
|
|
92
|
+
Number.parseInt(value.slice(4, 6), 16)
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
function fg(hex) {
|
|
96
|
+
const [r, g, b] = hexToRgb(hex);
|
|
97
|
+
return (text) => `\x1B[38;2;${r};${g};${b}m${text}\x1B[39m`;
|
|
98
|
+
}
|
|
99
|
+
var ink = fg(RIG_PALETTE.ink);
|
|
100
|
+
var ink2 = fg(RIG_PALETTE.ink2);
|
|
101
|
+
var ink3 = fg(RIG_PALETTE.ink3);
|
|
102
|
+
var ink4 = fg(RIG_PALETTE.ink4);
|
|
103
|
+
var accent = fg(RIG_PALETTE.accent);
|
|
104
|
+
var accentDim = fg(RIG_PALETTE.accentDim);
|
|
105
|
+
var cyan = fg(RIG_PALETTE.cyan);
|
|
106
|
+
var red = fg(RIG_PALETTE.red);
|
|
107
|
+
var yellow = fg(RIG_PALETTE.yellow);
|
|
108
|
+
function bold(text) {
|
|
109
|
+
return `\x1B[1m${text}\x1B[22m`;
|
|
110
|
+
}
|
|
111
|
+
var DRONE_ART = [
|
|
112
|
+
" .-=-. .-=-. ",
|
|
113
|
+
" ( !!! ) ( !!! ) ",
|
|
114
|
+
" '-=-'._ _.'-=-' ",
|
|
115
|
+
" '._ _.' ",
|
|
116
|
+
" '=$$$$$$$=.' ",
|
|
117
|
+
" =$$$$$$$$$$$= ",
|
|
118
|
+
" $$$@@@@@@@@@@$$$ ",
|
|
119
|
+
" $$$@@ @@$$$ ",
|
|
120
|
+
" $$@ ? @$$$ ",
|
|
121
|
+
" $$$@ '-' @$$$ ",
|
|
122
|
+
" $$$@@ @@$$$ ",
|
|
123
|
+
" $$$@@@@@@@@@@$$$ ",
|
|
124
|
+
" =$$$$$$$$$$$= ",
|
|
125
|
+
" '=$$$$$$$=.' ",
|
|
126
|
+
" _.' '._ ",
|
|
127
|
+
" .-=-.' '.-=-. ",
|
|
128
|
+
" ( !!! ) ( !!! ) ",
|
|
129
|
+
" '-=-' '-=-' "
|
|
130
|
+
];
|
|
131
|
+
var EYE_FRAMES = ["@", "o", "."];
|
|
132
|
+
var DRONE_WIDTH = DRONE_ART[0].length;
|
|
133
|
+
var DRONE_HEIGHT = DRONE_ART.length;
|
|
134
|
+
var MICRO_BLADES = ["---", "\\\\\\", "|||", "///"];
|
|
135
|
+
function microDroneFrame(tick) {
|
|
136
|
+
const blade = MICRO_BLADES[tick % MICRO_BLADES.length];
|
|
137
|
+
const eye = EYE_FRAMES[Math.floor(tick / 2) % EYE_FRAMES.length];
|
|
138
|
+
return `(${blade})${eye}(${blade})`;
|
|
139
|
+
}
|
|
140
|
+
var MICRO_DRONE_FRAMES = Array.from({ length: 12 }, (_, index) => microDroneFrame(index));
|
|
141
|
+
|
|
142
|
+
// packages/cli/src/app/drone-ui.ts
|
|
143
|
+
var isTty = () => Boolean(process.stdout.isTTY);
|
|
144
|
+
function droneCancel(text) {
|
|
145
|
+
console.log(` ${red("\u2716")} ${ink3(text)}`);
|
|
146
|
+
}
|
|
147
|
+
var SELECT_THEME = {
|
|
148
|
+
selectedPrefix: (text) => accent(text),
|
|
149
|
+
selectedText: (text) => bold(ink(text)),
|
|
150
|
+
description: (text) => ink3(text),
|
|
151
|
+
scrollInfo: (text) => ink4(text),
|
|
152
|
+
noMatch: (text) => ink3(text)
|
|
153
|
+
};
|
|
154
|
+
async function runMiniTui(build) {
|
|
155
|
+
const terminal = new ProcessTerminal;
|
|
156
|
+
const tui = new TUI(terminal);
|
|
157
|
+
let settled = false;
|
|
158
|
+
return await new Promise((resolve) => {
|
|
159
|
+
const finish = (result) => {
|
|
160
|
+
if (settled)
|
|
161
|
+
return;
|
|
162
|
+
settled = true;
|
|
163
|
+
tui.stop();
|
|
164
|
+
resolve(result);
|
|
165
|
+
};
|
|
166
|
+
build(tui, finish);
|
|
167
|
+
tui.start();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
async function droneSelect(input) {
|
|
171
|
+
if (!isTty() || input.options.length === 0) {
|
|
172
|
+
return input.initialValue ?? input.options[0]?.value ?? null;
|
|
173
|
+
}
|
|
174
|
+
return runMiniTui((tui, finish) => {
|
|
175
|
+
tui.addChild(new Text(` ${accent("\u258D")}${bold(ink(input.message))}`));
|
|
176
|
+
const items = input.options.map((option) => ({
|
|
177
|
+
value: option.value,
|
|
178
|
+
label: option.label,
|
|
179
|
+
...option.hint ? { description: option.hint } : {}
|
|
180
|
+
}));
|
|
181
|
+
const list = new SelectList(items, Math.min(items.length, 12), SELECT_THEME);
|
|
182
|
+
const initialIndex = input.initialValue ? items.findIndex((item) => item.value === input.initialValue) : -1;
|
|
183
|
+
if (initialIndex > 0)
|
|
184
|
+
list.setSelectedIndex(initialIndex);
|
|
185
|
+
list.onSelect = (item) => finish(item.value);
|
|
186
|
+
list.onCancel = () => finish(null);
|
|
187
|
+
tui.addChild(list);
|
|
188
|
+
tui.addChild(new Text(ink4(" \u2191\u2193 navigate \xB7 enter select \xB7 esc cancel")));
|
|
189
|
+
tui.setFocus(list);
|
|
190
|
+
tui.addInputListener((data) => {
|
|
191
|
+
if (matchesKey(data, "ctrl+c") || matchesKey(data, "escape")) {
|
|
192
|
+
finish(null);
|
|
193
|
+
return { consume: true };
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
}
|
|
68
199
|
|
|
69
200
|
// packages/cli/src/commands/_connection-state.ts
|
|
70
201
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
@@ -88,9 +219,14 @@ function readJsonFile(path) {
|
|
|
88
219
|
try {
|
|
89
220
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
90
221
|
} catch (error) {
|
|
91
|
-
throw new
|
|
222
|
+
throw new CliError(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1, { hint: "Fix or delete that file, then re-select a server with `rig server use <alias|local>`." });
|
|
92
223
|
}
|
|
93
224
|
}
|
|
225
|
+
function writeJsonFile(path, value) {
|
|
226
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
227
|
+
writeFileSync(path, `${JSON.stringify(value, null, 2)}
|
|
228
|
+
`, "utf8");
|
|
229
|
+
}
|
|
94
230
|
function normalizeConnection(value) {
|
|
95
231
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
96
232
|
return null;
|
|
@@ -120,6 +256,18 @@ function readGlobalConnections(options = {}) {
|
|
|
120
256
|
}
|
|
121
257
|
return { connections };
|
|
122
258
|
}
|
|
259
|
+
function writeGlobalConnections(state, options = {}) {
|
|
260
|
+
writeJsonFile(resolveGlobalConnectionsPath(options.env ?? process.env), state);
|
|
261
|
+
}
|
|
262
|
+
function upsertGlobalConnection(alias, connection, options = {}) {
|
|
263
|
+
const cleanAlias = alias.trim();
|
|
264
|
+
if (!cleanAlias)
|
|
265
|
+
throw new CliError("Connection alias is required.", 1, { hint: "Save a server with `rig server add <alias> <url>`." });
|
|
266
|
+
const state = readGlobalConnections(options);
|
|
267
|
+
state.connections[cleanAlias] = connection;
|
|
268
|
+
writeGlobalConnections(state, options);
|
|
269
|
+
return state;
|
|
270
|
+
}
|
|
123
271
|
function readRepoConnection(projectRoot) {
|
|
124
272
|
const payload = readJsonFile(resolveRepoConnectionPath(projectRoot));
|
|
125
273
|
if (!payload || typeof payload !== "object" || Array.isArray(payload))
|
|
@@ -131,25 +279,218 @@ function readRepoConnection(projectRoot) {
|
|
|
131
279
|
return {
|
|
132
280
|
selected,
|
|
133
281
|
project: typeof record.project === "string" ? record.project : undefined,
|
|
134
|
-
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
|
|
282
|
+
linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
|
|
283
|
+
serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
|
|
135
284
|
};
|
|
136
285
|
}
|
|
286
|
+
function writeRepoConnection(projectRoot, state) {
|
|
287
|
+
writeJsonFile(resolveRepoConnectionPath(projectRoot), state);
|
|
288
|
+
}
|
|
137
289
|
function resolveSelectedConnection(projectRoot, options = {}) {
|
|
138
290
|
const repo = readRepoConnection(projectRoot);
|
|
139
291
|
if (!repo)
|
|
140
292
|
return null;
|
|
141
293
|
if (repo.selected === "local")
|
|
142
|
-
return { alias: "local", connection: { kind: "local", mode: "auto" } };
|
|
294
|
+
return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
|
|
143
295
|
const global = readGlobalConnections(options);
|
|
144
296
|
const connection = global.connections[repo.selected];
|
|
145
297
|
if (!connection) {
|
|
146
|
-
throw new
|
|
298
|
+
throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
299
|
+
}
|
|
300
|
+
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
301
|
+
}
|
|
302
|
+
function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
|
|
303
|
+
const repo = readRepoConnection(projectRoot);
|
|
304
|
+
if (!repo)
|
|
305
|
+
return;
|
|
306
|
+
writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// packages/cli/src/commands/_cli-format.ts
|
|
310
|
+
import pc from "picocolors";
|
|
311
|
+
var themeDim = (value) => ink3(value);
|
|
312
|
+
var themeFaint = (value) => ink4(value);
|
|
313
|
+
function truncate(value, width) {
|
|
314
|
+
if (value.length <= width)
|
|
315
|
+
return value;
|
|
316
|
+
if (width <= 1)
|
|
317
|
+
return "\u2026";
|
|
318
|
+
return `${value.slice(0, width - 1)}\u2026`;
|
|
319
|
+
}
|
|
320
|
+
function pad(value, width) {
|
|
321
|
+
return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
|
|
322
|
+
}
|
|
323
|
+
function statusColor(status) {
|
|
324
|
+
const normalized = status.toLowerCase();
|
|
325
|
+
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved", "running"].includes(normalized))
|
|
326
|
+
return accent;
|
|
327
|
+
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
328
|
+
return red;
|
|
329
|
+
if (["reviewing", "validating", "in_progress", "in-progress", "remote", "preparing", "closing-out"].includes(normalized))
|
|
330
|
+
return cyan;
|
|
331
|
+
if (["ready", "open", "queued", "created", "local", "pending"].includes(normalized))
|
|
332
|
+
return yellow;
|
|
333
|
+
return themeDim;
|
|
334
|
+
}
|
|
335
|
+
function formatStatusPill(status) {
|
|
336
|
+
const label = status || "unknown";
|
|
337
|
+
return statusColor(label)(`\u25CF ${label}`);
|
|
338
|
+
}
|
|
339
|
+
function formatSection(title, subtitle) {
|
|
340
|
+
return `${pc.bold(accent("\u25C6"))} ${pc.bold(title)}${subtitle ? themeDim(` \u2014 ${subtitle}`) : ""}`;
|
|
341
|
+
}
|
|
342
|
+
function formatSuccessCard(title, rows = []) {
|
|
343
|
+
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${themeFaint("\u2502")} ${themeDim(key.padEnd(12))} ${value}`);
|
|
344
|
+
return [formatSection(title), ...body].join(`
|
|
345
|
+
`);
|
|
346
|
+
}
|
|
347
|
+
function formatNextSteps(steps) {
|
|
348
|
+
if (steps.length === 0)
|
|
349
|
+
return [];
|
|
350
|
+
return [pc.bold("Next"), ...steps.map((step) => `${accent("\u203A")} ${step}`)];
|
|
351
|
+
}
|
|
352
|
+
function formatConnectionList(connections) {
|
|
353
|
+
const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
|
|
354
|
+
const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
|
|
355
|
+
const lines = rows.map(([alias, connection]) => [
|
|
356
|
+
pc.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
|
|
357
|
+
formatStatusPill(connection.kind),
|
|
358
|
+
connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
|
|
359
|
+
].join(" "));
|
|
360
|
+
return [formatSection("Rig servers", `${rows.length} available`), `${pc.bold(pad("ALIAS", aliasWidth))} ${pc.bold("KIND")} ${pc.bold("TARGET")}`, ...lines, "", ...formatNextSteps(["Select one: `rig server use <alias|local>`"])].join(`
|
|
361
|
+
`);
|
|
362
|
+
}
|
|
363
|
+
function formatConnectionStatus(selected, connections) {
|
|
364
|
+
const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
|
|
365
|
+
const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
|
|
366
|
+
return [
|
|
367
|
+
formatSection("Rig server", "selected for this repo"),
|
|
368
|
+
`${themeFaint("\u2502")} ${themeDim("selected ")} ${pc.bold(selected)}`,
|
|
369
|
+
`${themeFaint("\u2502")} ${themeDim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
|
|
370
|
+
`${themeFaint("\u2502")} ${themeDim("target ")} ${target ?? "not configured"}`,
|
|
371
|
+
"",
|
|
372
|
+
...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
|
|
373
|
+
].join(`
|
|
374
|
+
`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// packages/cli/src/commands/connect.ts
|
|
378
|
+
function usageName(options) {
|
|
379
|
+
return `rig ${options.group}`;
|
|
380
|
+
}
|
|
381
|
+
function parseConnection(alias, value, options) {
|
|
382
|
+
if (alias === "local" && !value)
|
|
383
|
+
return { kind: "local", mode: "auto" };
|
|
384
|
+
if (!value)
|
|
385
|
+
throw new CliError(`Missing remote server URL. Usage: ${usageName(options)} add <alias> <url>`, 1);
|
|
386
|
+
let parsed;
|
|
387
|
+
try {
|
|
388
|
+
parsed = new URL(value);
|
|
389
|
+
} catch {
|
|
390
|
+
throw new CliError(`Invalid Rig server URL: ${value}`, 1, { hint: "Pass a full http(s) URL, e.g. `rig server add prod https://rig.example.com`." });
|
|
391
|
+
}
|
|
392
|
+
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
393
|
+
throw new CliError("Rig remote server URL must be http(s).", 1, { hint: "Use an http:// or https:// URL, e.g. `rig server add prod https://rig.example.com`." });
|
|
394
|
+
}
|
|
395
|
+
return { kind: "remote", baseUrl: parsed.toString().replace(/\/+$/, "") };
|
|
396
|
+
}
|
|
397
|
+
function printJsonOrText(context, payload, text) {
|
|
398
|
+
if (context.outputMode === "json") {
|
|
399
|
+
console.log(JSON.stringify(payload, null, 2));
|
|
400
|
+
} else {
|
|
401
|
+
console.log(text);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
async function promptForConnectionAlias(context) {
|
|
405
|
+
const state = readGlobalConnections();
|
|
406
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
407
|
+
const options = [
|
|
408
|
+
{ value: "local", label: "local", hint: "Use/start a local Rig server" },
|
|
409
|
+
...Object.entries(state.connections).map(([alias, connection]) => ({
|
|
410
|
+
value: alias,
|
|
411
|
+
label: alias,
|
|
412
|
+
hint: connection.kind === "remote" ? connection.baseUrl : "local"
|
|
413
|
+
}))
|
|
414
|
+
].filter((option, index, all) => all.findIndex((candidate) => candidate.value === option.value) === index);
|
|
415
|
+
const answer = await droneSelect({
|
|
416
|
+
message: "Select Rig server for this repo",
|
|
417
|
+
initialValue: repo?.selected ?? "local",
|
|
418
|
+
options
|
|
419
|
+
});
|
|
420
|
+
if (answer === null) {
|
|
421
|
+
droneCancel("No server selected.");
|
|
422
|
+
throw new CliError("No server selected.", 3);
|
|
423
|
+
}
|
|
424
|
+
return String(answer);
|
|
425
|
+
}
|
|
426
|
+
async function executeConnectionCommand(context, args, options) {
|
|
427
|
+
const [command, ...rest] = args;
|
|
428
|
+
switch (command ?? "status") {
|
|
429
|
+
case "list": {
|
|
430
|
+
requireNoExtraArgs(rest, `${usageName(options)} list`);
|
|
431
|
+
const state = readGlobalConnections();
|
|
432
|
+
printJsonOrText(context, state, formatConnectionList(state.connections));
|
|
433
|
+
return { ok: true, group: options.group, command: "list", details: state };
|
|
434
|
+
}
|
|
435
|
+
case "add": {
|
|
436
|
+
const [alias, url, ...extra] = rest;
|
|
437
|
+
if (!alias)
|
|
438
|
+
throw new CliError(`Missing alias. Usage: ${usageName(options)} add <alias> <url>`, 1);
|
|
439
|
+
requireNoExtraArgs(extra, `${usageName(options)} add <alias> <url>`);
|
|
440
|
+
const connection = parseConnection(alias, url, options);
|
|
441
|
+
const state = upsertGlobalConnection(alias, connection);
|
|
442
|
+
printJsonOrText(context, { alias, connection }, formatSuccessCard("Rig server saved", [
|
|
443
|
+
["alias", alias],
|
|
444
|
+
["target", connection.kind === "remote" ? connection.baseUrl : "local"],
|
|
445
|
+
["next", `${usageName(options)} use ${alias}`]
|
|
446
|
+
]));
|
|
447
|
+
return { ok: true, group: options.group, command: "add", details: { alias, connection, count: Object.keys(state.connections).length } };
|
|
448
|
+
}
|
|
449
|
+
case "use": {
|
|
450
|
+
let [alias, ...extra] = rest;
|
|
451
|
+
requireNoExtraArgs(extra, `${usageName(options)} use <alias|local>`);
|
|
452
|
+
if (!alias && options.interactiveUse && context.outputMode === "text" && process.stdin.isTTY) {
|
|
453
|
+
alias = await promptForConnectionAlias(context);
|
|
454
|
+
}
|
|
455
|
+
if (!alias)
|
|
456
|
+
throw new CliError(`Missing alias. Usage: ${usageName(options)} use <alias|local>`, 1);
|
|
457
|
+
if (alias !== "local") {
|
|
458
|
+
const state = readGlobalConnections();
|
|
459
|
+
if (!state.connections[alias])
|
|
460
|
+
throw new CliError(`Unknown Rig server: ${alias}`, 1, { hint: "Run `rig server list` to see saved aliases, or save one with `rig server add <alias> <url>`." });
|
|
461
|
+
}
|
|
462
|
+
const repoState = { selected: alias, linkedAt: new Date().toISOString() };
|
|
463
|
+
writeRepoConnection(context.projectRoot, repoState);
|
|
464
|
+
printJsonOrText(context, repoState, formatSuccessCard("Rig server selected", [
|
|
465
|
+
["selected", alias],
|
|
466
|
+
["scope", "this repo"],
|
|
467
|
+
["next", "rig task list"]
|
|
468
|
+
]));
|
|
469
|
+
return { ok: true, group: options.group, command: "use", details: repoState };
|
|
470
|
+
}
|
|
471
|
+
case "status": {
|
|
472
|
+
requireNoExtraArgs(rest, `${usageName(options)} status`);
|
|
473
|
+
const repo = readRepoConnection(context.projectRoot);
|
|
474
|
+
const global = readGlobalConnections();
|
|
475
|
+
const details = { selected: repo?.selected ?? "local", repo, connections: global.connections };
|
|
476
|
+
printJsonOrText(context, details, formatConnectionStatus(details.selected, global.connections));
|
|
477
|
+
return { ok: true, group: options.group, command: "status", details };
|
|
478
|
+
}
|
|
479
|
+
default:
|
|
480
|
+
throw new CliError(`Unknown ${options.group} command: ${String(command)}
|
|
481
|
+
Usage: ${usageName(options)} <list|add|use|status>`, 1);
|
|
147
482
|
}
|
|
148
|
-
return { alias: repo.selected, connection };
|
|
149
483
|
}
|
|
150
484
|
|
|
151
485
|
// packages/cli/src/commands/_server-client.ts
|
|
152
|
-
|
|
486
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
487
|
+
import { resolve as resolve2 } from "path";
|
|
488
|
+
import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
|
|
489
|
+
var scopedGitHubBearerTokens = new Map;
|
|
490
|
+
var serverPhaseListener = null;
|
|
491
|
+
function reportServerPhase(label) {
|
|
492
|
+
serverPhaseListener?.(label);
|
|
493
|
+
}
|
|
153
494
|
function cleanToken(value) {
|
|
154
495
|
const trimmed = value?.trim();
|
|
155
496
|
return trimmed ? trimmed : null;
|
|
@@ -166,49 +507,80 @@ function readPrivateRemoteSessionToken(projectRoot) {
|
|
|
166
507
|
}
|
|
167
508
|
}
|
|
168
509
|
function readGitHubBearerTokenForRemote(projectRoot) {
|
|
169
|
-
|
|
170
|
-
|
|
510
|
+
const scopedKey = resolve2(projectRoot);
|
|
511
|
+
if (scopedGitHubBearerTokens.has(scopedKey))
|
|
512
|
+
return scopedGitHubBearerTokens.get(scopedKey) ?? null;
|
|
171
513
|
const privateSession = readPrivateRemoteSessionToken(projectRoot);
|
|
172
|
-
if (privateSession)
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return
|
|
514
|
+
if (privateSession)
|
|
515
|
+
return privateSession;
|
|
516
|
+
return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
|
|
517
|
+
}
|
|
518
|
+
function readStoredGitHubAuthToken(projectRoot) {
|
|
519
|
+
const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
|
|
520
|
+
if (!existsSync2(path))
|
|
521
|
+
return null;
|
|
522
|
+
try {
|
|
523
|
+
const parsed = JSON.parse(readFileSync2(path, "utf8"));
|
|
524
|
+
return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
|
|
525
|
+
} catch {
|
|
526
|
+
return null;
|
|
180
527
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
185
|
-
});
|
|
186
|
-
cachedGitHubBearerToken = result.status === 0 ? cleanToken(result.stdout) : null;
|
|
187
|
-
return cachedGitHubBearerToken;
|
|
528
|
+
}
|
|
529
|
+
function readLocalConnectionFallbackToken(projectRoot) {
|
|
530
|
+
return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
|
|
188
531
|
}
|
|
189
532
|
async function ensureServerForCli(projectRoot) {
|
|
190
533
|
try {
|
|
191
534
|
const selected = resolveSelectedConnection(projectRoot);
|
|
192
535
|
if (selected?.connection.kind === "remote") {
|
|
536
|
+
reportServerPhase(`Connecting to ${selected.alias}\u2026`);
|
|
537
|
+
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
538
|
+
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
193
539
|
return {
|
|
194
540
|
baseUrl: selected.connection.baseUrl,
|
|
195
|
-
authToken
|
|
196
|
-
connectionKind: "remote"
|
|
541
|
+
authToken,
|
|
542
|
+
connectionKind: "remote",
|
|
543
|
+
serverProjectRoot
|
|
197
544
|
};
|
|
198
545
|
}
|
|
546
|
+
reportServerPhase("Starting local Rig server\u2026");
|
|
199
547
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
200
548
|
return {
|
|
201
549
|
baseUrl: connection.baseUrl,
|
|
202
|
-
authToken: connection.authToken,
|
|
203
|
-
connectionKind: "local"
|
|
550
|
+
authToken: connection.authToken ?? readLocalConnectionFallbackToken(projectRoot),
|
|
551
|
+
connectionKind: "local",
|
|
552
|
+
serverProjectRoot: resolve2(projectRoot)
|
|
204
553
|
};
|
|
205
554
|
} catch (error) {
|
|
206
555
|
if (error instanceof Error) {
|
|
207
|
-
throw new
|
|
556
|
+
throw new CliError(error.message, 1);
|
|
208
557
|
}
|
|
209
558
|
throw error;
|
|
210
559
|
}
|
|
211
560
|
}
|
|
561
|
+
async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
|
|
562
|
+
const repo = readRepoConnection(projectRoot);
|
|
563
|
+
const slug = repo?.project?.trim();
|
|
564
|
+
if (!slug)
|
|
565
|
+
return null;
|
|
566
|
+
try {
|
|
567
|
+
const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
|
|
568
|
+
headers: mergeHeaders(undefined, authToken)
|
|
569
|
+
});
|
|
570
|
+
if (!response.ok)
|
|
571
|
+
return null;
|
|
572
|
+
const payload = await response.json();
|
|
573
|
+
const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
|
|
574
|
+
const checkouts = Array.isArray(project?.checkouts) ? project.checkouts : [];
|
|
575
|
+
const latestCheckout = [...checkouts].reverse().find((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.path === "string"));
|
|
576
|
+
const path = typeof latestCheckout?.path === "string" && latestCheckout.path.trim() ? latestCheckout.path.trim() : null;
|
|
577
|
+
if (path)
|
|
578
|
+
writeRepoServerProjectRoot(projectRoot, path);
|
|
579
|
+
return path;
|
|
580
|
+
} catch {
|
|
581
|
+
return null;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
212
584
|
function mergeHeaders(headers, authToken) {
|
|
213
585
|
const merged = new Headers(headers);
|
|
214
586
|
if (authToken) {
|
|
@@ -231,12 +603,65 @@ function diagnosticMessage(payload) {
|
|
|
231
603
|
});
|
|
232
604
|
return messages.length > 0 ? messages.join("; ") : null;
|
|
233
605
|
}
|
|
606
|
+
var serverReachabilityCache = new Map;
|
|
607
|
+
async function probeServerReachability(baseUrl, authToken) {
|
|
608
|
+
try {
|
|
609
|
+
const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/server/status`, {
|
|
610
|
+
headers: mergeHeaders(undefined, authToken),
|
|
611
|
+
signal: AbortSignal.timeout(1500)
|
|
612
|
+
});
|
|
613
|
+
return response.ok;
|
|
614
|
+
} catch {
|
|
615
|
+
return false;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
function cachedServerReachability(projectRoot, baseUrl, authToken) {
|
|
619
|
+
const key = resolve2(projectRoot);
|
|
620
|
+
const cached = serverReachabilityCache.get(key);
|
|
621
|
+
if (cached)
|
|
622
|
+
return cached;
|
|
623
|
+
const probe = probeServerReachability(baseUrl, authToken);
|
|
624
|
+
serverReachabilityCache.set(key, probe);
|
|
625
|
+
return probe;
|
|
626
|
+
}
|
|
627
|
+
function describeSelectedServer(projectRoot, server) {
|
|
628
|
+
try {
|
|
629
|
+
const selected = resolveSelectedConnection(projectRoot);
|
|
630
|
+
if (selected) {
|
|
631
|
+
return {
|
|
632
|
+
alias: selected.alias,
|
|
633
|
+
target: selected.connection.kind === "remote" ? selected.connection.baseUrl : server.baseUrl
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
} catch {}
|
|
637
|
+
return { alias: server.connectionKind === "remote" ? "remote" : "local", target: server.baseUrl };
|
|
638
|
+
}
|
|
639
|
+
async function buildServerFailureContext(projectRoot, server) {
|
|
640
|
+
const { alias, target } = describeSelectedServer(projectRoot, server);
|
|
641
|
+
const reachable = await cachedServerReachability(projectRoot, server.baseUrl, server.authToken);
|
|
642
|
+
const reachability = reachable ? "server is reachable" : "server is unreachable";
|
|
643
|
+
return {
|
|
644
|
+
contextLine: `Currently connected to: ${alias} at ${target} (${reachability}).`,
|
|
645
|
+
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
646
|
+
};
|
|
647
|
+
}
|
|
234
648
|
async function requestServerJson(context, pathname, init = {}) {
|
|
235
649
|
const server = await ensureServerForCli(context.projectRoot);
|
|
236
|
-
const
|
|
237
|
-
|
|
238
|
-
headers
|
|
239
|
-
});
|
|
650
|
+
const headers = mergeHeaders(init.headers, server.authToken);
|
|
651
|
+
if (server.serverProjectRoot)
|
|
652
|
+
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
653
|
+
reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
|
|
654
|
+
let response;
|
|
655
|
+
try {
|
|
656
|
+
response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
657
|
+
...init,
|
|
658
|
+
headers
|
|
659
|
+
});
|
|
660
|
+
} catch (error) {
|
|
661
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
662
|
+
throw new CliError(`Rig server request failed: ${error instanceof Error ? error.message : String(error)}
|
|
663
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
664
|
+
}
|
|
240
665
|
const text = await response.text();
|
|
241
666
|
const payload = text.trim().length > 0 ? (() => {
|
|
242
667
|
try {
|
|
@@ -247,11 +672,26 @@ async function requestServerJson(context, pathname, init = {}) {
|
|
|
247
672
|
})() : null;
|
|
248
673
|
if (!response.ok) {
|
|
249
674
|
const diagnostics = diagnosticMessage(payload);
|
|
250
|
-
const
|
|
251
|
-
|
|
675
|
+
const rawDetail = diagnostics ?? (text || response.statusText);
|
|
676
|
+
const detail = diagnostics ? rawDetail : rawDetail.split(`
|
|
677
|
+
`).map((line) => line.trim()).find((line) => line.length > 0)?.slice(0, 200) ?? response.statusText;
|
|
678
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
679
|
+
throw new CliError(`Rig server request failed (${response.status}): ${detail}
|
|
680
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
252
681
|
}
|
|
253
682
|
return payload;
|
|
254
683
|
}
|
|
684
|
+
var RESUMABLE_RUN_STATUSES = new Set([
|
|
685
|
+
"created",
|
|
686
|
+
"preparing",
|
|
687
|
+
"running",
|
|
688
|
+
"validating",
|
|
689
|
+
"reviewing",
|
|
690
|
+
"stopped",
|
|
691
|
+
"failed",
|
|
692
|
+
"needs-attention",
|
|
693
|
+
"needs_attention"
|
|
694
|
+
]);
|
|
255
695
|
async function submitTaskRunViaServer(context, input) {
|
|
256
696
|
const isTaskRun = Boolean(input.taskId);
|
|
257
697
|
const endpoint = isTaskRun ? "/api/runs/task" : "/api/runs/adhoc";
|
|
@@ -275,18 +715,21 @@ async function submitTaskRunViaServer(context, input) {
|
|
|
275
715
|
})
|
|
276
716
|
});
|
|
277
717
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
278
|
-
throw new
|
|
718
|
+
throw new CliError("Rig server returned an invalid run submission payload.", 1, { hint: "Check `rig server status` and retry; `rig run list` shows whether the run was created anyway." });
|
|
279
719
|
}
|
|
280
720
|
const runId = payload.runId;
|
|
281
721
|
if (typeof runId !== "string" || runId.trim().length === 0) {
|
|
282
|
-
throw new
|
|
722
|
+
throw new CliError("Rig server returned no runId for the submitted run.", 1, { hint: "Check `rig run list` \u2014 the run may still have been created; otherwise retry the submission." });
|
|
283
723
|
}
|
|
284
724
|
return { runId };
|
|
285
725
|
}
|
|
286
726
|
|
|
287
727
|
// packages/cli/src/commands/server.ts
|
|
288
728
|
async function executeServer(context, args, options) {
|
|
289
|
-
const [command = "
|
|
729
|
+
const [command = "status", ...rest] = args;
|
|
730
|
+
if (["status", "list", "add", "use"].includes(command)) {
|
|
731
|
+
return executeConnectionCommand(context, [command, ...rest], { group: "server", interactiveUse: true });
|
|
732
|
+
}
|
|
290
733
|
switch (command) {
|
|
291
734
|
case "start": {
|
|
292
735
|
let pending = rest;
|
|
@@ -298,8 +741,9 @@ async function executeServer(context, args, options) {
|
|
|
298
741
|
pending = pollResult.rest;
|
|
299
742
|
const authTokenResult = takeOption(pending, "--auth-token");
|
|
300
743
|
pending = authTokenResult.rest;
|
|
301
|
-
requireNoExtraArgs(pending, "
|
|
302
|
-
const
|
|
744
|
+
requireNoExtraArgs(pending, "rig server start [--host <host>] [--port <n>] [--poll-ms <n>] [--auth-token <token>]");
|
|
745
|
+
const serverCommand = resolveRigServerCommand(context.projectRoot);
|
|
746
|
+
const commandParts = [serverCommand.command, ...serverCommand.commandArgs, "start"];
|
|
303
747
|
if (hostResult.value) {
|
|
304
748
|
commandParts.push("--host", hostResult.value);
|
|
305
749
|
}
|
|
@@ -316,13 +760,14 @@ async function executeServer(context, args, options) {
|
|
|
316
760
|
return { ok: true, group: "server", command };
|
|
317
761
|
}
|
|
318
762
|
case "events":
|
|
319
|
-
throw new
|
|
763
|
+
throw new CliError("server events is not supported by the CLI wrapper. Use `rig inspector stream` for bounded event streaming, or start the server with `rig server start`.", 2);
|
|
320
764
|
case "notify-test": {
|
|
321
765
|
let pending = rest;
|
|
322
766
|
const eventResult = takeOption(pending, "--event");
|
|
323
767
|
pending = eventResult.rest;
|
|
324
|
-
requireNoExtraArgs(pending, "
|
|
325
|
-
const
|
|
768
|
+
requireNoExtraArgs(pending, "rig server notify-test [--event <type>]");
|
|
769
|
+
const serverCommand = resolveRigServerCommand(context.projectRoot);
|
|
770
|
+
const commandParts = [serverCommand.command, ...serverCommand.commandArgs, "notify-test"];
|
|
326
771
|
if (eventResult.value) {
|
|
327
772
|
commandParts.push("--event", eventResult.value);
|
|
328
773
|
}
|
|
@@ -349,9 +794,9 @@ async function executeServer(context, args, options) {
|
|
|
349
794
|
pending = dirtyBaselineResult.rest;
|
|
350
795
|
const prResult = takeOption(pending, "--pr");
|
|
351
796
|
pending = prResult.rest;
|
|
352
|
-
requireNoExtraArgs(pending, "
|
|
797
|
+
requireNoExtraArgs(pending, "rig --run-id <run-id> server task-run [--task <id>] [--title <text>] [--runtime-adapter claude-code|codex|pi] [--model <model>] [--runtime-mode <mode>] [--interaction-mode <mode>] [--initial-prompt <text>] [--dirty-baseline head|dirty-snapshot] [--pr auto|ask|off]");
|
|
353
798
|
if (!taskResult.value && !initialPromptResult.value && !titleResult.value) {
|
|
354
|
-
throw new
|
|
799
|
+
throw new CliError("server task-run requires either --task <id> or --initial-prompt/--title for an ad hoc run.", 2);
|
|
355
800
|
}
|
|
356
801
|
const input = {
|
|
357
802
|
runId: context.runId,
|
|
@@ -378,7 +823,7 @@ async function executeServer(context, args, options) {
|
|
|
378
823
|
};
|
|
379
824
|
}
|
|
380
825
|
default:
|
|
381
|
-
throw new
|
|
826
|
+
throw new CliError(`Unknown server command: ${command}`, 1, { hint: "Run `rig server --help` \u2014 primary commands are status|list|add|use|start." });
|
|
382
827
|
}
|
|
383
828
|
}
|
|
384
829
|
export {
|