@h-rig/cli 0.0.6-alpha.63 → 0.0.6-alpha.65
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
|
@@ -4,10 +4,19 @@ import { spawnSync } from "child_process";
|
|
|
4
4
|
|
|
5
5
|
// packages/cli/src/runner.ts
|
|
6
6
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
7
|
-
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
7
|
+
import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
|
|
8
8
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
9
9
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
class CliError extends RuntimeCliError {
|
|
12
|
+
hint;
|
|
13
|
+
constructor(message, exitCode = 1, options = {}) {
|
|
14
|
+
super(message, exitCode);
|
|
15
|
+
if (options.hint?.trim()) {
|
|
16
|
+
this.hint = options.hint.trim();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
11
20
|
function takeOption(args, option) {
|
|
12
21
|
const rest = [];
|
|
13
22
|
let value;
|
|
@@ -16,7 +25,7 @@ function takeOption(args, option) {
|
|
|
16
25
|
if (current === option) {
|
|
17
26
|
const next = args[index + 1];
|
|
18
27
|
if (!next || next.startsWith("-")) {
|
|
19
|
-
throw new CliError(`Missing value for ${option}`);
|
|
28
|
+
throw new CliError(`Missing value for ${option}`, 1, { hint: `Provide a value after ${option}, e.g. \`${option} <value>\`.` });
|
|
20
29
|
}
|
|
21
30
|
value = next;
|
|
22
31
|
index += 1;
|
|
@@ -56,7 +65,7 @@ function readJsonFile(path) {
|
|
|
56
65
|
try {
|
|
57
66
|
return JSON.parse(readFileSync(path, "utf8"));
|
|
58
67
|
} catch (error) {
|
|
59
|
-
throw new
|
|
68
|
+
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>`." });
|
|
60
69
|
}
|
|
61
70
|
}
|
|
62
71
|
function writeJsonFile(path, value) {
|
|
@@ -120,7 +129,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
120
129
|
const global = readGlobalConnections(options);
|
|
121
130
|
const connection = global.connections[repo.selected];
|
|
122
131
|
if (!connection) {
|
|
123
|
-
throw new
|
|
132
|
+
throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
124
133
|
}
|
|
125
134
|
return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
|
|
126
135
|
}
|
|
@@ -193,7 +202,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
193
202
|
};
|
|
194
203
|
} catch (error) {
|
|
195
204
|
if (error instanceof Error) {
|
|
196
|
-
throw new
|
|
205
|
+
throw new CliError(error.message, 1);
|
|
197
206
|
}
|
|
198
207
|
throw error;
|
|
199
208
|
}
|
|
@@ -243,15 +252,64 @@ function diagnosticMessage(payload) {
|
|
|
243
252
|
});
|
|
244
253
|
return messages.length > 0 ? messages.join("; ") : null;
|
|
245
254
|
}
|
|
255
|
+
var serverReachabilityCache = new Map;
|
|
256
|
+
async function probeServerReachability(baseUrl, authToken) {
|
|
257
|
+
try {
|
|
258
|
+
const response = await fetch(`${baseUrl.replace(/\/+$/, "")}/api/server/status`, {
|
|
259
|
+
headers: mergeHeaders(undefined, authToken),
|
|
260
|
+
signal: AbortSignal.timeout(1500)
|
|
261
|
+
});
|
|
262
|
+
return response.ok;
|
|
263
|
+
} catch {
|
|
264
|
+
return false;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function cachedServerReachability(projectRoot, baseUrl, authToken) {
|
|
268
|
+
const key = resolve2(projectRoot);
|
|
269
|
+
const cached = serverReachabilityCache.get(key);
|
|
270
|
+
if (cached)
|
|
271
|
+
return cached;
|
|
272
|
+
const probe = probeServerReachability(baseUrl, authToken);
|
|
273
|
+
serverReachabilityCache.set(key, probe);
|
|
274
|
+
return probe;
|
|
275
|
+
}
|
|
276
|
+
function describeSelectedServer(projectRoot, server) {
|
|
277
|
+
try {
|
|
278
|
+
const selected = resolveSelectedConnection(projectRoot);
|
|
279
|
+
if (selected) {
|
|
280
|
+
return {
|
|
281
|
+
alias: selected.alias,
|
|
282
|
+
target: selected.connection.kind === "remote" ? selected.connection.baseUrl : server.baseUrl
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
} catch {}
|
|
286
|
+
return { alias: server.connectionKind === "remote" ? "remote" : "local", target: server.baseUrl };
|
|
287
|
+
}
|
|
288
|
+
async function buildServerFailureContext(projectRoot, server) {
|
|
289
|
+
const { alias, target } = describeSelectedServer(projectRoot, server);
|
|
290
|
+
const reachable = await cachedServerReachability(projectRoot, server.baseUrl, server.authToken);
|
|
291
|
+
const reachability = reachable ? "server is reachable" : "server is unreachable";
|
|
292
|
+
return {
|
|
293
|
+
contextLine: `Currently connected to: ${alias} at ${target} (${reachability}).`,
|
|
294
|
+
hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
|
|
295
|
+
};
|
|
296
|
+
}
|
|
246
297
|
async function requestServerJson(context, pathname, init = {}) {
|
|
247
298
|
const server = await ensureServerForCli(context.projectRoot);
|
|
248
299
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
249
300
|
if (server.serverProjectRoot)
|
|
250
301
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
302
|
+
let response;
|
|
303
|
+
try {
|
|
304
|
+
response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
305
|
+
...init,
|
|
306
|
+
headers
|
|
307
|
+
});
|
|
308
|
+
} catch (error) {
|
|
309
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
310
|
+
throw new CliError(`Rig server request failed: ${error instanceof Error ? error.message : String(error)}
|
|
311
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
312
|
+
}
|
|
255
313
|
const text = await response.text();
|
|
256
314
|
const payload = text.trim().length > 0 ? (() => {
|
|
257
315
|
try {
|
|
@@ -263,7 +321,9 @@ async function requestServerJson(context, pathname, init = {}) {
|
|
|
263
321
|
if (!response.ok) {
|
|
264
322
|
const diagnostics = diagnosticMessage(payload);
|
|
265
323
|
const detail = diagnostics ?? (text || response.statusText);
|
|
266
|
-
|
|
324
|
+
const failure = await buildServerFailureContext(context.projectRoot, server);
|
|
325
|
+
throw new CliError(`Rig server request failed (${response.status}): ${detail}
|
|
326
|
+
${failure.contextLine}`, 1, { hint: failure.hint });
|
|
267
327
|
}
|
|
268
328
|
return payload;
|
|
269
329
|
}
|
|
@@ -291,22 +351,22 @@ function readGhToken() {
|
|
|
291
351
|
const result = spawnSync("gh", ["auth", "token"], { encoding: "utf8" });
|
|
292
352
|
if (result.status !== 0) {
|
|
293
353
|
const detail = result.stderr?.trim() || result.stdout?.trim() || "gh auth token failed";
|
|
294
|
-
throw new
|
|
354
|
+
throw new CliError(`Could not import GitHub token from gh: ${detail}`, 1, { hint: "Sign in first with `gh auth login`, or store a token directly: `rig github auth token --token <token>`." });
|
|
295
355
|
}
|
|
296
356
|
const token = result.stdout.trim();
|
|
297
357
|
if (!token)
|
|
298
|
-
throw new
|
|
358
|
+
throw new CliError("gh auth token returned an empty token.", 1, { hint: "Sign in with `gh auth login`, then re-run `rig github auth import-gh`." });
|
|
299
359
|
return token;
|
|
300
360
|
}
|
|
301
361
|
async function executeGithub(context, args) {
|
|
302
362
|
const [group, command, ...rest] = args;
|
|
303
363
|
if (group !== "auth") {
|
|
304
|
-
throw new
|
|
364
|
+
throw new CliError("Usage: rig github auth <status|import-gh|token>", 1);
|
|
305
365
|
}
|
|
306
366
|
switch (command) {
|
|
307
367
|
case "status": {
|
|
308
368
|
if (rest.length > 0)
|
|
309
|
-
throw new
|
|
369
|
+
throw new CliError("Usage: rig github auth status", 1);
|
|
310
370
|
const status = await getGitHubAuthStatusViaServer(context);
|
|
311
371
|
printPayload(context, status, `GitHub auth: ${status.authenticated ? "authenticated" : "unauthenticated"}`);
|
|
312
372
|
return { ok: true, group: "github", command: "auth status", details: status };
|
|
@@ -314,23 +374,23 @@ async function executeGithub(context, args) {
|
|
|
314
374
|
case "token": {
|
|
315
375
|
const parsed = takeOption(rest, "--token");
|
|
316
376
|
if (parsed.rest.length > 0)
|
|
317
|
-
throw new
|
|
377
|
+
throw new CliError("Usage: rig github auth token --token <token>", 1);
|
|
318
378
|
const token = parsed.value?.trim();
|
|
319
379
|
if (!token)
|
|
320
|
-
throw new
|
|
380
|
+
throw new CliError("Missing --token value.", 1, { hint: "Re-run as `rig github auth token --token <token>`." });
|
|
321
381
|
const result = await postGitHubTokenViaServer(context, token);
|
|
322
382
|
printPayload(context, result, "GitHub token stored on the selected Rig server.");
|
|
323
383
|
return { ok: true, group: "github", command: "auth token", details: result };
|
|
324
384
|
}
|
|
325
385
|
case "import-gh": {
|
|
326
386
|
if (rest.length > 0)
|
|
327
|
-
throw new
|
|
387
|
+
throw new CliError("Usage: rig github auth import-gh", 1);
|
|
328
388
|
const result = await postGitHubTokenViaServer(context, readGhToken());
|
|
329
389
|
printPayload(context, result, "GitHub token imported from gh and stored on the selected Rig server.");
|
|
330
390
|
return { ok: true, group: "github", command: "auth import-gh", details: result };
|
|
331
391
|
}
|
|
332
392
|
default:
|
|
333
|
-
throw new
|
|
393
|
+
throw new CliError("Usage: rig github auth <status|import-gh|token>", 1);
|
|
334
394
|
}
|
|
335
395
|
}
|
|
336
396
|
export {
|