@h-rig/cli 0.0.6-alpha.27 → 0.0.6-alpha.28

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.
Files changed (38) hide show
  1. package/dist/bin/rig.js +1038 -620
  2. package/dist/src/commands/_cli-format.js +211 -6
  3. package/dist/src/commands/_connection-state.js +1 -1
  4. package/dist/src/commands/_doctor-checks.js +3 -3
  5. package/dist/src/commands/_help-catalog.js +225 -64
  6. package/dist/src/commands/_operator-view.js +1 -1
  7. package/dist/src/commands/_pi-frontend.js +1 -1
  8. package/dist/src/commands/_pi-worker-bridge-extension.js +1 -1
  9. package/dist/src/commands/_preflight.js +2 -2
  10. package/dist/src/commands/_server-client.js +1 -1
  11. package/dist/src/commands/_snapshot-upload.js +1 -1
  12. package/dist/src/commands/agent.js +7 -7
  13. package/dist/src/commands/browser.js +4 -4
  14. package/dist/src/commands/connect.js +5 -4
  15. package/dist/src/commands/dist.js +4 -4
  16. package/dist/src/commands/doctor.js +3 -3
  17. package/dist/src/commands/github.js +1 -1
  18. package/dist/src/commands/inbox.js +351 -29
  19. package/dist/src/commands/init.js +3 -3
  20. package/dist/src/commands/inspect.js +10 -10
  21. package/dist/src/commands/inspector.js +2 -2
  22. package/dist/src/commands/plugin.js +3 -3
  23. package/dist/src/commands/profile-and-review.js +8 -8
  24. package/dist/src/commands/queue.js +1 -1
  25. package/dist/src/commands/remote.js +18 -18
  26. package/dist/src/commands/repo-git-harness.js +4 -4
  27. package/dist/src/commands/run.js +157 -37
  28. package/dist/src/commands/server.js +6 -5
  29. package/dist/src/commands/setup.js +8 -8
  30. package/dist/src/commands/task-report-bug.js +5 -5
  31. package/dist/src/commands/task-run-driver.js +1 -1
  32. package/dist/src/commands/task.js +451 -45
  33. package/dist/src/commands/test.js +3 -3
  34. package/dist/src/commands/workspace.js +4 -4
  35. package/dist/src/commands.js +1038 -620
  36. package/dist/src/index.js +1038 -620
  37. package/dist/src/report-bug.js +3 -3
  38. package/package.json +6 -6
@@ -288,15 +288,15 @@ function buildBugReportMarkdown(input, browser, screenshots, assets) {
288
288
  ...input.issueId ? [
289
289
  `- Canonical task assets live under \`artifacts/${input.issueId}/bug-report/\`.`,
290
290
  `- Start with \`artifacts/${input.issueId}/bug-report/task.md\` and the files in \`artifacts/${input.issueId}/bug-report/assets/\`.`,
291
- browserRequired ? `- Run \`bun run rig task info --task ${input.issueId}\` to confirm browser wiring before debugging.` : `- Run \`bun run rig task info --task ${input.issueId}\` to confirm scope and artifact links before debugging.`
291
+ 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.`
292
292
  ] : [
293
- "- Draft-only report: convert this into a beads task before assigning it to an agent run."
293
+ "- Draft-only report: convert this into a Rig task before assigning it to an agent run."
294
294
  ],
295
295
  "",
296
296
  "## Validation",
297
297
  "",
298
298
  "```bash",
299
- ...input.issueId ? [`bun run rig task validate --task ${input.issueId}`] : [],
299
+ ...input.issueId ? [`rig task validate --task ${input.issueId}`] : [],
300
300
  ...browserRequired ? [
301
301
  "bun run app:check:browser:hp-next",
302
302
  "bun run app:e2e:browser:hp-next"
@@ -443,7 +443,7 @@ async function executeTaskReportBug(context, args) {
443
443
  pending = outputRootResult.rest;
444
444
  const slugResult = takeOption(pending, "--slug");
445
445
  pending = slugResult.rest;
446
- requireNoExtraArgs(pending, "bun run rig report-bug [--no-prompt] [--no-beads] [--browser|--no-browser] --title <text> --url <url> [--asset <dragged-file>]");
446
+ requireNoExtraArgs(pending, "rig report-bug [--no-prompt] [--no-beads] [--browser|--no-browser] --title <text> --url <url> [--asset <dragged-file>]");
447
447
  let draft = {
448
448
  outputRoot: outputRootResult.value || "",
449
449
  title: titleResult.value,
@@ -548,7 +548,7 @@ async function executeTaskReportBug(context, args) {
548
548
  console.log(`Evidence assets: ${result.assetDir}`);
549
549
  if (taskConfigPath) {
550
550
  console.log(`Task config: ${taskConfigPath}`);
551
- console.log(`Run: bun run rig task info --task ${issueId}`);
551
+ console.log(`Run: rig task info --task ${issueId}`);
552
552
  }
553
553
  }
554
554
  return {
@@ -1371,7 +1371,7 @@ async function executeBrowser(context, args) {
1371
1371
  return { ok: true, group: "browser", command: "help" };
1372
1372
  }
1373
1373
  if (command === "explain") {
1374
- requireNoExtraArgs(rest, "bun run rig browser explain");
1374
+ requireNoExtraArgs(rest, "rig browser explain");
1375
1375
  console.log(browserAgentUsageText());
1376
1376
  return { ok: true, group: "browser", command: "explain" };
1377
1377
  }
@@ -1397,7 +1397,7 @@ ${browserHelpText()}`);
1397
1397
 
1398
1398
  ${browserHelpText()}`);
1399
1399
  }
1400
- requireNoExtraArgs(appRest, `bun run rig browser ${command} ${subcommand}`);
1400
+ requireNoExtraArgs(appRest, `rig browser ${command} ${subcommand}`);
1401
1401
  await context.runCommand(["bun", "run", `app:${subcommand}:browser:${appSlug}`]);
1402
1402
  return { ok: true, group: "browser", command: `${command}-${subcommand}` };
1403
1403
  }
@@ -1409,7 +1409,7 @@ ${browserHelpText()}`);
1409
1409
  };
1410
1410
  const packageScript = packageScripts[command];
1411
1411
  if (packageScript) {
1412
- requireNoExtraArgs(rest, `bun run rig browser ${command}`);
1412
+ requireNoExtraArgs(rest, `rig browser ${command}`);
1413
1413
  await context.runCommand(["bun", "run", "--filter=@rig/browser", packageScript]);
1414
1414
  return { ok: true, group: "browser", command };
1415
1415
  }
@@ -1436,7 +1436,7 @@ async function executeBrowserDemo(context, args) {
1436
1436
  pending = keepOpenFlag.rest;
1437
1437
  const noBuildFlag = takeFlag(pending, "--no-build");
1438
1438
  pending = noBuildFlag.rest;
1439
- requireNoExtraArgs(pending, "bun run rig browser demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]");
1439
+ requireNoExtraArgs(pending, "rig browser demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]");
1440
1440
  if (context.outputMode !== "text" || !process.stdin.isTTY || !process.stdout.isTTY) {
1441
1441
  throw new CliError2("rig browser demo requires an interactive TTY in text mode.");
1442
1442
  }
@@ -1947,17 +1947,17 @@ async function executeProfile(context, args) {
1947
1947
  const [command = "show", ...rest] = args;
1948
1948
  switch (command) {
1949
1949
  case "show":
1950
- requireNoExtraArgs(rest, "bun run rig profile show");
1950
+ requireNoExtraArgs(rest, "rig profile show");
1951
1951
  await withMutedConsole(context.outputMode === "json", () => showProfile(context.projectRoot));
1952
1952
  return { ok: true, group: "profile", command };
1953
1953
  case "set": {
1954
1954
  if (rest.length === 0) {
1955
- throw new CliError2("Usage: bun run rig profile set <claude-code|codex-cli|pi> or set [--model ...] [--runtime ...] [--plugin ...]");
1955
+ throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi> or set [--model ...] [--runtime ...] [--plugin ...]");
1956
1956
  }
1957
1957
  const preset = rest[0];
1958
1958
  if (preset && !preset.startsWith("-")) {
1959
1959
  if (rest.length !== 1) {
1960
- throw new CliError2("Usage: bun run rig profile set <claude-code|codex-cli|pi>");
1960
+ throw new CliError2("Usage: rig profile set <claude-code|codex-cli|pi>");
1961
1961
  }
1962
1962
  try {
1963
1963
  await withMutedConsole(context.outputMode === "json", () => setProfile(context.projectRoot, { preset }));
@@ -1973,7 +1973,7 @@ async function executeProfile(context, args) {
1973
1973
  pending = runtimeResult.rest;
1974
1974
  const pluginResult = takeOption(pending, "--plugin");
1975
1975
  pending = pluginResult.rest;
1976
- requireNoExtraArgs(pending, "bun run rig profile set [--model ...] [--runtime ...] [--plugin ...]");
1976
+ requireNoExtraArgs(pending, "rig profile set [--model ...] [--runtime ...] [--plugin ...]");
1977
1977
  if (!modelResult.value && !runtimeResult.value && !pluginResult.value) {
1978
1978
  throw new CliError2("Provide at least one of --model, --runtime, or --plugin.");
1979
1979
  }
@@ -2005,21 +2005,21 @@ async function executeReview(context, args) {
2005
2005
  const [command = "show", ...rest] = args;
2006
2006
  switch (command) {
2007
2007
  case "show":
2008
- requireNoExtraArgs(rest, "bun run rig review show");
2008
+ requireNoExtraArgs(rest, "rig review show");
2009
2009
  await withMutedConsole(context.outputMode === "json", () => showReviewProfile(context.projectRoot));
2010
2010
  return { ok: true, group: "review", command };
2011
2011
  case "set": {
2012
2012
  if (rest.length === 0) {
2013
- throw new CliError2("Usage: bun run rig review set <off|advisory|required> [--provider greptile]");
2013
+ throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
2014
2014
  }
2015
2015
  const mode = rest[0];
2016
2016
  if (!mode) {
2017
- throw new CliError2("Usage: bun run rig review set <off|advisory|required> [--provider greptile]");
2017
+ throw new CliError2("Usage: rig review set <off|advisory|required> [--provider greptile]");
2018
2018
  }
2019
2019
  let pending = rest.slice(1);
2020
2020
  const providerResult = takeOption(pending, "--provider");
2021
2021
  pending = providerResult.rest;
2022
- requireNoExtraArgs(pending, "bun run rig review set <off|advisory|required> [--provider greptile]");
2022
+ requireNoExtraArgs(pending, "rig review set <off|advisory|required> [--provider greptile]");
2023
2023
  try {
2024
2024
  await withMutedConsole(context.outputMode === "json", () => {
2025
2025
  return setReviewProfile(context.projectRoot, mode, providerResult.value);
@@ -2104,13 +2104,13 @@ async function executeRepo(context, args) {
2104
2104
  switch (command) {
2105
2105
  case "sync": {
2106
2106
  const { value: task, rest: remaining } = takeOption(rest, "--task");
2107
- requireNoExtraArgs(remaining, "bun run rig repo sync [--task <beads-id>]");
2107
+ requireNoExtraArgs(remaining, "rig repo sync [--task <task-id>]");
2108
2108
  withMutedConsole(context.outputMode === "json", () => repoEnsure(context.projectRoot, task || undefined));
2109
2109
  return { ok: true, group: "repo", command, details: { task: task || null } };
2110
2110
  }
2111
2111
  case "reset-baseline": {
2112
2112
  const { value: keepTaskStatusFlag, rest: remaining } = takeFlag(rest, "--keep-task-status");
2113
- requireNoExtraArgs(remaining, "bun run rig repo reset-baseline [--keep-task-status]");
2113
+ requireNoExtraArgs(remaining, "rig repo reset-baseline [--keep-task-status]");
2114
2114
  withMutedConsole(context.outputMode === "json", () => resetBaseline(context.projectRoot, keepTaskStatusFlag));
2115
2115
  return { ok: true, group: "repo", command, details: { keepTaskStatus: keepTaskStatusFlag } };
2116
2116
  }
@@ -2120,7 +2120,7 @@ async function executeRepo(context, args) {
2120
2120
  }
2121
2121
  async function executeGit(context, args) {
2122
2122
  if (args.length === 0) {
2123
- throw new CliError2("Usage: bun run rig git <git-flow args...>");
2123
+ throw new CliError2("Usage: rig git <git-flow args...>");
2124
2124
  }
2125
2125
  await enforceNativeCommandPolicy(context, args, {
2126
2126
  commandPrefix: "rig-agent git",
@@ -2141,7 +2141,7 @@ async function executeGit(context, args) {
2141
2141
  }
2142
2142
  async function executeHarness(context, args) {
2143
2143
  if (args.length === 0) {
2144
- throw new CliError2("Usage: bun run rig harness <harness args...>");
2144
+ throw new CliError2("Usage: rig harness <harness args...>");
2145
2145
  }
2146
2146
  await enforceNativeCommandPolicy(context, args, {
2147
2147
  commandPrefix: "rig-agent",
@@ -2250,7 +2250,7 @@ async function executePlugin(context, args) {
2250
2250
  const [command = "list", ...rest] = args;
2251
2251
  switch (command) {
2252
2252
  case "list": {
2253
- requireNoExtraArgs(rest, "bun run rig plugin list");
2253
+ requireNoExtraArgs(rest, "rig plugin list");
2254
2254
  const legacyPlugins = context.plugins.list();
2255
2255
  const declarative = [];
2256
2256
  const config = await loadRigConfigOrNull(context.projectRoot);
@@ -2317,8 +2317,8 @@ async function executePlugin(context, args) {
2317
2317
  }
2318
2318
  case "validate": {
2319
2319
  const { value: task, rest: remaining } = takeOption(rest, "--task");
2320
- requireNoExtraArgs(remaining, "bun run rig plugin validate --task <beads-id>");
2321
- const taskId = requireTask(task, "bun run rig plugin validate --task <beads-id>");
2320
+ requireNoExtraArgs(remaining, "rig plugin validate --task <task-id>");
2321
+ const taskId = requireTask(task, "rig plugin validate --task <task-id>");
2322
2322
  const results = await context.plugins.runValidators(taskId);
2323
2323
  const passed = results.filter((result) => result.passed).length;
2324
2324
  const failed = results.length - passed;
@@ -2458,7 +2458,7 @@ function resolveSelectedConnection(projectRoot, options = {}) {
2458
2458
  const global = readGlobalConnections(options);
2459
2459
  const connection = global.connections[repo.selected];
2460
2460
  if (!connection) {
2461
- throw new CliError2(`Selected Rig connection "${repo.selected}" was not found. Run \`rig connect list\` or \`rig connect use local\`.`, 1);
2461
+ throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
2462
2462
  }
2463
2463
  return { alias: repo.selected, connection };
2464
2464
  }
@@ -2950,7 +2950,7 @@ async function runFastTaskRunPreflight(context, options = {}) {
2950
2950
  }
2951
2951
  }
2952
2952
  const repo = readRepoConnection(context.projectRoot);
