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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/dist/bin/build-rig-binaries.js +40 -8
  2. package/dist/bin/rig.js +23402 -14577
  3. package/dist/src/app/board.js +217 -41
  4. package/dist/src/app-opentui/adapters/command.d.ts +2 -0
  5. package/dist/src/app-opentui/adapters/command.js +329 -0
  6. package/dist/src/app-opentui/adapters/common.js +2 -2
  7. package/dist/src/app-opentui/adapters/doctor.d.ts +0 -2
  8. package/dist/src/app-opentui/adapters/doctor.js +64 -39
  9. package/dist/src/app-opentui/adapters/family.d.ts +62 -0
  10. package/dist/src/app-opentui/adapters/family.js +14305 -0
  11. package/dist/src/app-opentui/adapters/fleet.d.ts +0 -2
  12. package/dist/src/app-opentui/adapters/fleet.js +90 -60
  13. package/dist/src/app-opentui/adapters/inbox.d.ts +12 -2
  14. package/dist/src/app-opentui/adapters/inbox.js +137 -78
  15. package/dist/src/app-opentui/adapters/init.d.ts +0 -2
  16. package/dist/src/app-opentui/adapters/init.js +85 -47
  17. package/dist/src/app-opentui/adapters/inspect.d.ts +52 -0
  18. package/dist/src/app-opentui/adapters/inspect.js +1024 -0
  19. package/dist/src/app-opentui/adapters/pi-attach.d.ts +15 -6
  20. package/dist/src/app-opentui/adapters/pi-attach.js +442 -125
  21. package/dist/src/app-opentui/adapters/pi.d.ts +23 -0
  22. package/dist/src/app-opentui/adapters/pi.js +363 -0
  23. package/dist/src/app-opentui/adapters/plugin.d.ts +84 -0
  24. package/dist/src/app-opentui/adapters/plugin.js +544 -0
  25. package/dist/src/app-opentui/adapters/repo.d.ts +37 -0
  26. package/dist/src/app-opentui/adapters/repo.js +186 -0
  27. package/dist/src/app-opentui/adapters/run-detail.d.ts +9 -2
  28. package/dist/src/app-opentui/adapters/run-detail.js +180 -63
  29. package/dist/src/app-opentui/adapters/server.d.ts +10 -2
  30. package/dist/src/app-opentui/adapters/server.js +191 -45
  31. package/dist/src/app-opentui/adapters/tasks.d.ts +11 -2
  32. package/dist/src/app-opentui/adapters/tasks.js +1123 -143
  33. package/dist/src/app-opentui/adapters/workspace.d.ts +49 -0
  34. package/dist/src/app-opentui/adapters/workspace.js +333 -0
  35. package/dist/src/app-opentui/autocomplete.d.ts +20 -0
  36. package/dist/src/app-opentui/autocomplete.js +576 -0
  37. package/dist/src/app-opentui/bootstrap.d.ts +1 -6
  38. package/dist/src/app-opentui/bootstrap.js +25252 -16474
  39. package/dist/src/app-opentui/command-palette.d.ts +3 -0
  40. package/dist/src/app-opentui/command-palette.js +1010 -0
  41. package/dist/src/app-opentui/command-pty-host.d.ts +62 -0
  42. package/dist/src/app-opentui/command-pty-host.js +248 -0
  43. package/dist/src/app-opentui/drone.js +8 -6
  44. package/dist/src/app-opentui/events.js +1 -1
  45. package/dist/src/app-opentui/fleet-stats.d.ts +32 -0
  46. package/dist/src/app-opentui/fleet-stats.js +114 -0
  47. package/dist/src/app-opentui/focus-manager.d.ts +14 -0
  48. package/dist/src/app-opentui/focus-manager.js +24 -0
  49. package/dist/src/app-opentui/index.js +5431 -2797
  50. package/dist/src/app-opentui/intent.js +179 -50
  51. package/dist/src/app-opentui/keymap.d.ts +21 -0
  52. package/dist/src/app-opentui/keymap.js +1748 -0
  53. package/dist/src/app-opentui/launch-routing.d.ts +16 -0
  54. package/dist/src/app-opentui/launch-routing.js +55 -0
  55. package/dist/src/app-opentui/layout.d.ts +7 -0
  56. package/dist/src/app-opentui/layout.js +13 -6
  57. package/dist/src/app-opentui/list-search.d.ts +24 -0
  58. package/dist/src/app-opentui/list-search.js +88 -1
  59. package/dist/src/app-opentui/pi-host-child.js +99 -17
  60. package/dist/src/app-opentui/pi-pty-host.d.ts +14 -0
  61. package/dist/src/app-opentui/pi-pty-host.js +30 -14
  62. package/dist/src/app-opentui/react/App.d.ts +9 -0
  63. package/dist/src/app-opentui/react/App.js +5144 -0
  64. package/dist/src/app-opentui/react/Backdrop.d.ts +5 -0
  65. package/dist/src/app-opentui/react/Backdrop.js +1834 -0
  66. package/dist/src/app-opentui/react/ChromeHost.d.ts +5 -0
  67. package/dist/src/app-opentui/react/ChromeHost.js +2942 -0
  68. package/dist/src/app-opentui/react/SceneFrameView.d.ts +7 -0
  69. package/dist/src/app-opentui/react/SceneFrameView.js +529 -0
  70. package/dist/src/app-opentui/react/context.d.ts +17 -0
  71. package/dist/src/app-opentui/react/context.js +37 -0
  72. package/dist/src/app-opentui/react/launch.d.ts +2 -0
  73. package/dist/src/app-opentui/react/launch.js +5743 -0
  74. package/dist/src/app-opentui/react/nav.d.ts +18 -0
  75. package/dist/src/app-opentui/react/nav.js +54 -0
  76. package/dist/src/app-opentui/react/scroll.d.ts +12 -0
  77. package/dist/src/app-opentui/react/scroll.js +21 -0
  78. package/dist/src/app-opentui/react/syntax.d.ts +2 -0
  79. package/dist/src/app-opentui/react/syntax.js +64 -0
  80. package/dist/src/app-opentui/registry.js +20428 -4828
  81. package/dist/src/app-opentui/render/ascii-fleet.d.ts +15 -0
  82. package/dist/src/app-opentui/render/ascii-fleet.js +82 -0
  83. package/dist/src/app-opentui/render/constants.d.ts +31 -0
  84. package/dist/src/app-opentui/render/constants.js +66 -0
  85. package/dist/src/app-opentui/render/graphics.d.ts +2 -1
  86. package/dist/src/app-opentui/render/graphics.js +228 -46
  87. package/dist/src/app-opentui/render/image-visual-layer-worker.js +469 -930
  88. package/dist/src/app-opentui/render/image-visual-layer.d.ts +25 -10
  89. package/dist/src/app-opentui/render/image-visual-layer.js +448 -329
  90. package/dist/src/app-opentui/render/native-host.d.ts +37 -0
  91. package/dist/src/app-opentui/render/native-host.js +179 -0
  92. package/dist/src/app-opentui/render/panel-layout.d.ts +38 -0
  93. package/dist/src/app-opentui/render/panel-layout.js +48 -0
  94. package/dist/src/app-opentui/render/panels.d.ts +2 -0
  95. package/dist/src/app-opentui/render/panels.js +78 -38
  96. package/dist/src/app-opentui/render/preloader.d.ts +10 -0
  97. package/dist/src/app-opentui/render/preloader.js +165 -0
  98. package/dist/src/app-opentui/render/scene.d.ts +53 -1
  99. package/dist/src/app-opentui/render/scene.js +195 -6
  100. package/dist/src/app-opentui/render/text.d.ts +7 -1
  101. package/dist/src/app-opentui/render/text.js +15 -8
  102. package/dist/src/app-opentui/render/type-bar.d.ts +2 -1
  103. package/dist/src/app-opentui/render/type-bar.js +113 -39
  104. package/dist/src/app-opentui/runtime-resources.d.ts +16 -0
  105. package/dist/src/app-opentui/runtime-resources.js +62 -0
  106. package/dist/src/app-opentui/runtime.d.ts +44 -1
  107. package/dist/src/app-opentui/runtime.js +5415 -2738
  108. package/dist/src/app-opentui/scenes/command.d.ts +3 -0
  109. package/dist/src/app-opentui/scenes/command.js +117 -0
  110. package/dist/src/app-opentui/scenes/doctor.d.ts +2 -1
  111. package/dist/src/app-opentui/scenes/doctor.js +221 -17
  112. package/dist/src/app-opentui/scenes/error.js +60 -20
  113. package/dist/src/app-opentui/scenes/family-domains/agent.d.ts +2 -0
  114. package/dist/src/app-opentui/scenes/family-domains/agent.js +348 -0
  115. package/dist/src/app-opentui/scenes/family-domains/browser.d.ts +2 -0
  116. package/dist/src/app-opentui/scenes/family-domains/browser.js +195 -0
  117. package/dist/src/app-opentui/scenes/family-domains/dist.d.ts +2 -0
  118. package/dist/src/app-opentui/scenes/family-domains/dist.js +243 -0
  119. package/dist/src/app-opentui/scenes/family-domains/git.d.ts +2 -0
  120. package/dist/src/app-opentui/scenes/family-domains/git.js +195 -0
  121. package/dist/src/app-opentui/scenes/family-domains/github.d.ts +2 -0
  122. package/dist/src/app-opentui/scenes/family-domains/github.js +274 -0
  123. package/dist/src/app-opentui/scenes/family-domains/harness.d.ts +2 -0
  124. package/dist/src/app-opentui/scenes/family-domains/harness.js +152 -0
  125. package/dist/src/app-opentui/scenes/family-domains/index.d.ts +4 -0
  126. package/dist/src/app-opentui/scenes/family-domains/index.js +1679 -0
  127. package/dist/src/app-opentui/scenes/family-domains/kit.d.ts +76 -0
  128. package/dist/src/app-opentui/scenes/family-domains/kit.js +305 -0
  129. package/dist/src/app-opentui/scenes/family-domains/profile.d.ts +2 -0
  130. package/dist/src/app-opentui/scenes/family-domains/profile.js +212 -0
  131. package/dist/src/app-opentui/scenes/family-domains/queue.d.ts +2 -0
  132. package/dist/src/app-opentui/scenes/family-domains/queue.js +146 -0
  133. package/dist/src/app-opentui/scenes/family-domains/remote.d.ts +2 -0
  134. package/dist/src/app-opentui/scenes/family-domains/remote.js +518 -0
  135. package/dist/src/app-opentui/scenes/family-domains/review.d.ts +2 -0
  136. package/dist/src/app-opentui/scenes/family-domains/review.js +280 -0
  137. package/dist/src/app-opentui/scenes/family-domains/setup.d.ts +2 -0
  138. package/dist/src/app-opentui/scenes/family-domains/setup.js +267 -0
  139. package/dist/src/app-opentui/scenes/family-domains/stats.d.ts +2 -0
  140. package/dist/src/app-opentui/scenes/family-domains/stats.js +370 -0
  141. package/dist/src/app-opentui/scenes/family.d.ts +3 -0
  142. package/dist/src/app-opentui/scenes/family.js +2144 -0
  143. package/dist/src/app-opentui/scenes/fleet.js +552 -43
  144. package/dist/src/app-opentui/scenes/handoff.js +342 -35
  145. package/dist/src/app-opentui/scenes/help.js +640 -56
  146. package/dist/src/app-opentui/scenes/inbox.d.ts +2 -1
  147. package/dist/src/app-opentui/scenes/inbox.js +329 -21
  148. package/dist/src/app-opentui/scenes/init.d.ts +2 -1
  149. package/dist/src/app-opentui/scenes/init.js +120 -34
  150. package/dist/src/app-opentui/scenes/inspect.d.ts +3 -0
  151. package/dist/src/app-opentui/scenes/inspect.js +793 -0
  152. package/dist/src/app-opentui/scenes/main.d.ts +2 -1
  153. package/dist/src/app-opentui/scenes/main.js +264 -29
  154. package/dist/src/app-opentui/scenes/pi.d.ts +3 -0
  155. package/dist/src/app-opentui/scenes/pi.js +508 -0
  156. package/dist/src/app-opentui/scenes/plugin.d.ts +3 -0
  157. package/dist/src/app-opentui/scenes/plugin.js +486 -0
  158. package/dist/src/app-opentui/scenes/repo.d.ts +3 -0
  159. package/dist/src/app-opentui/scenes/repo.js +424 -0
  160. package/dist/src/app-opentui/scenes/run-detail.d.ts +2 -1
  161. package/dist/src/app-opentui/scenes/run-detail.js +362 -35
  162. package/dist/src/app-opentui/scenes/server.d.ts +2 -1
  163. package/dist/src/app-opentui/scenes/server.js +243 -26
  164. package/dist/src/app-opentui/scenes/tasks.js +518 -41
  165. package/dist/src/app-opentui/scenes/workspace.d.ts +3 -0
  166. package/dist/src/app-opentui/scenes/workspace.js +426 -0
  167. package/dist/src/app-opentui/selectable.d.ts +19 -0
  168. package/dist/src/app-opentui/selectable.js +79 -0
  169. package/dist/src/app-opentui/state.js +129 -36
  170. package/dist/src/app-opentui/surface-catalog.d.ts +20 -0
  171. package/dist/src/app-opentui/surface-catalog.js +540 -0
  172. package/dist/src/app-opentui/terminal-capabilities.d.ts +7 -0
  173. package/dist/src/app-opentui/terminal-capabilities.js +15 -0
  174. package/dist/src/app-opentui/theme.d.ts +28 -6
  175. package/dist/src/app-opentui/theme.js +61 -8
  176. package/dist/src/app-opentui/types.d.ts +130 -5
  177. package/dist/src/commands/_authority-runs.d.ts +1 -1
  178. package/dist/src/commands/_authority-runs.js +2 -12
  179. package/dist/src/commands/_doctor-checks.js +62 -13
  180. package/dist/src/commands/_help-catalog.js +95 -15
  181. package/dist/src/commands/_operator-view.js +97 -15
  182. package/dist/src/commands/_pi-frontend.d.ts +2 -0
  183. package/dist/src/commands/_pi-frontend.js +97 -13
  184. package/dist/src/commands/_preflight.js +64 -14
  185. package/dist/src/commands/_server-client.js +82 -18
  186. package/dist/src/commands/_server-events.d.ts +26 -0
  187. package/dist/src/commands/_server-events.js +310 -0
  188. package/dist/src/commands/_snapshot-upload.js +62 -13
  189. package/dist/src/commands/agent.js +2 -12
  190. package/dist/src/commands/connect.js +7 -1
  191. package/dist/src/commands/doctor.js +62 -13
  192. package/dist/src/commands/github.js +144 -23
  193. package/dist/src/commands/inbox.js +62 -13
  194. package/dist/src/commands/init.js +82 -18
  195. package/dist/src/commands/inspect.js +62 -13
  196. package/dist/src/commands/run.js +100 -15
  197. package/dist/src/commands/server.js +71 -26
  198. package/dist/src/commands/setup.js +62 -13
  199. package/dist/src/commands/stats.js +157 -28
  200. package/dist/src/commands/task-run-driver.js +64 -25
  201. package/dist/src/commands/task.js +196 -43
  202. package/dist/src/commands.js +419 -123
  203. package/dist/src/index.js +426 -130
  204. package/package.json +11 -10
  205. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.d.ts +0 -2
  206. package/dist/src/app-opentui/render/image-visual-layer-native-canvas.js +0 -1484
@@ -14,6 +14,7 @@ var __export = (target, all) => {
14
14
  });
15
15
  };
16
16
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
17
+ var __require = import.meta.require;
17
18
 
18
19
  // packages/cli/src/runner.ts
19
20
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
@@ -34,6 +35,19 @@ var init_runner = __esm(() => {
34
35
  });
35
36
 
36
37
  // packages/cli/src/commands/_connection-state.ts
38
+ var exports__connection_state = {};
39
+ __export(exports__connection_state, {
40
+ writeRepoServerProjectRoot: () => writeRepoServerProjectRoot,
41
+ writeRepoConnection: () => writeRepoConnection,
42
+ writeGlobalConnections: () => writeGlobalConnections,
43
+ upsertGlobalConnection: () => upsertGlobalConnection,
44
+ resolveSelectedConnection: () => resolveSelectedConnection,
45
+ resolveRepoConnectionPath: () => resolveRepoConnectionPath,
46
+ resolveGlobalConnectionsPath: () => resolveGlobalConnectionsPath,
47
+ readRepoConnection: () => readRepoConnection,
48
+ readGlobalConnections: () => readGlobalConnections,
49
+ isRemoteConnectionSelected: () => isRemoteConnectionSelected
50
+ });
37
51
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
38
52
  import { homedir } from "os";
39
53
  import { dirname, resolve } from "path";
@@ -92,6 +106,18 @@ function readGlobalConnections(options = {}) {
92
106
  }
93
107
  return { connections };
94
108
  }
109
+ function writeGlobalConnections(state, options = {}) {
110
+ writeJsonFile(resolveGlobalConnectionsPath(options.env ?? process.env), state);
111
+ }
112
+ function upsertGlobalConnection(alias, connection, options = {}) {
113
+ const cleanAlias = alias.trim();
114
+ if (!cleanAlias)
115
+ throw new CliError("Connection alias is required.", 1, { hint: "Save a server with `rig server add <alias> <url>`." });
116
+ const state = readGlobalConnections(options);
117
+ state.connections[cleanAlias] = connection;
118
+ writeGlobalConnections(state, options);
119
+ return state;
120
+ }
95
121
  function readRepoConnection(projectRoot) {
96
122
  const payload = readJsonFile(resolveRepoConnectionPath(projectRoot));
97
123
  if (!payload || typeof payload !== "object" || Array.isArray(payload))
@@ -129,6 +155,9 @@ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
129
155
  return;
130
156
  writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
131
157
  }
158
+ function isRemoteConnectionSelected(projectRoot) {
159
+ return resolveSelectedConnection(projectRoot)?.connection.kind === "remote";
160
+ }
132
161
  var init__connection_state = __esm(() => {
133
162
  init_runner();
134
163
  });
