@h-rig/cli 0.0.6-alpha.64 → 0.0.6-alpha.66
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 +1349 -1599
- package/dist/src/commands/_connection-state.js +14 -5
- package/dist/src/commands/_doctor-checks.js +71 -11
- package/dist/src/commands/_help-catalog.js +99 -60
- package/dist/src/commands/_json-output.js +56 -0
- package/dist/src/commands/_operator-view.js +97 -784
- package/dist/src/commands/_parsers.js +18 -9
- package/dist/src/commands/_pi-frontend.js +96 -788
- package/dist/src/commands/_policy.js +12 -3
- package/dist/src/commands/_preflight.js +73 -13
- package/dist/src/commands/_run-driver-helpers.js +31 -5
- package/dist/src/commands/_run-replay.js +2 -2
- package/dist/src/commands/_server-client.js +76 -16
- package/dist/src/commands/_snapshot-upload.js +70 -10
- package/dist/src/commands/agent.js +21 -11
- package/dist/src/commands/browser.js +24 -15
- package/dist/src/commands/connect.js +22 -17
- package/dist/src/commands/dist.js +15 -6
- package/dist/src/commands/doctor.js +70 -10
- package/dist/src/commands/github.js +79 -19
- package/dist/src/commands/inbox.js +215 -131
- package/dist/src/commands/init.js +202 -35
- package/dist/src/commands/inspect.js +77 -17
- package/dist/src/commands/inspector.js +18 -9
- package/dist/src/commands/pi.js +18 -9
- package/dist/src/commands/plugin.js +19 -10
- package/dist/src/commands/profile-and-review.js +22 -13
- package/dist/src/commands/queue.js +19 -9
- package/dist/src/commands/remote.js +25 -16
- package/dist/src/commands/repo-git-harness.js +18 -9
- package/dist/src/commands/run.js +158 -805
- package/dist/src/commands/server.js +85 -25
- package/dist/src/commands/setup.js +73 -13
- package/dist/src/commands/stats.js +681 -0
- package/dist/src/commands/task-report-bug.js +24 -15
- package/dist/src/commands/task-run-driver.js +121 -49
- package/dist/src/commands/task.js +254 -893
- package/dist/src/commands/test.js +12 -3
- package/dist/src/commands/workspace.js +14 -5
- package/dist/src/commands.js +1339 -1650
- package/dist/src/index.js +1349 -1599
- package/dist/src/launcher.js +72 -10
- package/dist/src/runner.js +14 -5
- package/package.json +10 -7
- package/dist/src/commands/_pi-remote-session.js +0 -771
- package/dist/src/commands/_pi-worker-bridge-extension.js +0 -834
|
@@ -1,10 +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
6
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
7
|
-
|
|
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
|
+
}
|
|
8
17
|
function takeOption(args, option) {
|
|
9
18
|
const rest = [];
|
|
10
19
|
let value;
|
|
@@ -13,7 +22,7 @@ function takeOption(args, option) {
|
|
|
13
22
|
if (current === option) {
|
|
14
23
|
const next = args[index + 1];
|
|
15
24
|
if (!next || next.startsWith("-")) {
|
|
16
|
-
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>\`.` });
|
|
17
26
|
}
|
|
18
27
|
value = next;
|
|
19
28
|
index += 1;
|
|
@@ -85,7 +94,7 @@ function readJsonFile(path) {
|
|
|
85
94
|
try {
|
|
86
95
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
87
96
|
} catch (error) {
|
|
88
|
-
throw new
|
|
97
|
+
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>`." });
|
|
89
98
|
}
|
|
90
99
|
}
|
|
91
100
|
function writeJsonFile(path, value) {
|
|
@@ -128,7 +137,7 @@ function writeGlobalConnections(state, options = {}) {
|
|
|
128
137
|
function upsertGlobalConnection(alias, connection, options = {}) {
|
|
129
138
|
const cleanAlias = alias.trim();
|
|
130
139
|
if (!cleanAlias)
|
|
131
|
-
throw new
|
|
140
|
+
throw new CliError("Connection alias is required.", 1, { hint: "Save a server with `rig server add <alias> <url>`." });
|
|
132
141
|
const state = readGlobalConnections(options);
|
|
133
142
|
state.connections[cleanAlias] = connection;
|
|
134
143
|
writeGlobalConnections(state, options);
|
|
@@ -161,7 +170,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
161
170
|
const global = readGlobalConnections(options);
|
|
162
171
|
const connection = global.connections[repo.selected];
|
|
163
172
|
if (!connection) {
|
|
164
|
-
throw new
|
|
173
|
+
throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
165
174
|
}
|
|
166
175
|
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
167
176
|
}
|
|
@@ -247,15 +256,15 @@ function parseConnection(alias, value, options) {
|
|
|
247
256
|
if (alias === "local" && !value)
|
|
248
257
|
return { kind: "local", mode: "auto" };
|
|
249
258
|
if (!value)
|
|
250
|
-
throw new
|
|
259
|
+
throw new CliError(`Missing remote server URL. Usage: ${usageName(options)} add <alias> <url>`, 1);
|
|
251
260
|
let parsed;
|
|
252
261
|
try {
|
|
253
262
|
parsed = new URL(value);
|
|
254
263
|
} catch {
|
|
255
|
-
throw new
|
|
264
|
+
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`." });
|
|
256
265
|
}
|
|
257
266
|
if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
|
|
258
|
-
throw new
|
|
267
|
+
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`." });
|
|
259
268
|
}
|
|
260
269
|
return { kind: "remote", baseUrl: parsed.toString().replace(/\/+$/, "") };
|
|
261
270
|
}
|
|
@@ -284,7 +293,7 @@ async function promptForConnectionAlias(context) {
|
|
|
284
293
|
});
|
|
285
294
|
if (isCancel(answer)) {
|
|
286
295
|
cancel("No server selected.");
|
|
287
|
-
throw new
|
|
296
|
+
throw new CliError("No server selected.", 3);
|
|
288
297
|
}
|
|
289
298
|
return String(answer);
|
|
290
299
|
}
|
|
@@ -300,7 +309,7 @@ async function executeConnectionCommand(context, args, options) {
|
|
|
300
309
|
case "add": {
|
|
301
310
|
const [alias, url, ...extra] = rest;
|
|
302
311
|
if (!alias)
|
|
303
|
-
throw new
|
|
312
|
+
throw new CliError(`Missing alias. Usage: ${usageName(options)} add <alias> <url>`, 1);
|
|
304
313
|
requireNoExtraArgs(extra, `${usageName(options)} add <alias> <url>`);
|
|
305
314
|
const connection = parseConnection(alias, url, options);
|
|
306
315
|
const state = upsertGlobalConnection(alias, connection);
|
|
@@ -318,11 +327,11 @@ async function executeConnectionCommand(context, args, options) {
|
|
|
318
327
|
alias = await promptForConnectionAlias(context);
|
|
319
328
|
}
|
|
320
329
|
if (!alias)
|
|
321
|
-
throw new
|
|
330
|
+
throw new CliError(`Missing alias. Usage: ${usageName(options)} use <alias|local>`, 1);
|
|
322
331
|
if (alias !== "local") {
|
|
323
332
|
const state = readGlobalConnections();
|
|
324
333
|
if (!state.connections[alias])
|
|
325
|
-
throw new
|
|
334
|
+
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>`." });
|
|
326
335
|
}
|
|
327
336
|
const repoState = { selected: alias, linkedAt: new Date().toISOString() };
|
|
328
337
|
writeRepoConnection(context.projectRoot, repoState);
|
|
@@ -342,7 +351,7 @@ async function executeConnectionCommand(context, args, options) {
|
|
|
342
351
|
return { ok: true, group: options.group, command: "status", details };
|
|
343
352
|
}
|
|
344
353
|
default:
|
|
345
|
-
throw new
|
|
354
|
+
throw new CliError(`Unknown ${options.group} command: ${String(command)}
|
|
346
355
|
Usage: ${usageName(options)} <list|add|use|status>`, 1);
|
|
347
356
|
}
|
|
348
357
|
}
|
|
@@ -412,7 +421,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
412
421
|
};
|
|
413
422
|
} catch (error) {
|
|
414
423
|
if (error instanceof Error) {
|
|
415
|
-
throw new
|
|
424
|
+
throw new CliError(error.message, 1);
|
|
416
425
|
}
|
|
417
426
|
throw error;
|
|
418
427
|
}
|
|
@@ -462,15 +471,64 @@ function diagnosticMessage(payload) {
|
|
|
462
471
|
});
|
|
463
472
|
return messages.length > 0 ? messages.join("; ") : null;
|
|
464
473
|
}
|
|
474
|
+
var serverReachabilityCache = new Map;
|
|
475
|
+
async function probeServerReachability(baseUrl, authToken) {
|
|
476
|
+
try {
|
|
477
|
+
const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/server/status`, {
|
|
478
|
+
headers: mergeHeaders(undefined, authToken),
|
|
479
|
+
signal: AbortSignal.timeout(1500)
|
|
480
|
+
});
|
|
481
|
+
return response.ok;
|
|
482
|
+
} catch {
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function cachedServerReachability(projectRoot, baseUrl, authToken) {
|
|
487
|
+
const key = resolve2(projectRoot);
|
|
488
|
+
const cached = serverReachabilityCache.get(key);
|
|
489
|
+
if (cached)
|
|
490
|
+
return cached;
|
|
491
|
+
const probe = probeServerReachability(baseUrl, authToken);
|
|
492
|
+
serverReachabilityCache.set(key, probe);
|
|
493
|
+
return probe;
|
|
494
|
+
}
|
|
495
|
+
function describeSelectedServer(projectRoot, server) {
|
|
496
|
+
try {
|
|
497
|
+
const selected = resolveSelectedConnection(projectRoot);
|
|
498
|
+
if (selected) {
|
|
499
|
+
return {
|
|
500
|
+
alias: selected.alias,
|
|
501
|
+
target: selected.connection.kind === "remote" ? selected.connection.baseUrl : server.baseUrl
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
} catch {}
|
|
505
|
+
return { alias: server.connectionKind === "remote" ? "remote" : "local", target: server.baseUrl };
|
|
506
|
+
}
|
|
507
|
+
async function buildServerFailureContext(projectRoot, server) {
|
|
508
|
+
const { alias, target } = describeSelectedServer(projectRoot, server);
|
|
509
|
+
const reachable = await cachedServerReachability(projectRoot, server.baseUrl, server.authToken);
|
|
510
|
+
const reachability = reachable ? "server is reachable" : "server is unreachable";
|
|
511
|
+
return {
|
|
512
|
+
contextLine: `Currently connected to: ${alias} at ${target} (${reachability}).`,
|
|
513
|
+
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
514
|
+
};
|
|
515
|
+
}
|
|
465
516
|
async function requestServerJson(context, pathname, init = {}) {
|
|
466
517
|
const server = await ensureServerForCli(context.projectRoot);
|
|
467
518
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
468
519
|
if (server.serverProjectRoot)
|
|
469
520
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
521
|
+
let response;
|
|
522
|
+
try {
|
|
523
|
+
response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
524
|
+
...init,
|
|
525
|
+
headers
|
|
526
|
+
});
|
|
527
|
+
} catch (error) {
|
|
528
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
529
|
+
throw new CliError(`Rig server request failed: ${error instanceof Error ? error.message : String(error)}
|
|
530
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
531
|
+
}
|
|
474
532
|
const text = await response.text();
|
|
475
533
|
const payload = text.trim().length > 0 ? (() => {
|
|
476
534
|
try {
|
|
@@ -482,7 +540,9 @@ async function requestServerJson(context, pathname, init = {}) {
|
|
|
482
540
|
if (!response.ok) {
|
|
483
541
|
const diagnostics = diagnosticMessage(payload);
|
|
484
542
|
const detail = diagnostics ?? (text || response.statusText);
|
|
485
|
-
|
|
543
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
544
|
+
throw new CliError(`Rig server request failed (${response.status}): ${detail}
|
|
545
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
486
546
|
}
|
|
487
547
|
return payload;
|
|
488
548
|
}
|
|
@@ -509,11 +569,11 @@ async function submitTaskRunViaServer(context, input) {
|
|
|
509
569
|
})
|
|
510
570
|
});
|
|
511
571
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
512
|
-
throw new
|
|
572
|
+
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." });
|
|
513
573
|
}
|
|
514
574
|
const runId = payload.runId;
|
|
515
575
|
if (typeof runId !== "string" || runId.trim().length === 0) {
|
|
516
|
-
throw new
|
|
576
|
+
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." });
|
|
517
577
|
}
|
|
518
578
|
return { runId };
|
|
519
579
|
}
|
|
@@ -554,7 +614,7 @@ async function executeServer(context, args, options) {
|
|
|
554
614
|
return { ok: true, group: "server", command };
|
|
555
615
|
}
|
|
556
616
|
case "events":
|
|
557
|
-
throw new
|
|
617
|
+
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);
|
|
558
618
|
case "notify-test": {
|
|
559
619
|
let pending = rest;
|
|
560
620
|
const eventResult = takeOption(pending, "--event");
|
|
@@ -590,7 +650,7 @@ async function executeServer(context, args, options) {
|
|
|
590
650
|
pending = prResult.rest;
|
|
591
651
|
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]");
|
|
592
652
|
if (!taskResult.value && !initialPromptResult.value && !titleResult.value) {
|
|
593
|
-
throw new
|
|
653
|
+
throw new CliError("server task-run requires either --task <id> or --initial-prompt/--title for an ad hoc run.", 2);
|
|
594
654
|
}
|
|
595
655
|
const input = {
|
|
596
656
|
runId: context.runId,
|
|
@@ -617,7 +677,7 @@ async function executeServer(context, args, options) {
|
|
|
617
677
|
};
|
|
618
678
|
}
|
|
619
679
|
default:
|
|
620
|
-
throw new
|
|
680
|
+
throw new CliError(`Unknown server command: ${command}`, 1, { hint: "Run `rig server --help` \u2014 primary commands are status|list|add|use|start." });
|
|
621
681
|
}
|
|
622
682
|
}
|
|
623
683
|
export {
|
|
@@ -7,10 +7,19 @@ import { resolve as resolve6 } from "path";
|
|
|
7
7
|
|
|
8
8
|
// packages/cli/src/runner.ts
|
|
9
9
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
10
|
-
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
10
|
+
import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
|
|
11
11
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
12
12
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
class CliError extends RuntimeCliError {
|
|
15
|
+
hint;
|
|
16
|
+
constructor(message, exitCode = 1, options = {}) {
|
|
17
|
+
super(message, exitCode);
|
|
18
|
+
if (options.hint?.trim()) {
|
|
19
|
+
this.hint = options.hint.trim();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
14
23
|
function requireNoExtraArgs(args, usage) {
|
|
15
24
|
if (args.length > 0) {
|
|
16
25
|
throw new CliError(`Unexpected arguments: ${args.join(" ")}
|
|
@@ -196,7 +205,7 @@ function readJsonFile(path) {
|
|
|
196
205
|
try {
|
|
197
206
|
return JSON.parse(readFileSync2(path, "utf8"));
|
|
198
207
|
} catch (error) {
|
|
199
|
-
throw new
|
|
208
|
+
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>`." });
|
|
200
209
|
}
|
|
201
210
|
}
|
|
202
211
|
function writeJsonFile(path, value) {
|
|
@@ -260,7 +269,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
260
269
|
const global = readGlobalConnections(options);
|
|
261
270
|
const connection = global.connections[repo.selected];
|
|
262
271
|
if (!connection) {
|
|
263
|
-
throw new
|
|
272
|
+
throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
264
273
|
}
|
|
265
274
|
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
266
275
|
}
|
|
@@ -336,7 +345,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
336
345
|
};
|
|
337
346
|
} catch (error) {
|
|
338
347
|
if (error instanceof Error) {
|
|
339
|
-
throw new
|
|
348
|
+
throw new CliError(error.message, 1);
|
|
340
349
|
}
|
|
341
350
|
throw error;
|
|
342
351
|
}
|
|
@@ -386,15 +395,64 @@ function diagnosticMessage(payload) {
|
|
|
386
395
|
});
|
|
387
396
|
return messages.length > 0 ? messages.join("; ") : null;
|
|
388
397
|
}
|
|
398
|
+
var serverReachabilityCache = new Map;
|
|
399
|
+
async function probeServerReachability(baseUrl, authToken) {
|
|
400
|
+
try {
|
|
401
|
+
const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/server/status`, {
|
|
402
|
+
headers: mergeHeaders(undefined, authToken),
|
|
403
|
+
signal: AbortSignal.timeout(1500)
|
|
404
|
+
});
|
|
405
|
+
return response.ok;
|
|
406
|
+
} catch {
|
|
407
|
+
return false;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
function cachedServerReachability(projectRoot, baseUrl, authToken) {
|
|
411
|
+
const key = resolve4(projectRoot);
|
|
412
|
+
const cached = serverReachabilityCache.get(key);
|
|
413
|
+
if (cached)
|
|
414
|
+
return cached;
|
|
415
|
+
const probe = probeServerReachability(baseUrl, authToken);
|
|
416
|
+
serverReachabilityCache.set(key, probe);
|
|
417
|
+
return probe;
|
|
418
|
+
}
|
|
419
|
+
function describeSelectedServer(projectRoot, server) {
|
|
420
|
+
try {
|
|
421
|
+
const selected = resolveSelectedConnection(projectRoot);
|
|
422
|
+
if (selected) {
|
|
423
|
+
return {
|
|
424
|
+
alias: selected.alias,
|
|
425
|
+
target: selected.connection.kind === "remote" ? selected.connection.baseUrl : server.baseUrl
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
} catch {}
|
|
429
|
+
return { alias: server.connectionKind === "remote" ? "remote" : "local", target: server.baseUrl };
|
|
430
|
+
}
|
|
431
|
+
async function buildServerFailureContext(projectRoot, server) {
|
|
432
|
+
const { alias, target } = describeSelectedServer(projectRoot, server);
|
|
433
|
+
const reachable = await cachedServerReachability(projectRoot, server.baseUrl, server.authToken);
|
|
434
|
+
const reachability = reachable ? "server is reachable" : "server is unreachable";
|
|
435
|
+
return {
|
|
436
|
+
contextLine: `Currently connected to: ${alias} at ${target} (${reachability}).`,
|
|
437
|
+
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
438
|
+
};
|
|
439
|
+
}
|
|
389
440
|
async function requestServerJson(context, pathname, init = {}) {
|
|
390
441
|
const server = await ensureServerForCli(context.projectRoot);
|
|
391
442
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
392
443
|
if (server.serverProjectRoot)
|
|
393
444
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
445
|
+
let response;
|
|
446
|
+
try {
|
|
447
|
+
response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
448
|
+
...init,
|
|
449
|
+
headers
|
|
450
|
+
});
|
|
451
|
+
} catch (error) {
|
|
452
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
453
|
+
throw new CliError(`Rig server request failed: ${error instanceof Error ? error.message : String(error)}
|
|
454
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
455
|
+
}
|
|
398
456
|
const text = await response.text();
|
|
399
457
|
const payload = text.trim().length > 0 ? (() => {
|
|
400
458
|
try {
|
|
@@ -406,7 +464,9 @@ async function requestServerJson(context, pathname, init = {}) {
|
|
|
406
464
|
if (!response.ok) {
|
|
407
465
|
const diagnostics = diagnosticMessage(payload);
|
|
408
466
|
const detail = diagnostics ?? (text || response.statusText);
|
|
409
|
-
|
|
467
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
468
|
+
throw new CliError(`Rig server request failed (${response.status}): ${detail}
|
|
469
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
410
470
|
}
|
|
411
471
|
return payload;
|
|
412
472
|
}
|
|
@@ -650,7 +710,7 @@ async function executeSetup(context, args) {
|
|
|
650
710
|
});
|
|
651
711
|
const exitCode = await proc.exited;
|
|
652
712
|
if (exitCode !== 0) {
|
|
653
|
-
throw new
|
|
713
|
+
throw new CliError(`Command failed (${exitCode}): ${hostBash} ./bootstrap.sh`, exitCode);
|
|
654
714
|
}
|
|
655
715
|
}
|
|
656
716
|
return { ok: true, group: "setup", command };
|
|
@@ -669,7 +729,7 @@ async function executeSetup(context, args) {
|
|
|
669
729
|
await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
|
|
670
730
|
return { ok: true, group: "setup", command };
|
|
671
731
|
default:
|
|
672
|
-
throw new
|
|
732
|
+
throw new CliError(`Unknown setup command: ${command}`, 1, { hint: "Run `rig setup --help` \u2014 commands are bootstrap|check|preflight." });
|
|
673
733
|
}
|
|
674
734
|
}
|
|
675
735
|
function formatTaskSourceKinds(kinds) {
|
|
@@ -708,7 +768,7 @@ async function runSetupCheck(projectRoot) {
|
|
|
708
768
|
console.log(formatDoctorChecks(doctorChecks));
|
|
709
769
|
const failures = countDoctorFailures(doctorChecks);
|
|
710
770
|
if (failures > 0) {
|
|
711
|
-
throw new
|
|
771
|
+
throw new CliError(`Setup check failed (${failures} failing doctor check${failures === 1 ? "" : "s"}).`, 1, { hint: "Run `rig doctor` for the full check list with remediations." });
|
|
712
772
|
}
|
|
713
773
|
return doctorChecks;
|
|
714
774
|
}
|