2953
- checks.push(repo ? preflightCheck("project-link", "project linked to Rig connection", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to Rig connection", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig connect use <alias|local>`."));
2953
+ checks.push(repo ? preflightCheck("project-link", "project linked to Rig server", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to Rig server", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
2954
2954
  try {
2955
2955
  const auth = await request("/api/github/auth/status");
2956
2956
  checks.push(isAuthenticated(auth) ? preflightCheck("github-auth", "GitHub auth valid", "pass") : preflightCheck("github-auth", "GitHub auth valid", legacyServerCompatibility ? "warn" : "fail", "not authenticated", "Run `rig github auth import-gh` or `rig github auth token --token <token>`."));
@@ -3068,7 +3068,7 @@ async function executeQueue(context, args) {
3068
3068
  pending = failFastResult.rest;
3069
3069
  const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
3070
3070
  pending = skipProjectSyncResult.rest;
3071
- requireNoExtraArgs(pending, "bun run rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]");
3071
+ requireNoExtraArgs(pending, "rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]");
3072
3072
  const workers = parsePositiveInt(workersResult.value, "--workers", 2);
3073
3073
  const maxTasks = parsePositiveInt(maxTasksResult.value, "--max-tasks", 10);
3074
3074
  const action = parseAction(actionResult.value);
@@ -3246,7 +3246,7 @@ async function executeAgent(context, args) {
3246
3246
  const [command = "list", ...rest] = args;
3247
3247
  switch (command) {
3248
3248
  case "list": {
3249
- requireNoExtraArgs(rest, "bun run rig agent list");
3249
+ requireNoExtraArgs(rest, "rig agent list");
3250
3250
  const runtimes = await listAgentRuntimes(context.projectRoot);
3251
3251
  if (context.outputMode === "text") {
3252
3252
  if (runtimes.length === 0) {
@@ -3267,12 +3267,12 @@ async function executeAgent(context, args) {
3267
3267
  pending = modeResult.rest;
3268
3268
  const taskResult = takeOption(pending, "--task");
3269
3269
  pending = taskResult.rest;
3270
- requireNoExtraArgs(pending, "bun run rig agent prepare --task <id> [--id <id>] [--mode worktree]");
3270
+ requireNoExtraArgs(pending, "rig agent prepare --task <id> [--id <id>] [--mode worktree]");
3271
3271
  const mode = parseIsolationMode(modeResult.value, false);
3272
3272
  const id = idResult.value || agentId("agent");
3273
3273
  const taskId = taskResult.value?.trim();
3274
3274
  if (!taskId) {
3275
- throw new CliError2("Usage: bun run rig agent prepare --task <id> [--id <id>] [--mode worktree]");
3275
+ throw new CliError2("Usage: rig agent prepare --task <id> [--id <id>] [--mode worktree]");
3276
3276
  }
3277
3277
  const runtime = await withMutedConsole(context.outputMode === "json", () => ensureAgentRuntime({
3278
3278
  projectRoot: context.projectRoot,
@@ -3290,7 +3290,7 @@ async function executeAgent(context, args) {
3290
3290
  case "run": {
3291
3291
  const { options, commandParts } = splitAtDoubleDash(rest);
3292
3292
  if (commandParts.length === 0) {
3293
- throw new CliError2("Usage: bun run rig agent run [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
3293
+ throw new CliError2("Usage: rig agent run [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
3294
3294
  }
3295
3295
  let pending = options;
3296
3296
  const idResult = takeOption(pending, "--id");
@@ -3301,12 +3301,12 @@ async function executeAgent(context, args) {
3301
3301
  pending = taskResult.rest;
3302
3302
  const skipProjectSyncResult = takeFlag(pending, "--skip-project-sync");
3303
3303
  pending = skipProjectSyncResult.rest;
3304
- requireNoExtraArgs(pending, "bun run rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
3304
+ requireNoExtraArgs(pending, "rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
3305
3305
  const mode = parseIsolationMode(modeResult.value, false);
3306
3306
  const id = idResult.value || agentId("agent-run");
3307
3307
  const taskId = taskResult.value?.trim();
3308
3308
  if (!taskId) {
3309
- throw new CliError2("Usage: bun run rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
3309
+ throw new CliError2("Usage: rig agent run --task <id> [--id <id>] [--mode worktree] [--skip-project-sync] -- <command...>");
3310
3310
  }
3311
3311
  await runProjectMainSyncPreflight(context, { disabled: skipProjectSyncResult.value });
3312
3312
  const createdAt = new Date().toISOString();
@@ -3420,7 +3420,7 @@ ${result.stderr.trim()}` : ""}`, result.exitCode);
3420
3420
  pending = allResult.rest;
3421
3421
  const idResult = takeOption(pending, "--id");
3422
3422
  pending = idResult.rest;
3423
- requireNoExtraArgs(pending, "bun run rig agent cleanup (--id <id> | --all)");
3423
+ requireNoExtraArgs(pending, "rig agent cleanup (--id <id> | --all)");
3424
3424
  if (!allResult.value && !idResult.value) {
3425
3425
  throw new CliError2("Provide --id <id> or --all.");
3426
3426
  }
@@ -3556,7 +3556,7 @@ async function executeDist(context, args) {
3556
3556
  switch (command) {
3557
3557
  case "build": {
3558
3558
  const { value: outputDir, rest: pending } = takeOption(rest, "--output-dir");
3559
- requireNoExtraArgs(pending, "bun run rig dist build [--output-dir <dir>]");
3559
+ requireNoExtraArgs(pending, "rig dist build [--output-dir <dir>]");
3560
3560
  const commandParts = ["bun", "run", "packages/cli/bin/build-rig-binaries.ts"];
3561
3561
  if (outputDir) {
3562
3562
  commandParts.push("--output-dir", outputDir);
@@ -3570,7 +3570,7 @@ async function executeDist(context, args) {
3570
3570
  pending = scopeResult.rest;
3571
3571
  const pathResult = takeOption(pending, "--path");
3572
3572
  pending = pathResult.rest;
3573
- requireNoExtraArgs(pending, "bun run rig dist install [--scope user|system] [--path <dir>]");
3573
+ requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
3574
3574
  const scope = parseInstallScope(scopeResult.value);
3575
3575
  const installDir = resolveInstallDir(scope, pathResult.value);
3576
3576
  mkdirSync5(installDir, { recursive: true });
@@ -3613,7 +3613,7 @@ async function executeDist(context, args) {
3613
3613
  };
3614
3614
  }
3615
3615
  case "doctor": {
3616
- requireNoExtraArgs(rest, "bun run rig dist doctor");
3616
+ requireNoExtraArgs(rest, "rig dist doctor");
3617
3617
  const details = await runDistDoctor(context.projectRoot);
3618
3618
  if (context.outputMode === "text") {
3619
3619
  console.log(`bun: ${details.bun.available ? `ok (${details.bun.version})` : "missing"}`);
@@ -3624,7 +3624,7 @@ async function executeDist(context, args) {
3624
3624
  return { ok: true, group: "dist", command, details };
3625
3625
  }
3626
3626
  case "rebuild-agent": {
3627
- requireNoExtraArgs(rest, "bun run rig dist rebuild-agent");
3627
+ requireNoExtraArgs(rest, "rig dist rebuild-agent");
3628
3628
  const fp = await computeRuntimeImageFingerprint(context.projectRoot);
3629
3629
  const currentId = computeRuntimeImageId(fp);
3630
3630
  const imagesDir = resolve11(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
@@ -3776,6 +3776,414 @@ import {
3776
3776
  readJsonlFile as readJsonlFile3,
3777
3777
  resolveAuthorityRunDir as resolveAuthorityRunDir2
3778
3778
  } from "@rig/runtime/control-plane/authority-files";
3779
+
3780
+ // packages/cli/src/commands/_cli-format.ts
3781
+ import { log as log3, note as note3 } from "@clack/prompts";
3782
+ import pc3 from "picocolors";
3783
+ function stringField(record, key, fallback = "") {
3784
+ const value = record[key];
3785
+ return typeof value === "string" && value.trim() ? value.trim() : fallback;
3786
+ }
3787
+ function numberField(record, key) {
3788
+ const value = record[key];
3789
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
3790
+ }
3791
+ function arrayField(record, key) {
3792
+ const value = record[key];
3793
+ return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
3794
+ }
3795
+ function rawObject(record) {
3796
+ const raw = record.raw;
3797
+ return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
3798
+ }
3799
+ function truncate(value, width) {
3800
+ if (value.length <= width)
3801
+ return value;
3802
+ if (width <= 1)
3803
+ return "\u2026";
3804
+ return `${value.slice(0, width - 1)}\u2026`;
3805
+ }
3806
+ function pad(value, width) {
3807
+ return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
3808
+ }
3809
+ function statusColor(status) {
3810
+ const normalized = status.toLowerCase();
3811
+ if (["completed", "merged", "closed", "done", "accepted", "pass", "selected", "approved"].includes(normalized))
3812
+ return pc3.green;
3813
+ if (["failed", "needs_attention", "needs-attention", "blocked", "error", "rejected"].includes(normalized))
3814
+ return pc3.red;
3815
+ if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
3816
+ return pc3.cyan;
3817
+ if (["ready", "open", "queued", "created", "preparing", "local", "pending"].includes(normalized))
3818
+ return pc3.yellow;
3819
+ return pc3.dim;
3820
+ }
3821
+ function compactDate(value) {
3822
+ if (!value.trim())
3823
+ return "";
3824
+ const parsed = Date.parse(value);
3825
+ if (!Number.isFinite(parsed))
3826
+ return value;
3827
+ return new Date(parsed).toISOString().replace("T", " ").replace(/\.\d{3}Z$/, "Z");
3828
+ }
3829
+ function compactValue(value) {
3830
+ if (value === null || value === undefined)
3831
+ return "";
3832
+ if (typeof value === "string")
3833
+ return value;
3834
+ if (typeof value === "number" || typeof value === "boolean")
3835
+ return String(value);
3836
+ if (Array.isArray(value))
3837
+ return value.map(compactValue).filter(Boolean).join(", ");
3838
+ return JSON.stringify(value);
3839
+ }
3840
+ function firstString(record, keys, fallback = "") {
3841
+ for (const key of keys) {
3842
+ const value = stringField(record, key);
3843
+ if (value)
3844
+ return value;
3845
+ }
3846
+ return fallback;
3847
+ }
3848
+ function runIdOf(run) {
3849
+ return firstString(run, ["runId", "id"], "(unknown-run)");
3850
+ }
3851
+ function taskIdOf(run) {
3852
+ return firstString(run, ["taskId", "task", "task_id"]);
3853
+ }
3854
+ function runTitleOf(run) {
3855
+ return firstString(run, ["title", "summary", "name"], taskIdOf(run) || "(untitled)");
3856
+ }
3857
+ function requestIdOf(entry) {
3858
+ return firstString(entry, ["requestId", "id", "approvalId", "inputId"], "(unknown-request)");
3859
+ }
3860
+ function shouldUseClackOutput() {
3861
+ return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
3862
+ }
3863
+ function printFormattedOutput(message2, options = {}) {
3864
+ if (!shouldUseClackOutput()) {
3865
+ console.log(message2);
3866
+ return;
3867
+ }
3868
+ if (options.title)
3869
+ note3(message2, options.title);
3870
+ else
3871
+ log3.message(message2);
3872
+ }
3873
+ function formatStatusPill(status) {
3874
+ const label = status || "unknown";
3875
+ return statusColor(label)(`\u25CF ${label}`);
3876
+ }
3877
+ function formatSection(title, subtitle) {
3878
+ return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
3879
+ }
3880
+ function formatSuccessCard(title, rows = []) {
3881
+ const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc3.dim("\u2502")} ${pc3.dim(key.padEnd(12))} ${value}`);
3882
+ return [formatSection(title), ...body].join(`
3883
+ `);
3884
+ }
3885
+ function formatNextSteps(steps) {
3886
+ if (steps.length === 0)
3887
+ return [];
3888
+ return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
3889
+ }
3890
+ function formatTaskList(tasks, options = {}) {
3891
+ if (options.raw)
3892
+ return tasks.map((task) => JSON.stringify(task)).join(`
3893
+ `);
3894
+ if (tasks.length === 0)
3895
+ return [formatSection("Tasks", "none found"), ...formatNextSteps(["Try `rig server status` to confirm the selected server.", "Relax filters or run `rig task run --title ... --initial-prompt ...` for ad hoc work."])].join(`
3896
+ `);
3897
+ const rows = tasks.map((task) => {
3898
+ const raw = rawObject(task);
3899
+ const id = stringField(task, "id", "<unknown>");
3900
+ const status = stringField(task, "status", "unknown");
3901
+ const title = stringField(task, "title", "Untitled task");
3902
+ const source = stringField(task, "source", stringField(raw, "source", ""));
3903
+ const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
3904
+ return { id, status, title, source, labels };
3905
+ });
3906
+ const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
3907
+ const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
3908
+ const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
3909
+ const body = rows.map((row) => {
3910
+ const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
3911
+ const source = row.source ? pc3.dim(` ${row.source}`) : "";
3912
+ return [
3913
+ pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
3914
+ statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
3915
+ `${row.title}${labels}${source}`
3916
+ ].join(" ");
3917
+ });
3918
+ return [formatSection("Tasks", `${rows.length} shown`), header, ...body, "", ...formatNextSteps(["Run one: `rig task run <id>` or `rig task run --next`", "Attach later: `rig run attach <run-id> --follow`"])].join(`
3919
+ `);
3920
+ }
3921
+ function formatTaskCard(task, options = {}) {
3922
+ const raw = rawObject(task);
3923
+ const id = stringField(task, "id", stringField(raw, "id", "<unknown>"));
3924
+ const status = stringField(task, "status", stringField(raw, "status", "unknown"));
3925
+ const title = stringField(task, "title", stringField(raw, "title", "Untitled task"));
3926
+ const source = stringField(task, "source", stringField(raw, "source", ""));
3927
+ const url = stringField(task, "url", stringField(raw, "url", ""));
3928
+ const number = numberField(task, "number") ?? numberField(raw, "number");
3929
+ const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
3930
+ const assignees = arrayField(task, "assignees").length > 0 ? arrayField(task, "assignees") : arrayField(raw, "assignees");
3931
+ const readiness = compactValue(task.readiness ?? raw.readiness);
3932
+ const validators = compactValue(task.validators ?? raw.validators ?? task.validation ?? raw.validation);
3933
+ const rows = [
3934
+ ["task", pc3.bold(id)],
3935
+ ["status", formatStatusPill(status)],
3936
+ ["title", title],
3937
+ ["source", source],
3938
+ ["number", number],
3939
+ ["labels", labels.length ? labels.map((label) => `#${label}`).join(" ") : ""],
3940
+ ["assignees", assignees.join(", ")],
3941
+ ["readiness", readiness],
3942
+ ["validators", validators],
3943
+ ["url", url]
3944
+ ];
3945
+ return [
3946
+ formatSuccessCard(options.title ?? (options.selected ? "Selected task" : "Task"), rows),
3947
+ "",
3948
+ ...formatNextSteps([`Start: \`rig task run ${id}\``, `Details: \`rig task show ${id} --raw\``])
3949
+ ].join(`
3950
+ `);
3951
+ }
3952
+ function formatTaskDetails(task) {
3953
+ return formatTaskCard(task, { title: "Task details" });
3954
+ }
3955
+ function formatRunList(runs, options = {}) {
3956
+ if (runs.length === 0) {
3957
+ return [
3958
+ formatSection("Runs", "none recorded"),
3959
+ options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
3960
+ "",
3961
+ ...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
3962
+ ].join(`
3963
+ `);
3964
+ }
3965
+ const rows = runs.map((run) => {
3966
+ const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
3967
+ const status = stringField(run, "status", "unknown");
3968
+ const taskId = stringField(run, "taskId", "");
3969
+ const title = stringField(run, "title", taskId || "(untitled)");
3970
+ const runtime = stringField(run, "runtimeAdapter", "");
3971
+ return { runId, status, title, runtime };
3972
+ });
3973
+ const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
3974
+ const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
3975
+ const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
3976
+ const body = rows.map((row) => [
3977
+ pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
3978
+ statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
3979
+ `${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
3980
+ ].join(" "));
3981
+ 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(`
3982
+ `);
3983
+ }
3984
+ function formatSubmittedRun(input) {
3985
+ const rows = [["run", pc3.bold(input.runId)]];
3986
+ if (input.task) {
3987
+ const id = stringField(input.task, "id", "<unknown>");
3988
+ const status = stringField(input.task, "status", "unknown");
3989
+ const title = stringField(input.task, "title", "Untitled task");
3990
+ rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
3991
+ }
3992
+ const runtime = [input.runtimeAdapter || "pi", input.runtimeMode || "full-access", input.interactionMode || "default"].filter(Boolean).join(" \xB7 ");
3993
+ rows.push(["runtime", runtime]);
3994
+ return [
3995
+ formatSuccessCard("Run submitted", rows),
3996
+ "",
3997
+ ...formatNextSteps([
3998
+ `Attach: \`rig run attach ${input.runId} --follow\``,
3999
+ `Inspect: \`rig run show ${input.runId}\``,
4000
+ input.detached ? "Submitted detached; attach when you are ready." : "Interactive mode opens the native bundled Pi frontend."
4001
+ ])
4002
+ ].join(`
4003
+ `);
4004
+ }
4005
+ function formatRunCard(run, options = {}) {
4006
+ const raw = rawObject(run);
4007
+ const merged = { ...raw, ...run };
4008
+ const runId = runIdOf(merged);
4009
+ const status = firstString(merged, ["status"], "unknown");
4010
+ const taskId = taskIdOf(merged);
4011
+ const title = runTitleOf(merged);
4012
+ const runtime = firstString(merged, ["runtimeAdapter", "runtime", "adapter"]);
4013
+ const mode = firstString(merged, ["runtimeMode", "mode"]);
4014
+ const interaction = firstString(merged, ["interactionMode"]);
4015
+ const created = compactDate(firstString(merged, ["createdAt"]));
4016
+ const started = compactDate(firstString(merged, ["startedAt"]));
4017
+ const updated = compactDate(firstString(merged, ["updatedAt"]));
4018
+ const completed = compactDate(firstString(merged, ["completedAt", "finishedAt"]));
4019
+ const worktree = firstString(merged, ["worktreePath", "cwd", "projectRoot"]);
4020
+ const piSession = merged.piSession && typeof merged.piSession === "object" && !Array.isArray(merged.piSession) ? firstString(merged.piSession, ["sessionId", "id"]) : "";
4021
+ const timeline = Array.isArray(merged.timeline) ? merged.timeline.length : null;
4022
+ const approvals = Array.isArray(merged.approvals) ? merged.approvals.length : null;
4023
+ const inputs = Array.isArray(merged.userInputs) ? merged.userInputs.length : null;
4024
+ const rows = [
4025
+ ["run", pc3.bold(runId)],
4026
+ ["status", formatStatusPill(status)],
4027
+ ["task", taskId],
4028
+ ["title", title],
4029
+ ["runtime", [runtime, mode, interaction].filter(Boolean).join(" \xB7 ")],
4030
+ ["created", created],
4031
+ ["started", started],
4032
+ ["updated", updated],
4033
+ ["completed", completed],
4034
+ ["worktree", worktree],
4035
+ ["pi", piSession],
4036
+ ["timeline", timeline],
4037
+ ["approvals", approvals],
4038
+ ["inputs", inputs]
4039
+ ];
4040
+ return [
4041
+ formatSuccessCard(options.title ?? "Run details", rows),
4042
+ "",
4043
+ ...formatNextSteps([`Follow live: \`rig run attach ${runId} --follow\``, `Raw payload: \`rig run show ${runId} --raw\``])
4044
+ ].join(`
4045
+ `);
4046
+ }
4047
+ function formatRunStatus(summary, options = {}) {
4048
+ const activeRuns = summary.activeRuns ?? [];
4049
+ const recentRuns = summary.recentRuns ?? [];
4050
+ const lines = [formatSection("Run status", options.source === "server" ? "selected server" : "local state")];
4051
+ lines.push("", pc3.bold(`Active runs (${activeRuns.length})`));
4052
+ if (activeRuns.length === 0) {
4053
+ lines.push(pc3.dim("No active runs."));
4054
+ } else {
4055
+ for (const run of activeRuns) {
4056
+ lines.push(formatRunSummaryLine(run));
4057
+ }
4058
+ }
4059
+ lines.push("", pc3.bold(`Recent runs (${recentRuns.length})`));
4060
+ if (recentRuns.length === 0) {
4061
+ lines.push(pc3.dim("No recent terminal runs."));
4062
+ } else {
4063
+ for (const run of recentRuns.slice(0, 10)) {
4064
+ lines.push(formatRunSummaryLine(run));
4065
+ }
4066
+ }
4067
+ lines.push("", ...formatNextSteps(["Start work: `rig task run --next`", "Attach: `rig run attach <run-id> --follow`", "Details: `rig run show <run-id>`"]));
4068
+ return lines.join(`
4069
+ `);
4070
+ }
4071
+ function formatRunSummaryLine(run) {
4072
+ const record = run;
4073
+ const runId = runIdOf(record);
4074
+ const status = firstString(record, ["status"], "unknown");
4075
+ const taskId = taskIdOf(record);
4076
+ const title = runTitleOf(record);
4077
+ const runtime = firstString(record, ["runtimeAdapter", "runtime", "adapter"]);
4078
+ const descriptor = [taskId, title].filter(Boolean).join(" \xB7 ");
4079
+ return `${pc3.dim("\u2502")} ${pc3.bold(runId)} ${formatStatusPill(status)} ${descriptor}${runtime ? pc3.dim(` ${runtime}`) : ""}`;
4080
+ }
4081
+ function formatInboxList(kind, entries) {
4082
+ const title = kind === "approvals" ? "Approval inbox" : "Input inbox";
4083
+ if (entries.length === 0) {
4084
+ return [
4085
+ formatSection(title, "empty"),
4086
+ pc3.dim(kind === "approvals" ? "No pending approvals." : "No pending user-input requests."),
4087
+ "",
4088
+ ...formatNextSteps(["Check runs: `rig run status`", "Start work: `rig task run --next`"])
4089
+ ].join(`
4090
+ `);
4091
+ }
4092
+ const lines = [formatSection(title, `${entries.length} pending`)];
4093
+ for (const entry of entries) {
4094
+ const record = entry.record && typeof entry.record === "object" && !Array.isArray(entry.record) ? entry.record : entry;
4095
+ const runId = firstString(entry, ["runId"], firstString(record, ["runId"]));
4096
+ const taskId = firstString(entry, ["taskId"], firstString(record, ["taskId", "task"]));
4097
+ const requestId = requestIdOf(record);
4098
+ const status = firstString(record, ["status", "state"], "pending");
4099
+ const prompt = firstString(record, ["prompt", "message", "reason", "title", "summary"], kind === "approvals" ? "Approval requested" : "Input requested");
4100
+ lines.push(`${pc3.dim("\u2502")} ${pc3.bold(requestId)} ${formatStatusPill(status)} ${prompt}`);
4101
+ lines.push(`${pc3.dim("\u2502")} ${pc3.dim("run ")} ${runId || "(unknown-run)"}${taskId ? pc3.dim(` task ${taskId}`) : ""}`);
4102
+ }
4103
+ lines.push("", ...formatNextSteps(kind === "approvals" ? ["Resolve: `rig inbox approve --run <run-id> --request <request-id> --decision approve|reject`", "Rejoin: `rig run attach <run-id> --follow`"] : ["Respond: `rig inbox respond --run <run-id> --request <request-id> --answer key=value`", "Rejoin: `rig run attach <run-id> --follow`"]));
4104
+ return lines.join(`
4105
+ `);
4106
+ }
4107
+ function formatConnectionList(connections) {
4108
+ const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
4109
+ const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
4110
+ const lines = rows.map(([alias, connection]) => [
4111
+ pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
4112
+ formatStatusPill(connection.kind),
4113
+ connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
4114
+ ].join(" "));
4115
+ return [formatSection("Rig servers", `${rows.length} available`), `${pc3.bold(pad("ALIAS", aliasWidth))} ${pc3.bold("KIND")} ${pc3.bold("TARGET")}`, ...lines, "", ...formatNextSteps(["Select one: `rig server use <alias|local>`"])].join(`
4116
+ `);
4117
+ }
4118
+ function formatConnectionStatus(selected, connections) {
4119
+ const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
4120
+ const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
4121
+ return [
4122
+ formatSection("Rig server", "selected for this repo"),
4123
+ `${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
4124
+ `${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
4125
+ `${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
4126
+ "",
4127
+ ...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
4128
+ ].join(`
4129
+ `);
4130
+ }
4131
+
4132
+ // packages/cli/src/commands/inbox.ts
4133
+ function isRemoteConnectionSelected(projectRoot) {
4134
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
4135
+ }
4136
+ function runMatches(entry, filters) {
4137
+ const runId = typeof entry.runId === "string" ? entry.runId : typeof entry.id === "string" ? entry.id : "";
4138
+ const taskId = typeof entry.taskId === "string" ? entry.taskId : "";
4139
+ return (!filters.run || runId === filters.run) && (!filters.task || taskId === filters.task);
4140
+ }
4141
+ function normalizeRemoteRunDetails(payload) {
4142
+ const run = payload.run;
4143
+ if (run && typeof run === "object" && !Array.isArray(run)) {
4144
+ return {
4145
+ ...run,
4146
+ ...Array.isArray(payload.timeline) ? { timeline: payload.timeline } : {},
4147
+ ...Array.isArray(payload.approvals) ? { approvals: payload.approvals } : {},
4148
+ ...Array.isArray(payload.userInputs) ? { userInputs: payload.userInputs } : {}
4149
+ };
4150
+ }
4151
+ return payload;
4152
+ }
4153
+ function remoteRecordsFromRun(run, kind) {
4154
+ const key = kind === "approvals" ? "approvals" : "userInputs";
4155
+ const direct = run[key];
4156
+ if (!Array.isArray(direct))
4157
+ return [];
4158
+ const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
4159
+ const taskId = typeof run.taskId === "string" ? run.taskId : "";
4160
+ return direct.filter((record) => Boolean(record && typeof record === "object" && !Array.isArray(record))).map((record) => ({ runId, taskId, record }));
4161
+ }
4162
+ async function listRemoteInboxRecords(context, kind, filters) {
4163
+ const runs = (await listRunsViaServer(context, { limit: 100 })).filter((entry) => runMatches(entry, filters));
4164
+ const records = [];
4165
+ for (const run of runs) {
4166
+ const runId = typeof run.runId === "string" ? run.runId : typeof run.id === "string" ? run.id : "";
4167
+ const detailed = runId ? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, runId).catch(() => run)) : run;
4168
+ records.push(...remoteRecordsFromRun(detailed, kind));
4169
+ }
4170
+ return records;
4171
+ }
4172
+ function listLocalInboxRecords(context, kind, filters) {
4173
+ const fileName = kind === "approvals" ? "approvals.jsonl" : "user-input.jsonl";
4174
+ const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!filters.run || entry.runId === filters.run) && (!filters.task || entry.taskId === filters.task));
4175
+ return runs.flatMap((entry) => readJsonlFile3(resolve12(resolveAuthorityRunDir2(context.projectRoot, entry.runId), fileName)).map((record) => ({
4176
+ runId: entry.runId,
4177
+ taskId: entry.taskId ?? undefined,
4178
+ record
4179
+ })));
4180
+ }
4181
+ async function listInboxRecords(context, kind, filters) {
4182
+ if (isRemoteConnectionSelected(context.projectRoot)) {
4183
+ return listRemoteInboxRecords(context, kind, filters);
4184
+ }
4185
+ return listLocalInboxRecords(context, kind, filters);
4186
+ }
3779
4187
  async function executeInbox(context, args) {
3780
4188
  const [command = "approvals", ...rest] = args;
3781
4189
  switch (command) {
@@ -3785,16 +4193,10 @@ async function executeInbox(context, args) {
3785
4193
  pending = run.rest;
3786
4194
  const task = takeOption(pending, "--task");
3787
4195
  pending = task.rest;
3788
- requireNoExtraArgs(pending, "bun run rig inbox approvals [--run <id>] [--task <id>]");
3789
- const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!run.value || entry.runId === run.value) && (!task.value || entry.taskId === task.value));
3790
- const approvals = runs.flatMap((entry) => readJsonlFile3(resolve12(resolveAuthorityRunDir2(context.projectRoot, entry.runId), "approvals.jsonl")).map((record) => ({
3791
- runId: entry.runId,
3792
- record
3793
- })));
4196
+ requireNoExtraArgs(pending, "rig inbox approvals [--run <id>] [--task <id>]");
4197
+ const approvals = await listInboxRecords(context, "approvals", { run: run.value, task: task.value });
3794
4198
  if (context.outputMode === "text") {
3795
- for (const approval of approvals) {
3796
- console.log(JSON.stringify(approval));
3797
- }
4199
+ printFormattedOutput(formatInboxList("approvals", approvals));
3798
4200
  }
3799
4201
  return { ok: true, group: "inbox", command, details: { approvals } };
3800
4202
  }
@@ -3806,19 +4208,22 @@ async function executeInbox(context, args) {
3806
4208
  pending = request.rest;
3807
4209
  const decision = takeOption(pending, "--decision");
3808
4210
  pending = decision.rest;
3809
- const note3 = takeOption(pending, "--note");
3810
- pending = note3.rest;
3811
- requireNoExtraArgs(pending, "bun run rig inbox approve --run <id> --request <id> --decision approve|reject [--note <text>]");
4211
+ const note4 = takeOption(pending, "--note");
4212
+ pending = note4.rest;
4213
+ requireNoExtraArgs(pending, "rig inbox approve --run <id> --request <id> --decision approve|reject [--note <text>]");
3812
4214
  if (!run.value || !request.value || !decision.value) {
3813
4215
  throw new CliError2("approve requires --run, --request, and --decision.");
3814
4216
  }
3815
4217
  if (decision.value !== "approve" && decision.value !== "reject") {
3816
4218
  throw new CliError2("decision must be approve or reject.");
3817
4219
  }
4220
+ if (isRemoteConnectionSelected(context.projectRoot)) {
4221
+ throw new CliError2("Remote approval resolution is not available from this CLI yet; use the server UI/API or switch to local state for direct JSONL edits.", 2);
4222
+ }
3818
4223
  const approvalsPath = resolve12(resolveAuthorityRunDir2(context.projectRoot, run.value), "approvals.jsonl");
3819
4224
  const approvals = readJsonlFile3(approvalsPath);
3820
4225
  const resolvedAt = new Date().toISOString();
3821
- const next = approvals.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", decision: decision.value, note: note3.value ?? null, resolvedAt } : entry);
4226
+ const next = approvals.map((entry) => entry.requestId === request.value || entry.id === request.value ? { ...entry, status: "resolved", decision: decision.value, note: note4.value ?? null, resolvedAt } : entry);
3822
4227
  writeFileSync4(approvalsPath, `${next.map((entry) => JSON.stringify(entry)).join(`
3823
4228
  `)}
3824
4229
  `, "utf8");
@@ -3830,16 +4235,10 @@ async function executeInbox(context, args) {
3830
4235
  pending = run.rest;
3831
4236
  const task = takeOption(pending, "--task");
3832
4237
  pending = task.rest;
3833
- requireNoExtraArgs(pending, "bun run rig inbox inputs [--run <id>] [--task <id>]");
3834
- const runs = listAuthorityRuns(context.projectRoot).filter((entry) => (!run.value || entry.runId === run.value) && (!task.value || entry.taskId === task.value));
3835
- const requests = runs.flatMap((entry) => readJsonlFile3(resolve12(resolveAuthorityRunDir2(context.projectRoot, entry.runId), "user-input.jsonl")).map((record) => ({
3836
- runId: entry.runId,
3837
- record
3838
- })));
4238
+ requireNoExtraArgs(pending, "rig inbox inputs [--run <id>] [--task <id>]");
4239
+ const requests = await listInboxRecords(context, "inputs", { run: run.value, task: task.value });
3839
4240
  if (context.outputMode === "text") {
3840
- for (const request of requests) {
3841
- console.log(JSON.stringify(request));
3842
- }
4241
+ printFormattedOutput(formatInboxList("inputs", requests));
3843
4242
  }
3844
4243
  return { ok: true, group: "inbox", command, details: { requests } };
3845
4244
  }
@@ -3866,10 +4265,13 @@ async function executeInbox(context, args) {
3866
4265
  remaining.push(current);
3867
4266
  }
3868
4267
  }
3869
- requireNoExtraArgs(remaining, "bun run rig inbox respond --run <id> --request <id> --answer key=value [--answer key=value]");
4268
+ requireNoExtraArgs(remaining, "rig inbox respond --run <id> --request <id> --answer key=value [--answer key=value]");
3870
4269
  if (!run.value || !request.value || answers.length === 0) {
3871
4270
  throw new CliError2("respond requires --run, --request, and at least one --answer.");
3872
4271
  }
4272
+ if (isRemoteConnectionSelected(context.projectRoot)) {
4273
+ throw new CliError2("Remote input responses are not available from this CLI yet; use the server UI/API or switch to local state for direct JSONL edits.", 2);
4274
+ }
3873
4275
  const parsedAnswers = Object.fromEntries(answers.map((entry) => {
3874
4276
  const [key, ...restValue] = entry.split("=");
3875
4277
  return [key, restValue.join("=")];
@@ -4293,7 +4695,7 @@ async function runRigDoctorChecks(options) {
4293
4695
  const taskSourceKind = config?.taskSource?.kind;
4294
4696
  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."));
4295
4697
  const repo = readRepoConnection(projectRoot);
4296
- checks.push(repo ? check("project-link", "repo selected Rig connection", 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 connection", "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig connect use <alias|local>`."));
4698
+ 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>`."));
4297
4699
  const selected = (() => {
4298
4700
  try {
4299
4701
  return resolveSelectedConnection(projectRoot);
@@ -4301,7 +4703,7 @@ async function runRigDoctorChecks(options) {
4301
4703
  return null;
4302
4704
  }
4303
4705
  })();
4304
- checks.push(selected ? check("connection", "selected server connection", "pass", selected.connection.kind === "remote" ? selected.connection.baseUrl : "local auto") : check("connection", "selected server connection", repo ? "fail" : "warn", repo ? "selected alias is missing" : "will auto-start local server", repo ? "Run `rig connect list` and `rig connect use <alias|local>`." : undefined));
4706
+ 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));
4305
4707
  let server = null;
4306
4708
  try {
4307
4709
  server = await (options.resolveServer ?? ensureServerForCli)(projectRoot);
@@ -5110,179 +5512,24 @@ Usage: rig init`, 1);
5110
5512
 
5111
5513
  // packages/cli/src/commands/connect.ts
5112
5514
  import { cancel as cancel2, isCancel as isCancel2, select as select2 } from "@clack/prompts";
5113
-
5114
- // packages/cli/src/commands/_cli-format.ts
5115
- import pc3 from "picocolors";
5116
- function stringField(record, key, fallback = "") {
5117
- const value = record[key];
5118
- return typeof value === "string" && value.trim() ? value.trim() : fallback;
5119
- }
5120
- function arrayField(record, key) {
5121
- const value = record[key];
5122
- return Array.isArray(value) ? value.flatMap((entry) => typeof entry === "string" && entry.trim() ? [entry.trim()] : []) : [];
5515
+ function usageName(options) {
5516
+ return `rig ${options.group}`;
5123
5517
  }
5124
- function rawObject(record) {
5125
- const raw = record.raw;
5126
- return raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
5127
- }
5128
- function truncate(value, width) {
5129
- if (value.length <= width)
5130
- return value;
5131
- if (width <= 1)
5132
- return "\u2026";
5133
- return `${value.slice(0, width - 1)}\u2026`;
5134
- }
5135
- function pad(value, width) {
5136
- return value.length >= width ? value : `${value}${" ".repeat(width - value.length)}`;
5137
- }
5138
- function statusColor(status) {
5139
- const normalized = status.toLowerCase();
5140
- if (["completed", "merged", "closed", "done", "accepted", "pass", "selected"].includes(normalized))
5141
- return pc3.green;
5142
- if (["failed", "needs_attention", "needs-attention", "blocked", "error"].includes(normalized))
5143
- return pc3.red;
5144
- if (["running", "reviewing", "validating", "in_progress", "in-progress", "remote"].includes(normalized))
5145
- return pc3.cyan;
5146
- if (["ready", "open", "queued", "created", "preparing", "local"].includes(normalized))
5147
- return pc3.yellow;
5148
- return pc3.dim;
5149
- }
5150
- function formatStatusPill(status) {
5151
- const label = status || "unknown";
5152
- return statusColor(label)(`\u25CF ${label}`);
5153
- }
5154
- function formatSection(title, subtitle) {
5155
- return `${pc3.bold(pc3.cyan("\u25C6"))} ${pc3.bold(title)}${subtitle ? pc3.dim(` \u2014 ${subtitle}`) : ""}`;
5156
- }
5157
- function formatSuccessCard(title, rows = []) {
5158
- const body = rows.filter(([, value]) => value !== undefined && value !== null && String(value).length > 0).map(([key, value]) => `${pc3.dim("\u2502")} ${pc3.dim(key.padEnd(9))} ${value}`);
5159
- return [formatSection(title), ...body].join(`
5160
- `);
5161
- }
5162
- function formatNextSteps(steps) {
5163
- if (steps.length === 0)
5164
- return [];
5165
- return [pc3.bold("Next"), ...steps.map((step) => `${pc3.dim("\u203A")} ${step}`)];
5166
- }
5167
- function formatTaskList(tasks, options = {}) {
5168
- if (options.raw)
5169
- return tasks.map((task) => JSON.stringify(task)).join(`
5170
- `);
5171
- if (tasks.length === 0)
5172
- return [formatSection("Tasks", "none found"), ...formatNextSteps(["Try `rig server status` to confirm the selected server.", "Relax filters or run `rig task run --title ... --initial-prompt ...` for ad hoc work."])].join(`
5173
- `);
5174
- const rows = tasks.map((task) => {
5175
- const raw = rawObject(task);
5176
- const id = stringField(task, "id", "<unknown>");
5177
- const status = stringField(task, "status", "unknown");
5178
- const title = stringField(task, "title", "Untitled task");
5179
- const source = stringField(task, "source", stringField(raw, "source", ""));
5180
- const labels = arrayField(task, "labels").length > 0 ? arrayField(task, "labels") : arrayField(raw, "labels");
5181
- return { id, status, title, source, labels };
5182
- });
5183
- const idWidth = Math.min(18, Math.max(4, ...rows.map((row) => row.id.length)));
5184
- const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
5185
- const header = `${pc3.bold(pad("TASK", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
5186
- const body = rows.map((row) => {
5187
- const labels = row.labels.length > 0 ? pc3.dim(` ${row.labels.slice(0, 4).map((label) => `#${label}`).join(" ")}`) : "";
5188
- const source = row.source ? pc3.dim(` ${row.source}`) : "";
5189
- return [
5190
- pc3.bold(pad(truncate(row.id, idWidth), idWidth)),
5191
- statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
5192
- `${row.title}${labels}${source}`
5193
- ].join(" ");
5194
- });
5195
- return [formatSection("Tasks", `${rows.length} shown`), header, ...body, "", ...formatNextSteps(["Run one: `rig task run <id>` or `rig task run --next`", "Attach later: `rig run attach <run-id> --follow`"])].join(`
5196
- `);
5197
- }
5198
- function formatRunList(runs, options = {}) {
5199
- if (runs.length === 0) {
5200
- return [
5201
- formatSection("Runs", "none recorded"),
5202
- options.source === "server" ? pc3.dim("No runs recorded on the selected Rig server.") : pc3.dim("No runs recorded in .rig/runs."),
5203
- "",
5204
- ...formatNextSteps(["Start one: `rig task run --next`", "Check server: `rig server status`"])
5205
- ].join(`
5206
- `);
5207
- }
5208
- const rows = runs.map((run) => {
5209
- const runId = stringField(run, "runId", stringField(run, "id", "(unknown-run)"));
5210
- const status = stringField(run, "status", "unknown");
5211
- const taskId = stringField(run, "taskId", "");
5212
- const title = stringField(run, "title", taskId || "(untitled)");
5213
- const runtime = stringField(run, "runtimeAdapter", "");
5214
- return { runId, status, title, runtime };
5215
- });
5216
- const idWidth = Math.min(36, Math.max(6, ...rows.map((row) => row.runId.length)));
5217
- const statusWidth = Math.min(16, Math.max(6, ...rows.map((row) => row.status.length)));
5218
- const header = `${pc3.bold(pad("RUN", idWidth))} ${pc3.bold(pad("STATUS", statusWidth))} ${pc3.bold("TITLE")}`;
5219
- const body = rows.map((row) => [
5220
- pc3.bold(pad(truncate(row.runId, idWidth), idWidth)),
5221
- statusColor(row.status)(pad(truncate(row.status, statusWidth), statusWidth)),
5222
- `${row.title}${row.runtime ? pc3.dim(` ${row.runtime}`) : ""}`
5223
- ].join(" "));
5224
- 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 <run-id>`"])].join(`
5225
- `);
5226
- }
5227
- function formatSubmittedRun(input) {
5228
- const rows = [["run", pc3.bold(input.runId)]];
5229
- if (input.task) {
5230
- const id = stringField(input.task, "id", "<unknown>");
5231
- const status = stringField(input.task, "status", "unknown");
5232
- const title = stringField(input.task, "title", "Untitled task");
5233
- rows.push(["task", `${pc3.bold(id)} ${formatStatusPill(status)} ${title}`]);
5234
- }
5235
- return [
5236
- formatSuccessCard("Run submitted", rows),
5237
- "",
5238
- ...formatNextSteps([`Attach: \`rig run attach ${input.runId} --follow\``, `Inspect: \`rig run show --run ${input.runId}\``])
5239
- ].join(`
5240
- `);
5241
- }
5242
- function formatConnectionList(connections) {
5243
- const rows = [["local", { kind: "local", mode: "auto" }], ...Object.entries(connections)];
5244
- const aliasWidth = Math.min(24, Math.max(5, ...rows.map(([alias]) => alias.length)));
5245
- const lines = rows.map(([alias, connection]) => [
5246
- pc3.bold(pad(truncate(alias, aliasWidth), aliasWidth)),
5247
- formatStatusPill(connection.kind),
5248
- connection.kind === "remote" ? connection.baseUrl ?? "" : connection.mode ?? "local"
5249
- ].join(" "));
5250
- return [formatSection("Rig servers", `${rows.length} available`), `${pc3.bold(pad("ALIAS", aliasWidth))} ${pc3.bold("KIND")} ${pc3.bold("TARGET")}`, ...lines, "", ...formatNextSteps(["Select one: `rig server use <alias|local>`"])].join(`
5251
- `);
5252
- }
5253
- function formatConnectionStatus(selected, connections) {
5254
- const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
5255
- const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
5256
- return [
5257
- formatSection("Rig server", "selected for this repo"),
5258
- `${pc3.dim("\u2502")} ${pc3.dim("selected ")} ${pc3.bold(selected)}`,
5259
- `${pc3.dim("\u2502")} ${pc3.dim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
5260
- `${pc3.dim("\u2502")} ${pc3.dim("target ")} ${target ?? "not configured"}`,
5261
- "",
5262
- ...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
5263
- ].join(`
5264
- `);
5265
- }
5266
-
5267
- // packages/cli/src/commands/connect.ts
5268
- function usageName(options) {
5269
- return `rig ${options.group}`;
5270
- }
5271
- function parseConnection(alias, value, options) {
5272
- if (alias === "local" && !value)
5273
- return { kind: "local", mode: "auto" };
5274
- if (!value)
5275
- throw new CliError2(`Missing remote server URL. Usage: ${usageName(options)} add <alias> <url>`, 1);
5276
- let parsed;
5277
- try {
5278
- parsed = new URL(value);
5279
- } catch {
5280
- throw new CliError2(`Invalid Rig server URL: ${value}`, 1);
5281
- }
5282
- if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
5283
- throw new CliError2("Rig remote server URL must be http(s).", 1);
5284
- }
5285
- return { kind: "remote", baseUrl: parsed.toString().replace(/\/+$/, "") };
5518
+ function parseConnection(alias, value, options) {
5519
+ if (alias === "local" && !value)
5520
+ return { kind: "local", mode: "auto" };
5521
+ if (!value)
5522
+ throw new CliError2(`Missing remote server URL. Usage: ${usageName(options)} add <alias> <url>`, 1);
5523
+ let parsed;
5524
+ try {
5525
+ parsed = new URL(value);
5526
+ } catch {
5527
+ throw new CliError2(`Invalid Rig server URL: ${value}`, 1);
5528
+ }
5529
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
5530
+ throw new CliError2("Rig remote server URL must be http(s).", 1);
5531
+ }
5532
+ return { kind: "remote", baseUrl: parsed.toString().replace(/\/+$/, "") };
5286
5533
  }
5287
5534
  function printJsonOrText(context, payload, text2) {
5288
5535
  if (context.outputMode === "json") {
@@ -5689,8 +5936,8 @@ async function executeInspect(context, args) {
5689
5936
  switch (command) {
5690
5937
  case "logs": {
5691
5938
  const { value: task, rest: remaining } = takeOption(rest, "--task");
5692
- requireNoExtraArgs(remaining, "bun run rig inspect logs --task <beads-id>");
5693
- const requiredTask = requireTask(task, "bun run rig inspect logs --task <beads-id>");
5939
+ requireNoExtraArgs(remaining, "rig inspect logs --task <task-id>");
5940
+ const requiredTask = requireTask(task, "rig inspect logs --task <task-id>");
5694
5941
  const latestRun = listAuthorityRuns2(context.projectRoot).map((entry) => readAuthorityRun3(context.projectRoot, entry.runId)).filter((run) => Boolean(run)).filter((run) => run.taskId === requiredTask).sort((left, right) => String(right.updatedAt ?? "").localeCompare(String(left.updatedAt ?? "")))[0];
5695
5942
  if (!latestRun) {
5696
5943
  throw new CliError2(`No runs found for ${requiredTask}.`);
@@ -5704,8 +5951,8 @@ async function executeInspect(context, args) {
5704
5951
  }
5705
5952
  case "artifacts": {
5706
5953
  const { value: task, rest: remaining } = takeOption(rest, "--task");
5707
- requireNoExtraArgs(remaining, "bun run rig inspect artifacts --task <beads-id>");
5708
- const requiredTask = requireTask(task, "bun run rig inspect artifacts --task <beads-id>");
5954
+ requireNoExtraArgs(remaining, "rig inspect artifacts --task <task-id>");
5955
+ const requiredTask = requireTask(task, "rig inspect artifacts --task <task-id>");
5709
5956
  const artifactRoot = resolveTaskArtifactDirs(context.projectRoot, requiredTask).find((path) => existsSync10(path));
5710
5957
  if (!artifactRoot) {
5711
5958
  throw new CliError2(`No artifacts found for ${requiredTask}.`);
@@ -5719,8 +5966,8 @@ async function executeInspect(context, args) {
5719
5966
  previewPending = task.rest;
5720
5967
  const file = takeOption(previewPending, "--file");
5721
5968
  previewPending = file.rest;
5722
- requireNoExtraArgs(previewPending, "bun run rig inspect artifact --task <beads-id> --file <name>");
5723
- const requiredTask = requireTask(task.value, "bun run rig inspect artifact --task <beads-id> --file <name>");
5969
+ requireNoExtraArgs(previewPending, "rig inspect artifact --task <task-id> --file <name>");
5970
+ const requiredTask = requireTask(task.value, "rig inspect artifact --task <task-id> --file <name>");
5724
5971
  if (!file.value) {
5725
5972
  throw new CliError2("Missing --file for rig inspect artifact.");
5726
5973
  }
@@ -5749,7 +5996,7 @@ async function executeInspect(context, args) {
5749
5996
  }
5750
5997
  case "diff": {
5751
5998
  const { value: task, rest: remaining } = takeOption(rest, "--task");
5752
- requireNoExtraArgs(remaining, "bun run rig inspect diff [--task <beads-id>]");
5999
+ requireNoExtraArgs(remaining, "rig inspect diff [--task <task-id>]");
5753
6000
  if (task) {
5754
6001
  const files = changedFilesForTask(context.projectRoot, task, false);
5755
6002
  for (const file of files) {
@@ -5761,7 +6008,7 @@ async function executeInspect(context, args) {
5761
6008
  return { ok: true, group: "inspect", command, details: { task: task || null } };
5762
6009
  }
5763
6010
  case "failures": {
5764
- requireNoExtraArgs(rest, "bun run rig inspect failures");
6011
+ requireNoExtraArgs(rest, "rig inspect failures");
5765
6012
  const failed = resolveHarnessPaths2(context.projectRoot).failedApproachesPath;
5766
6013
  if (!existsSync10(failed)) {
5767
6014
  console.log("No failures recorded.");
@@ -5771,7 +6018,7 @@ async function executeInspect(context, args) {
5771
6018
  return { ok: true, group: "inspect", command };
5772
6019
  }
5773
6020
  case "graph":
5774
- requireNoExtraArgs(rest, "bun run rig inspect graph");
6021
+ requireNoExtraArgs(rest, "rig inspect graph");
5775
6022
  {
5776
6023
  const monorepoRoot = resolveMonorepoRoot2(context.projectRoot);
5777
6024
  const result = runCapture3(["br", "--no-db", "list", "--pretty"], monorepoRoot);
@@ -5782,7 +6029,7 @@ async function executeInspect(context, args) {
5782
6029
  }
5783
6030
  return { ok: true, group: "inspect", command };
5784
6031
  case "audit": {
5785
- requireNoExtraArgs(rest, "bun run rig inspect audit");
6032
+ requireNoExtraArgs(rest, "rig inspect audit");
5786
6033
  const auditPath = resolve18(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
5787
6034
  if (!existsSync10(auditPath)) {
5788
6035
  console.log("No audit log found.");
@@ -5841,7 +6088,7 @@ async function executeInspector(context, args) {
5841
6088
  pending = secondsResult.rest;
5842
6089
  const pollMsResult = takeOption(pending, "--poll-ms");
5843
6090
  pending = pollMsResult.rest;
5844
- requireNoExtraArgs(pending, "bun run rig inspector stream [--once] [--seconds <n>] [--poll-ms <n>]");
6091
+ requireNoExtraArgs(pending, "rig inspector stream [--once] [--seconds <n>] [--poll-ms <n>]");
5845
6092
  const seconds = secondsResult.value ? parseRequiredPositiveInt(secondsResult.value, "--seconds") : null;
5846
6093
  const pollMs = pollMsResult.value ? parseRequiredPositiveInt(pollMsResult.value, "--poll-ms") : null;
5847
6094
  if (context.outputMode === "json" && !onceResult.value && !seconds) {
@@ -5935,7 +6182,7 @@ async function executeInspector(context, args) {
5935
6182
  let pending = rest;
5936
6183
  const scanIdResult = takeOption(pending, "--scan-id");
5937
6184
  pending = scanIdResult.rest;
5938
- requireNoExtraArgs(pending, "bun run rig inspector scan-upstream-drift [--scan-id <id>]");
6185
+ requireNoExtraArgs(pending, "rig inspector scan-upstream-drift [--scan-id <id>]");
5939
6186
  const connection = await ensureLocalRigServerConnection2(context.projectRoot);
5940
6187
  const response = await fetch(new URL("/api/inspector/tools/invoke", connection.baseUrl), {
5941
6188
  method: "POST",
@@ -6046,7 +6293,7 @@ async function executeRemote(context, args) {
6046
6293
  const [subcommand = "list", ...subRest] = rest;
6047
6294
  switch (subcommand) {
6048
6295
  case "list": {
6049
- requireNoExtraArgs(subRest, "bun run rig remote endpoint list");
6296
+ requireNoExtraArgs(subRest, "rig remote endpoint list");
6050
6297
  const endpoints = listManagedRemoteEndpoints(undefined, context.projectRoot);
6051
6298
  const redactedEndpoints = endpoints.map((endpoint2) => redactRemoteEndpoint(endpoint2));
6052
6299
  if (context.outputMode === "text") {
@@ -6070,7 +6317,7 @@ async function executeRemote(context, args) {
6070
6317
  pending2 = port.rest;
6071
6318
  const token = takeOption(pending2, "--token");
6072
6319
  pending2 = token.rest;
6073
- requireNoExtraArgs(pending2, "bun run rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>");
6320
+ requireNoExtraArgs(pending2, "rig remote endpoint add --alias <a> --host <h> --port <n> --token <t>");
6074
6321
  if (!alias.value || !host.value || !token.value || !port.value) {
6075
6322
  throw new CliError2("remote endpoint add requires --alias, --host, --port, and --token.");
6076
6323
  }
@@ -6097,7 +6344,7 @@ async function executeRemote(context, args) {
6097
6344
  pending2 = port.rest;
6098
6345
  const token = takeOption(pending2, "--token");
6099
6346
  pending2 = token.rest;
6100
- requireNoExtraArgs(pending2, "bun run rig remote endpoint update --id <id> [--alias <a>] [--host <h>] [--port <n>] [--token <t>]");
6347
+ requireNoExtraArgs(pending2, "rig remote endpoint update --id <id> [--alias <a>] [--host <h>] [--port <n>] [--token <t>]");
6101
6348
  if (!endpointId.value && !alias.value) {
6102
6349
  throw new CliError2("remote endpoint update requires --id <id> or --alias <a>.");
6103
6350
  }
@@ -6120,7 +6367,7 @@ async function executeRemote(context, args) {
6120
6367
  let pending2 = subRest;
6121
6368
  const alias = takeOption(pending2, "--alias");
6122
6369
  pending2 = alias.rest;
6123
- requireNoExtraArgs(pending2, "bun run rig remote endpoint remove --alias <a>");
6370
+ requireNoExtraArgs(pending2, "rig remote endpoint remove --alias <a>");
6124
6371
  if (!alias.value) {
6125
6372
  throw new CliError2("remote endpoint remove requires --alias.");
6126
6373
  }
@@ -6137,7 +6384,7 @@ async function executeRemote(context, args) {
6137
6384
  let pending2 = subRest;
6138
6385
  const alias = takeOption(pending2, "--alias");
6139
6386
  pending2 = alias.rest;
6140
- requireNoExtraArgs(pending2, "bun run rig remote endpoint test --alias <a>");
6387
+ requireNoExtraArgs(pending2, "rig remote endpoint test --alias <a>");
6141
6388
  if (!alias.value) {
6142
6389
  throw new CliError2("remote endpoint test requires --alias.");
6143
6390
  }
@@ -6168,7 +6415,7 @@ async function executeRemote(context, args) {
6168
6415
  }
6169
6416
  }
6170
6417
  case "migrate": {
6171
- requireNoExtraArgs(subRest, "bun run rig remote endpoint migrate");
6418
+ requireNoExtraArgs(subRest, "rig remote endpoint migrate");
6172
6419
  const result = migrateManagedRemoteEndpoints(context.projectRoot);
6173
6420
  if (context.outputMode === "text") {
6174
6421
  console.log(`Imported ${result.imported} endpoint(s) from ${result.sourcePath}${result.skipped > 0 ? `, skipped ${result.skipped}` : ""}.`);
@@ -6176,7 +6423,7 @@ async function executeRemote(context, args) {
6176
6423
  return { ok: true, group: "remote", command: "endpoint migrate", details: result };
6177
6424
  }
6178
6425
  case "doctor": {
6179
- requireNoExtraArgs(subRest, "bun run rig remote endpoint doctor");
6426
+ requireNoExtraArgs(subRest, "rig remote endpoint doctor");
6180
6427
  const result = doctorManagedRemoteEndpoints(context.projectRoot);
6181
6428
  if (context.outputMode === "text") {
6182
6429
  console.log(JSON.stringify(result, null, 2));
@@ -6229,17 +6476,17 @@ async function executeRemote(context, args) {
6229
6476
  try {
6230
6477
  switch (command) {
6231
6478
  case "test": {
6232
- requireNoExtraArgs(pending, "bun run rig remote test [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6479
+ requireNoExtraArgs(pending, "rig remote test [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6233
6480
  const response = await withClient((client) => client.ping());
6234
6481
  return { ok: true, group: "remote", command, details: toDetails(response) };
6235
6482
  }
6236
6483
  case "status": {
6237
- requireNoExtraArgs(pending, "bun run rig remote status [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6484
+ requireNoExtraArgs(pending, "rig remote status [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6238
6485
  const response = await withClient((client) => client.getState());
6239
6486
  return { ok: true, group: "remote", command, details: toDetails(response) };
6240
6487
  }
6241
6488
  case "tasks": {
6242
- requireNoExtraArgs(pending, "bun run rig remote tasks [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6489
+ requireNoExtraArgs(pending, "rig remote tasks [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6243
6490
  const response = await withClient((client) => client.getTasks());
6244
6491
  return { ok: true, group: "remote", command, details: toDetails(response) };
6245
6492
  }
@@ -6249,7 +6496,7 @@ async function executeRemote(context, args) {
6249
6496
  watchPending = secondsResult.rest;
6250
6497
  const eventResult = takeOption(watchPending, "--event");
6251
6498
  watchPending = eventResult.rest;
6252
- requireNoExtraArgs(watchPending, "bun run rig remote watch [--seconds <n>] [--event <type>] [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6499
+ requireNoExtraArgs(watchPending, "rig remote watch [--seconds <n>] [--event <type>] [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]");
6253
6500
  const seconds = parseOptionalPositiveInt(secondsResult.value, "--seconds");
6254
6501
  const eventFilter = eventResult.value || undefined;
6255
6502
  if (context.outputMode === "json" && !seconds) {
@@ -6318,7 +6565,7 @@ async function executeRemote(context, args) {
6318
6565
  case "stop":
6319
6566
  case "continue":
6320
6567
  case "refresh": {
6321
- requireNoExtraArgs(pending, `bun run rig remote ${command} [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6568
+ requireNoExtraArgs(pending, `rig remote ${command} [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6322
6569
  const response = await withClient(async (client) => {
6323
6570
  switch (command) {
6324
6571
  case "pause":
@@ -6341,7 +6588,7 @@ async function executeRemote(context, args) {
6341
6588
  let countPending = pending;
6342
6589
  const countResult = takeOption(countPending, "--count");
6343
6590
  countPending = countResult.rest;
6344
- requireNoExtraArgs(countPending, `bun run rig remote ${command} --count <n> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6591
+ requireNoExtraArgs(countPending, `rig remote ${command} --count <n> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6345
6592
  const count = parseRequiredPositiveInt(countResult.value, "--count");
6346
6593
  const response = await withClient(async (client) => command === "add-iterations" ? await client.addIterations(count) : await client.removeIterations(count));
6347
6594
  assertRemoteOperationSuccess(command, response);
@@ -6352,8 +6599,8 @@ async function executeRemote(context, args) {
6352
6599
  let taskPending = pending;
6353
6600
  const taskResult = takeOption(taskPending, "--task");
6354
6601
  taskPending = taskResult.rest;
6355
- requireNoExtraArgs(taskPending, `bun run rig remote ${command} --task <id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6356
- const taskId = requireTask(taskResult.value, `bun run rig remote ${command} --task <id>`);
6602
+ requireNoExtraArgs(taskPending, `rig remote ${command} --task <id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6603
+ const taskId = requireTask(taskResult.value, `rig remote ${command} --task <id>`);
6357
6604
  const response = await withClient(async (client) => command === "prompt-preview" ? await client.getPromptPreview(taskId) : await client.getIterationOutput(taskId));
6358
6605
  assertRemoteOperationSuccess(command, response);
6359
6606
  return { ok: true, group: "remote", command, details: toDetails(response) };
@@ -6366,7 +6613,7 @@ async function executeRemote(context, args) {
6366
6613
  orchestrationPending = maxIterationsResult.rest;
6367
6614
  const directMergeResult = takeFlag(orchestrationPending, "--direct-merge");
6368
6615
  orchestrationPending = directMergeResult.rest;
6369
- requireNoExtraArgs(orchestrationPending, "bun run rig remote orchestrate-start [--max-workers <n>] [--max-iterations <n>] [--direct-merge]");
6616
+ requireNoExtraArgs(orchestrationPending, "rig remote orchestrate-start [--max-workers <n>] [--max-iterations <n>] [--direct-merge]");
6370
6617
  const response = await withClient((client) => client.startOrchestration({
6371
6618
  maxWorkers: parseOptionalPositiveInt(maxWorkersResult.value, "--max-workers"),
6372
6619
  maxIterations: parseOptionalPositiveInt(maxIterationsResult.value, "--max-iterations"),
@@ -6387,8 +6634,8 @@ async function executeRemote(context, args) {
6387
6634
  let orchestrationPending = pending;
6388
6635
  const idResult = takeOption(orchestrationPending, "--id");
6389
6636
  orchestrationPending = idResult.rest;
6390
- requireNoExtraArgs(orchestrationPending, `bun run rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6391
- const orchestrationId = requireTask(idResult.value, `bun run rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6637
+ requireNoExtraArgs(orchestrationPending, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6638
+ const orchestrationId = requireTask(idResult.value, `rig remote ${command} --id <orch-id> [--remote <alias>] [--host <host>] [--port <n>] [--token <token>]`);
6392
6639
  const response = await withClient(async (client) => {
6393
6640
  switch (command) {
6394
6641
  case "orchestrate-pause":
@@ -6452,8 +6699,8 @@ var CANONICAL_STAGES = [
6452
6699
  "Merge",
6453
6700
  "Complete"
6454
6701
  ];
6455
- function logDetail(log3) {
6456
- return typeof log3.detail === "string" ? log3.detail.trim() : "";
6702
+ function logDetail(log4) {
6703
+ return typeof log4.detail === "string" ? log4.detail.trim() : "";
6457
6704
  }
6458
6705
  function parseProviderProtocolLog(title, detail) {
6459
6706
  if (title.trim().toLowerCase() !== "agent output")
@@ -6500,12 +6747,12 @@ function renderOperatorSnapshot(snapshot) {
6500
6747
  const status = String(run.status ?? "unknown");
6501
6748
  const logs = snapshot.logs ?? [];
6502
6749
  const latestByStage = new Map;
6503
- for (const log3 of logs) {
6504
- const title = String(log3.title ?? "").toLowerCase();
6505
- const stageName = String(log3.stage ?? "").toLowerCase();
6750
+ for (const log4 of logs) {
6751
+ const title = String(log4.title ?? "").toLowerCase();
6752
+ const stageName = String(log4.stage ?? "").toLowerCase();
6506
6753
  const stage = CANONICAL_STAGES.find((candidate) => candidate.toLowerCase() === title || candidate.toLowerCase() === stageName);
6507
6754
  if (stage)
6508
- latestByStage.set(stage, log3);
6755
+ latestByStage.set(stage, log4);
6509
6756
  }
6510
6757
  const stageLines = CANONICAL_STAGES.flatMap((stage) => {
6511
6758
  const match = latestByStage.get(stage);
@@ -7309,7 +7556,7 @@ async function attachRunOperatorView(context, input) {
7309
7556
  }
7310
7557
 
7311
7558
  // packages/cli/src/commands/run.ts
7312
- function normalizeRemoteRunDetails(payload) {
7559
+ function normalizeRemoteRunDetails2(payload) {
7313
7560
  const run = payload.run;
7314
7561
  if (!run || typeof run !== "object" || Array.isArray(run))
7315
7562
  return null;
@@ -7321,11 +7568,11 @@ function normalizeRemoteRunDetails(payload) {
7321
7568
  };
7322
7569
  }
7323
7570
  var REMOTE_TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged"]);
7324
- function isRemoteConnectionSelected(projectRoot) {
7571
+ function isRemoteConnectionSelected2(projectRoot) {
7325
7572
  return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
7326
7573
  }
7327
7574
  async function listRunsForSelectedConnection(context, options = {}) {
7328
- if (isRemoteConnectionSelected(context.projectRoot)) {
7575
+ if (isRemoteConnectionSelected2(context.projectRoot)) {
7329
7576
  return { runs: await listRunsViaServer(context, options), source: "server" };
7330
7577
  }
7331
7578
  return { runs: listAuthorityRuns3(context.projectRoot), source: "local" };
@@ -7334,9 +7581,6 @@ function runStringField(run, key, fallback = "") {
7334
7581
  const value = run[key];
7335
7582
  return typeof value === "string" && value.trim() ? value : fallback;
7336
7583
  }
7337
- function runDisplayTitle(run) {
7338
- return runStringField(run, "title", runStringField(run, "taskId", "(untitled)"));
7339
- }
7340
7584
  function buildServerRunStatus(runs) {
7341
7585
  const activeRuns = runs.filter((run) => !REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
7342
7586
  const recentRuns = runs.filter((run) => REMOTE_TERMINAL_RUN_STATUSES.has(runStringField(run, "status").toLowerCase()));
@@ -7406,10 +7650,10 @@ async function executeRun(context, args) {
7406
7650
  const runtimeContext = loadRuntimeContextFromEnv2() ?? undefined;
7407
7651
  switch (command) {
7408
7652
  case "list": {
7409
- requireNoExtraArgs(rest, "bun run rig run list");
7653
+ requireNoExtraArgs(rest, "rig run list");
7410
7654
  const { runs, source } = await listRunsForSelectedConnection(context, { limit: 100 });
7411
7655
  if (context.outputMode === "text") {
7412
- console.log(formatRunList(runs, { source }));
7656
+ printFormattedOutput(formatRunList(runs, { source }));
7413
7657
  }
7414
7658
  return { ok: true, group: "run", command, details: { runs, source } };
7415
7659
  }
@@ -7419,7 +7663,7 @@ async function executeRun(context, args) {
7419
7663
  pending = run.rest;
7420
7664
  const purgeArtifacts = takeFlag(pending, "--purge-artifacts");
7421
7665
  pending = purgeArtifacts.rest;
7422
- requireNoExtraArgs(pending, "bun run rig run delete --run <id> [--purge-artifacts]");
7666
+ requireNoExtraArgs(pending, "rig run delete --run <id> [--purge-artifacts]");
7423
7667
  if (!run.value) {
7424
7668
  throw new CliError2("run delete requires --run <id>.");
7425
7669
  }
@@ -7449,7 +7693,7 @@ async function executeRun(context, args) {
7449
7693
  pending = keepRuntimes.rest;
7450
7694
  const keepQueue = takeFlag(pending, "--keep-queue");
7451
7695
  pending = keepQueue.rest;
7452
- requireNoExtraArgs(pending, "bun run rig run cleanup --all [--keep-artifacts] [--keep-runtimes] [--keep-queue]");
7696
+ requireNoExtraArgs(pending, "rig run cleanup --all [--keep-artifacts] [--keep-runtimes] [--keep-queue]");
7453
7697
  if (!all.value) {
7454
7698
  throw new CliError2("run cleanup currently requires --all.");
7455
7699
  }
@@ -7468,20 +7712,25 @@ async function executeRun(context, args) {
7468
7712
  }
7469
7713
  case "show": {
7470
7714
  let pending = rest;
7715
+ const rawResult = takeFlag(pending, "--raw");
7716
+ pending = rawResult.rest;
7471
7717
  const run = takeOption(pending, "--run");
7472
7718
  pending = run.rest;
7473
- requireNoExtraArgs(pending, "bun run rig run show --run <id>");
7474
- if (!run.value) {
7475
- throw new CliError2("run show requires --run <id>.");
7719
+ const positionalRunId = pending.length > 0 && pending[0] && !pending[0].startsWith("-") ? pending[0] : undefined;
7720
+ const extra = positionalRunId ? pending.slice(1) : pending;
7721
+ requireNoExtraArgs(extra, "rig run show <id>|--run <id> [--raw]");
7722
+ const runId = run.value ?? positionalRunId;
7723
+ if (!runId) {
7724
+ throw new CliError2("run show requires a run id.");
7476
7725
  }
7477
- const record = readAuthorityRun4(context.projectRoot, run.value) ?? normalizeRemoteRunDetails(await getRunDetailsViaServer(context, run.value).catch(() => ({})));
7726
+ const record = readAuthorityRun4(context.projectRoot, runId) ?? normalizeRemoteRunDetails2(await getRunDetailsViaServer(context, runId).catch(() => ({})));
7478
7727
  if (!record) {
7479
- throw new CliError2(`Run not found: ${run.value}`, 2);
7728
+ throw new CliError2(`Run not found: ${runId}`, 2);
7480
7729
  }
7481
7730
  if (context.outputMode === "text") {
7482
- console.log(JSON.stringify(record, null, 2));
7731
+ printFormattedOutput(rawResult.value ? JSON.stringify(record, null, 2) : formatRunCard(record));
7483
7732
  }
7484
- return { ok: true, group: "run", command, details: record };
7733
+ return { ok: true, group: "run", command, details: { ...record, rawOutput: rawResult.value } };
7485
7734
  }
7486
7735
  case "timeline": {
7487
7736
  let pending = rest;
@@ -7489,7 +7738,7 @@ async function executeRun(context, args) {
7489
7738
  pending = run.rest;
7490
7739
  const follow = takeFlag(pending, "--follow");
7491
7740
  pending = follow.rest;
7492
- requireNoExtraArgs(pending, "bun run rig run timeline --run <id> [--follow]");
7741
+ requireNoExtraArgs(pending, "rig run timeline --run <id> [--follow]");
7493
7742
  if (!run.value) {
7494
7743
  throw new CliError2("run timeline requires --run <id>.");
7495
7744
  }
@@ -7526,7 +7775,7 @@ async function executeRun(context, args) {
7526
7775
  pending = pollMs.rest;
7527
7776
  const positionalRunId = pending.length > 0 ? pending[0] : undefined;
7528
7777
  const extra = positionalRunId ? pending.slice(1) : pending;
7529
- requireNoExtraArgs(extra, "bun run rig run attach <run-id>|--run <run-id> [--message <text>] [--once|--follow] [--poll-ms <ms>]");
7778
+ requireNoExtraArgs(extra, "rig run attach <run-id>|--run <run-id> [--message <text>] [--once|--follow] [--poll-ms <ms>]");
7530
7779
  const runId = runOption.value ?? positionalRunId;
7531
7780
  if (!runId) {
7532
7781
  throw new CliError2("run attach requires a run id.", 2);
@@ -7546,28 +7795,18 @@ async function executeRun(context, args) {
7546
7795
  return { ok: true, group: "run", command, details: { ...attached, steered: attached.steered || steered } };
7547
7796
  }
7548
7797
  case "status": {
7549
- requireNoExtraArgs(rest, "bun run rig run status");
7798
+ requireNoExtraArgs(rest, "rig run status");
7550
7799
  if (context.dryRun) {
7551
7800
  if (context.outputMode === "text") {
7552
7801
  console.log("[dry-run] rig run status");
7553
7802
  }
7554
7803
  return { ok: true, group: "run", command };
7555
7804
  }
7556
- const summary = isRemoteConnectionSelected(context.projectRoot) ? buildServerRunStatus(await listRunsViaServer(context, { limit: 100 })) : runStatus(context.projectRoot, runtimeContext);
7805
+ const summary = isRemoteConnectionSelected2(context.projectRoot) ? buildServerRunStatus(await listRunsViaServer(context, { limit: 100 })) : runStatus(context.projectRoot, runtimeContext);
7557
7806
  const activeRuns = Array.isArray(summary.activeRuns) ? summary.activeRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
7558
7807
  const recentRuns = Array.isArray(summary.recentRuns) ? summary.recentRuns.filter((run) => Boolean(run && typeof run === "object" && !Array.isArray(run))) : [];
7559
7808
  if (context.outputMode === "text") {
7560
- console.log(`Active runs: ${activeRuns.length}`);
7561
- for (const run of activeRuns) {
7562
- console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
7563
- }
7564
- if (recentRuns.length > 0) {
7565
- console.log("");
7566
- console.log("Recent runs:");
7567
- for (const run of recentRuns) {
7568
- console.log(`- ${runStringField(run, "runId", "(unknown-run)")} \xB7 ${runStringField(run, "status", "unknown")} \xB7 ${runStringField(run, "taskId", runDisplayTitle(run))}`);
7569
- }
7570
- }
7809
+ printFormattedOutput(formatRunStatus({ activeRuns, recentRuns, runs: Array.isArray(summary.runs) ? summary.runs : [...activeRuns, ...recentRuns] }, { source: isRemoteConnectionSelected2(context.projectRoot) ? "server" : "local" }));
7571
7810
  }
7572
7811
  return { ok: true, group: "run", command, details: summary };
7573
7812
  }
@@ -7591,7 +7830,7 @@ async function executeRun(context, args) {
7591
7830
  pending = pollResult.rest;
7592
7831
  const noServerResult = takeFlag(pending, "--no-server");
7593
7832
  pending = noServerResult.rest;
7594
- requireNoExtraArgs(pending, "bun run rig run start [--epic <id>] [--prompt-epic|--no-epic-prompt] [--ws-port <n>] [--server-host <host>] [--server-port <n>] [--poll-ms <n>] [--no-server]");
7833
+ 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]");
7595
7834
  if (promptEpicResult.value && noEpicPromptResult.value) {
7596
7835
  throw new CliError2("Cannot use --prompt-epic and --no-epic-prompt together.");
7597
7836
  }
@@ -7639,7 +7878,7 @@ async function executeRun(context, args) {
7639
7878
  };
7640
7879
  }
7641
7880
  case "resume": {
7642
- requireNoExtraArgs(rest, "bun run rig run resume");
7881
+ requireNoExtraArgs(rest, "rig run resume");
7643
7882
  if (context.dryRun) {
7644
7883
  if (context.outputMode === "text") {
7645
7884
  console.log("[dry-run] rig run resume");
@@ -7653,7 +7892,7 @@ async function executeRun(context, args) {
7653
7892
  return { ok: true, group: "run", command, details: resumed };
7654
7893
  }
7655
7894
  case "restart": {
7656
- requireNoExtraArgs(rest, "bun run rig run restart");
7895
+ requireNoExtraArgs(rest, "rig run restart");
7657
7896
  if (context.dryRun) {
7658
7897
  if (context.outputMode === "text") {
7659
7898
  console.log("[dry-run] rig run restart");
@@ -7670,7 +7909,7 @@ async function executeRun(context, args) {
7670
7909
  const runOption = takeOption(rest, "--run");
7671
7910
  const positionalRunId = runOption.rest.length > 0 ? runOption.rest[0] : undefined;
7672
7911
  const extra = positionalRunId ? runOption.rest.slice(1) : runOption.rest;
7673
- requireNoExtraArgs(extra, "bun run rig run stop [<run-id>|--run <id>]");
7912
+ requireNoExtraArgs(extra, "rig run stop [<run-id>|--run <id>]");
7674
7913
  const runId = runOption.value ?? positionalRunId;
7675
7914
  if (context.dryRun) {
7676
7915
  return {
@@ -7808,73 +8047,425 @@ async function executeServer(context, args, options) {
7808
8047
  throw new CliError2(`Unknown server command: ${command}`);
7809
8048
  }
7810
8049
  }
7811
-
7812
- // packages/cli/src/commands/task.ts
7813
- import { readFileSync as readFileSync9 } from "fs";
7814
- import { spawnSync as spawnSync3 } from "child_process";
7815
- import { resolve as resolve19 } from "path";
7816
- import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
7817
- import {
7818
- taskArtifactDir,
7819
- taskArtifacts,
7820
- taskArtifactWrite,
7821
- taskDeps,
7822
- taskInfo,
7823
- taskLookup as taskLookup2,
7824
- taskReady,
7825
- taskRecord,
7826
- taskReopen,
7827
- taskScope,
7828
- taskStatus as taskStatus2,
7829
- taskValidate,
7830
- taskVerify
7831
- } from "@rig/runtime/control-plane/native/task-ops";
7832
-
7833
- // packages/cli/src/commands/_task-picker.ts
7834
- import { cancel as cancel3, isCancel as isCancel3, select as select3 } from "@clack/prompts";
7835
- function taskId2(task) {
7836
- return typeof task.id === "string" && task.id.trim() ? task.id : "<unknown>";
8050
+
8051
+ // packages/cli/src/commands/task.ts
8052
+ import { readFileSync as readFileSync9 } from "fs";
8053
+ import { spawnSync as spawnSync3 } from "child_process";
8054
+ import { resolve as resolve19 } from "path";
8055
+ import { cancel as cancel4, confirm as confirm2, isCancel as isCancel4 } from "@clack/prompts";
8056
+ import {
8057
+ taskArtifactDir,
8058
+ taskArtifacts,
8059
+ taskArtifactWrite,
8060
+ taskDeps,
8061
+ taskInfo,
8062
+ taskLookup as taskLookup2,
8063
+ taskReady,
8064
+ taskRecord,
8065
+ taskReopen,
8066
+ taskScope,
8067
+ taskStatus as taskStatus2,
8068
+ taskValidate,
8069
+ taskVerify
8070
+ } from "@rig/runtime/control-plane/native/task-ops";
8071
+
8072
+ // packages/cli/src/commands/_task-picker.ts
8073
+ import { cancel as cancel3, isCancel as isCancel3, select as select3 } from "@clack/prompts";
8074
+ function taskId2(task) {
8075
+ return typeof task.id === "string" && task.id.trim() ? task.id : "<unknown>";
8076
+ }
8077
+ async function selectTaskWithTextPicker(tasks, io = {}) {
8078
+ if (tasks.length === 0)
8079
+ return null;
8080
+ if (tasks.length === 1)
8081
+ return tasks[0];
8082
+ const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
8083
+ if (!isTty) {
8084
+ throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
8085
+ }
8086
+ if (io.prompt || io.renderer) {
8087
+ const prompt = io.prompt ?? promptForTaskSelection;
8088
+ const renderer = io.renderer ?? { writeLine: (line) => process.stdout.write(`${line}
8089
+ `) };
8090
+ renderer.writeLine("Select Rig task:");
8091
+ for (const row of renderTaskPickerRows(tasks))
8092
+ renderer.writeLine(` ${row}`);
8093
+ const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
8094
+ if (!answer2)
8095
+ return null;
8096
+ if (/^\d+$/.test(answer2)) {
8097
+ const index2 = Number.parseInt(answer2, 10) - 1;
8098
+ return tasks[index2] ?? null;
8099
+ }
8100
+ return tasks.find((task) => taskId2(task) === answer2) ?? null;
8101
+ }
8102
+ const options = tasks.map((task, index2) => ({
8103
+ value: `${index2}`,
8104
+ label: `${taskId2(task)} \xB7 ${typeof task.title === "string" && task.title.trim() ? task.title.trim() : "Untitled task"}`,
8105
+ hint: typeof task.status === "string" && task.status.trim() ? task.status.trim() : undefined
8106
+ }));
8107
+ const answer = await select3({
8108
+ message: "Select Rig task",
8109
+ options
8110
+ });
8111
+ if (isCancel3(answer)) {
8112
+ cancel3("No task selected.");
8113
+ return null;
8114
+ }
8115
+ const index = Number.parseInt(String(answer), 10);
8116
+ return Number.isFinite(index) ? tasks[index] ?? null : null;
8117
+ }
8118
+
8119
+ // packages/cli/src/commands/_help-catalog.ts
8120
+ import { intro as intro3, log as log4, note as note4, outro as outro3 } from "@clack/prompts";
8121
+ import pc4 from "picocolors";
8122
+ var TOP_LEVEL_SECTIONS = [
8123
+ {
8124
+ title: "Server",
8125
+ subtitle: "choose the local or remote Rig server that owns this repo",
8126
+ commands: [
8127
+ { command: "rig server status", description: "Show the selected local/remote server for this repo." },
8128
+ { command: "rig server use local", description: "Switch this repo back to the local Rig server." },
8129
+ { command: "rig server add <alias> <url>", description: "Save a remote Rig server alias." },
8130
+ { command: "rig server use <alias>", description: "Switch this repo to a saved remote server." },
8131
+ { command: "rig server list", description: "Show saved server aliases, including local." }
8132
+ ]
8133
+ },
8134
+ {
8135
+ title: "Tasks",
8136
+ subtitle: "find work, inspect it, and submit Pi-backed workers",
8137
+ commands: [
8138
+ { command: "rig task list", description: "List tasks from the selected task source/server." },
8139
+ { command: "rig task next", description: "Show the next matching task as a selected-task card." },
8140
+ { command: "rig task show <id>", description: "Show a human task summary; add --raw or --json for the full payload." },
8141
+ { command: "rig task run <id|--next> [--detach]", description: "Submit a task run; interactive mode follows with bundled Pi." }
8142
+ ]
8143
+ },
8144
+ {
8145
+ title: "Runs",
8146
+ subtitle: "observe, attach to, and stop live or recent runs",
8147
+ commands: [
8148
+ { command: "rig run list", description: "List recent runs from the selected server or local state." },
8149
+ { command: "rig run show <id>", description: "Show a human run summary; add --raw or --json for the full payload." },
8150
+ { command: "rig run attach <id> --follow", description: "Open the native bundled Pi live view for a worker run." },
8151
+ { command: "rig run stop <id>", description: "Request cancellation for a running worker." }
8152
+ ]
8153
+ },
8154
+ {
8155
+ title: "Review / inbox",
8156
+ subtitle: "clear blocked runs and configure completion review",
8157
+ commands: [
8158
+ { command: "rig inbox approvals", description: "List pending approval requests from local/server run state." },
8159
+ { command: "rig inbox inputs", description: "List pending user-input requests from local/server run state." },
8160
+ { command: "rig review show|set", description: "Inspect or change the review gate policy." }
8161
+ ]
8162
+ },
8163
+ {
8164
+ title: "Health / setup",
8165
+ subtitle: "bootstrap and diagnose the repo/server/GitHub/Pi path",
8166
+ commands: [
8167
+ { command: "rig init", description: "Interactive setup: config, GitHub auth, task source, server, checkout, Pi." },
8168
+ { command: "rig doctor", description: "Diagnose project/server/GitHub/task/Pi wiring." },
8169
+ { command: "rig github auth status", description: "Show GitHub auth state on the selected Rig server." }
8170
+ ]
8171
+ }
8172
+ ];
8173
+ var PRIMARY_GROUPS = [
8174
+ {
8175
+ name: "server",
8176
+ summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
8177
+ usage: ["rig server <status|list|add|use|start> [options]"],
8178
+ commands: [
8179
+ { command: "status", description: "Show the selected server for this repo.", primary: true },
8180
+ { command: "use local", description: "Switch this repo to the local Rig server.", primary: true },
8181
+ { command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
8182
+ { command: "use <alias>", description: "Select a saved remote server alias.", primary: true },
8183
+ { command: "list", description: "List saved local/remote server aliases.", primary: true },
8184
+ { command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process." }
8185
+ ],
8186
+ examples: [
8187
+ "rig server status",
8188
+ "rig server add prod https://where.rig-does.work",
8189
+ "rig server use prod",
8190
+ "rig server use local",
8191
+ "rig server start --port 3773"
8192
+ ],
8193
+ next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
8194
+ advanced: ["Compatibility alias: `rig connect ...` remains callable."]
8195
+ },
8196
+ {
8197
+ name: "task",
8198
+ summary: "Find work, start Pi-backed runs, and validate task results.",
8199
+ usage: ["rig task <list|next|show|run> [options]"],
8200
+ commands: [
8201
+ { command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
8202
+ { command: "next [filters]", description: "Render the next matching task as a selected-task card.", primary: true },
8203
+ { command: "show <id>|--task <id> [--raw]", description: "Show a human task summary; --raw prints the full payload.", primary: true },
8204
+ { command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
8205
+ { command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
8206
+ { command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
8207
+ { command: "report-bug", description: "Create a structured bug report/task." }
8208
+ ],
8209
+ examples: [
8210
+ "rig task list --assignee @me --limit 20",
8211
+ "rig task next",
8212
+ "rig task show 123 --raw",
8213
+ "rig task run --next",
8214
+ "rig task run #123 --runtime-adapter pi",
8215
+ "rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
8216
+ ],
8217
+ next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
8218
+ },
8219
+ {
8220
+ name: "run",
8221
+ summary: "Observe, attach to, and control Rig runs.",
8222
+ usage: ["rig run <list|status|show|attach|stop> [options]"],
8223
+ commands: [
8224
+ { command: "list", description: "List recent runs from the selected server or local state.", primary: true },
8225
+ { command: "status", description: "Render active and recent run groups.", primary: true },
8226
+ { command: "show <id>|--run <id> [--raw]", description: "Show a human run summary; --raw prints the full payload.", primary: true },
8227
+ { command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; --follow launches native bundled Pi for live Pi runs.", primary: true },
8228
+ { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
8229
+ { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
8230
+ { command: "delete|cleanup", description: "Remove completed run records/artifacts." }
8231
+ ],
8232
+ examples: [
8233
+ "rig run list",
8234
+ "rig run status",
8235
+ "rig run show <run-id>",
8236
+ "rig run attach <run-id> --follow",
8237
+ "rig run stop <run-id>"
8238
+ ],
8239
+ next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
8240
+ },
8241
+ {
8242
+ name: "inbox",
8243
+ summary: "Review approval and user-input requests that block worker runs.",
8244
+ usage: ["rig inbox <approvals|approve|inputs|respond> [options]"],
8245
+ commands: [
8246
+ { command: "approvals [--run <id>] [--task <id>]", description: "List pending approvals.", primary: true },
8247
+ { command: "inputs [--run <id>] [--task <id>]", description: "List pending user-input requests.", primary: true },
8248
+ { command: "approve --run <id> --request <id> --decision approve|reject", description: "Resolve an approval request." },
8249
+ { command: "respond --run <id> --request <id> --answer key=value", description: "Answer a user-input request." }
8250
+ ],
8251
+ examples: [
8252
+ "rig inbox approvals",
8253
+ "rig inbox inputs --run <run-id>",
8254
+ "rig inbox approve --run <run-id> --request <request-id> --decision approve"
8255
+ ],
8256
+ next: ["Rejoin the run after resolving a block: `rig run attach <run-id> --follow`."]
8257
+ },
8258
+ {
8259
+ name: "review",
8260
+ summary: "Inspect or change completion review gate policy.",
8261
+ usage: ["rig review <show|set>"],
8262
+ commands: [
8263
+ { command: "show", description: "Show current review gate settings.", primary: true },
8264
+ { command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider.", primary: true }
8265
+ ],
8266
+ examples: ["rig review show", "rig review set required --provider greptile"],
8267
+ next: ["Use `rig inbox approvals` for blocked run handoffs."]
8268
+ },
8269
+ {
8270
+ name: "init",
8271
+ summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
8272
+ usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
8273
+ commands: [
8274
+ { command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
8275
+ { command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
8276
+ { command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
8277
+ { command: "init --repair", description: "Repair missing private state without replacing project config." }
8278
+ ],
8279
+ examples: [
8280
+ "rig init",
8281
+ "rig init --yes --repo humanity-org/humanwork",
8282
+ "rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
8283
+ ],
8284
+ next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
8285
+ },
8286
+ {
8287
+ name: "doctor",
8288
+ summary: "Diagnostics for project/server/GitHub/Pi state.",
8289
+ usage: ["rig doctor"],
8290
+ commands: [
8291
+ { command: "doctor", description: "Run setup and runtime diagnostics.", primary: true },
8292
+ { command: "check", description: "Compatibility spelling for diagnostics." }
8293
+ ],
8294
+ examples: ["rig doctor", "rig doctor --json"],
8295
+ next: ["Use `rig server status` and `rig github auth status` to inspect common failure points."]
8296
+ },
8297
+ {
8298
+ name: "github",
8299
+ summary: "GitHub auth helpers for the selected Rig server.",
8300
+ usage: ["rig github auth <status|import-gh|token>"],
8301
+ commands: [
8302
+ { command: "auth status", description: "Show GitHub auth state.", primary: true },
8303
+ { command: "auth import-gh", description: "Import the current `gh` token into the selected server." },
8304
+ { command: "auth token --token <token>", description: "Store a token on the selected server." }
8305
+ ],
8306
+ examples: ["rig github auth status", "rig github auth import-gh"],
8307
+ next: ["After auth is valid, use `rig task run --next`."]
8308
+ }
8309
+ ];
8310
+ var ADVANCED_GROUPS = [
8311
+ { name: "connect", summary: "Compatibility alias for `rig server` selection commands.", usage: ["rig connect <status|list|add|use>"], commands: [{ command: "status|list|add|use", description: "Use `rig server ...` for the primary UX." }] },
8312
+ { name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
8313
+ { name: "inspect", summary: "Inspect logs, artifacts, graphs, failures.", usage: ["rig inspect <logs|artifacts|failures|graph|audit|diff>"], commands: [{ command: "logs --task <id>", description: "Inspect task logs." }] },
8314
+ { name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
8315
+ { name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
8316
+ { name: "browser", summary: "Browser/app diagnostics.", usage: ["rig browser <help|explain|demo|app>"], commands: [{ command: "help", description: "Browser command help." }] },
8317
+ { name: "plugin", summary: "Plugin validation/listing.", usage: ["rig plugin <list|validate>"], commands: [{ command: "list", description: "List plugins." }] },
8318
+ { name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
8319
+ { name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
8320
+ { name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
8321
+ { name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
8322
+ { name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
8323
+ { name: "remote", summary: "Compatibility remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
8324
+ { name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
8325
+ { name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
8326
+ { name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
8327
+ ];
8328
+ var ADVANCED_COMMANDS = [
8329
+ { command: "rig server task-run ...", description: "Internal server-owned task execution entry point." },
8330
+ { command: "rig server notify-test [--event <type>]", description: "Internal event notification smoke command." },
8331
+ { command: "rig run start|start-serial|start-parallel", description: "Compatibility local run starters; prefer `rig task run ...`." },
8332
+ { command: "rig setup install-agent-shell", description: "Development helper for materializing the agent shell." },
8333
+ { command: "rig remote orchestrate-*", description: "Compatibility remote orchestration commands." }
8334
+ ];
8335
+ var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
8336
+ function heading(title) {
8337
+ return pc4.bold(pc4.cyan(title));
8338
+ }
8339
+ function commandLine(command, description) {
8340
+ const commandColumn = command.length >= 38 ? `${command} ` : command.padEnd(38);
8341
+ return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
8342
+ }
8343
+ function renderCommandBlock(commands) {
8344
+ return commands.map((entry) => commandLine(entry.command, entry.description)).join(`
8345
+ `);
8346
+ }
8347
+ function renderGroup(group) {
8348
+ const lines = [
8349
+ `${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
8350
+ "",
8351
+ pc4.bold("Usage"),
8352
+ ...group.usage.map((line) => ` ${line}`),
8353
+ "",
8354
+ pc4.bold("Commands"),
8355
+ ...group.commands.map((entry) => commandLine(entry.command, entry.description))
8356
+ ];
8357
+ if (group.examples?.length) {
8358
+ lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
8359
+ }
8360
+ if (group.next?.length) {
8361
+ lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
8362
+ }
8363
+ if (group.advanced?.length) {
8364
+ lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
8365
+ }
8366
+ return lines.join(`
8367
+ `);
8368
+ }
8369
+ function renderTopLevelHelp() {
8370
+ return [
8371
+ `${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
8372
+ pc4.dim("Current path: select a server, choose a task, submit a run, attach with native Pi, clear inbox/review gates."),
8373
+ "",
8374
+ ...TOP_LEVEL_SECTIONS.flatMap((section) => [
8375
+ `${pc4.bold(pc4.magenta(`\u25C7 ${section.title}`))} \u2014 ${pc4.dim(section.subtitle)}`,
8376
+ renderCommandBlock(section.commands),
8377
+ ""
8378
+ ]),
8379
+ pc4.dim("More: `rig help --advanced` for dev/compatibility commands; `rig <group> --help` for rich per-group help; `rig --version` for the installed version."),
8380
+ "",
8381
+ pc4.bold("Global options"),
8382
+ commandLine("--project <path>", "Use a project root instead of auto-discovery."),
8383
+ commandLine("--json", "Emit structured output for scripts/agents."),
8384
+ commandLine("--dry-run", "Print the command plan without mutating state.")
8385
+ ].join(`
8386
+ `).trimEnd();
8387
+ }
8388
+ function renderAdvancedHelp() {
8389
+ return [
8390
+ `${heading("rig advanced")} \u2014 compatibility, diagnostics, and internal surfaces`,
8391
+ "",
8392
+ pc4.bold("Primary groups"),
8393
+ " server, task, run, inbox, review, init, doctor, github",
8394
+ "",
8395
+ pc4.bold("Advanced commands"),
8396
+ ...ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)),
8397
+ "",
8398
+ pc4.bold("Advanced groups"),
8399
+ ...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
8400
+ "",
8401
+ pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, `rig run`, `rig inbox`, and `rig review` for day-to-day work.")
8402
+ ].join(`
8403
+ `);
8404
+ }
8405
+ function renderGroupHelp(groupName) {
8406
+ const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
8407
+ return group ? renderGroup(group) : null;
7837
8408
  }
7838
- async function selectTaskWithTextPicker(tasks, io = {}) {
7839
- if (tasks.length === 0)
7840
- return null;
7841
- if (tasks.length === 1)
7842
- return tasks[0];
7843
- const isTty = io.isTty ?? Boolean(process.stdin.isTTY && process.stdout.isTTY);
7844
- if (!isTty) {
7845
- throw new Error("task run requires an interactive terminal to pick a task; pass --task <id>, --next, or --detach with a task id.");
8409
+ function shouldUseClackOutput2() {
8410
+ return Boolean(process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
8411
+ }
8412
+ function printTopLevelHelp() {
8413
+ if (!shouldUseClackOutput2()) {
8414
+ console.log(renderTopLevelHelp());
8415
+ return;
7846
8416
  }
7847
- if (io.prompt || io.renderer) {
7848
- const prompt = io.prompt ?? promptForTaskSelection;
7849
- const renderer = io.renderer ?? { writeLine: (line) => process.stdout.write(`${line}
7850
- `) };
7851
- renderer.writeLine("Select Rig task:");
7852
- for (const row of renderTaskPickerRows(tasks))
7853
- renderer.writeLine(` ${row}`);
7854
- const answer2 = (await prompt(`Task [1-${tasks.length}] or id: `)).trim();
7855
- if (!answer2)
7856
- return null;
7857
- if (/^\d+$/.test(answer2)) {
7858
- const index2 = Number.parseInt(answer2, 10) - 1;
7859
- return tasks[index2] ?? null;
7860
- }
7861
- return tasks.find((task) => taskId2(task) === answer2) ?? null;
8417
+ intro3("rig");
8418
+ for (const section of TOP_LEVEL_SECTIONS) {
8419
+ note4(renderCommandBlock(section.commands), `${section.title} \u2014 ${section.subtitle}`);
7862
8420
  }
7863
- const options = tasks.map((task, index2) => ({
7864
- value: `${index2}`,
7865
- label: `${taskId2(task)} \xB7 ${typeof task.title === "string" && task.title.trim() ? task.title.trim() : "Untitled task"}`,
7866
- hint: typeof task.status === "string" && task.status.trim() ? task.status.trim() : undefined
7867
- }));
7868
- const answer = await select3({
7869
- message: "Select Rig task",
7870
- options
7871
- });
7872
- if (isCancel3(answer)) {
7873
- cancel3("No task selected.");
7874
- return null;
8421
+ log4.info("More: rig help --advanced \xB7 rig <group> --help \xB7 rig --version");
8422
+ note4([
8423
+ commandLine("--project <path>", "Use a project root instead of auto-discovery."),
8424
+ commandLine("--json", "Emit structured output for scripts/agents."),
8425
+ commandLine("--dry-run", "Print the command plan without mutating state.")
8426
+ ].join(`
8427
+ `), "Global options");
8428
+ outro3("Server \u2192 task \u2192 run \u2192 inbox/review.");
8429
+ }
8430
+ function printAdvancedHelp() {
8431
+ if (!shouldUseClackOutput2()) {
8432
+ console.log(renderAdvancedHelp());
8433
+ return;
7875
8434
  }
7876
- const index = Number.parseInt(String(answer), 10);
7877
- return Number.isFinite(index) ? tasks[index] ?? null : null;
8435
+ intro3("rig advanced");
8436
+ note4(ADVANCED_COMMANDS.map((entry) => commandLine(entry.command, entry.description)).join(`
8437
+ `), "Advanced commands");
8438
+ note4(ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)).join(`
8439
+ `), "Advanced groups");
8440
+ outro3("Primary daily flow: rig server \xB7 rig task \xB7 rig run \xB7 rig inbox \xB7 rig review.");
8441
+ }
8442
+ function printGroupHelpDocument(groupName) {
8443
+ const rendered = renderGroupHelp(groupName) ?? renderTopLevelHelp();
8444
+ if (!shouldUseClackOutput2()) {
8445
+ console.log(rendered);
8446
+ return;
8447
+ }
8448
+ const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
8449
+ if (!group) {
8450
+ printTopLevelHelp();
8451
+ return;
8452
+ }
8453
+ intro3(`rig ${group.name}`);
8454
+ note4(group.summary, "Purpose");
8455
+ note4(group.usage.join(`
8456
+ `), "Usage");
8457
+ note4(group.commands.map((entry) => commandLine(entry.command, entry.description)).join(`
8458
+ `), "Commands");
8459
+ if (group.examples?.length)
8460
+ note4(group.examples.map((line) => `$ ${line}`).join(`
8461
+ `), "Examples");
8462
+ if (group.next?.length)
8463
+ note4(group.next.map((line) => `\u203A ${line}`).join(`
8464
+ `), "Next steps");
8465
+ if (group.advanced?.length)
8466
+ log4.info(group.advanced.join(`
8467
+ `));
8468
+ outro3("Run with --json when scripts need structured output.");
7878
8469
  }
7879
8470
 
7880
8471
  // packages/cli/src/commands/task.ts
@@ -8028,27 +8619,30 @@ function summarizeTask(task, options = {}) {
8028
8619
  ...options.raw ? { raw: raw ?? task } : {}
8029
8620
  };
8030
8621
  }
8031
- function printTaskSummary(task) {
8032
- console.log(formatTaskList([task]));
8033
- }
8034
8622
  async function validatorRegistryForTaskCommands(projectRoot) {
8035
8623
  return buildPluginHostContext(projectRoot).then((ctx) => ctx?.validatorRegistry ?? undefined).catch(() => {
8036
8624
  return;
8037
8625
  });
8038
8626
  }
8039
8627
  async function executeTask(context, args, options) {
8040
- const [command = "info", ...rest] = args;
8628
+ if (args.length === 0) {
8629
+ if (context.outputMode === "text") {
8630
+ printGroupHelpDocument("task");
8631
+ }
8632
+ return { ok: true, group: "task", command: "help" };
8633
+ }
8634
+ const [command = "help", ...rest] = args;
8041
8635
  switch (command) {
8042
8636
  case "list": {
8043
8637
  let pending = rest;
8044
8638
  const rawResult = takeFlag(pending, "--raw");
8045
8639
  pending = rawResult.rest;
8046
8640
  const { filters, rest: remaining } = parseTaskFilters(pending);
8047
- requireNoExtraArgs(remaining, "bun run rig task list [--raw] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
8641
+ requireNoExtraArgs(remaining, "rig task list [--raw] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
8048
8642
  const tasks = await listWorkspaceTasksViaServer(context, filters);
8049
8643
  if (context.outputMode === "text") {
8050
8644
  const renderedTasks = rawResult.value ? tasks.map((task) => summarizeTask(task, { raw: true })) : tasks.map((task) => summarizeTask(task));
8051
- console.log(formatTaskList(renderedTasks, { raw: rawResult.value }));
8645
+ printFormattedOutput(formatTaskList(renderedTasks, { raw: rawResult.value }));
8052
8646
  }
8053
8647
  return {
8054
8648
  ok: true,
@@ -8058,10 +8652,13 @@ async function executeTask(context, args, options) {
8058
8652
  };
8059
8653
  }
8060
8654
  case "show": {
8061
- const taskOption = takeOption(rest, "--task");
8655
+ let pending = rest;
8656
+ const rawResult = takeFlag(pending, "--raw");
8657
+ pending = rawResult.rest;
8658
+ const taskOption = takeOption(pending, "--task");
8062
8659
  const positional = taskOption.rest.length > 0 && taskOption.rest[0] && !taskOption.rest[0].startsWith("-") ? taskOption.rest[0] : undefined;
8063
8660
  const remaining = positional ? taskOption.rest.slice(1) : taskOption.rest;
8064
- requireNoExtraArgs(remaining, "bun run rig task show <id>|--task <id>");
8661
+ requireNoExtraArgs(remaining, "rig task show <id>|--task <id> [--raw]");
8065
8662
  const taskId3 = normalizeTaskRunTaskId(taskOption.value ?? positional);
8066
8663
  if (!taskId3)
8067
8664
  throw new CliError2("task show requires a task id.", 2);
@@ -8069,19 +8666,20 @@ async function executeTask(context, args, options) {
8069
8666
  if (!task)
8070
8667
  throw new CliError2(`Task not found: ${taskId3}`, 3);
8071
8668
  const summary = summarizeTask(task, { raw: true });
8072
- if (context.outputMode === "text")
8073
- console.log(JSON.stringify(summary, null, 2));
8074
- return { ok: true, group: "task", command, details: { task: summary } };
8669
+ if (context.outputMode === "text") {
8670
+ printFormattedOutput(rawResult.value ? JSON.stringify(summary, null, 2) : formatTaskDetails(summary));
8671
+ }
8672
+ return { ok: true, group: "task", command, details: { task: summary, raw: rawResult.value } };
8075
8673
  }
8076
8674
  case "next": {
8077
8675
  const { filters, rest: remaining } = parseTaskFilters(rest);
8078
- requireNoExtraArgs(remaining, "bun run rig task next [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
8676
+ requireNoExtraArgs(remaining, "rig task next [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>]");
8079
8677
  const selected = await selectNextWorkspaceTaskViaServer(context, filters);
8080
8678
  if (context.outputMode === "text") {
8081
8679
  if (selected.task) {
8082
- printTaskSummary(selected.task);
8680
+ printFormattedOutput(formatTaskCard(summarizeTask(selected.task, { raw: true }), { title: "Selected task", selected: true }));
8083
8681
  } else {
8084
- console.log("No matching tasks.");
8682
+ printFormattedOutput("No matching tasks.\n\nNext\n\u203A Try `rig task list` to inspect available work.\n\u203A Check server: `rig server status`");
8085
8683
  }
8086
8684
  }
8087
8685
  return {
@@ -8097,31 +8695,31 @@ async function executeTask(context, args, options) {
8097
8695
  }
8098
8696
  case "info": {
8099
8697
  const { value: task, rest: remaining } = takeOption(rest, "--task");
8100
- requireNoExtraArgs(remaining, "bun run rig task info [--task <beads-id>]");
8698
+ requireNoExtraArgs(remaining, "rig task info [--task <task-id>]");
8101
8699
  await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, task || undefined));
8102
8700
  return { ok: true, group: "task", command, details: { task: task || null } };
8103
8701
  }
8104
8702
  case "scope": {
8105
8703
  const filesFlag = takeFlag(rest, "--files");
8106
8704
  const { value: task, rest: remaining } = takeOption(filesFlag.rest, "--task");
8107
- requireNoExtraArgs(remaining, "bun run rig task scope [--task <id>] [--files]");
8705
+ requireNoExtraArgs(remaining, "rig task scope [--task <id>] [--files]");
8108
8706
  await withMutedConsole(context.outputMode === "json", () => taskScope(context.projectRoot, filesFlag.value, task || undefined));
8109
8707
  return { ok: true, group: "task", command, details: { files: filesFlag.value, task: task || null } };
8110
8708
  }
8111
8709
  case "deps":
8112
- requireNoExtraArgs(rest, "bun run rig task deps");
8710
+ requireNoExtraArgs(rest, "rig task deps");
8113
8711
  await withMutedConsole(context.outputMode === "json", () => taskDeps(context.projectRoot));
8114
8712
  return { ok: true, group: "task", command };
8115
8713
  case "status":
8116
- requireNoExtraArgs(rest, "bun run rig task status");
8714
+ requireNoExtraArgs(rest, "rig task status");
8117
8715
  withMutedConsole(context.outputMode === "json", () => taskStatus2(context.projectRoot));
8118
8716
  return { ok: true, group: "task", command };
8119
8717
  case "artifacts":
8120
- requireNoExtraArgs(rest, "bun run rig task artifacts");
8718
+ requireNoExtraArgs(rest, "rig task artifacts");
8121
8719
  withMutedConsole(context.outputMode === "json", () => taskArtifacts(context.projectRoot));
8122
8720
  return { ok: true, group: "task", command };
8123
8721
  case "artifact-dir": {
8124
- requireNoExtraArgs(rest, "bun run rig task artifact-dir");
8722
+ requireNoExtraArgs(rest, "rig task artifact-dir");
8125
8723
  const path = taskArtifactDir(context.projectRoot);
8126
8724
  if (context.outputMode === "text") {
8127
8725
  console.log(path);
@@ -8130,7 +8728,7 @@ async function executeTask(context, args, options) {
8130
8728
  }
8131
8729
  case "artifact-write": {
8132
8730
  if (rest.length < 1) {
8133
- throw new CliError2(`Usage: bun run rig task artifact-write <filename> [--file <path>]
8731
+ throw new CliError2(`Usage: rig task artifact-write <filename> [--file <path>]
8134
8732
  ` + ` Reads content from stdin (or --file), writes to the active task artifact dir.
8135
8733
  ` + " Example: echo '...' | rig task artifact-write collection-audit.md");
8136
8734
  }
@@ -8143,7 +8741,7 @@ async function executeTask(context, args, options) {
8143
8741
  content = await readStdin();
8144
8742
  }
8145
8743
  if (!artifactFilename) {
8146
- throw new CliError2("Usage: bun run rig task artifact-write <filename> [--file path]");
8744
+ throw new CliError2("Usage: rig task artifact-write <filename> [--file path]");
8147
8745
  }
8148
8746
  withMutedConsole(context.outputMode === "json", () => taskArtifactWrite(context.projectRoot, artifactFilename, content));
8149
8747
  return { ok: true, group: "task", command, details: { filename: artifactFilename } };
@@ -8152,11 +8750,11 @@ async function executeTask(context, args, options) {
8152
8750
  return options.executeTaskReportBug(context, rest);
8153
8751
  case "lookup": {
8154
8752
  if (rest.length !== 1) {
8155
- throw new CliError2("Usage: bun run rig task lookup <beads-id>");
8753
+ throw new CliError2("Usage: rig task lookup <task-id>");
8156
8754
  }
8157
8755
  const lookupId = rest[0];
8158
8756
  if (!lookupId) {
8159
- throw new CliError2("Usage: bun run rig task lookup <beads-id>");
8757
+ throw new CliError2("Usage: rig task lookup <task-id>");
8160
8758
  }
8161
8759
  const result = taskLookup2(context.projectRoot, lookupId);
8162
8760
  if (context.outputMode === "text") {
@@ -8166,17 +8764,17 @@ async function executeTask(context, args, options) {
8166
8764
  }
8167
8765
  case "record": {
8168
8766
  if (rest.length < 2) {
8169
- throw new CliError2("Usage: bun run rig task record <decision|failure> <text>");
8767
+ throw new CliError2("Usage: rig task record <decision|failure> <text>");
8170
8768
  }
8171
8769
  const type = rest[0];
8172
8770
  if (type !== "decision" && type !== "failure") {
8173
- throw new CliError2("Usage: bun run rig task record <decision|failure> <text>");
8771
+ throw new CliError2("Usage: rig task record <decision|failure> <text>");
8174
8772
  }
8175
8773
  withMutedConsole(context.outputMode === "json", () => taskRecord(context.projectRoot, type, rest.slice(1).join(" ")));
8176
8774
  return { ok: true, group: "task", command, details: { type: rest[0] } };
8177
8775
  }
8178
8776
  case "ready":
8179
- requireNoExtraArgs(rest, "bun run rig task ready");
8777
+ requireNoExtraArgs(rest, "rig task ready");
8180
8778
  await withMutedConsole(context.outputMode === "json", () => taskReady(context.projectRoot));
8181
8779
  return { ok: true, group: "task", command };
8182
8780
  case "run": {
@@ -8213,7 +8811,7 @@ async function executeTask(context, args, options) {
8213
8811
  if (positionalTaskId) {
8214
8812
  pending = pending.slice(1);
8215
8813
  }
8216
- requireNoExtraArgs(pending, "bun run rig task run [#<issue>|<task-id>] [--next] [--task <id>] [--detach] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>] [--title <text>] [--runtime-adapter claude-code|codex|pi] [--model <model>] [--runtime-mode <mode>] [--interaction-mode <mode>] [--initial-prompt <text>] [--pr auto|ask|off] [--no-pr] [--dirty-baseline head|dirty-snapshot] [--skip-project-sync]");
8814
+ requireNoExtraArgs(pending, "rig task run [#<issue>|<task-id>] [--next] [--task <id>] [--detach] [--assignee <login|@me>] [--assigned-to <login|me|@me>] [--state open|closed] [--status <status>] [--limit <n>] [--title <text>] [--runtime-adapter claude-code|codex|pi] [--model <model>] [--runtime-mode <mode>] [--interaction-mode <mode>] [--initial-prompt <text>] [--pr auto|ask|off] [--no-pr] [--dirty-baseline head|dirty-snapshot] [--skip-project-sync]");
8217
8815
  if (nextResult.value && (taskResult.value || positionalTaskId)) {
8218
8816
  throw new CliError2("task run cannot combine --next with an explicit task id.", 2);
8219
8817
  }
@@ -8267,10 +8865,24 @@ async function executeTask(context, args, options) {
8267
8865
  });
8268
8866
  let attachDetails = null;
8269
8867
  if (!detachResult.value && context.outputMode === "text") {
8270
- console.log(formatSubmittedRun({ runId: submitted.runId, task: selectedTask ? summarizeTask(selectedTask) : null }));
8868
+ printFormattedOutput(formatSubmittedRun({
8869
+ runId: submitted.runId,
8870
+ task: selectedTask ? summarizeTask(selectedTask) : null,
8871
+ runtimeAdapter,
8872
+ runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
8873
+ interactionMode: interactionModeResult.value || "default",
8874
+ detached: false
8875
+ }));
8271
8876
  attachDetails = await attachRunOperatorView(context, { runId: submitted.runId, follow: true });
8272
8877
  } else if (context.outputMode === "text") {
8273
- console.log(formatSubmittedRun({ runId: submitted.runId, task: selectedTask ? summarizeTask(selectedTask) : null }));
8878
+ printFormattedOutput(formatSubmittedRun({
8879
+ runId: submitted.runId,
8880
+ task: selectedTask ? summarizeTask(selectedTask) : null,
8881
+ runtimeAdapter,
8882
+ runtimeMode: runtimeModeResult.value || projectDefaults.runtimeMode || "full-access",
8883
+ interactionMode: interactionModeResult.value || "default",
8884
+ detached: true
8885
+ }));
8274
8886
  }
8275
8887
  return {
8276
8888
  ok: true,
@@ -8294,7 +8906,7 @@ async function executeTask(context, args, options) {
8294
8906
  }
8295
8907
  case "validate": {
8296
8908
  const { value: task, rest: remaining } = takeOption(rest, "--task");
8297
- requireNoExtraArgs(remaining, "bun run rig task validate [--task <beads-id>]");
8909
+ requireNoExtraArgs(remaining, "rig task validate [--task <task-id>]");
8298
8910
  if (context.dryRun) {
8299
8911
  await context.runCommand(["rig", "task", "validate", ...task ? ["--task", task] : []]);
8300
8912
  return { ok: true, group: "task", command, details: { task: task || "active" } };
@@ -8307,7 +8919,7 @@ async function executeTask(context, args, options) {
8307
8919
  }
8308
8920
  case "verify": {
8309
8921
  const { value: task, rest: remaining } = takeOption(rest, "--task");
8310
- requireNoExtraArgs(remaining, "bun run rig task verify [--task <beads-id>]");
8922
+ requireNoExtraArgs(remaining, "rig task verify [--task <task-id>]");
8311
8923
  if (context.dryRun) {
8312
8924
  await context.runCommand(["rig", "task", "verify", ...task ? ["--task", task] : []]);
8313
8925
  return { ok: true, group: "task", command, details: { task: task || "active" } };
@@ -8320,15 +8932,15 @@ async function executeTask(context, args, options) {
8320
8932
  }
8321
8933
  case "reset": {
8322
8934
  const { value: task, rest: remaining } = takeOption(rest, "--task");
8323
- requireNoExtraArgs(remaining, "bun run rig task reset --task <beads-id>");
8324
- const requiredTask = requireTask(task, "bun run rig task reset --task <beads-id>");
8935
+ requireNoExtraArgs(remaining, "rig task reset --task <task-id>");
8936
+ const requiredTask = requireTask(task, "rig task reset --task <task-id>");
8325
8937
  await context.runCommand(["br", "--no-db", "update", requiredTask, "--status", "open"]);
8326
8938
  return { ok: true, group: "task", command, details: { task: requiredTask } };
8327
8939
  }
8328
8940
  case "details": {
8329
8941
  const { value: task, rest: remaining } = takeOption(rest, "--task");
8330
- requireNoExtraArgs(remaining, "bun run rig task details --task <beads-id>");
8331
- const requiredTask = requireTask(task, "bun run rig task details --task <beads-id>");
8942
+ requireNoExtraArgs(remaining, "rig task details --task <task-id>");
8943
+ const requiredTask = requireTask(task, "rig task details --task <task-id>");
8332
8944
  await withMutedConsole(context.outputMode === "json", () => taskInfo(context.projectRoot, requiredTask));
8333
8945
  return { ok: true, group: "task", command, details: { task: requiredTask } };
8334
8946
  }
@@ -8336,9 +8948,9 @@ async function executeTask(context, args, options) {
8336
8948
  const { value: task, rest: rest1 } = takeOption(rest, "--task");
8337
8949
  const allFlag = takeFlag(rest1, "--all");
8338
8950
  const { rest: remaining } = takeOption(allFlag.rest, "--reason");
8339
- requireNoExtraArgs(remaining, "bun run rig task reopen [--task <id> | --all] [--reason <text>]");
8951
+ requireNoExtraArgs(remaining, "rig task reopen [--task <id> | --all] [--reason <text>]");
8340
8952
  if (!allFlag.value && !task) {
8341
- throw new CliError2("Usage: bun run rig task reopen [--task <id> | --all] [--reason <text>]");
8953
+ throw new CliError2("Usage: rig task reopen [--task <id> | --all] [--reason <text>]");
8342
8954
  }
8343
8955
  const summary = withMutedConsole(context.outputMode === "json", () => taskReopen(context.projectRoot, {
8344
8956
  all: allFlag.value,
@@ -10373,15 +10985,15 @@ async function executeTest(context, args) {
10373
10985
  const [command = "unit", ...rest] = args;
10374
10986
  switch (command) {
10375
10987
  case "unit":
10376
- requireNoExtraArgs(rest, "bun run rig test unit");
10988
+ requireNoExtraArgs(rest, "rig test unit");
10377
10989
  await context.runCommand(["bun", "test", "tests/harness/", "--ignore", "tests/harness/e2e/**"]);
10378
10990
  return { ok: true, group: "test", command };
10379
10991
  case "e2e":
10380
- requireNoExtraArgs(rest, "bun run rig test e2e");
10992
+ requireNoExtraArgs(rest, "rig test e2e");
10381
10993
  await context.runCommand(["bun", "test", "tests/harness/e2e/"]);
10382
10994
  return { ok: true, group: "test", command };
10383
10995
  case "all":
10384
- requireNoExtraArgs(rest, "bun run rig test all");
10996
+ requireNoExtraArgs(rest, "rig test all");
10385
10997
  await context.runCommand(["bun", "test", "tests/harness/"]);
10386
10998
  return { ok: true, group: "test", command };
10387
10999
  default:
@@ -10401,7 +11013,7 @@ async function executeSetup(context, args) {
10401
11013
  const [command = "check", ...rest] = args;
10402
11014
  switch (command) {
10403
11015
  case "bootstrap":
10404
- requireNoExtraArgs(rest, "bun run rig setup bootstrap");
11016
+ requireNoExtraArgs(rest, "rig setup bootstrap");
10405
11017
  {
10406
11018
  const hostBash = Bun.which("bash") || "/bin/bash";
10407
11019
  const env = { ...process.env };
@@ -10424,21 +11036,21 @@ async function executeSetup(context, args) {
10424
11036
  }
10425
11037
  return { ok: true, group: "setup", command };
10426
11038
  case "check":
10427
- requireNoExtraArgs(rest, `bun run rig setup ${command}`);
11039
+ requireNoExtraArgs(rest, `rig setup ${command}`);
10428
11040
  {
10429
11041
  const checks = await withMutedConsole(context.outputMode === "json", () => runSetupCheck(context.projectRoot));
10430
11042
  return { ok: true, group: "setup", command, details: { checks, failures: countDoctorFailures(checks) } };
10431
11043
  }
10432
11044
  case "setup":
10433
- requireNoExtraArgs(rest, "bun run rig setup setup");
11045
+ requireNoExtraArgs(rest, "rig setup setup");
10434
11046
  withMutedConsole(context.outputMode === "json", () => runSetupInit(context.projectRoot));
10435
11047
  return { ok: true, group: "setup", command };
10436
11048
  case "preflight":
10437
- requireNoExtraArgs(rest, "bun run rig setup preflight");
11049
+ requireNoExtraArgs(rest, "rig setup preflight");
10438
11050
  await withMutedConsole(context.outputMode === "json", () => runSetupPreflight(context.projectRoot));
10439
11051
  return { ok: true, group: "setup", command };
10440
11052
  case "install-agent-shell":
10441
- requireNoExtraArgs(rest, "bun run rig setup install-agent-shell");
11053
+ requireNoExtraArgs(rest, "rig setup install-agent-shell");
10442
11054
  if (context.outputMode === "text") {
10443
11055
  console.log("install-agent-shell is deprecated. Runtime shells now use compiled rig-agent directly.");
10444
11056
  }
@@ -10503,7 +11115,7 @@ async function executeWorkspace(context, args) {
10503
11115
  const [command = "summary", ...rest] = args;
10504
11116
  switch (command) {
10505
11117
  case "summary": {
10506
- requireNoExtraArgs(rest, "bun run rig workspace summary");
11118
+ requireNoExtraArgs(rest, "rig workspace summary");
10507
11119
  const summary = await readWorkspaceSummary(context.projectRoot);
10508
11120
  if (context.outputMode === "text") {
10509
11121
  console.log("Workspace Summary");
@@ -10528,7 +11140,7 @@ Warnings:`);
10528
11140
  return { ok: true, group: "workspace", command, details: summary };
10529
11141
  }
10530
11142
  case "topology": {
10531
- requireNoExtraArgs(rest, "bun run rig workspace topology");
11143
+ requireNoExtraArgs(rest, "rig workspace topology");
10532
11144
  const topology = readWorkspaceTopology(context.projectRoot);
10533
11145
  if (context.outputMode === "text") {
10534
11146
  console.log(`Topology: ${topology.status}`);
@@ -10541,7 +11153,7 @@ Warnings:`);
10541
11153
  return { ok: true, group: "workspace", command, details: topology };
10542
11154
  }
10543
11155
  case "remote-hosts": {
10544
- requireNoExtraArgs(rest, "bun run rig workspace remote-hosts");
11156
+ requireNoExtraArgs(rest, "rig workspace remote-hosts");
10545
11157
  const fleet = readWorkspaceRemoteFleet(context.projectRoot);
10546
11158
  if (context.outputMode === "text") {
10547
11159
  console.log(`Remote Hosts: ${fleet.status}`);
@@ -10556,7 +11168,7 @@ Warnings:`);
10556
11168
  let pending = serviceRest;
10557
11169
  const services = takeOption(pending, "--service");
10558
11170
  pending = services.rest;
10559
- requireNoExtraArgs(pending, "bun run rig workspace service-fabric <status|up|verify|down> [--service <name>]");
11171
+ requireNoExtraArgs(pending, "rig workspace service-fabric <status|up|verify|down> [--service <name>]");
10560
11172
  if (action !== "status" && action !== "up" && action !== "verify" && action !== "down") {
10561
11173
  throw new CliError2(`Unknown workspace service-fabric action: ${action}`);
10562
11174
  }
@@ -10577,200 +11189,6 @@ Warnings:`);
10577
11189
  }
10578
11190
  }
10579
11191
 
10580
- // packages/cli/src/commands/_help-catalog.ts
10581
- import pc4 from "picocolors";
10582
- var PRIMARY_GROUPS = [
10583
- {
10584
- name: "init",
10585
- summary: "Set up Rig for this repo: server, GitHub auth, checkout strategy, task source, and Pi wiring.",
10586
- usage: ["rig init [--yes] [--server local|remote] [--repo owner/repo] [--remote-url <url>]"],
10587
- commands: [
10588
- { command: "init", description: "Interactive setup wizard for a new or existing Rig repo.", primary: true },
10589
- { command: "init --yes", description: "Non-interactive setup using detected/default settings.", primary: true },
10590
- { command: "init --server remote --remote-url <url>", description: "Link this repo to a remote Rig server.", primary: true },
10591
- { command: "init --repair", description: "Repair missing private state without replacing project config." }
10592
- ],
10593
- examples: [
10594
- "rig init",
10595
- "rig init --yes --repo humanity-org/humanwork",
10596
- "rig init --server remote --remote-url https://where.rig-does.work --repo owner/repo"
10597
- ],
10598
- next: ["After init, run `rig server status`.", "Then use `rig task list` and `rig task run --next` for day-to-day work."]
10599
- },
10600
- {
10601
- name: "server",
10602
- summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
10603
- usage: ["rig server <status|list|add|use|start> [options]"],
10604
- commands: [
10605
- { command: "status", description: "Show the selected server for this repo.", primary: true },
10606
- { command: "list", description: "List saved local/remote server aliases.", primary: true },
10607
- { command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
10608
- { command: "use [alias|local]", description: "Select a server; prompts in an interactive TTY.", primary: true },
10609
- { command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process.", primary: true }
10610
- ],
10611
- examples: [
10612
- "rig server status",
10613
- "rig server add prod https://where.rig-does.work",
10614
- "rig server use prod",
10615
- "rig server use local",
10616
- "rig server start --port 3773"
10617
- ],
10618
- next: ["Use `rig task list` to see server-owned work.", "Use `rig run list` or `rig run attach <id> --follow` to monitor runs."],
10619
- advanced: ["Compatibility alias: `rig connect ...` remains callable."]
10620
- },
10621
- {
10622
- name: "task",
10623
- summary: "Find work, start Pi-backed runs, and validate task results.",
10624
- usage: ["rig task <list|next|show|run> [options]"],
10625
- commands: [
10626
- { command: "list [--assignee <login|@me>] [--state open|closed]", description: "List tasks from the selected server/source.", primary: true },
10627
- { command: "next [filters]", description: "Pick the next matching task.", primary: true },
10628
- { command: "show <id>|--task <id>", description: "Show task details.", primary: true },
10629
- { command: "run [#<issue>|<task-id>|--next|--task <id>]", description: "Submit a task run; interactive follows with bundled Pi.", primary: true },
10630
- { command: "validate|verify [--task <id>]", description: "Run configured task checks/review gates." },
10631
- { command: "artifacts|artifact-dir|artifact-write", description: "Inspect or write task artifacts." },
10632
- { command: "report-bug", description: "Create a structured bug report/task." }
10633
- ],
10634
- examples: [
10635
- "rig task list --assignee @me --limit 20",
10636
- "rig task run --next",
10637
- "rig task run #123 --runtime-adapter pi",
10638
- "rig task run --title 'Investigate deploy drift' --initial-prompt 'Check server health'"
10639
- ],
10640
- next: ["Use `--detach` to submit without attaching.", "Use `rig run attach <run-id> --follow` to rejoin a live run."]
10641
- },
10642
- {
10643
- name: "run",
10644
- summary: "Observe, attach to, and control Rig runs.",
10645
- usage: ["rig run <list|status|show|attach|stop> [options]"],
10646
- commands: [
10647
- { command: "list", description: "List recent runs from the selected server or local state.", primary: true },
10648
- { command: "status", description: "Summarize active and recent runs.", primary: true },
10649
- { command: "show --run <id>", description: "Show one run record.", primary: true },
10650
- { command: "attach <run-id>|--run <id> [--follow]", description: "Attach to the run; `--follow` launches native bundled Pi for live Pi runs.", primary: true },
10651
- { command: "stop [<run-id>|--run <id>]", description: "Request stop for one run or local active runs.", primary: true },
10652
- { command: "timeline --run <id> [--follow]", description: "Stream raw run timeline events." },
10653
- { command: "delete|cleanup", description: "Remove completed run records/artifacts." }
10654
- ],
10655
- examples: [
10656
- "rig run list",
10657
- "rig run attach 01234567-89ab-cdef-0123-456789abcdef --follow",
10658
- "rig run show --run <run-id>",
10659
- "rig run stop <run-id>"
10660
- ],
10661
- next: ["Use `rig task run --next` to create a new run.", "Use `--json` when scripts need the full structured record."]
10662
- }
10663
- ];
10664
- var ADVANCED_GROUPS = [
10665
- { name: "connect", summary: "Compatibility alias for `rig server` selection commands.", usage: ["rig connect <status|list|add|use>"], commands: [{ command: "status|list|add|use", description: "Use `rig server ...` for the primary UX." }] },
10666
- { name: "github", summary: "GitHub auth helpers.", usage: ["rig github auth <status|import-gh|token>"], commands: [{ command: "auth status", description: "Show GitHub auth state." }] },
10667
- { name: "doctor", summary: "Diagnostics for project/server/GitHub/Pi state.", usage: ["rig doctor [check|run|shared|...]"], commands: [{ command: "check", description: "Run diagnostics." }] },
10668
- { name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
10669
- { name: "inspect", summary: "Inspect logs, artifacts, graphs, failures.", usage: ["rig inspect <logs|artifacts|failures|graph|audit|diff>"], commands: [{ command: "logs --task <id>", description: "Inspect task logs." }] },
10670
- { name: "repo", summary: "Repository sync/baseline helpers.", usage: ["rig repo <sync|reset-baseline>"], commands: [{ command: "sync", description: "Sync project repository state." }] },
10671
- { name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
10672
- { name: "review", summary: "Review policy configuration.", usage: ["rig review <show|set>"], commands: [{ command: "show", description: "Show review settings." }] },
10673
- { name: "browser", summary: "Browser/app diagnostics.", usage: ["rig browser <help|explain|demo|app>"], commands: [{ command: "help", description: "Browser command help." }] },
10674
- { name: "plugin", summary: "Plugin validation/listing.", usage: ["rig plugin <list|validate>"], commands: [{ command: "list", description: "List plugins." }] },
10675
- { name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
10676
- { name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
10677
- { name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
10678
- { name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
10679
- { name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
10680
- { name: "remote", summary: "Legacy remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
10681
- { name: "inbox", summary: "Approval/input inbox for blocked runs.", usage: ["rig inbox <approvals|approve|inputs|respond>"], commands: [{ command: "approvals", description: "List pending approvals." }] },
10682
- { name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
10683
- { name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
10684
- { name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
10685
- ];
10686
- var ALL_GROUPS = [...PRIMARY_GROUPS, ...ADVANCED_GROUPS];
10687
- function heading(title) {
10688
- return pc4.bold(pc4.cyan(title));
10689
- }
10690
- function commandLine(command, description) {
10691
- const commandColumn = command.length >= 34 ? `${command} ` : command.padEnd(34);
10692
- return `${pc4.dim("\u2502")} ${pc4.bold(commandColumn)} ${description}`;
10693
- }
10694
- function renderGroup(group) {
10695
- const lines = [
10696
- `${heading(`rig ${group.name}`)} \u2014 ${group.summary}`,
10697
- "",
10698
- pc4.bold("Usage"),
10699
- ...group.usage.map((line) => ` ${line}`),
10700
- "",
10701
- pc4.bold("Commands"),
10702
- ...group.commands.map((entry) => commandLine(entry.command, entry.description))
10703
- ];
10704
- if (group.examples?.length) {
10705
- lines.push("", pc4.bold("Examples"), ...group.examples.map((line) => ` ${pc4.dim("$")} ${line}`));
10706
- }
10707
- if (group.next?.length) {
10708
- lines.push("", pc4.bold("Next steps"), ...group.next.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
10709
- }
10710
- if (group.advanced?.length) {
10711
- lines.push("", pc4.bold("Compatibility / advanced"), ...group.advanced.map((line) => ` ${pc4.dim("\u203A")} ${line}`));
10712
- }
10713
- return lines.join(`
10714
- `);
10715
- }
10716
- function renderTopLevelHelp() {
10717
- return [
10718
- `${heading("rig")} ${pc4.dim("\u2014 server-owned task/run control plane for Pi-backed engineering work")}`,
10719
- pc4.dim("A repo-local CLI for setup, server selection, task runs, live attach, and completion review."),
10720
- "",
10721
- `${pc4.bold(pc4.magenta("\u25C7 Start here"))} \u2014 ${pc4.dim("bootstrap a repo and choose where Rig runs")}`,
10722
- commandLine("rig init", "Interactive setup: project config, GitHub auth, task source, server, checkout, Pi."),
10723
- commandLine("rig init --yes", "Non-interactive setup using detected defaults; good for repeatable installs."),
10724
- commandLine("rig server status", "Show whether this repo is using local Rig or a remote server."),
10725
- commandLine("rig server use <alias|local>", "Switch the server that owns task/run state for this repo."),
10726
- "",
10727
- `${pc4.bold(pc4.magenta("\u25C7 Daily task loop"))} \u2014 ${pc4.dim("find work, start a worker, and rejoin it later")}`,
10728
- commandLine("rig task list", "List tasks from the selected task source/server with status, labels, and source."),
10729
- commandLine("rig task next", "Pick the next matching task without starting it."),
10730
- commandLine("rig task run --next", "Start the next task and attach to the live bundled Pi frontend."),
10731
- commandLine("rig task run #123 --detach", "Submit a specific issue/task and return immediately."),
10732
- "",
10733
- `${pc4.bold(pc4.magenta("\u25C7 Live run control"))} \u2014 ${pc4.dim("observe, steer, stop, or inspect active runs")}`,
10734
- commandLine("rig run list", "Show recent/active runs from the selected server or local state."),
10735
- commandLine("rig run attach <run-id> --follow", "Open the native Pi live view for a worker-backed run."),
10736
- commandLine("rig run show --run <id>", "Print one run record; add `--json` for automation."),
10737
- commandLine("rig run stop <run-id>", "Request cancellation for a running worker."),
10738
- "",
10739
- `${pc4.bold(pc4.magenta("\u25C7 Core groups"))} \u2014 ${pc4.dim("run `rig <group> --help` for detailed commands and examples")}`,
10740
- ...PRIMARY_GROUPS.map((group) => commandLine(group.name, group.summary)),
10741
- commandLine("doctor", "Diagnose project/server/GitHub/task/Pi wiring when setup or runs misbehave."),
10742
- "",
10743
- `${pc4.bold(pc4.magenta("\u25C7 More"))}`,
10744
- commandLine("rig help --advanced", "Legacy, dev, diagnostics, browser, queue, agent, remote, git, harness commands."),
10745
- commandLine("rig <group> --help", "Rich per-group help with usage, descriptions, examples, and next steps."),
10746
- commandLine("rig --version", "Print the installed Rig CLI version."),
10747
- "",
10748
- `${pc4.bold(pc4.magenta("\u25C7 Global options"))}`,
10749
- commandLine("--project <path>", "Use a project root instead of auto-discovery."),
10750
- commandLine("--json", "Emit structured output for scripts/agents."),
10751
- commandLine("--dry-run", "Print the command plan without mutating state.")
10752
- ].join(`
10753
- `);
10754
- }
10755
- function renderAdvancedHelp() {
10756
- return [
10757
- `${heading("rig advanced")} \u2014 legacy, dev, and compatibility groups`,
10758
- "",
10759
- pc4.bold("Primary groups are still"),
10760
- " init, server, task, run",
10761
- "",
10762
- pc4.bold("Advanced groups"),
10763
- ...ADVANCED_GROUPS.map((group) => commandLine(group.name, group.summary)),
10764
- "",
10765
- pc4.dim("All groups remain callable. Prefer `rig server`, `rig task`, and `rig run` for day-to-day work.")
10766
- ].join(`
10767
- `);
10768
- }
10769
- function renderGroupHelp(groupName) {
10770
- const group = ALL_GROUPS.find((candidate) => candidate.name === groupName);
10771
- return group ? renderGroup(group) : null;
10772
- }
10773
-
10774
11192
  // packages/cli/src/commands.ts
10775
11193
  import { ensureProjectMainFreshBeforeRun as ensureProjectMainFreshBeforeRun2 } from "@rig/runtime/control-plane/project-main-pre-run-sync";
10776
11194
  var TOP_LEVEL_ALIASES = {
@@ -10782,7 +11200,7 @@ var TOP_LEVEL_ALIASES = {
10782
11200
  status: ["run", "status"],
10783
11201
  start: ["task", "run", "--next"],
10784
11202
  "start-parallel": ["run", "start-parallel"],
10785
- "start-serial": ["task", "run", "--next"],
11203
+ "start-serial": ["run", "start-serial"],
10786
11204
  resume: ["run", "resume"],
10787
11205
  stop: ["run", "stop"],
10788
11206
  ready: ["task", "ready"],
@@ -10838,7 +11256,7 @@ var GROUPS = new Set([
10838
11256
  "test"
10839
11257
  ]);
10840
11258
  function printGroupHelp(group) {
10841
- console.log(renderGroupHelp(group) ?? helpText());
11259
+ printGroupHelpDocument(group);
10842
11260
  }
10843
11261
  function isHelpArg(arg) {
10844
11262
  return arg === "--help" || arg === "-h" || arg === "help";
@@ -10848,7 +11266,7 @@ function helpText() {
10848
11266
  }
10849
11267
  async function execute(context, args) {
10850
11268
  if (args.length === 0) {
10851
- console.log(helpText());
11269
+ printTopLevelHelp();
10852
11270
  return { ok: true, group: "help", command: "show" };
10853
11271
  }
10854
11272
  const [first, ...rest] = args;
@@ -10859,14 +11277,14 @@ ${helpText()}`);
10859
11277
  }
10860
11278
  if (first === "help" || first === "--help" || first === "-h") {
10861
11279
  if (rest[0] === "--advanced") {
10862
- console.log(renderAdvancedHelp());
11280
+ printAdvancedHelp();
10863
11281
  return { ok: true, group: "help", command: "advanced" };
10864
11282
  }
10865
11283
  if (rest[0]) {
10866
- console.log(renderGroupHelp(rest[0]) ?? helpText());
11284
+ printGroupHelp(rest[0]);
10867
11285
  return { ok: true, group: "help", command: rest[0] };
10868
11286
  }
10869
- console.log(helpText());
11287
+ printTopLevelHelp();
10870
11288
  return { ok: true, group: "help", command: "show" };
10871
11289
  }
10872
11290
  if (first === "--version" || first === "-V" || first === "version") {