@h-rig/cli 0.0.6-alpha.82 → 0.0.6-alpha.84

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 (206) hide show
  1. package/dist/bin/build-rig-binaries.js +40 -8
  2. package/dist/bin/rig.js +23402 -14577
  3. package/dist/src/app/board.js +217 -41
  4. package/dist/src/app-opentui/adapters/command.d.ts +2 -0
  5. package/dist/src/app-opentui/adapters/command.js +329 -0
  6. package/dist/src/app-opentui/adapters/common.js +2 -2
  7. package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
  8. package/dist/src/app-opentui/adapters/doctor.js +64 -39
  9. package/dist/src/app-opentui/adapters/family.d.ts +62 -0
  10. package/dist/src/app-opentui/adapters/family.js +14305 -0
  11. package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
  12. package/dist/src/app-opentui/adapters/fleet.js +90 -60
  13. package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
  14. package/dist/src/app-opentui/adapters/inbox.js +137 -78
  15. package/dist/src/app-opentui/adapters/init.d.ts +0 -2
  16. package/dist/src/app-opentui/adapters/init.js +85 -47
  17. package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
  18. package/dist/src/app-opentui/adapters/inspect.js +1024 -0
  19. package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
  20. package/dist/src/app-opentui/adapters/pi-attach.js +442 -125
  21. package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
  22. package/dist/src/app-opentui/adapters/pi.js +363 -0
  23. package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
  24. package/dist/src/app-opentui/adapters/plugin.js +544 -0
  25. package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
  26. package/dist/src/app-opentui/adapters/repo.js +186 -0
  27. package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
  28. package/dist/src/app-opentui/adapters/run-detail.js +180 -63
  29. package/dist/src/app-opentui/adapters/server.d.ts +10 -2
  30. package/dist/src/app-opentui/adapters/server.js +191 -45
  31. package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
  32. package/dist/src/app-opentui/adapters/tasks.js +1123 -143
  33. package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
  34. package/dist/src/app-opentui/adapters/workspace.js +333 -0
  35. package/dist/src/app-opentui/autocomplete.d.ts +20 -0
  36. package/dist/src/app-opentui/autocomplete.js +576 -0
  37. package/dist/src/app-opentui/bootstrap.d.ts +1 -6
  38. package/dist/src/app-opentui/bootstrap.js +25252 -16474
  39. package/dist/src/app-opentui/command-palette.d.ts +3 -0
  40. package/dist/src/app-opentui/command-palette.js +1010 -0
  41. package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
  42. package/dist/src/app-opentui/command-pty-host.js +248 -0
  43. package/dist/src/app-opentui/drone.js +8 -6
  44. package/dist/src/app-opentui/events.js +1 -1
  45. package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
  46. package/dist/src/app-opentui/fleet-stats.js +114 -0
  47. package/dist/src/app-opentui/focus-manager.d.ts +14 -0
  48. package/dist/src/app-opentui/focus-manager.js +24 -0
  49. package/dist/src/app-opentui/index.js +5431 -2797
  50. package/dist/src/app-opentui/intent.js +179 -50
  51. package/dist/src/app-opentui/keymap.d.ts +21 -0
  52. package/dist/src/app-opentui/keymap.js +1748 -0
  53. package/dist/src/app-opentui/launch-routing.d.ts +16 -0
  54. package/dist/src/app-opentui/launch-routing.js +55 -0
  55. package/dist/src/app-opentui/layout.d.ts +7 -0
  56. package/dist/src/app-opentui/layout.js +13 -6
  57. package/dist/src/app-opentui/list-search.d.ts +24 -0
  58. package/dist/src/app-opentui/list-search.js +88 -1
  59. package/dist/src/app-opentui/pi-host-child.js +99 -17
  60. package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
  61. package/dist/src/app-opentui/pi-pty-host.js +30 -14
  62. package/dist/src/app-opentui/react/App.d.ts +9 -0
  63. package/dist/src/app-opentui/react/App.js +5144 -0
  64. package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
  65. package/dist/src/app-opentui/react/Backdrop.js +1834 -0
  66. package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
  67. package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
  68. package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
  69. package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
  70. package/dist/src/app-opentui/react/context.d.ts +17 -0
  71. package/dist/src/app-opentui/react/context.js +37 -0
  72. package/dist/src/app-opentui/react/launch.d.ts +2 -0
  73. package/dist/src/app-opentui/react/launch.js +5743 -0
  74. package/dist/src/app-opentui/react/nav.d.ts +18 -0
  75. package/dist/src/app-opentui/react/nav.js +54 -0
  76. package/dist/src/app-opentui/react/scroll.d.ts +12 -0
  77. package/dist/src/app-opentui/react/scroll.js +21 -0
  78. package/dist/src/app-opentui/react/syntax.d.ts +2 -0
  79. package/dist/src/app-opentui/react/syntax.js +64 -0
  80. package/dist/src/app-opentui/registry.js +20428 -4828
  81. package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
  82. package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
  83. package/dist/src/app-opentui/render/constants.d.ts +31 -0
  84. package/dist/src/app-opentui/render/constants.js +66 -0
  85. package/dist/src/app-opentui/render/graphics.d.ts +2 -1
  86. package/dist/src/app-opentui/render/graphics.js +228 -46
  87. package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
  88. package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
  89. package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
  90. package/dist/src/app-opentui/render/native-host.d.ts +37 -0
  91. package/dist/src/app-opentui/render/native-host.js +179 -0
  92. package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
  93. package/dist/src/app-opentui/render/panel-layout.js +48 -0
  94. package/dist/src/app-opentui/render/panels.d.ts +2 -0
  95. package/dist/src/app-opentui/render/panels.js +78 -38
  96. package/dist/src/app-opentui/render/preloader.d.ts +10 -0
  97. package/dist/src/app-opentui/render/preloader.js +165 -0
  98. package/dist/src/app-opentui/render/scene.d.ts +53 -1
  99. package/dist/src/app-opentui/render/scene.js +195 -6
  100. package/dist/src/app-opentui/render/text.d.ts +7 -1
  101. package/dist/src/app-opentui/render/text.js +15 -8
  102. package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
  103. package/dist/src/app-opentui/render/type-bar.js +113 -39
  104. package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
  105. package/dist/src/app-opentui/runtime-resources.js +62 -0
  106. package/dist/src/app-opentui/runtime.d.ts +44 -1
  107. package/dist/src/app-opentui/runtime.js +5415 -2738
  108. package/dist/src/app-opentui/scenes/command.d.ts +3 -0
  109. package/dist/src/app-opentui/scenes/command.js +117 -0
  110. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
  111. package/dist/src/app-opentui/scenes/doctor.js +221 -17
  112. package/dist/src/app-opentui/scenes/error.js +60 -20
  113. package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
  114. package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
  115. package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
  116. package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
  117. package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
  118. package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
  119. package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
  120. package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
  121. package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
  122. package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
  123. package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
  124. package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
  125. package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
  126. package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
  127. package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
  128. package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
  129. package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
  130. package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
  131. package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
  132. package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
  133. package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
  134. package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
  135. package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
  136. package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
  137. package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
  138. package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
  139. package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
  140. package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
  141. package/dist/src/app-opentui/scenes/family.d.ts +3 -0
  142. package/dist/src/app-opentui/scenes/family.js +2144 -0
  143. package/dist/src/app-opentui/scenes/fleet.js +552 -43
  144. package/dist/src/app-opentui/scenes/handoff.js +342 -35
  145. package/dist/src/app-opentui/scenes/help.js +640 -56
  146. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
  147. package/dist/src/app-opentui/scenes/inbox.js +329 -21
  148. package/dist/src/app-opentui/scenes/init.d.ts +2 -1
  149. package/dist/src/app-opentui/scenes/init.js +120 -34
  150. package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
  151. package/dist/src/app-opentui/scenes/inspect.js +793 -0
  152. package/dist/src/app-opentui/scenes/main.d.ts +2 -1
  153. package/dist/src/app-opentui/scenes/main.js +264 -29
  154. package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
  155. package/dist/src/app-opentui/scenes/pi.js +508 -0
  156. package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
  157. package/dist/src/app-opentui/scenes/plugin.js +486 -0
  158. package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
  159. package/dist/src/app-opentui/scenes/repo.js +424 -0
  160. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
  161. package/dist/src/app-opentui/scenes/run-detail.js +362 -35
  162. package/dist/src/app-opentui/scenes/server.d.ts +2 -1
  163. package/dist/src/app-opentui/scenes/server.js +243 -26
  164. package/dist/src/app-opentui/scenes/tasks.js +518 -41
  165. package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
  166. package/dist/src/app-opentui/scenes/workspace.js +426 -0
  167. package/dist/src/app-opentui/selectable.d.ts +19 -0
  168. package/dist/src/app-opentui/selectable.js +79 -0
  169. package/dist/src/app-opentui/state.js +129 -36
  170. package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
  171. package/dist/src/app-opentui/surface-catalog.js +540 -0
  172. package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
  173. package/dist/src/app-opentui/terminal-capabilities.js +15 -0
  174. package/dist/src/app-opentui/theme.d.ts +28 -6
  175. package/dist/src/app-opentui/theme.js +61 -8
  176. package/dist/src/app-opentui/types.d.ts +130 -5
  177. package/dist/src/commands/_authority-runs.d.ts +1 -1
  178. package/dist/src/commands/_authority-runs.js +2 -12
  179. package/dist/src/commands/_doctor-checks.js +62 -13
  180. package/dist/src/commands/_help-catalog.js +95 -15
  181. package/dist/src/commands/_operator-view.js +97 -15
  182. package/dist/src/commands/_pi-frontend.d.ts +2 -0
  183. package/dist/src/commands/_pi-frontend.js +97 -13
  184. package/dist/src/commands/_preflight.js +64 -14
  185. package/dist/src/commands/_server-client.js +82 -18
  186. package/dist/src/commands/_server-events.d.ts +26 -0
  187. package/dist/src/commands/_server-events.js +310 -0
  188. package/dist/src/commands/_snapshot-upload.js +62 -13
  189. package/dist/src/commands/agent.js +2 -12
  190. package/dist/src/commands/connect.js +7 -1
  191. package/dist/src/commands/doctor.js +62 -13
  192. package/dist/src/commands/github.js +144 -23
  193. package/dist/src/commands/inbox.js +62 -13
  194. package/dist/src/commands/init.js +82 -18
  195. package/dist/src/commands/inspect.js +62 -13
  196. package/dist/src/commands/run.js +100 -15
  197. package/dist/src/commands/server.js +71 -26
  198. package/dist/src/commands/setup.js +62 -13
  199. package/dist/src/commands/stats.js +157 -28
  200. package/dist/src/commands/task-run-driver.js +64 -25
  201. package/dist/src/commands/task.js +196 -43
  202. package/dist/src/commands.js +419 -123
  203. package/dist/src/index.js +426 -130
  204. package/package.json +11 -10
  205. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
  206. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
@@ -96,18 +96,8 @@ function resolveControlPlaneTaskConfigPath(projectRoot) {
96
96
 
97
97
  // packages/cli/src/commands/_authority-runs.ts
98
98
  var RIG_WORKSPACE_ID = "rig-local-workspace";
99
- function normalizeRuntimeAdapter(value) {
100
- const normalized = value?.trim().toLowerCase();
101
- if (!normalized) {
102
- return "pi";
103
- }
104
- if (normalized === "codex" || normalized === "codex-cli" || normalized === "codex-app-server" || normalized === "gpt-codex") {
105
- return "codex";
106
- }
107
- if (normalized === "pi" || normalized === "rig-pi" || normalized === "@rig/pi") {
108
- return "pi";
109
- }
110
- return "claude-code";
99
+ function normalizeRuntimeAdapter(_value) {
100
+ return "pi";
111
101
  }
112
102
  function readLatestBeadRecord(projectRoot, taskId) {
113
103
  const issuesPath = resolve2(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
@@ -551,17 +541,21 @@ function cleanToken(value) {
551
541
  const trimmed = value?.trim();
552
542
  return trimmed ? trimmed : null;
553
543
  }
554
- function readPrivateRemoteSessionToken(projectRoot) {
544
+ function readRemoteAuthState(projectRoot) {
555
545
  const path = resolve5(projectRoot, ".rig", "state", "github-auth.json");
556
546
  if (!existsSync3(path))
557
547
  return null;
558
548
  try {
559
549
  const parsed = JSON.parse(readFileSync3(path, "utf8"));
560
- return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
550
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
561
551
  } catch {
562
552
  return null;
563
553
  }
564
554
  }
555
+ function readPrivateRemoteSessionToken(projectRoot) {
556
+ const parsed = readRemoteAuthState(projectRoot);
557
+ return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
558
+ }
565
559
  function readGitHubBearerTokenForRemote(projectRoot) {
566
560
  const scopedKey = resolve5(projectRoot);
567
561
  if (scopedGitHubBearerTokens.has(scopedKey))
@@ -572,15 +566,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
572
566
  return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
573
567
  }
574
568
  function readStoredGitHubAuthToken(projectRoot) {
575
- const path = resolve5(projectRoot, ".rig", "state", "github-auth.json");
576
- if (!existsSync3(path))
569
+ const parsed = readRemoteAuthState(projectRoot);
570
+ return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
571
+ }
572
+ function inferRemoteServerProjectRootFromAuthState(projectRoot) {
573
+ const repo = readRepoConnection(projectRoot);
574
+ const slug = repo?.project?.trim();
575
+ if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
577
576
  return null;
578
- try {
579
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
580
- return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
581
- } catch {
577
+ const auth = readRemoteAuthState(projectRoot);
578
+ const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
579
+ const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
580
+ if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
582
581
  return null;
583
- }
582
+ const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
583
+ if (!checkoutBaseDir)
584
+ return null;
585
+ const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
586
+ writeRepoServerProjectRoot(projectRoot, inferred);
587
+ return inferred;
584
588
  }
585
589
  function readLocalConnectionFallbackToken(projectRoot) {
586
590
  return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
@@ -591,7 +595,7 @@ async function ensureServerForCli(projectRoot) {
591
595
  if (selected?.connection.kind === "remote") {
592
596
  reportServerPhase(`Connecting to ${selected.alias}\u2026`);
593
597
  const authToken = readGitHubBearerTokenForRemote(projectRoot);
594
- const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
598
+ const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
595
599
  return {
596
600
  baseUrl: selected.connection.baseUrl,
597
601
  authToken,
@@ -620,7 +624,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
620
624
  if (!slug)
621
625
  return null;
622
626
  try {
623
- const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
627
+ const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
628
+ if (authToken && queryAuthFallbackEnabled())
629
+ url.searchParams.set("rt", authToken);
630
+ const response = await fetch(url, {
624
631
  headers: mergeHeaders(undefined, authToken)
625
632
  });
626
633
  if (!response.ok)
@@ -637,10 +644,23 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
637
644
  return null;
638
645
  }
639
646
  }
647
+ function mergeCookie(existing, name, value) {
648
+ const encoded = `${name}=${encodeURIComponent(value)}`;
649
+ if (!existing?.trim())
650
+ return encoded;
651
+ const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
652
+ return [...parts, encoded].join("; ");
653
+ }
654
+ function queryAuthFallbackEnabled(env = process.env) {
655
+ return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
656
+ }
640
657
  function mergeHeaders(headers, authToken) {
641
658
  const merged = new Headers(headers);
642
659
  if (authToken) {
643
- merged.set("authorization", `Bearer ${authToken}`);
660
+ const bearer = `Bearer ${authToken}`;
661
+ merged.set("authorization", bearer);
662
+ merged.set("x-auth", bearer);
663
+ merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
644
664
  }
645
665
  return merged;
646
666
  }
@@ -701,15 +721,34 @@ async function buildServerFailureContext(projectRoot, server) {
701
721
  hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
702
722
  };
703
723
  }
724
+ function isLoopbackRemoteBaseUrl(baseUrl) {
725
+ try {
726
+ const host = new URL(baseUrl).hostname.toLowerCase();
727
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
728
+ } catch {
729
+ return false;
730
+ }
731
+ }
732
+ function canUseRemoteWithoutProjectRoot(pathname) {
733
+ return pathname === "/health" || pathname === "/api/health" || pathname === "/api/server/status" || pathname === "/api/server/project-root" || pathname.startsWith("/api/github/auth/") || pathname === "/api/projects" || pathname.startsWith("/api/projects/");
734
+ }
704
735
  async function requestServerJson(context, pathname, init = {}) {
705
736
  const server = await ensureServerForCli(context.projectRoot);
737
+ const requestUrl = new URL(`${server.baseUrl}${pathname}`);
738
+ if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
739
+ const repo = readRepoConnection(context.projectRoot);
740
+ throw new CliError(`Remote server is selected for ${repo?.project ?? "this repo"}, but this checkout has no server-host project root link.`, 1, { hint: "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to repair the remote project link before task/run commands." });
741
+ }
706
742
  const headers = mergeHeaders(init.headers, server.authToken);
707
743
  if (server.serverProjectRoot)
708
744
  headers.set("x-rig-project-root", server.serverProjectRoot);
745
+ if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
746
+ requestUrl.searchParams.set("rt", server.authToken);
747
+ }
709
748
  reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
710
749
  let response;
711
750
  try {
712
- response = await fetch(`${server.baseUrl}${pathname}`, {
751
+ response = await fetch(requestUrl, {
713
752
  ...init,
714
753
  headers
715
754
  });
@@ -306,18 +306,8 @@ import {
306
306
  import { resolveMonorepoRoot } from "@rig/runtime/control-plane/native/utils";
307
307
 
308
308
  // packages/cli/src/commands/_authority-runs.ts
309
- function normalizeRuntimeAdapter(value) {
310
- const normalized = value?.trim().toLowerCase();
311
- if (!normalized) {
312
- return "pi";
313
- }
314
- if (normalized === "codex" || normalized === "codex-cli" || normalized === "codex-app-server" || normalized === "gpt-codex") {
315
- return "codex";
316
- }
317
- if (normalized === "pi" || normalized === "rig-pi" || normalized === "@rig/pi") {
318
- return "pi";
319
- }
320
- return "claude-code";
309
+ function normalizeRuntimeAdapter(_value) {
310
+ return "pi";
321
311
  }
322
312
 
323
313
  // packages/cli/src/commands/_preflight.ts
@@ -438,17 +428,21 @@ function cleanToken(value) {
438
428
  const trimmed = value?.trim();
439
429
  return trimmed ? trimmed : null;
440
430
  }
441
- function readPrivateRemoteSessionToken(projectRoot) {
431
+ function readRemoteAuthState(projectRoot) {
442
432
  const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
443
433
  if (!existsSync2(path))
444
434
  return null;
445
435
  try {
446
436
  const parsed = JSON.parse(readFileSync2(path, "utf8"));
447
- return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
437
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
448
438
  } catch {
449
439
  return null;
450
440
  }
451
441
  }
442
+ function readPrivateRemoteSessionToken(projectRoot) {
443
+ const parsed = readRemoteAuthState(projectRoot);
444
+ return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
445
+ }
452
446
  function readGitHubBearerTokenForRemote(projectRoot) {
453
447
  const scopedKey = resolve2(projectRoot);
454
448
  if (scopedGitHubBearerTokens.has(scopedKey))
@@ -459,15 +453,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
459
453
  return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
460
454
  }
461
455
  function readStoredGitHubAuthToken(projectRoot) {
462
- const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
463
- if (!existsSync2(path))
456
+ const parsed = readRemoteAuthState(projectRoot);
457
+ return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
458
+ }
459
+ function inferRemoteServerProjectRootFromAuthState(projectRoot) {
460
+ const repo = readRepoConnection(projectRoot);
461
+ const slug = repo?.project?.trim();
462
+ if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
464
463
  return null;
465
- try {
466
- const parsed = JSON.parse(readFileSync2(path, "utf8"));
467
- return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
468
- } catch {
464
+ const auth = readRemoteAuthState(projectRoot);
465
+ const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
466
+ const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
467
+ if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
469
468
  return null;
470
- }
469
+ const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
470
+ if (!checkoutBaseDir)
471
+ return null;
472
+ const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
473
+ writeRepoServerProjectRoot(projectRoot, inferred);
474
+ return inferred;
471
475
  }
472
476
  function readLocalConnectionFallbackToken(projectRoot) {
473
477
  return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
@@ -478,7 +482,7 @@ async function ensureServerForCli(projectRoot) {
478
482
  if (selected?.connection.kind === "remote") {
479
483
  reportServerPhase(`Connecting to ${selected.alias}\u2026`);
480
484
  const authToken = readGitHubBearerTokenForRemote(projectRoot);
481
- const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
485
+ const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
482
486
  return {
483
487
  baseUrl: selected.connection.baseUrl,
484
488
  authToken,
@@ -507,7 +511,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
507
511
  if (!slug)
508
512
  return null;
509
513
  try {
510
- const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
514
+ const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
515
+ if (authToken && queryAuthFallbackEnabled())
516
+ url.searchParams.set("rt", authToken);
517
+ const response = await fetch(url, {
511
518
  headers: mergeHeaders(undefined, authToken)
512
519
  });
513
520
  if (!response.ok)
@@ -534,10 +541,23 @@ function appendTaskFilterParams(url, filters) {
534
541
  if (filters.limit !== undefined)
535
542
  url.searchParams.set("limit", String(filters.limit));
536
543
  }
544
+ function mergeCookie(existing, name, value) {
545
+ const encoded = `${name}=${encodeURIComponent(value)}`;
546
+ if (!existing?.trim())
547
+ return encoded;
548
+ const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
549
+ return [...parts, encoded].join("; ");
550
+ }
551
+ function queryAuthFallbackEnabled(env = process.env) {
552
+ return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
553
+ }
537
554
  function mergeHeaders(headers, authToken) {
538
555
  const merged = new Headers(headers);
539
556
  if (authToken) {
540
- merged.set("authorization", `Bearer ${authToken}`);
557
+ const bearer = `Bearer ${authToken}`;
558
+ merged.set("authorization", bearer);
559
+ merged.set("x-auth", bearer);
560
+ merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
541
561
  }
542
562
  return merged;
543
563
  }
@@ -598,15 +618,34 @@ async function buildServerFailureContext(projectRoot, server) {
598
618
  hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
599
619
  };
600
620
  }
621
+ function isLoopbackRemoteBaseUrl(baseUrl) {
622
+ try {
623
+ const host = new URL(baseUrl).hostname.toLowerCase();
624
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
625
+ } catch {
626
+ return false;
627
+ }
628
+ }
629
+ function canUseRemoteWithoutProjectRoot(pathname) {
630
+ return pathname === "/health" || pathname === "/api/health" || pathname === "/api/server/status" || pathname === "/api/server/project-root" || pathname.startsWith("/api/github/auth/") || pathname === "/api/projects" || pathname.startsWith("/api/projects/");
631
+ }
601
632
  async function requestServerJson(context, pathname, init = {}) {
602
633
  const server = await ensureServerForCli(context.projectRoot);
634
+ const requestUrl = new URL(`${server.baseUrl}${pathname}`);
635
+ if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
636
+ const repo = readRepoConnection(context.projectRoot);
637
+ throw new CliError(`Remote server is selected for ${repo?.project ?? "this repo"}, but this checkout has no server-host project root link.`, 1, { hint: "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to repair the remote project link before task/run commands." });
638
+ }
603
639
  const headers = mergeHeaders(init.headers, server.authToken);
604
640
  if (server.serverProjectRoot)
605
641
  headers.set("x-rig-project-root", server.serverProjectRoot);
642
+ if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
643
+ requestUrl.searchParams.set("rt", server.authToken);
644
+ }
606
645
  reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
607
646
  let response;
608
647
  try {
609
- response = await fetch(`${server.baseUrl}${pathname}`, {
648
+ response = await fetch(requestUrl, {
610
649
  ...init,
611
650
  headers
612
651
  });
@@ -863,7 +902,8 @@ async function runFastTaskRunPreflight(context, options = {}) {
863
902
  }
864
903
  }
865
904
  const repo = readRepoConnection(context.projectRoot);
866
- 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>`."));
905
+ const remoteWithoutProjectLink = selectedServer?.connectionKind === "remote" && !repo?.project;
906
+ checks.push(repo ? preflightCheck("project-link", "project linked to selected server", repo.project ? "pass" : remoteWithoutProjectLink ? "fail" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : " (missing project link)"}`, remoteWithoutProjectLink ? "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to restore the remote project link." : "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to selected server", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
867
907
  try {
868
908
  const auth = await request("/api/github/auth/status");
869
909
  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>`."));
@@ -1322,6 +1362,14 @@ import { homedir as homedir2, tmpdir } from "os";
1322
1362
  import { join } from "path";
1323
1363
  import { main as runPiMain } from "@earendil-works/pi-coding-agent";
1324
1364
  import createPiRigExtension from "@rig/pi-rig";
1365
+ var TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
1366
+
1367
+ class OperatorTranscriptUnavailableError extends Error {
1368
+ constructor(message2) {
1369
+ super(message2);
1370
+ this.name = "OperatorTranscriptUnavailableError";
1371
+ }
1372
+ }
1325
1373
  function setTemporaryEnv(updates) {
1326
1374
  const previous = new Map;
1327
1375
  for (const [key, value] of Object.entries(updates)) {
@@ -1349,6 +1397,23 @@ function buildOperatorPiEnv(input) {
1349
1397
  ...input.serverProjectRoot ? { RIG_PROJECT_ROOT: input.serverProjectRoot } : {}
1350
1398
  };
1351
1399
  }
1400
+ function shouldRequireOperatorTranscript(status) {
1401
+ return typeof status === "string" && TERMINAL_RUN_STATUSES.has(status.trim().toLowerCase());
1402
+ }
1403
+ function missingOperatorTranscriptMessage(runId, status) {
1404
+ const shortRun = runId.trim().slice(0, 8) || "unknown";
1405
+ const statusText = typeof status === "string" && status.trim() ? status.trim() : "terminal";
1406
+ return `Run ${shortRun} is ${statusText}, but no worker Pi session transcript is recorded for this run. It likely failed before Pi started or predates full-session capture. Use \`rig run show ${runId}\` and \`rig run logs ${runId}\` for the lifecycle details.`;
1407
+ }
1408
+ function statusFromRunDetails(run) {
1409
+ if (!run || typeof run !== "object" || Array.isArray(run))
1410
+ return;
1411
+ const record = run;
1412
+ if (typeof record.status === "string")
1413
+ return record.status;
1414
+ const nested = record.run;
1415
+ return nested && typeof nested === "object" && !Array.isArray(nested) ? nested.status : undefined;
1416
+ }
1352
1417
  async function prepareOperatorConsole(context, runId, tempSessionDir) {
1353
1418
  const server = await ensureServerForCli(context.projectRoot);
1354
1419
  const localCwd = join(homedir2(), ".rig", "drones", runId.slice(0, 8));
@@ -1378,6 +1443,13 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
1378
1443
  sessionFileArg = ["--session", localSessionPath];
1379
1444
  }
1380
1445
  } catch {}
1446
+ if (sessionFileArg.length === 0) {
1447
+ const run = await getRunDetailsViaServer(context, runId).catch(() => null);
1448
+ const status = statusFromRunDetails(run);
1449
+ if (shouldRequireOperatorTranscript(status)) {
1450
+ throw new OperatorTranscriptUnavailableError(missingOperatorTranscriptMessage(runId, status));
1451
+ }
1452
+ }
1381
1453
  return { server, sessionFileArg };
1382
1454
  }
1383
1455
  var RIG_PI_THEME = {
@@ -1495,6 +1567,7 @@ async function attachRunBundledPiFrontend(context, input) {
1495
1567
  let detached = false;
1496
1568
  try {
1497
1569
  await runPiMain([
1570
+ "--offline",
1498
1571
  "--no-extensions",
1499
1572
  "--no-skills",
1500
1573
  "--no-prompt-templates",
@@ -1524,7 +1597,7 @@ async function attachRunBundledPiFrontend(context, input) {
1524
1597
  }
1525
1598
 
1526
1599
  // packages/cli/src/commands/_operator-view.ts
1527
- var TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
1600
+ var TERMINAL_RUN_STATUSES2 = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
1528
1601
  function runStatusFromPayload(payload) {
1529
1602
  const run = payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
1530
1603
  return String(run.status ?? "unknown").toLowerCase();
@@ -1602,7 +1675,7 @@ async function attachRunOperatorView(context, input) {
1602
1675
  }
1603
1676
  const pollMs = Math.max(250, Math.trunc(input.pollMs ?? 2000));
1604
1677
  let timelineCursor = snapshot.timelineCursor;
1605
- while (!detached && !TERMINAL_RUN_STATUSES.has(runStatusFromPayload(snapshot.run))) {
1678
+ while (!detached && !TERMINAL_RUN_STATUSES2.has(runStatusFromPayload(snapshot.run))) {
1606
1679
  await Bun.sleep(pollMs);
1607
1680
  snapshot = await readOperatorSnapshot(context, input.runId, { timelineCursor });
1608
1681
  timelineCursor = snapshot.timelineCursor;
@@ -2072,30 +2145,62 @@ var PRIMARY_GROUPS = [
2072
2145
  }
2073
2146
  ];
2074
2147
  var ADVANCED_GROUPS = [
2075
- { name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
2076
- { name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
2148
+ {
2149
+ name: "setup",
2150
+ summary: "Bootstrap/check local setup.",
2151
+ usage: ["rig setup <bootstrap|check|preflight>"],
2152
+ commands: [
2153
+ { command: "bootstrap", description: "Bootstrap local setup dependencies.", primary: true },
2154
+ { command: "check", description: "Check local setup state (toolchain, deps, config).", primary: true },
2155
+ { command: "preflight", description: "Run preflight checks before a run.", primary: true }
2156
+ ]
2157
+ },
2158
+ {
2159
+ name: "profile",
2160
+ summary: "Runtime profile/model defaults.",
2161
+ usage: ["rig profile <show|set>"],
2162
+ commands: [
2163
+ { command: "show", description: "Show the active execution profile.", primary: true },
2164
+ { command: "set [--model <model>] [--runtime <runtime>] [--plugin <plugin>]", description: "Set model/runtime/plugin profile defaults.", primary: true }
2165
+ ]
2166
+ },
2077
2167
  {
2078
2168
  name: "review",
2079
2169
  summary: "Inspect or change completion review gate policy.",
2080
2170
  usage: ["rig review <show|set>"],
2081
2171
  commands: [
2082
2172
  { command: "show", description: "Show current review gate settings." },
2083
- { command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider." }
2173
+ { command: "set <off|advisory|required> [--provider <provider>]", description: "Change review strictness/provider (e.g. --provider greptile)." }
2084
2174
  ],
2085
2175
  examples: ["rig review show", "rig review set required --provider greptile"],
2086
2176
  next: ["Use `rig inbox approvals` for blocked run handoffs."]
2087
2177
  },
2088
2178
  {
2089
2179
  name: "browser",
2090
- summary: "Browser/app diagnostics for browser-required tasks.",
2091
- usage: ["rig browser <help|explain|demo|app|hp-next> [options]"],
2180
+ summary: "Browser workstation actions for browser-required tasks: launch, check, CDP probe, profile reset, and app-specific smokes.",
2181
+ usage: ["rig browser <help|explain|demo|hp-next|cdp-probe|profile-persistence|profile-lock-check|smoke-test> [options]"],
2092
2182
  commands: [
2093
- { command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
2094
- { command: "explain", description: "Explain the browser-required task contract." },
2095
- { command: "demo", description: "Run browser demo flows against a local page." },
2096
- { command: "app", description: "Launch the Rig Browser workstation app." },
2097
- { command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
2098
- ]
2183
+ { command: "help", description: "Rich browser command help (canonical: `rig browser help`).", primary: true },
2184
+ { command: "explain", description: "Explain the browser-required task contract and runtime helper commands.", primary: true },
2185
+ { command: "demo [--port <n>] [--profile <name>] [--state-dir <path>] [--target-url <url>] [--keep-open] [--no-build]", description: "Run a guided real browser/agent demo flow.", primary: true },
2186
+ { command: "hp-next dev", description: "Start hp-next Rig Browser in dev/watch mode.", primary: true },
2187
+ { command: "hp-next start", description: "Build/start the hp-next browser workstation without watch mode.", primary: true },
2188
+ { command: "hp-next check", description: "Validate the hp-next CDP endpoint on the configured port.", primary: true },
2189
+ { command: "hp-next e2e", description: "Run hp-next browser e2e smoke checks through Rig Browser.", primary: true },
2190
+ { command: "hp-next reset", description: "Reset the hp-next browser profile when stale browser state is suspected.", primary: true },
2191
+ { command: "cdp-probe", description: "Run an isolated CDP attach/evaluate/layout probe." },
2192
+ { command: "profile-persistence", description: "Verify a named browser profile persists browser state." },
2193
+ { command: "profile-lock-check", description: "Verify concurrent launches reject the same profile." },
2194
+ { command: "smoke-test", description: "Run the browser package smoke test." }
2195
+ ],
2196
+ examples: [
2197
+ "rig browser help",
2198
+ "rig browser hp-next check",
2199
+ "rig browser hp-next e2e",
2200
+ "rig browser cdp-probe",
2201
+ "rig browser profile-lock-check"
2202
+ ],
2203
+ next: ["Inside a task run, use rig-browser-launch, rig-browser-check, and rig-browser-attach-info from the worker PATH."]
2099
2204
  },
2100
2205
  {
2101
2206
  name: "pi",
@@ -2110,12 +2215,60 @@ var ADVANCED_GROUPS = [
2110
2215
  examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
2111
2216
  next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
2112
2217
  },
2113
- { name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
2114
- { name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
2218
+ {
2219
+ name: "queue",
2220
+ summary: "Run task queues locally.",
2221
+ usage: ["rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]"],
2222
+ commands: [
2223
+ { command: "run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]", description: "Process queue work: drain matching tasks with N workers, optional per-task action and isolation.", primary: true }
2224
+ ]
2225
+ },
2226
+ {
2227
+ name: "agent",
2228
+ summary: "Runtime agent workspace helpers.",
2229
+ usage: ["rig agent <list|prepare|run|cleanup>"],
2230
+ commands: [
2231
+ { command: "list", description: "List prepared agent runtimes.", primary: true },
2232
+ { command: "prepare [--id <id>] [--mode <mode>] [--task <task>]", description: "Prepare an isolated agent runtime workspace.", primary: true },
2233
+ { command: "run [--id <id>] [--mode <mode>] [--task <task>] [--skip-project-sync]", description: "Prepare (if needed) and run an agent in its workspace.", primary: true },
2234
+ { command: "cleanup [--all] [--id <id>]", description: "Remove prepared agent workspaces.", primary: true }
2235
+ ]
2236
+ },
2115
2237
  { name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
2116
- { name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
2238
+ {
2239
+ name: "dist",
2240
+ summary: "Build/install packaged Rig CLI.",
2241
+ usage: ["rig dist <build|install|doctor|rebuild-agent>"],
2242
+ commands: [
2243
+ { command: "build [--output-dir <dir>]", description: "Build the distributable Rig CLI.", primary: true },
2244
+ { command: "install [--scope <scope>] [--path <path>]", description: "Install the built CLI to a scope/path.", primary: true },
2245
+ { command: "doctor", description: "Diagnose the dist toolchain and install state.", primary: true },
2246
+ { command: "rebuild-agent", description: "Rebuild the agent runtime image, pruning stale images.", primary: true }
2247
+ ]
2248
+ },
2117
2249
  { name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
2118
- { name: "remote", summary: "Compatibility remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
2250
+ {
2251
+ name: "remote",
2252
+ summary: "Compatibility remote orchestration controls.",
2253
+ usage: ["rig remote <status|tasks|watch|pause|resume|continue|stop|refresh|add-iterations|remove-iterations|endpoint ...>"],
2254
+ commands: [
2255
+ { command: "status [--remote <alias>]", description: "Show the remote orchestration state.", primary: true },
2256
+ { command: "tasks [--remote <alias>]", description: "List the remote's tracked tasks.", primary: true },
2257
+ { command: "watch [--remote <alias>] [--seconds <n>] [--event <type>]", description: "Stream remote orchestration events.", primary: true },
2258
+ { command: "pause [--remote <alias>]", description: "Pause the running remote orchestration.", primary: true },
2259
+ { command: "resume [--remote <alias>] [--max-workers <n>] [--max-iterations <n>] [--direct-merge]", description: "Resume the remote with optional tuning.", primary: true },
2260
+ { command: "continue [--remote <alias>]", description: "Continue a paused remote orchestration.", primary: true },
2261
+ { command: "stop [--remote <alias>]", description: "Stop the remote orchestration.", primary: true },
2262
+ { command: "refresh [--remote <alias>]", description: "Refresh remote state.", primary: true },
2263
+ { command: "add-iterations [--count <n>] [--remote <alias>]", description: "Grant the remote more iterations.", primary: true },
2264
+ { command: "remove-iterations [--count <n>] [--remote <alias>]", description: "Reduce the remote's iteration budget.", primary: true },
2265
+ { command: "endpoint list", description: "List configured remote endpoints.", primary: true },
2266
+ { command: "endpoint add --alias <alias> --host <host> --port <n> [--token <token>]", description: "Register a remote endpoint.", primary: true },
2267
+ { command: "endpoint remove --alias <alias>", description: "Remove a remote endpoint.", primary: true },
2268
+ { command: "endpoint test [--alias <alias>]", description: "Test connectivity to a remote endpoint.", primary: true },
2269
+ { command: "endpoint doctor", description: "Diagnose remote endpoint configuration.", primary: true }
2270
+ ]
2271
+ },
2119
2272
  { name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
2120
2273
  { name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
2121
2274
  { name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }