@h-rig/cli 0.0.6-alpha.5 → 0.0.6-alpha.50

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 (49) hide show
  1. package/dist/bin/rig.js +4072 -1204
  2. package/dist/src/commands/_cli-format.js +369 -0
  3. package/dist/src/commands/_connection-state.js +12 -6
  4. package/dist/src/commands/_doctor-checks.js +65 -34
  5. package/dist/src/commands/_help-catalog.js +445 -0
  6. package/dist/src/commands/_operator-surface.js +220 -0
  7. package/dist/src/commands/_operator-view.js +1109 -63
  8. package/dist/src/commands/_parsers.js +0 -2
  9. package/dist/src/commands/_pi-frontend.js +1066 -0
  10. package/dist/src/commands/_pi-install.js +4 -3
  11. package/dist/src/commands/_pi-remote-session.js +757 -0
  12. package/dist/src/commands/_pi-worker-bridge-extension.js +820 -0
  13. package/dist/src/commands/_policy.js +0 -2
  14. package/dist/src/commands/_preflight.js +84 -116
  15. package/dist/src/commands/_run-driver-helpers.js +2 -2
  16. package/dist/src/commands/_server-client.js +211 -48
  17. package/dist/src/commands/_snapshot-upload.js +60 -30
  18. package/dist/src/commands/_spinner.js +63 -0
  19. package/dist/src/commands/_task-picker.js +44 -16
  20. package/dist/src/commands/agent.js +8 -9
  21. package/dist/src/commands/browser.js +4 -6
  22. package/dist/src/commands/connect.js +134 -26
  23. package/dist/src/commands/dist.js +4 -6
  24. package/dist/src/commands/doctor.js +65 -34
  25. package/dist/src/commands/github.js +62 -32
  26. package/dist/src/commands/inbox.js +396 -31
  27. package/dist/src/commands/init.js +342 -88
  28. package/dist/src/commands/inspect.js +282 -23
  29. package/dist/src/commands/inspector.js +2 -4
  30. package/dist/src/commands/pi.js +168 -0
  31. package/dist/src/commands/plugin.js +81 -22
  32. package/dist/src/commands/profile-and-review.js +8 -10
  33. package/dist/src/commands/queue.js +2 -3
  34. package/dist/src/commands/remote.js +18 -20
  35. package/dist/src/commands/repo-git-harness.js +6 -8
  36. package/dist/src/commands/run.js +1407 -130
  37. package/dist/src/commands/server.js +266 -40
  38. package/dist/src/commands/setup.js +69 -44
  39. package/dist/src/commands/task-report-bug.js +5 -7
  40. package/dist/src/commands/task-run-driver.js +662 -70
  41. package/dist/src/commands/task.js +1846 -259
  42. package/dist/src/commands/test.js +3 -5
  43. package/dist/src/commands/workspace.js +4 -6
  44. package/dist/src/commands.js +4054 -1180
  45. package/dist/src/index.js +4065 -1200
  46. package/dist/src/launcher.js +5 -3
  47. package/dist/src/report-bug.js +3 -3
  48. package/dist/src/runner.js +5 -19
  49. package/package.json +7 -4
@@ -7,8 +7,6 @@ import { resolve } from "path";
7
7
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
8
8
  import { CliError } 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
11
  import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
14
12
  function formatCommand(parts) {
@@ -3,8 +3,6 @@
3
3
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
4
4
  import { CliError } from "@rig/runtime/control-plane/errors";
5
5
  import { evaluate, loadPolicy, resolveAction } from "@rig/runtime/control-plane/runtime/guard";
6
- import { PluginManager } from "@rig/runtime/control-plane/runtime/plugins";
7
- import { loadRuntimeContextFromEnv } from "@rig/runtime/control-plane/runtime/context";
8
6
  import { buildBinary } from "@rig/runtime/control-plane/runtime/isolation";
9
7
  import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
10
8
 
@@ -36,6 +34,11 @@ function readJsonFile(path) {
36
34
  throw new CliError2(`Invalid Rig connection state at ${path}: ${error instanceof Error ? error.message : String(error)}`, 1);
37
35
  }
38
36
  }