@@ -192,17 +221,21 @@ function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
192
221
  const scopedKey = resolve2(projectRoot ?? process.cwd());
193
222
  scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
194
223
  }
195
- function readPrivateRemoteSessionToken(projectRoot) {
224
+ function readRemoteAuthState(projectRoot) {
196
225
  const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
197
226
  if (!existsSync2(path))
198
227
  return null;
199
228
  try {
200
229
  const parsed = JSON.parse(readFileSync2(path, "utf8"));
201
- return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
230
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
202
231
  } catch {
203
232
  return null;
204
233
  }
205
234
  }
235
+ function readPrivateRemoteSessionToken(projectRoot) {
236
+ const parsed = readRemoteAuthState(projectRoot);
237
+ return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
238
+ }
206
239
  function readGitHubBearerTokenForRemote(projectRoot) {
207
240
  const scopedKey = resolve2(projectRoot);
208
241
  if (scopedGitHubBearerTokens.has(scopedKey))
@@ -213,15 +246,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
213
246
  return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
214
247
  }
215
248
  function readStoredGitHubAuthToken(projectRoot) {
216
- const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
217
- if (!existsSync2(path))
249
+ const parsed = readRemoteAuthState(projectRoot);
250
+ return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
251
+ }
252
+ function inferRemoteServerProjectRootFromAuthState(projectRoot) {
253
+ const repo = readRepoConnection(projectRoot);
254
+ const slug = repo?.project?.trim();
255
+ if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
218
256
  return null;
219
- try {
220
- const parsed = JSON.parse(readFileSync2(path, "utf8"));
221
- return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
222
- } catch {
257
+ const auth = readRemoteAuthState(projectRoot);
258
+ const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
259
+ const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
260
+ if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
223
261
  return null;
224
- }
262
+ const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
263
+ if (!checkoutBaseDir)
264
+ return null;
265
+ const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
266
+ writeRepoServerProjectRoot(projectRoot, inferred);
267
+ return inferred;
225
268
  }
226
269
  function readLocalConnectionFallbackToken(projectRoot) {
227
270
  return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
@@ -232,7 +275,7 @@ async function ensureServerForCli(projectRoot) {
232
275
  if (selected?.connection.kind === "remote") {
233
276
  reportServerPhase(`Connecting to ${selected.alias}\u2026`);
234
277
  const authToken = readGitHubBearerTokenForRemote(projectRoot);
235
- const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
278
+ const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
236
279
  return {
237
280
  baseUrl: selected.connection.baseUrl,
238
281
  authToken,
@@ -261,7 +304,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
261
304
  if (!slug)
262
305
  return null;
263
306
  try {
264
- const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
307
+ const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
308
+ if (authToken && queryAuthFallbackEnabled())
309
+ url.searchParams.set("rt", authToken);
310
+ const response = await fetch(url, {
265
311
  headers: mergeHeaders(undefined, authToken)
266
312
  });
267
313
  if (!response.ok)
@@ -288,10 +334,23 @@ function appendTaskFilterParams(url, filters) {
288
334
  if (filters.limit !== undefined)
289
335
  url.searchParams.set("limit", String(filters.limit));
290
336
  }
337
+ function mergeCookie(existing, name, value) {
338
+ const encoded = `${name}=${encodeURIComponent(value)}`;
339
+ if (!existing?.trim())
340
+ return encoded;
341
+ const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
342
+ return [...parts, encoded].join("; ");
343
+ }
344
+ function queryAuthFallbackEnabled(env = process.env) {
345
+ return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
346
+ }
291
347
  function mergeHeaders(headers, authToken) {
292
348
  const merged = new Headers(headers);
293
349
  if (authToken) {
294
- merged.set("authorization", `Bearer ${authToken}`);
350
+ const bearer = `Bearer ${authToken}`;
351
+ merged.set("authorization", bearer);
352
+ merged.set("x-auth", bearer);
353
+ merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
295
354
  }
296
355
  return merged;
297
356
  }
@@ -351,15 +410,34 @@ async function buildServerFailureContext(projectRoot, server) {
351
410
  hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
352
411
  };
353
412
  }
413
+ function isLoopbackRemoteBaseUrl(baseUrl) {
414
+ try {
415
+ const host = new URL(baseUrl).hostname.toLowerCase();
416
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
417
+ } catch {
418
+ return false;
419
+ }
420
+ }
421
+ function canUseRemoteWithoutProjectRoot(pathname) {
422
+ 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/");
423
+ }
354
424
  async function requestServerJson(context, pathname, init = {}) {
355
425
  const server = await ensureServerForCli(context.projectRoot);
426
+ const requestUrl = new URL(`${server.baseUrl}${pathname}`);
427
+ if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
428
+ const repo = readRepoConnection(context.projectRoot);
429
+ throw new CliError(`Remote server is selected for ${repo?.project ?? "this repo"}, but this checkout has no server-host project root link.`, 1, { hint: "Run `rig init --repair` or `rig init --yes --repo owner/repo --server remote` to repair the remote project link before task/run commands." });
430
+ }
356
431
  const headers = mergeHeaders(init.headers, server.authToken);
357
432
  if (server.serverProjectRoot)
358
433
  headers.set("x-rig-project-root", server.serverProjectRoot);
434
+ if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
435
+ requestUrl.searchParams.set("rt", server.authToken);
436
+ }
359
437
  reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
360
438
  let response;
361
439
  try {
362
- response = await fetch(`${server.baseUrl}${pathname}`, {
440
+ response = await fetch(requestUrl, {
363
441
  ...init,
364
442
  headers
365
443
  });
@@ -421,11 +499,26 @@ async function getGitHubAuthStatusViaServer(context) {
421
499
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
422
500
  }
423
501
  async function postGitHubTokenViaServer(context, token, options = {}) {
424
- const payload = await requestServerJson(context, "/api/github/auth/token", {
425
- method: "POST",
426
- headers: { "content-type": "application/json" },
427
- body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot })
428
- });
502
+ const server = await ensureServerForCli(context.projectRoot);
503
+ const requestUrl = new URL(`${server.baseUrl}/api/github/auth/token`);
504
+ reportServerPhase("POST /api/github/auth/token\u2026");
505
+ let response;
506
+ try {
507
+ response = await fetch(requestUrl, {
508
+ method: "POST",
509
+ headers: { "content-type": "application/json" },
510
+ body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot ?? server.serverProjectRoot ?? undefined })
511
+ });
512
+ } catch (error) {
513
+ const failure = await buildServerFailureContext(context.projectRoot, server);
514
+ throw new CliError(`Rig server auth bootstrap failed: ${error instanceof Error ? error.message : String(error)}
515
+ ${failure.contextLine}`, 1, { hint: failure.hint });
516
+ }
517
+ const payload = await response.json().catch(() => null);
518
+ if (!response.ok) {
519
+ const detail = payload && typeof payload === "object" && !Array.isArray(payload) ? String(payload.error ?? JSON.stringify(payload)) : `HTTP ${response.status}`;
520
+ 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`." });
521
+ }
429
522
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
430
523
  }
431
524
  async function prepareRemoteCheckoutViaServer(context, input) {
@@ -703,20 +796,11 @@ var init__server_client = __esm(() => {
703
796
  });
704
797
 
705
798
  // packages/cli/src/app-opentui/adapters/common.ts
706
- function adapterContextFromRuntime(runtime, renderer) {
707
- return {
708
- projectRoot: runtime.getState().projectRoot,
709
- renderer,
710
- ensureRuntime: () => runtime.getRunnerContext(),
711
- emit: (event) => runtime.emit(event),
712
- getState: () => runtime.getState()
713
- };
714
- }
715
799
  function projectRootOf(ctx) {
716
800
  const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
717
801
  if (typeof root === "string" && root.trim())
718
802
  return root;
719
- throw new Error("Rig app adapter requires a projectRoot.");
803
+ throw new Error("App adapter requires a projectRoot.");
720
804
  }
721
805
  function emitStarted(ctx, label, optimistic) {
722
806
  ctx.emit({ type: "action.started", label, ...optimistic ? { optimistic } : {} });
@@ -735,36 +819,98 @@ function patchFooter(ctx, footer) {
735
819
  }
736
820
 
737
821
  // packages/cli/src/app-opentui/adapters/server.ts
738
- function createServerAdapter() {
739
- return {
740
- id: "server",
741
- async handleIntent(runtime, intent) {
742
- if (intent.scene !== "server")
743
- return false;
744
- if (intent.action.kind === "refresh" || intent.action.kind === "navigate") {
745
- await refreshServerStatus(adapterContextFromRuntime(runtime));
746
- return true;
822
+ var SERVER_PROBE_TIMEOUT_MS = Number(process.env.RIG_SERVER_PROBE_TIMEOUT_MS) || 5000;
823
+ function withTimeout(promise, ms, label) {
824
+ return new Promise((resolve3, reject) => {
825
+ const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
826
+ promise.then((value) => {
827
+ clearTimeout(timer);
828
+ resolve3(value);
829
+ }, (error) => {
830
+ clearTimeout(timer);
831
+ reject(error);
832
+ });
833
+ });
834
+ }
835
+ async function withRetry(label, attempt, opts) {
836
+ const retries = opts?.retries ?? 1;
837
+ const baseDelayMs = opts?.baseDelayMs ?? 250;
838
+ let lastError;
839
+ for (let n = 0;n <= retries; n++) {
840
+ try {
841
+ return await attempt();
842
+ } catch (error) {
843
+ lastError = error;
844
+ if (n < retries) {
845
+ const delay = baseDelayMs * 2 ** n;
846
+ await new Promise((r) => setTimeout(r, delay));
747
847
  }
748
- return false;
749
848
  }
750
- };
849
+ }
850
+ throw lastError instanceof Error ? lastError : new Error(`${label} failed: ${String(lastError)}`);
851
+ }
852
+ function startLocalRequested(ctx) {
853
+ const intent = ctx.getState().data?.lastIntent;
854
+ if (!intent || typeof intent !== "object" || Array.isArray(intent))
855
+ return false;
856
+ const action = intent.action;
857
+ return action?.payload?.startLocal === true;
858
+ }
859
+ async function startLocalServerFromApp(ctx) {
860
+ const label = "Starting local server";
861
+ emitStarted(ctx, label);
862
+ patchData(ctx, {
863
+ lastIntent: undefined,
864
+ server: { label: "starting local server", reachable: false, error: "spawning local rig-server (detached)\u2026" }
865
+ });
866
+ try {
867
+ const projectRoot = projectRootOf(ctx);
868
+ emitProgress(ctx, label, "selecting local server for this repo");
869
+ const { writeRepoConnection: writeRepoConnection2, readRepoConnection: readRepoConnection2 } = await Promise.resolve().then(() => (init__connection_state(), exports__connection_state));
870
+ const previous = readRepoConnection2(projectRoot);
871
+ writeRepoConnection2(projectRoot, {
872
+ selected: "local",
873
+ ...previous?.project ? { project: previous.project } : {},
874
+ linkedAt: new Date().toISOString()
875
+ });
876
+ emitProgress(ctx, label, "spawning local rig-server (detached) and waiting for ready");
877
+ const { ensureLocalRigServerConnection: ensureLocalRigServerConnection2 } = await import("@rig/runtime/local-server");
878
+ const connection = await ensureLocalRigServerConnection2(projectRoot);
879
+ emitProgress(ctx, label, "local server ready", { baseUrl: connection.baseUrl });
880
+ emitCompleted(ctx, label, { baseUrl: connection.baseUrl });
881
+ return await refreshServerStatus(ctx);
882
+ } catch (error) {
883
+ const state = {
884
+ label: "local server failed to start",
885
+ reachable: false,
886
+ error: error instanceof Error ? error.message : String(error)
887
+ };
888
+ patchData(ctx, { server: state, lastRefreshError: state.error });
889
+ patchFooter(ctx, { server: "unavailable" });
890
+ emitCompleted(ctx, label, { server: state.label, reachable: false, error: state.error });
891
+ return state;
892
+ }
751
893
  }
752
894
  async function refreshServerStatus(ctx) {
895
+ if (startLocalRequested(ctx)) {
896
+ return startLocalServerFromApp(ctx);
897
+ }
753
898
  const label = "Checking server";
754
899
  emitStarted(ctx, label);
900
+ patchData(ctx, { server: { label: "checking selected server", reachable: false, error: "checking selected server\u2026" } });
755
901
  const started = Date.now();
756
902
  try {
757
903
  const { ensureServerForCli: ensureServerForCli2, requestServerJson: requestServerJson2, resolveServerConnectionLabel: resolveServerConnectionLabel2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
758
904
  const projectRoot = projectRootOf(ctx);
759
- emitProgress(ctx, label, "resolving selected Rig server");
905
+ emitProgress(ctx, label, "resolving selected server");
760
906
  const [connectionLabel, server] = await Promise.all([
761
907
  resolveServerConnectionLabel2(projectRoot),
762
- ensureServerForCli2(projectRoot)
908
+ withTimeout(ensureServerForCli2(projectRoot), 5000, "server connection")
763
909
  ]);
764
910
  emitProgress(ctx, label, "requesting server status", { baseUrl: server.baseUrl, kind: server.connectionKind });
765
911
  const [status, auth] = await Promise.all([
766
- requestServerJson2({ projectRoot }, "/api/server/status").catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) })),
767
- requestServerJson2({ projectRoot }, "/api/github/auth/status").catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }))
912
+ withRetry("server status", () => withTimeout(requestServerJson2({ projectRoot }, "/api/server/status"), SERVER_PROBE_TIMEOUT_MS, "server status")).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) })),
913
+ withRetry("github auth status", () => withTimeout(requestServerJson2({ projectRoot }, "/api/github/auth/status"), SERVER_PROBE_TIMEOUT_MS, "github auth status")).catch((error) => ({ ok: false, error: error instanceof Error ? error.message : String(error) }))
768
914
  ]);
769
915
  const state = {
770
916
  label: connectionLabel,
@@ -793,6 +939,6 @@ async function refreshServerStatus(ctx) {
793
939
  }
794
940
  }
795
941
  export {
796
- refreshServerStatus,
797
- createServerAdapter
942
+ startLocalServerFromApp,
943
+ refreshServerStatus
798
944
  };
@@ -1,6 +1,4 @@
1
- import type { AppAdapter } from "../types";
2
1
  import { type AppAdapterContext } from "./common";
3
- export declare function createTasksAdapter(): AppAdapter;
4
2
  export type AppTaskSort = "priority" | "recency" | "status" | "id";
5
3
  export type AppTaskFilters = {
6
4
  readonly preset?: "open" | "ready" | "blocked" | "closed" | "mine" | "all" | "custom";
@@ -11,6 +9,11 @@ export type AppTaskFilters = {
11
9
  readonly label?: string;
12
10
  readonly search?: string;
13
11
  };
12
+ export type AppTaskActiveRun = {
13
+ readonly runId: string;
14
+ readonly status?: string;
15
+ readonly stage?: string;
16
+ };
14
17
  export type AppTaskRecord = {
15
18
  readonly id: string;
16
19
  readonly status: string;
@@ -20,6 +23,7 @@ export type AppTaskRecord = {
20
23
  readonly createdAt?: string;
21
24
  readonly labels: readonly string[];
22
25
  readonly assignees: readonly string[];
26
+ readonly activeRun?: AppTaskActiveRun;
23
27
  readonly raw: Record<string, unknown>;
24
28
  };
25
29
  export type AppTaskViewState = {
@@ -31,6 +35,8 @@ export type AppTaskViewState = {
31
35
  readonly totalCount: number;
32
36
  readonly visibleCount: number;
33
37
  };
38
+ export declare function activeRunIdFromTaskLike(task: Record<string, unknown>): string | undefined;
39
+ export declare function activeRunIdFromTaskRunError(error: unknown): string | null;
34
40
  export declare function normalizeTaskRecord(record: Record<string, unknown>): AppTaskRecord | null;
35
41
  export declare function refreshTasks(ctx: AppAdapterContext, input?: AppTaskFilters & {
36
42
  readonly sort?: AppTaskSort | string;
@@ -40,6 +46,7 @@ export declare function submitTaskRun(ctx: AppAdapterContext, input?: {
40
46
  readonly title?: string;
41
47
  readonly initialPrompt?: string;
42
48
  readonly runId?: string;
49
+ readonly detach?: boolean;
43
50
  }): Promise<{
44
51
  runId: string;
45
52
  }>;
@@ -47,6 +54,8 @@ export declare function submitNextTaskRun(ctx: AppAdapterContext, filters?: {
47
54
  readonly assignee?: string;
48
55
  readonly state?: string;
49
56
  readonly status?: string;
57
+ }, options?: {
58
+ readonly detach?: boolean;
50
59
  }): Promise<{
51
60
  runId: string;
52
61
  task: AppTaskRecord | null;