@h-rig/cli 0.0.6-alpha.89 → 0.0.6-alpha.90

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 (231) hide show
  1. package/dist/bin/build-rig-binaries.js +8 -40
  2. package/dist/bin/rig.js +12519 -26675
  3. package/dist/src/app/board.js +74 -693
  4. package/dist/src/app/drone-ui.js +1 -1
  5. package/dist/src/app/theme.js +0 -1
  6. package/dist/src/commands/_async-ui.js +1 -1
  7. package/dist/src/commands/_authority-runs.d.ts +1 -1
  8. package/dist/src/commands/_authority-runs.js +12 -2
  9. package/dist/src/commands/_cli-format.d.ts +1 -10
  10. package/dist/src/commands/_cli-format.js +2 -5
  11. package/dist/src/commands/_connection-state.d.ts +1 -11
  12. package/dist/src/commands/_connection-state.js +5 -50
  13. package/dist/src/commands/_doctor-checks.js +40 -501
  14. package/dist/src/commands/_help-catalog.js +17 -99
  15. package/dist/src/commands/_json-output.js +0 -4
  16. package/dist/src/commands/_operator-view.js +54 -575
  17. package/dist/src/commands/_pi-frontend.d.ts +0 -27
  18. package/dist/src/commands/_pi-frontend.js +52 -576
  19. package/dist/src/commands/_preflight.js +66 -553
  20. package/dist/src/commands/_server-client.d.ts +0 -33
  21. package/dist/src/commands/_server-client.js +46 -541
  22. package/dist/src/commands/_snapshot-upload.js +42 -503
  23. package/dist/src/commands/_spinner.js +1 -1
  24. package/dist/src/commands/agent.js +12 -2
  25. package/dist/src/commands/browser.js +1 -1
  26. package/dist/src/commands/connect.js +15 -626
  27. package/dist/src/commands/doctor.js +41 -502
  28. package/dist/src/commands/github.js +51 -584
  29. package/dist/src/commands/inbox.js +41 -502
  30. package/dist/src/commands/init.js +74 -561
  31. package/dist/src/commands/inspect.js +41 -502
  32. package/dist/src/commands/run.js +54 -578
  33. package/dist/src/commands/server.js +163 -692
  34. package/dist/src/commands/setup.js +46 -507
  35. package/dist/src/commands/stats.js +58 -601
  36. package/dist/src/commands/task-run-driver.js +58 -509
  37. package/dist/src/commands/task.js +110 -729
  38. package/dist/src/commands.js +237 -1112
  39. package/dist/src/index.js +244 -1123
  40. package/dist/src/launcher.js +0 -4
  41. package/package.json +9 -13
  42. package/dist/src/app-opentui/adapters/command.d.ts +0 -2
  43. package/dist/src/app-opentui/adapters/command.js +0 -329
  44. package/dist/src/app-opentui/adapters/common.d.ts +0 -56
  45. package/dist/src/app-opentui/adapters/common.js +0 -153
  46. package/dist/src/app-opentui/adapters/doctor.d.ts +0 -9
  47. package/dist/src/app-opentui/adapters/doctor.js +0 -1217
  48. package/dist/src/app-opentui/adapters/family.d.ts +0 -62
  49. package/dist/src/app-opentui/adapters/family.js +0 -14855
  50. package/dist/src/app-opentui/adapters/fleet.d.ts +0 -14
  51. package/dist/src/app-opentui/adapters/fleet.js +0 -1335
  52. package/dist/src/app-opentui/adapters/inbox.d.ts +0 -43
  53. package/dist/src/app-opentui/adapters/inbox.js +0 -1944
  54. package/dist/src/app-opentui/adapters/init.d.ts +0 -11
  55. package/dist/src/app-opentui/adapters/init.js +0 -2818
  56. package/dist/src/app-opentui/adapters/inspect.d.ts +0 -52
  57. package/dist/src/app-opentui/adapters/inspect.js +0 -1455
  58. package/dist/src/app-opentui/adapters/pi-attach.d.ts +0 -32
  59. package/dist/src/app-opentui/adapters/pi-attach.js +0 -2101
  60. package/dist/src/app-opentui/adapters/pi.d.ts +0 -23
  61. package/dist/src/app-opentui/adapters/pi.js +0 -363
  62. package/dist/src/app-opentui/adapters/plugin.d.ts +0 -84
  63. package/dist/src/app-opentui/adapters/plugin.js +0 -544
  64. package/dist/src/app-opentui/adapters/repo.d.ts +0 -37
  65. package/dist/src/app-opentui/adapters/repo.js +0 -186
  66. package/dist/src/app-opentui/adapters/run-detail.d.ts +0 -27
  67. package/dist/src/app-opentui/adapters/run-detail.js +0 -1441
  68. package/dist/src/app-opentui/adapters/server.d.ts +0 -48
  69. package/dist/src/app-opentui/adapters/server.js +0 -1561
  70. package/dist/src/app-opentui/adapters/tasks.d.ts +0 -64
  71. package/dist/src/app-opentui/adapters/tasks.js +0 -4524
  72. package/dist/src/app-opentui/adapters/workspace.d.ts +0 -49
  73. package/dist/src/app-opentui/adapters/workspace.js +0 -333
  74. package/dist/src/app-opentui/autocomplete.d.ts +0 -20
  75. package/dist/src/app-opentui/autocomplete.js +0 -578
  76. package/dist/src/app-opentui/bootstrap.d.ts +0 -11
  77. package/dist/src/app-opentui/bootstrap.js +0 -27833
  78. package/dist/src/app-opentui/command-palette.d.ts +0 -3
  79. package/dist/src/app-opentui/command-palette.js +0 -1038
  80. package/dist/src/app-opentui/command-pty-host.d.ts +0 -62
  81. package/dist/src/app-opentui/command-pty-host.js +0 -248
  82. package/dist/src/app-opentui/drone.d.ts +0 -12
  83. package/dist/src/app-opentui/drone.js +0 -230
  84. package/dist/src/app-opentui/events.d.ts +0 -7
  85. package/dist/src/app-opentui/events.js +0 -28
  86. package/dist/src/app-opentui/fleet-stats.d.ts +0 -32
  87. package/dist/src/app-opentui/fleet-stats.js +0 -114
  88. package/dist/src/app-opentui/focus-manager.d.ts +0 -14
  89. package/dist/src/app-opentui/focus-manager.js +0 -24
  90. package/dist/src/app-opentui/index.d.ts +0 -8
  91. package/dist/src/app-opentui/index.js +0 -5260
  92. package/dist/src/app-opentui/intent.d.ts +0 -3
  93. package/dist/src/app-opentui/intent.js +0 -365
  94. package/dist/src/app-opentui/keymap.d.ts +0 -21
  95. package/dist/src/app-opentui/keymap.js +0 -1377
  96. package/dist/src/app-opentui/launch-routing.d.ts +0 -16
  97. package/dist/src/app-opentui/launch-routing.js +0 -55
  98. package/dist/src/app-opentui/layout.d.ts +0 -22
  99. package/dist/src/app-opentui/layout.js +0 -51
  100. package/dist/src/app-opentui/list-search.d.ts +0 -36
  101. package/dist/src/app-opentui/list-search.js +0 -130
  102. package/dist/src/app-opentui/pi-host-child.d.ts +0 -2
  103. package/dist/src/app-opentui/pi-host-child.js +0 -1299
  104. package/dist/src/app-opentui/pi-pty-host.d.ts +0 -28
  105. package/dist/src/app-opentui/pi-pty-host.js +0 -10
  106. package/dist/src/app-opentui/react/App.d.ts +0 -9
  107. package/dist/src/app-opentui/react/App.js +0 -3866
  108. package/dist/src/app-opentui/react/Backdrop.d.ts +0 -5
  109. package/dist/src/app-opentui/react/Backdrop.js +0 -823
  110. package/dist/src/app-opentui/react/ChromeHost.d.ts +0 -5
  111. package/dist/src/app-opentui/react/ChromeHost.js +0 -1539
  112. package/dist/src/app-opentui/react/SceneFrameView.d.ts +0 -7
  113. package/dist/src/app-opentui/react/SceneFrameView.js +0 -579
  114. package/dist/src/app-opentui/react/context.d.ts +0 -17
  115. package/dist/src/app-opentui/react/context.js +0 -37
  116. package/dist/src/app-opentui/react/launch.d.ts +0 -2
  117. package/dist/src/app-opentui/react/launch.js +0 -4897
  118. package/dist/src/app-opentui/react/nav.d.ts +0 -18
  119. package/dist/src/app-opentui/react/nav.js +0 -54
  120. package/dist/src/app-opentui/react/scroll.d.ts +0 -12
  121. package/dist/src/app-opentui/react/scroll.js +0 -21
  122. package/dist/src/app-opentui/react/syntax.d.ts +0 -2
  123. package/dist/src/app-opentui/react/syntax.js +0 -65
  124. package/dist/src/app-opentui/registry.d.ts +0 -4
  125. package/dist/src/app-opentui/registry.js +0 -22876
  126. package/dist/src/app-opentui/remote-link.d.ts +0 -10
  127. package/dist/src/app-opentui/remote-link.js +0 -47
  128. package/dist/src/app-opentui/render/ascii-fleet.d.ts +0 -15
  129. package/dist/src/app-opentui/render/ascii-fleet.js +0 -82
  130. package/dist/src/app-opentui/render/constants.d.ts +0 -30
  131. package/dist/src/app-opentui/render/constants.js +0 -64
  132. package/dist/src/app-opentui/render/graphics.d.ts +0 -40
  133. package/dist/src/app-opentui/render/graphics.js +0 -713
  134. package/dist/src/app-opentui/render/hover.d.ts +0 -11
  135. package/dist/src/app-opentui/render/hover.js +0 -34
  136. package/dist/src/app-opentui/render/native-host.d.ts +0 -37
  137. package/dist/src/app-opentui/render/native-host.js +0 -180
  138. package/dist/src/app-opentui/render/panel-layout.d.ts +0 -38
  139. package/dist/src/app-opentui/render/panel-layout.js +0 -48
  140. package/dist/src/app-opentui/render/panels.d.ts +0 -12
  141. package/dist/src/app-opentui/render/panels.js +0 -288
  142. package/dist/src/app-opentui/render/preloader.d.ts +0 -10
  143. package/dist/src/app-opentui/render/preloader.js +0 -166
  144. package/dist/src/app-opentui/render/scene.d.ts +0 -68
  145. package/dist/src/app-opentui/render/scene.js +0 -300
  146. package/dist/src/app-opentui/render/terminal-handoff.d.ts +0 -16
  147. package/dist/src/app-opentui/render/terminal-handoff.js +0 -14
  148. package/dist/src/app-opentui/render/text.d.ts +0 -29
  149. package/dist/src/app-opentui/render/text.js +0 -177
  150. package/dist/src/app-opentui/render/type-bar.d.ts +0 -15
  151. package/dist/src/app-opentui/render/type-bar.js +0 -212
  152. package/dist/src/app-opentui/runtime-resources.d.ts +0 -16
  153. package/dist/src/app-opentui/runtime-resources.js +0 -62
  154. package/dist/src/app-opentui/runtime.d.ts +0 -45
  155. package/dist/src/app-opentui/runtime.js +0 -5232
  156. package/dist/src/app-opentui/scenes/command.d.ts +0 -3
  157. package/dist/src/app-opentui/scenes/command.js +0 -118
  158. package/dist/src/app-opentui/scenes/doctor.d.ts +0 -3
  159. package/dist/src/app-opentui/scenes/doctor.js +0 -296
  160. package/dist/src/app-opentui/scenes/error.d.ts +0 -2
  161. package/dist/src/app-opentui/scenes/error.js +0 -277
  162. package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +0 -2
  163. package/dist/src/app-opentui/scenes/family-domains/agent.js +0 -349
  164. package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +0 -2
  165. package/dist/src/app-opentui/scenes/family-domains/browser.js +0 -196
  166. package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +0 -2
  167. package/dist/src/app-opentui/scenes/family-domains/dist.js +0 -244
  168. package/dist/src/app-opentui/scenes/family-domains/git.d.ts +0 -2
  169. package/dist/src/app-opentui/scenes/family-domains/git.js +0 -196
  170. package/dist/src/app-opentui/scenes/family-domains/github.d.ts +0 -2
  171. package/dist/src/app-opentui/scenes/family-domains/github.js +0 -275
  172. package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +0 -2
  173. package/dist/src/app-opentui/scenes/family-domains/harness.js +0 -153
  174. package/dist/src/app-opentui/scenes/family-domains/index.d.ts +0 -4
  175. package/dist/src/app-opentui/scenes/family-domains/index.js +0 -1680
  176. package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +0 -76
  177. package/dist/src/app-opentui/scenes/family-domains/kit.js +0 -306
  178. package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +0 -2
  179. package/dist/src/app-opentui/scenes/family-domains/profile.js +0 -213
  180. package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +0 -2
  181. package/dist/src/app-opentui/scenes/family-domains/queue.js +0 -147
  182. package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +0 -2
  183. package/dist/src/app-opentui/scenes/family-domains/remote.js +0 -519
  184. package/dist/src/app-opentui/scenes/family-domains/review.d.ts +0 -2
  185. package/dist/src/app-opentui/scenes/family-domains/review.js +0 -281
  186. package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +0 -2
  187. package/dist/src/app-opentui/scenes/family-domains/setup.js +0 -268
  188. package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +0 -2
  189. package/dist/src/app-opentui/scenes/family-domains/stats.js +0 -371
  190. package/dist/src/app-opentui/scenes/family.d.ts +0 -3
  191. package/dist/src/app-opentui/scenes/family.js +0 -2199
  192. package/dist/src/app-opentui/scenes/fleet.d.ts +0 -3
  193. package/dist/src/app-opentui/scenes/fleet.js +0 -766
  194. package/dist/src/app-opentui/scenes/handoff.d.ts +0 -2
  195. package/dist/src/app-opentui/scenes/handoff.js +0 -455
  196. package/dist/src/app-opentui/scenes/help.d.ts +0 -3
  197. package/dist/src/app-opentui/scenes/help.js +0 -725
  198. package/dist/src/app-opentui/scenes/inbox.d.ts +0 -3
  199. package/dist/src/app-opentui/scenes/inbox.js +0 -427
  200. package/dist/src/app-opentui/scenes/init.d.ts +0 -3
  201. package/dist/src/app-opentui/scenes/init.js +0 -181
  202. package/dist/src/app-opentui/scenes/inspect.d.ts +0 -3
  203. package/dist/src/app-opentui/scenes/inspect.js +0 -794
  204. package/dist/src/app-opentui/scenes/main.d.ts +0 -3
  205. package/dist/src/app-opentui/scenes/main.js +0 -332
  206. package/dist/src/app-opentui/scenes/pi.d.ts +0 -3
  207. package/dist/src/app-opentui/scenes/pi.js +0 -509
  208. package/dist/src/app-opentui/scenes/plugin.d.ts +0 -3
  209. package/dist/src/app-opentui/scenes/plugin.js +0 -487
  210. package/dist/src/app-opentui/scenes/repo.d.ts +0 -3
  211. package/dist/src/app-opentui/scenes/repo.js +0 -425
  212. package/dist/src/app-opentui/scenes/run-detail.d.ts +0 -3
  213. package/dist/src/app-opentui/scenes/run-detail.js +0 -467
  214. package/dist/src/app-opentui/scenes/server.d.ts +0 -3
  215. package/dist/src/app-opentui/scenes/server.js +0 -378
  216. package/dist/src/app-opentui/scenes/tasks.d.ts +0 -3
  217. package/dist/src/app-opentui/scenes/tasks.js +0 -768
  218. package/dist/src/app-opentui/scenes/workspace.d.ts +0 -3
  219. package/dist/src/app-opentui/scenes/workspace.js +0 -427
  220. package/dist/src/app-opentui/selectable.d.ts +0 -19
  221. package/dist/src/app-opentui/selectable.js +0 -80
  222. package/dist/src/app-opentui/state.d.ts +0 -4
  223. package/dist/src/app-opentui/state.js +0 -399
  224. package/dist/src/app-opentui/surface-catalog.d.ts +0 -20
  225. package/dist/src/app-opentui/surface-catalog.js +0 -542
  226. package/dist/src/app-opentui/theme.d.ts +0 -59
  227. package/dist/src/app-opentui/theme.js +0 -142
  228. package/dist/src/app-opentui/types.d.ts +0 -313
  229. package/dist/src/app-opentui/types.js +0 -1
  230. package/dist/src/commands/_server-events.d.ts +0 -26
  231. package/dist/src/commands/_server-events.js +0 -715
@@ -107,7 +107,6 @@ function statusColor(status) {
107
107
  case "validating":
108
108
  case "reviewing":
109
109
  case "closing-out":
110
- case "stopping":
111
110
  return cyan;
112
111
  case "needs-attention":
113
112
  case "needs_attention":
@@ -244,7 +243,7 @@ function createTtySpinner(input) {
244
243
  output.write("\r\x1B[2K");
245
244
  };
246
245
  render();
247
- const timer = isTty ? setInterval(render, input.intervalMs ?? 16) : null;
246
+ const timer = isTty ? setInterval(render, input.intervalMs ?? 120) : null;
248
247
  return {
249
248
  setLabel(next) {
250
249
  label = next;
@@ -864,28 +863,12 @@ function readRepoConnection(projectRoot) {
864
863
  selected,
865
864
  project: typeof record.project === "string" ? record.project : undefined,
866
865
  linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
867
- serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined,
868
- serverProjectRootAlias: typeof record.serverProjectRootAlias === "string" && record.serverProjectRootAlias.trim() ? record.serverProjectRootAlias.trim() : undefined,
869
- serverProjectRootBaseUrl: typeof record.serverProjectRootBaseUrl === "string" && record.serverProjectRootBaseUrl.trim() ? record.serverProjectRootBaseUrl.trim().replace(/\/+$/, "") : undefined
866
+ serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
870
867
  };
871
868
  }
872
869
  function writeRepoConnection(projectRoot, state) {
873
870
  writeJsonFile2(resolveRepoConnectionPath(projectRoot), state);
874
871
  }
875
- function rootAllowedForSelection(repo, connection) {
876
- const root = repo.serverProjectRoot?.trim();
877
- if (!root)
878
- return;
879
- if (connection.kind === "remote") {
880
- if (repo.serverProjectRootAlias !== repo.selected)
881
- return;
882
- if (repo.serverProjectRootBaseUrl !== connection.baseUrl)
883
- return;
884
- } else if (repo.serverProjectRootAlias && repo.serverProjectRootAlias !== repo.selected) {
885
- return;
886
- }
887
- return root;
888
- }
889
872
  function resolveSelectedConnection(projectRoot, options = {}) {
890
873
  const repo = readRepoConnection(projectRoot);
891
874
  if (!repo)
@@ -897,41 +880,13 @@ function resolveSelectedConnection(projectRoot, options = {}) {
897
880
  if (!connection) {
898
881
  throw new CliError(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
899
882
  }
900
- return { alias: repo.selected, connection, serverProjectRoot: rootAllowedForSelection(repo, connection) };
883
+ return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
901
884
  }
902
- function writeRepoServerProjectRoot(projectRoot, serverProjectRoot, metadata = {}) {
885
+ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
903
886
  const repo = readRepoConnection(projectRoot);
904
887
  if (!repo)
905
888
  return;
906
- let inferred = metadata;
907
- if (!inferred.alias || !inferred.baseUrl) {
908
- try {
909
- const selected = resolveSelectedConnection(projectRoot);
910
- if (selected?.connection.kind === "remote") {
911
- inferred = {
912
- alias: inferred.alias ?? selected.alias,
913
- baseUrl: inferred.baseUrl ?? selected.connection.baseUrl
914
- };
915
- }
916
- } catch {}
917
- }
918
- writeRepoConnection(projectRoot, {
919
- ...repo,
920
- ...metadata.project ? { project: metadata.project } : {},
921
- serverProjectRoot,
922
- ...inferred.alias ? { serverProjectRootAlias: inferred.alias } : {},
923
- ...inferred.baseUrl ? { serverProjectRootBaseUrl: inferred.baseUrl.replace(/\/+$/, "") } : {}
924
- });
925
- }
926
- function clearRepoServerProjectRoot(projectRoot) {
927
- const repo = readRepoConnection(projectRoot);
928
- if (!repo)
929
- return;
930
- writeRepoConnection(projectRoot, {
931
- selected: repo.selected,
932
- ...repo.project ? { project: repo.project } : {},
933
- ...repo.linkedAt ? { linkedAt: repo.linkedAt } : {}
934
- });
889
+ writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
935
890
  }
936
891
  function isRemoteConnectionSelected(projectRoot) {
937
892
  return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
@@ -941,8 +896,8 @@ var init__connection_state = __esm(() => {
941
896
  });
942
897
 
943
898
  // packages/cli/src/commands/_server-client.ts
944
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync4, writeFileSync as writeFileSync5 } from "fs";
945
- import { dirname as dirname3, isAbsolute, resolve as resolve10 } from "path";
899
+ import { existsSync as existsSync6, readFileSync as readFileSync4 } from "fs";
900
+ import { resolve as resolve10 } from "path";
946
901
  import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
947
902
  function setServerPhaseListener(listener) {
948
903
  const previous = serverPhaseListener;
@@ -960,21 +915,17 @@ function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
960
915
  const scopedKey = resolve10(projectRoot ?? process.cwd());
961
916
  scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
962
917
  }
963
- function readRemoteAuthState(projectRoot) {
918
+ function readPrivateRemoteSessionToken(projectRoot) {
964
919
  const path = resolve10(projectRoot, ".rig", "state", "github-auth.json");
965
920
  if (!existsSync6(path))
966
921
  return null;
967
922
  try {
968
923
  const parsed = JSON.parse(readFileSync4(path, "utf8"));
969
- return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
924
+ return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
970
925
  } catch {
971
926
  return null;
972
927
  }
973
928
  }
974
- function readPrivateRemoteSessionToken(projectRoot) {
975
- const parsed = readRemoteAuthState(projectRoot);
976
- return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
977
- }
978
929
  function readGitHubBearerTokenForRemote(projectRoot) {
979
930
  const scopedKey = resolve10(projectRoot);
980
931
  if (scopedGitHubBearerTokens.has(scopedKey))
@@ -985,421 +936,18 @@ function readGitHubBearerTokenForRemote(projectRoot) {
985
936
  return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
986
937
  }
987
938
  function readStoredGitHubAuthToken(projectRoot) {
988
- const parsed = readRemoteAuthState(projectRoot);
989
- return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
990
- }
991
- function inferRemoteServerProjectRootCandidateFromAuthState(projectRoot, repoSlug) {
992
- if (!/^[^/]+\/[^/]+$/.test(repoSlug))
993
- return null;
994
- const repo = readRepoConnection(projectRoot);
995
- const auth = readRemoteAuthState(projectRoot);
996
- const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
997
- const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
998
- if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
999
- return null;
1000
- const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
1001
- if (!checkoutBaseDir)
1002
- return null;
1003
- return `${checkoutBaseDir.replace(/\/+$/, "")}/${repoSlug}`;
1004
- }
1005
- function readLocalConnectionFallbackToken(projectRoot) {
1006
- return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
1007
- }
1008
- function normalizeRepoSlug(value) {
1009
- const slug = value?.trim();
1010
- return slug && /^[^/\s]+\/[^/\s]+$/.test(slug) ? slug : null;
1011
- }
1012
- function readProjectLinkSlug(projectRoot) {
1013
- const path = resolve10(projectRoot, ".rig", "state", "project-link.json");
939
+ const path = resolve10(projectRoot, ".rig", "state", "github-auth.json");
1014
940
  if (!existsSync6(path))
1015
941
  return null;
1016
942
  try {
1017
943
  const parsed = JSON.parse(readFileSync4(path, "utf8"));
1018
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
1019
- return null;
1020
- return normalizeRepoSlug(typeof parsed.repoSlug === "string" ? String(parsed.repoSlug) : null);
944
+ return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
1021
945
  } catch {
1022
946
  return null;
1023
947
  }
1024
948
  }
1025
- function writeProjectLinkConnection(projectRoot, repoSlug, alias) {
1026
- const path = resolve10(projectRoot, ".rig", "state", "project-link.json");
1027
- mkdirSync6(dirname3(path), { recursive: true });
1028
- writeFileSync5(path, `${JSON.stringify({ repoSlug, connection: alias, linkedAt: new Date().toISOString() }, null, 2)}
1029
- `, "utf8");
1030
- }
1031
- function remoteLinkRepairCommand(repoSlug) {
1032
- return repoSlug ? `rig server repair-link --repo ${repoSlug}` : "rig server repair-link --repo owner/repo";
1033
- }
1034
- function formatRemoteProjectLinkHint(resolution) {
1035
- const repair = remoteLinkRepairCommand(resolution.repoSlug);
1036
- if (resolution.status === "auth_required") {
1037
- return `Authenticate the selected remote${resolution.alias ? ` (${resolution.alias})` : ""}, then run \`${repair}\`. Use \`rig github auth import-gh\` or \`rig init --repair --server remote --github-auth device${resolution.repoSlug ? ` --repo ${resolution.repoSlug}` : ""}\`.`;
1038
- }
1039
- if (resolution.status === "missing_project") {
1040
- return `Record the repo slug, then run \`${repair}\` (or \`rig init --repo owner/repo --server remote --github-auth device\`).`;
1041
- }
1042
- if (resolution.status === "not_remote")
1043
- return "Select a remote server with `rig server use <alias>` before repairing a remote project link.";
1044
- return `Run \`${repair}\` to backfill or prepare a server-host checkout for the selected remote${resolution.alias ? ` (${resolution.alias})` : ""}.`;
1045
- }
1046
- function remoteProjectLinkFailure(input) {
1047
- const partial = {
1048
- status: input.status,
1049
- alias: input.alias,
1050
- baseUrl: input.baseUrl,
1051
- repoSlug: input.repoSlug
1052
- };
1053
- return {
1054
- ok: false,
1055
- ...input,
1056
- hint: formatRemoteProjectLinkHint(partial),
1057
- next: remoteLinkRepairCommand(input.repoSlug)
1058
- };
1059
- }
1060
- function remoteProjectLinkSuccess(input) {
1061
- return {
1062
- ok: true,
1063
- status: input.status,
1064
- alias: input.alias,
1065
- baseUrl: input.baseUrl,
1066
- repoSlug: input.repoSlug,
1067
- serverProjectRoot: input.serverProjectRoot,
1068
- source: input.source,
1069
- prepared: input.prepared ?? input.status === "prepared",
1070
- validated: input.validated ?? false,
1071
- message: input.message ?? `Remote project link ready for ${input.repoSlug}.`,
1072
- hint: "Remote-scoped task/run/status requests will send x-rig-project-root for this server-host checkout.",
1073
- next: "rig task list"
1074
- };
1075
- }
1076
- function localCheckoutPathCandidate(projectRoot, candidate) {
1077
- try {
1078
- const local = resolve10(projectRoot);
1079
- const resolved = resolve10(candidate);
1080
- return resolved === local || resolved.startsWith(`${local}/`);
1081
- } catch {
1082
- return false;
1083
- }
1084
- }
1085
- async function requestRemoteProjectLinkJson(baseUrl, pathname, authToken, init = {}) {
1086
- const requestUrl = new URL(`${baseUrl}${pathname}`);
1087
- if (authToken && queryAuthFallbackEnabled())
1088
- requestUrl.searchParams.set("rt", authToken);
1089
- const response = await fetch(requestUrl, {
1090
- ...init,
1091
- headers: mergeHeaders(init.headers, authToken)
1092
- });
1093
- const text = await response.text();
1094
- const payload = text.trim().length > 0 ? (() => {
1095
- try {
1096
- return JSON.parse(text);
1097
- } catch {
1098
- return null;
1099
- }
1100
- })() : null;
1101
- return { ok: response.ok, status: response.status, payload, text };
1102
- }
1103
- function payloadError(payload, fallback) {
1104
- if (payload && typeof payload === "object" && !Array.isArray(payload)) {
1105
- const record = payload;
1106
- const value = record.error ?? record.message ?? record.reason;
1107
- if (typeof value === "string" && value.trim())
1108
- return value.trim();
1109
- }
1110
- return fallback;
1111
- }
1112
- function checkoutPathsFromProjectPayload(payload) {
1113
- if (!payload || typeof payload !== "object" || Array.isArray(payload))
1114
- return [];
1115
- const project = payload.project;
1116
- if (!project || typeof project !== "object" || Array.isArray(project))
1117
- return [];
1118
- const checkouts = project.checkouts;
1119
- if (!Array.isArray(checkouts))
1120
- return [];
1121
- return [...checkouts].reverse().flatMap((entry) => {
1122
- if (!entry || typeof entry !== "object" || Array.isArray(entry))
1123
- return [];
1124
- const path = entry.path;
1125
- return typeof path === "string" && path.trim() ? [path.trim()] : [];
1126
- });
1127
- }
1128
- function checkoutPathFromPreparePayload(payload) {
1129
- if (!payload || typeof payload !== "object" || Array.isArray(payload))
1130
- return null;
1131
- const checkout = payload.checkout;
1132
- if (!checkout || typeof checkout !== "object" || Array.isArray(checkout))
1133
- return null;
1134
- const path = checkout.path;
1135
- return typeof path === "string" && path.trim() ? path.trim() : null;
1136
- }
1137
- async function validateAndPersistRemoteRoot(input) {
1138
- const candidate = input.candidate.trim();
1139
- if (!candidate || !isAbsolute(candidate)) {
1140
- return remoteProjectLinkFailure({
1141
- status: "invalid_root",
1142
- alias: input.alias,
1143
- baseUrl: input.baseUrl,
1144
- repoSlug: input.repoSlug,
1145
- message: `Remote project root candidate is not an absolute server-host path: ${candidate || "(empty)"}.`
1146
- });
1147
- }
1148
- if (localCheckoutPathCandidate(input.projectRoot, candidate)) {
1149
- return remoteProjectLinkFailure({
1150
- status: "invalid_root",
1151
- alias: input.alias,
1152
- baseUrl: input.baseUrl,
1153
- repoSlug: input.repoSlug,
1154
- message: `Refusing to use local checkout path ${candidate} as a remote server project root.`
1155
- });
1156
- }
1157
- let response;
1158
- try {
1159
- response = await requestRemoteProjectLinkJson(input.baseUrl, "/api/server/project-root", input.authToken, {
1160
- method: "POST",
1161
- headers: { "content-type": "application/json" },
1162
- body: JSON.stringify({ projectRoot: candidate })
1163
- });
1164
- } catch (error) {
1165
- return remoteProjectLinkFailure({
1166
- status: "error",
1167
- alias: input.alias,
1168
- baseUrl: input.baseUrl,
1169
- repoSlug: input.repoSlug,
1170
- message: `Could not validate remote project root ${candidate}: ${error instanceof Error ? error.message : String(error)}`
1171
- });
1172
- }
1173
- if (response.status === 401 || response.status === 403) {
1174
- return remoteProjectLinkFailure({
1175
- status: "auth_required",
1176
- alias: input.alias,
1177
- baseUrl: input.baseUrl,
1178
- repoSlug: input.repoSlug,
1179
- statusCode: response.status,
1180
- message: `Remote server ${input.alias} requires authentication before validating project root ${candidate}.`
1181
- });
1182
- }
1183
- if (!response.ok) {
1184
- return remoteProjectLinkFailure({
1185
- status: "invalid_root",
1186
- alias: input.alias,
1187
- baseUrl: input.baseUrl,
1188
- repoSlug: input.repoSlug,
1189
- statusCode: response.status,
1190
- message: `Remote server rejected project root ${candidate} (${response.status}): ${payloadError(response.payload, response.text || "project-root validation failed")}`
1191
- });
1192
- }
1193
- const record = response.payload && typeof response.payload === "object" && !Array.isArray(response.payload) ? response.payload : {};
1194
- if (record.ok !== true) {
1195
- return remoteProjectLinkFailure({
1196
- status: "invalid_root",
1197
- alias: input.alias,
1198
- baseUrl: input.baseUrl,
1199
- repoSlug: input.repoSlug,
1200
- message: `Remote server did not accept project root ${candidate}: ${payloadError(response.payload, "project-root validation failed")}`
1201
- });
1202
- }
1203
- const accepted = typeof record.projectRoot === "string" && record.projectRoot.trim() ? record.projectRoot.trim() : typeof record.requestedProjectRoot === "string" && record.requestedProjectRoot.trim() ? record.requestedProjectRoot.trim() : candidate;
1204
- writeRepoServerProjectRoot(input.projectRoot, accepted, { alias: input.alias, baseUrl: input.baseUrl, project: input.repoSlug });
1205
- writeProjectLinkConnection(input.projectRoot, input.repoSlug, input.alias);
1206
- const status = input.status ?? (input.prepared ? "prepared" : "backfilled");
1207
- return remoteProjectLinkSuccess({
1208
- status,
1209
- alias: input.alias,
1210
- baseUrl: input.baseUrl,
1211
- repoSlug: input.repoSlug,
1212
- serverProjectRoot: accepted,
1213
- source: input.source,
1214
- prepared: input.prepared,
1215
- validated: true,
1216
- message: status === "ready" ? `Remote project link already points to ${accepted} and was validated on ${input.alias}.` : input.prepared ? `Prepared and linked remote checkout ${accepted} for ${input.repoSlug}.` : `Backfilled remote checkout ${accepted} for ${input.repoSlug}.`
1217
- });
1218
- }
1219
- async function ensureRemoteProjectRootLink(projectRoot, options = {}) {
1220
- let selected;
1221
- try {
1222
- selected = resolveSelectedConnection(projectRoot);
1223
- } catch (error) {
1224
- return remoteProjectLinkFailure({ status: "error", message: error instanceof Error ? error.message : String(error) });
1225
- }
1226
- if (!selected || selected.connection.kind !== "remote") {
1227
- return remoteProjectLinkFailure({ status: "not_remote", message: "No remote Rig server is selected for this repo." });
1228
- }
1229
- const repo = readRepoConnection(projectRoot);
1230
- const explicitRepoRequested = options.repoSlug !== undefined;
1231
- const explicitRepoSlug = explicitRepoRequested ? normalizeRepoSlug(options.repoSlug) : null;
1232
- const repoProjectSlug = normalizeRepoSlug(repo?.project);
1233
- const repoSlug = explicitRepoSlug ?? repoProjectSlug ?? readProjectLinkSlug(projectRoot);
1234
- const alias = selected.alias;
1235
- const baseUrl = selected.connection.baseUrl;
1236
- const authToken = options.authToken === undefined ? readGitHubBearerTokenForRemote(projectRoot) : options.authToken;
1237
- const mode = options.mode ?? "backfill-only";
1238
- if (explicitRepoRequested && !explicitRepoSlug) {
1239
- return remoteProjectLinkFailure({
1240
- status: "missing_project",
1241
- alias,
1242
- baseUrl,
1243
- message: `Invalid --repo value ${JSON.stringify(options.repoSlug)}. Expected owner/repo.`
1244
- });
1245
- }
1246
- if (!repoSlug) {
1247
- return remoteProjectLinkFailure({
1248
- status: "missing_project",
1249
- alias,
1250
- baseUrl,
1251
- message: `Remote server ${alias} is selected, but this checkout has no GitHub repo slug recorded.`
1252
- });
1253
- }
1254
- const skippedCandidates = [];
1255
- const storedRoot = selected.serverProjectRoot?.trim() || null;
1256
- const storedRootMatchesResolvedRepo = repoProjectSlug === repoSlug;
1257
- if (storedRoot && storedRootMatchesResolvedRepo) {
1258
- if (localCheckoutPathCandidate(projectRoot, storedRoot)) {
1259
- clearRepoServerProjectRoot(projectRoot);
1260
- skippedCandidates.push(storedRoot);
1261
- } else {
1262
- const storedResult = await validateAndPersistRemoteRoot({
1263
- projectRoot,
1264
- alias,
1265
- baseUrl,
1266
- authToken,
1267
- repoSlug,
1268
- candidate: storedRoot,
1269
- source: "stored",
1270
- status: "ready"
1271
- });
1272
- if (storedResult.ok || storedResult.status === "auth_required" || storedResult.status === "error")
1273
- return storedResult;
1274
- clearRepoServerProjectRoot(projectRoot);
1275
- skippedCandidates.push(storedRoot);
1276
- }
1277
- } else if (storedRoot) {
1278
- skippedCandidates.push(storedRoot);
1279
- }
1280
- const authCandidate = inferRemoteServerProjectRootCandidateFromAuthState(projectRoot, repoSlug);
1281
- if (authCandidate) {
1282
- const authResult = await validateAndPersistRemoteRoot({ projectRoot, alias, baseUrl, authToken, repoSlug, candidate: authCandidate, source: "auth-state" });
1283
- if (authResult.ok || authResult.status === "auth_required")
1284
- return authResult;
1285
- }
1286
- let registryResponse;
1287
- try {
1288
- registryResponse = await requestRemoteProjectLinkJson(baseUrl, `/api/projects/${encodeURIComponent(repoSlug)}`, authToken);
1289
- } catch (error) {
1290
- return remoteProjectLinkFailure({
1291
- status: "error",
1292
- alias,
1293
- baseUrl,
1294
- repoSlug,
1295
- message: `Could not read remote project registry for ${repoSlug} on ${alias}: ${error instanceof Error ? error.message : String(error)}`
1296
- });
1297
- }
1298
- if (registryResponse.status === 401 || registryResponse.status === 403) {
1299
- return remoteProjectLinkFailure({
1300
- status: "auth_required",
1301
- alias,
1302
- baseUrl,
1303
- repoSlug,
1304
- statusCode: registryResponse.status,
1305
- message: `Remote server ${alias} requires authentication before reading the ${repoSlug} project registry.`
1306
- });
1307
- }
1308
- if (registryResponse.ok) {
1309
- const candidates = checkoutPathsFromProjectPayload(registryResponse.payload);
1310
- for (const candidate of candidates) {
1311
- const result = await validateAndPersistRemoteRoot({ projectRoot, alias, baseUrl, authToken, repoSlug, candidate, source: "registry" });
1312
- if (result.ok || result.status === "auth_required")
1313
- return result;
1314
- skippedCandidates.push(candidate);
1315
- }
1316
- if (mode === "backfill-only") {
1317
- return remoteProjectLinkFailure({
1318
- status: candidates.length > 0 ? "invalid_root" : "no_server_checkout",
1319
- alias,
1320
- baseUrl,
1321
- repoSlug,
1322
- message: candidates.length > 0 ? `Remote registry has checkout candidates for ${repoSlug}, but none validated for ${alias}.` : `Remote registry has ${repoSlug}, but no server checkout path is linked yet.`,
1323
- skippedCandidates
1324
- });
1325
- }
1326
- } else if (registryResponse.status === 404) {
1327
- if (mode === "backfill-only") {
1328
- return remoteProjectLinkFailure({
1329
- status: "project_not_registered",
1330
- alias,
1331
- baseUrl,
1332
- repoSlug,
1333
- statusCode: registryResponse.status,
1334
- message: `Remote server ${alias} has no registered project record for ${repoSlug}.`
1335
- });
1336
- }
1337
- } else {
1338
- return remoteProjectLinkFailure({
1339
- status: "error",
1340
- alias,
1341
- baseUrl,
1342
- repoSlug,
1343
- statusCode: registryResponse.status,
1344
- message: `Could not backfill ${repoSlug} from remote registry (${registryResponse.status}): ${payloadError(registryResponse.payload, registryResponse.text || "registry lookup failed")}`,
1345
- skippedCandidates
1346
- });
1347
- }
1348
- let prepareResponse;
1349
- try {
1350
- prepareResponse = await requestRemoteProjectLinkJson(baseUrl, `/api/projects/${encodeURIComponent(repoSlug)}/prepare-checkout`, authToken, {
1351
- method: "POST",
1352
- headers: { "content-type": "application/json" },
1353
- body: JSON.stringify({ checkout: { kind: "managed-clone" }, repoUrl: `https://github.com/${repoSlug}.git` })
1354
- });
1355
- } catch (error) {
1356
- return remoteProjectLinkFailure({
1357
- status: "error",
1358
- alias,
1359
- baseUrl,
1360
- repoSlug,
1361
- message: `Could not prepare remote checkout for ${repoSlug} on ${alias}: ${error instanceof Error ? error.message : String(error)}`
1362
- });
1363
- }
1364
- if (prepareResponse.status === 401 || prepareResponse.status === 403) {
1365
- return remoteProjectLinkFailure({
1366
- status: "auth_required",
1367
- alias,
1368
- baseUrl,
1369
- repoSlug,
1370
- statusCode: prepareResponse.status,
1371
- message: `Remote server ${alias} requires authentication before preparing ${repoSlug}.`
1372
- });
1373
- }
1374
- if (!prepareResponse.ok) {
1375
- return remoteProjectLinkFailure({
1376
- status: "error",
1377
- alias,
1378
- baseUrl,
1379
- repoSlug,
1380
- statusCode: prepareResponse.status,
1381
- message: `Remote checkout prepare failed for ${repoSlug} (${prepareResponse.status}): ${payloadError(prepareResponse.payload, prepareResponse.text || "prepare-checkout failed")}`,
1382
- skippedCandidates
1383
- });
1384
- }
1385
- const preparedPath = checkoutPathFromPreparePayload(prepareResponse.payload);
1386
- if (!preparedPath) {
1387
- return remoteProjectLinkFailure({
1388
- status: "invalid_root",
1389
- alias,
1390
- baseUrl,
1391
- repoSlug,
1392
- message: `Remote checkout prepare for ${repoSlug} did not return a checkout.path.`,
1393
- skippedCandidates
1394
- });
1395
- }
1396
- return validateAndPersistRemoteRoot({ projectRoot, alias, baseUrl, authToken, repoSlug, candidate: preparedPath, source: "prepare", prepared: true });
1397
- }
1398
- async function repairRemoteProjectRootLink(context, options = {}) {
1399
- const resolution = await ensureRemoteProjectRootLink(context.projectRoot, { mode: options.mode ?? "prepare-if-missing", repoSlug: options.repoSlug });
1400
- if (!resolution.ok)
1401
- throw new CliError(resolution.message, 1, { hint: resolution.hint });
1402
- return resolution;
949
+ function readLocalConnectionFallbackToken(projectRoot) {
950
+ return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
1403
951
  }
1404
952
  async function ensureServerForCli(projectRoot) {
1405
953
  try {
@@ -1407,12 +955,12 @@ async function ensureServerForCli(projectRoot) {
1407
955
  if (selected?.connection.kind === "remote") {
1408
956
  reportServerPhase(`Connecting to ${selected.alias}\u2026`);
1409
957
  const authToken = readGitHubBearerTokenForRemote(projectRoot);
1410
- const link = await ensureRemoteProjectRootLink(projectRoot, { mode: "backfill-only", authToken });
958
+ const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
1411
959
  return {
1412
960
  baseUrl: selected.connection.baseUrl,
1413
961
  authToken,
1414
962
  connectionKind: "remote",
1415
- serverProjectRoot: link.ok ? link.serverProjectRoot ?? null : null
963
+ serverProjectRoot
1416
964
  };
1417
965
  }
1418
966
  reportServerPhase("Starting local Rig server\u2026");
@@ -1430,6 +978,29 @@ async function ensureServerForCli(projectRoot) {
1430
978
  throw error;
1431
979
  }
1432
980
  }
981
+ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
982
+ const repo = readRepoConnection(projectRoot);
983
+ const slug = repo?.project?.trim();
984
+ if (!slug)
985
+ return null;
986
+ try {
987
+ const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
988
+ headers: mergeHeaders(undefined, authToken)
989
+ });
990
+ if (!response.ok)
991
+ return null;
992
+ const payload = await response.json();
993
+ const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
994
+ const checkouts = Array.isArray(project?.checkouts) ? project.checkouts : [];
995
+ const latestCheckout = [...checkouts].reverse().find((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.path === "string"));
996
+ const path = typeof latestCheckout?.path === "string" && latestCheckout.path.trim() ? latestCheckout.path.trim() : null;
997
+ if (path)
998
+ writeRepoServerProjectRoot(projectRoot, path);
999
+ return path;
1000
+ } catch {
1001
+ return null;
1002
+ }
1003
+ }
1433
1004
  function appendTaskFilterParams(url, filters) {
1434
1005
  if (filters.assignee)
1435
1006
  url.searchParams.set("assignee", filters.assignee);
@@ -1440,23 +1011,10 @@ function appendTaskFilterParams(url, filters) {
1440
1011
  if (filters.limit !== undefined)
1441
1012
  url.searchParams.set("limit", String(filters.limit));
1442
1013
  }
1443
- function mergeCookie(existing, name, value) {
1444
- const encoded = `${name}=${encodeURIComponent(value)}`;
1445
- if (!existing?.trim())
1446
- return encoded;
1447
- const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
1448
- return [...parts, encoded].join("; ");
1449
- }
1450
- function queryAuthFallbackEnabled(env = process.env) {
1451
- return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
1452
- }
1453
1014
  function mergeHeaders(headers, authToken) {
1454
1015
  const merged = new Headers(headers);
1455
1016
  if (authToken) {
1456
- const bearer = `Bearer ${authToken}`;
1457
- merged.set("authorization", bearer);
1458
- merged.set("x-auth", bearer);
1459
- merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
1017
+ merged.set("authorization", `Bearer ${authToken}`);
1460
1018
  }
1461
1019
  return merged;
1462
1020
  }
@@ -1516,41 +1074,15 @@ async function buildServerFailureContext(projectRoot, server) {
1516
1074
  hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
1517
1075
  };
1518
1076
  }
1519
- function isLoopbackRemoteBaseUrl(baseUrl) {
1520
- try {
1521
- const host = new URL(baseUrl).hostname.toLowerCase();
1522
- return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
1523
- } catch {
1524
- return false;
1525
- }
1526
- }
1527
- function canUseRemoteWithoutProjectRoot(pathname) {
1528
- 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/");
1529
- }
1530
1077
  async function requestServerJson(context, pathname, init = {}) {
1531
1078
  const server = await ensureServerForCli(context.projectRoot);
1532
- const requestUrl = new URL(`${server.baseUrl}${pathname}`);
1533
- let scopedServerProjectRoot = server.serverProjectRoot;
1534
- if (server.connectionKind === "remote" && !scopedServerProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
1535
- const link = await ensureRemoteProjectRootLink(context.projectRoot, { mode: "backfill-only", authToken: server.authToken });
1536
- if (link.ok && link.serverProjectRoot) {
1537
- scopedServerProjectRoot = link.serverProjectRoot;
1538
- } else {
1539
- const repo = readRepoConnection(context.projectRoot);
1540
- const target = link.alias && link.baseUrl ? `${link.alias} (${link.baseUrl})` : server.baseUrl;
1541
- throw new CliError(`Remote server ${target} is selected for ${link.repoSlug ?? repo?.project ?? "this repo"}, but this checkout has no server-host project root link. ${link.message}`, 1, { hint: link.hint });
1542
- }
1543
- }
1544
1079
  const headers = mergeHeaders(init.headers, server.authToken);
1545
- if (scopedServerProjectRoot)
1546
- headers.set("x-rig-project-root", scopedServerProjectRoot);
1547
- if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
1548
- requestUrl.searchParams.set("rt", server.authToken);
1549
- }
1080
+ if (server.serverProjectRoot)
1081
+ headers.set("x-rig-project-root", server.serverProjectRoot);
1550
1082
  reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
1551
1083
  let response;
1552
1084
  try {
1553
- response = await fetch(requestUrl, {
1085
+ response = await fetch(`${server.baseUrl}${pathname}`, {
1554
1086
  ...init,
1555
1087
  headers
1556
1088
  });
@@ -1612,26 +1144,11 @@ async function getGitHubAuthStatusViaServer(context) {
1612
1144
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
1613
1145
  }
1614
1146
  async function postGitHubTokenViaServer(context, token, options = {}) {
1615
- const server = await ensureServerForCli(context.projectRoot);
1616
- const requestUrl = new URL(`${server.baseUrl}/api/github/auth/token`);
1617
- reportServerPhase("POST /api/github/auth/token\u2026");
1618
- let response;
1619
- try {
1620
- response = await fetch(requestUrl, {
1621
- method: "POST",
1622
- headers: { "content-type": "application/json" },
1623
- body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot ?? server.serverProjectRoot ?? undefined })
1624
- });
1625
- } catch (error) {
1626
- const failure = await buildServerFailureContext(context.projectRoot, server);
1627
- throw new CliError(`Rig server auth bootstrap failed: ${error instanceof Error ? error.message : String(error)}
1628
- ${failure.contextLine}`, 1, { hint: failure.hint });
1629
- }
1630
- const payload = await response.json().catch(() => null);
1631
- if (!response.ok) {
1632
- const detail = payload && typeof payload === "object" && !Array.isArray(payload) ? String(payload.error ?? JSON.stringify(payload)) : `HTTP ${response.status}`;
1633
- throw new CliError(`Rig server auth bootstrap failed (${response.status}): ${detail}`, 1, { hint: "Re-run `rig github auth import-gh`, or check the selected server with `rig server status`." });
1634
- }
1147
+ const payload = await requestServerJson(context, "/api/github/auth/token", {
1148
+ method: "POST",
1149
+ headers: { "content-type": "application/json" },
1150
+ body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot })
1151
+ });
1635
1152
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
1636
1153
  }
1637
1154
  async function prepareRemoteCheckoutViaServer(context, input) {
@@ -1909,14 +1426,6 @@ function permissionAllowsPr(payload) {
1909
1426
  function isNotFoundError(error) {
1910
1427
  return /\b(404|not found)\b/i.test(message(error));
1911
1428
  }
1912
- function isLoopbackBaseUrl(baseUrl) {
1913
- try {
1914
- const host = new URL(baseUrl).hostname.toLowerCase();
1915
- return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
1916
- } catch {
1917
- return false;
1918
- }
1919
- }
1920
1429
  function projectCheckoutReady(payload) {
1921
1430
  if (!payload || typeof payload !== "object" || Array.isArray(payload))
1922
1431
  return null;
@@ -1970,38 +1479,25 @@ async function runFastTaskRunPreflight(context, options = {}) {
1970
1479
  }
1971
1480
  }
1972
1481
  const repo = readRepoConnection(context.projectRoot);
1973
- const remoteWithoutProjectLink = selectedServer?.connectionKind === "remote" && !repo?.project;
1974
- let remoteRootBlocked = false;
1975
- 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 server repair-link --repo owner/repo` or `rig init --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>`."));
1976
- if (selectedServer?.connectionKind === "remote" && repo?.project && !selectedServer.serverProjectRoot) {
1977
- const link = await ensureRemoteProjectRootLink(context.projectRoot, { mode: "backfill-only", authToken: selectedServer.authToken });
1978
- const loopbackDevRemote = !selectedServer.authToken && isLoopbackBaseUrl(selectedServer.baseUrl);
1979
- checks.push(preflightCheck("remote-project-root-link", "remote server checkout/root linked", link.ok ? "pass" : loopbackDevRemote ? "warn" : "fail", link.ok ? `${link.repoSlug} -> ${link.serverProjectRoot}` : link.message, link.ok ? undefined : loopbackDevRemote ? "Loopback development remotes may continue without x-rig-project-root; production remotes must run `rig server repair-link`." : link.hint));
1980
- remoteRootBlocked = !link.ok && !loopbackDevRemote;
1981
- }
1482
+ 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>`."));
1982
1483
  try {
1983
1484
  const auth = await request("/api/github/auth/status");
1984
1485
  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>`."));
1985
1486
  } catch (error) {
1986
1487
  checks.push(preflightCheck("github-auth", "GitHub auth valid", legacyServerCompatibility ? "warn" : "fail", message(error), "Fix GitHub auth on the selected Rig server."));
1987
1488
  }
1988
- if (!remoteRootBlocked) {
1989
- try {
1990
- const projection = await request("/api/workspace/task-projection");
1991
- checks.push(preflightCheck("task-projection", "task projection ready", "pass", JSON.stringify(projection).slice(0, 120)));
1992
- } catch (error) {
1993
- checks.push(preflightCheck("task-projection", "task projection ready", "warn", message(error), "Refresh task projection with `rig task list` before launching."));
1994
- }
1995
- try {
1996
- const permissions = await request("/api/github/repo/permissions");
1997
- const allowed = permissionAllowsPr(permissions);
1998
- checks.push(allowed === false ? preflightCheck("github-repo-permissions", "GitHub PR permissions", "fail", JSON.stringify(permissions).slice(0, 120), "Grant the selected GitHub token permission to push branches and open PRs.") : preflightCheck("github-repo-permissions", "GitHub PR permissions", allowed === true ? "pass" : "warn", JSON.stringify(permissions).slice(0, 120), "Confirm the selected token can push branches and open PRs."));
1999
- } catch (error) {
2000
- checks.push(preflightCheck("github-repo-permissions", "GitHub PR permissions", "warn", message(error), "Ensure the selected token can push branches and open PRs."));
2001
- }
2002
- } else {
2003
- checks.push(preflightCheck("task-projection", "task projection ready", "warn", "skipped until remote project-root link is repaired", "Run `rig server repair-link`, then retry."));
2004
- checks.push(preflightCheck("github-repo-permissions", "GitHub PR permissions", "warn", "skipped until remote project-root link is repaired", "Run `rig server repair-link`, then retry."));
1489
+ try {
1490
+ const projection = await request("/api/workspace/task-projection");
1491
+ checks.push(preflightCheck("task-projection", "task projection ready", "pass", JSON.stringify(projection).slice(0, 120)));
1492
+ } catch (error) {
1493
+ checks.push(preflightCheck("task-projection", "task projection ready", "warn", message(error), "Refresh task projection with `rig task list` before launching."));
1494
+ }
1495
+ try {
1496
+ const permissions = await request("/api/github/repo/permissions");
1497
+ const allowed = permissionAllowsPr(permissions);
1498
+ checks.push(allowed === false ? preflightCheck("github-repo-permissions", "GitHub PR permissions", "fail", JSON.stringify(permissions).slice(0, 120), "Grant the selected GitHub token permission to push branches and open PRs.") : preflightCheck("github-repo-permissions", "GitHub PR permissions", allowed === true ? "pass" : "warn", JSON.stringify(permissions).slice(0, 120), "Confirm the selected token can push branches and open PRs."));
1499
+ } catch (error) {
1500
+ checks.push(preflightCheck("github-repo-permissions", "GitHub PR permissions", "warn", message(error), "Ensure the selected token can push branches and open PRs."));
2005
1501
  }
2006
1502
  if (repo?.project) {
2007
1503
  try {
@@ -2013,24 +1509,19 @@ async function runFastTaskRunPreflight(context, options = {}) {
2013
1509
  }
2014
1510
  }
2015
1511
  if (taskId) {
2016
- if (!remoteRootBlocked) {
2017
- try {
2018
- const tasks = await request(`/api/workspace/tasks?limit=200&refresh=1`);
2019
- const found = Array.isArray(tasks) && tasks.some((task) => taskMatchesId(task, taskId));
2020
- checks.push(found ? preflightCheck("issue", "task/issue accessible", "pass", taskId) : preflightCheck("issue", "task/issue accessible", legacyServerCompatibility ? "warn" : "fail", taskId, "Confirm the issue exists and matches the configured task filters."));
2021
- } catch (error) {
2022
- checks.push(preflightCheck("issue", "task/issue accessible", legacyServerCompatibility ? "warn" : "fail", message(error), "Fix the task source before launching a run."));
2023
- }
2024
- try {
2025
- const runs = await request("/api/runs?limit=200");
2026
- const duplicate = activeDuplicateRun(runs, taskId);
2027
- checks.push(duplicate ? preflightCheck("duplicate-active-run", "one active run per task", "fail", String(duplicate.runId ?? taskId), "Attach to or stop the existing run before starting another one for this task.") : preflightCheck("duplicate-active-run", "one active run per task", "pass", taskId));
2028
- } catch (error) {
2029
- checks.push(preflightCheck("duplicate-active-run", "one active run per task", "warn", message(error), "Could not list active runs; the server will still reject conflicting runs if configured."));
2030
- }
2031
- } else {
2032
- checks.push(preflightCheck("issue", "task/issue accessible", "fail", "skipped until remote project-root link is repaired", "Run `rig server repair-link`, then retry."));
2033
- checks.push(preflightCheck("duplicate-active-run", "one active run per task", "warn", "skipped until remote project-root link is repaired", "Run `rig server repair-link`, then retry."));
1512
+ try {
1513
+ const tasks = await request(`/api/workspace/tasks?limit=200&refresh=1`);
1514
+ const found = Array.isArray(tasks) && tasks.some((task) => taskMatchesId(task, taskId));
1515
+ checks.push(found ? preflightCheck("issue", "task/issue accessible", "pass", taskId) : preflightCheck("issue", "task/issue accessible", legacyServerCompatibility ? "warn" : "fail", taskId, "Confirm the issue exists and matches the configured task filters."));
1516
+ } catch (error) {
1517
+ checks.push(preflightCheck("issue", "task/issue accessible", legacyServerCompatibility ? "warn" : "fail", message(error), "Fix the task source before launching a run."));
1518
+ }
1519
+ try {
1520
+ const runs = await request("/api/runs?limit=200");
1521
+ const duplicate = activeDuplicateRun(runs, taskId);
1522
+ checks.push(duplicate ? preflightCheck("duplicate-active-run", "one active run per task", "fail", String(duplicate.runId ?? taskId), "Attach to or stop the existing run before starting another one for this task.") : preflightCheck("duplicate-active-run", "one active run per task", "pass", taskId));
1523
+ } catch (error) {
1524
+ checks.push(preflightCheck("duplicate-active-run", "one active run per task", "warn", message(error), "Could not list active runs; the server will still reject conflicting runs if configured."));
2034
1525
  }
2035
1526
  }
2036
1527
  if ((options.runtimeAdapter ?? "pi") === "pi") {
@@ -2099,8 +1590,18 @@ import {
2099
1590
  readJsonlFile as readJsonlFile2,
2100
1591
  writeAuthorityRunRecord
2101
1592
  } from "@rig/runtime/control-plane/authority-files";
2102
- function normalizeRuntimeAdapter(_value) {
2103
- return "pi";
1593
+ function normalizeRuntimeAdapter(value) {
1594
+ const normalized = value?.trim().toLowerCase();
1595
+ if (!normalized) {
1596
+ return "pi";
1597
+ }
1598
+ if (normalized === "codex" || normalized === "codex-cli" || normalized === "codex-app-server" || normalized === "gpt-codex") {
1599
+ return "codex";
1600
+ }
1601
+ if (normalized === "pi" || normalized === "rig-pi" || normalized === "@rig/pi") {
1602
+ return "pi";
1603
+ }
1604
+ return "claude-code";
2104
1605
  }
2105
1606
  function readLatestBeadRecord(projectRoot, taskId) {
2106
1607
  const issuesPath = resolve11(resolveControlPlaneMonorepoRoot(projectRoot), ".beads", "issues.jsonl");
@@ -2514,19 +2015,16 @@ function formatConnectionList(connections) {
2514
2015
  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(`
2515
2016
  `);
2516
2017
  }
2517
- function formatConnectionStatus(selected, connections, repo, remoteProjectLink) {
2018
+ function formatConnectionStatus(selected, connections) {
2518
2019
  const connection = selected === "local" ? { kind: "local", mode: "auto" } : connections[selected];
2519
2020
  const target = !connection ? "not configured" : connection.kind === "remote" ? connection.baseUrl : "local";
2520
- const rootLabel = remoteProjectLink ? remoteProjectLink.ok ? `ready \xB7 ${remoteProjectLink.serverProjectRoot ?? repo?.serverProjectRoot ?? "linked"}` : `${remoteProjectLink.status ?? "needs repair"} \xB7 ${remoteProjectLink.hint ?? remoteProjectLink.message ?? "run rig server repair-link"}` : repo?.serverProjectRoot ? repo.serverProjectRoot : "not required";
2521
2021
  return [
2522
2022
  formatSection("Rig server", "selected for this repo"),
2523
2023
  `${themeFaint("\u2502")} ${themeDim("selected ")} ${pc3.bold(selected)}`,
2524
2024
  `${themeFaint("\u2502")} ${themeDim("kind ")} ${formatStatusPill(connection?.kind ?? "unknown")}`,
2525
2025
  `${themeFaint("\u2502")} ${themeDim("target ")} ${target ?? "not configured"}`,
2526
- ...repo?.project ? [`${themeFaint("\u2502")} ${themeDim("project ")} ${repo.project}`] : [],
2527
- ...connection?.kind === "remote" ? [`${themeFaint("\u2502")} ${themeDim("root ")} ${rootLabel}`] : [],
2528
2026
  "",
2529
- ...formatNextSteps(remoteProjectLink && !remoteProjectLink.ok ? ["Repair remote link: `rig server repair-link`", "Authenticate first if needed: `rig github auth import-gh`"] : ["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
2027
+ ...formatNextSteps(["Change: `rig server use <alias|local>`", "List saved servers: `rig server list`"])
2530
2028
  ].join(`
2531
2029
  `);
2532
2030
  }
@@ -3025,7 +2523,7 @@ var init__operator_surface = __esm(() => {
3025
2523
  });
3026
2524
 
3027
2525
  // packages/cli/src/commands/_pi-frontend.ts
3028
- import { existsSync as existsSync14, mkdirSync as mkdirSync10, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "fs";
2526
+ import { existsSync as existsSync14, mkdirSync as mkdirSync8, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync5, writeFileSync as writeFileSync6 } from "fs";
3029
2527
  import { homedir as homedir6, tmpdir } from "os";
3030
2528
  import { join as join3 } from "path";
3031
2529
  import { main as runPiMain } from "@earendil-works/pi-coding-agent";
@@ -3057,27 +2555,10 @@ function buildOperatorPiEnv(input) {
3057
2555
  ...input.serverProjectRoot ? { RIG_PROJECT_ROOT: input.serverProjectRoot } : {}
3058
2556
  };
3059
2557
  }
3060
- function shouldRequireOperatorTranscript(status) {
3061
- return typeof status === "string" && TERMINAL_RUN_STATUSES.has(status.trim().toLowerCase());
3062
- }
3063
- function missingOperatorTranscriptMessage(runId, status) {
3064
- const shortRun = runId.trim().slice(0, 8) || "unknown";
3065
- const statusText = typeof status === "string" && status.trim() ? status.trim() : "terminal";
3066
- 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.`;
3067
- }
3068
- function statusFromRunDetails(run) {
3069
- if (!run || typeof run !== "object" || Array.isArray(run))
3070
- return;
3071
- const record = run;
3072
- if (typeof record.status === "string")
3073
- return record.status;
3074
- const nested = record.run;
3075
- return nested && typeof nested === "object" && !Array.isArray(nested) ? nested.status : undefined;
3076
- }
3077
2558
  async function prepareOperatorConsole(context, runId, tempSessionDir) {
3078
2559
  const server = await ensureServerForCli(context.projectRoot);
3079
2560
  const localCwd = join3(homedir6(), ".rig", "drones", runId.slice(0, 8));
3080
- mkdirSync10(localCwd, { recursive: true });
2561
+ mkdirSync8(localCwd, { recursive: true });
3081
2562
  trustDroneCwd(localCwd);
3082
2563
  installRigPiTheme();
3083
2564
  let sessionFileArg = [];
@@ -3099,28 +2580,21 @@ async function prepareOperatorConsole(context, runId, tempSessionDir) {
3099
2580
  return line;
3100
2581
  }).join(`
3101
2582
  `);
3102
- writeFileSync8(localSessionPath, content);
2583
+ writeFileSync6(localSessionPath, content);
3103
2584
  sessionFileArg = ["--session", localSessionPath];
3104
2585
  }
3105
2586
  } catch {}
3106
- if (sessionFileArg.length === 0) {
3107
- const run = await getRunDetailsViaServer(context, runId).catch(() => null);
3108
- const status = statusFromRunDetails(run);
3109
- if (shouldRequireOperatorTranscript(status)) {
3110
- throw new OperatorTranscriptUnavailableError(missingOperatorTranscriptMessage(runId, status));
3111
- }
3112
- }
3113
2587
  return { server, sessionFileArg };
3114
2588
  }
3115
2589
  function trustDroneCwd(localCwd) {
3116
2590
  try {
3117
2591
  const agentDir = join3(homedir6(), ".pi", "agent");
3118
- mkdirSync10(agentDir, { recursive: true });
2592
+ mkdirSync8(agentDir, { recursive: true });
3119
2593
  const trustPath = join3(agentDir, "trust.json");
3120
2594
  const store = existsSync14(trustPath) ? JSON.parse(readFileSync10(trustPath, "utf8")) : {};
3121
2595
  if (store[localCwd] !== true) {
3122
2596
  store[localCwd] = true;
3123
- writeFileSync8(trustPath, `${JSON.stringify(store, null, "\t")}
2597
+ writeFileSync6(trustPath, `${JSON.stringify(store, null, "\t")}
3124
2598
  `);
3125
2599
  }
3126
2600
  } catch {}
@@ -3128,38 +2602,15 @@ function trustDroneCwd(localCwd) {
3128
2602
  function installRigPiTheme() {
3129
2603
  try {
3130
2604
  const themesDir = join3(homedir6(), ".pi", "agent", "themes");
3131
- mkdirSync10(themesDir, { recursive: true });
2605
+ mkdirSync8(themesDir, { recursive: true });
3132
2606
  const themePath = join3(themesDir, "rig.json");
3133
2607
  const next = `${JSON.stringify(RIG_PI_THEME, null, "\t")}
3134
2608
  `;
3135
2609
  if (!existsSync14(themePath) || readFileSync10(themePath, "utf8") !== next) {
3136
- writeFileSync8(themePath, next);
2610
+ writeFileSync6(themePath, next);
3137
2611
  }
3138
2612
  } catch {}
3139
2613
  }
3140
- async function runWithProcessExitGuard(body) {
3141
- const realExit = process.exit;
3142
- let exitCode = 0;
3143
- let signalQuit = () => {};
3144
- const quit = new Promise((resolve22) => {
3145
- signalQuit = resolve22;
3146
- });
3147
- const guardedExit = (code) => {
3148
- exitCode = typeof code === "number" ? code : 0;
3149
- signalQuit();
3150
- return;
3151
- };
3152
- process.exit = guardedExit;
3153
- try {
3154
- await Promise.race([Promise.resolve().then(body), quit]);
3155
- } finally {
3156
- process.exit = realExit;
3157
- }
3158
- return exitCode;
3159
- }
3160
- function runPiMainReturningOnQuit(args, options) {
3161
- return runWithProcessExitGuard(() => runPiMain(args, options));
3162
- }
3163
2614
  async function attachRunBundledPiFrontend(context, input) {
3164
2615
  const tempSessionDir = mkdtempSync(join3(tmpdir(), "rig-pi-frontend-sessions-"));
3165
2616
  const { server, sessionFileArg } = await withSpinner(`Opening Pi console for run ${input.runId}\u2026`, () => prepareOperatorConsole(context, input.runId, tempSessionDir), { outputMode: context.outputMode });
@@ -3175,20 +2626,15 @@ async function attachRunBundledPiFrontend(context, input) {
3175
2626
  };
3176
2627
  let detached = false;
3177
2628
  try {
3178
- const piArgs = [
3179
- "--offline",
2629
+ await runPiMain([
3180
2630
  "--no-extensions",
3181
2631
  "--no-skills",
3182
2632
  "--no-prompt-templates",
3183
2633
  "--no-context-files",
3184
2634
  ...sessionFileArg
3185
- ];
3186
- const piOptions = { extensionFactories: [piRigExtensionFactory] };
3187
- if (input.returnOnQuit) {
3188
- await runPiMainReturningOnQuit(piArgs, piOptions);
3189
- } else {
3190
- await runPiMain(piArgs, piOptions);
3191
- }
2635
+ ], {
2636
+ extensionFactories: [piRigExtensionFactory]
2637
+ });
3192
2638
  detached = true;
3193
2639
  } finally {
3194
2640
  restoreEnv();
@@ -3208,17 +2654,10 @@ async function attachRunBundledPiFrontend(context, input) {
3208
2654
  rendered: "stock Pi operator console with the pi-rig extension"
3209
2655
  };
3210
2656
  }
3211
- var TERMINAL_RUN_STATUSES, OperatorTranscriptUnavailableError, RIG_PI_THEME;
2657
+ var RIG_PI_THEME;
3212
2658
  var init__pi_frontend = __esm(() => {
3213
2659
  init__server_client();
3214
2660
  init__async_ui();
3215
- TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
3216
- OperatorTranscriptUnavailableError = class OperatorTranscriptUnavailableError extends Error {
3217
- constructor(message2) {
3218
- super(message2);
3219
- this.name = "OperatorTranscriptUnavailableError";
3220
- }
3221
- };
3222
2661
  RIG_PI_THEME = {
3223
2662
  $schema: "https://raw.githubusercontent.com/earendil-works/pi/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
3224
2663
  name: "rig",
@@ -3373,7 +2812,7 @@ async function attachRunOperatorView(context, input) {
3373
2812
  }
3374
2813
  const pollMs = Math.max(250, Math.trunc(input.pollMs ?? 2000));
3375
2814
  let timelineCursor = snapshot.timelineCursor;
3376
- while (!detached && !TERMINAL_RUN_STATUSES2.has(runStatusFromPayload(snapshot.run))) {
2815
+ while (!detached && !TERMINAL_RUN_STATUSES.has(runStatusFromPayload(snapshot.run))) {
3377
2816
  await Bun.sleep(pollMs);
3378
2817
  snapshot = await readOperatorSnapshot(context, input.runId, { timelineCursor });
3379
2818
  timelineCursor = snapshot.timelineCursor;
@@ -3385,13 +2824,13 @@ async function attachRunOperatorView(context, input) {
3385
2824
  }
3386
2825
  return { ...snapshot, steered, detached };
3387
2826
  }
3388
- var TERMINAL_RUN_STATUSES2;
2827
+ var TERMINAL_RUN_STATUSES;
3389
2828
  var init__operator_view = __esm(() => {
3390
2829
  init__server_client();
3391
2830
  init__operator_surface();
3392
2831
  init__pi_frontend();
3393
2832
  init__async_ui();
3394
- TERMINAL_RUN_STATUSES2 = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
2833
+ TERMINAL_RUN_STATUSES = new Set(["completed", "failed", "stopped", "cancelled", "canceled", "closed", "merged", "needs_attention", "needs-attention"]);
3395
2834
  });
3396
2835
 
3397
2836
  // packages/cli/src/commands/_help-catalog.ts
@@ -3561,13 +3000,12 @@ var init__help_catalog = __esm(() => {
3561
3000
  {
3562
3001
  name: "server",
3563
3002
  summary: "Choose, inspect, and start the Rig server that owns tasks and runs.",
3564
- usage: ["rig server <status|list|add|use|repair-link|start> [options]"],
3003
+ usage: ["rig server <status|list|add|use|start> [options]"],
3565
3004
  commands: [
3566
- { command: "status", description: "Show the selected server and remote project-root link for this repo.", primary: true },
3005
+ { command: "status", description: "Show the selected server for this repo.", primary: true },
3567
3006
  { command: "use local", description: "Switch this repo to the local Rig server.", primary: true },
3568
3007
  { command: "add <alias> <url>", description: "Save a remote Rig server URL.", primary: true },
3569
3008
  { command: "use <alias>", description: "Select a saved remote server alias.", primary: true },
3570
- { command: "repair-link [--prepare|--backfill-only] [--repo owner/repo]", description: "Backfill or prepare the selected remote's server-host checkout link.", primary: true },
3571
3009
  { command: "list", description: "List saved local/remote server aliases.", primary: true },
3572
3010
  { command: "start [--host <host>] [--port <n>]", description: "Start a local rig-server process." }
3573
3011
  ],
@@ -3575,7 +3013,6 @@ var init__help_catalog = __esm(() => {
3575
3013
  "rig server status",
3576
3014
  "rig server add prod https://where.rig-does.work",
3577
3015
  "rig server use prod",
3578
- "rig server repair-link --repo owner/repo",
3579
3016
  "rig server use local",
3580
3017
  "rig server start --port 3773"
3581
3018
  ],
@@ -3750,62 +3187,30 @@ var init__help_catalog = __esm(() => {
3750
3187
  }
3751
3188
  ];
3752
3189
  ADVANCED_GROUPS = [
3753
- {
3754
- name: "setup",
3755
- summary: "Bootstrap/check local setup.",
3756
- usage: ["rig setup <bootstrap|check|preflight>"],
3757
- commands: [
3758
- { command: "bootstrap", description: "Bootstrap local setup dependencies.", primary: true },
3759
- { command: "check", description: "Check local setup state (toolchain, deps, config).", primary: true },
3760
- { command: "preflight", description: "Run preflight checks before a run.", primary: true }
3761
- ]
3762
- },
3763
- {
3764
- name: "profile",
3765
- summary: "Runtime profile/model defaults.",
3766
- usage: ["rig profile <show|set>"],
3767
- commands: [
3768
- { command: "show", description: "Show the active execution profile.", primary: true },
3769
- { command: "set [--model <model>] [--runtime <runtime>] [--plugin <plugin>]", description: "Set model/runtime/plugin profile defaults.", primary: true }
3770
- ]
3771
- },
3190
+ { name: "setup", summary: "Bootstrap/check local setup.", usage: ["rig setup <bootstrap|check|preflight>"], commands: [{ command: "bootstrap|check|preflight", description: "Setup helpers." }] },
3191
+ { name: "profile", summary: "Runtime profile/model defaults.", usage: ["rig profile <show|set>"], commands: [{ command: "show", description: "Show active profile." }] },
3772
3192
  {
3773
3193
  name: "review",
3774
3194
  summary: "Inspect or change completion review gate policy.",
3775
3195
  usage: ["rig review <show|set>"],
3776
3196
  commands: [
3777
3197
  { command: "show", description: "Show current review gate settings." },
3778
- { command: "set <off|advisory|required> [--provider <provider>]", description: "Change review strictness/provider (e.g. --provider greptile)." }
3198
+ { command: "set <off|advisory|required> [--provider greptile]", description: "Change review strictness/provider." }
3779
3199
  ],
3780
3200
  examples: ["rig review show", "rig review set required --provider greptile"],
3781
3201
  next: ["Use `rig inbox approvals` for blocked run handoffs."]
3782
3202
  },
3783
3203
  {
3784
3204
  name: "browser",
3785
- summary: "Browser workstation actions for browser-required tasks: launch, check, CDP probe, profile reset, and app-specific smokes.",
3786
- usage: ["rig browser <help|explain|demo|hp-next|cdp-probe|profile-persistence|profile-lock-check|smoke-test> [options]"],
3205
+ summary: "Browser/app diagnostics for browser-required tasks.",
3206
+ usage: ["rig browser <help|explain|demo|app|hp-next> [options]"],
3787
3207
  commands: [
3788
- { command: "help", description: "Rich browser command help (canonical: `rig browser help`).", primary: true },
3789
- { command: "explain", description: "Explain the browser-required task contract and runtime helper commands.", primary: true },
3790
- { 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 },
3791
- { command: "hp-next dev", description: "Start hp-next Rig Browser in dev/watch mode.", primary: true },
3792
- { command: "hp-next start", description: "Build/start the hp-next browser workstation without watch mode.", primary: true },
3793
- { command: "hp-next check", description: "Validate the hp-next CDP endpoint on the configured port.", primary: true },
3794
- { command: "hp-next e2e", description: "Run hp-next browser e2e smoke checks through Rig Browser.", primary: true },
3795
- { command: "hp-next reset", description: "Reset the hp-next browser profile when stale browser state is suspected.", primary: true },
3796
- { command: "cdp-probe", description: "Run an isolated CDP attach/evaluate/layout probe." },
3797
- { command: "profile-persistence", description: "Verify a named browser profile persists browser state." },
3798
- { command: "profile-lock-check", description: "Verify concurrent launches reject the same profile." },
3799
- { command: "smoke-test", description: "Run the browser package smoke test." }
3800
- ],
3801
- examples: [
3802
- "rig browser help",
3803
- "rig browser hp-next check",
3804
- "rig browser hp-next e2e",
3805
- "rig browser cdp-probe",
3806
- "rig browser profile-lock-check"
3807
- ],
3808
- next: ["Inside a task run, use rig-browser-launch, rig-browser-check, and rig-browser-attach-info from the worker PATH."]
3208
+ { command: "help", description: "Rich browser command help (canonical: `rig browser help`)." },
3209
+ { command: "explain", description: "Explain the browser-required task contract." },
3210
+ { command: "demo", description: "Run browser demo flows against a local page." },
3211
+ { command: "app", description: "Launch the Rig Browser workstation app." },
3212
+ { command: "hp-next <dev|check|e2e|reset>", description: "Drive the hp-next browser test harness." }
3213
+ ]
3809
3214
  },
3810
3215
  {
3811
3216
  name: "pi",
@@ -3820,60 +3225,12 @@ var init__help_catalog = __esm(() => {
3820
3225
  examples: ["rig pi search subagents", "rig pi add pi-subagents", "rig pi list"],
3821
3226
  next: ["Config-managed extensions: declare `runtime: { pi: { packages: [...] } }` in rig.config.ts \u2014 workers pick them up automatically."]
3822
3227
  },
3823
- {
3824
- name: "queue",
3825
- summary: "Run task queues locally.",
3826
- usage: ["rig queue run [--workers <n>] [--max-tasks <n>] [--action validate|verify|pipeline] [--isolation off|worktree] [--no-runtime-reuse] [--fail-fast] [--skip-project-sync]"],
3827
- commands: [
3828
- { 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 }
3829
- ]
3830
- },
3831
- {
3832
- name: "agent",
3833
- summary: "Runtime agent workspace helpers.",
3834
- usage: ["rig agent <list|prepare|run|cleanup>"],
3835
- commands: [
3836
- { command: "list", description: "List prepared agent runtimes.", primary: true },
3837
- { command: "prepare [--id <id>] [--mode <mode>] [--task <task>]", description: "Prepare an isolated agent runtime workspace.", primary: true },
3838
- { command: "run [--id <id>] [--mode <mode>] [--task <task>] [--skip-project-sync]", description: "Prepare (if needed) and run an agent in its workspace.", primary: true },
3839
- { command: "cleanup [--all] [--id <id>]", description: "Remove prepared agent workspaces.", primary: true }
3840
- ]
3841
- },
3228
+ { name: "queue", summary: "Run task queues locally.", usage: ["rig queue run [options]"], commands: [{ command: "run", description: "Process queue work." }] },
3229
+ { name: "agent", summary: "Runtime agent workspace helpers.", usage: ["rig agent <list|prepare|run|cleanup>"], commands: [{ command: "list", description: "List prepared agents." }] },
3842
3230
  { name: "inspector", summary: "Event stream and drift scanners.", usage: ["rig inspector <stream|scan-upstream-drift>"], commands: [{ command: "stream", description: "Stream events." }] },
3843
- {
3844
- name: "dist",
3845
- summary: "Build/install packaged Rig CLI.",
3846
- usage: ["rig dist <build|install|doctor|rebuild-agent>"],
3847
- commands: [
3848
- { command: "build [--output-dir <dir>]", description: "Build the distributable Rig CLI.", primary: true },
3849
- { command: "install [--scope <scope>] [--path <path>]", description: "Install the built CLI to a scope/path.", primary: true },
3850
- { command: "doctor", description: "Diagnose the dist toolchain and install state.", primary: true },
3851
- { command: "rebuild-agent", description: "Rebuild the agent runtime image, pruning stale images.", primary: true }
3852
- ]
3853
- },
3231
+ { name: "dist", summary: "Build/install packaged Rig CLI.", usage: ["rig dist <build|install|doctor>"], commands: [{ command: "build", description: "Build distribution." }] },
3854
3232
  { name: "workspace", summary: "Workspace topology/service helpers.", usage: ["rig workspace <summary|topology|remote-hosts>"], commands: [{ command: "summary", description: "Show workspace summary." }] },
3855
- {
3856
- name: "remote",
3857
- summary: "Compatibility remote orchestration controls.",
3858
- usage: ["rig remote <status|tasks|watch|pause|resume|continue|stop|refresh|add-iterations|remove-iterations|endpoint ...>"],
3859
- commands: [
3860
- { command: "status [--remote <alias>]", description: "Show the remote orchestration state.", primary: true },
3861
- { command: "tasks [--remote <alias>]", description: "List the remote's tracked tasks.", primary: true },
3862
- { command: "watch [--remote <alias>] [--seconds <n>] [--event <type>]", description: "Stream remote orchestration events.", primary: true },
3863
- { command: "pause [--remote <alias>]", description: "Pause the running remote orchestration.", primary: true },
3864
- { command: "resume [--remote <alias>] [--max-workers <n>] [--max-iterations <n>] [--direct-merge]", description: "Resume the remote with optional tuning.", primary: true },
3865
- { command: "continue [--remote <alias>]", description: "Continue a paused remote orchestration.", primary: true },
3866
- { command: "stop [--remote <alias>]", description: "Stop the remote orchestration.", primary: true },
3867
- { command: "refresh [--remote <alias>]", description: "Refresh remote state.", primary: true },
3868
- { command: "add-iterations [--count <n>] [--remote <alias>]", description: "Grant the remote more iterations.", primary: true },
3869
- { command: "remove-iterations [--count <n>] [--remote <alias>]", description: "Reduce the remote's iteration budget.", primary: true },
3870
- { command: "endpoint list", description: "List configured remote endpoints.", primary: true },
3871
- { command: "endpoint add --alias <alias> --host <host> --port <n> [--token <token>]", description: "Register a remote endpoint.", primary: true },
3872
- { command: "endpoint remove --alias <alias>", description: "Remove a remote endpoint.", primary: true },
3873
- { command: "endpoint test [--alias <alias>]", description: "Test connectivity to a remote endpoint.", primary: true },
3874
- { command: "endpoint doctor", description: "Diagnose remote endpoint configuration.", primary: true }
3875
- ]
3876
- },
3233
+ { name: "remote", summary: "Compatibility remote orchestration controls.", usage: ["rig remote <status|watch|pause|resume|...>"], commands: [{ command: "status", description: "Show remote state." }] },
3877
3234
  { name: "git", summary: "Pass through to Rig git-flow helper.", usage: ["rig git <args...>"], commands: [{ command: "<args...>", description: "Advanced git flow operations." }] },
3878
3235
  { name: "harness", summary: "Pass through to runtime harness CLI.", usage: ["rig harness <args...>"], commands: [{ command: "<args...>", description: "Advanced harness operations." }] },
3879
3236
  { name: "test", summary: "Project test wrappers.", usage: ["rig test <unit|e2e|all>"], commands: [{ command: "all", description: "Run configured project tests." }] }
@@ -3940,7 +3297,7 @@ var init__task_picker = __esm(() => {
3940
3297
  // packages/cli/src/commands/task.ts
3941
3298
  import { readFileSync as readFileSync11 } from "fs";
3942
3299
  import { spawnSync as spawnSync3 } from "child_process";
3943
- import { resolve as resolve22 } from "path";
3300
+ import { resolve as resolve21 } from "path";
3944
3301
  import {
3945
3302
  taskArtifactDir,
3946
3303
  taskArtifacts,
@@ -4218,7 +3575,7 @@ async function executeTask(context, args, options) {
4218
3575
  const fileFlag = takeOption(rest.slice(1), "--file");
4219
3576
  let content;
4220
3577
  if (fileFlag.value) {
4221
- content = readFileSync11(resolve22(context.projectRoot, fileFlag.value), "utf-8");
3578
+ content = readFileSync11(resolve21(context.projectRoot, fileFlag.value), "utf-8");
4222
3579
  } else {
4223
3580
  content = await readStdin();
4224
3581
  }
@@ -4456,47 +3813,6 @@ var init_task = __esm(() => {
4456
3813
  init__connection_state();
4457
3814
  });
4458
3815
 
4459
- // packages/cli/src/commands/_server-events.ts
4460
- import { WsTransport } from "@rig/client";
4461
- import { RIG_WS_CHANNELS } from "@rig/contracts";
4462
- function buildRigWebSocketUrl(baseUrl, authToken) {
4463
- const url = new URL(baseUrl);
4464
- url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
4465
- if (authToken)
4466
- url.searchParams.set("token", authToken);
4467
- return url.toString();
4468
- }
4469
- async function connectRigServerEvents(projectRoot, handlers) {
4470
- const { baseUrl, authToken } = await ensureServerForCli(projectRoot);
4471
- const transport = new WsTransport(buildRigWebSocketUrl(baseUrl, authToken));
4472
- const unsubscribers = [];
4473
- if (handlers.onSnapshotInvalidated)
4474
- unsubscribers.push(transport.subscribe(RIG_WS_CHANNELS.snapshotInvalidated, handlers.onSnapshotInvalidated));
4475
- if (handlers.onRunLogAppended)
4476
- unsubscribers.push(transport.subscribe(RIG_WS_CHANNELS.runLogAppended, handlers.onRunLogAppended));
4477
- if (handlers.onEngineEvent)
4478
- unsubscribers.push(transport.subscribe(RIG_WS_CHANNELS.event, handlers.onEngineEvent));
4479
- let status = "connecting";
4480
- unsubscribers.push(transport.subscribeState((state) => {
4481
- status = state.status;
4482
- handlers.onStatus?.(state.status);
4483
- }));
4484
- return {
4485
- connected: () => status === "connected",
4486
- close: () => {
4487
- for (const unsubscribe of unsubscribers) {
4488
- try {
4489
- unsubscribe();
4490
- } catch {}
4491
- }
4492
- transport.dispose();
4493
- }
4494
- };
4495
- }
4496
- var init__server_events = __esm(() => {
4497
- init__server_client();
4498
- });
4499
-
4500
3816
  // packages/cli/src/app/board.ts
4501
3817
  var exports_board = {};
4502
3818
  __export(exports_board, {
@@ -4528,7 +3844,6 @@ function statusRank(status) {
4528
3844
  case "pending":
4529
3845
  case "preparing":
4530
3846
  case "adopted":
4531
- case "stopping":
4532
3847
  return 2;
4533
3848
  case "completed":
4534
3849
  case "merged":
@@ -4568,10 +3883,6 @@ class RunsList {
4568
3883
  selectedRun() {
4569
3884
  return this.visibleRuns()[this.selected] ?? null;
4570
3885
  }
4571
- patchRun(runId, patch) {
4572
- this.runs = this.runs.map((run) => run.runId === runId ? { ...run, ...patch } : run);
4573
- this.clampSelection();
4574
- }
4575
3886
  cycleSort() {
4576
3887
  this.sortMode = this.sortMode === "active" ? "recent" : this.sortMode === "recent" ? "status" : "active";
4577
3888
  this.clampSelection();
@@ -4794,14 +4105,6 @@ class InboxView {
4794
4105
  selectedItem() {
4795
4106
  return this.items[this.selected] ?? null;
4796
4107
  }
4797
- patchItem(requestId, summary) {
4798
- this.items = this.items.map((item) => item.requestId === requestId ? { ...item, summary } : item);
4799
- }
4800
- removeItem(requestId) {
4801
- const previousIndex = this.selected;
4802
- this.items = this.items.filter((item) => item.requestId !== requestId);
4803
- this.selected = Math.max(0, Math.min(previousIndex, Math.max(0, this.items.length - 1)));
4804
- }
4805
4108
  invalidate() {}
4806
4109
  render(width) {
4807
4110
  return this.renderLines(width).map((line) => truncateToWidth(line, Math.max(10, width - 1)));
@@ -5023,14 +4326,9 @@ async function runOperatorBoard(context, options = {}) {
5023
4326
  tui.stop();
5024
4327
  };
5025
4328
  let refreshInFlight = false;
5026
- const refresh = async (options2 = {}) => {
4329
+ const refresh = async () => {
5027
4330
  if (refreshInFlight)
5028
4331
  return;
5029
- if (!options2.quiet) {
5030
- notice = "refreshing fleet\u2026";
5031
- renderFooter();
5032
- tui.requestRender();
5033
- }
5034
4332
  if (!hasRigProject(context.projectRoot)) {
5035
4333
  list.loading = false;
5036
4334
  list.noProject = true;
@@ -5113,7 +4411,6 @@ async function runOperatorBoard(context, options = {}) {
5113
4411
  };
5114
4412
  const resolveApproval = async (item, decision) => {
5115
4413
  notice = `${decision === "approve" ? "approving" : "rejecting"} ${item.requestId.slice(0, 12)}\u2026`;
5116
- inboxView.patchItem(item.requestId, `${decision === "approve" ? "approving" : "rejecting"}\u2026 ${item.summary}`);
5117
4414
  renderFooter();
5118
4415
  tui.requestRender();
5119
4416
  try {
@@ -5122,10 +4419,8 @@ async function runOperatorBoard(context, options = {}) {
5122
4419
  headers: { "content-type": "application/json" },
5123
4420
  body: JSON.stringify({ runId: item.runId, requestId: item.requestId, decision, note: null })
5124
4421
  });
5125
- inboxView.removeItem(item.requestId);
5126
4422
  notice = `${decision === "approve" ? "approved" : "rejected"} \u2014 drone resumes`;
5127
4423
  } catch (error) {
5128
- inboxView.patchItem(item.requestId, item.summary);
5129
4424
  notice = `resolve failed: ${oneLine(error instanceof Error ? error.message : String(error))}`;
5130
4425
  }
5131
4426
  renderFooter();
@@ -5134,7 +4429,6 @@ async function runOperatorBoard(context, options = {}) {
5134
4429
  };
5135
4430
  const answerInput = async (item, text2) => {
5136
4431
  notice = `answering ${item.requestId.slice(0, 12)}\u2026`;
5137
- inboxView.patchItem(item.requestId, `answering\u2026 ${item.summary}`);
5138
4432
  renderFooter();
5139
4433
  tui.requestRender();
5140
4434
  try {
@@ -5147,10 +4441,8 @@ async function runOperatorBoard(context, options = {}) {
5147
4441
  answers: { [item.questionId ?? "response"]: text2 }
5148
4442
  })
5149
4443
  });
5150
- inboxView.removeItem(item.requestId);
5151
4444
  notice = "answer sent \u2014 drone resumes";
5152
4445
  } catch (error) {
5153
- inboxView.patchItem(item.requestId, item.summary);
5154
4446
  notice = `answer failed: ${oneLine(error instanceof Error ? error.message : String(error))}`;
5155
4447
  }
5156
4448
  renderFooter();
@@ -5299,7 +4591,6 @@ async function runOperatorBoard(context, options = {}) {
5299
4591
  const run = list.selectedRun();
5300
4592
  if (run) {
5301
4593
  notice = `stop requested for ${run.runId.slice(0, 8)}\u2026`;
5302
- list.patchRun(run.runId, { status: "stopping" });
5303
4594
  renderFooter();
5304
4595
  tui.requestRender();
5305
4596
  stopRunViaServer(context, run.runId).then(() => refresh()).catch(() => refresh());
@@ -5307,9 +4598,6 @@ async function runOperatorBoard(context, options = {}) {
5307
4598
  return { consume: true };
5308
4599
  }
5309
4600
  if (data === "r") {
5310
- notice = "refreshing fleet\u2026";
5311
- renderFooter();
5312
- tui.requestRender();
5313
4601
  refresh();
5314
4602
  return { consume: true };
5315
4603
  }
@@ -5335,39 +4623,21 @@ async function runOperatorBoard(context, options = {}) {
5335
4623
  tui.requestRender();
5336
4624
  }
5337
4625
  }, BOARD_TICK_MS);
5338
- const live = { subscription: null };
5339
- const refreshActiveView = () => {
5340
- refresh({ quiet: true });
5341
- if (view === "tasks")
5342
- refreshTasks();
5343
- if (view === "inbox")
5344
- refreshInbox();
5345
- };
5346
- connectRigServerEvents(context.projectRoot, {
5347
- onSnapshotInvalidated: () => refreshActiveView()
5348
- }).then((subscription) => {
5349
- live.subscription = subscription;
5350
- }).catch(() => {
5351
- live.subscription = null;
5352
- });
5353
4626
  const refreshTimer = setInterval(() => {
5354
- if (live.subscription?.connected())
5355
- return;
5356
4627
  refresh();
5357
4628
  }, BOARD_REFRESH_MS);
5358
4629
  tui.start();
5359
- refresh({ quiet: true });
5360
- await new Promise((resolve25) => {
4630
+ refresh();
4631
+ await new Promise((resolve24) => {
5361
4632
  const poll = setInterval(() => {
5362
4633
  if (stopped) {
5363
4634
  clearInterval(poll);
5364
- resolve25();
4635
+ resolve24();
5365
4636
  }
5366
4637
  }, 50);
5367
4638
  });
5368
4639
  clearInterval(animation);
5369
4640
  clearInterval(refreshTimer);
5370
- live.subscription?.close();
5371
4641
  return outcome;
5372
4642
  }
5373
4643
  async function runOperatorBoardLoop(context, attach, options = {}) {
@@ -5380,13 +4650,12 @@ async function runOperatorBoardLoop(context, attach, options = {}) {
5380
4650
  await attach(outcome.runId);
5381
4651
  }
5382
4652
  }
5383
- var BOARD_REFRESH_MS = 5000, BOARD_TICK_MS = 16, BOARD_TASK_PAGE = 20;
4653
+ var BOARD_REFRESH_MS = 5000, BOARD_TICK_MS = 250, BOARD_TASK_PAGE = 20;
5384
4654
  var init_board = __esm(() => {
5385
4655
  init_theme();
5386
4656
  init__help_catalog();
5387
4657
  init__server_client();
5388
4658
  init__authority_runs();
5389
- init__server_events();
5390
4659
  init_inbox();
5391
4660
  init_task();
5392
4661
  });
@@ -5397,7 +4666,7 @@ import {
5397
4666
  existsSync as existsSync18,
5398
4667
  readFileSync as readFileSync13
5399
4668
  } from "fs";
5400
- import { resolve as resolve25 } from "path";
4669
+ import { resolve as resolve24 } from "path";
5401
4670
  import { readBuildConfig } from "@rig/runtime/build-time-config";
5402
4671
 
5403
4672
  // packages/cli/src/commands/browser.ts
@@ -7904,7 +7173,7 @@ import {
7904
7173
  chmodSync,
7905
7174
  copyFileSync as copyFileSync2,
7906
7175
  existsSync as existsSync8,
7907
- mkdirSync as mkdirSync7,
7176
+ mkdirSync as mkdirSync6,
7908
7177
  readdirSync,
7909
7178
  readlinkSync,
7910
7179
  rmSync as rmSync3,
@@ -8021,7 +7290,7 @@ async function executeDist(context, args) {
8021
7290
  requireNoExtraArgs(pending, "rig dist install [--scope user|system] [--path <dir>]");
8022
7291
  const scope = parseInstallScope(scopeResult.value);
8023
7292
  const installDir = resolveInstallDir(scope, pathResult.value);
8024
- mkdirSync7(installDir, { recursive: true });
7293
+ mkdirSync6(installDir, { recursive: true });
8025
7294
  let source = await findLatestDistBinary(context.projectRoot);
8026
7295
  let buildDir = null;
8027
7296
  if (!source) {
@@ -8076,7 +7345,7 @@ async function executeDist(context, args) {
8076
7345
  const fp = await computeRuntimeImageFingerprint(context.projectRoot);
8077
7346
  const currentId = computeRuntimeImageId(fp);
8078
7347
  const imagesDir = resolve13(resolveControlPlaneMonorepoRuntimeDir(context.projectRoot), "images");
8079
- mkdirSync7(imagesDir, { recursive: true });
7348
+ mkdirSync6(imagesDir, { recursive: true });
8080
7349
  let pruned = 0;
8081
7350
  for (const entry of readdirSync(imagesDir, { withFileTypes: true })) {
8082
7351
  if (entry.isDirectory() && entry.name !== currentId) {
@@ -8088,9 +7357,9 @@ async function executeDist(context, args) {
8088
7357
  console.log(`Pruned ${pruned} stale image(s).`);
8089
7358
  }
8090
7359
  const imageDir = resolve13(imagesDir, currentId);
8091
- mkdirSync7(resolve13(imageDir, "bin/hooks"), { recursive: true });
8092
- mkdirSync7(resolve13(imageDir, "bin/plugins"), { recursive: true });
8093
- mkdirSync7(resolve13(imageDir, "bin/validators"), { recursive: true });
7360
+ mkdirSync6(resolve13(imageDir, "bin/hooks"), { recursive: true });
7361
+ mkdirSync6(resolve13(imageDir, "bin/plugins"), { recursive: true });
7362
+ mkdirSync6(resolve13(imageDir, "bin/validators"), { recursive: true });
8094
7363
  const hookNames = [
8095
7364
  "scope-guard",
8096
7365
  "import-guard",
@@ -8115,8 +7384,8 @@ async function executeDist(context, args) {
8115
7384
  const binPluginsDir = resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "plugins");
8116
7385
  const validatorsRoot = resolve13(hostProjectRoot, "packages/runtime/src/control-plane/validators");
8117
7386
  const binValidatorsDir = resolve13(resolveControlPlaneHostBinDir(context.projectRoot), "validators");
8118
- mkdirSync7(binPluginsDir, { recursive: true });
8119
- mkdirSync7(binValidatorsDir, { recursive: true });
7387
+ mkdirSync6(binPluginsDir, { recursive: true });
7388
+ mkdirSync6(binValidatorsDir, { recursive: true });
8120
7389
  if (existsSync8(pluginsDir)) {
8121
7390
  for (const entry of readdirSync(pluginsDir, { withFileTypes: true })) {
8122
7391
  const m = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
@@ -8223,7 +7492,7 @@ init_inbox();
8223
7492
  init_runner();
8224
7493
  init__connection_state();
8225
7494
  init__server_client();
8226
- import { appendFileSync as appendFileSync2, existsSync as existsSync11, mkdirSync as mkdirSync8, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
7495
+ import { appendFileSync as appendFileSync2, existsSync as existsSync11, mkdirSync as mkdirSync7, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
8227
7496
  import { spawnSync } from "child_process";
8228
7497
  import { basename as basename2, resolve as resolve17 } from "path";
8229
7498
  import { buildRigInitConfigSource } from "@rig/core";
@@ -8409,7 +7678,7 @@ async function buildPiSetupChecks(input = {}) {
8409
7678
  // packages/cli/src/commands/_snapshot-upload.ts
8410
7679
  init__server_client();
8411
7680
  import { mkdir, readdir, readFile, writeFile } from "fs/promises";
8412
- import { dirname as dirname4, resolve as resolve15, relative, sep } from "path";
7681
+ import { dirname as dirname3, resolve as resolve15, relative, sep } from "path";
8413
7682
  var SNAPSHOT_ARCHIVE_VERSION = 1;
8414
7683
  var SNAPSHOT_ARCHIVE_CONTENT_TYPE = "application/vnd.rig.snapshot+json";
8415
7684
  var DEFAULT_EXCLUDED_DIRECTORIES = new Set([
@@ -8758,14 +8027,14 @@ function parseRepoSlug(value) {
8758
8027
  }
8759
8028
  function ensureRigPrivateDirs(projectRoot) {
8760
8029
  const rigDir = resolve17(projectRoot, ".rig");
8761
- mkdirSync8(resolve17(rigDir, "state"), { recursive: true });
8762
- mkdirSync8(resolve17(rigDir, "logs"), { recursive: true });
8763
- mkdirSync8(resolve17(rigDir, "runs"), { recursive: true });
8764
- mkdirSync8(resolve17(rigDir, "tmp"), { recursive: true });
8765
- mkdirSync8(resolve17(projectRoot, "artifacts"), { recursive: true });
8030
+ mkdirSync7(resolve17(rigDir, "state"), { recursive: true });
8031
+ mkdirSync7(resolve17(rigDir, "logs"), { recursive: true });
8032
+ mkdirSync7(resolve17(rigDir, "runs"), { recursive: true });
8033
+ mkdirSync7(resolve17(rigDir, "tmp"), { recursive: true });
8034
+ mkdirSync7(resolve17(projectRoot, "artifacts"), { recursive: true });
8766
8035
  const taskConfigPath = resolve17(rigDir, "task-config.json");
8767
8036
  if (!existsSync11(taskConfigPath))
8768
- writeFileSync6(taskConfigPath, `{}
8037
+ writeFileSync5(taskConfigPath, `{}
8769
8038
  `, "utf-8");
8770
8039
  }
8771
8040
  function ensureGitignoreEntries(projectRoot) {
@@ -8793,7 +8062,7 @@ function ensureRigConfigPackageDependencies(projectRoot) {
8793
8062
  ...existsSync11(path) ? existing : { name: "rig-project", private: true },
8794
8063
  devDependencies
8795
8064
  };
8796
- writeFileSync6(path, `${JSON.stringify(next, null, 2)}
8065
+ writeFileSync5(path, `${JSON.stringify(next, null, 2)}
8797
8066
  `, "utf8");
8798
8067
  }
8799
8068
  function applyGitHubProjectConfig(source, options) {
@@ -8819,9 +8088,9 @@ function checkoutForInit(projectRoot, serverKind, strategy) {
8819
8088
  const selected = strategy ?? { kind: "managed-clone" };
8820
8089
  switch (selected.kind) {
8821
8090
  case "managed-clone":
8822
- return { kind: "managed-clone" };
8091
+ return { kind: "managed-clone", path: projectRoot };
8823
8092
  case "current-ref":
8824
- return { kind: "current-ref", ...selected.ref ? { ref: selected.ref } : {} };
8093
+ return { kind: "current-ref", path: projectRoot, ...selected.ref ? { ref: selected.ref } : {} };
8825
8094
  case "uploaded-snapshot":
8826
8095
  return { kind: "uploaded-snapshot", path: projectRoot, source: "local-working-tree" };
8827
8096
  case "existing-path":
@@ -9091,7 +8360,7 @@ function remoteGitHubAuthMetadata(payload) {
9091
8360
  };
9092
8361
  }
9093
8362
  function writeRemoteGitHubAuthState(projectRoot, input) {
9094
- writeFileSync6(resolve17(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
8363
+ writeFileSync5(resolve17(projectRoot, ".rig", "state", "github-auth.json"), `${JSON.stringify({
9095
8364
  authenticated: true,
9096
8365
  source: input.source,
9097
8366
  storedOnServer: true,
@@ -9139,7 +8408,7 @@ function runLocalFilesInit(context, options) {
9139
8408
  console.log("rig.config already exists; leaving it unchanged. Pass --repair to rewrite it.");
9140
8409
  } else {
9141
8410
  const projectName = basename2(projectRoot) || "rig-project";
9142
- writeFileSync6(configTsPath, buildRigInitConfigSource({
8411
+ writeFileSync5(configTsPath, buildRigInitConfigSource({
9143
8412
  projectName,
9144
8413
  taskSource: { kind: "files", path: "tasks" },
9145
8414
  useStandardPlugin: true
@@ -9148,8 +8417,8 @@ function runLocalFilesInit(context, options) {
9148
8417
  ensureRigConfigPackageDependencies(projectRoot);
9149
8418
  const tasksDir = resolve17(projectRoot, "tasks");
9150
8419
  if (!existsSync11(tasksDir)) {
9151
- mkdirSync8(tasksDir, { recursive: true });
9152
- writeFileSync6(resolve17(tasksDir, "T-1.json"), `${JSON.stringify({ id: "T-1", title: "My first Rig task", body: "Describe the change you want an agent to make." }, null, 2)}
8420
+ mkdirSync7(tasksDir, { recursive: true });
8421
+ writeFileSync5(resolve17(tasksDir, "T-1.json"), `${JSON.stringify({ id: "T-1", title: "My first Rig task", body: "Describe the change you want an agent to make." }, null, 2)}
9153
8422
  `, "utf-8");
9154
8423
  }
9155
8424
  if (context.outputMode !== "json") {
@@ -9212,7 +8481,7 @@ function runDemoInit(context, options) {
9212
8481
  console.log("rig.config already exists; leaving it unchanged. Pass --repair to rewrite it for the demo.");
9213
8482
  }
9214
8483
  } else {
9215
- writeFileSync6(configTsPath, buildRigInitConfigSource({
8484
+ writeFileSync5(configTsPath, buildRigInitConfigSource({
9216
8485
  projectName: basename2(projectRoot) || "rig-demo",
9217
8486
  taskSource: { kind: "files", path: DEMO_TASKS_RELATIVE_DIR },
9218
8487
  useStandardPlugin: true
@@ -9221,14 +8490,14 @@ function runDemoInit(context, options) {
9221
8490
  }
9222
8491
  ensureRigConfigPackageDependencies(projectRoot);
9223
8492
  const demoTasksDir = resolve17(projectRoot, DEMO_TASKS_RELATIVE_DIR);
9224
- mkdirSync8(demoTasksDir, { recursive: true });
8493
+ mkdirSync7(demoTasksDir, { recursive: true });
9225
8494
  const taskIds = [];
9226
8495
  for (const task of DEMO_TASKS) {
9227
8496
  const id = String(task.id);
9228
8497
  taskIds.push(id);
9229
8498
  const taskPath = resolve17(demoTasksDir, `${id}.json`);
9230
8499
  if (!existsSync11(taskPath)) {
9231
- writeFileSync6(taskPath, `${JSON.stringify(task, null, 2)}
8500
+ writeFileSync5(taskPath, `${JSON.stringify(task, null, 2)}
9232
8501
  `, "utf-8");
9233
8502
  }
9234
8503
  }
@@ -9256,32 +8525,21 @@ function runDemoInit(context, options) {
9256
8525
  }
9257
8526
  async function runControlPlaneInit(context, options) {
9258
8527
  const projectRoot = context.projectRoot;
9259
- const existingRepoConnection = readRepoConnection(projectRoot);
9260
- const selectedConnection = (() => {
9261
- try {
9262
- return resolveSelectedConnection(projectRoot);
9263
- } catch {
9264
- return null;
9265
- }
9266
- })();
9267
- const selectedRemote = selectedConnection?.connection.kind === "remote" ? { alias: selectedConnection.alias, connection: selectedConnection.connection } : null;
9268
- const detectedSlug = options.repoSlug ?? existingRepoConnection?.project ?? detectOriginRepoSlug(projectRoot);
9269
- const serverKind = options.server ?? (selectedRemote ? "remote" : "local");
8528
+ const detectedSlug = options.repoSlug ?? detectOriginRepoSlug(projectRoot);
9270
8529
  if (!detectedSlug) {
9271
8530
  const authMethod2 = options.githubAuthMethod ?? (options.githubToken ? "token" : "skip");
9272
- if (serverKind === "local" && authMethod2 === "skip") {
8531
+ if ((options.server ?? "local") === "local" && authMethod2 === "skip") {
9273
8532
  return runLocalFilesInit(context, options);
9274
8533
  }
9275
8534
  throw new CliError("Could not detect GitHub repo slug from origin. Pass --repo owner/repo \u2014 or run `rig init --yes --server local --github-auth skip` for a local files-source project without GitHub.", 1);
9276
8535
  }
9277
8536
  const repo = parseRepoSlug(detectedSlug);
9278
- const connectionAlias = options.connectionAlias ?? (serverKind === "local" ? "local" : selectedRemote?.alias ?? "remote");
9279
- const selectedRemoteUrl = selectedRemote && (!options.connectionAlias || options.connectionAlias === selectedRemote.alias) ? selectedRemote.connection.baseUrl : undefined;
9280
- const remoteUrl = serverKind === "remote" ? (options.remoteUrl ?? selectedRemoteUrl)?.replace(/\/+$/, "") : undefined;
8537
+ const serverKind = options.server ?? "local";
8538
+ const connectionAlias = options.connectionAlias ?? (serverKind === "local" ? "local" : "remote");
9281
8539
  if (serverKind === "remote") {
9282
- if (!remoteUrl)
9283
- throw new CliError("Missing --remote-url for --server remote.", 1, { hint: "Re-run as `rig init --server remote --remote-url https://your-rig-server`, or first select a saved remote with `rig server use <alias>`." });
9284
- upsertGlobalConnection(connectionAlias, { kind: "remote", baseUrl: remoteUrl });
8540
+ if (!options.remoteUrl)
8541
+ throw new CliError("Missing --remote-url for --server remote.", 1, { hint: "Re-run as `rig init --server remote --remote-url https://your-rig-server`." });
8542
+ upsertGlobalConnection(connectionAlias, { kind: "remote", baseUrl: options.remoteUrl });
9285
8543
  }
9286
8544
  writeRepoConnection(projectRoot, {
9287
8545
  selected: connectionAlias,
@@ -9304,11 +8562,11 @@ async function runControlPlaneInit(context, options) {
9304
8562
  taskSource: { kind: "github-issues", owner: repo.owner, repo: repo.repo },
9305
8563
  useStandardPlugin: true
9306
8564
  }), options);
9307
- writeFileSync6(configTsPath, source, "utf-8");
8565
+ writeFileSync5(configTsPath, source, "utf-8");
9308
8566
  }
9309
8567
  ensureRigConfigPackageDependencies(projectRoot);
9310
8568
  }
9311
- writeFileSync6(resolve17(projectRoot, ".rig", "state", "project-link.json"), `${JSON.stringify({ repoSlug: repo.slug, connection: connectionAlias, linkedAt: new Date().toISOString() }, null, 2)}
8569
+ writeFileSync5(resolve17(projectRoot, ".rig", "state", "project-link.json"), `${JSON.stringify({ repoSlug: repo.slug, connection: connectionAlias, linkedAt: new Date().toISOString() }, null, 2)}
9312
8570
  `, "utf8");
9313
8571
  const checkout = checkoutForInit(projectRoot, serverKind, options.remoteCheckout);
9314
8572
  let uploadedSnapshot = null;
@@ -9323,7 +8581,7 @@ async function runControlPlaneInit(context, options) {
9323
8581
  let githubAuth = null;
9324
8582
  let deviceAuth = null;
9325
8583
  const authMethod = options.githubAuthMethod ?? (options.githubToken ? "token" : "skip");
9326
- const remoteGhTokenWarning = serverKind === "remote" && authMethod === "gh" ? `This sends a GitHub token from this machine to ${remoteUrl ?? "the remote Rig server"}.` : null;
8584
+ const remoteGhTokenWarning = serverKind === "remote" && authMethod === "gh" ? `This sends a GitHub token from this machine to ${options.remoteUrl ?? "the remote Rig server"}.` : null;
9327
8585
  if (remoteGhTokenWarning && !options.yes) {
9328
8586
  throw new CliError(`${remoteGhTokenWarning} Re-run with --yes to confirm this explicit token transfer.`, 1);
9329
8587
  }
@@ -9636,64 +8894,14 @@ Usage: rig init`, 1);
9636
8894
  // packages/cli/src/commands/github.ts
9637
8895
  init_runner();
9638
8896
  init__server_client();
9639
- init__connection_state();
9640
8897
  init__async_ui();
9641
8898
  import { spawnSync as spawnSync2 } from "child_process";
9642
- import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync7 } from "fs";
9643
- import { dirname as dirname5, resolve as resolve18 } from "path";
9644
8899
  function printPayload(context, payload, fallback) {
9645
8900
  if (context.outputMode === "json")
9646
8901
  console.log(JSON.stringify(payload, null, 2));
9647
8902
  else
9648
8903
  console.log(fallback);
9649
8904
  }
9650
- function apiSessionTokenFrom2(payload) {
9651
- if (!payload || typeof payload !== "object" || Array.isArray(payload))
9652
- return null;
9653
- const token = payload.apiSessionToken;
9654
- return typeof token === "string" && token.trim() ? token.trim() : null;
9655
- }
9656
- function payloadString(payload, key) {
9657
- const value = payload[key];
9658
- return typeof value === "string" && value.trim() ? value.trim() : null;
9659
- }
9660
- function payloadRecord(payload, key) {
9661
- const value = payload[key];
9662
- return value && typeof value === "object" && !Array.isArray(value) ? value : null;
9663
- }
9664
- function remoteNamespaceMetadata(result) {
9665
- const namespace = payloadRecord(result, "userNamespace");
9666
- return {
9667
- ...payloadString(result, "login") ? { login: payloadString(result, "login") } : {},
9668
- ...payloadString(result, "userId") ? { userId: payloadString(result, "userId") } : {},
9669
- ...namespace && payloadString(namespace, "key") ? { userNamespaceKey: payloadString(namespace, "key") } : {},
9670
- ...namespace && payloadString(namespace, "root") ? { userNamespaceRoot: payloadString(namespace, "root") } : {},
9671
- ...namespace && payloadString(namespace, "checkoutBaseDir") ? { checkoutBaseDir: payloadString(namespace, "checkoutBaseDir") } : {},
9672
- ...namespace && payloadString(namespace, "snapshotBaseDir") ? { snapshotBaseDir: payloadString(namespace, "snapshotBaseDir") } : {}
9673
- };
9674
- }
9675
- function persistRemoteAuthSession(context, source, result, fallbackToken) {
9676
- const apiSessionToken = apiSessionTokenFrom2(result);
9677
- setGitHubBearerTokenForCurrentProcess(apiSessionToken ?? fallbackToken, context.projectRoot);
9678
- if (!apiSessionToken)
9679
- return;
9680
- const repo = readRepoConnection(context.projectRoot);
9681
- const path = resolve18(context.projectRoot, ".rig", "state", "github-auth.json");
9682
- mkdirSync9(dirname5(path), { recursive: true });
9683
- writeFileSync7(path, `${JSON.stringify({
9684
- authenticated: true,
9685
- source,
9686
- storedOnServer: true,
9687
- ...repo?.project ? { selectedRepo: repo.project } : {},
9688
- ...remoteNamespaceMetadata(result),
9689
- apiSessionToken,
9690
- updatedAt: new Date().toISOString()
9691
- }, null, 2)}
9692
- `, "utf8");
9693
- }
9694
- function isSignedIn(status) {
9695
- return status.signedIn === true || status.authenticated === true;
9696
- }
9697
8905
  function readGhToken() {
9698
8906
  const result = spawnSync2("gh", ["auth", "token"], { encoding: "utf8" });
9699
8907
  if (result.status !== 0) {
@@ -9715,7 +8923,7 @@ async function executeGithub(context, args) {
9715
8923
  if (rest.length > 0)
9716
8924
  throw new CliError("Usage: rig github auth status", 1);
9717
8925
  const status = await withSpinner("Checking GitHub auth on the server\u2026", () => getGitHubAuthStatusViaServer(context), { outputMode: context.outputMode });
9718
- printPayload(context, status, `GitHub auth: ${isSignedIn(status) ? "authenticated" : "unauthenticated"}`);
8926
+ printPayload(context, status, `GitHub auth: ${status.authenticated ? "authenticated" : "unauthenticated"}`);
9719
8927
  return { ok: true, group: "github", command: "auth status", details: status };
9720
8928
  }
9721
8929
  case "token": {
@@ -9725,20 +8933,16 @@ async function executeGithub(context, args) {
9725
8933
  const token = parsed.value?.trim();
9726
8934
  if (!token)
9727
8935
  throw new CliError("Missing --token value.", 1, { hint: "Re-run as `rig github auth token --token <token>`." });
9728
- const repo = readRepoConnection(context.projectRoot);
9729
- const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, token, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
9730
- persistRemoteAuthSession(context, "token", result, token);
9731
- printPayload(context, result, "GitHub token stored on the selected server.");
8936
+ const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, token), { outputMode: context.outputMode });
8937
+ printPayload(context, result, "GitHub token stored on the selected Rig server.");
9732
8938
  return { ok: true, group: "github", command: "auth token", details: result };
9733
8939
  }
9734
8940
  case "import-gh": {
9735
8941
  if (rest.length > 0)
9736
8942
  throw new CliError("Usage: rig github auth import-gh", 1);
9737
8943
  const importedToken = readGhToken();
9738
- const repo = readRepoConnection(context.projectRoot);
9739
- const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, importedToken, repo?.project ? { selectedRepo: repo.project } : {}), { outputMode: context.outputMode });
9740
- persistRemoteAuthSession(context, "gh", result, importedToken);
9741
- printPayload(context, result, "GitHub token imported from gh and stored on the selected server.");
8944
+ const result = await withSpinner("Storing GitHub token on the server\u2026", () => postGitHubTokenViaServer(context, importedToken), { outputMode: context.outputMode });
8945
+ printPayload(context, result, "GitHub token imported from gh and stored on the selected Rig server.");
9742
8946
  return { ok: true, group: "github", command: "auth import-gh", details: result };
9743
8947
  }
9744
8948
  default:
@@ -9768,7 +8972,7 @@ init_runner();
9768
8972
  init__authority_runs();
9769
8973
  init__paths();
9770
8974
  import { readFileSync as readFileSync8 } from "fs";
9771
- import { resolve as resolve19 } from "path";
8975
+ import { resolve as resolve18 } from "path";
9772
8976
  import {
9773
8977
  appendRunJournalEvent,
9774
8978
  appendRunLogEntry,
@@ -9805,7 +9009,7 @@ function touchAuthorityRun(projectRoot, runId) {
9805
9009
  if (!current) {
9806
9010
  return;
9807
9011
  }
9808
- writeJsonFile3(resolve19(resolveAuthorityRunDir(projectRoot, runId), "run.json"), {
9012
+ writeJsonFile3(resolve18(resolveAuthorityRunDir(projectRoot, runId), "run.json"), {
9809
9013
  ...current,
9810
9014
  updatedAt: new Date().toISOString()
9811
9015
  });
@@ -10043,7 +9247,7 @@ init_runner();
10043
9247
  init__server_client();
10044
9248
  init__async_ui();
10045
9249
  import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
10046
- import { resolve as resolve20 } from "path";
9250
+ import { resolve as resolve19 } from "path";
10047
9251
  import {
10048
9252
  listAuthorityRuns,
10049
9253
  readAuthorityRun as readAuthorityRun3,
@@ -10087,7 +9291,7 @@ async function executeInspect(context, args) {
10087
9291
  }
10088
9292
  return { ok: true, group: "inspect", command, details: { task: requiredTask, runId: fallback.runId, source: "server", entries } };
10089
9293
  }
10090
- const logsPath = resolve20(resolveAuthorityRunDir2(context.projectRoot, latestRun.runId), "logs.jsonl");
9294
+ const logsPath = resolve19(resolveAuthorityRunDir2(context.projectRoot, latestRun.runId), "logs.jsonl");
10091
9295
  if (!existsSync12(logsPath)) {
10092
9296
  throw new CliError(`No logs found for run ${latestRun.runId}.`, 1, { hint: `Try \`rig run show ${latestRun.runId}\` or \`rig run replay ${latestRun.runId}\`.` });
10093
9297
  }
@@ -10175,7 +9379,7 @@ async function executeInspect(context, args) {
10175
9379
  return { ok: true, group: "inspect", command };
10176
9380
  case "audit": {
10177
9381
  requireNoExtraArgs(rest, "rig inspect audit");
10178
- const auditPath = resolve20(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
9382
+ const auditPath = resolve19(resolveHarnessPaths2(context.projectRoot).logsDir, "audit.jsonl");
10179
9383
  if (!existsSync12(auditPath)) {
10180
9384
  console.log("No audit log found.");
10181
9385
  } else {
@@ -10834,7 +10038,7 @@ import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/co
10834
10038
 
10835
10039
  // packages/cli/src/commands/_run-replay.ts
10836
10040
  import { existsSync as existsSync13, readdirSync as readdirSync2 } from "fs";
10837
- import { join as join2, resolve as resolve21 } from "path";
10041
+ import { join as join2, resolve as resolve20 } from "path";
10838
10042
  import {
10839
10043
  readAuthorityRun as readAuthorityRun4,
10840
10044
  readJsonlFile as readJsonlFile3,
@@ -10927,7 +10131,7 @@ function resolveRunSessionFile(record) {
10927
10131
  const sessionId = text(piSession.sessionId);
10928
10132
  if (!cwd || !sessionId)
10929
10133
  return null;
10930
- const sessionDir = resolve21(cwd, ".rig", "session");
10134
+ const sessionDir = resolve20(cwd, ".rig", "session");
10931
10135
  try {
10932
10136
  const match = readdirSync2(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
10933
10137
  return match ? join2(sessionDir, match) : null;
@@ -11425,9 +10629,6 @@ async function executeRun(context, args) {
11425
10629
  console.log(`Stop requested: ${runId}`);
11426
10630
  return { ok: true, group: "run", command, details: stopped };
11427
10631
  }
11428
- if (isRemoteConnectionSelected(context.projectRoot)) {
11429
- throw new CliError("Remote run stop requires an explicit run id.", 2, { hint: "Run `rig run list`, then `rig run stop <run-id>`." });
11430
- }
11431
10632
  const result = await runStop(context.projectRoot);
11432
10633
  if (result.remaining.length > 0) {
11433
10634
  throw new CliError(`Failed to stop run(s): ${result.remaining.join(", ")}`, 1, { hint: "Check `rig run status`, then retry `rig run stop <run-id>` for the remaining runs." });
@@ -11460,7 +10661,6 @@ init_drone_ui();
11460
10661
  init_runner();
11461
10662
  init__connection_state();
11462
10663
  init__cli_format();
11463
- init__server_client();
11464
10664
  function usageName(options) {
11465
10665
  return `rig ${options.group}`;
11466
10666
  }
@@ -11480,46 +10680,13 @@ function parseConnection(alias, value, options) {
11480
10680
  }
11481
10681
  return { kind: "remote", baseUrl: parsed.toString().replace(/\/+$/, "") };
11482
10682
  }
11483
- function printJsonOrText(context, _payload, text2) {
11484
- if (context.outputMode !== "json") {
10683
+ function printJsonOrText(context, payload, text2) {
10684
+ if (context.outputMode === "json") {
10685
+ console.log(JSON.stringify(payload, null, 2));
10686
+ } else {
11485
10687
  console.log(text2);
11486
10688
  }
11487
10689
  }
11488
- function formatRemoteProjectLinkText(result) {
11489
- return formatSuccessCard(result.ok ? "Remote project link ready" : "Remote project link needs repair", [
11490
- ["selected", result.alias ?? "remote"],
11491
- ["target", result.baseUrl ?? "unknown"],
11492
- ["repo", result.repoSlug ?? "owner/repo"],
11493
- ["status", result.status],
11494
- ...result.serverProjectRoot ? [["server root", result.serverProjectRoot]] : [],
11495
- ["next", result.ok ? result.next ?? "rig task list" : result.hint]
11496
- ]);
11497
- }
11498
- function parseRepairLinkArgs(rest, usage) {
11499
- let repoSlug;
11500
- let mode = "prepare-if-missing";
11501
- const pending = [...rest];
11502
- while (pending.length > 0) {
11503
- const token = pending.shift();
11504
- if (token === "--repo") {
11505
- const value = pending.shift()?.trim();
11506
- if (!value)
11507
- throw new CliError(`Missing --repo value. Usage: ${usage}`, 1);
11508
- const normalized = normalizeRepoSlug(value);
11509
- if (!normalized)
11510
- throw new CliError(`Invalid --repo value: ${value}`, 1, { hint: "Use the canonical owner/repo slug, e.g. `--repo humanity-org/humanwork`." });
11511
- repoSlug = normalized;
11512
- } else if (token === "--backfill-only") {
11513
- mode = "backfill-only";
11514
- } else if (token === "--prepare") {
11515
- mode = "prepare-if-missing";
11516
- } else {
11517
- throw new CliError(`Unexpected argument: ${String(token)}
11518
- Usage: ${usage}`, 1);
11519
- }
11520
- }
11521
- return { repoSlug, mode };
11522
- }
11523
10690
  async function promptForConnectionAlias(context) {
11524
10691
  const state = readGlobalConnections();
11525
10692
  const repo = readRepoConnection(context.projectRoot);
@@ -11573,67 +10740,31 @@ async function executeConnectionCommand(context, args, options) {
11573
10740
  }
11574
10741
  if (!alias)
11575
10742
  throw new CliError(`Missing alias. Usage: ${usageName(options)} use <alias|local>`, 1);
11576
- let selectedConnection = { kind: "local", mode: "auto" };
11577
10743
  if (alias !== "local") {
11578
10744
  const state = readGlobalConnections();
11579
- const connection = state.connections[alias];
11580
- if (!connection)
10745
+ if (!state.connections[alias])
11581
10746
  throw new CliError(`Unknown Rig server: ${alias}`, 1, { hint: "Run `rig server list` to see saved aliases, or save one with `rig server add <alias> <url>`." });
11582
- selectedConnection = connection;
11583
- }
11584
- const previousRepo = readRepoConnection(context.projectRoot);
11585
- const preserveRemoteRoot = Boolean(previousRepo?.serverProjectRoot && previousRepo.selected === alias && selectedConnection.kind === "remote" && previousRepo.serverProjectRootAlias === alias && previousRepo.serverProjectRootBaseUrl === selectedConnection.baseUrl);
11586
- const repoState = {
11587
- selected: alias,
11588
- ...previousRepo?.project ? { project: previousRepo.project } : {},
11589
- linkedAt: new Date().toISOString(),
11590
- ...preserveRemoteRoot ? {
11591
- serverProjectRoot: previousRepo.serverProjectRoot,
11592
- serverProjectRootAlias: previousRepo.serverProjectRootAlias,
11593
- serverProjectRootBaseUrl: previousRepo.serverProjectRootBaseUrl
11594
- } : {}
11595
- };
10747
+ }
10748
+ const repoState = { selected: alias, linkedAt: new Date().toISOString() };
11596
10749
  writeRepoConnection(context.projectRoot, repoState);
11597
- const remoteProjectLink = alias !== "local" ? await ensureRemoteProjectRootLink(context.projectRoot, { mode: "backfill-only" }).catch((error) => ({
11598
- ok: false,
11599
- status: "error",
11600
- message: error instanceof Error ? error.message : String(error),
11601
- hint: "Run `rig server repair-link` after authenticating the selected remote."
11602
- })) : null;
11603
- const latestRepo = readRepoConnection(context.projectRoot);
11604
- const details = { selected: latestRepo?.selected ?? alias, repo: latestRepo, remoteProjectLink };
11605
- printJsonOrText(context, details, formatSuccessCard("Rig server selected", [
10750
+ printJsonOrText(context, repoState, formatSuccessCard("Rig server selected", [
11606
10751
  ["selected", alias],
11607
10752
  ["scope", "this repo"],
11608
- ...remoteProjectLink ? [["remote link", remoteProjectLink.ok ? `ready (${remoteProjectLink.serverProjectRoot ?? "linked"})` : `${remoteProjectLink.status}: ${remoteProjectLink.hint}`]] : [],
11609
- ["next", remoteProjectLink && !remoteProjectLink.ok ? "rig server repair-link" : "rig task list"]
10753
+ ["next", "rig task list"]
11610
10754
  ]));
11611
- return { ok: true, group: options.group, command: "use", details };
11612
- }
11613
- case "repair-link": {
11614
- const parsed = parseRepairLinkArgs(rest, `${usageName(options)} repair-link [--prepare|--backfill-only] [--repo owner/repo]`);
11615
- const result = await repairRemoteProjectRootLink(context, parsed);
11616
- printJsonOrText(context, result, formatRemoteProjectLinkText(result));
11617
- return { ok: true, group: options.group, command: "repair-link", details: result };
10755
+ return { ok: true, group: options.group, command: "use", details: repoState };
11618
10756
  }
11619
10757
  case "status": {
11620
10758
  requireNoExtraArgs(rest, `${usageName(options)} status`);
11621
10759
  const repo = readRepoConnection(context.projectRoot);
11622
10760
  const global = readGlobalConnections();
11623
- const remoteProjectLink = repo?.selected && repo.selected !== "local" ? await ensureRemoteProjectRootLink(context.projectRoot, { mode: "backfill-only" }).catch((error) => ({
11624
- ok: false,
11625
- status: "error",
11626
- message: error instanceof Error ? error.message : String(error),
11627
- hint: "Run `rig server repair-link` after authenticating the selected remote."
11628
- })) : null;
11629
- const latestRepo = readRepoConnection(context.projectRoot) ?? repo;
11630
- const details = { selected: latestRepo?.selected ?? "local", repo: latestRepo, connections: global.connections, remoteProjectLink };
11631
- printJsonOrText(context, details, formatConnectionStatus(details.selected, global.connections, latestRepo ?? null, remoteProjectLink));
10761
+ const details = { selected: repo?.selected ?? "local", repo, connections: global.connections };
10762
+ printJsonOrText(context, details, formatConnectionStatus(details.selected, global.connections));
11632
10763
  return { ok: true, group: options.group, command: "status", details };
11633
10764
  }
11634
10765
  default:
11635
10766
  throw new CliError(`Unknown ${options.group} command: ${String(command)}
11636
- Usage: ${usageName(options)} <list|add|use|status|repair-link>`, 1);
10767
+ Usage: ${usageName(options)} <list|add|use|status>`, 1);
11637
10768
  }
11638
10769
  }
11639
10770
 
@@ -11641,7 +10772,7 @@ Usage: ${usageName(options)} <list|add|use|status|repair-link>`, 1);
11641
10772
  init__server_client();
11642
10773
  async function executeServer(context, args, options) {
11643
10774
  const [command = "status", ...rest] = args;
11644
- if (["status", "list", "add", "use", "repair-link"].includes(command)) {
10775
+ if (["status", "list", "add", "use"].includes(command)) {
11645
10776
  return executeConnectionCommand(context, [command, ...rest], { group: "server", interactiveUse: true });
11646
10777
  }
11647
10778
  switch (command) {
@@ -11849,8 +10980,8 @@ init_task();
11849
10980
 
11850
10981
  // packages/cli/src/commands/task-run-driver.ts
11851
10982
  init_runner();
11852
- import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync11, readFileSync as readFileSync12, statSync as statSync2, writeFileSync as writeFileSync9 } from "fs";
11853
- import { resolve as resolve23 } from "path";
10983
+ import { copyFileSync as copyFileSync3, existsSync as existsSync15, mkdirSync as mkdirSync9, readFileSync as readFileSync12, statSync as statSync2, writeFileSync as writeFileSync7 } from "fs";
10984
+ import { resolve as resolve22 } from "path";
11854
10985
  import { spawn as spawn2, spawnSync as spawnSync4 } from "child_process";
11855
10986
  import { createInterface as createLineInterface } from "readline";
11856
10987
  import { loadConfig as loadConfig2 } from "@rig/core/load-config";
@@ -11949,12 +11080,12 @@ function copyUntrackedDirtyFiles(sourceRoot, targetRoot) {
11949
11080
  return 0;
11950
11081
  let copied = 0;
11951
11082
  for (const relativePath of listed.stdout.split("\x00").filter(Boolean)) {
11952
- const sourcePath = resolve23(sourceRoot, relativePath);
11953
- const targetPath = resolve23(targetRoot, relativePath);
11083
+ const sourcePath = resolve22(sourceRoot, relativePath);
11084
+ const targetPath = resolve22(targetRoot, relativePath);
11954
11085
  try {
11955
11086
  if (!statSync2(sourcePath).isFile())
11956
11087
  continue;
11957
- mkdirSync11(resolve23(targetPath, ".."), { recursive: true });
11088
+ mkdirSync9(resolve22(targetPath, ".."), { recursive: true });
11958
11089
  copyFileSync3(sourcePath, targetPath);
11959
11090
  copied += 1;
11960
11091
  } catch {}
@@ -11993,7 +11124,7 @@ function buildDirtyBaselineHandshakeEnv(input) {
11993
11124
  return { RIG_BASELINE_MODE: input.baselineMode ?? "head" };
11994
11125
  return {
11995
11126
  RIG_BASELINE_MODE: "dirty-snapshot",
11996
- RIG_DIRTY_BASELINE_READY_FILE: resolve23(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
11127
+ RIG_DIRTY_BASELINE_READY_FILE: resolve22(input.projectRoot, ".rig", "runs", input.runId, "dirty-baseline.ready.json")
11997
11128
  };
11998
11129
  }
11999
11130
  function positiveInt(value, fallback) {
@@ -12098,9 +11229,9 @@ function createCommandRunner(binary) {
12098
11229
  const stderrChunks = [];
12099
11230
  child.stdout.on("data", (chunk) => stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
12100
11231
  child.stderr.on("data", (chunk) => stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk))));
12101
- return await new Promise((resolve24) => {
12102
- child.once("error", (error) => resolve24({ exitCode: 1, stderr: error.message }));
12103
- child.once("close", (code) => resolve24({
11232
+ return await new Promise((resolve23) => {
11233
+ child.once("error", (error) => resolve23({ exitCode: 1, stderr: error.message }));
11234
+ child.once("close", (code) => resolve23({
12104
11235
  exitCode: code ?? 1,
12105
11236
  stdout: Buffer.concat(stdoutChunks).toString("utf8"),
12106
11237
  stderr: Buffer.concat(stderrChunks).toString("utf8")
@@ -12174,7 +11305,7 @@ async function runTaskRunPostValidationLifecycle(input) {
12174
11305
  config,
12175
11306
  sourceTask: input.sourceTask,
12176
11307
  uploadedSnapshot: input.uploadedSnapshot,
12177
- artifactRoot: resolve23(input.projectRoot, "artifacts", taskId3),
11308
+ artifactRoot: resolve22(input.projectRoot, "artifacts", taskId3),
12178
11309
  command: ghCommand,
12179
11310
  gitCommand,
12180
11311
  steerPi,
@@ -12304,7 +11435,7 @@ function summarizeValidationFailure(projectRoot, taskId3) {
12304
11435
  return null;
12305
11436
  }
12306
11437
  for (const artifactDir of resolveTaskArtifactDirs2(projectRoot, taskId3)) {
12307
- const summary = readJsonFile3(resolve23(artifactDir, "validation-summary.json"), null);
11438
+ const summary = readJsonFile3(resolve22(artifactDir, "validation-summary.json"), null);
12308
11439
  if (!summary || summary.status !== "fail") {
12309
11440
  continue;
12310
11441
  }
@@ -12385,9 +11516,9 @@ function readTaskRunAcceptedArtifactState(input) {
12385
11516
  if (!input.taskId || !input.workspaceDir) {
12386
11517
  return { accepted: false, reason: null };
12387
11518
  }
12388
- const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
12389
- const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
12390
- const taskResultPath = resolve23(artifactDir, "task-result.json");
11519
+ const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
11520
+ const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
11521
+ const taskResultPath = resolve22(artifactDir, "task-result.json");
12391
11522
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
12392
11523
  if (reviewStatus !== "APPROVED") {
12393
11524
  return { accepted: false, reason: null };
@@ -12424,12 +11555,12 @@ function resolveTaskRunRetryContext(input) {
12424
11555
  if (!input.taskId || !input.workspaceDir) {
12425
11556
  return { shouldRetry: false, failureDetail: null, nextPrompt: null };
12426
11557
  }
12427
- const artifactDir = resolve23(input.workspaceDir, "artifacts", input.taskId);
12428
- const reviewStatePath = resolve23(artifactDir, "review-state.json");
12429
- const reviewFeedbackPath = resolve23(artifactDir, "review-feedback.md");
12430
- const reviewStatusPath = resolve23(artifactDir, "review-status.txt");
12431
- const failedApproachesPath = resolve23(input.workspaceDir, ".rig", "state", "failed_approaches.md");
12432
- const validationSummaryPath = resolve23(artifactDir, "validation-summary.json");
11558
+ const artifactDir = resolve22(input.workspaceDir, "artifacts", input.taskId);
11559
+ const reviewStatePath = resolve22(artifactDir, "review-state.json");
11560
+ const reviewFeedbackPath = resolve22(artifactDir, "review-feedback.md");
11561
+ const reviewStatusPath = resolve22(artifactDir, "review-status.txt");
11562
+ const failedApproachesPath = resolve22(input.workspaceDir, ".rig", "state", "failed_approaches.md");
11563
+ const validationSummaryPath = resolve22(artifactDir, "validation-summary.json");
12433
11564
  const reviewState = readJsonFile3(reviewStatePath, null);
12434
11565
  const reviewStatus = readTaskRunReviewStatus(reviewStatusPath);
12435
11566
  const reviewRejected = isTaskRunReviewRejected(reviewState);
@@ -12839,15 +11970,15 @@ async function executeRigOwnedTaskRun(context, input) {
12839
11970
  const loadedAutomationConfig = await loadTaskRunAutomationConfig(context.projectRoot);
12840
11971
  const automationConfig = input.prMode ? { ...loadedAutomationConfig ?? {}, pr: { ...loadedAutomationConfig?.pr ?? {}, mode: input.prMode } } : loadedAutomationConfig;
12841
11972
  const planningClassification = classifyPlanningNeed({ config: automationConfig, sourceTask });
12842
- const planningArtifactPath = resolve23("artifacts", runtimeTaskId, "implementation-plan.md");
11973
+ const planningArtifactPath = resolve22("artifacts", runtimeTaskId, "implementation-plan.md");
12843
11974
  const persistedPlanning = {
12844
11975
  ...planningClassification,
12845
11976
  classifier: input.runtimeAdapter === "pi" ? "pi-rig-structured-policy" : "rig-structured-policy",
12846
11977
  artifactPath: planningClassification.planningRequired ? planningArtifactPath : null,
12847
11978
  classifiedAt: new Date().toISOString()
12848
11979
  };
12849
- mkdirSync11(resolve23(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
12850
- writeFileSync9(resolve23(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
11980
+ mkdirSync9(resolve22(context.projectRoot, ".rig", "runs", input.runId), { recursive: true });
11981
+ writeFileSync7(resolve22(context.projectRoot, ".rig", "runs", input.runId, "planning-classification.json"), `${JSON.stringify(persistedPlanning, null, 2)}
12851
11982
  `, "utf8");
12852
11983
  patchAuthorityRun(context.projectRoot, input.runId, { planning: persistedPlanning });
12853
11984
  prompt = `${prompt}
@@ -12897,7 +12028,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
12897
12028
  let verificationStarted = false;
12898
12029
  let reviewStarted = false;
12899
12030
  let latestRuntimeWorkspace = resumeMode && typeof existingRunRecord?.worktreePath === "string" ? existingRunRecord.worktreePath : null;
12900
- let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve23(existingRunRecord.sessionPath, "..") : null;
12031
+ let latestSessionDir = resumeMode && typeof existingRunRecord?.sessionPath === "string" ? resolve22(existingRunRecord.sessionPath, "..") : null;
12901
12032
  let latestLogsDir = resumeMode && typeof existingRunRecord?.logRoot === "string" ? existingRunRecord.logRoot : null;
12902
12033
  let latestProviderCommand = null;
12903
12034
  let latestRuntimeBranch = resumeMode && typeof existingRunRecord?.branch === "string" ? existingRunRecord.branch : null;
@@ -12983,10 +12114,10 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
12983
12114
  setRunStatusOrFail(context.projectRoot, input.runId, "running");
12984
12115
  patchAuthorityRun(context.projectRoot, input.runId, {
12985
12116
  worktreePath: latestRuntimeWorkspace,
12986
- artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve23(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
12117
+ artifactRoot: latestRuntimeWorkspace && input.taskId ? resolve22(latestRuntimeWorkspace, "artifacts", input.taskId) : null,
12987
12118
  logRoot: latestLogsDir,
12988
- sessionPath: latestSessionDir ? resolve23(latestSessionDir, "session.json") : null,
12989
- sessionLogPath: latestLogsDir ? resolve23(latestLogsDir, "agent-stdout.log") : null,
12119
+ sessionPath: latestSessionDir ? resolve22(latestSessionDir, "session.json") : null,
12120
+ sessionLogPath: latestLogsDir ? resolve22(latestLogsDir, "agent-stdout.log") : null,
12990
12121
  branch: runtimeId
12991
12122
  });
12992
12123
  if (!dirtyBaselineApplied && input.baselineMode === "dirty-snapshot" && latestRuntimeWorkspace) {
@@ -12994,8 +12125,8 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
12994
12125
  const dirty = applyDirtyBaselineSnapshot({ sourceRoot: context.projectRoot, targetRoot: latestRuntimeWorkspace });
12995
12126
  const readyFile = childEnv.RIG_DIRTY_BASELINE_READY_FILE;
12996
12127
  if (readyFile) {
12997
- mkdirSync11(resolve23(readyFile, ".."), { recursive: true });
12998
- writeFileSync9(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
12128
+ mkdirSync9(resolve22(readyFile, ".."), { recursive: true });
12129
+ writeFileSync7(readyFile, `${JSON.stringify({ ...dirty, workspaceDir: latestRuntimeWorkspace, appliedAt: new Date().toISOString() }, null, 2)}
12999
12130
  `, "utf8");
13000
12131
  }
13001
12132
  appendRunLog(context.projectRoot, input.runId, {
@@ -13391,7 +12522,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
13391
12522
  let acceptedArtifactObservedAt = null;
13392
12523
  let acceptedArtifactPollTimer = null;
13393
12524
  let acceptedArtifactKillTimer = null;
13394
- const attemptExit = await new Promise((resolve24) => {
12525
+ const attemptExit = await new Promise((resolve23) => {
13395
12526
  let settled = false;
13396
12527
  const settle = (result) => {
13397
12528
  if (settled)
@@ -13399,7 +12530,7 @@ ${planningClassification.planningRequired ? `Before implementing, write a concis
13399
12530
  settled = true;
13400
12531
  if (acceptedArtifactPollTimer)
13401
12532
  clearInterval(acceptedArtifactPollTimer);
13402
- resolve24(result);
12533
+ resolve23(result);
13403
12534
  };
13404
12535
  const pollAcceptedArtifacts = () => {
13405
12536
  const artifactState = readTaskRunAcceptedArtifactState({
@@ -13602,7 +12733,7 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
13602
12733
  }
13603
12734
  if (planningClassification.planningRequired) {
13604
12735
  const planWorkspace = latestRuntimeWorkspace ?? context.projectRoot;
13605
- const expectedPlanPath = resolve23(planWorkspace, planningArtifactPath);
12736
+ const expectedPlanPath = resolve22(planWorkspace, planningArtifactPath);
13606
12737
  if (!existsSync15(expectedPlanPath)) {
13607
12738
  const failedAt = new Date().toISOString();
13608
12739
  const failureDetail = `Planning was required (${planningClassification.reason}) but ${planningArtifactPath} was not written before implementation completed.`;
@@ -13772,9 +12903,9 @@ Failed to update task source for ${input.taskId ?? runtimeTaskId} to failed: ${e
13772
12903
  });
13773
12904
  emitServerRunEvent({ type: "log", runId: input.runId, title: "Pi PR feedback fix stderr" });
13774
12905
  });
13775
- const exitCode = await new Promise((resolve24) => {
13776
- child.once("error", () => resolve24(1));
13777
- child.once("close", (code) => resolve24(code ?? 1));
12906
+ const exitCode = await new Promise((resolve23) => {
12907
+ child.once("error", () => resolve23(1));
12908
+ child.once("close", (code) => resolve23(code ?? 1));
13778
12909
  });
13779
12910
  for (const pendingLog of flushPendingClaudeToolUseLogs({
13780
12911
  runId: input.runId,
@@ -13915,8 +13046,8 @@ async function executeTest(context, args) {
13915
13046
  init_runner();
13916
13047
  init__parsers();
13917
13048
  init__paths();
13918
- import { existsSync as existsSync16, mkdirSync as mkdirSync12, readdirSync as readdirSync3, writeFileSync as writeFileSync10 } from "fs";
13919
- import { resolve as resolve24 } from "path";
13049
+ import { existsSync as existsSync16, mkdirSync as mkdirSync10, readdirSync as readdirSync3, writeFileSync as writeFileSync8 } from "fs";
13050
+ import { resolve as resolve23 } from "path";
13920
13051
  import { createPluginHost } from "@rig/core";
13921
13052
  import {
13922
13053
  isSupportedBunVersion as isSupportedBunVersion2,
@@ -13971,12 +13102,12 @@ function runSetupInit(projectRoot) {
13971
13102
  const stateDir = resolveControlPlaneHostStateDir(projectRoot);
13972
13103
  const logsDir = resolveControlPlaneHostLogsDir(projectRoot);
13973
13104
  const artifactsDir = resolveControlPlaneArtifactsDir(projectRoot);
13974
- mkdirSync12(stateDir, { recursive: true });
13975
- mkdirSync12(logsDir, { recursive: true });
13976
- mkdirSync12(artifactsDir, { recursive: true });
13977
- const failuresPath = resolve24(stateDir, "failed_approaches.md");
13105
+ mkdirSync10(stateDir, { recursive: true });
13106
+ mkdirSync10(logsDir, { recursive: true });
13107
+ mkdirSync10(artifactsDir, { recursive: true });
13108
+ const failuresPath = resolve23(stateDir, "failed_approaches.md");
13978
13109
  if (!existsSync16(failuresPath)) {
13979
- writeFileSync10(failuresPath, `# Failed Approaches
13110
+ writeFileSync8(failuresPath, `# Failed Approaches
13980
13111
 
13981
13112
  `, "utf-8");
13982
13113
  }
@@ -13993,17 +13124,17 @@ async function runSetupCheck(projectRoot, outputMode = "text") {
13993
13124
  }
13994
13125
  async function runSetupPreflight(projectRoot, outputMode = "text") {
13995
13126
  await runSetupCheck(projectRoot, outputMode);
13996
- const validationRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
13127
+ const validationRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "validation");
13997
13128
  if (existsSync16(validationRoot)) {
13998
13129
  const validators = readdirSync3(validationRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory());
13999
13130
  for (const validator of validators) {
14000
- const script = resolve24(validationRoot, validator.name, "validate.sh");
13131
+ const script = resolve23(validationRoot, validator.name, "validate.sh");
14001
13132
  if (existsSync16(script)) {
14002
13133
  console.log(`OK: validator script ${script}`);
14003
13134
  }
14004
13135
  }
14005
13136
  }
14006
- const hooksRoot = resolve24(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
13137
+ const hooksRoot = resolve23(resolveControlPlaneDefinitionRoot(projectRoot), "hooks");
14007
13138
  if (existsSync16(hooksRoot)) {
14008
13139
  const hooks = readdirSync3(hooksRoot).filter((name) => name.endsWith(".sh"));
14009
13140
  for (const hook of hooks) {
@@ -14150,7 +13281,7 @@ var PROJECT_REQUIRED_GROUPS = new Set([
14150
13281
  ]);
14151
13282
  var RIG_CONFIG_FILENAMES = ["rig.config.ts", "rig.config.mts", "rig.config.json"];
14152
13283
  function hasInitializedRigProject(projectRoot) {
14153
- return RIG_CONFIG_FILENAMES.some((name) => existsSync18(resolve25(projectRoot, name))) || existsSync18(resolve25(projectRoot, ".rig"));
13284
+ return RIG_CONFIG_FILENAMES.some((name) => existsSync18(resolve24(projectRoot, name))) || existsSync18(resolve24(projectRoot, ".rig"));
14154
13285
  }
14155
13286
  function requireInitializedRigProject(context, group) {
14156
13287
  if (hasInitializedRigProject(context.projectRoot)) {
@@ -14204,7 +13335,7 @@ function resolveTopLevelLaunchState(context) {
14204
13335
  let selectedServer = null;
14205
13336
  if (projectInitialized) {
14206
13337
  try {
14207
- const statePath = resolve25(context.projectRoot, ".rig", "state", "connection.json");
13338
+ const statePath = resolve24(context.projectRoot, ".rig", "state", "connection.json");
14208
13339
  if (existsSync18(statePath)) {
14209
13340
  const parsed = JSON.parse(readFileSync13(statePath, "utf-8"));
14210
13341
  selectedServer = parsed.remoteUrl || parsed.url || parsed.selected || null;
@@ -14213,14 +13344,8 @@ function resolveTopLevelLaunchState(context) {
14213
13344
  }
14214
13345
  return { projectInitialized, selectedServer, version: process.env.RIG_CLI_VERSION || readBuildConfig().RIG_CLI_VERSION || undefined };
14215
13346
  }
14216
- function envTruthy(value) {
14217
- if (!value)
14218
- return false;
14219
- const normalized = value.trim().toLowerCase();
14220
- return normalized !== "0" && normalized !== "false" && normalized !== "no";
14221
- }
14222
13347
  function shouldOpenApp(context) {
14223
- return context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1" && process.env.RIG_PLAIN !== "1" && !envTruthy(process.env.CI);
13348
+ return context.outputMode === "text" && Boolean(process.stdin.isTTY && process.stdout.isTTY) && process.env.RIG_CLI_PLAIN_HELP !== "1";
14224
13349
  }
14225
13350
  async function openApp(context, options = {}) {
14226
13351
  const { runOperatorBoardLoop: runOperatorBoardLoop2 } = await Promise.resolve().then(() => (init_board(), exports_board));