@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
@@ -0,0 +1,186 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // packages/cli/src/app-opentui/adapters/common.ts
5
+ function projectRootOf(ctx) {
6
+ const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
7
+ if (typeof root === "string" && root.trim())
8
+ return root;
9
+ throw new Error("App adapter requires a projectRoot.");
10
+ }
11
+ function normalizeAppError(error) {
12
+ const message = error instanceof Error ? error.message : String(error);
13
+ const rawHint = error instanceof Error ? error.hint : undefined;
14
+ return {
15
+ message,
16
+ ...typeof rawHint === "string" && rawHint.trim() ? { hint: rawHint.trim() } : {}
17
+ };
18
+ }
19
+ function emitStarted(ctx, label, optimistic) {
20
+ ctx.emit({ type: "action.started", label, ...optimistic ? { optimistic } : {} });
21
+ }
22
+ function emitProgress(ctx, label, detail, data) {
23
+ ctx.emit({ type: "action.progress", label, ...detail ? { detail } : {}, ...data ? { data } : {} });
24
+ }
25
+ function emitCompleted(ctx, label, data) {
26
+ ctx.emit({ type: "action.completed", label, ...data ? { data } : {} });
27
+ }
28
+ function emitFailed(ctx, label, error, data) {
29
+ if (data)
30
+ patchData(ctx, data);
31
+ const normalized = normalizeAppError(error);
32
+ ctx.emit({
33
+ type: "action.failed",
34
+ label,
35
+ message: normalized.message,
36
+ ...normalized.hint ? { hint: normalized.hint } : {},
37
+ cause: error
38
+ });
39
+ }
40
+ function patchData(ctx, data) {
41
+ ctx.emit({ type: "data.patch", data });
42
+ }
43
+ function patchFooter(ctx, footer) {
44
+ ctx.emit({ type: "footer.patch", footer });
45
+ }
46
+ async function captureConsole(fn) {
47
+ const output = [];
48
+ const original = {
49
+ log: console.log,
50
+ info: console.info,
51
+ warn: console.warn,
52
+ error: console.error
53
+ };
54
+ const capture = (...parts) => {
55
+ output.push(parts.map((part) => typeof part === "string" ? part : JSON.stringify(part)).join(" "));
56
+ };
57
+ console.log = capture;
58
+ console.info = capture;
59
+ console.warn = capture;
60
+ console.error = capture;
61
+ try {
62
+ const result = await fn();
63
+ return { result, output };
64
+ } finally {
65
+ console.log = original.log;
66
+ console.info = original.info;
67
+ console.warn = original.warn;
68
+ console.error = original.error;
69
+ }
70
+ }
71
+
72
+ // packages/cli/src/app-opentui/adapters/repo.ts
73
+ function repoActionRequest(ctx) {
74
+ const intent = ctx.getState().intent;
75
+ const payload = intent?.action?.payload;
76
+ if (!payload)
77
+ return { kind: "none" };
78
+ if (payload.repoReset === true)
79
+ return { kind: "reset" };
80
+ const alias = payload.repoSync;
81
+ if (typeof alias === "string" && alias.trim())
82
+ return { kind: "sync", alias: alias.trim() };
83
+ return { kind: "none" };
84
+ }
85
+ function readRepoGitStatus(projectRoot, checkoutRoot, pinnedCommit, runCapture, existsSync, joinPath) {
86
+ const unavailable = { available: false, clean: false, dirtyCount: 0, head: "", branch: "", ahead: 0, behind: 0 };
87
+ if (!checkoutRoot || !existsSync(joinPath(checkoutRoot, ".git")))
88
+ return unavailable;
89
+ const porcelain = runCapture(["git", "-C", checkoutRoot, "status", "--porcelain"], projectRoot);
90
+ if (porcelain.exitCode !== 0)
91
+ return unavailable;
92
+ const dirtyLines = porcelain.stdout.split(/\r?\n/).filter((row) => row.trim().length > 0);
93
+ const head = runCapture(["git", "-C", checkoutRoot, "rev-parse", "--short", "HEAD"], projectRoot).stdout.trim();
94
+ const branchRaw = runCapture(["git", "-C", checkoutRoot, "rev-parse", "--abbrev-ref", "HEAD"], projectRoot).stdout.trim();
95
+ let ahead = 0;
96
+ let behind = 0;
97
+ if (pinnedCommit) {
98
+ const counts = runCapture(["git", "-C", checkoutRoot, "rev-list", "--left-right", "--count", `${pinnedCommit}...HEAD`], projectRoot);
99
+ if (counts.exitCode === 0) {
100
+ const [behindStr = "0", aheadStr = "0"] = counts.stdout.trim().split(/\s+/);
101
+ behind = Number.parseInt(behindStr, 10) || 0;
102
+ ahead = Number.parseInt(aheadStr, 10) || 0;
103
+ }
104
+ }
105
+ return {
106
+ available: true,
107
+ clean: dirtyLines.length === 0,
108
+ dirtyCount: dirtyLines.length,
109
+ head,
110
+ branch: branchRaw && branchRaw !== "HEAD" ? branchRaw : "(detached)",
111
+ ahead,
112
+ behind
113
+ };
114
+ }
115
+ async function refreshRepo(ctx) {
116
+ const request = repoActionRequest(ctx);
117
+ const label = request.kind === "sync" ? `Syncing ${request.alias}` : request.kind === "reset" ? "Resetting repo baseline" : "Loading repo state";
118
+ emitStarted(ctx, label);
119
+ try {
120
+ const projectRoot = projectRootOf(ctx);
121
+ const [
122
+ { repoBaseline, resetBaseline },
123
+ { currentTaskId },
124
+ { listManagedRepoEntries, resolveManagedRepoIdByAlias },
125
+ { syncManagedRepo, resolveManagedRepoLayoutByAlias },
126
+ { runCapture },
127
+ { existsSync },
128
+ pathMod
129
+ ] = await Promise.all([
130
+ import("@rig/runtime/control-plane/native/repo-ops"),
131
+ import("@rig/runtime/control-plane/native/task-state"),
132
+ import("@rig/runtime/control-plane/repos/registry"),
133
+ import("@rig/runtime/control-plane/repos"),
134
+ import("@rig/runtime/control-plane/native/utils"),
135
+ import("fs"),
136
+ import("path")
137
+ ]);
138
+ const joinPath = (...parts) => pathMod.resolve(...parts);
139
+ if (request.kind === "sync") {
140
+ const repoId = resolveManagedRepoIdByAlias(request.alias);
141
+ if (!repoId)
142
+ throw new Error(`No managed repo registered for alias ${request.alias}.`);
143
+ emitProgress(ctx, label, `re-syncing ${request.alias} from its remote default branch`);
144
+ await captureConsole(() => syncManagedRepo(projectRoot, repoId));
145
+ } else if (request.kind === "reset") {
146
+ emitProgress(ctx, label, "resetting baseline to origin/main and refreshing pins");
147
+ await captureConsole(() => resetBaseline(projectRoot, false));
148
+ }
149
+ emitProgress(ctx, label, "reading baseline pins and managed repos");
150
+ const { result } = await captureConsole(() => ({
151
+ pins: repoBaseline(projectRoot, false),
152
+ taskId: currentTaskId(projectRoot),
153
+ managed: listManagedRepoEntries()
154
+ }));
155
+ const baselinePins = Object.entries(result.pins).map(([alias, commit]) => ({ alias, commit: String(commit) }));
156
+ const pinByAlias = new Map(baselinePins.map((pin) => [pin.alias, pin.commit]));
157
+ const managedRepos = result.managed.map((entry) => {
158
+ const layout = resolveManagedRepoLayoutByAlias(projectRoot, entry.alias);
159
+ const git = layout ? readRepoGitStatus(projectRoot, layout.checkoutRoot, pinByAlias.get(entry.alias), runCapture, existsSync, joinPath) : undefined;
160
+ return {
161
+ id: entry.id,
162
+ alias: entry.alias,
163
+ defaultBranch: entry.defaultBranch,
164
+ defaultRemoteUrl: entry.defaultRemoteUrl,
165
+ ...git ? { git } : {}
166
+ };
167
+ });
168
+ const snapshot = {
169
+ activeTaskId: result.taskId.trim() ? result.taskId.trim() : null,
170
+ baselinePins,
171
+ managedRepos,
172
+ flatLayout: managedRepos.length === 0,
173
+ refreshedAt: Date.now()
174
+ };
175
+ patchData(ctx, { repo: snapshot, lastRefreshError: undefined });
176
+ patchFooter(ctx, { message: snapshot.flatLayout ? "flat layout \xB7 no managed repos" : `${managedRepos.length} managed repos \xB7 ${baselinePins.length} pins` });
177
+ emitCompleted(ctx, label, { managed: managedRepos.length, pins: baselinePins.length, task: snapshot.activeTaskId });
178
+ return snapshot;
179
+ } catch (error) {
180
+ emitFailed(ctx, label, error);
181
+ throw error;
182
+ }
183
+ }
184
+ export {
185
+ refreshRepo
186
+ };
@@ -1,6 +1,4 @@
1
- import type { AppAdapter } from "../types";
2
1
  import { type AppAdapterContext } from "./common";
3
- export declare function createRunDetailAdapter(): AppAdapter;
4
2
  export type AppRunSnapshot = {
5
3
  readonly runId: string;
6
4
  readonly status: string;
@@ -9,10 +7,19 @@ export type AppRunSnapshot = {
9
7
  readonly logs: Record<string, unknown>[];
10
8
  readonly timeline: Record<string, unknown>[];
11
9
  readonly timelineCursor: string | null;
10
+ /** Server-reported totals (when available) so the scene can show "N of M" and
11
+ * decide whether a "load more" affordance is warranted (#2). */
12
+ readonly logsTotal?: number;
13
+ readonly timelineTotal?: number;
12
14
  };
13
15
  export declare function loadRunDetail(ctx: AppAdapterContext, runId: string, options?: {
14
16
  readonly timelineCursor?: string | null;
15
17
  }): Promise<AppRunSnapshot>;
18
+ /** "Load more" for the timeline (#2): fetch the NEXT page using the stored
19
+ * `timelineCursor` and APPEND it to the existing snapshot, advancing the cursor.
20
+ * The previously-loaded rows stay; nothing is re-fetched. No cursor ⇒ nothing
21
+ * more to load (the scene only offers the affordance while a cursor exists). */
22
+ export declare function loadMoreRunTimeline(ctx: AppAdapterContext, runId: string): Promise<AppRunSnapshot | null>;
16
23
  export declare function steerRunFromApp(ctx: AppAdapterContext, input: {
17
24
  readonly runId: string;
18
25
  readonly message: string;
@@ -192,17 +192,21 @@ function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
192
192
  const scopedKey = resolve2(projectRoot ?? process.cwd());
193
193
  scopedGitHubBearerTokens.set(scopedKey, cleanToken(token ?? undefined));
194
194
  }
195
- function readPrivateRemoteSessionToken(projectRoot) {
195
+ function readRemoteAuthState(projectRoot) {
196
196
  const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
197
197
  if (!existsSync2(path))
198
198
  return null;
199
199
  try {
200
200
  const parsed = JSON.parse(readFileSync2(path, "utf8"));
201
- return cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined);
201
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
202
202
  } catch {
203
203
  return null;
204
204
  }
205
205
  }
206
+ function readPrivateRemoteSessionToken(projectRoot) {
207
+ const parsed = readRemoteAuthState(projectRoot);
208
+ return parsed ? cleanToken(typeof parsed.apiSessionToken === "string" ? parsed.apiSessionToken : typeof parsed.sessionToken === "string" ? parsed.sessionToken : undefined) : null;
209
+ }
206
210
  function readGitHubBearerTokenForRemote(projectRoot) {
207
211
  const scopedKey = resolve2(projectRoot);
208
212
  if (scopedGitHubBearerTokens.has(scopedKey))
@@ -213,15 +217,25 @@ function readGitHubBearerTokenForRemote(projectRoot) {
213
217
  return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
214
218
  }
215
219
  function readStoredGitHubAuthToken(projectRoot) {
216
- const path = resolve2(projectRoot, ".rig", "state", "github-auth.json");
217
- if (!existsSync2(path))
220
+ const parsed = readRemoteAuthState(projectRoot);
221
+ return parsed ? cleanToken(typeof parsed.token === "string" ? parsed.token : undefined) : null;
222
+ }
223
+ function inferRemoteServerProjectRootFromAuthState(projectRoot) {
224
+ const repo = readRepoConnection(projectRoot);
225
+ const slug = repo?.project?.trim();
226
+ if (!slug || !/^[^/]+\/[^/]+$/.test(slug))
218
227
  return null;
219
- try {
220
- const parsed = JSON.parse(readFileSync2(path, "utf8"));
221
- return cleanToken(typeof parsed.token === "string" ? parsed.token : undefined);
222
- } catch {
228
+ const auth = readRemoteAuthState(projectRoot);
229
+ const authUpdatedAt = typeof auth?.updatedAt === "string" ? Date.parse(auth.updatedAt) : Number.NaN;
230
+ const repoLinkedAt = typeof repo?.linkedAt === "string" ? Date.parse(repo.linkedAt) : Number.NaN;
231
+ if (Number.isFinite(authUpdatedAt) && Number.isFinite(repoLinkedAt) && authUpdatedAt + 1000 < repoLinkedAt)
223
232
  return null;
224
- }
233
+ const checkoutBaseDir = typeof auth?.checkoutBaseDir === "string" && auth.checkoutBaseDir.trim() ? auth.checkoutBaseDir.trim() : null;
234
+ if (!checkoutBaseDir)
235
+ return null;
236
+ const inferred = `${checkoutBaseDir.replace(/\/+$/, "")}/${slug}`;
237
+ writeRepoServerProjectRoot(projectRoot, inferred);
238
+ return inferred;
225
239
  }
226
240
  function readLocalConnectionFallbackToken(projectRoot) {
227
241
  return readGitHubBearerTokenForRemote(projectRoot) ?? cleanToken(process.env.RIG_GITHUB_TOKEN) ?? readStoredGitHubAuthToken(projectRoot);
@@ -232,7 +246,7 @@ async function ensureServerForCli(projectRoot) {
232
246
  if (selected?.connection.kind === "remote") {
233
247
  reportServerPhase(`Connecting to ${selected.alias}\u2026`);
234
248
  const authToken = readGitHubBearerTokenForRemote(projectRoot);
235
- const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
249
+ const serverProjectRoot = selected.serverProjectRoot ?? inferRemoteServerProjectRootFromAuthState(projectRoot) ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
236
250
  return {
237
251
  baseUrl: selected.connection.baseUrl,
238
252
  authToken,
@@ -261,7 +275,10 @@ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken)
261
275
  if (!slug)
262
276
  return null;
263
277
  try {
264
- const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
278
+ const url = new URL(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`);
279
+ if (authToken && queryAuthFallbackEnabled())
280
+ url.searchParams.set("rt", authToken);
281
+ const response = await fetch(url, {
265
282
  headers: mergeHeaders(undefined, authToken)
266
283
  });
267
284
  if (!response.ok)
@@ -288,10 +305,23 @@ function appendTaskFilterParams(url, filters) {
288
305
  if (filters.limit !== undefined)
289
306
  url.searchParams.set("limit", String(filters.limit));
290
307
  }
308
+ function mergeCookie(existing, name, value) {
309
+ const encoded = `${name}=${encodeURIComponent(value)}`;
310
+ if (!existing?.trim())
311
+ return encoded;
312
+ const parts = existing.split(";").map((part) => part.trim()).filter((part) => part && !part.startsWith(`${name}=`));
313
+ return [...parts, encoded].join("; ");
314
+ }
315
+ function queryAuthFallbackEnabled(env = process.env) {
316
+ return env.RIG_ENABLE_QUERY_AUTH_FALLBACK === "1" || env.RIG_QUERY_AUTH_FALLBACK === "1";
317
+ }
291
318
  function mergeHeaders(headers, authToken) {
292
319
  const merged = new Headers(headers);
293
320
  if (authToken) {
294
- merged.set("authorization", `Bearer ${authToken}`);
321
+ const bearer = `Bearer ${authToken}`;
322
+ merged.set("authorization", bearer);
323
+ merged.set("x-auth", bearer);
324
+ merged.set("cookie", mergeCookie(merged.get("cookie"), "rig_auth", authToken));
295
325
  }
296
326
  return merged;
297
327
  }
@@ -351,15 +381,34 @@ async function buildServerFailureContext(projectRoot, server) {
351
381
  hint: "Check the selected server with `rig server status`, or switch with `rig server use <alias|local>`."
352
382
  };
353
383
  }
384
+ function isLoopbackRemoteBaseUrl(baseUrl) {
385
+ try {
386
+ const host = new URL(baseUrl).hostname.toLowerCase();
387
+ return host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "[::1]";
388
+ } catch {
389
+ return false;
390
+ }
391
+ }
392
+ function canUseRemoteWithoutProjectRoot(pathname) {
393
+ 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/");
394
+ }
354
395
  async function requestServerJson(context, pathname, init = {}) {
355
396
  const server = await ensureServerForCli(context.projectRoot);
397
+ const requestUrl = new URL(`${server.baseUrl}${pathname}`);
398
+ if (server.connectionKind === "remote" && !server.serverProjectRoot && !canUseRemoteWithoutProjectRoot(requestUrl.pathname) && (server.authToken || !isLoopbackRemoteBaseUrl(server.baseUrl))) {
399
+ const repo = readRepoConnection(context.projectRoot);
400
+ 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." });
401
+ }
356
402
  const headers = mergeHeaders(init.headers, server.authToken);
357
403
  if (server.serverProjectRoot)
358
404
  headers.set("x-rig-project-root", server.serverProjectRoot);
405
+ if (server.connectionKind === "remote" && server.authToken && queryAuthFallbackEnabled()) {
406
+ requestUrl.searchParams.set("rt", server.authToken);
407
+ }
359
408
  reportServerPhase(`${(init.method ?? "GET").toUpperCase()} ${pathname.split("?")[0]}\u2026`);
360
409
  let response;
361
410
  try {
362
- response = await fetch(`${server.baseUrl}${pathname}`, {
411
+ response = await fetch(requestUrl, {
363
412
  ...init,
364
413
  headers
365
414
  });
@@ -421,11 +470,26 @@ async function getGitHubAuthStatusViaServer(context) {
421
470
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
422
471
  }
423
472
  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
- });
473
+ const server = await ensureServerForCli(context.projectRoot);
474
+ const requestUrl = new URL(`${server.baseUrl}/api/github/auth/token`);
475
+ reportServerPhase("POST /api/github/auth/token\u2026");
476
+ let response;
477
+ try {
478
+ response = await fetch(requestUrl, {
479
+ method: "POST",
480
+ headers: { "content-type": "application/json" },
481
+ body: JSON.stringify({ token, selectedRepo: options.selectedRepo, projectRoot: options.projectRoot ?? server.serverProjectRoot ?? undefined })
482
+ });
483
+ } catch (error) {
484
+ const failure = await buildServerFailureContext(context.projectRoot, server);
485
+ throw new CliError(`Rig server auth bootstrap failed: ${error instanceof Error ? error.message : String(error)}
486
+ ${failure.contextLine}`, 1, { hint: failure.hint });
487
+ }
488
+ const payload = await response.json().catch(() => null);
489
+ if (!response.ok) {
490
+ const detail = payload && typeof payload === "object" && !Array.isArray(payload) ? String(payload.error ?? JSON.stringify(payload)) : `HTTP ${response.status}`;
491
+ 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`." });
492
+ }
429
493
  return payload && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
430
494
  }
431
495
  async function prepareRemoteCheckoutViaServer(context, input) {
@@ -703,20 +767,11 @@ var init__server_client = __esm(() => {
703
767
  });
704
768
 
705
769
  // 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
770
  function projectRootOf(ctx) {
716
771
  const root = ctx.rig?.projectRoot ?? ctx.projectRoot ?? ctx.getState().projectRoot;
717
772
  if (typeof root === "string" && root.trim())
718
773
  return root;
719
- throw new Error("Rig app adapter requires a projectRoot.");
774
+ throw new Error("App adapter requires a projectRoot.");
720
775
  }
721
776
  function normalizeAppError(error) {
722
777
  const message = error instanceof Error ? error.message : String(error);
@@ -774,33 +829,17 @@ function stringField(record, keys, fallback = "") {
774
829
  }
775
830
  return fallback;
776
831
  }
777
- function payloadString(intent, key) {
778
- const value = intent.action.payload?.[key];
779
- return typeof value === "string" && value.trim() ? value.trim() : undefined;
780
- }
781
832
 
782
833
  // packages/cli/src/app-opentui/adapters/run-detail.ts
783
- function createRunDetailAdapter() {
784
- return {
785
- id: "run-detail",
786
- async handleIntent(runtime, intent) {
787
- if (intent.scene !== "run-detail" && intent.action.kind !== "run-steer")
788
- return false;
789
- const ctx = adapterContextFromRuntime(runtime);
790
- const runId = payloadString(intent, "runId") ?? runtime.getState().data.selectedRunId;
791
- if (intent.action.kind === "run-steer") {
792
- const message = payloadString(intent, "message") ?? intent.raw;
793
- if (runId && message)
794
- await steerRunFromApp(ctx, { runId, message });
795
- return true;
796
- }
797
- if (runId) {
798
- await loadRunDetail(ctx, runId);
799
- return true;
800
- }
801
- return false;
802
- }
803
- };
834
+ var LOG_PAGE = 100;
835
+ var TIMELINE_PAGE = 200;
836
+ function payloadTotal(payload) {
837
+ for (const key of ["total", "totalCount", "count"]) {
838
+ const value = payload[key];
839
+ if (typeof value === "number" && Number.isFinite(value))
840
+ return value;
841
+ }
842
+ return;
804
843
  }
805
844
  function unwrapRun(payload) {
806
845
  return payload.run && typeof payload.run === "object" && !Array.isArray(payload.run) ? payload.run : payload;
@@ -809,8 +848,24 @@ function nextCursor(payload) {
809
848
  const cursor = payload.nextCursor ?? payload.cursor;
810
849
  return typeof cursor === "string" && cursor.trim() ? cursor : null;
811
850
  }
851
+ function loadMoreRequest(ctx, runId) {
852
+ const value = ctx.getState().data?.runDetailLoadMore;
853
+ if (!value || typeof value !== "object" || Array.isArray(value))
854
+ return null;
855
+ const record = value;
856
+ if (record.runId !== runId || typeof record.cursor !== "string" || !record.cursor.trim())
857
+ return null;
858
+ return { runId, cursor: record.cursor };
859
+ }
812
860
  async function loadRunDetail(ctx, runId, options = {}) {
813
861
  const cleanRunId = runId.trim();
862
+ const more = loadMoreRequest(ctx, cleanRunId);
863
+ if (more) {
864
+ patchData(ctx, { runDetailLoadMore: undefined });
865
+ const appended = await loadMoreRunTimeline(ctx, cleanRunId).catch(() => null);
866
+ if (appended)
867
+ return appended;
868
+ }
814
869
  const label = `Loading run ${cleanRunId.slice(0, 8)}`;
815
870
  if (!cleanRunId) {
816
871
  const error = new Error("Run detail requires a run id.");
@@ -824,10 +879,12 @@ async function loadRunDetail(ctx, runId, options = {}) {
824
879
  emitProgress(ctx, label, "loading run, logs, and timeline");
825
880
  const [runPayload, logsPayload, timelinePayload] = await Promise.all([
826
881
  getRunDetailsViaServer2(context, cleanRunId),
827
- getRunLogsViaServer2(context, cleanRunId, { limit: 100 }),
828
- getRunTimelineViaServer2(context, cleanRunId, { limit: 200, ...options.timelineCursor ? { cursor: options.timelineCursor } : {} })
882
+ getRunLogsViaServer2(context, cleanRunId, { limit: LOG_PAGE }),
883
+ getRunTimelineViaServer2(context, cleanRunId, { limit: TIMELINE_PAGE, ...options.timelineCursor ? { cursor: options.timelineCursor } : {} })
829
884
  ]);
830
885
  const run = unwrapRun(runPayload);
886
+ const logsTotal = payloadTotal(logsPayload);
887
+ const timelineTotal = payloadTotal(timelinePayload);
831
888
  const snapshot = {
832
889
  runId: cleanRunId,
833
890
  status: stringField(run, ["status", "state"], "unknown"),
@@ -835,9 +892,12 @@ async function loadRunDetail(ctx, runId, options = {}) {
835
892
  run,
836
893
  logs: arrayFromPayload(logsPayload),
837
894
  timeline: arrayFromPayload(timelinePayload),
838
- timelineCursor: nextCursor(timelinePayload)
895
+ timelineCursor: nextCursor(timelinePayload),
896
+ ...logsTotal !== undefined ? { logsTotal } : {},
897
+ ...timelineTotal !== undefined ? { timelineTotal } : {}
839
898
  };
840
- patchData(ctx, { selectedRunId: cleanRunId, runDetail: snapshot });
899
+ const clearSettledSteer = settledSteerForRun(ctx, cleanRunId) ? { pendingRunMessage: undefined } : {};
900
+ patchData(ctx, { selectedRunId: cleanRunId, runDetail: snapshot, lastRefreshError: undefined, ...clearSettledSteer });
841
901
  patchFooter(ctx, { run: `${cleanRunId.slice(0, 8)} ${snapshot.status}` });
842
902
  emitCompleted(ctx, label, { runId: cleanRunId, status: snapshot.status, logs: snapshot.logs.length, timeline: snapshot.timeline.length });
843
903
  return snapshot;
@@ -846,6 +906,56 @@ async function loadRunDetail(ctx, runId, options = {}) {
846
906
  throw error;
847
907
  }
848
908
  }
909
+ function settledSteerForRun(ctx, runId) {
910
+ const value = ctx.getState().data?.pendingRunMessage;
911
+ if (!value || typeof value !== "object" || Array.isArray(value))
912
+ return false;
913
+ const record = value;
914
+ if (record.runId !== runId)
915
+ return false;
916
+ return record.status === "sent" || record.status === "delivered" || record.status === "failed";
917
+ }
918
+ function currentSnapshot(ctx) {
919
+ const value = ctx.getState().data?.runDetail;
920
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
921
+ }
922
+ async function loadMoreRunTimeline(ctx, runId) {
923
+ const cleanRunId = runId.trim();
924
+ const snapshot = currentSnapshot(ctx);
925
+ if (!snapshot || snapshot.runId !== cleanRunId || !snapshot.timelineCursor)
926
+ return snapshot;
927
+ const label = `More timeline ${cleanRunId.slice(0, 8)}`;
928
+ emitStarted(ctx, label);
929
+ try {
930
+ const { getRunTimelineViaServer: getRunTimelineViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
931
+ const context = { projectRoot: projectRootOf(ctx) };
932
+ const page = await getRunTimelineViaServer2(context, cleanRunId, { limit: TIMELINE_PAGE, cursor: snapshot.timelineCursor });
933
+ const more = arrayFromPayload(page);
934
+ const timelineTotal = payloadTotal(page) ?? snapshot.timelineTotal;
935
+ const next = {
936
+ ...snapshot,
937
+ timeline: [...snapshot.timeline, ...more],
938
+ timelineCursor: nextCursor(page),
939
+ ...timelineTotal !== undefined ? { timelineTotal } : {}
940
+ };
941
+ patchData(ctx, { runDetail: next, lastRefreshError: undefined });
942
+ emitCompleted(ctx, label, { runId: cleanRunId, added: more.length, timeline: next.timeline.length });
943
+ return next;
944
+ } catch (error) {
945
+ emitFailed(ctx, label, error, { runId: cleanRunId });
946
+ throw error;
947
+ }
948
+ }
949
+ function steerResultSummary(result) {
950
+ for (const key of ["status", "state", "message", "detail"]) {
951
+ const value = result[key];
952
+ if (typeof value === "string" && value.trim())
953
+ return value.trim();
954
+ }
955
+ if (result.ok === true || result.queued === true || result.delivered === true)
956
+ return "accepted by run";
957
+ return "delivered";
958
+ }
849
959
  async function steerRunFromApp(ctx, input) {
850
960
  const label = `Steering ${input.runId.slice(0, 8)}`;
851
961
  const message = input.message.trim();
@@ -854,17 +964,21 @@ async function steerRunFromApp(ctx, input) {
854
964
  emitFailed(ctx, label, error, { runId: input.runId });
855
965
  throw error;
856
966
  }
857
- emitStarted(ctx, label, { runMessage: { runId: input.runId, text: message, status: "queued" } });
858
- patchData(ctx, { pendingRunMessage: { runId: input.runId, text: message, status: "queued" } });
967
+ const pending = { runId: input.runId, text: message, status: "queued" };
968
+ emitStarted(ctx, label, { pendingRunMessage: pending });
969
+ patchData(ctx, { pendingRunMessage: pending });
859
970
  try {
860
971
  const { sendRunPiPromptViaServer: sendRunPiPromptViaServer2, steerRunViaServer: steerRunViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
861
972
  const context = { projectRoot: projectRootOf(ctx) };
862
973
  const result = await sendRunPiPromptViaServer2(context, input.runId, message, "steer").catch(() => steerRunViaServer2(context, input.runId, message));
974
+ const summary = steerResultSummary(result);
975
+ patchData(ctx, { pendingRunMessage: { runId: input.runId, text: message, status: "sent", result: summary } });
863
976
  emitCompleted(ctx, label, { runId: input.runId, result });
864
- patchData(ctx, { pendingRunMessage: null });
865
977
  return result;
866
978
  } catch (error) {
867
- emitFailed(ctx, label, error, { runId: input.runId, revert: { pendingRunMessage: null } });
979
+ const message2 = normalizeAppError(error).message;
980
+ emitFailed(ctx, label, error, { runId: input.runId });
981
+ patchData(ctx, { pendingRunMessage: { runId: input.runId, text: message, status: "failed", result: message2 } });
868
982
  throw error;
869
983
  }
870
984
  }
@@ -878,7 +992,10 @@ async function stopRunFromDetail(ctx, runId) {
878
992
  const { stopRunViaServer: stopRunViaServer2 } = await Promise.resolve().then(() => (init__server_client(), exports__server_client));
879
993
  const result = await stopRunViaServer2({ projectRoot: projectRootOf(ctx) }, cleanRunId);
880
994
  emitCompleted(ctx, label, { runId: cleanRunId, result });
881
- await loadRunDetail(ctx, cleanRunId).catch(() => null);
995
+ await loadRunDetail(ctx, cleanRunId).catch((error) => {
996
+ patchData(ctx, { lastRefreshError: normalizeAppError(error).message });
997
+ return null;
998
+ });
882
999
  return result;
883
1000
  } catch (error) {
884
1001
  emitFailed(ctx, label, error, { runId: cleanRunId, revert: { status: "unknown" } });
@@ -889,5 +1006,5 @@ export {
889
1006
  stopRunFromDetail,
890
1007
  steerRunFromApp,
891
1008
  loadRunDetail,
892
- createRunDetailAdapter
1009
+ loadMoreRunTimeline
893
1010
  };
@@ -1,6 +1,4 @@
1
- import type { AppAdapter } from "../types";
2
1
  import { type AppAdapterContext } from "./common";
3
- export declare function createServerAdapter(): AppAdapter;
4
2
  export type AppServerState = {
5
3
  readonly label: string;
6
4
  readonly baseUrl?: string;
@@ -11,4 +9,14 @@ export type AppServerState = {
11
9
  readonly auth?: Record<string, unknown>;
12
10
  readonly error?: string;
13
11
  };
12
+ /** Start the local Rig server DETACHED and return to the server scene (bug #3).
13
+ *
14
+ * `rig server start` is a blocking long-running process; running it through the
15
+ * foreground command PTY traps the operator (kitty-mode even swallows ctrl-c).
16
+ * Instead we: (a) switch this repo's connection to local, (b) spawn the server
17
+ * detached + wait for ready via ensureLocalRigServerConnection (it writes the
18
+ * published server state and unrefs the child), then (c) re-probe. The operator
19
+ * is never blocked: this returns once the detached server answers.
20
+ */
21
+ export declare function startLocalServerFromApp(ctx: AppAdapterContext): Promise<AppServerState>;
14
22
  export declare function refreshServerStatus(ctx: AppAdapterContext): Promise<AppServerState>;