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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/README.md +1 -1
  2. package/dist/bin/build-rig-binaries.d.ts +2 -0
  3. package/dist/bin/rig.d.ts +2 -0
  4. package/dist/bin/rig.js +11052 -6668
  5. package/dist/src/app/board.d.ts +23 -0
  6. package/dist/src/app/board.js +1786 -0
  7. package/dist/src/app/drone-ui.d.ts +37 -0
  8. package/dist/src/app/drone-ui.js +294 -0
  9. package/dist/src/app/theme.d.ts +47 -0
  10. package/dist/src/app/theme.js +150 -0
  11. package/dist/src/commands/_async-ui.d.ts +13 -0
  12. package/dist/src/commands/_async-ui.js +223 -0
  13. package/dist/src/commands/_authority-runs.d.ts +22 -0
  14. package/dist/src/commands/_authority-runs.js +2 -3
  15. package/dist/src/commands/_cli-format.d.ts +49 -0
  16. package/dist/src/commands/_cli-format.js +447 -0
  17. package/dist/src/commands/_connection-state.d.ts +44 -0
  18. package/dist/src/commands/_connection-state.js +30 -11
  19. package/dist/src/commands/_doctor-checks.d.ts +52 -0
  20. package/dist/src/commands/_doctor-checks.js +180 -44
  21. package/dist/src/commands/_help-catalog.d.ts +51 -0
  22. package/dist/src/commands/_help-catalog.js +442 -0
  23. package/dist/src/commands/_json-output.d.ts +11 -0
  24. package/dist/src/commands/_json-output.js +56 -0
  25. package/dist/src/commands/_operator-surface.d.ts +34 -0
  26. package/dist/src/commands/_operator-surface.js +220 -0
  27. package/dist/src/commands/_operator-view.d.ts +30 -0
  28. package/dist/src/commands/_operator-view.js +803 -73
  29. package/dist/src/commands/_parsers.d.ts +15 -0
  30. package/dist/src/commands/_parsers.js +18 -11
  31. package/dist/src/commands/_paths.d.ts +11 -0
  32. package/dist/src/commands/_pi-frontend.d.ts +27 -0
  33. package/dist/src/commands/_pi-frontend.js +742 -0
  34. package/dist/src/commands/_pi-install.d.ts +42 -0
  35. package/dist/src/commands/_pi-install.js +5 -4
  36. package/dist/src/commands/_policy.d.ts +8 -0
  37. package/dist/src/commands/_policy.js +12 -5
  38. package/dist/src/commands/_preflight.d.ts +22 -0
  39. package/dist/src/commands/_preflight.js +190 -128
  40. package/dist/src/commands/_probes.d.ts +1 -0
  41. package/dist/src/commands/_run-driver-helpers.d.ts +99 -0
  42. package/dist/src/commands/_run-driver-helpers.js +75 -22
  43. package/dist/src/commands/_run-replay.d.ts +24 -0
  44. package/dist/src/commands/_run-replay.js +142 -0
  45. package/dist/src/commands/_server-client.d.ts +186 -0
  46. package/dist/src/commands/_server-client.js +360 -61
  47. package/dist/src/commands/_snapshot-upload.d.ts +39 -0
  48. package/dist/src/commands/_snapshot-upload.js +163 -39
  49. package/dist/src/commands/_spinner.d.ts +25 -0
  50. package/dist/src/commands/_spinner.js +65 -0
  51. package/dist/src/commands/_task-picker.d.ts +9 -0
  52. package/dist/src/commands/_task-picker.js +172 -19
  53. package/dist/src/commands/agent.d.ts +3 -0
  54. package/dist/src/commands/agent.js +39 -20
  55. package/dist/src/commands/browser.d.ts +65 -0
  56. package/dist/src/commands/browser.js +334 -51
  57. package/dist/src/commands/connect.d.ts +7 -0
  58. package/dist/src/commands/connect.js +272 -33
  59. package/dist/src/commands/dist.d.ts +28 -0
  60. package/dist/src/commands/dist.js +19 -12
  61. package/dist/src/commands/doctor.d.ts +3 -0
  62. package/dist/src/commands/doctor.js +378 -45
  63. package/dist/src/commands/github.d.ts +3 -0
  64. package/dist/src/commands/github.js +375 -53
  65. package/dist/src/commands/inbox.d.ts +30 -0
  66. package/dist/src/commands/inbox.js +760 -70
  67. package/dist/src/commands/init.d.ts +74 -0
  68. package/dist/src/commands/init.js +963 -119
  69. package/dist/src/commands/inspect.d.ts +3 -0
  70. package/dist/src/commands/inspect.js +588 -32
  71. package/dist/src/commands/inspector.d.ts +3 -0
  72. package/dist/src/commands/inspector.js +20 -13
  73. package/dist/src/commands/pi.d.ts +3 -0
  74. package/dist/src/commands/pi.js +177 -0
  75. package/dist/src/commands/plugin.d.ts +16 -0
  76. package/dist/src/commands/plugin.js +95 -27
  77. package/dist/src/commands/profile-and-review.d.ts +4 -0
  78. package/dist/src/commands/profile-and-review.js +26 -19
  79. package/dist/src/commands/queue.d.ts +3 -0
  80. package/dist/src/commands/queue.js +32 -12
  81. package/dist/src/commands/remote.d.ts +3 -0
  82. package/dist/src/commands/remote.js +43 -36
  83. package/dist/src/commands/repo-git-harness.d.ts +5 -0
  84. package/dist/src/commands/repo-git-harness.js +22 -15
  85. package/dist/src/commands/run.d.ts +3 -0
  86. package/dist/src/commands/run.js +1379 -159
  87. package/dist/src/commands/server.d.ts +7 -0
  88. package/dist/src/commands/server.js +502 -57
  89. package/dist/src/commands/setup.d.ts +16 -0
  90. package/dist/src/commands/setup.js +390 -63
  91. package/dist/src/commands/stats.d.ts +12 -0
  92. package/dist/src/commands/stats.js +1051 -0
  93. package/dist/src/commands/task-report-bug.d.ts +19 -0
  94. package/dist/src/commands/task-report-bug.js +260 -62
  95. package/dist/src/commands/task-run-driver.d.ts +132 -0
  96. package/dist/src/commands/task-run-driver.js +886 -130
  97. package/dist/src/commands/task.d.ts +14 -0
  98. package/dist/src/commands/task.js +1644 -314
  99. package/dist/src/commands/test.d.ts +3 -0
  100. package/dist/src/commands/test.js +15 -8
  101. package/dist/src/commands/workspace.d.ts +3 -0
  102. package/dist/src/commands/workspace.js +18 -11
  103. package/dist/src/commands.d.ts +29 -0
  104. package/dist/src/commands.js +10967 -6637
  105. package/dist/src/index.d.ts +4 -0
  106. package/dist/src/index.js +10168 -5787
  107. package/dist/src/launcher.d.ts +61 -0
  108. package/dist/src/launcher.js +77 -13
  109. package/dist/src/report-bug.d.ts +44 -0
  110. package/dist/src/report-bug.js +3 -3
  111. package/dist/src/runner.d.ts +47 -0
  112. package/dist/src/runner.js +16 -22
  113. package/dist/src/withMutedConsole.d.ts +2 -0
  114. package/package.json +13 -6
@@ -0,0 +1,99 @@
1
+ import { type AuthorityRunPatch, type AuthorityRunRecord } from "@rig/runtime/control-plane/authority-files";
2
+ import type { RunStatus } from "@rig/contracts";
3
+ export type SourceTaskContract = {
4
+ id: string;
5
+ title?: string | null;
6
+ description?: string | null;
7
+ body?: string | null;
8
+ acceptanceCriteria?: string | null;
9
+ acceptance_criteria?: string | null;
10
+ sourceIssueId?: string | null;
11
+ status?: string | null;
12
+ issueType?: string | null;
13
+ role?: string | null;
14
+ externalRef?: string | null;
15
+ scope?: readonly string[];
16
+ validation?: readonly string[];
17
+ validators?: readonly string[];
18
+ labels?: readonly string[];
19
+ };
20
+ export declare function patchAuthorityRun(projectRoot: string, runId: string, patch: AuthorityRunPatch): AuthorityRunRecord;
21
+ /**
22
+ * THE status mutation on the CLI driver side: transition-checked and
23
+ * journaled as a status-changed event (see @rig/contracts run-journal).
24
+ */
25
+ export declare function setRunStatusOrFail(projectRoot: string, runId: string, to: RunStatus, options?: {
26
+ reason?: string | null;
27
+ errorText?: string | null;
28
+ }): AuthorityRunRecord;
29
+ export declare function touchAuthorityRun(projectRoot: string, runId: string): void;
30
+ export declare function appendRunTimeline(projectRoot: string, runId: string, value: Record<string, unknown>): void;
31
+ export declare function appendRunLog(projectRoot: string, runId: string, value: Record<string, unknown>): void;
32
+ type RunActionInput = {
33
+ id: string;
34
+ actionType: string;
35
+ title: string;
36
+ detail?: string | null;
37
+ state: "running" | "completed" | "failed";
38
+ startedAt: string;
39
+ completedAt?: string | null;
40
+ payload?: Record<string, unknown>;
41
+ };
42
+ export declare function appendRunAction(projectRoot: string, runId: string, value: RunActionInput): void;
43
+ export type RunActionHandle = {
44
+ startedAt: string;
45
+ complete: (detail?: string | null, payload?: Record<string, unknown>) => void;
46
+ fail: (detail: string, payload?: Record<string, unknown>) => void;
47
+ };
48
+ export declare function startRunAction(projectRoot: string, runId: string, input: {
49
+ actionId: string;
50
+ actionType: string;
51
+ title: string;
52
+ detail?: string | null;
53
+ payload?: Record<string, unknown>;
54
+ }): RunActionHandle;
55
+ export type RunEvent = {
56
+ type: "status";
57
+ runId: string;
58
+ status: string;
59
+ detail?: string | null;
60
+ sessionId?: string | null;
61
+ } | {
62
+ type: "timeline";
63
+ runId: string;
64
+ } | {
65
+ type: "log";
66
+ runId: string;
67
+ title?: string;
68
+ } | {
69
+ type: "completed";
70
+ runId: string;
71
+ } | {
72
+ type: "failed";
73
+ runId: string;
74
+ error: string;
75
+ };
76
+ /**
77
+ * Route emitServerRunEvent through the run.jsonl lifecycle log + doorbell in
78
+ * addition to stdout. Called once at the start of executeRigOwnedTaskRun.
79
+ */
80
+ export declare function configureRunEventSink(projectRoot: string): void;
81
+ /**
82
+ * Print a parseable status line to stdout that the server's spawn-and-watch
83
+ * path reads to update its own state. Format: `__RIG_RUN_EVENT__<json>`.
84
+ *
85
+ * When `configureRunEventSink` has run, the same event is also appended to
86
+ * the run's `run.jsonl` lifecycle log and the server doorbell is rung.
87
+ */
88
+ export declare function emitServerRunEvent(event: RunEvent): void;
89
+ export declare function buildRunPrompt(input: {
90
+ projectRoot: string;
91
+ taskId?: string;
92
+ fallbackTitle?: string | null;
93
+ fallbackDescription?: string | null;
94
+ fallbackAcceptanceCriteria?: string | null;
95
+ sourceTask?: SourceTaskContract | null;
96
+ initialPrompt?: string;
97
+ runtimeAdapter: "claude-code" | "codex" | "pi";
98
+ }): string;
99
+ export {};
@@ -5,21 +5,33 @@ import { resolve as resolve3 } from "path";
5
5
 
