@h-rig/cli 0.0.6-alpha.66 → 0.0.6-alpha.68
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 +250 -166
- package/dist/src/commands/_async-ui.js +141 -0
- package/dist/src/commands/_connection-state.js +5 -1
- package/dist/src/commands/_doctor-checks.js +18 -0
- package/dist/src/commands/_operator-view.js +143 -4
- package/dist/src/commands/_pi-frontend.js +13 -1
- package/dist/src/commands/_preflight.js +7 -0
- package/dist/src/commands/_server-client.js +13 -0
- package/dist/src/commands/_snapshot-upload.js +7 -0
- package/dist/src/commands/_spinner.js +4 -2
- package/dist/src/commands/doctor.js +145 -1
- package/dist/src/commands/github.js +137 -3
- package/dist/src/commands/inbox.js +139 -6
- package/dist/src/commands/init.js +18 -0
- package/dist/src/commands/inspect.js +147 -8
- package/dist/src/commands/run.js +190 -38
- package/dist/src/commands/server.js +7 -0
- package/dist/src/commands/setup.js +150 -6
- package/dist/src/commands/stats.js +448 -110
- package/dist/src/commands/task-run-driver.js +7 -0
- package/dist/src/commands/task.js +186 -47
- package/dist/src/commands.js +250 -166
- package/dist/src/index.js +250 -166
- package/package.json +8 -8
|
@@ -213,6 +213,15 @@ import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
|
213
213
|
import { resolve as resolve2 } from "path";
|
|
214
214
|
import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
|
|
215
215
|
var scopedGitHubBearerTokens = new Map;
|
|
216
|
+
var serverPhaseListener = null;
|
|
217
|
+
function setServerPhaseListener(listener) {
|
|
218
|
+
const previous = serverPhaseListener;
|
|
219
|
+
serverPhaseListener = listener;
|
|
220
|
+
return previous;
|
|
221
|
+
}
|
|
222
|
+
function reportServerPhase(label) {
|
|
223
|
+
serverPhaseListener?.(label);
|
|
224
|
+
}
|
|
216
225
|
function cleanToken(value) {
|
|
217
226
|
const trimmed = value?.trim();
|
|
218
227
|
return trimmed ? trimmed : null;
|
|
@@ -255,6 +264,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
255
264
|
try {
|
|
256
265
|
const selected = resolveSelectedConnection(projectRoot);
|
|
257
266
|
if (selected?.connection.kind === "remote") {
|
|
267
|
+
reportServerPhase(`Connecting to ${selected.alias}\u2026`);
|
|
258
268
|
const authToken = readGitHubBearerTokenForRemote(projectRoot);
|
|
259
269
|
const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
|
|
260
270
|
return {
|
|
@@ -264,6 +274,7 @@ async function ensureServerForCli(projectRoot) {
|
|
|
264
274
|
serverProjectRoot
|
|
265
275
|
};
|
|
266
276
|
}
|
|
277
|
+
reportServerPhase("Starting local Rig server\u2026");
|
|
267
278
|
const connection = await ensureLocalRigServerConnection(projectRoot);
|
|
268
279
|
return {
|
|
269
280
|
baseUrl: connection.baseUrl,
|
|
@@ -380,6 +391,7 @@ async function requestServerJson(context, pathname, init = {}) {
|
|
|
380
391
|
const headers = mergeHeaders(init.headers, server.authToken);
|
|
381
392
|
if (server.serverProjectRoot)
|
|
382
393
|
headers.set("x-rig-project-root", server.serverProjectRoot);
|
|
394
|
+
reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
|
|
383
395
|
let response;
|
|
384
396
|
try {
|
|
385
397
|
response = await fetch(`${server.baseUrl}${pathname}`, {
|
|
@@ -1025,6 +1037,127 @@ async function selectTaskWithTextPicker(tasks, io = {}) {
|
|
|
1025
1037
|
return Number.isFinite(index) ? tasks[index] ?? null : null;
|
|
1026
1038
|
}
|
|
1027
1039
|
|
|
1040
|
+
// packages/cli/src/commands/_async-ui.ts
|
|
1041
|
+
import pc from "picocolors";
|
|
1042
|
+
|
|
1043
|
+
// packages/cli/src/commands/_spinner.ts
|
|
1044
|
+
var SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
1045
|
+
function createTtySpinner(input) {
|
|
1046
|
+
const output = input.output ?? process.stdout;
|
|
1047
|
+
const isTty = output.isTTY === true;
|
|
1048
|
+
const frames = input.frames && input.frames.length > 0 ? input.frames : SPINNER_FRAMES;
|
|
1049
|
+
let label = input.label;
|
|
1050
|
+
let frame = 0;
|
|
1051
|
+
let paused = false;
|
|
1052
|
+
let stopped = false;
|
|
1053
|
+
let lastPrintedLabel = "";
|
|
1054
|
+
const render = () => {
|
|
1055
|
+
if (stopped || paused)
|
|
1056
|
+
return;
|
|
1057
|
+
if (!isTty) {
|
|
1058
|
+
if (label !== lastPrintedLabel) {
|
|
1059
|
+
output.write(`${label}
|
|
1060
|
+
`);
|
|
1061
|
+
lastPrintedLabel = label;
|
|
1062
|
+
}
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1065
|
+
frame = (frame + 1) % frames.length;
|
|
1066
|
+
const glyph = frames[frame] ?? frames[0] ?? "";
|
|
1067
|
+
output.write(`\r\x1B[2K${input.styleFrame ? input.styleFrame(glyph) : glyph} ${label}`);
|
|
1068
|
+
};
|
|
1069
|
+
const clearLine = () => {
|
|
1070
|
+
if (isTty)
|
|
1071
|
+
output.write("\r\x1B[2K");
|
|
1072
|
+
};
|
|
1073
|
+
render();
|
|
1074
|
+
const timer = isTty ? setInterval(render, input.intervalMs ?? 120) : null;
|
|
1075
|
+
return {
|
|
1076
|
+
setLabel(next) {
|
|
1077
|
+
label = next;
|
|
1078
|
+
render();
|
|
1079
|
+
},
|
|
1080
|
+
pause() {
|
|
1081
|
+
paused = true;
|
|
1082
|
+
clearLine();
|
|
1083
|
+
},
|
|
1084
|
+
resume() {
|
|
1085
|
+
if (stopped)
|
|
1086
|
+
return;
|
|
1087
|
+
paused = false;
|
|
1088
|
+
render();
|
|
1089
|
+
},
|
|
1090
|
+
stop(finalLine) {
|
|
1091
|
+
if (stopped)
|
|
1092
|
+
return;
|
|
1093
|
+
stopped = true;
|
|
1094
|
+
if (timer)
|
|
1095
|
+
clearInterval(timer);
|
|
1096
|
+
clearLine();
|
|
1097
|
+
if (finalLine)
|
|
1098
|
+
output.write(`${finalLine}
|
|
1099
|
+
`);
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// packages/cli/src/commands/_async-ui.ts
|
|
1105
|
+
var CLACK_SPINNER_FRAMES = ["\u25D2", "\u25D0", "\u25D3", "\u25D1"];
|
|
1106
|
+
var DONE_SYMBOL = pc.green("\u25C7");
|
|
1107
|
+
var FAIL_SYMBOL = pc.red("\u25A0");
|
|
1108
|
+
var activeUpdate = null;
|
|
1109
|
+
async function withSpinner(label, work, options = {}) {
|
|
1110
|
+
if (options.outputMode === "json") {
|
|
1111
|
+
return work(() => {});
|
|
1112
|
+
}
|
|
1113
|
+
if (activeUpdate) {
|
|
1114
|
+
const outer = activeUpdate;
|
|
1115
|
+
outer(label);
|
|
1116
|
+
return work(outer);
|
|
1117
|
+
}
|
|
1118
|
+
const output = options.output ?? process.stderr;
|
|
1119
|
+
const isTty = output.isTTY === true;
|
|
1120
|
+
let lastLabel = label;
|
|
1121
|
+
if (!isTty) {
|
|
1122
|
+
output.write(`${label}
|
|
1123
|
+
`);
|
|
1124
|
+
const update2 = (next) => {
|
|
1125
|
+
lastLabel = next;
|
|
1126
|
+
};
|
|
1127
|
+
activeUpdate = update2;
|
|
1128
|
+
const previousListener2 = setServerPhaseListener(update2);
|
|
1129
|
+
try {
|
|
1130
|
+
return await work(update2);
|
|
1131
|
+
} finally {
|
|
1132
|
+
activeUpdate = null;
|
|
1133
|
+
setServerPhaseListener(previousListener2);
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const spinner = createTtySpinner({
|
|
1137
|
+
label,
|
|
1138
|
+
output,
|
|
1139
|
+
frames: CLACK_SPINNER_FRAMES,
|
|
1140
|
+
styleFrame: (frame) => pc.magenta(frame)
|
|
1141
|
+
});
|
|
1142
|
+
const update = (next) => {
|
|
1143
|
+
lastLabel = next;
|
|
1144
|
+
spinner.setLabel(next);
|
|
1145
|
+
};
|
|
1146
|
+
activeUpdate = update;
|
|
1147
|
+
const previousListener = setServerPhaseListener(update);
|
|
1148
|
+
try {
|
|
1149
|
+
const result = await work(update);
|
|
1150
|
+
spinner.stop(options.doneLabel ? `${DONE_SYMBOL} ${options.doneLabel}` : undefined);
|
|
1151
|
+
return result;
|
|
1152
|
+
} catch (error) {
|
|
1153
|
+
spinner.stop(`${FAIL_SYMBOL} ${lastLabel}`);
|
|
1154
|
+
throw error;
|
|
1155
|
+
} finally {
|
|
1156
|
+
activeUpdate = null;
|
|
1157
|
+
setServerPhaseListener(previousListener);
|
|
1158
|
+
}
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1028
1161
|
// packages/cli/src/commands/_pi-frontend.ts
|
|
1029
1162
|
import { mkdtempSync, rmSync } from "fs";
|
|
1030
1163
|
import { tmpdir } from "os";
|
|
@@ -1072,7 +1205,12 @@ async function attachRunBundledPiFrontend(context, input) {
|
|
|
1072
1205
|
};
|
|
1073
1206
|
let detached = false;
|
|
1074
1207
|
try {
|
|
1075
|
-
await runPiMain([
|
|
1208
|
+
await runPiMain([
|
|
1209
|
+
"--no-extensions",
|
|
1210
|
+
"--no-skills",
|
|
1211
|
+
"--no-prompt-templates",
|
|
1212
|
+
"--no-context-files"
|
|
1213
|
+
], {
|
|
1076
1214
|
extensionFactories: [piRigExtensionFactory]
|
|
1077
1215
|
});
|
|
1078
1216
|
detached = true;
|
|
@@ -1137,8 +1275,9 @@ async function readOperatorSnapshot(context, runId, options = {}) {
|
|
|
1137
1275
|
}
|
|
1138
1276
|
async function attachRunOperatorView(context, input) {
|
|
1139
1277
|
let steered = false;
|
|
1140
|
-
|
|
1141
|
-
|
|
1278
|
+
const attachMessage = input.message?.trim();
|
|
1279
|
+
if (attachMessage) {
|
|
1280
|
+
await withSpinner("Queueing steering message\u2026", () => sendRunPiPromptViaServer(context, input.runId, attachMessage, "steer").catch(() => steerRunViaServer(context, input.runId, attachMessage)), { outputMode: context.outputMode });
|
|
1142
1281
|
steered = true;
|
|
1143
1282
|
}
|
|
1144
1283
|
if (input.follow && !input.once && input.interactive !== false && context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY)) {
|
|
@@ -1148,7 +1287,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
1148
1287
|
});
|
|
1149
1288
|
}
|
|
1150
1289
|
const surface = createOperatorSurface({ interactive: input.interactive !== false });
|
|
1151
|
-
let snapshot = await readOperatorSnapshot(context, input.runId);
|
|
1290
|
+
let snapshot = await withSpinner(`Connecting to run ${input.runId}\u2026`, () => readOperatorSnapshot(context, input.runId), { outputMode: context.outputMode });
|
|
1152
1291
|
if (context.outputMode === "text") {
|
|
1153
1292
|
surface.renderSnapshot(snapshot);
|
|
1154
1293
|
surface.renderTimeline(snapshot.timeline);
|
|
@@ -1188,7 +1327,7 @@ async function attachRunOperatorView(context, input) {
|
|
|
1188
1327
|
|
|
1189
1328
|
// packages/cli/src/commands/_cli-format.ts
|
|
1190
1329
|
import { log, note } from "@clack/prompts";
|
|
1191
|
-
import
|
|
1330
|
+
import pc2 from "picocolors";
|
|
1192
1331
|
function stringField(record, key, fallback = "") {
|
|
1193
1332
|
const value = record[key];
|
|
1194
1333
|
return typeof value === "string" && value.trim() ? value.trim() : fallback;
|
|
@@ -1218,14 +1357,14 @@ function pad(value, width) {
|
|
|
1218
1357
|
function statusColor(status) {
|
|
1219
1358
|
const normalized = status.toLowerCase();
|
|
1220
1359
|
if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
|
|
1221
|
-
return
|
|
1360
|
+
return pc2.green;
|
|
1222
1361
|
if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
|
|
1223
|
-
return
|
|
1362
|
+
return pc2.red;
|
|
1224
1363
|
if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
|
|
1225
|
-
return
|
|
1364
|
+
return pc2.cyan;
|
|
1226
1365
|
if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
|
|
1227
|
-
return
|
|
1228
|
-
return
|
|
1366
|
+
return pc2.yellow;
|
|
1367
|
+
return pc2.dim;
|
|
1229
1368
|
}
|
|
1230
1369
|
function compactValue(value) {
|
|
1231
1370
|
if (value === null || value === undefined)
|
|
@@ -1256,17 +1395,17 @@ function formatStatusPill(status) {
|
|
|
1256
1395
|
return statusColor(label)(`\u25CF ${label}`);
|
|
1257
1396
|
}
|
|
1258
1397
|
function formatSection(title, subtitle) {
|
|
1259
|
-
return `${
|
|
1398
|
+
return `${pc2.bold(pc2.cyan("\u25C6"))} ${pc2.bold(title)}${subtitle ? pc2.dim(` \u2014 ${subtitle}`) : ""}`;
|
|
1260
1399
|
}
|
|
1261
1400
|
function formatSuccessCard(title, rows = []) {
|
|
1262
|
-
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${
|
|
1401
|
+
const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc2.dim("\u2502")} ${pc2.dim(key.padEnd(12))} ${value}`);
|
|
1263
1402
|
return [formatSection(title), ...body].join(`
|
|
1264
1403
|
`);
|
|
1265
1404
|
}
|
|
1266
1405
|
function formatNextSteps(steps) {
|
|
1267
1406
|
if (steps.length === 0)
|
|
1268
1407
|
return [];
|
|
1269
|
-
return [
|
|
1408
|
+
return [pc2.bold("Next"), ...steps.map((step) => `${pc2.dim("\u203A")} ${step}`)];
|
|
1270
1409
|
}
|
|
1271
1410
|
function formatTaskList(tasks, options = {}) {
|
|
1272
1411
|
if (options.raw)
|
|
@@ -1286,12 +1425,12 @@ function formatTaskList(tasks, options = {}) {
|
|
|
1286
1425
|
});
|
|
1287
1426
|
const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
|
|
1288
1427
|
const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
|
|
1289
|
-
const header = `${
|
|
1428
|
+
const header = `${pc2.bold(pad("TASK", idWidth))} ${pc2.bold(pad("STATUS", statusWidth))} ${pc2.bold("TITLE")}`;
|
|
1290
1429
|
const body = rows.map((row) => {
|
|
1291
|
-
const labels = row.labels.length > 0 ?
|
|
1292
|
-
const source = row.source ?
|
|
1430
|
+
const labels = row.labels.length > 0 ? pc2.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
|
|
1431
|
+
const source = row.source ? pc2.dim(` ${row.source}`) : "";
|
|
1293
1432
|
return [
|
|
1294
|
-
|
|
1433
|
+
pc2.bold(pad(truncate(row.id, idWidth), idWidth)),
|
|
1295
1434
|
statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
|
|
1296
1435
|
`${row.title}${labels}${source}`
|
|
1297
1436
|
].join(" ");
|
|
@@ -1312,7 +1451,7 @@ function formatTaskCard(task, options = {}) {
|
|
|
1312
1451
|
const readiness = compactValue(task.readiness ?? raw.readiness);
|
|
1313
1452
|
const validators = compactValue(task.validators ?? raw.validators ?? task.validation ?? raw.validation);
|
|
1314
1453
|
const rows = [
|
|
1315
|
-
["task",
|
|
1454
|
+
["task", pc2.bold(id)],
|
|
1316
1455
|
["status", formatStatusPill(status)],
|
|
1317
1456
|
["title", title],
|
|
1318
1457
|
["source", source],
|
|
@@ -1334,12 +1473,12 @@ function formatTaskDetails(task) {
|
|
|
1334
1473
|
return formatTaskCard(task, { title: "Task details" });
|
|
1335
1474
|
}
|
|
1336
1475
|
function formatSubmittedRun(input) {
|
|
1337
|
-
const rows = [["run",
|
|
1476
|
+
const rows = [["run", pc2.bold(input.runId)]];
|
|
1338
1477
|
if (input.task) {
|
|
1339
1478
|
const id = stringField(input.task, "id", "<unknown>");
|
|
1340
1479
|
const status = stringField(input.task, "status", "unknown");
|
|
1341
1480
|
const title = stringField(input.task, "title", "Untitled task");
|
|
1342
|
-
rows.push(["task", `${
|
|
1481
|
+
rows.push(["task", `${pc2.bold(id)} ${formatStatusPill(status)} ${title}`]);
|
|
1343
1482
|
}
|
|
1344
1483
|
const runtime = [input.runtimeAdapter || "pi", input.runtimeMode || "full-access", input.interactionMode || "default"].filter(Boolean).join(" \xB7 ");
|
|
1345
1484
|
rows.push(["runtime", runtime]);
|
|
@@ -1395,7 +1534,7 @@ async function printPendingInboxFooter(context) {
|
|
|
1395
1534
|
|
|
1396
1535
|
// packages/cli/src/commands/_help-catalog.ts
|
|
1397
1536
|
import { intro, log as log2, note as note2, outro } from "@clack/prompts";
|
|
1398
|
-
import
|
|
1537
|
+
import pc3 from "picocolors";
|
|
1399
1538
|
var TOP_LEVEL_SECTIONS = [
|
|
1400
1539
|
{
|
|
1401
1540
|
title: "Start here",
|
|
@@ -1677,13 +1816,13 @@ var ADVANCED_GROUPS = [
|
|
|
1677
1816
|
];
|
|
1678
1817
|
var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
|
|
1679
1818
|
function heading(title) {
|
|
1680
|
-
return
|
|
1819
|
+
return pc3.bold(pc3.cyan(title));
|
|
1681
1820
|
}
|
|
1682
1821
|
function renderRigBanner(version) {
|
|
1683
|
-
const m = (s) =>
|
|
1684
|
-
const c = (s) =>
|
|
1685
|
-
const y = (s) =>
|
|
1686
|
-
const d = (s) =>
|
|
1822
|
+
const m = (s) => pc3.bold(pc3.magenta(s));
|
|
1823
|
+
const c = (s) => pc3.bold(pc3.cyan(s));
|
|
1824
|
+
const y = (s) => pc3.yellow(s);
|
|
1825
|
+
const d = (s) => pc3.dim(s);
|
|
1687
1826
|
const lines = [
|
|
1688
1827
|
m(" \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 ") + d(" \u2591\u2592\u2593\u2588 "),
|
|
1689
1828
|
m(" \u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2550\u2550\u255D ") + d("\u2593\u2592\u2591"),
|
|
@@ -1692,7 +1831,7 @@ function renderRigBanner(version) {
|
|
|
1692
1831
|
y(" \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D") + d(" \u2592\u2591"),
|
|
1693
1832
|
y(" \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D "),
|
|
1694
1833
|
"",
|
|
1695
|
-
` ${c("\u25E2\u25E4")} ${
|
|
1834
|
+
` ${c("\u25E2\u25E4")} ${pc3.bold("the control rig for autonomous coding agents")} ${m("//")} ${d("you are the operator")}`,
|
|
1696
1835
|
version ? ` ${d(`v${version} \xB7 jack in: rig task run --next`)}` : ` ${d("jack in: rig task run --next")}`
|
|
1697
1836
|
];
|
|
1698
1837
|
return lines.join(`
|
|
@@ -1700,7 +1839,7 @@ function renderRigBanner(version) {
|
|
|
1700
1839
|
}
|
|
1701
1840
|
function commandLine(command, description) {
|
|
1702
1841
|
const commandColumn = command.length >= 38 ? `${command} ` : command.padEnd(38);
|
|
1703
|
-
return `${
|
|
1842
|
+
return `${pc3.dim("\u2502")} ${pc3.bold(commandColumn)} ${description}`;
|
|
1704
1843
|
}
|
|
1705
1844
|
function renderCommandBlock(commands) {
|
|
1706
1845
|
return commands.map((entry) => commandLine(entry.command, entry.description)).join(`
|
|
@@ -1710,37 +1849,37 @@ function renderGroup(group) {
|
|
|
1710
1849
|
const lines = [
|
|
1711
1850
|
`${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
|
|
1712
1851
|
"",
|
|
1713
|
-
|
|
1852
|
+
pc3.bold("Usage"),
|
|
1714
1853
|
...group.usage.map((line) => ` ${line}`),
|
|
1715
1854
|
"",
|
|
1716
|
-
|
|
1855
|
+
pc3.bold("Commands"),
|
|
1717
1856
|
...group.commands.map((entry) => commandLine(entry.command, entry.description))
|
|
1718
1857
|
];
|
|
1719
1858
|
if (group.examples?.length) {
|
|
1720
|
-
lines.push("",
|
|
1859
|
+
lines.push("", pc3.bold("Examples"), ...group.examples.map((line) => ` ${pc3.dim("$")} ${line}`));
|
|
1721
1860
|
}
|
|
1722
1861
|
if (group.next?.length) {
|
|
1723
|
-
lines.push("",
|
|
1862
|
+
lines.push("", pc3.bold("Next steps"), ...group.next.map((line) => ` ${pc3.dim("\u203A")} ${line}`));
|
|
1724
1863
|
}
|
|
1725
1864
|
if (group.advanced?.length) {
|
|
1726
|
-
lines.push("",
|
|
1865
|
+
lines.push("", pc3.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc3.dim("\u203A")} ${line}`));
|
|
1727
1866
|
}
|
|
1728
1867
|
return lines.join(`
|
|
1729
1868
|
`);
|
|
1730
1869
|
}
|
|
1731
1870
|
function renderTopLevelHelp() {
|
|
1732
1871
|
return [
|
|
1733
|
-
`${heading("rig")} ${
|
|
1734
|
-
|
|
1872
|
+
`${heading("rig")} ${pc3.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
|
|
1873
|
+
pc3.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox gates."),
|
|
1735
1874
|
"",
|
|
1736
1875
|
...TOP_LEVEL_SECTIONS.flatMap((section) => [
|
|
1737
|
-
`${
|
|
1876
|
+
`${pc3.bold(pc3.magenta(`\u25C7 ${section.title}`))} \u2014 ${pc3.dim(section.subtitle)}`,
|
|
1738
1877
|
renderCommandBlock(section.commands),
|
|
1739
1878
|
""
|
|
1740
1879
|
]),
|
|
1741
|
-
|
|
1880
|
+
pc3.dim("More: `rig help --advanced` for dev/compatibility commands; `rig <group> --help` for rich per-group help; `rig --version` for the installed version."),
|
|
1742
1881
|
"",
|
|
1743
|
-
|
|
1882
|
+
pc3.bold("Global options"),
|
|
1744
1883
|
commandLine("--project <path>", "Use a project root instead of auto-discovery."),
|
|
1745
1884
|
commandLine("--json", "Emit structured output for scripts/agents."),
|
|
1746
1885
|
commandLine("--dry-run", "Print the command plan without mutating state.")
|
|
@@ -1979,7 +2118,7 @@ async function executeTask(context, args, options) {
|
|
|
1979
2118
|
pending = rawResult.rest;
|
|
1980
2119
|
const { filters, rest: remaining } = parseTaskFilters(pending);
|
|
1981
2120
|
requireNoExtraArgs(remaining, "rig task list [--raw] [--assignee <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
1982
|
-
const tasks = await listWorkspaceTasksViaServer(context, filters);
|
|
2121
|
+
const tasks = await withSpinner("Reading tasks from server\u2026", () => listWorkspaceTasksViaServer(context, filters), { outputMode: context.outputMode });
|
|
1983
2122
|
if (context.outputMode === "text") {
|
|
1984
2123
|
const renderedTasks = rawResult.value ? tasks.map((task) => summarizeTask(task, { raw: true })) : tasks.map((task) => summarizeTask(task));
|
|
1985
2124
|
printFormattedOutput(formatTaskList(renderedTasks, { raw: rawResult.value }));
|
|
@@ -2003,7 +2142,7 @@ async function executeTask(context, args, options) {
|
|
|
2003
2142
|
const taskId3 = normalizeTaskRunTaskId(taskOption.value ?? positional);
|
|
2004
2143
|
if (!taskId3)
|
|
2005
2144
|
throw new CliError("task show requires a task id.", 2, { hint: "Run `rig task list` to find ids, then `rig task show <id>`." });
|
|
2006
|
-
const task = await getWorkspaceTaskViaServer(context, taskId3);
|
|
2145
|
+
const task = await withSpinner(`Reading task ${taskId3} from server\u2026`, () => getWorkspaceTaskViaServer(context, taskId3), { outputMode: context.outputMode });
|
|
2007
2146
|
if (!task)
|
|
2008
2147
|
throw new CliError(`Task not found: ${taskId3}`, 3, { hint: "Run `rig task list` to see available tasks." });
|
|
2009
2148
|
const summary = summarizeTask(task, { raw: true });
|
|
@@ -2015,7 +2154,7 @@ async function executeTask(context, args, options) {
|
|
|
2015
2154
|
case "next": {
|
|
2016
2155
|
const { filters, rest: remaining } = parseTaskFilters(rest);
|
|
2017
2156
|
requireNoExtraArgs(remaining, "rig task next [--assignee <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
|
|
2018
|
-
const selected = await selectNextWorkspaceTaskViaServer(context, filters);
|
|
2157
|
+
const selected = await withSpinner("Selecting next ready task\u2026", () => selectNextWorkspaceTaskViaServer(context, filters), { outputMode: context.outputMode });
|
|
2019
2158
|
if (context.outputMode === "text") {
|
|
2020
2159
|
if (selected.task) {
|
|
2021
2160
|
printFormattedOutput(formatTaskCard(summarizeTask(selected.task, { raw: true }), { title: "Selected task", selected: true }));
|
|
@@ -2165,7 +2304,7 @@ async function executeTask(context, args, options) {
|
|
|
2165
2304
|
let selectedTask = null;
|
|
2166
2305
|
let selectedTaskId = normalizeTaskRunTaskId(taskResult.value) ?? positionalTaskId;
|
|
2167
2306
|
if (nextResult.value) {
|
|
2168
|
-
const selected = await selectNextWorkspaceTaskViaServer(context, filterResult.filters);
|
|
2307
|
+
const selected = await withSpinner("Selecting next ready task\u2026", () => selectNextWorkspaceTaskViaServer(context, filterResult.filters), { outputMode: context.outputMode });
|
|
2169
2308
|
selectedTask = selected.task;
|
|
2170
2309
|
selectedTaskId = selected.task ? readTaskId(selected.task) : null;
|
|
2171
2310
|
if (!selectedTaskId) {
|
|
@@ -2176,7 +2315,7 @@ async function executeTask(context, args, options) {
|
|
|
2176
2315
|
if (context.outputMode !== "text" || !process.stdin.isTTY || !process.stdout.isTTY) {
|
|
2177
2316
|
throw new CliError("task run requires an interactive terminal to pick a task; pass --next, --task <id>, or --initial-prompt/--title for an ad hoc run.", 2);
|
|
2178
2317
|
}
|
|
2179
|
-
const tasks = await listWorkspaceTasksViaServer(context, filterResult.filters);
|
|
2318
|
+
const tasks = await withSpinner("Reading tasks from server\u2026", () => listWorkspaceTasksViaServer(context, filterResult.filters), { outputMode: context.outputMode });
|
|
2180
2319
|
selectedTask = await selectTaskWithTextPicker(tasks);
|
|
2181
2320
|
selectedTaskId = selectedTask ? readTaskId(selectedTask) : null;
|
|
2182
2321
|
if (!selectedTaskId) {
|
|
@@ -2186,13 +2325,13 @@ async function executeTask(context, args, options) {
|
|
|
2186
2325
|
await runProjectMainSyncPreflight(context, { disabled: skipProjectSyncResult.value });
|
|
2187
2326
|
const projectDefaults = await loadTaskRunProjectDefaults(context.projectRoot);
|
|
2188
2327
|
const runtimeAdapter = normalizeRuntimeAdapter(runtimeAdapterResult.value ?? projectDefaults.runtimeAdapter);
|
|
2189
|
-
await runFastTaskRunPreflight(context, {
|
|
2328
|
+
await withSpinner("Running task-run preflight\u2026", () => runFastTaskRunPreflight(context, {
|
|
2190
2329
|
taskId: selectedTaskId,
|
|
2191
2330
|
runtimeAdapter
|
|
2192
|
-
});
|
|
2331
|
+
}), { outputMode: context.outputMode });
|
|
2193
2332
|
const dirtyBaseline = await resolveDirtyBaselineForTaskRun(context, dirtyBaselineResult.value);
|
|
2194
2333
|
const prMode = noPrResult.value ? "off" : normalizePrMode(prResult.value) ?? projectDefaults.prMode;
|
|
2195
|
-
const submitted = await submitTaskRunViaServer(context, {
|
|
2334
|
+
const submitted = await withSpinner("Dispatching run\u2026", () => submitTaskRunViaServer(context, {
|
|
2196
2335
|
runId: context.runId,
|
|
2197
2336
|
taskId: selectedTaskId ?? undefined,
|
|
2198
2337
|
title: titleResult.value ?? undefined,
|
|
@@ -2203,7 +2342,7 @@ async function executeTask(context, args, options) {
|
|
|
2203
2342
|
initialPrompt: initialPromptResult.value ?? undefined,
|
|
2204
2343
|
baselineMode: dirtyBaseline.mode,
|
|
2205
2344
|
prMode
|
|
2206
|
-
});
|
|
2345
|
+
}), { outputMode: context.outputMode });
|
|
2207
2346
|
let attachDetails = null;
|
|
2208
2347
|
if (!detachResult.value && context.outputMode === "text") {
|
|
2209
2348
|
printFormattedOutput(formatSubmittedRun({
|