@h-rig/cli 0.0.6-alpha.27 → 0.0.6-alpha.29
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 +1505 -907
- package/dist/src/commands/_cli-format.js +211 -6
- package/dist/src/commands/_connection-state.js +1 -3
- package/dist/src/commands/_doctor-checks.js +3 -5
- package/dist/src/commands/_help-catalog.js +251 -66
- package/dist/src/commands/_operator-view.js +1 -3
- package/dist/src/commands/_parsers.js +0 -2
- package/dist/src/commands/_pi-frontend.js +1 -3
- package/dist/src/commands/_pi-worker-bridge-extension.js +1 -3
- package/dist/src/commands/_policy.js +0 -2
- package/dist/src/commands/_preflight.js +2 -4
- package/dist/src/commands/_run-driver-helpers.js +0 -2
- package/dist/src/commands/_server-client.js +1 -3
- package/dist/src/commands/_snapshot-upload.js +1 -3
- package/dist/src/commands/agent.js +7 -9
- package/dist/src/commands/browser.js +4 -6
- package/dist/src/commands/connect.js +5 -6
- package/dist/src/commands/dist.js +4 -6
- package/dist/src/commands/doctor.js +3 -5
- package/dist/src/commands/github.js +1 -3
- package/dist/src/commands/inbox.js +351 -31
- package/dist/src/commands/init.js +3 -5
- package/dist/src/commands/inspect.js +10 -12
- package/dist/src/commands/inspector.js +2 -4
- package/dist/src/commands/plugin.js +76 -22
- package/dist/src/commands/profile-and-review.js +8 -10
- package/dist/src/commands/queue.js +1 -3
- package/dist/src/commands/remote.js +18 -20
- package/dist/src/commands/repo-git-harness.js +6 -8
- package/dist/src/commands/run.js +159 -41
- package/dist/src/commands/server.js +6 -7
- package/dist/src/commands/setup.js +7 -15
- package/dist/src/commands/task-report-bug.js +5 -7
- package/dist/src/commands/task-run-driver.js +1 -3
- package/dist/src/commands/task.js +483 -50
- package/dist/src/commands/test.js +3 -5
- package/dist/src/commands/workspace.js +4 -6
- package/dist/src/commands.js +1508 -901
- package/dist/src/index.js +1511 -916
- package/dist/src/report-bug.js +3 -3
- package/dist/src/runner.js +2 -17
- package/package.json +6 -6
package/dist/src/commands/run.js
CHANGED
|
@@ -6,8 +6,6 @@ import { createInterface as createInterface2 } from "readline/promises";
|
|
|
6
6
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
7
7
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
8
8
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
9
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
10
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
11
9
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
12
10
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
13
11
|
function takeFlag(args, flag) {
|
|
@@ -66,7 +64,7 @@ import {
|
|
|
66
64
|
startRun,
|
|
67
65
|
defaultStartRunOptions
|
|
68
66
|
} from "@rig/runtime/control-plane/native/run-ops";
|
|
69
|
-
import { loadRuntimeContextFromEnv
|
|
67
|
+
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
70
68
|
|
|
71
69
|
// packages/cli/src/commands/_parsers.ts
|
|
72
70
|
function parsePositiveInt(value, option, fallback) {
|
|
@@ -162,7 +160,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
162
160
|
const global = readGlobalConnections(options);
|
|
163
161
|
const connection = global.connections[repo.selected];
|
|
164
162
|
if (!connection) {
|
|
165
|
-
throw new CliError2(`Selected Rig
|
|
163
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
166
164
|
}
|
|
167
165
|
return { alias: repo.selected, connection };
|
|
168
166
|
}
|
|
@@ -1219,11 +1217,16 @@ async function attachRunOperatorView(context, input) {
|
|
|
1219
1217
|
}
|
|
1220
1218
|
|
|
1221
1219
|
// packages/cli/src/commands/_cli-format.ts
|
|
1220
|
+
import { log, note } from "@clack/prompts";
|
|
1222
1221
|
import pc from "picocolors";
|
|
1223
1222
|
function stringField(record, key, fallback = "") {
|
|
1224
1223
|
const value = record[key];
|
|
1225
1224
|
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
1226
1225
|
}
|
|
1226
|
+
function rawObject(record) {
|
|
1227
|
+
const raw = record.raw;
|
|
1228
|
+
return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
1229
|
+
}
|
|
1227
1230
|
function truncate(value, width) {
|
|
1228
1231
|
if (value.length <= width)
|
|
1229
1232
|
return value;
|
|
@@ -1236,19 +1239,66 @@ function pad(value, width) {
|
|
|
1236
1239
|
}
|
|
1237
1240
|
function statusColor(status) {
|
|
1238
1241
|
const normalized = status.toLowerCase();
|
|
1239
|
-
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected"].includes(normalized))
|
|
1242
|
+
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
|
|
1240
1243
|
return pc.green;
|
|
1241
|
-
if (["failed", "needs_attention", "needs-attention", "blocked", "error"].includes(normalized))
|
|
1244
|
+
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
1242
1245
|
return pc.red;
|
|
1243
1246
|
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
1244
1247
|
return pc.cyan;
|
|
1245
|
-
if (["ready", "open", "queued", "created", "preparing", "local"].includes(normalized))
|
|
1248
|
+
if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
|
|
1246
1249
|
return pc.yellow;
|
|
1247
1250
|
return pc.dim;
|
|
1248
1251
|
}
|
|
1252
|
+
function compactDate(value) {
|
|
1253
|
+
if (!value.trim())
|
|
1254
|
+
return "";
|
|
1255
|
+
const parsed = Date.parse(value);
|
|
1256
|
+
if (!Number.isFinite(parsed))
|
|
1257
|
+
return value;
|
|
1258
|
+
return new Date(parsed).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z");
|
|
1259
|
+
}
|
|
1260
|
+
function firstString(record, keys, fallback = "") {
|
|
1261
|
+
for (const key of keys) {
|
|
1262
|
+
const value = stringField(record, key);
|
|
1263
|
+
if (value)
|
|
1264
|
+
return value;
|
|
1265
|
+
}
|
|
1266
|
+
return fallback;
|
|
1267
|
+
}
|
|
1268
|
+
function runIdOf(run) {
|
|
1269
|
+
return firstString(run, ["runId", "id"], "(unknown-run)");
|
|
1270
|
+
}
|
|
1271
|
+
function taskIdOf(run) {
|
|
1272
|
+
return firstString(run, ["taskId", "task", "task_id"]);
|
|
1273
|
+
}
|
|
1274
|
+
function runTitleOf(run) {
|
|
1275
|
+
return firstString(run, ["title", "summary", "name"], taskIdOf(run) || "(untitled)");
|
|
1276
|
+
}
|
|
1277
|
+
function shouldUseClackOutput() {
|
|
1278
|
+
return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
|
|
1279
|
+
}
|
|
1280
|
+
function printFormattedOutput(message, options = {}) {
|
|
1281
|
+
if (!shouldUseClackOutput()) {
|
|
1282
|
+
console.log(message);
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
if (options.title)
|
|
1286
|
+
note(message, options.title);
|
|
1287
|
+
else
|
|
1288
|
+
log.message(message);
|
|
1289
|
+
}
|
|
1290
|
+
function formatStatusPill(status) {
|
|
1291
|
+
const label = status || "unknown";
|
|
1292
|
+
return statusColor(label)(`\u25CF ${label}`);
|
|
1293
|
+
}
|
|
1249
1294
|
function formatSection(title, subtitle) {
|
|
1250
1295
|
return `${pc.bold(pc.cyan("\u25C6"))} ${pc.bold(title)}${subtitle ? pc.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
1251
1296
|
}
|
|
1297
|
+
function formatSuccessCard(title, rows = []) {
|
|
1298
|
+
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc.dim("\u2502")} ${pc.dim(key.padEnd(12))} ${value}`);
|
|
1299
|
+
return [formatSection(title), ...body].join(`
|
|
1300
|
+
`);
|
|
1301
|
+
}
|
|
1252
1302
|
function formatNextSteps(steps) {
|
|
1253
1303
|
if (steps.length === 0)
|
|
1254
1304
|
return [];
|
|
@@ -1280,9 +1330,85 @@ function formatRunList(runs, options = {}) {
|
|
|
1280
1330
|
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
1281
1331
|
`${row.title}${row.runtime ? pc.dim(` ${row.runtime}`) : ""}`
|
|
1282
1332
|
].join(" "));
|
|
1283
|
-
return [formatSection("Runs", options.source === "server" ? "selected server" : "local state"), header, ...body, "", ...formatNextSteps(["Follow live: `rig run attach <run-id> --follow`", "Details: `rig run show
|
|
1333
|
+
return [formatSection("Runs", options.source === "server" ? "selected server" : "local state"), header, ...body, "", ...formatNextSteps(["Follow live: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"])].join(`
|
|
1284
1334
|
`);
|
|
1285
1335
|
}
|
|
1336
|
+
function formatRunCard(run, options = {}) {
|
|
1337
|
+
const raw = rawObject(run);
|
|
1338
|
+
const merged = { ...raw, ...run };
|
|
1339
|
+
const runId = runIdOf(merged);
|
|
1340
|
+
const status = firstString(merged, ["status"], "unknown");
|
|
1341
|
+
const taskId = taskIdOf(merged);
|
|
1342
|
+
const title = runTitleOf(merged);
|
|
1343
|
+
const runtime = firstString(merged, ["runtimeAdapter", "runtime", "adapter"]);
|
|
1344
|
+
const mode = firstString(merged, ["runtimeMode", "mode"]);
|
|
1345
|
+
const interaction = firstString(merged, ["interactionMode"]);
|
|
1346
|
+
const created = compactDate(firstString(merged, ["createdAt"]));
|
|
1347
|
+
const started = compactDate(firstString(merged, ["startedAt"]));
|
|
1348
|
+
const updated = compactDate(firstString(merged, ["updatedAt"]));
|
|
1349
|
+
const completed = compactDate(firstString(merged, ["completedAt", "finishedAt"]));
|
|
1350
|
+
const worktree = firstString(merged, ["worktreePath", "cwd", "projectRoot"]);
|
|
1351
|
+
const piSession = merged.piSession && typeof merged.piSession === "object" && !Array.isArray(merged.piSession) ? firstString(merged.piSession, ["sessionId", "id"]) : "";
|
|
1352
|
+
const timeline = Array.isArray(merged.timeline) ? merged.timeline.length : null;
|
|
1353
|
+
const approvals = Array.isArray(merged.approvals) ? merged.approvals.length : null;
|
|
1354
|
+
const inputs = Array.isArray(merged.userInputs) ? merged.userInputs.length : null;
|
|
1355
|
+
const rows = [
|
|
1356
|
+
["run", pc.bold(runId)],
|
|
1357
|
+
["status", formatStatusPill(status)],
|
|
1358
|
+
["task", taskId],
|
|
1359
|
+
["title", title],
|
|
1360
|
+
["runtime", [runtime, mode, interaction].filter(Boolean).join(" \xB7 ")],
|
|
1361
|
+
["created", created],
|
|
1362
|
+
["started", started],
|
|
1363
|
+
["updated", updated],
|
|
1364
|
+
["completed", completed],
|
|
1365
|
+
["worktree", worktree],
|
|
1366
|
+
["pi", piSession],
|
|
1367
|
+
["timeline", timeline],
|
|
1368
|
+
["approvals", approvals],
|
|
1369
|
+
["inputs", inputs]
|
|
1370
|
+
];
|
|
1371
|
+
return [
|
|
1372
|
+
formatSuccessCard(options.title ?? "Run details", rows),
|
|
1373
|
+
"",
|
|
1374
|
+
...formatNextSteps([`Follow live: \`rig run attach ${runId} --follow\``, `Raw payload: \`rig run show ${runId} --raw\``])
|
|
1375
|
+
].join(`
|
|
1376
|
+
`);
|
|
1377
|
+
}
|
|
1378
|
+
function formatRunStatus(summary, options = {}) {
|
|
1379
|
+
const activeRuns = summary.activeRuns ?? [];
|
|
1380
|
+
const recentRuns = summary.recentRuns ?? [];
|
|
1381
|
+
const lines = [formatSection("Run status", options.source === "server" ? "selected server" : "local state")];
|
|
1382
|
+
lines.push("", pc.bold(`Active runs (${activeRuns.length})`));
|
|
1383
|
+
if (activeRuns.length === 0) {
|
|
1384
|
+
lines.push(pc.dim("No active runs."));
|
|
1385
|
+
} else {
|
|
1386
|
+
for (const run of activeRuns) {
|
|
1387
|
+
lines.push(formatRunSummaryLine(run));
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
lines.push("", pc.bold(`Recent runs (${recentRuns.length})`));
|
|
1391
|
+
if (recentRuns.length === 0) {
|
|
1392
|
+
lines.push(pc.dim("No recent terminal runs."));
|
|
1393
|
+
} else {
|
|
1394
|
+
for (const run of recentRuns.slice(0, 10)) {
|
|
1395
|
+
lines.push(formatRunSummaryLine(run));
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
1398
|
+
lines.push("", ...formatNextSteps(["Start work: `rig task run --next`", "Attach: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"]));
|
|
1399
|
+
return lines.join(`
|
|
1400
|
+
`);
|
|
1401
|
+
}
|
|
1402
|
+
function formatRunSummaryLine(run) {
|
|
1403
|
+
const record = run;
|
|
1404
|
+
const runId = runIdOf(record);
|
|
1405
|
+
const status = firstString(record, ["status"], "unknown");
|
|
1406
|
+
const taskId = taskIdOf(record);
|
|
1407
|
+
const title = runTitleOf(record);
|
|
1408
|
+
const runtime = firstString(record, ["runtimeAdapter", "runtime", "adapter"]);
|
|
1409
|
+
const descriptor = [taskId, title].filter(Boolean).join(" \xB7 ");
|
|
1410
|
+
return `${pc.dim("\u2502")} ${pc.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? pc.dim(` ${runtime}`) : ""}`;
|
|
1411
|
+
}
|
|
1286
1412
|
|
|
1287
1413
|
// packages/cli/src/commands/run.ts
|
|
1288
1414
|
function normalizeRemoteRunDetails(payload) {
|
|
@@ -1310,9 +1436,6 @@ function runStringField(run, key, fallback = "") {
|
|
|
1310
1436
|
const value = run[key];
|
|
1311
1437
|
return typeof value === "string" && value.trim() ? value : fallback;
|
|
1312
1438
|
}
|
|
1313
|
-
function runDisplayTitle(run) {
|
|
1314
|
-
return runStringField(run, "title", runStringField(run, "taskId", "(untitled)"));
|
|
1315
|
-
}
|
|
1316
1439
|
function buildServerRunStatus(runs) {
|
|
1317
1440
|
const activeRuns = runs.filter((run) => !REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
1318
1441
|
const recentRuns = runs.filter((run) => REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
|
|
@@ -1379,13 +1502,13 @@ async function promptForEpicSelection(projectRoot, command) {
|
|
|
1379
1502
|
}
|
|
1380
1503
|
async function executeRun(context, args) {
|
|
1381
1504
|
const [command = "status", ...rest] = args;
|
|
1382
|
-
const runtimeContext =
|
|
1505
|
+
const runtimeContext = loadRuntimeContextFromEnv() ?? undefined;
|
|
1383
1506
|
switch (command) {
|
|
1384
1507
|
case "list": {
|
|
1385
|
-
requireNoExtraArgs(rest, "
|
|
1508
|
+
requireNoExtraArgs(rest, "rig run list");
|
|
1386
1509
|
const { runs, source } = await listRunsForSelectedConnection(context, { limit: 100 });
|
|
1387
1510
|
if (context.outputMode === "text") {
|
|
1388
|
-
|
|
1511
|
+
printFormattedOutput(formatRunList(runs, { source }));
|
|
1389
1512
|
}
|
|
1390
1513
|
return { ok: true, group: "run", command, details: { runs, source } };
|
|
1391
1514
|
}
|
|
@@ -1395,7 +1518,7 @@ async function executeRun(context, args) {
|
|
|
1395
1518
|
pending = run.rest;
|
|
1396
1519
|
const purgeArtifacts = takeFlag(pending, "--purge-artifacts");
|
|
1397
1520
|
pending = purgeArtifacts.rest;
|
|
1398
|
-
requireNoExtraArgs(pending, "
|
|
1521
|
+
requireNoExtraArgs(pending, "rig run delete --run <id> [--purge-artifacts]");
|
|
1399
1522
|
if (!run.value) {
|
|
1400
1523
|
throw new CliError2("run delete requires --run <id>.");
|
|
1401
1524
|
}
|
|
@@ -1425,7 +1548,7 @@ async function executeRun(context, args) {
|
|
|
1425
1548
|
pending = keepRuntimes.rest;
|
|
1426
1549
|
const keepQueue = takeFlag(pending, "--keep-queue");
|
|
1427
1550
|
pending = keepQueue.rest;
|
|
1428
|
-
requireNoExtraArgs(pending, "
|
|
1551
|
+
requireNoExtraArgs(pending, "rig run cleanup --all [--keep-artifacts] [--keep-runtimes] [--keep-queue]");
|
|
1429
1552
|
if (!all.value) {
|
|
1430
1553
|
throw new CliError2("run cleanup currently requires --all.");
|
|
1431
1554
|
}
|
|
@@ -1444,20 +1567,25 @@ async function executeRun(context, args) {
|
|
|
1444
1567
|
}
|
|
1445
1568
|
case "show": {
|
|
1446
1569
|
let pending = rest;
|
|
1570
|
+
const rawResult = takeFlag(pending, "--raw");
|
|
1571
|
+
pending = rawResult.rest;
|
|
1447
1572
|
const run = takeOption(pending, "--run");
|
|
1448
1573
|
pending = run.rest;
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1574
|
+
const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
|
|
1575
|
+
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
1576
|
+
requireNoExtraArgs(extra, "rig run show <id>|--run <id> [--raw]");
|
|
1577
|
+
const runId = run.value ?? positionalRunId;
|
|
1578
|
+
if (!runId) {
|
|
1579
|
+
throw new CliError2("run show requires a run id.");
|
|
1452
1580
|
}
|
|
1453
|
-
const record = readAuthorityRun(context.projectRoot,
|
|
1581
|
+
const record = readAuthorityRun(context.projectRoot, runId) ?? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, runId).catch(() => ({})));
|
|
1454
1582
|
if (!record) {
|
|
1455
|
-
throw new CliError2(`Run not found: ${
|
|
1583
|
+
throw new CliError2(`Run not found: ${runId}`, 2);
|
|
1456
1584
|
}
|
|
1457
1585
|
if (context.outputMode === "text") {
|
|
1458
|
-
|
|
1586
|
+
printFormattedOutput(rawResult.value ? JSON.stringify(record, null, 2) : formatRunCard(record));
|
|
1459
1587
|
}
|
|
1460
|
-
return { ok: true, group: "run", command, details: record };
|
|
1588
|
+
return { ok: true, group: "run", command, details: { ...record, rawOutput: rawResult.value } };
|
|
1461
1589
|
}
|
|
1462
1590
|
case "timeline": {
|
|
1463
1591
|
let pending = rest;
|
|
@@ -1465,7 +1593,7 @@ async function executeRun(context, args) {
|
|
|
1465
1593
|
pending = run.rest;
|
|
1466
1594
|
const follow = takeFlag(pending, "--follow");
|
|
1467
1595
|
pending = follow.rest;
|
|
1468
|
-
requireNoExtraArgs(pending, "
|
|
1596
|
+
requireNoExtraArgs(pending, "rig run timeline --run <id> [--follow]");
|
|
1469
1597
|
if (!run.value) {
|
|
1470
1598
|
throw new CliError2("run timeline requires --run <id>.");
|
|
1471
1599
|
}
|
|
@@ -1502,7 +1630,7 @@ async function executeRun(context, args) {
|
|
|
1502
1630
|
pending = pollMs.rest;
|
|
1503
1631
|
const positionalRunId = pending.length > 0 ? pending[0] : undefined;
|
|
1504
1632
|
const extra = positionalRunId ? pending.slice(1) : pending;
|
|
1505
|
-
requireNoExtraArgs(extra, "
|
|
1633
|
+
requireNoExtraArgs(extra, "rig run attach <run-id>|--run <run-id> [--message <text>] [--once|--follow] [--poll-ms <ms>]");
|
|
1506
1634
|
const runId = runOption.value ?? positionalRunId;
|
|
1507
1635
|
if (!runId) {
|
|
1508
1636
|
throw new CliError2("run attach requires a run id.", 2);
|
|
@@ -1522,7 +1650,7 @@ async function executeRun(context, args) {
|
|
|
1522
1650
|
return { ok: true, group: "run", command, details: { ...attached, steered: attached.steered || steered } };
|
|
1523
1651
|
}
|
|
1524
1652
|
case "status": {
|
|
1525
|
-
requireNoExtraArgs(rest, "
|
|
1653
|
+
requireNoExtraArgs(rest, "rig run status");
|
|
1526
1654
|
if (context.dryRun) {
|
|
1527
1655
|
if (context.outputMode === "text") {
|
|
1528
1656
|
console.log("[dry-run] rig run status");
|
|
@@ -1533,17 +1661,7 @@ async function executeRun(context, args) {
|
|
|
1533
1661
|
const activeRuns = Array.isArray(summary.activeRuns) ? summary.activeRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
1534
1662
|
const recentRuns = Array.isArray(summary.recentRuns) ? summary.recentRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
|
|
1535
1663
|
if (context.outputMode === "text") {
|
|
1536
|
-
|
|
1537
|
-
for (const run of activeRuns) {
|
|
1538
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
1539
|
-
}
|
|
1540
|
-
if (recentRuns.length > 0) {
|
|
1541
|
-
console.log("");
|
|
1542
|
-
console.log("Recent runs:");
|
|
1543
|
-
for (const run of recentRuns) {
|
|
1544
|
-
console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
|
|
1545
|
-
}
|
|
1546
|
-
}
|
|
1664
|
+
printFormattedOutput(formatRunStatus({ activeRuns, recentRuns, runs: Array.isArray(summary.runs) ? summary.runs : [...activeRuns, ...recentRuns] }, { source: isRemoteConnectionSelected(context.projectRoot) ? "server" : "local" }));
|
|
1547
1665
|
}
|
|
1548
1666
|
return { ok: true, group: "run", command, details: summary };
|
|
1549
1667
|
}
|
|
@@ -1567,7 +1685,7 @@ async function executeRun(context, args) {
|
|
|
1567
1685
|
pending = pollResult.rest;
|
|
1568
1686
|
const noServerResult = takeFlag(pending, "--no-server");
|
|
1569
1687
|
pending = noServerResult.rest;
|
|
1570
|
-
requireNoExtraArgs(pending, "
|
|
1688
|
+
requireNoExtraArgs(pending, "rig run start [--epic <id>] [--prompt-epic|--no-epic-prompt] [--ws-port <n>] [--server-host <host>] [--server-port <n>] [--poll-ms <n>] [--no-server]");
|
|
1571
1689
|
if (promptEpicResult.value && noEpicPromptResult.value) {
|
|
1572
1690
|
throw new CliError2("Cannot use --prompt-epic and --no-epic-prompt together.");
|
|
1573
1691
|
}
|
|
@@ -1615,7 +1733,7 @@ async function executeRun(context, args) {
|
|
|
1615
1733
|
};
|
|
1616
1734
|
}
|
|
1617
1735
|
case "resume": {
|
|
1618
|
-
requireNoExtraArgs(rest, "
|
|
1736
|
+
requireNoExtraArgs(rest, "rig run resume");
|
|
1619
1737
|
if (context.dryRun) {
|
|
1620
1738
|
if (context.outputMode === "text") {
|
|
1621
1739
|
console.log("[dry-run] rig run resume");
|
|
@@ -1629,7 +1747,7 @@ async function executeRun(context, args) {
|
|
|
1629
1747
|
return { ok: true, group: "run", command, details: resumed };
|
|
1630
1748
|
}
|
|
1631
1749
|
case "restart": {
|
|
1632
|
-
requireNoExtraArgs(rest, "
|
|
1750
|
+
requireNoExtraArgs(rest, "rig run restart");
|
|
1633
1751
|
if (context.dryRun) {
|
|
1634
1752
|
if (context.outputMode === "text") {
|
|
1635
1753
|
console.log("[dry-run] rig run restart");
|
|
@@ -1646,7 +1764,7 @@ async function executeRun(context, args) {
|
|
|
1646
1764
|
const runOption = takeOption(rest, "--run");
|
|
1647
1765
|
const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
|
|
1648
1766
|
const extra = positionalRunId ? runOption.rest.slice(1) : runOption.rest;
|
|
1649
|
-
requireNoExtraArgs(extra, "
|
|
1767
|
+
requireNoExtraArgs(extra, "rig run stop [<run-id>|--run <id>]");
|
|
1650
1768
|
const runId = runOption.value ?? positionalRunId;
|
|
1651
1769
|
if (context.dryRun) {
|
|
1652
1770
|
return {
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
4
4
|
import { CliError } 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
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
10
8
|
function takeOption(args, option) {
|
|
@@ -160,12 +158,13 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
160
158
|
const global = readGlobalConnections(options);
|
|
161
159
|
const connection = global.connections[repo.selected];
|
|
162
160
|
if (!connection) {
|
|
163
|
-
throw new CliError2(`Selected Rig
|
|
161
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
164
162
|
}
|
|
165
163
|
return { alias: repo.selected, connection };
|
|
166
164
|
}
|
|
167
165
|
|
|
168
166
|
// packages/cli/src/commands/_cli-format.ts
|
|
167
|
+
import { log, note } from "@clack/prompts";
|
|
169
168
|
import pc from "picocolors";
|
|
170
169
|
function truncate(value, width) {
|
|
171
170
|
if (value.length <= width)
|
|
@@ -179,13 +178,13 @@ function pad(value, width) {
|
|
|
179
178
|
}
|
|
180
179
|
function statusColor(status) {
|
|
181
180
|
const normalized = status.toLowerCase();
|
|
182
|
-
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected"].includes(normalized))
|
|
181
|
+
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
|
|
183
182
|
return pc.green;
|
|
184
|
-
if (["failed", "needs_attention", "needs-attention", "blocked", "error"].includes(normalized))
|
|
183
|
+
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
185
184
|
return pc.red;
|
|
186
185
|
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
187
186
|
return pc.cyan;
|
|
188
|
-
if (["ready", "open", "queued", "created", "preparing", "local"].includes(normalized))
|
|
187
|
+
if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
|
|
189
188
|
return pc.yellow;
|
|
190
189
|
return pc.dim;
|
|
191
190
|
}
|
|
@@ -197,7 +196,7 @@ function formatSection(title, subtitle) {
|
|
|
197
196
|
return `${pc.bold(pc.cyan("\u25C6"))} ${pc.bold(title)}${subtitle ? pc.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
198
197
|
}
|
|
199
198
|
function formatSuccessCard(title, rows = []) {
|
|
200
|
-
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc.dim("\u2502")} ${pc.dim(key.padEnd(
|
|
199
|
+
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc.dim("\u2502")} ${pc.dim(key.padEnd(12))} ${value}`);
|
|
201
200
|
return [formatSection(title), ...body].join(`
|
|
202
201
|
`);
|
|
203
202
|
}
|
|
@@ -9,8 +9,6 @@ import { resolve as resolve6 } from "path";
|
|
|
9
9
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
10
10
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
11
11
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
12
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
13
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
14
12
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
15
13
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
16
14
|
function requireNoExtraArgs(args, usage) {
|
|
@@ -253,7 +251,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
253
251
|
const global = readGlobalConnections(options);
|
|
254
252
|
const connection = global.connections[repo.selected];
|
|
255
253
|
if (!connection) {
|
|
256
|
-
throw new CliError2(`Selected Rig
|
|
254
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
257
255
|
}
|
|
258
256
|
return { alias: repo.selected, connection };
|
|
259
257
|
}
|
|
@@ -481,7 +479,7 @@ async function runRigDoctorChecks(options) {
|
|
|
481
479
|
const taskSourceKind = config?.taskSource?.kind;
|
|
482
480
|
checks.push(taskSourceKind ? check("task-source", "task source configured", "pass", taskSourceKind) : check("task-source", "task source configured", "fail", "missing taskSource", "Configure taskSource in rig.config.ts."));
|
|
483
481
|
const repo = readRepoConnection(projectRoot);
|
|
484
|
-
checks.push(repo ? check("project-link", "repo selected Rig
|
|
482
|
+
checks.push(repo ? check("project-link", "repo selected Rig server", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to link this checkout to a GitHub repo slug.") : check("project-link", "repo selected Rig server", "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
|
|
485
483
|
const selected = (() => {
|
|
486
484
|
try {
|
|
487
485
|
return resolveSelectedConnection(projectRoot);
|
|
@@ -489,7 +487,7 @@ async function runRigDoctorChecks(options) {
|
|
|
489
487
|
return null;
|
|
490
488
|
}
|
|
491
489
|
})();
|
|
492
|
-
checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server
|
|
490
|
+
checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server", repo ? "fail" : "warn", repo ? "selected alias is missing" : "will auto-start local server", repo ? "Run `rig server list` and `rig server use <alias|local>`." : undefined));
|
|
493
491
|
let server = null;
|
|
494
492
|
try {
|
|
495
493
|
server = await (options.resolveServer ?? ensureServerForCli)(projectRoot);
|
|
@@ -575,7 +573,7 @@ async function executeSetup(context, args) {
|
|
|
575
573
|
const [command = "check", ...rest] = args;
|
|
576
574
|
switch (command) {
|
|
577
575
|
case "bootstrap":
|
|
578
|
-
requireNoExtraArgs(rest, "
|
|
576
|
+
requireNoExtraArgs(rest, "rig setup bootstrap");
|
|
579
577
|
{
|
|
580
578
|
const hostBash = Bun.which("bash") || "/bin/bash";
|
|
581
579
|
const env = { ...process.env };
|
|
@@ -598,25 +596,19 @@ async function executeSetup(context, args) {
|
|
|
598
596
|
}
|
|
599
597
|
return { ok: true, group: "setup", command };
|
|
600
598
|
case "check":
|
|
601
|
-
requireNoExtraArgs(rest, `
|
|
599
|
+
requireNoExtraArgs(rest, `rig setup ${command}`);
|
|
602
600
|
{
|
|
603
601
|
const checks = await withMutedConsole(context.outputMode === "json", () => runSetupCheck(context.projectRoot));
|
|
604
602
|
return { ok: true, group: "setup", command, details: { checks, failures: countDoctorFailures(checks) } };
|
|
605
603
|
}
|
|
606
604
|
case "setup":
|
|
607
|
-
requireNoExtraArgs(rest, "
|
|
605
|
+
requireNoExtraArgs(rest, "rig setup setup");
|
|
608
606
|
withMutedConsole(context.outputMode === "json", () => runSetupInit(context.projectRoot));
|
|
609
607
|
return { ok: true, group: "setup", command };
|
|
610
608
|
case "preflight":
|
|
611
|
-
requireNoExtraArgs(rest, "
|
|
609
|
+
requireNoExtraArgs(rest, "rig setup preflight");
|
|
612
610
|
await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
|
|
613
611
|
return { ok: true, group: "setup", command };
|
|
614
|
-
case "install-agent-shell":
|
|
615
|
-
requireNoExtraArgs(rest, "bun run rig setup install-agent-shell");
|
|
616
|
-
if (context.outputMode === "text") {
|
|
617
|
-
console.log("install-agent-shell is deprecated. Runtime shells now use compiled rig-agent directly.");
|
|
618
|
-
}
|
|
619
|
-
return { ok: true, group: "setup", command };
|
|
620
612
|
default:
|
|
621
613
|
throw new CliError2(`Unknown setup command: ${command}`);
|
|
622
614
|
}
|
|
@@ -9,8 +9,6 @@ import pc from "picocolors";
|
|
|
9
9
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
10
10
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
11
11
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
12
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
13
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
14
12
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
15
13
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
16
14
|
function formatCommand(parts) {
|
|
@@ -241,15 +239,15 @@ function buildBugReportMarkdown(input, browser, screenshots, assets) {
|
|
|
241
239
|
...input.issueId ? [
|
|
242
240
|
`- Canonical task assets live under \`artifacts/${input.issueId}/bug-report/\`.`,
|
|
243
241
|
`- Start with \`artifacts/${input.issueId}/bug-report/task.md\` and the files in \`artifacts/${input.issueId}/bug-report/assets/\`.`,
|
|
244
|
-
browserRequired ? `- Run \`
|
|
242
|
+
browserRequired ? `- Run \`rig task info --task ${input.issueId}\` to confirm browser wiring before debugging.` : `- Run \`rig task info --task ${input.issueId}\` to confirm scope and artifact links before debugging.`
|
|
245
243
|
] : [
|
|
246
|
-
"- Draft-only report: convert this into a
|
|
244
|
+
"- Draft-only report: convert this into a Rig task before assigning it to an agent run."
|
|
247
245
|
],
|
|
248
246
|
"",
|
|
249
247
|
"## Validation",
|
|
250
248
|
"",
|
|
251
249
|
"```bash",
|
|
252
|
-
...input.issueId ? [`
|
|
250
|
+
...input.issueId ? [`rig task validate --task ${input.issueId}`] : [],
|
|
253
251
|
...browserRequired ? [
|
|
254
252
|
"bun run app:check:browser:hp-next",
|
|
255
253
|
"bun run app:e2e:browser:hp-next"
|
|
@@ -396,7 +394,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
396
394
|
pending = outputRootResult.rest;
|
|
397
395
|
const slugResult = takeOption(pending, "--slug");
|
|
398
396
|
pending = slugResult.rest;
|
|
399
|
-
requireNoExtraArgs(pending, "
|
|
397
|
+
requireNoExtraArgs(pending, "rig report-bug [--no-prompt] [--no-beads] [--browser|--no-browser] --title <text> --url <url> [--asset <dragged-file>]");
|
|
400
398
|
let draft = {
|
|
401
399
|
outputRoot: outputRootResult.value || "",
|
|
402
400
|
title: titleResult.value,
|
|
@@ -501,7 +499,7 @@ async function executeTaskReportBug(context, args) {
|
|
|
501
499
|
console.log(`Evidence assets: ${result.assetDir}`);
|
|
502
500
|
if (taskConfigPath) {
|
|
503
501
|
console.log(`Task config: ${taskConfigPath}`);
|
|
504
|
-
console.log(`Run:
|
|
502
|
+
console.log(`Run: rig task info --task ${issueId}`);
|
|
505
503
|
}
|
|
506
504
|
}
|
|
507
505
|
return {
|
|
@@ -9,8 +9,6 @@ import { createInterface as createLineInterface } from "readline";
|
|
|
9
9
|
import { EventBus } from "@rig/runtime/control-plane/runtime/events";
|
|
10
10
|
import { CliError } from "@rig/runtime/control-plane/errors";
|
|
11
11
|
import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
|
|
12
|
-
import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
|
|
13
|
-
import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
|
|
14
12
|
import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
|
|
15
13
|
import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
|
|
16
14
|
function formatCommand(parts) {
|
|
@@ -469,7 +467,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
|
|
|
469
467
|
const global = readGlobalConnections(options);
|
|
470
468
|
const connection = global.connections[repo.selected];
|
|
471
469
|
if (!connection) {
|
|
472
|
-
throw new CliError2(`Selected Rig
|
|
470
|
+
throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
|
|
473
471
|
}
|
|
474
472
|
return { alias: repo.selected, connection };
|
|
475
473
|
}
|