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

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 (118) hide show
  1. package/README.md +18 -19
  2. package/dist/bin/build-rig-binaries.js +22 -10
  3. package/dist/bin/rig.d.ts +71 -1
  4. package/dist/bin/rig.js +15078 -11169
  5. package/dist/config/rig-default-config.yml +5 -0
  6. package/dist/src/app/drone-ui.d.ts +11 -14
  7. package/dist/src/app/drone-ui.js +70 -86
  8. package/dist/src/commands/_async-ui.d.ts +1 -4
  9. package/dist/src/commands/_async-ui.js +9 -111
  10. package/dist/src/commands/_cli-format.d.ts +16 -9
  11. package/dist/src/commands/_cli-format.js +167 -295
  12. package/dist/src/commands/_connection-state.d.ts +11 -1
  13. package/dist/src/commands/_connection-state.js +50 -5
  14. package/dist/src/commands/_doctor-checks.d.ts +0 -6
  15. package/dist/src/commands/_doctor-checks.js +79 -382
  16. package/dist/src/commands/_help-catalog.d.ts +1 -1
  17. package/dist/src/commands/_help-catalog.js +217 -157
  18. package/dist/src/commands/_inprocess-services.d.ts +33 -0
  19. package/dist/src/commands/_inprocess-services.js +102 -0
  20. package/dist/src/commands/_json-output.js +4 -0
  21. package/dist/src/commands/_lazy-reconcile.d.ts +34 -0
  22. package/dist/src/commands/_lazy-reconcile.js +102 -0
  23. package/dist/src/commands/_paths.js +1 -1
  24. package/dist/src/commands/_pi-frontend.d.ts +18 -10
  25. package/dist/src/commands/_pi-frontend.js +37 -715
  26. package/dist/src/commands/_pi-install.js +18 -36
  27. package/dist/src/commands/_policy.d.ts +1 -1
  28. package/dist/src/commands/_policy.js +56 -15
  29. package/dist/src/commands/_run-bridge.d.ts +114 -0
  30. package/dist/src/commands/_run-bridge.js +387 -0
  31. package/dist/src/commands/_run-diagnostics.d.ts +9 -0
  32. package/dist/src/commands/_run-diagnostics.js +51 -0
  33. package/dist/src/commands/_run-driver-helpers.d.ts +8 -81
  34. package/dist/src/commands/_run-driver-helpers.js +79 -283
  35. package/dist/src/commands/_run-projection.d.ts +50 -0
  36. package/dist/src/commands/_run-projection.js +349 -0
  37. package/dist/src/commands/_run-subcommands.d.ts +3 -0
  38. package/dist/src/commands/_run-subcommands.js +31 -0
  39. package/dist/src/commands/_spinner.js +1 -1
  40. package/dist/src/commands/agent.d.ts +1 -1
  41. package/dist/src/commands/agent.js +8559 -239
  42. package/dist/src/commands/dist.d.ts +1 -1
  43. package/dist/src/commands/dist.js +27 -19
  44. package/dist/src/commands/doctor.d.ts +1 -1
  45. package/dist/src/commands/doctor.js +93 -475
  46. package/dist/src/commands/github.d.ts +1 -1
  47. package/dist/src/commands/github.js +113 -387
  48. package/dist/src/commands/inbox.d.ts +22 -24
  49. package/dist/src/commands/inbox.js +420 -691
  50. package/dist/src/commands/init.d.ts +6 -16
  51. package/dist/src/commands/init.js +334 -971
  52. package/dist/src/commands/inspect.d.ts +19 -2
  53. package/dist/src/commands/inspect.js +644 -610
  54. package/dist/src/commands/pi.d.ts +1 -1
  55. package/dist/src/commands/plugin.d.ts +1 -1
  56. package/dist/src/commands/plugin.js +486 -7
  57. package/dist/src/commands/profile-and-review.d.ts +1 -1
  58. package/dist/src/commands/profile-and-review.js +94 -56
  59. package/dist/src/commands/queue.js +1 -21
  60. package/dist/src/commands/remote.d.ts +1 -1
  61. package/dist/src/commands/remote.js +837 -14
  62. package/dist/src/commands/repo-git-harness.d.ts +1 -1
  63. package/dist/src/commands/repo-git-harness.js +57 -14
  64. package/dist/src/commands/run.d.ts +20 -2
  65. package/dist/src/commands/run.js +17579 -1759
  66. package/dist/src/commands/server.d.ts +2 -6
  67. package/dist/src/commands/server.js +141 -723
  68. package/dist/src/commands/setup.d.ts +1 -1
  69. package/dist/src/commands/setup.js +102 -484
  70. package/dist/src/commands/stats.d.ts +13 -10
  71. package/dist/src/commands/stats.js +689 -761
  72. package/dist/src/commands/task-run-driver.d.ts +50 -88
  73. package/dist/src/commands/task-run-driver.js +116 -2717
  74. package/dist/src/commands/task.d.ts +34 -13
  75. package/dist/src/commands/task.js +668 -2523
  76. package/dist/src/commands/test.d.ts +1 -1
  77. package/dist/src/commands/triage.d.ts +11 -0
  78. package/dist/src/commands/triage.js +227 -0
  79. package/dist/src/commands/workspace.d.ts +1 -1
  80. package/dist/src/commands.d.ts +0 -16
  81. package/dist/src/commands.js +16657 -12250
  82. package/dist/src/index.js +16528 -12497
  83. package/dist/src/launcher.js +4 -0
  84. package/dist/src/operator-cli.d.ts +2 -0
  85. package/dist/src/operator-cli.js +17837 -0
  86. package/dist/src/operator-entry.d.ts +1 -0
  87. package/dist/src/operator-entry.js +3 -0
  88. package/package.json +18 -12
  89. package/dist/src/app/board.d.ts +0 -23
  90. package/dist/src/app/board.js +0 -1786
  91. package/dist/src/app/theme.d.ts +0 -47
  92. package/dist/src/app/theme.js +0 -150
  93. package/dist/src/commands/_authority-runs.d.ts +0 -22
  94. package/dist/src/commands/_authority-runs.js +0 -110
  95. package/dist/src/commands/_operator-surface.d.ts +0 -34
  96. package/dist/src/commands/_operator-surface.js +0 -220
  97. package/dist/src/commands/_operator-view.d.ts +0 -30
  98. package/dist/src/commands/_operator-view.js +0 -1070
  99. package/dist/src/commands/_preflight.d.ts +0 -22
  100. package/dist/src/commands/_preflight.js +0 -540
  101. package/dist/src/commands/_run-replay.d.ts +0 -24
  102. package/dist/src/commands/_run-replay.js +0 -142
  103. package/dist/src/commands/_server-client.d.ts +0 -186
  104. package/dist/src/commands/_server-client.js +0 -681
  105. package/dist/src/commands/_snapshot-upload.d.ts +0 -39
  106. package/dist/src/commands/_snapshot-upload.js +0 -455
  107. package/dist/src/commands/_task-picker.d.ts +0 -9
  108. package/dist/src/commands/_task-picker.js +0 -201
  109. package/dist/src/commands/browser.d.ts +0 -65
  110. package/dist/src/commands/browser.js +0 -1173
  111. package/dist/src/commands/connect.d.ts +0 -7
  112. package/dist/src/commands/connect.js +0 -419
  113. package/dist/src/commands/inspector.d.ts +0 -3
  114. package/dist/src/commands/inspector.js +0 -263
  115. package/dist/src/commands/task-report-bug.d.ts +0 -19
  116. package/dist/src/commands/task-report-bug.js +0 -1281
  117. package/dist/src/report-bug.d.ts +0 -44
  118. package/dist/src/report-bug.js +0 -260
@@ -0,0 +1,33 @@
1
+ import { saveGitHubTokenForProject, type GitHubAuthStatus } from "@rig/runtime/control-plane/github/index";
2
+ export type GitHubAuthStatusResponse = {
3
+ readonly ok: true;
4
+ } & GitHubAuthStatus;
5
+ export type GitHubTokenPostResponse = Awaited<ReturnType<typeof saveGitHubTokenForProject>> & {
6
+ readonly authenticated: boolean;
7
+ readonly apiSessionToken: string;
8
+ };
9
+ export declare function setGitHubBearerTokenForCurrentProcess(token: string | null, projectRoot?: string): void;
10
+ export declare function getGitHubAuthStatusInProcess(context: {
11
+ projectRoot: string;
12
+ }): Promise<GitHubAuthStatusResponse>;
13
+ export declare function postGitHubTokenInProcess(context: {
14
+ projectRoot: string;
15
+ }, token: string, options?: {
16
+ readonly selectedRepo?: string;
17
+ readonly projectRoot?: string;
18
+ }): Promise<GitHubTokenPostResponse>;
19
+ export declare function listGitHubProjectsInProcess(context: {
20
+ projectRoot: string;
21
+ }, owner: string, options?: {
22
+ readonly authToken?: string | null;
23
+ readonly baseUrl?: string | null;
24
+ }): Promise<Record<string, unknown>>;
25
+ export declare function getGitHubProjectStatusFieldInProcess(context: {
26
+ projectRoot: string;
27
+ }, projectId: string, options?: {
28
+ readonly authToken?: string | null;
29
+ readonly baseUrl?: string | null;
30
+ }): Promise<Record<string, unknown>>;
31
+ export declare function requestGitHubAuthJsonInProcess(context: {
32
+ projectRoot: string;
33
+ }, pathname: string, init?: RequestInit): Promise<unknown>;
@@ -0,0 +1,102 @@
1
+ // @bun
2
+ // packages/cli/src/commands/_inprocess-services.ts
3
+ import { resolve } from "path";
4
+ import {
5
+ beginGitHubDeviceFlow,
6
+ checkGitHubRepoPermissions,
7
+ createGitHubAuthStore,
8
+ listGitHubProjects,
9
+ pollGitHubDeviceFlow,
10
+ resolveGitHubAuthStatus,
11
+ resolveProjectStatusField,
12
+ saveGitHubTokenForProject
13
+ } from "@rig/runtime/control-plane/github/index";
14
+ var scopedGitHubBearerTokens = new Map;
15
+ function cleanToken(value) {
16
+ const trimmed = value?.trim();
17
+ return trimmed ? trimmed : null;
18
+ }
19
+ function cleanString(value) {
20
+ return typeof value === "string" && value.trim() ? value.trim() : null;
21
+ }
22
+ function oauthClientId() {
23
+ return cleanToken(process.env.RIG_GITHUB_OAUTH_CLIENT_ID);
24
+ }
25
+ function tokenForProject(projectRoot, override) {
26
+ const scoped = scopedGitHubBearerTokens.get(resolve(projectRoot));
27
+ return cleanToken(override) ?? scoped ?? createGitHubAuthStore(projectRoot).readToken() ?? cleanToken(process.env.RIG_GITHUB_TOKEN);
28
+ }
29
+ function setGitHubBearerTokenForCurrentProcess(token, projectRoot) {
30
+ scopedGitHubBearerTokens.set(resolve(projectRoot ?? process.cwd()), cleanToken(token));
31
+ }
32
+ async function getGitHubAuthStatusInProcess(context) {
33
+ return { ok: true, ...resolveGitHubAuthStatus({ projectRoot: context.projectRoot, oauthConfigured: Boolean(oauthClientId()) }) };
34
+ }
35
+ async function postGitHubTokenInProcess(context, token, options = {}) {
36
+ const targetRoot = options.projectRoot?.trim() || context.projectRoot;
37
+ const result = await saveGitHubTokenForProject({
38
+ projectRoot: targetRoot,
39
+ token,
40
+ tokenSource: "manual-token",
41
+ selectedRepo: options.selectedRepo ?? null
42
+ });
43
+ const store = createGitHubAuthStore(targetRoot);
44
+ const session = store.createApiSession();
45
+ if (targetRoot !== context.projectRoot) {
46
+ store.copyToLocalProjectRoot(context.projectRoot);
47
+ }
48
+ return { ...result, authenticated: result.signedIn, apiSessionToken: session.token };
49
+ }
50
+ async function listGitHubProjectsInProcess(context, owner, options = {}) {
51
+ const token = tokenForProject(context.projectRoot, options.authToken);
52
+ if (!token)
53
+ return { ok: false, error: "missing-token", projects: [] };
54
+ const projects = await listGitHubProjects({ owner, token });
55
+ return { ok: true, projects };
56
+ }
57
+ async function getGitHubProjectStatusFieldInProcess(context, projectId, options = {}) {
58
+ const token = tokenForProject(context.projectRoot, options.authToken);
59
+ if (!token)
60
+ return { ok: false, error: "missing-token" };
61
+ const field = await resolveProjectStatusField({ projectId, token });
62
+ return { ok: true, field };
63
+ }
64
+ async function requestGitHubAuthJsonInProcess(context, pathname, init = {}) {
65
+ const method = (init.method ?? "GET").toUpperCase();
66
+ if (pathname === "/api/github/auth/status")
67
+ return getGitHubAuthStatusInProcess(context);
68
+ if (pathname === "/api/github/repo/permissions") {
69
+ return checkGitHubRepoPermissions({ projectRoot: context.projectRoot, oauthConfigured: Boolean(oauthClientId()) });
70
+ }
71
+ if (pathname === "/api/github/auth/device/start" && method === "POST") {
72
+ const clientId = oauthClientId();
73
+ if (!clientId)
74
+ return { ok: false, oauthConfigured: false, error: "RIG_GITHUB_OAUTH_CLIENT_ID is not configured." };
75
+ const body = init.body ? JSON.parse(String(init.body)) : {};
76
+ return beginGitHubDeviceFlow({
77
+ projectRoot: context.projectRoot,
78
+ clientId,
79
+ scope: cleanString(body.scope) ?? undefined,
80
+ selectedRepo: cleanString(body.repoSlug)
81
+ });
82
+ }
83
+ if (pathname === "/api/github/auth/device/poll" && method === "POST") {
84
+ const clientId = oauthClientId();
85
+ if (!clientId)
86
+ return { ok: false, oauthConfigured: false, error: "RIG_GITHUB_OAUTH_CLIENT_ID is not configured." };
87
+ const body = init.body ? JSON.parse(String(init.body)) : {};
88
+ const pollId = cleanString(body.pollId);
89
+ if (!pollId)
90
+ return { ok: false, status: "error", error: "pollId is required" };
91
+ return pollGitHubDeviceFlow({ projectRoot: context.projectRoot, clientId, pollId, selectedRepo: cleanString(body.repoSlug) });
92
+ }
93
+ throw new Error(`No in-process GitHub auth API for ${method} ${pathname}`);
94
+ }
95
+ export {
96
+ setGitHubBearerTokenForCurrentProcess,
97
+ requestGitHubAuthJsonInProcess,
98
+ postGitHubTokenInProcess,
99
+ listGitHubProjectsInProcess,
100
+ getGitHubProjectStatusFieldInProcess,
101
+ getGitHubAuthStatusInProcess
102
+ };
@@ -7,7 +7,9 @@ import {
7
7
  RigInboxInputsOutput,
8
8
  RigRunListOutput,
9
9
  RigRunShowOutput,
10
+ RigServerRepairLinkOutput,
10
11
  RigServerStatusOutput,
12
+ RigServerUseOutput,
11
13
  RigStatsOutput,
12
14
  RigTaskListOutput,
13
15
  RigTaskShowOutput
@@ -17,7 +19,9 @@ var CLI_OUTPUT_SCHEMAS = {
17
19
  "task show": RigTaskShowOutput,
18
20
  "run list": RigRunListOutput,
19
21
  "run show": RigRunShowOutput,
22
+ "server use": RigServerUseOutput,
20
23
  "server status": RigServerStatusOutput,
24
+ "server repair-link": RigServerRepairLinkOutput,
21
25
  "inbox approvals": RigInboxApprovalsOutput,
22
26
  "inbox inputs": RigInboxInputsOutput,
23
27
  "doctor check": RigDoctorCheckOutput,
@@ -0,0 +1,34 @@
1
+ import { SessionManager } from "@oh-my-pi/pi-coding-agent";
2
+ import { type CollabRegistryFilter, type CollabSessionProjection } from "@oh-my-pi/pi-coding-agent/collab/api";
3
+ import { type RunJournalProjection, type RunSessionCustomEntry } from "@rig/contracts";
4
+ type SessionWriter = {
5
+ appendCustomEntry(customType: string, data: unknown): void;
6
+ };
7
+ export type CollabSessionProjectionLike = Pick<CollabSessionProjection, "collab" | "customEntries" | "source"> & {
8
+ readonly runId?: string;
9
+ readonly session: Pick<CollabSessionProjection["session"], "path" | "id">;
10
+ };
11
+ export type ProjectRunProjection = Pick<RunJournalProjection, "status">;
12
+ export type ProjectRunFromSession = (source: Pick<SessionManager, "getEntries"> | ReadonlyArray<RunSessionCustomEntry> | readonly unknown[], runId: string) => ProjectRunProjection;
13
+ export type LazyReconcileFlippedRun = {
14
+ readonly runId: string;
15
+ readonly sessionPath: string;
16
+ readonly reason: "lazy-reconcile:dead-pid";
17
+ };
18
+ export type LazyReconcileResult = {
19
+ readonly flipped: readonly LazyReconcileFlippedRun[];
20
+ readonly resumable: readonly LazyReconcileFlippedRun[];
21
+ };
22
+ type LazyReconcileDeps = {
23
+ readonly listCollabSessionProjections?: (filter: CollabRegistryFilter) => Promise<readonly CollabSessionProjectionLike[]>;
24
+ readonly projectRunFromSession?: ProjectRunFromSession;
25
+ readonly processExists?: (pid: number) => boolean;
26
+ readonly openSession?: (sessionPath: string) => Promise<SessionWriter>;
27
+ readonly nowIso?: () => string;
28
+ };
29
+ export type LazyReconcileInput = {
30
+ readonly workspaceRoot: string;
31
+ readonly identityFilter: CollabRegistryFilter;
32
+ };
33
+ export declare function runLazyReconcile(input: LazyReconcileInput, deps?: LazyReconcileDeps): Promise<LazyReconcileResult>;
34
+ export {};
@@ -0,0 +1,102 @@
1
+ // @bun
2
+ var __require = import.meta.require;
3
+
4
+ // packages/cli/src/commands/_lazy-reconcile.ts
5
+ import { SessionManager } from "@oh-my-pi/pi-coding-agent";
6
+ import {
7
+ listCollabSessionProjections as ompListCollabSessionProjections
8
+ } from "@oh-my-pi/pi-coding-agent/collab/api";
9
+ import {
10
+ CUSTOM_TYPE_FOR,
11
+ isTerminalRunStatus
12
+ } from "@rig/contracts";
13
+ var ACTIVE_LOCAL_RUN_STATUSES = new Set([
14
+ "created",
15
+ "preparing",
16
+ "running",
17
+ "validating",
18
+ "reviewing",
19
+ "closing-out"
20
+ ]);
21
+ function processExists(pid) {
22
+ if (!Number.isInteger(pid) || pid <= 0)
23
+ return false;
24
+ try {
25
+ process.kill(pid, 0);
26
+ return true;
27
+ } catch {
28
+ return false;
29
+ }
30
+ }
31
+ async function defaultProjectRunFromSession(source, runId) {
32
+ const mod = await import("@rig/runtime/control-plane/run-session-projection");
33
+ const candidate = Reflect.get(mod, "projectRunFromSession");
34
+ if (typeof candidate !== "function") {
35
+ throw new Error("@rig/runtime/control-plane/run-session-projection does not export projectRunFromSession yet; inject projectRunFromSession until RunState lands it.");
36
+ }
37
+ return candidate(source, runId);
38
+ }
39
+ async function defaultOpenSession(sessionPath) {
40
+ return await SessionManager.open(sessionPath, undefined, undefined, { suppressBreadcrumb: true });
41
+ }
42
+ function projectionRunId(item) {
43
+ if (item.runId?.trim())
44
+ return item.runId.trim();
45
+ if (item.collab?.sessionId?.trim())
46
+ return item.collab.sessionId.trim();
47
+ if (item.session.id?.trim())
48
+ return item.session.id.trim();
49
+ return null;
50
+ }
51
+ function isLocallyDiscovered(item) {
52
+ return item.source === "session-list";
53
+ }
54
+ function isActiveStatus(status) {
55
+ if (status === null)
56
+ return false;
57
+ return !isTerminalRunStatus(status);
58
+ }
59
+ function shouldFlip(item, status, exists) {
60
+ if (!isActiveStatus(status))
61
+ return false;
62
+ if (item.collab?.stale === true)
63
+ return true;
64
+ const pid = item.collab?.pid;
65
+ return isLocallyDiscovered(item) && pid !== undefined && ACTIVE_LOCAL_RUN_STATUSES.has(status) && !exists(pid);
66
+ }
67
+ function failedStatusData(status, at) {
68
+ return {
69
+ type: "status-changed",
70
+ from: status,
71
+ to: "failed",
72
+ reason: "lazy-reconcile:dead-pid",
73
+ actor: { kind: "agent" },
74
+ at
75
+ };
76
+ }
77
+ async function runLazyReconcile(input, deps = {}) {
78
+ const listProjections = deps.listCollabSessionProjections ?? ompListCollabSessionProjections;
79
+ const projectRun = deps.projectRunFromSession ?? defaultProjectRunFromSession;
80
+ const exists = deps.processExists ?? processExists;
81
+ const openSession = deps.openSession ?? defaultOpenSession;
82
+ const nowIso = deps.nowIso ?? (() => new Date().toISOString());
83
+ const projections = await listProjections(input.identityFilter);
84
+ const flipped = [];
85
+ for (const item of projections) {
86
+ const runId = projectionRunId(item);
87
+ const sessionPath = item.session.path || item.collab?.sessionPath || "";
88
+ if (!runId || !sessionPath)
89
+ continue;
90
+ const projection = await projectRun(item.customEntries, runId);
91
+ const status = projection.status;
92
+ if (status === null || !shouldFlip(item, status, exists))
93
+ continue;
94
+ const session = await openSession(sessionPath);
95
+ session.appendCustomEntry(CUSTOM_TYPE_FOR["status-changed"], failedStatusData(status, nowIso()));
96
+ flipped.push({ runId, sessionPath, reason: "lazy-reconcile:dead-pid" });
97
+ }
98
+ return { flipped, resumable: flipped };
99
+ }
100
+ export {
101
+ runLazyReconcile
102
+ };
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  // packages/cli/src/commands/_paths.ts
3
3
  import { resolve } from "path";
4
- import { resolveMonorepoRoot } from "@rig/runtime/control-plane/native/utils";
4
+ import { resolveMonorepoRoot } from "@rig/runtime/layout";
5
5
  function resolveControlPlaneMonorepoRoot(projectRoot) {
6
6
  return resolveMonorepoRoot(projectRoot);
7
7
  }
@@ -1,17 +1,17 @@
1
1
  import type { RunnerContext } from "../runner";
2
2
  type AttachResult = {
3
- run: Record<string, unknown>;
4
- logs: Record<string, unknown>[];
5
- timeline: Record<string, unknown>[];
6
- timelineCursor: string | null;
7
- steered: boolean;
8
- rendered: string;
9
- detached?: boolean;
3
+ readonly run: Record<string, unknown>;
4
+ readonly logs: Record<string, unknown>[];
5
+ readonly timeline: Record<string, unknown>[];
6
+ readonly timelineCursor: string | null;
7
+ readonly steered: boolean;
8
+ readonly rendered: string;
9
+ readonly detached?: boolean;
10
10
  };
11
+ export declare function resolveOperatorDroneCwd(runId: string, homeDir?: string): string;
11
12
  /**
12
- * Compose the operator-session environment for the attached Pi console.
13
- * Exported for tests: this is the contract between `rig run attach` and the
14
- * pi-rig extension's context discovery (see packages/pi-rig/src/client.ts).
13
+ * Compose the operator-session environment used by the legacy interactive
14
+ * attach shim. Exported for tests that pin the env contract.
15
15
  */
16
16
  export declare function buildOperatorPiEnv(input: {
17
17
  readonly runId: string;
@@ -20,8 +20,16 @@ export declare function buildOperatorPiEnv(input: {
20
20
  readonly serverProjectRoot?: string | null;
21
21
  readonly sessionDir: string;
22
22
  }): Record<string, string>;
23
+ export declare function shouldRequireOperatorTranscript(status: unknown): boolean;
24
+ export declare function missingOperatorTranscriptMessage(runId: string, status: unknown): string;
25
+ /**
26
+ * Run `body` in-process while RETURNING (instead of terminating) when it calls
27
+ * `process.exit`. Exported for unit tests that pin the guard semantics.
28
+ */
29
+ export declare function runWithProcessExitGuard(body: () => Promise<unknown>): Promise<number>;
23
30
  export declare function attachRunBundledPiFrontend(context: Pick<RunnerContext, "projectRoot" | "outputMode">, input: {
24
31
  readonly runId: string;
25
32
  readonly steered?: boolean;
33
+ readonly returnOnQuit?: boolean;
26
34
  }): Promise<AttachResult>;
27
35
  export {};