6
6
  // packages/cli/src/runner.ts
7
7
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
8
- import { CliError } from "@rig/runtime/control-plane/errors";
8
+ import { CliError as RuntimeCliError } from "@rig/runtime/control-plane/errors";
9
9
  import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
10
- import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
11
- import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
12
10
  import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
13
- import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
11
+
12
+ class CliError extends RuntimeCliError {
13
+ hint;
14
+ constructor(message, exitCode = 1, options = {}) {
15
+ super(message, exitCode);
16
+ if (options.hint?.trim()) {
17
+ this.hint = options.hint.trim();
18
+ }
19
+ }
20
+ }
14
21
 
15
22
  // packages/cli/src/commands/_run-driver-helpers.ts
16
23
  import {
17
- appendJsonlRecord,
24
+ appendRunJournalEvent,
25
+ appendRunLogEntry,
26
+ appendRunTimelineEntry,
27
+ patchAuthorityRunRecord,
18
28
  readAuthorityRun as readAuthorityRun2,
19
- resolveAuthorityRunDir as resolveAuthorityRunDir2,
20
- writeJsonFile as writeJsonFile2
29
+ resolveAuthorityRunDir,
30
+ setAuthorityRunStatus,
31
+ writeJsonFile
21
32
  } from "@rig/runtime/control-plane/authority-files";
22
33
  import { taskLookup } from "@rig/runtime/control-plane/native/task-ops";
34
+ import { readPriorPrProgressPromptSection } from "@rig/runtime/control-plane/prompt-context";
23
35
  import { buildProviderTaskRunInstructionLines } from "@rig/runtime/control-plane/provider/runtime-instructions";
24
36
  import { loadRigTaskRunSkillBody } from "@rig/runtime/control-plane/provider/rig-task-run-skill";
25
37
 
@@ -29,8 +41,7 @@ import { resolve as resolve2 } from "path";
29
41
  import {
30
42
  readAuthorityRun,
31
43
  readJsonlFile,
32
- resolveAuthorityRunDir,
33
- writeJsonFile
44
+ writeAuthorityRunRecord
34
45
  } from "@rig/runtime/control-plane/authority-files";
35
46
 
36
47
  // packages/cli/src/commands/_paths.ts
@@ -64,16 +75,20 @@ function readLatestBeadRecord(projectRoot, taskId) {
64
75
 
65
76
  // packages/cli/src/commands/_run-driver-helpers.ts
66
77
  function patchAuthorityRun(projectRoot, runId, patch) {
67
- const current = readAuthorityRun2(projectRoot, runId);
68
- if (!current) {
69
- throw new CliError2(`Run not found: ${runId}`, 2);
78
+ const next = patchAuthorityRunRecord(projectRoot, runId, patch);
79
+ if (!next) {
80
+ throw new CliError(`Run not found: ${runId}`, 2, { hint: "Run `rig run list` to see recorded runs." });
81
+ }
82
+ return next;
83
+ }
84
+ function setRunStatusOrFail(projectRoot, runId, to, options = {}) {
85
+ const next = setAuthorityRunStatus(projectRoot, runId, to, {
86
+ ...options,
87
+ actor: { kind: "agent" }
88
+ });
89
+ if (!next) {
90
+ throw new CliError(`Run not found: ${runId}`, 2, { hint: "Run `rig run list` to see recorded runs." });
70
91
  }
71
- const next = {
72
- ...current,
73
- ...patch,
74
- updatedAt: new Date().toISOString()
75
- };
76
- writeJsonFile2(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), next);
77
92
  return next;
78
93
  }
79
94
  function touchAuthorityRun(projectRoot, runId) {
@@ -81,21 +96,21 @@ function touchAuthorityRun(projectRoot, runId) {
81
96
  if (!current) {
82
97
  return;
83
98
  }
84
- writeJsonFile2(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "run.json"), {
99
+ writeJsonFile(resolve3(resolveAuthorityRunDir(projectRoot, runId), "run.json"), {
85
100
  ...current,
86
101
  updatedAt: new Date().toISOString()
87
102
  });
88
103
  }
89
104
  function appendRunTimeline(projectRoot, runId, value) {
90
- appendJsonlRecord(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "timeline.jsonl"), value);
105
+ appendRunTimelineEntry(projectRoot, runId, value);
91
106
  touchAuthorityRun(projectRoot, runId);
92
107
  }
93
108
  function appendRunLog(projectRoot, runId, value) {
94
- appendJsonlRecord(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "logs.jsonl"), value);
109
+ appendRunLogEntry(projectRoot, runId, value);
95
110
  touchAuthorityRun(projectRoot, runId);
96
111
  }
97
112
  function appendRunAction(projectRoot, runId, value) {
98
- appendJsonlRecord(resolve3(resolveAuthorityRunDir2(projectRoot, runId), "timeline.jsonl"), {
113
+ appendRunTimelineEntry(projectRoot, runId, {
99
114
  id: value.id,
100
115
  type: "action",
101
116
  actionType: value.actionType,
@@ -149,8 +164,43 @@ function startRunAction(projectRoot, runId, input) {
149
164
  }
150
165
  };
151
166
  }
167
+ var runEventSinkProjectRoot = null;
168
+ function configureRunEventSink(projectRoot) {
169
+ runEventSinkProjectRoot = projectRoot;
170
+ }
171
+ var lastDoorbellRangAt = 0;
172
+ function ringServerRunDoorbell(runId) {
173
+ const serverUrl = process.env.RIG_SERVER_URL?.trim();
174
+ if (!serverUrl)
175
+ return;
176
+ const now = Date.now();
177
+ if (now - lastDoorbellRangAt < 250)
178
+ return;
179
+ lastDoorbellRangAt = now;
180
+ const token = process.env.RIG_AUTH_TOKEN || process.env.RIG_GITHUB_TOKEN || "";
181
+ fetch(`${serverUrl.replace(/\/+$/, "")}/api/runs/doorbell`, {
182
+ method: "POST",
183
+ headers: {
184
+ "content-type": "application/json",
185
+ authorization: `Bearer ${token}`
186
+ },
187
+ body: JSON.stringify({ runId }),
188
+ signal: AbortSignal.timeout(1000)
189
+ }).catch(() => {});
190
+ }
152
191
  function emitServerRunEvent(event) {
153
192
  console.log(`__RIG_RUN_EVENT__${JSON.stringify({ ...event, at: new Date().toISOString() })}`);
193
+ if (runEventSinkProjectRoot) {
194
+ try {
195
+ if (event.type === "status" || event.type === "completed" || event.type === "failed") {
196
+ appendRunJournalEvent(runEventSinkProjectRoot, event.runId, {
197
+ type: "timeline-entry",
198
+ payload: { kind: "driver-event", ...event }
199
+ });
200
+ }
201
+ } catch {}
202
+ ringServerRunDoorbell(event.runId);
203
+ }
154
204
  }
155
205
  function buildRunPrompt(input) {
156
206
  const initialPrompt = input.initialPrompt?.trim() || null;
@@ -207,6 +257,7 @@ ${acceptance}` : null,
207
257
  ${sourceContractLines.join(`
208
258
  `)}` : null,
209
259
  scopeText || renderSourceScopeValidation(sourceTask, sourceValidation) || null,
260
+ readPriorPrProgressPromptSection(input.projectRoot, input.taskId),
210
261
  initialPrompt ? `Additional operator guidance:
211
262
  ${initialPrompt}` : null,
212
263
  providerLines.length > 0 ? `Provider-specific runtime tooling:
@@ -280,8 +331,10 @@ function renderSourceScopeValidation(task, validation) {
280
331
  export {
281
332
  touchAuthorityRun,
282
333
  startRunAction,
334
+ setRunStatusOrFail,
283
335
  patchAuthorityRun,
284
336
  emitServerRunEvent,
337
+ configureRunEventSink,
285
338
  buildRunPrompt,
286
339
  appendRunTimeline,
287
340
  appendRunLog,
@@ -0,0 +1,24 @@
1
+ import { type AuthorityRunRecord } from "@rig/runtime/control-plane/authority-files";
2
+ export type RunReplayLine = {
3
+ at: string | null;
4
+ source: "run" | "session";
5
+ summary: string;
6
+ };
7
+ export type RunReplayResult = {
8
+ runId: string;
9
+ logPath: string;
10
+ sessionFile: string | null;
11
+ entryCount: number;
12
+ sessionEntryCount: number;
13
+ lines: string[];
14
+ };
15
+ /**
16
+ * Locate the worker Pi session.jsonl for a run, without ever reading the file
17
+ * during the run lifecycle — replay-time only. Prefers the exact
18
+ * piSession.sessionFile recorded on the run record; falls back to scanning
19
+ * `<piSession.cwd>/.rig/session/` for `*_<sessionId>.jsonl`.
20
+ */
21
+ export declare function resolveRunSessionFile(record: AuthorityRunRecord | null): string | null;
22
+ export declare function buildRunReplay(projectRoot: string, runId: string, options?: {
23
+ withSession?: boolean;
24
+ }): RunReplayResult;
@@ -0,0 +1,142 @@
1
+ // @bun
2
+ // packages/cli/src/commands/_run-replay.ts
3
+ import { existsSync, readdirSync } from "fs";
4
+ import { join, resolve } from "path";
5
+ import {
6
+ readAuthorityRun,
7
+ readJsonlFile,
8
+ runJournalPath
9
+ } from "@rig/runtime/control-plane/authority-files";
10
+ function asRecord(value) {
11
+ return value && typeof value === "object" && !Array.isArray(value) ? value : null;
12
+ }
13
+ function text(value) {
14
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
15
+ }
16
+ function snippet(value, max = 120) {
17
+ const raw = text(value);
18
+ if (!raw)
19
+ return null;
20
+ const flat = raw.replace(/\s+/g, " ");
21
+ return flat.length > max ? `${flat.slice(0, max - 1)}\u2026` : flat;
22
+ }
23
+ function summarizeLifecycleEntry(entry) {
24
+ const type = text(entry.type) ?? "event";
25
+ switch (type) {
26
+ case "status": {
27
+ const anchor = text(entry.sessionId);
28
+ return [
29
+ `status \u2192 ${text(entry.status) ?? "(unknown)"}`,
30
+ snippet(entry.detail) ? `\u2014 ${snippet(entry.detail)}` : null,
31
+ anchor ? `[session ${anchor}]` : null
32
+ ].filter(Boolean).join(" ");
33
+ }
34
+ case "timeline-entry": {
35
+ const payload = asRecord(entry.payload) ?? {};
36
+ const kind = text(payload.type) ?? "entry";
37
+ const body = snippet(payload.title) ?? snippet(payload.text) ?? snippet(payload.detail);
38
+ const state = text(payload.state);
39
+ return [`timeline ${kind}`, body ? `\u2014 ${body}` : null, state ? `(${state})` : null].filter(Boolean).join(" ");
40
+ }
41
+ case "log-entry": {
42
+ const payload = asRecord(entry.payload) ?? {};
43
+ const title = snippet(payload.title) ?? "log";
44
+ const detail = snippet(payload.detail);
45
+ return [`log ${title}`, detail ? `\u2014 ${detail}` : null].filter(Boolean).join(" ");
46
+ }
47
+ case "record-patch": {
48
+ const patch = asRecord(entry.patch) ?? {};
49
+ const keys = Object.keys(patch);
50
+ const shown = keys.slice(0, 8).join(", ");
51
+ return `record-patch {${shown}${keys.length > 8 ? `, +${keys.length - 8} more` : ""}}`;
52
+ }
53
+ case "timeline":
54
+ return "timeline updated (signal)";
55
+ case "log":
56
+ return `log signal${snippet(entry.title) ? ` \u2014 ${snippet(entry.title)}` : ""}`;
57
+ case "completed":
58
+ return "run completed";
59
+ case "failed":
60
+ return `run failed${snippet(entry.error) ? ` \u2014 ${snippet(entry.error)}` : ""}`;
61
+ default:
62
+ return type;
63
+ }
64
+ }
65
+ function summarizeSessionEntry(entry) {
66
+ const type = text(entry.type) ?? "entry";
67
+ const message = asRecord(entry.message);
68
+ const role = text(message?.role);
69
+ const content = message?.content;
70
+ let body = null;
71
+ if (typeof content === "string") {
72
+ body = snippet(content);
73
+ } else if (Array.isArray(content)) {
74
+ body = snippet(content.map((part) => text(asRecord(part)?.text) ?? "").filter(Boolean).join(" "));
75
+ }
76
+ return [
77
+ `pi ${type}`,
78
+ role ? `(${role})` : null,
79
+ body ? `\u2014 ${body}` : null
80
+ ].filter(Boolean).join(" ");
81
+ }
82
+ function sessionEntryTimestamp(entry) {
83
+ return text(entry.timestamp) ?? text(entry.at) ?? text(entry.createdAt) ?? null;
84
+ }
85
+ function resolveRunSessionFile(record) {
86
+ const piSession = record?.piSession ?? null;
87
+ if (!piSession)
88
+ return null;
89
+ const recorded = text(piSession.sessionFile);
90
+ if (recorded && existsSync(recorded)) {
91
+ return recorded;
92
+ }
93
+ const cwd = text(piSession.cwd);
94
+ const sessionId = text(piSession.sessionId);
95
+ if (!cwd || !sessionId)
96
+ return null;
97
+ const sessionDir = resolve(cwd, ".rig", "session");
98
+ try {
99
+ const match = readdirSync(sessionDir).find((name) => name.endsWith(`_${sessionId}.jsonl`));
100
+ return match ? join(sessionDir, match) : null;
101
+ } catch {
102
+ return null;
103
+ }
104
+ }
105
+ function buildRunReplay(projectRoot, runId, options = {}) {
106
+ const logPath = runJournalPath(projectRoot, runId);
107
+ const record = readAuthorityRun(projectRoot, runId);
108
+ const lifecycleEntries = readJsonlFile(logPath).map((entry) => asRecord(entry)).filter((entry) => entry !== null);
109
+ const merged = lifecycleEntries.map((entry) => ({
110
+ at: text(entry.at),
111
+ source: "run",
112
+ summary: summarizeLifecycleEntry(entry)
113
+ }));
114
+ let sessionFile = null;
115
+ let sessionEntryCount = 0;
116
+ if (options.withSession) {
117
+ sessionFile = resolveRunSessionFile(record);
118
+ if (sessionFile) {
119
+ let lastSeenAt = null;
120
+ const sessionLines = readJsonlFile(sessionFile).map((entry) => asRecord(entry)).filter((entry) => entry !== null).map((entry) => {
121
+ lastSeenAt = sessionEntryTimestamp(entry) ?? lastSeenAt;
122
+ return { at: lastSeenAt, source: "session", summary: summarizeSessionEntry(entry) };
123
+ });
124
+ sessionEntryCount = sessionLines.length;
125
+ merged.push(...sessionLines);
126
+ merged.sort((left, right) => (left.at ?? "").localeCompare(right.at ?? ""));
127
+ }
128
+ }
129
+ const lines = merged.map((line) => `${line.at ?? "(no timestamp) "} ${line.source === "run" ? "run " : "session"} ${line.summary}`);
130
+ return {
131
+ runId,
132
+ logPath,
133
+ sessionFile,
134
+ entryCount: lifecycleEntries.length,
135
+ sessionEntryCount,
136
+ lines
137
+ };
138
+ }
139
+ export {
140
+ resolveRunSessionFile,
141
+ buildRunReplay
142
+ };
@@ -0,0 +1,186 @@
1
+ type ServerPhaseListener = (label: string) => void;
2
+ /** Returns the previously registered listener so scopes can restore it. */
3
+ export declare function setServerPhaseListener(listener: ServerPhaseListener | null): ServerPhaseListener | null;
4
+ export declare function setGitHubBearerTokenForCurrentProcess(token: string | null, projectRoot?: string): void;
5
+ export declare function ensureServerForCli(projectRoot: string): Promise<{
6
+ baseUrl: string;
7
+ authToken: string | null;
8
+ connectionKind: "local" | "remote";
9
+ serverProjectRoot: string | null;
10
+ }>;
11
+ export interface WorkspaceTaskFilters {
12
+ readonly assignee?: string;
13
+ readonly state?: string;
14
+ readonly status?: string;
15
+ readonly limit?: number;
16
+ }
17
+ export type WorkspaceTaskRecord = Record<string, unknown> & {
18
+ readonly id?: unknown;
19
+ readonly title?: unknown;
20
+ readonly status?: unknown;
21
+ };
22
+ export type SubmitTaskRunInput = {
23
+ runId: string;
24
+ taskId?: string;
25
+ title?: string;
26
+ runtimeAdapter: "claude-code" | "codex" | "pi";
27
+ model?: string;
28
+ runtimeMode: string;
29
+ interactionMode: string;
30
+ initialPrompt?: string;
31
+ baselineMode?: "head" | "dirty-snapshot";
32
+ prMode?: "auto" | "ask" | "off";
33
+ };
34
+ export declare function requestServerJson(context: {
35
+ projectRoot: string;
36
+ }, pathname: string, init?: RequestInit): Promise<unknown>;
37
+ export declare function listWorkspaceTasksViaServer(context: {
38
+ projectRoot: string;
39
+ }, filters?: WorkspaceTaskFilters): Promise<WorkspaceTaskRecord[]>;
40
+ export declare function getWorkspaceTaskViaServer(context: {
41
+ projectRoot: string;
42
+ }, taskId: string): Promise<WorkspaceTaskRecord | null>;
43
+ export declare function selectNextWorkspaceTaskViaServer(context: {
44
+ projectRoot: string;
45
+ }, filters?: WorkspaceTaskFilters): Promise<{
46
+ task: WorkspaceTaskRecord | null;
47
+ count: number;
48
+ }>;
49
+ /**
50
+ * Submit a run (task or ad-hoc) to the local rig server. Routes to
51
+ * /api/runs/task vs /api/runs/adhoc based on whether a taskId is provided.
52
+ *
53
+ * Caller is responsible for any pre-flight (e.g. project sync). This helper
54
+ * only performs the POST and surfaces server errors as CliError.
55
+ */
56
+ export declare function getGitHubAuthStatusViaServer(context: {
57
+ projectRoot: string;
58
+ }): Promise<Record<string, unknown>>;
59
+ export declare function postGitHubTokenViaServer(context: {
60
+ projectRoot: string;
61
+ }, token: string, options?: {
62
+ readonly selectedRepo?: string;
63
+ readonly projectRoot?: string;
64
+ }): Promise<Record<string, unknown>>;
65
+ export declare function prepareRemoteCheckoutViaServer(context: {
66
+ projectRoot: string;
67
+ }, input: {
68
+ repoSlug: string;
69
+ checkout: Record<string, unknown>;
70
+ repoUrl?: string;
71
+ baseDir?: string;
72
+ }): Promise<Record<string, unknown>>;
73
+ export declare function registerProjectViaServer(context: {
74
+ projectRoot: string;
75
+ }, input: {
76
+ repoSlug: string;
77
+ checkout?: Record<string, unknown>;
78
+ }): Promise<Record<string, unknown>>;
79
+ export declare function switchServerProjectRootViaServer(context: {
80
+ projectRoot: string;
81
+ }, projectRoot: string, options?: {
82
+ timeoutMs?: number;
83
+ pollMs?: number;
84
+ }): Promise<Record<string, unknown>>;
85
+ export declare function listRunsViaServer(context: {
86
+ projectRoot: string;
87
+ }, options?: {
88
+ limit?: number;
89
+ }): Promise<Record<string, unknown>[]>;
90
+ export declare function getRunDetailsViaServer(context: {
91
+ projectRoot: string;
92
+ }, runId: string): Promise<Record<string, unknown>>;
93
+ export declare function getRunLogsViaServer(context: {
94
+ projectRoot: string;
95
+ }, runId: string, options?: {
96
+ limit?: number;
97
+ cursor?: string;
98
+ }): Promise<Record<string, unknown>>;
99
+ export declare function getRunTimelineViaServer(context: {
100
+ projectRoot: string;
101
+ }, runId: string, options?: {
102
+ limit?: number;
103
+ cursor?: string;
104
+ }): Promise<Record<string, unknown>>;
105
+ export declare function ensureTaskLabelsViaServer(context: {
106
+ projectRoot: string;
107
+ }): Promise<Record<string, unknown>>;
108
+ export declare function listGitHubProjectsViaServer(context: {
109
+ projectRoot: string;
110
+ }, owner: string): Promise<Record<string, unknown>>;
111
+ export declare function getGitHubProjectStatusFieldViaServer(context: {
112
+ projectRoot: string;
113
+ }, projectId: string): Promise<Record<string, unknown>>;
114
+ export declare function updateWorkspaceTaskViaServer(context: {
115
+ projectRoot: string;
116
+ }, input: {
117
+ id: string;
118
+ status?: string;
119
+ comment?: string;
120
+ title?: string;
121
+ body?: string;
122
+ issueNodeId?: string | null;
123
+ }): Promise<Record<string, unknown>>;
124
+ /**
125
+ * Resume (or restart) a run through the selected server — works against the
126
+ * auto-started local daemon AND a remote connection, unlike the old
127
+ * runtime-side path that could only spawn a local engine-checkout server.
128
+ * Without an explicit run id, targets the most recently updated resumable
129
+ * run known to the server.
130
+ */
131
+ export declare function resumeRunViaServer(context: {
132
+ projectRoot: string;
133
+ }, runId: string | null, options: {
134
+ restart: boolean;
135
+ }): Promise<Record<string, unknown>>;
136
+ /** Short human label for the selected server — board/header decoration. */
137
+ export declare function resolveServerConnectionLabel(projectRoot: string): Promise<string>;
138
+ export declare function stopRunViaServer(context: {
139
+ projectRoot: string;
140
+ }, runId: string): Promise<Record<string, unknown>>;
141
+ export declare function steerRunViaServer(context: {
142
+ projectRoot: string;
143
+ }, runId: string, message: string): Promise<Record<string, unknown>>;
144
+ export declare function getRunPiSessionViaServer(context: {
145
+ projectRoot: string;
146
+ }, runId: string): Promise<Record<string, unknown>>;
147
+ export declare function getRunPiMessagesViaServer(context: {
148
+ projectRoot: string;
149
+ }, runId: string): Promise<Record<string, unknown>>;
150
+ export declare function getRunPiStatusViaServer(context: {
151
+ projectRoot: string;
152
+ }, runId: string): Promise<Record<string, unknown>>;
153
+ export declare function getRunPiCommandsViaServer(context: {
154
+ projectRoot: string;
155
+ }, runId: string): Promise<Record<string, unknown>>;
156
+ export declare function getRunPiCapabilitiesViaServer(context: {
157
+ projectRoot: string;
158
+ }, runId: string): Promise<Record<string, unknown>>;
159
+ export declare function sendRunPiPromptViaServer(context: {
160
+ projectRoot: string;
161
+ }, runId: string, text: string, streamingBehavior?: "steer" | "followUp"): Promise<Record<string, unknown>>;
162
+ export declare function sendRunPiShellViaServer(context: {
163
+ projectRoot: string;
164
+ }, runId: string, text: string): Promise<Record<string, unknown>>;
165
+ export declare function runRunPiCommandViaServer(context: {
166
+ projectRoot: string;
167
+ }, runId: string, text: string): Promise<Record<string, unknown>>;
168
+ export declare function respondRunPiExtensionUiViaServer(context: {
169
+ projectRoot: string;
170
+ }, runId: string, requestId: string, valueOrCancel: {
171
+ value?: unknown;
172
+ confirmed?: boolean;
173
+ cancelled?: boolean;
174
+ }): Promise<Record<string, unknown>>;
175
+ export declare function abortRunPiViaServer(context: {
176
+ projectRoot: string;
177
+ }, runId: string): Promise<Record<string, unknown>>;
178
+ export declare function buildRunPiEventsWebSocketUrl(context: {
179
+ projectRoot: string;
180
+ }, runId: string): Promise<string>;
181
+ export declare function submitTaskRunViaServer(context: {
182
+ projectRoot: string;
183
+ }, input: SubmitTaskRunInput): Promise<{
184
+ runId: string;
185
+ }>;
186
+ export {};