37
+ function writeJsonFile(path, value) {
38
+ mkdirSync(dirname(path), { recursive: true });
39
+ writeFileSync(path, `${JSON.stringify(value, null, 2)}
40
+ `, "utf8");
41
+ }
39
42
  function normalizeConnection(value) {
40
43
  if (!value || typeof value !== "object" || Array.isArray(value))
41
44
  return null;
@@ -76,29 +79,38 @@ function readRepoConnection(projectRoot) {
76
79
  return {
77
80
  selected,
78
81
  project: typeof record.project === "string" ? record.project : undefined,
79
- linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined
82
+ linkedAt: typeof record.linkedAt === "string" ? record.linkedAt : undefined,
83
+ serverProjectRoot: typeof record.serverProjectRoot === "string" && record.serverProjectRoot.trim() ? record.serverProjectRoot.trim() : undefined
80
84
  };
81
85
  }
86
+ function writeRepoConnection(projectRoot, state) {
87
+ writeJsonFile(resolveRepoConnectionPath(projectRoot), state);
88
+ }
82
89
  function resolveSelectedConnection(projectRoot, options = {}) {
83
90
  const repo = readRepoConnection(projectRoot);
84
91
  if (!repo)
85
92
  return null;
86
93
  if (repo.selected === "local")
87
- return { alias: "local", connection: { kind: "local", mode: "auto" } };
94
+ return { alias: "local", connection: { kind: "local", mode: "auto" }, serverProjectRoot: repo.serverProjectRoot };
88
95
  const global = readGlobalConnections(options);
89
96
  const connection = global.connections[repo.selected];
90
97
  if (!connection) {
91
- throw new CliError2(`Selected Rig connection "${repo.selected}" was not found. Run \`rig connect list\` or \`rig connect use local\`.`, 1);
98
+ throw new CliError2(`Selected Rig server "${repo.selected}" was not found. Run \`rig server list\` or \`rig server use local\`.`, 1);
92
99
  }
93
- return { alias: repo.selected, connection };
100
+ return { alias: repo.selected, connection, serverProjectRoot: repo.serverProjectRoot };
101
+ }
102
+ function writeRepoServerProjectRoot(projectRoot, serverProjectRoot) {
103
+ const repo = readRepoConnection(projectRoot);
104
+ if (!repo)
105
+ return;
106
+ writeRepoConnection(projectRoot, { ...repo, serverProjectRoot });
94
107
  }
95
108
 
96
109
  // packages/cli/src/commands/_server-client.ts
97
- import { spawnSync } from "child_process";
98
110
  import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
99
111
  import { resolve as resolve2 } from "path";
100
112
  import { ensureLocalRigServerConnection } from "@rig/runtime/local-server";
101
- var cachedGitHubBearerToken;
113
+ var scopedGitHubBearerTokens = new Map;
102
114
  function cleanToken(value) {
103
115
  const trimmed = value?.trim();
104
116
  return trimmed ? trimmed : null;
@@ -115,41 +127,33 @@ function readPrivateRemoteSessionToken(projectRoot) {
115
127
  }
116
128
  }
117
129
  function readGitHubBearerTokenForRemote(projectRoot) {
118
- if (cachedGitHubBearerToken !== undefined)
119
- return cachedGitHubBearerToken;
130
+ const scopedKey = resolve2(projectRoot);
131
+ if (scopedGitHubBearerTokens.has(scopedKey))
132
+ return scopedGitHubBearerTokens.get(scopedKey) ?? null;
120
133
  const privateSession = readPrivateRemoteSessionToken(projectRoot);
121
- if (privateSession) {
122
- cachedGitHubBearerToken = privateSession;
123
- return cachedGitHubBearerToken;
124
- }
125
- const envToken = cleanToken(process.env.RIG_GITHUB_TOKEN) ?? cleanToken(process.env.GITHUB_TOKEN) ?? cleanToken(process.env.GH_TOKEN);
126
- if (envToken) {
127
- cachedGitHubBearerToken = envToken;
128
- return cachedGitHubBearerToken;
129
- }
130
- const result = spawnSync("gh", ["auth", "token"], {
131
- encoding: "utf8",
132
- timeout: 5000,
133
- stdio: ["ignore", "pipe", "ignore"]
134
- });
135
- cachedGitHubBearerToken = result.status === 0 ? cleanToken(result.stdout) : null;
136
- return cachedGitHubBearerToken;
134
+ if (privateSession)
135
+ return privateSession;
136
+ return cleanToken(process.env.RIG_SERVER_AUTH_TOKEN) ?? cleanToken(process.env.RIG_REMOTE_AUTH_TOKEN);
137
137
  }
138
138
  async function ensureServerForCli(projectRoot) {
139
139
  try {
140
140
  const selected = resolveSelectedConnection(projectRoot);
141
141
  if (selected?.connection.kind === "remote") {
142
+ const authToken = readGitHubBearerTokenForRemote(projectRoot);
143
+ const serverProjectRoot = selected.serverProjectRoot ?? await backfillRemoteServerProjectRoot(projectRoot, selected.connection.baseUrl, authToken);
142
144
  return {
143
145
  baseUrl: selected.connection.baseUrl,
144
- authToken: readGitHubBearerTokenForRemote(projectRoot),
145
- connectionKind: "remote"
146
+ authToken,
147
+ connectionKind: "remote",
148
+ serverProjectRoot
146
149
  };
147
150
  }
148
151
  const connection = await ensureLocalRigServerConnection(projectRoot);
149
152
  return {
150
153
  baseUrl: connection.baseUrl,
151
154
  authToken: connection.authToken,
152
- connectionKind: "local"
155
+ connectionKind: "local",
156
+ serverProjectRoot: resolve2(projectRoot)
153
157
  };
154
158
  } catch (error) {
155
159
  if (error instanceof Error) {
@@ -158,6 +162,29 @@ async function ensureServerForCli(projectRoot) {
158
162
  throw error;
159
163
  }
160
164
  }
165
+ async function backfillRemoteServerProjectRoot(projectRoot, baseUrl, authToken) {
166
+ const repo = readRepoConnection(projectRoot);
167
+ const slug = repo?.project?.trim();
168
+ if (!slug)
169
+ return null;
170
+ try {
171
+ const response = await fetch(`${baseUrl}/api/projects/${encodeURIComponent(slug)}`, {
172
+ headers: mergeHeaders(undefined, authToken)
173
+ });
174
+ if (!response.ok)
175
+ return null;
176
+ const payload = await response.json();
177
+ const project = payload.project && typeof payload.project === "object" && !Array.isArray(payload.project) ? payload.project : null;
178
+ const checkouts = Array.isArray(project?.checkouts) ? project.checkouts : [];
179
+ const latestCheckout = [...checkouts].reverse().find((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry) && typeof entry.path === "string"));
180
+ const path = typeof latestCheckout?.path === "string" && latestCheckout.path.trim() ? latestCheckout.path.trim() : null;
181
+ if (path)
182
+ writeRepoServerProjectRoot(projectRoot, path);
183
+ return path;
184
+ } catch {
185
+ return null;
186
+ }
187
+ }
161
188
  function mergeHeaders(headers, authToken) {
162
189
  const merged = new Headers(headers);
163
190
  if (authToken) {
@@ -182,9 +209,12 @@ function diagnosticMessage(payload) {
182
209
  }
183
210
  async function requestServerJson(context, pathname, init = {}) {
184
211
  const server = await ensureServerForCli(context.projectRoot);
212
+ const headers = mergeHeaders(init.headers, server.authToken);
213
+ if (server.serverProjectRoot)
214
+ headers.set("x-rig-project-root", server.serverProjectRoot);
185
215
  const response = await fetch(`${server.baseUrl}${pathname}`, {
186
216
  ...init,
187
- headers: mergeHeaders(init.headers, server.authToken)
217
+ headers
188
218
  });
189
219
  const text = await response.text();
190
220
  const payload = text.trim().length > 0 ? (() => {
@@ -202,78 +232,6 @@ async function requestServerJson(context, pathname, init = {}) {
202
232
  return payload;
203
233
  }
204
234
 
205
- // packages/cli/src/commands/_pi-install.ts
206
- import { existsSync as existsSync3, readFileSync as readFileSync3, rmSync } from "fs";
207
- import { homedir as homedir2 } from "os";
208
- import { resolve as resolve3 } from "path";
209
- var PI_RIG_PACKAGE_NAME = "@rig/pi-rig";
210
- async function defaultCommandRunner(command, options = {}) {
211
- const proc = Bun.spawn(command, { cwd: options.cwd, stdout: "pipe", stderr: "pipe" });
212
- const [stdout, stderr, exitCode] = await Promise.all([
213
- new Response(proc.stdout).text(),
214
- new Response(proc.stderr).text(),
215
- proc.exited
216
- ]);
217
- return { exitCode, stdout, stderr };
218
- }
219
- function resolvePiRigExtensionPath(homeDir) {
220
- return resolve3(homeDir, ".pi", "agent", "extensions", "pi-rig");
221
- }
222
- function resolvePiHomeDir(inputHomeDir) {
223
- return inputHomeDir ?? process.env.RIG_PI_HOME_DIR?.trim() ?? homedir2();
224
- }
225
- function piListContainsPiRig(output) {
226
- return output.split(/\r?\n/).some((line) => {
227
- const normalized = line.trim();
228
- return normalized.includes(PI_RIG_PACKAGE_NAME) || /(?:^|[\\/])packages[\\/]pi-rig(?:$|\s)/.test(normalized);
229
- });
230
- }
231
- async function safeRun(runner, command, options) {
232
- try {
233
- return await runner(command, options);
234
- } catch (error) {
235
- return { exitCode: 1, stdout: "", stderr: error instanceof Error ? error.message : String(error) };
236
- }
237
- }
238
- async function checkPiRigInstall(input = {}) {
239
- const home = resolvePiHomeDir(input.homeDir);
240
- const extensionPath = resolvePiRigExtensionPath(home);
241
- if (process.env.RIG_TEST_FAKE_PI_INSTALL === "1") {
242
- return {
243
- extensionPath,
244
- pi: { ok: true, label: "pi", detail: "fake-pi" },
245
- piRig: { ok: true, label: "pi-rig global extension", detail: extensionPath }
246
- };
247
- }
248
- const exists = input.exists ?? existsSync3;
249
- const runner = input.commandRunner ?? defaultCommandRunner;
250
- const piResult = await safeRun(runner, ["pi", "--version"]);
251
- const piListResult = piResult.exitCode === 0 ? await safeRun(runner, ["pi", "list"]) : { exitCode: 1, stdout: "", stderr: "" };
252
- const listedPiRig = piListResult.exitCode === 0 && piListContainsPiRig(`${piListResult.stdout}
253
- ${piListResult.stderr}`);
254
- const legacyBridge = exists(resolve3(extensionPath, "index.ts"));
255
- const hasPiRig = listedPiRig;
256
- return {
257
- extensionPath,
258
- pi: {
259
- ok: piResult.exitCode === 0,
260
- label: "pi",
261
- detail: (piResult.stdout || piResult.stderr).trim() || undefined,
262
- hint: piResult.exitCode === 0 ? undefined : "Install Pi or run `rig init --yes` to install/update the Pi runtime."
263
- },
264
- piRig: {
265
- ok: hasPiRig,
266
- label: "pi-rig global extension",
267
- detail: hasPiRig ? piListResult.stdout.trim() || PI_RIG_PACKAGE_NAME : legacyBridge ? `${extensionPath} (legacy bridge; reinstall required)` : undefined,
268
- hint: hasPiRig ? undefined : "Run `rig init --yes` to install/enable the global pi-rig package with `pi install`."
269
- }
270
- };
271
- }
272
- async function buildPiSetupChecks(input = {}) {
273
- const status = await checkPiRigInstall(input);
274
- return [status.pi, status.piRig];
275
- }
276
-
277
235
  // packages/cli/src/commands/_preflight.ts
278
236
  function preflightCheck(id, label, status, detail, remediation) {
279
237
  return {
@@ -329,6 +287,9 @@ function permissionAllowsPr(payload) {
329
287
  }
330
288
  return null;
331
289
  }
290
+ function isNotFoundError(error) {
291
+ return /\b(404|not found)\b/i.test(message(error));
292
+ }
332
293
  function projectCheckoutReady(payload) {
333
294
  if (!payload || typeof payload !== "object" || Array.isArray(payload))
334
295
  return null;
@@ -361,19 +322,33 @@ async function runFastTaskRunPreflight(context, options = {}) {
361
322
  const checks = [];
362
323
  const request = options.requestJson ?? ((pathname, init) => requestServerJson(context, pathname, init));
363
324
  const taskId = options.taskId?.trim() || null;
325
+ const requiresCurrentRunApi = Boolean(taskId);
326
+ const selectedServer = options.requestJson ? null : await ensureServerForCli(context.projectRoot).catch(() => null);
327
+ const allowLocalLegacyTaskRunCompatibility = selectedServer?.connectionKind === "local";
328
+ let legacyServerCompatibility = false;
364
329
  try {
365
330
  await request("/api/server/status");
366
331
  checks.push(preflightCheck("server", "Rig server reachable", "pass"));
367
332
  } catch (error) {
368
- checks.push(preflightCheck("server", "Rig server reachable", "fail", message(error), "Start or select a reachable Rig server."));
333
+ if (isNotFoundError(error)) {
334
+ try {
335
+ await request("/health");
336
+ legacyServerCompatibility = !requiresCurrentRunApi || allowLocalLegacyTaskRunCompatibility;
337
+ checks.push(requiresCurrentRunApi && !allowLocalLegacyTaskRunCompatibility ? preflightCheck("server", "Rig server reachable", "fail", "legacy /health endpoint only; current task-run APIs are required", "Upgrade/select the Rig server before launching a task run.") : preflightCheck("server", "Rig server reachable", "pass", allowLocalLegacyTaskRunCompatibility ? "local legacy /health endpoint; submit endpoint will be authoritative" : "legacy /health endpoint"));
338
+ } catch (healthError) {
339
+ checks.push(preflightCheck("server", "Rig server reachable", "fail", message(healthError), "Start or select a reachable Rig server."));
340
+ }
341
+ } else {
342
+ checks.push(preflightCheck("server", "Rig server reachable", "fail", message(error), "Start or select a reachable Rig server."));
343
+ }
369
344
  }
370
345
  const repo = readRepoConnection(context.projectRoot);
371
- checks.push(repo ? preflightCheck("project-link", "project linked to Rig connection", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to Rig connection", "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig connect use <alias|local>`."));
346
+ checks.push(repo ? preflightCheck("project-link", "project linked to Rig server", repo.project ? "pass" : "warn", `${repo.selected}${repo.project ? ` -> ${repo.project}` : ""}`, "Run `rig init --yes --repo owner/repo` to record the GitHub repo slug.") : preflightCheck("project-link", "project linked to Rig server", legacyServerCompatibility ? "warn" : "fail", "missing .rig/state/connection.json", "Run `rig init` or `rig server use <alias|local>`."));
372
347
  try {
373
348
  const auth = await request("/api/github/auth/status");
374
- checks.push(isAuthenticated(auth) ? preflightCheck("github-auth", "GitHub auth valid", "pass") : preflightCheck("github-auth", "GitHub auth valid", "fail", "not authenticated", "Run `rig github auth import-gh` or `rig github auth token --token <token>`."));
349
+ checks.push(isAuthenticated(auth) ? preflightCheck("github-auth", "GitHub auth valid", "pass") : preflightCheck("github-auth", "GitHub auth valid", legacyServerCompatibility ? "warn" : "fail", "not authenticated", "Run `rig github auth import-gh` or `rig github auth token --token <token>`."));
375
350
  } catch (error) {
376
- checks.push(preflightCheck("github-auth", "GitHub auth valid", "fail", message(error), "Fix GitHub auth on the selected Rig server."));
351
+ checks.push(preflightCheck("github-auth", "GitHub auth valid", legacyServerCompatibility ? "warn" : "fail", message(error), "Fix GitHub auth on the selected Rig server."));
377
352
  }
378
353
  try {
379
354
  const projection = await request("/api/workspace/task-projection");
@@ -401,9 +376,9 @@ async function runFastTaskRunPreflight(context, options = {}) {
401
376
  try {
402
377
  const tasks = await request(`/api/workspace/tasks?limit=200&refresh=1`);
403
378
  const found = Array.isArray(tasks) && tasks.some((task) => taskMatchesId(task, taskId));
404
- checks.push(found ? preflightCheck("issue", "task/issue accessible", "pass", taskId) : preflightCheck("issue", "task/issue accessible", "fail", taskId, "Confirm the issue exists and matches the configured task filters."));
379
+ checks.push(found ? preflightCheck("issue", "task/issue accessible", "pass", taskId) : preflightCheck("issue", "task/issue accessible", legacyServerCompatibility ? "warn" : "fail", taskId, "Confirm the issue exists and matches the configured task filters."));
405
380
  } catch (error) {
406
- checks.push(preflightCheck("issue", "task/issue accessible", "fail", message(error), "Fix the task source before launching a run."));
381
+ checks.push(preflightCheck("issue", "task/issue accessible", legacyServerCompatibility ? "warn" : "fail", message(error), "Fix the task source before launching a run."));
407
382
  }
408
383
  try {
409
384
  const runs = await request("/api/runs?limit=200");
@@ -414,14 +389,7 @@ async function runFastTaskRunPreflight(context, options = {}) {
414
389
  }
415
390
  }
416
391
  if ((options.runtimeAdapter ?? "pi") === "pi") {
417
- const piChecks = await (options.piChecks ?? (() => buildPiSetupChecks()))().catch((error) => [{
418
- ok: false,
419
- label: "pi/pi-rig checks",
420
- hint: message(error)
421
- }]);
422
- for (const pi of piChecks) {
423
- checks.push(preflightCheck(pi.label === "pi" ? "pi" : "pi-rig", pi.label, pi.ok ? "pass" : "fail", pi.detail, pi.hint ?? (pi.ok ? undefined : "Run `rig init --yes` to install/update Pi and enable pi-rig.")));
424
- }
392
+ checks.push(preflightCheck("runtime", "worker Pi SDK session daemon", "pass", selectedServer?.connectionKind === "remote" ? "remote worker-owned runtime" : "bundled server-owned runtime"));
425
393
  } else {
426
394
  checks.push(preflightCheck("runtime", "runtime adapter", "pass", options.runtimeAdapter));
427
395
  }
@@ -7,8 +7,6 @@ import { resolve as resolve3 } from "path";
7
7
  import { EventBus } from "@rig/runtime/control-plane/runtime/events";
8
8
  import { CliError } 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
11
  import { CliError as CliError2 } from "@rig/runtime/control-plane/errors";
14
12
 
@@ -20,6 +18,7 @@ import {
20
18
  writeJsonFile as writeJsonFile2
21
19
  } from "@rig/runtime/control-plane/authority-files";
22
20
  import { taskLookup } from "@rig/runtime/control-plane/native/task-ops";
21
+ import { readPriorPrProgressPromptSection } from "@rig/runtime/control-plane/prompt-context";
23
22
  import { buildProviderTaskRunInstructionLines } from "@rig/runtime/control-plane/provider/runtime-instructions";
24
23
  import { loadRigTaskRunSkillBody } from "@rig/runtime/control-plane/provider/rig-task-run-skill";
25
24
 
@@ -207,6 +206,7 @@ ${acceptance}` : null,
207
206
  ${sourceContractLines.join(`
208
207
  `)}` : null,
209
208
  scopeText || renderSourceScopeValidation(sourceTask, sourceValidation) || null,
209
+ readPriorPrProgressPromptSection(input.projectRoot, input.taskId),
210
210
  initialPrompt ? `Additional operator guidance:
211
211
  ${initialPrompt}` : null,
212
212
  providerLines.length > 0 ? `Provider-specific runtime tooling: