@h-rig/runtime 0.0.6-alpha.3 → 0.0.6-alpha.30

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 (59) hide show
  1. package/dist/bin/rig-agent-dispatch.js +1165 -785
  2. package/dist/bin/rig-agent.js +458 -389
  3. package/dist/src/control-plane/agent-wrapper.js +1191 -504
  4. package/dist/src/control-plane/authority-files.js +12 -6
  5. package/dist/src/control-plane/harness-main.js +2186 -1786
  6. package/dist/src/control-plane/hooks/completion-verification.js +2084 -1019
  7. package/dist/src/control-plane/hooks/inject-context.js +193 -139
  8. package/dist/src/control-plane/hooks/submodule-branch.js +603 -545
  9. package/dist/src/control-plane/hooks/task-runtime-start.js +603 -545
  10. package/dist/src/control-plane/materialize-task-config.js +64 -8
  11. package/dist/src/control-plane/native/git-ops.js +90 -64
  12. package/dist/src/control-plane/native/harness-cli.js +1989 -682
  13. package/dist/src/control-plane/native/pr-automation.js +1657 -54
  14. package/dist/src/control-plane/native/pr-review-gate.js +1455 -0
  15. package/dist/src/control-plane/native/repo-ops.js +3 -0
  16. package/dist/src/control-plane/native/run-ops.js +39 -13
  17. package/dist/src/control-plane/native/task-ops.js +1819 -527
  18. package/dist/src/control-plane/native/validator.js +163 -109
  19. package/dist/src/control-plane/native/verifier.js +1616 -323
  20. package/dist/src/control-plane/native/workspace-ops.js +12 -6
  21. package/dist/src/control-plane/pi-sessiond/bin.js +793 -0
  22. package/dist/src/control-plane/pi-sessiond/client.js +41 -0
  23. package/dist/src/control-plane/pi-sessiond/event-hub.js +59 -0
  24. package/dist/src/control-plane/pi-sessiond/extension-ui-context.js +198 -0
  25. package/dist/src/control-plane/pi-sessiond/launcher.js +173 -0
  26. package/dist/src/control-plane/pi-sessiond/server.js +802 -0
  27. package/dist/src/control-plane/pi-sessiond/session-service.js +540 -0
  28. package/dist/src/control-plane/pi-sessiond/types.js +1 -0
  29. package/dist/src/control-plane/plugin-host-context.js +54 -0
  30. package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
  31. package/dist/src/control-plane/runtime/image/index.js +3 -0
  32. package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
  33. package/dist/src/control-plane/runtime/image.js +3 -0
  34. package/dist/src/control-plane/runtime/index.js +517 -722
  35. package/dist/src/control-plane/runtime/isolation/home.js +28 -6
  36. package/dist/src/control-plane/runtime/isolation/index.js +541 -461
  37. package/dist/src/control-plane/runtime/isolation/runner.js +28 -6
  38. package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
  39. package/dist/src/control-plane/runtime/isolation.js +541 -461
  40. package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
  41. package/dist/src/control-plane/runtime/queue.js +458 -385
  42. package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
  43. package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
  44. package/dist/src/control-plane/skill-materializer.js +46 -0
  45. package/dist/src/control-plane/tasks/source-aware-task-config-source.js +14 -2
  46. package/dist/src/control-plane/tasks/source-lifecycle.js +86 -32
  47. package/dist/src/index.js +27 -298
  48. package/dist/src/layout.js +12 -7
  49. package/dist/src/local-server.js +20 -14
  50. package/native/darwin-arm64/rig-git +0 -0
  51. package/native/darwin-arm64/rig-git.build-manifest.json +1 -1
  52. package/native/darwin-arm64/rig-shell +0 -0
  53. package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
  54. package/native/darwin-arm64/rig-tools +0 -0
  55. package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
  56. package/native/darwin-arm64/runtime-native.dylib +0 -0
  57. package/package.json +8 -6
  58. package/dist/src/control-plane/runtime/plugins.js +0 -1131
  59. package/dist/src/plugins.js +0 -329
@@ -150,32 +150,32 @@ var RIG_DEFINITION_DIRNAME = "rig", RIG_ARTIFACTS_DIRNAME = "artifacts";
150
150
  var init_layout = () => {};
151
151
 
152
152
  // packages/runtime/src/control-plane/runtime/sandbox/utils.ts
153
- import { existsSync as existsSync19, readdirSync as readdirSync3, realpathSync } from "fs";
154
- import { resolve as resolve19 } from "path";
153
+ import { existsSync as existsSync20, readdirSync as readdirSync4, realpathSync } from "fs";
154
+ import { resolve as resolve20 } from "path";
155
155
  function toRealPath(path) {
156
- if (!existsSync19(path)) {
157
- return resolve19(path);
156
+ if (!existsSync20(path)) {
157
+ return resolve20(path);
158
158
  }
159
159
  try {
160
160
  return realpathSync.native(path);
161
161
  } catch {
162
- return resolve19(path);
162
+ return resolve20(path);
163
163
  }
164
164
  }
165
165
  function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
166
166
  const candidates = new Set;
167
167
  const addPath = (candidate) => {
168
- if (existsSync19(candidate)) {
168
+ if (existsSync20(candidate)) {
169
169
  candidates.add(toRealPath(candidate));
170
170
  }
171
171
  };
172
- addPath(resolve19(projectRoot, ".git"));
173
- addPath(resolve19(workspaceDir, "..", "..", ".git"));
172
+ addPath(resolve20(projectRoot, ".git"));
173
+ addPath(resolve20(workspaceDir, "..", "..", ".git"));
174
174
  for (const repoRoot of resolveHostRepoRootPaths(projectRoot)) {
175
- addPath(resolve19(repoRoot, ".git"));
175
+ addPath(resolve20(repoRoot, ".git"));
176
176
  }
177
- const workspaceGit = resolve19(workspaceDir, ".git");
178
- if (existsSync19(workspaceGit)) {
177
+ const workspaceGit = resolve20(workspaceDir, ".git");
178
+ if (existsSync20(workspaceGit)) {
179
179
  addPath(workspaceGit);
180
180
  }
181
181
  return [...candidates];
@@ -183,7 +183,7 @@ function resolveHostGitMetadataPaths(projectRoot, workspaceDir) {
183
183
  function resolveHostRepoRootPaths(projectRoot) {
184
184
  const candidates = new Set;
185
185
  const addPath = (candidate) => {
186
- if (existsSync19(candidate)) {
186
+ if (existsSync20(candidate)) {
187
187
  candidates.add(toRealPath(candidate));
188
188
  }
189
189
  };
@@ -193,11 +193,11 @@ function resolveHostRepoRootPaths(projectRoot) {
193
193
  addPath(monorepoRoot);
194
194
  }
195
195
  } catch {}
196
- const reposDir = resolve19(projectRoot, "repos");
197
- if (existsSync19(reposDir)) {
198
- for (const entry of readdirSync3(reposDir, { withFileTypes: true })) {
196
+ const reposDir = resolve20(projectRoot, "repos");
197
+ if (existsSync20(reposDir)) {
198
+ for (const entry of readdirSync4(reposDir, { withFileTypes: true })) {
199
199
  if (entry.isDirectory() || entry.isSymbolicLink()) {
200
- addPath(resolve19(reposDir, entry.name));
200
+ addPath(resolve20(reposDir, entry.name));
201
201
  }
202
202
  }
203
203
  }
@@ -241,8 +241,8 @@ var exports_backend_seatbelt = {};
241
241
  __export(exports_backend_seatbelt, {
242
242
  SeatbeltBackend: () => SeatbeltBackend
243
243
  });
244
- import { mkdirSync as mkdirSync16, writeFileSync as writeFileSync11 } from "fs";
245
- import { resolve as resolve31 } from "path";
244
+ import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "fs";
245
+ import { resolve as resolve32 } from "path";
246
246
 
247
247
  class SeatbeltBackend {
248
248
  kind = "macos-seatbelt";
@@ -266,11 +266,11 @@ class SeatbeltBackend {
266
266
  };
267
267
  }
268
268
  writeSeatbeltProfile(options) {
269
- const sandboxDir = resolve31(options.runtime.rootDir, "sandbox");
270
- mkdirSync16(sandboxDir, { recursive: true });
271
- const profilePath = resolve31(sandboxDir, "seatbelt.sb");
269
+ const sandboxDir = resolve32(options.runtime.rootDir, "sandbox");
270
+ mkdirSync17(sandboxDir, { recursive: true });
271
+ const profilePath = resolve32(sandboxDir, "seatbelt.sb");
272
272
  const profile = this.renderProfile(options);
273
- writeFileSync11(profilePath, `${profile}
273
+ writeFileSync12(profilePath, `${profile}
274
274
  `, "utf-8");
275
275
  return profilePath;
276
276
  }
@@ -355,7 +355,7 @@ class SeatbeltBackend {
355
355
  const realHome = process.env.HOME?.trim();
356
356
  if (realHome) {
357
357
  for (const binSubdir of [".local/bin", ".cargo/bin"]) {
358
- const binPath = resolve31(realHome, binSubdir);
358
+ const binPath = resolve32(realHome, binSubdir);
359
359
  if (ctx.pathExists(binPath)) {
360
360
  lines.push(`(allow file-read* (subpath ${seatbeltString(ctx.realPath(binPath))}))`);
361
361
  }
@@ -384,8 +384,8 @@ var exports_backend_bwrap = {};
384
384
  __export(exports_backend_bwrap, {
385
385
  BwrapBackend: () => BwrapBackend
386
386
  });
387
- import { mkdirSync as mkdirSync17 } from "fs";
388
- import { resolve as resolve32 } from "path";
387
+ import { mkdirSync as mkdirSync18 } from "fs";
388
+ import { resolve as resolve33 } from "path";
389
389
 
390
390
  class BwrapBackend {
391
391
  kind = "linux-bwrap";
@@ -514,18 +514,18 @@ class BwrapBackend {
514
514
  const realHome = process.env.HOME?.trim();
515
515
  if (realHome) {
516
516
  for (const binSubdir of [".local/bin", ".local/lib", ".cargo/bin"]) {
517
- const binPath = ctx.realPath(resolve32(realHome, binSubdir));
517
+ const binPath = ctx.realPath(resolve33(realHome, binSubdir));
518
518
  if (ctx.pathExists(binPath)) {
519
519
  args.push("--ro-bind", binPath, binPath);
520
520
  }
521
521
  }
522
- const agentSshDir = resolve32(homeReal, ".ssh");
522
+ const agentSshDir = resolve33(homeReal, ".ssh");
523
523
  if (ctx.pathExists(agentSshDir)) {
524
524
  args.push("--ro-bind", agentSshDir, agentSshDir);
525
525
  } else {
526
- const hostSshDir = resolve32(realHome, ".ssh");
526
+ const hostSshDir = resolve33(realHome, ".ssh");
527
527
  if (ctx.pathExists(hostSshDir)) {
528
- mkdirSync17(agentSshDir, { recursive: true });
528
+ mkdirSync18(agentSshDir, { recursive: true });
529
529
  args.push("--ro-bind", hostSshDir, agentSshDir);
530
530
  args.push("--ro-bind", hostSshDir, hostSshDir);
531
531
  }
@@ -567,8 +567,9 @@ var init_backend_bwrap = __esm(() => {
567
567
  });
568
568
 
569
569
  // packages/runtime/src/control-plane/agent-wrapper.ts
570
- import { resolve as resolve35 } from "path";
571
- import { existsSync as existsSync33, mkdirSync as mkdirSync19, writeFileSync as writeFileSync13 } from "fs";
570
+ import { createRequire } from "module";
571
+ import { resolve as resolve37 } from "path";
572
+ import { existsSync as existsSync35, mkdirSync as mkdirSync21, writeFileSync as writeFileSync14 } from "fs";
572
573
 
573
574
  // packages/runtime/src/control-plane/runtime/context.ts
574
575
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
@@ -776,9 +777,9 @@ function isAgentRuntimeContextPath(path) {
776
777
  }
777
778
 
778
779
  // packages/runtime/src/control-plane/runtime/isolation/index.ts
779
- import { existsSync as existsSync32, mkdirSync as mkdirSync18, readFileSync as readFileSync15, rmSync as rmSync12 } from "fs";
780
+ import { existsSync as existsSync33, mkdirSync as mkdirSync19, readFileSync as readFileSync16, rmSync as rmSync13 } from "fs";
780
781
  import { copyFile, mkdir as mkdir3, writeFile as writeFile2 } from "fs/promises";
781
- import { resolve as resolve34 } from "path";
782
+ import { resolve as resolve35 } from "path";
782
783
 
783
784
  // packages/runtime/src/control-plane/native/git-native.ts
784
785
  import { chmodSync, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync as writeFileSync2 } from "fs";
@@ -1853,8 +1854,8 @@ async function readCanonicalMemoryDb(projectRoot, deps = {}) {
1853
1854
  var DEFAULT_RESULT_LIMIT = DEFAULT_RUNTIME_MEMORY_RETRIEVAL.topK;
1854
1855
  var DAY_MS = 24 * 60 * 60 * 1000;
1855
1856
  // packages/runtime/src/control-plane/native/task-ops.ts
1856
- import { appendFileSync, existsSync as existsSync22, mkdirSync as mkdirSync9, readFileSync as readFileSync10, writeFileSync as writeFileSync8 } from "fs";
1857
- import { resolve as resolve23 } from "path";
1857
+ import { appendFileSync, existsSync as existsSync23, mkdirSync as mkdirSync10, readFileSync as readFileSync11, writeFileSync as writeFileSync9 } from "fs";
1858
+ import { resolve as resolve24 } from "path";
1858
1859
 
1859
1860
  // packages/runtime/src/build-time-config.ts
1860
1861
  function normalizeBuildConfig(value) {
@@ -2705,6 +2706,49 @@ function safeReadJson(path) {
2705
2706
  }
2706
2707
  }
2707
2708
 
2709
+ // packages/runtime/src/control-plane/skill-materializer.ts
2710
+ import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync5, readdirSync, rmSync as rmSync7, writeFileSync as writeFileSync5 } from "fs";
2711
+ import { resolve as resolve12 } from "path";
2712
+ import { loadSkill } from "@rig/skill-loader";
2713
+ var MARKER_FILENAME = ".rig-plugin";
2714
+ function skillDirName(id) {
2715
+ return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
2716
+ }
2717
+ async function materializeSkills(projectRoot, entries) {
2718
+ const skillsRoot = resolve12(projectRoot, ".pi", "skills");
2719
+ if (existsSync12(skillsRoot)) {
2720
+ for (const name of readdirSync(skillsRoot)) {
2721
+ const dir = resolve12(skillsRoot, name);
2722
+ if (existsSync12(resolve12(dir, MARKER_FILENAME))) {
2723
+ rmSync7(dir, { recursive: true, force: true });
2724
+ }
2725
+ }
2726
+ }
2727
+ const written = [];
2728
+ for (const { pluginName, skill } of entries) {
2729
+ const sourcePath = resolve12(projectRoot, skill.path);
2730
+ if (!existsSync12(sourcePath)) {
2731
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
2732
+ continue;
2733
+ }
2734
+ let body;
2735
+ try {
2736
+ await loadSkill(sourcePath);
2737
+ body = readFileSync5(sourcePath, "utf-8");
2738
+ } catch (err) {
2739
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
2740
+ continue;
2741
+ }
2742
+ const dir = resolve12(skillsRoot, skillDirName(skill.id));
2743
+ mkdirSync8(dir, { recursive: true });
2744
+ writeFileSync5(resolve12(dir, "SKILL.md"), body, "utf-8");
2745
+ writeFileSync5(resolve12(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
2746
+ `, "utf-8");
2747
+ written.push({ id: skill.id, pluginName, directory: dir });
2748
+ }
2749
+ return written;
2750
+ }
2751
+
2708
2752
  // packages/runtime/src/control-plane/plugin-host-context.ts
2709
2753
  async function buildPluginHostContext(projectRoot) {
2710
2754
  let config;
@@ -2741,6 +2785,17 @@ async function buildPluginHostContext(projectRoot) {
2741
2785
  } catch (err) {
2742
2786
  console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
2743
2787
  }
2788
+ try {
2789
+ const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
2790
+ pluginName: plugin.name,
2791
+ skill
2792
+ })));
2793
+ if (skillEntries.length > 0) {
2794
+ await materializeSkills(projectRoot, skillEntries);
2795
+ }
2796
+ } catch (err) {
2797
+ console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
2798
+ }
2744
2799
  return {
2745
2800
  config,
2746
2801
  pluginHost,
@@ -2754,12 +2809,12 @@ async function buildPluginHostContext(projectRoot) {
2754
2809
 
2755
2810
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
2756
2811
  import { spawnSync } from "child_process";
2757
- import { existsSync as existsSync13, readFileSync as readFileSync6, readdirSync, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
2758
- import { basename as basename4, join as join3, resolve as resolve13 } from "path";
2812
+ import { existsSync as existsSync14, readFileSync as readFileSync7, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
2813
+ import { basename as basename4, join as join3, resolve as resolve14 } from "path";
2759
2814
 
2760
2815
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
2761
- import { existsSync as existsSync12, readFileSync as readFileSync5 } from "fs";
2762
- import { resolve as resolve12 } from "path";
2816
+ import { existsSync as existsSync13, readFileSync as readFileSync6 } from "fs";
2817
+ import { resolve as resolve13 } from "path";
2763
2818
 
2764
2819
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
2765
2820
  async function findTaskById(reader, id) {
@@ -2782,7 +2837,7 @@ class LegacyTaskConfigReadError extends Error {
2782
2837
  }
2783
2838
  }
2784
2839
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
2785
- const configPath = options.configPath ?? resolve12(projectRoot, ".rig", "task-config.json");
2840
+ const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
2786
2841
  const reader = {
2787
2842
  async listTasks() {
2788
2843
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -2793,8 +2848,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
2793
2848
  };
2794
2849
  return reader;
2795
2850
  }
2796
- function readLegacyTaskRecords(projectRoot, configPath = resolve12(projectRoot, ".rig", "task-config.json")) {
2797
- if (!existsSync12(configPath)) {
2851
+ function readLegacyTaskRecords(projectRoot, configPath = resolve13(projectRoot, ".rig", "task-config.json")) {
2852
+ if (!existsSync13(configPath)) {
2798
2853
  return [];
2799
2854
  }
2800
2855
  const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
@@ -2802,7 +2857,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve12(projectRoot,
2802
2857
  }
2803
2858
  function readLegacyTaskConfigJson(projectRoot, configPath) {
2804
2859
  try {
2805
- const parsed = JSON.parse(readFileSync5(configPath, "utf8"));
2860
+ const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
2806
2861
  if (isPlainRecord(parsed)) {
2807
2862
  return parsed;
2808
2863
  }
@@ -2886,7 +2941,7 @@ function isPlainRecord(candidate) {
2886
2941
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
2887
2942
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
2888
2943
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
2889
- const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
2944
+ const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
2890
2945
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
2891
2946
  const spawnFn = options.spawn ?? spawnSync;
2892
2947
  const ghBinary = options.ghBinary ?? "gh";
@@ -2951,8 +3006,19 @@ async function readSourceAwareTaskStatus(projectRoot, taskId, options = {}) {
2951
3006
  return null;
2952
3007
  }
2953
3008
  }
3009
+ function updateGithubIssueTaskBySourceIssueId(sourceIssueId, taskId, update, options = {}) {
3010
+ const parsed = sourceIssueId?.trim().match(/^([^/]+)\/([^#]+)#(\d+)$/);
3011
+ if (!parsed || parsed[3] !== taskId) {
3012
+ return false;
3013
+ }
3014
+ applyGithubIssueUpdate(options.ghBinary ?? "gh", options.spawn ?? spawnSync, parsed[3], {
3015
+ sourceIssueId: sourceIssueId.trim(),
3016
+ taskSource: { kind: "github-issues", owner: parsed[1], repo: parsed[2] }
3017
+ }, update);
3018
+ return true;
3019
+ }
2954
3020
  function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
2955
- const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
3021
+ const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
2956
3022
  const rawEntry = readRawTaskEntry(configPath, taskId);
2957
3023
  if (!rawEntry) {
2958
3024
  const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
@@ -3005,10 +3071,10 @@ function readMaterializedTaskMetadata(entry) {
3005
3071
  return metadata;
3006
3072
  }
3007
3073
  function readConfiguredFilesTaskSourcePath(projectRoot) {
3008
- const jsonPath = resolve13(projectRoot, "rig.config.json");
3009
- if (existsSync13(jsonPath)) {
3074
+ const jsonPath = resolve14(projectRoot, "rig.config.json");
3075
+ if (existsSync14(jsonPath)) {
3010
3076
  try {
3011
- const parsed = JSON.parse(readFileSync6(jsonPath, "utf8"));
3077
+ const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
3012
3078
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
3013
3079
  const source = parsed.taskSource;
3014
3080
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -3017,12 +3083,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
3017
3083
  return null;
3018
3084
  }
3019
3085
  }
3020
- const tsPath = resolve13(projectRoot, "rig.config.ts");
3021
- if (!existsSync13(tsPath)) {
3086
+ const tsPath = resolve14(projectRoot, "rig.config.ts");
3087
+ if (!existsSync14(tsPath)) {
3022
3088
  return null;
3023
3089
  }
3024
3090
  try {
3025
- const source = readFileSync6(tsPath, "utf8");
3091
+ const source = readFileSync7(tsPath, "utf8");
3026
3092
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
3027
3093
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
3028
3094
  if (kind !== "files") {
@@ -3042,10 +3108,10 @@ function readRawTaskEntry(configPath, taskId) {
3042
3108
  return isPlainRecord2(entry) ? entry : null;
3043
3109
  }
3044
3110
  function readRawTaskConfig(configPath) {
3045
- if (!existsSync13(configPath)) {
3111
+ if (!existsSync14(configPath)) {
3046
3112
  return null;
3047
3113
  }
3048
- const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
3114
+ const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
3049
3115
  return isPlainRecord2(parsed) ? parsed : null;
3050
3116
  }
3051
3117
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -3062,16 +3128,16 @@ function writeLegacyTaskStatus(configPath, taskId, status) {
3062
3128
  return;
3063
3129
  }
3064
3130
  entry.status = status;
3065
- writeFileSync5(configPath, `${JSON.stringify(rawConfig, null, 2)}
3131
+ writeFileSync6(configPath, `${JSON.stringify(rawConfig, null, 2)}
3066
3132
  `, "utf8");
3067
3133
  }
3068
3134
  function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
3069
- const directory = resolve13(projectRoot, sourcePath);
3135
+ const directory = resolve14(projectRoot, sourcePath);
3070
3136
  const file = findFileBackedTaskFile(directory, taskId);
3071
3137
  if (!file) {
3072
3138
  return false;
3073
3139
  }
3074
- const raw = JSON.parse(readFileSync6(file, "utf8"));
3140
+ const raw = JSON.parse(readFileSync7(file, "utf8"));
3075
3141
  if (!isPlainRecord2(raw)) {
3076
3142
  return false;
3077
3143
  }
@@ -3088,17 +3154,17 @@ function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
3088
3154
  { body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
3089
3155
  ];
3090
3156
  }
3091
- writeFileSync5(file, `${JSON.stringify(raw, null, 2)}
3157
+ writeFileSync6(file, `${JSON.stringify(raw, null, 2)}
3092
3158
  `, "utf8");
3093
3159
  return true;
3094
3160
  }
3095
3161
  function listFileBackedTasks(projectRoot, sourcePath) {
3096
- const directory = resolve13(projectRoot, sourcePath);
3097
- if (!existsSync13(directory)) {
3162
+ const directory = resolve14(projectRoot, sourcePath);
3163
+ if (!existsSync14(directory)) {
3098
3164
  return [];
3099
3165
  }
3100
3166
  const tasks = [];
3101
- for (const name of readdirSync(directory)) {
3167
+ for (const name of readdirSync2(directory)) {
3102
3168
  if (!FILE_TASK_PATTERN.test(name))
3103
3169
  continue;
3104
3170
  const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
@@ -3109,11 +3175,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
3109
3175
  return tasks;
3110
3176
  }
3111
3177
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
3112
- const file = findFileBackedTaskFile(resolve13(projectRoot, sourcePath), taskId);
3178
+ const file = findFileBackedTaskFile(resolve14(projectRoot, sourcePath), taskId);
3113
3179
  if (!file) {
3114
3180
  return null;
3115
3181
  }
3116
- const raw = JSON.parse(readFileSync6(file, "utf8"));
3182
+ const raw = JSON.parse(readFileSync7(file, "utf8"));
3117
3183
  if (!isPlainRecord2(raw)) {
3118
3184
  return null;
3119
3185
  }
@@ -3126,17 +3192,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
3126
3192
  };
3127
3193
  }
3128
3194
  function findFileBackedTaskFile(directory, taskId) {
3129
- if (!existsSync13(directory)) {
3195
+ if (!existsSync14(directory)) {
3130
3196
  return null;
3131
3197
  }
3132
- for (const name of readdirSync(directory)) {
3198
+ for (const name of readdirSync2(directory)) {
3133
3199
  if (!FILE_TASK_PATTERN.test(name))
3134
3200
  continue;
3135
3201
  const file = join3(directory, name);
3136
3202
  try {
3137
3203
  if (!statSync3(file).isFile())
3138
3204
  continue;
3139
- const raw = JSON.parse(readFileSync6(file, "utf8"));
3205
+ const raw = JSON.parse(readFileSync7(file, "utf8"));
3140
3206
  const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
3141
3207
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
3142
3208
  if (id === taskId) {
@@ -3306,8 +3372,8 @@ function ensureStatusLabel(bin, repo, spawnFn, label) {
3306
3372
  }
3307
3373
  }
3308
3374
  function selectedGitHubEnv() {
3309
- const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() ?? "";
3310
- return { GH_TOKEN: token, GITHUB_TOKEN: token };
3375
+ const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
3376
+ return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
3311
3377
  }
3312
3378
  function ghSpawnOptions() {
3313
3379
  return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
@@ -3485,8 +3551,8 @@ function buildTaskRunLifecycleComment(input) {
3485
3551
  }
3486
3552
 
3487
3553
  // packages/runtime/src/control-plane/native/task-state.ts
3488
- import { existsSync as existsSync17, readFileSync as readFileSync8, readdirSync as readdirSync2, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
3489
- import { basename as basename6, resolve as resolve17 } from "path";
3554
+ import { existsSync as existsSync18, readFileSync as readFileSync9, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
3555
+ import { basename as basename6, resolve as resolve18 } from "path";
3490
3556
 
3491
3557
  // packages/runtime/src/control-plane/state-sync/types.ts
3492
3558
  var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
@@ -3594,39 +3660,39 @@ function readTaskStateMetadataEnvelope(raw) {
3594
3660
  };
3595
3661
  }
3596
3662
  // packages/runtime/src/control-plane/state-sync/read.ts
3597
- import { existsSync as existsSync16, readFileSync as readFileSync7 } from "fs";
3598
- import { resolve as resolve16 } from "path";
3663
+ import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
3664
+ import { resolve as resolve17 } from "path";
3599
3665
 
3600
3666
  // packages/runtime/src/control-plane/state-sync/repo.ts
3601
- import { existsSync as existsSync15 } from "fs";
3602
- import { resolve as resolve15 } from "path";
3667
+ import { existsSync as existsSync16 } from "fs";
3668
+ import { resolve as resolve16 } from "path";
3603
3669
 
3604
3670
  // packages/runtime/src/control-plane/repos/layout.ts
3605
3671
  init_layout();
3606
- import { existsSync as existsSync14 } from "fs";
3607
- import { basename as basename5, dirname as dirname9, join as join4, resolve as resolve14 } from "path";
3672
+ import { existsSync as existsSync15 } from "fs";
3673
+ import { basename as basename5, dirname as dirname9, join as join4, resolve as resolve15 } from "path";
3608
3674
  function resolveRepoStateDir(projectRoot) {
3609
- const normalizedProjectRoot = resolve14(projectRoot);
3675
+ const normalizedProjectRoot = resolve15(projectRoot);
3610
3676
  const projectParent = dirname9(normalizedProjectRoot);
3611
3677
  if (basename5(projectParent) === ".worktrees") {
3612
3678
  const ownerRoot = dirname9(projectParent);
3613
- const ownerHasRepoMarkers = existsSync14(resolve14(ownerRoot, ".git")) || existsSync14(resolve14(ownerRoot, ".rig", "state"));
3679
+ const ownerHasRepoMarkers = existsSync15(resolve15(ownerRoot, ".git")) || existsSync15(resolve15(ownerRoot, ".rig", "state"));
3614
3680
  if (ownerHasRepoMarkers) {
3615
- return resolve14(ownerRoot, ".rig", "state");
3681
+ return resolve15(ownerRoot, ".rig", "state");
3616
3682
  }
3617
3683
  }
3618
- return resolve14(projectRoot, ".rig", "state");
3684
+ return resolve15(projectRoot, ".rig", "state");
3619
3685
  }
3620
3686
  function resolveManagedRepoLayout(projectRoot, repoId) {
3621
- const normalizedProjectRoot = resolve14(projectRoot);
3687
+ const normalizedProjectRoot = resolve15(projectRoot);
3622
3688
  const entry = getManagedRepoEntry(repoId);
3623
3689
  const stateDir = resolveRepoStateDir(normalizedProjectRoot);
3624
3690
  const metadataRelativePath = join4("repos", entry.id);
3625
- const metadataRoot = resolve14(stateDir, metadataRelativePath);
3691
+ const metadataRoot = resolve15(stateDir, metadataRelativePath);
3626
3692
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
3627
- const runsInsideTaskWorktree = runtimeWorkspace && resolve14(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
3693
+ const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
3628
3694
  const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
3629
- const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve14(process.env[entry.checkoutEnvVar].trim()) : resolve14(normalizedProjectRoot, entry.alias);
3695
+ const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
3630
3696
  return {
3631
3697
  projectRoot: normalizedProjectRoot,
3632
3698
  repoId: entry.id,
@@ -3634,12 +3700,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
3634
3700
  defaultBranch: entry.defaultBranch,
3635
3701
  remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
3636
3702
  checkoutRoot,
3637
- worktreesRoot: resolve14(checkoutRoot, ".worktrees"),
3703
+ worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
3638
3704
  stateDir,
3639
3705
  metadataRoot,
3640
3706
  metadataRelativePath,
3641
- mirrorRoot: resolve14(metadataRoot, "mirror.git"),
3642
- mirrorStatePath: resolve14(metadataRoot, "mirror-state.json"),
3707
+ mirrorRoot: resolve15(metadataRoot, "mirror.git"),
3708
+ mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
3643
3709
  mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
3644
3710
  };
3645
3711
  }
@@ -3657,7 +3723,7 @@ function resolveTrackerRepoPath(projectRoot) {
3657
3723
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
3658
3724
  try {
3659
3725
  const layout = resolveMonorepoRepoLayout(projectRoot);
3660
- if (existsSync15(resolve15(layout.mirrorRoot, "HEAD"))) {
3726
+ if (existsSync16(resolve16(layout.mirrorRoot, "HEAD"))) {
3661
3727
  return layout.mirrorRoot;
3662
3728
  }
3663
3729
  } catch {}
@@ -3668,8 +3734,8 @@ function resolveTrackerRepoPath(projectRoot) {
3668
3734
  var DEFAULT_READ_DEPS2 = {
3669
3735
  fetchRef: nativeFetchRef,
3670
3736
  readBlobAtRef: nativeReadBlobAtRef,
3671
- exists: existsSync16,
3672
- readFile: (path) => readFileSync7(path, "utf8")
3737
+ exists: existsSync17,
3738
+ readFile: (path) => readFileSync8(path, "utf8")
3673
3739
  };
3674
3740
  function parseIssueStatus(rawStatus) {
3675
3741
  const normalized = normalizeTaskLifecycleStatus(rawStatus);
@@ -3750,12 +3816,12 @@ function shouldPreferLocalTrackerState(options) {
3750
3816
  if (runtimeContextPath) {
3751
3817
  return true;
3752
3818
  }
3753
- return existsSync16(resolve16(runtimeWorkspace, ".rig", "runtime-context.json"));
3819
+ return existsSync17(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
3754
3820
  }
3755
3821
  function readLocalTrackerState(projectRoot, deps) {
3756
3822
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
3757
- const issuesPath = resolve16(monorepoRoot, ".beads", "issues.jsonl");
3758
- const taskStatePath = resolve16(monorepoRoot, ".beads", "task-state.json");
3823
+ const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
3824
+ const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
3759
3825
  return projectSyncedTrackerSnapshot({
3760
3826
  source: "local",
3761
3827
  issuesBaseOid: null,
@@ -3817,7 +3883,7 @@ function readValidationDescriptions(projectRoot) {
3817
3883
  return readValidationDescriptionMap(raw);
3818
3884
  }
3819
3885
  function readSourceValidationDescriptions(projectRoot) {
3820
- const rootRaw = readJsonFile(resolve17(projectRoot, "rig", "task-config.json"), {});
3886
+ const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
3821
3887
  const sourcePath = findSourceTaskConfigPath(projectRoot);
3822
3888
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
3823
3889
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -3893,15 +3959,15 @@ function readValidationDescriptionsFromMeta(meta) {
3893
3959
  return meta.validation_descriptions;
3894
3960
  }
3895
3961
  function readLocalSourceTaskStateEnvelope(projectRoot) {
3896
- const taskStatePath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
3962
+ const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
3897
3963
  return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
3898
3964
  }
3899
3965
  function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
3900
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
3901
- if (!existsSync17(issuesPath)) {
3966
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
3967
+ if (!existsSync18(issuesPath)) {
3902
3968
  return null;
3903
3969
  }
3904
- for (const line of readFileSync8(issuesPath, "utf8").split(/\r?\n/)) {
3970
+ for (const line of readFileSync9(issuesPath, "utf8").split(/\r?\n/)) {
3905
3971
  const trimmed = line.trim();
3906
3972
  if (!trimmed) {
3907
3973
  continue;
@@ -3926,25 +3992,25 @@ function inferTaskIdFromRuntimePath(path) {
3926
3992
  function artifactDirForId(projectRoot, id) {
3927
3993
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
3928
3994
  if (workspaceDir) {
3929
- const worktreeArtifacts = resolve17(workspaceDir, "artifacts", id);
3930
- if (existsSync17(worktreeArtifacts) || existsSync17(resolve17(workspaceDir, "artifacts"))) {
3995
+ const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
3996
+ if (existsSync18(worktreeArtifacts) || existsSync18(resolve18(workspaceDir, "artifacts"))) {
3931
3997
  return worktreeArtifacts;
3932
3998
  }
3933
3999
  }
3934
4000
  try {
3935
4001
  const paths = resolveHarnessPaths(projectRoot);
3936
- return resolve17(paths.artifactsDir, id);
4002
+ return resolve18(paths.artifactsDir, id);
3937
4003
  } catch {
3938
- return resolve17(resolveMonorepoRoot2(projectRoot), "artifacts", id);
4004
+ return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
3939
4005
  }
3940
4006
  }
3941
4007
  function resolveTaskConfigPath(projectRoot) {
3942
4008
  const paths = resolveHarnessPaths(projectRoot);
3943
- if (existsSync17(paths.taskConfigPath)) {
4009
+ if (existsSync18(paths.taskConfigPath)) {
3944
4010
  return paths.taskConfigPath;
3945
4011
  }
3946
4012
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
3947
- if (existsSync17(candidate)) {
4013
+ if (existsSync18(candidate)) {
3948
4014
  return candidate;
3949
4015
  }
3950
4016
  }
@@ -3952,7 +4018,7 @@ function resolveTaskConfigPath(projectRoot) {
3952
4018
  }
3953
4019
  function findSourceTaskConfigPath(projectRoot) {
3954
4020
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
3955
- if (existsSync17(candidate)) {
4021
+ if (existsSync18(candidate)) {
3956
4022
  return candidate;
3957
4023
  }
3958
4024
  }
@@ -3965,7 +4031,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
3965
4031
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
3966
4032
  if (sourcePath && synced.updated) {
3967
4033
  try {
3968
- writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
4034
+ writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
3969
4035
  `, "utf-8");
3970
4036
  } catch {}
3971
4037
  }
@@ -4017,12 +4083,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
4017
4083
  return !candidate.role;
4018
4084
  }
4019
4085
  function readSourceIssueRecords(projectRoot) {
4020
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
4021
- if (!existsSync17(issuesPath)) {
4086
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
4087
+ if (!existsSync18(issuesPath)) {
4022
4088
  return [];
4023
4089
  }
4024
4090
  const records = [];
4025
- for (const line of readFileSync8(issuesPath, "utf-8").split(/\r?\n/)) {
4091
+ for (const line of readFileSync9(issuesPath, "utf-8").split(/\r?\n/)) {
4026
4092
  const trimmed = line.trim();
4027
4093
  if (!trimmed) {
4028
4094
  continue;
@@ -4078,19 +4144,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
4078
4144
  if (!sourcePath) {
4079
4145
  return {};
4080
4146
  }
4081
- const directory = resolve17(projectRoot, sourcePath);
4082
- if (!existsSync17(directory)) {
4147
+ const directory = resolve18(projectRoot, sourcePath);
4148
+ if (!existsSync18(directory)) {
4083
4149
  return {};
4084
4150
  }
4085
4151
  const config = {};
4086
- for (const name of readdirSync2(directory)) {
4152
+ for (const name of readdirSync3(directory)) {
4087
4153
  if (!FILE_TASK_PATTERN2.test(name))
4088
4154
  continue;
4089
- const file = resolve17(directory, name);
4155
+ const file = resolve18(directory, name);
4090
4156
  try {
4091
4157
  if (!statSync4(file).isFile())
4092
4158
  continue;
4093
- const raw = JSON.parse(readFileSync8(file, "utf8"));
4159
+ const raw = JSON.parse(readFileSync9(file, "utf8"));
4094
4160
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
4095
4161
  continue;
4096
4162
  const record = raw;
@@ -4132,10 +4198,10 @@ function firstStringList2(...candidates) {
4132
4198
  return [];
4133
4199
  }
4134
4200
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
4135
- const jsonPath = resolve17(projectRoot, "rig.config.json");
4136
- if (existsSync17(jsonPath)) {
4201
+ const jsonPath = resolve18(projectRoot, "rig.config.json");
4202
+ if (existsSync18(jsonPath)) {
4137
4203
  try {
4138
- const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
4204
+ const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
4139
4205
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
4140
4206
  const taskSource = parsed.taskSource;
4141
4207
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -4147,12 +4213,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
4147
4213
  return null;
4148
4214
  }
4149
4215
  }
4150
- const tsPath = resolve17(projectRoot, "rig.config.ts");
4151
- if (!existsSync17(tsPath)) {
4216
+ const tsPath = resolve18(projectRoot, "rig.config.ts");
4217
+ if (!existsSync18(tsPath)) {
4152
4218
  return null;
4153
4219
  }
4154
4220
  try {
4155
- const source = readFileSync8(tsPath, "utf8");
4221
+ const source = readFileSync9(tsPath, "utf8");
4156
4222
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
4157
4223
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
4158
4224
  if (kind !== "files") {
@@ -4166,9 +4232,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
4166
4232
  function sourceTaskConfigCandidates(projectRoot) {
4167
4233
  const runtimeContext = loadRuntimeContextFromEnv();
4168
4234
  return [
4169
- runtimeContext?.monorepoMainRoot ? resolve17(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
4170
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve17(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
4171
- resolve17(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
4235
+ runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
4236
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
4237
+ resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
4172
4238
  ].filter(Boolean);
4173
4239
  }
4174
4240
 
@@ -4177,8 +4243,8 @@ init_layout();
4177
4243
 
4178
4244
  // packages/runtime/src/binary-run.ts
4179
4245
  init_layout();
4180
- import { chmodSync as chmodSync4, cpSync, existsSync as existsSync18, mkdirSync as mkdirSync8, renameSync as renameSync3, rmSync as rmSync7, writeFileSync as writeFileSync7 } from "fs";
4181
- import { basename as basename7, dirname as dirname10, resolve as resolve18 } from "path";
4246
+ import { chmodSync as chmodSync4, cpSync, existsSync as existsSync19, mkdirSync as mkdirSync9, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
4247
+ import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
4182
4248
  import { fileURLToPath } from "url";
4183
4249
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
4184
4250
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -4204,9 +4270,9 @@ async function buildRuntimeBinary(options) {
4204
4270
  });
4205
4271
  }
4206
4272
  async function buildRuntimeBinaryInProcess(options, manifest) {
4207
- const tempBuildDir = resolve18(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
4208
- const tempOutputPath = resolve18(tempBuildDir, basename7(options.outputPath));
4209
- mkdirSync8(tempBuildDir, { recursive: true });
4273
+ const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
4274
+ const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
4275
+ mkdirSync9(tempBuildDir, { recursive: true });
4210
4276
  await withTemporaryEnv({
4211
4277
  ...options.env,
4212
4278
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -4231,7 +4297,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
4231
4297
  `);
4232
4298
  throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
4233
4299
  }
4234
- if (!existsSync18(tempOutputPath)) {
4300
+ if (!existsSync19(tempOutputPath)) {
4235
4301
  const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
4236
4302
  throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
4237
4303
  }
@@ -4246,7 +4312,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
4246
4312
  });
4247
4313
  }
4248
4314
  })).finally(() => {
4249
- rmSync7(tempBuildDir, { recursive: true, force: true });
4315
+ rmSync8(tempBuildDir, { recursive: true, force: true });
4250
4316
  });
4251
4317
  }
4252
4318
  function runBestEffortBuildGc() {
@@ -4263,8 +4329,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
4263
4329
  function resolveRuntimeBinaryBuildOptions(options) {
4264
4330
  return {
4265
4331
  ...options,
4266
- entrypoint: resolve18(options.cwd, options.sourcePath),
4267
- outputPath: resolve18(options.outputPath)
4332
+ entrypoint: resolve19(options.cwd, options.sourcePath),
4333
+ outputPath: resolve19(options.outputPath)
4268
4334
  };
4269
4335
  }
4270
4336
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -4278,7 +4344,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
4278
4344
  }
4279
4345
  async function buildRuntimeBinaryViaWorker(options) {
4280
4346
  const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
4281
- if (!workerSourcePath || !existsSync18(workerSourcePath)) {
4347
+ if (!workerSourcePath || !existsSync19(workerSourcePath)) {
4282
4348
  await buildRuntimeBinaryInProcess(options, {
4283
4349
  manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
4284
4350
  buildKey: createRuntimeBinaryBuildKey({
@@ -4309,13 +4375,13 @@ async function buildRuntimeBinaryViaWorker(options) {
4309
4375
  new Response(build.stdout).text(),
4310
4376
  new Response(build.stderr).text()
4311
4377
  ]);
4312
- rmSync7(payloadPath, { force: true });
4378
+ rmSync8(payloadPath, { force: true });
4313
4379
  if (exitCode !== 0) {
4314
4380
  throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
4315
4381
  }
4316
4382
  }
4317
4383
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
4318
- return resolve18(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
4384
+ return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
4319
4385
  }
4320
4386
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
4321
4387
  const envRoots = [
@@ -4324,13 +4390,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
4324
4390
  process.env.PROJECT_RIG_ROOT?.trim()
4325
4391
  ].filter(Boolean);
4326
4392
  for (const root of envRoots) {
4327
- const candidate = resolve18(root, "packages/runtime/src/binary-build-worker.ts");
4328
- if (existsSync18(candidate)) {
4393
+ const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
4394
+ if (existsSync19(candidate)) {
4329
4395
  return candidate;
4330
4396
  }
4331
4397
  }
4332
- const localCandidate = resolve18(import.meta.dir, "binary-build-worker.ts");
4333
- return existsSync18(localCandidate) ? localCandidate : null;
4398
+ const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
4399
+ return existsSync19(localCandidate) ? localCandidate : null;
4334
4400
  }
4335
4401
  function resolveRuntimeBinaryBuildWorkerInvocation() {
4336
4402
  const bunPath = Bun.which("bun");
@@ -4366,7 +4432,7 @@ function createRuntimeBinaryBuildKey(input) {
4366
4432
  });
4367
4433
  }
4368
4434
  async function isRuntimeBinaryBuildFresh(input) {
4369
- if (!existsSync18(input.outputPath) || !existsSync18(input.manifestPath)) {
4435
+ if (!existsSync19(input.outputPath) || !existsSync19(input.manifestPath)) {
4370
4436
  return false;
4371
4437
  }
4372
4438
  let manifest = null;
@@ -4379,7 +4445,7 @@ async function isRuntimeBinaryBuildFresh(input) {
4379
4445
  return false;
4380
4446
  }
4381
4447
  for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
4382
- if (!existsSync18(filePath)) {
4448
+ if (!existsSync19(filePath)) {
4383
4449
  return false;
4384
4450
  }
4385
4451
  if (await sha256File4(filePath) !== expectedDigest) {
@@ -4392,7 +4458,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
4392
4458
  const inputs = {};
4393
4459
  for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
4394
4460
  const normalized = normalizeBuildInputPath(input.cwd, inputPath);
4395
- if (!normalized || !existsSync18(normalized)) {
4461
+ if (!normalized || !existsSync19(normalized)) {
4396
4462
  continue;
4397
4463
  }
4398
4464
  inputs[normalized] = await sha256File4(normalized);
@@ -4415,7 +4481,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
4415
4481
  if (inputPath.startsWith("<")) {
4416
4482
  return null;
4417
4483
  }
4418
- return resolve18(cwd, inputPath);
4484
+ return resolve19(cwd, inputPath);
4419
4485
  }
4420
4486
  async function sha256File4(path) {
4421
4487
  const hasher = new Bun.CryptoHasher("sha256");
@@ -4431,8 +4497,8 @@ function sortRecord(value) {
4431
4497
  async function runSerializedRuntimeBinaryBuild(action) {
4432
4498
  const previous = runtimeBinaryBuildQueue;
4433
4499
  let release;
4434
- runtimeBinaryBuildQueue = new Promise((resolve19) => {
4435
- release = resolve19;
4500
+ runtimeBinaryBuildQueue = new Promise((resolve20) => {
4501
+ release = resolve20;
4436
4502
  });
4437
4503
  await previous;
4438
4504
  try {
@@ -4477,11 +4543,11 @@ async function withTemporaryCwd(cwd, action) {
4477
4543
  }
4478
4544
 
4479
4545
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
4480
- import { delimiter, resolve as resolve21 } from "path";
4546
+ import { delimiter, resolve as resolve22 } from "path";
4481
4547
 
4482
4548
  // packages/runtime/src/control-plane/runtime/runtime-paths.ts
4483
- import { existsSync as existsSync20, readdirSync as readdirSync4, realpathSync as realpathSync2 } from "fs";
4484
- import { resolve as resolve20 } from "path";
4549
+ import { existsSync as existsSync21, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
4550
+ import { resolve as resolve21 } from "path";
4485
4551
 
4486
4552
  // packages/runtime/src/control-plane/runtime/sandbox-utils.ts
4487
4553
  init_utils();
@@ -4498,7 +4564,7 @@ function resolveBunBinaryPath() {
4498
4564
  }
4499
4565
  const home = process.env.HOME?.trim();
4500
4566
  const fallbackCandidates = [
4501
- home ? resolve20(home, ".bun/bin/bun") : "",
4567
+ home ? resolve21(home, ".bun/bin/bun") : "",
4502
4568
  "/opt/homebrew/bin/bun",
4503
4569
  "/usr/local/bin/bun",
4504
4570
  "/usr/bin/bun"
@@ -4526,8 +4592,8 @@ function resolveClaudeBinaryPath() {
4526
4592
  }
4527
4593
  const home = process.env.HOME?.trim();
4528
4594
  const fallbackCandidates = [
4529
- home ? resolve20(home, ".local/bin/claude") : "",
4530
- home ? resolve20(home, ".local/share/claude/local/claude") : "",
4595
+ home ? resolve21(home, ".local/bin/claude") : "",
4596
+ home ? resolve21(home, ".local/share/claude/local/claude") : "",
4531
4597
  "/opt/homebrew/bin/claude",
4532
4598
  "/usr/local/bin/claude",
4533
4599
  "/usr/bin/claude"
@@ -4541,35 +4607,35 @@ function resolveClaudeBinaryPath() {
4541
4607
  throw new Error("claude not found in PATH");
4542
4608
  }
4543
4609
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
4544
- return resolve20(bunBinaryPath, "../..");
4610
+ return resolve21(bunBinaryPath, "../..");
4545
4611
  }
4546
4612
  function resolveClaudeInstallDir() {
4547
4613
  const realPath = resolveClaudeBinaryPath();
4548
- return resolve20(realPath, "..");
4614
+ return resolve21(realPath, "..");
4549
4615
  }
4550
4616
  function resolveNodeInstallDir() {
4551
4617
  const preferredNode = resolvePreferredNodeBinary();
4552
4618
  if (!preferredNode)
4553
4619
  return null;
4554
4620
  const explicitNode = process.env.RIG_NODE_BIN?.trim();
4555
- if (explicitNode && resolve20(explicitNode) === resolve20(preferredNode)) {
4556
- return preferredNode.endsWith("/bin/node") ? resolve20(preferredNode, "../..") : resolve20(preferredNode, "..");
4621
+ if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
4622
+ return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
4557
4623
  }
4558
4624
  try {
4559
4625
  const realPath = realpathSync2(preferredNode);
4560
4626
  if (realPath.endsWith("/bin/node")) {
4561
- return resolve20(realPath, "../..");
4627
+ return resolve21(realPath, "../..");
4562
4628
  }
4563
- return resolve20(realPath, "..");
4629
+ return resolve21(realPath, "..");
4564
4630
  } catch {
4565
- return resolve20(preferredNode, "..");
4631
+ return resolve21(preferredNode, "..");
4566
4632
  }
4567
4633
  }
4568
4634
  function resolveRuntimeDependencyRoots(runtimeDirs) {
4569
4635
  const roots = [];
4570
4636
  if (process.platform === "darwin") {
4571
4637
  for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
4572
- if (existsSync20(macPath)) {
4638
+ if (existsSync21(macPath)) {
4573
4639
  roots.push(macPath);
4574
4640
  }
4575
4641
  }
@@ -4587,23 +4653,23 @@ function resolvePreferredNodeBinary() {
4587
4653
  const candidates = [];
4588
4654
  const envNode = process.env.RIG_NODE_BIN?.trim();
4589
4655
  if (envNode) {
4590
- const explicit = resolve20(envNode);
4591
- if (existsSync20(explicit)) {
4656
+ const explicit = resolve21(envNode);
4657
+ if (existsSync21(explicit)) {
4592
4658
  return explicit;
4593
4659
  }
4594
4660
  }
4595
4661
  const nvmBin = process.env.NVM_BIN?.trim();
4596
4662
  if (nvmBin) {
4597
- candidates.push(resolve20(nvmBin, "node"));
4663
+ candidates.push(resolve21(nvmBin, "node"));
4598
4664
  }
4599
4665
  const home = process.env.HOME?.trim();
4600
4666
  if (home) {
4601
- const nvmVersionsDir = resolve20(home, ".nvm/versions/node");
4602
- if (existsSync20(nvmVersionsDir)) {
4667
+ const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
4668
+ if (existsSync21(nvmVersionsDir)) {
4603
4669
  try {
4604
- const versionDirs = readdirSync4(nvmVersionsDir).map((entry) => entry.trim()).filter((entry) => /^v\d+\.\d+\.\d+$/.test(entry)).sort((a, b) => Bun.semver.order(b.replace(/^v/, ""), a.replace(/^v/, "")));
4670
+ const versionDirs = readdirSync5(nvmVersionsDir).map((entry) => entry.trim()).filter((entry) => /^v\d+\.\d+\.\d+$/.test(entry)).sort((a, b) => Bun.semver.order(b.replace(/^v/, ""), a.replace(/^v/, "")));
4605
4671
  for (const versionDir of versionDirs) {
4606
- candidates.push(resolve20(nvmVersionsDir, versionDir, "bin/node"));
4672
+ candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
4607
4673
  }
4608
4674
  } catch {}
4609
4675
  }
@@ -4612,8 +4678,8 @@ function resolvePreferredNodeBinary() {
4612
4678
  if (whichNode) {
4613
4679
  candidates.push(whichNode);
4614
4680
  }
4615
- const deduped = uniq(candidates.map((candidate) => resolve20(candidate)));
4616
- const existing = deduped.filter((candidate) => existsSync20(candidate));
4681
+ const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
4682
+ const existing = deduped.filter((candidate) => existsSync21(candidate));
4617
4683
  if (existing.length === 0) {
4618
4684
  return null;
4619
4685
  }
@@ -4627,7 +4693,7 @@ function resolvePreferredNodeBinary() {
4627
4693
  return existing[0] ?? null;
4628
4694
  }
4629
4695
  function inferNodeMajor(nodeBinaryPath) {
4630
- const normalized = resolve20(nodeBinaryPath).replace(/\\/g, "/");
4696
+ const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
4631
4697
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
4632
4698
  if (!match) {
4633
4699
  return null;
@@ -4639,8 +4705,8 @@ function normalizeExecutablePath(candidate) {
4639
4705
  if (!candidate) {
4640
4706
  return "";
4641
4707
  }
4642
- const normalized = resolve20(candidate);
4643
- if (!existsSync20(normalized)) {
4708
+ const normalized = resolve21(candidate);
4709
+ if (!existsSync21(normalized)) {
4644
4710
  return "";
4645
4711
  }
4646
4712
  try {
@@ -4650,7 +4716,7 @@ function normalizeExecutablePath(candidate) {
4650
4716
  }
4651
4717
  }
4652
4718
  function looksLikeRuntimeGateway(candidate) {
4653
- const normalized = resolve20(candidate).replace(/\\/g, "/");
4719
+ const normalized = resolve21(candidate).replace(/\\/g, "/");
4654
4720
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
4655
4721
  }
4656
4722
 
@@ -4671,7 +4737,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4671
4737
  try {
4672
4738
  return resolveClaudeInstallDir();
4673
4739
  } catch {
4674
- return resolve21(claudeBinary, "..");
4740
+ return resolve22(claudeBinary, "..");
4675
4741
  }
4676
4742
  })() : "";
4677
4743
  const nodeDir = resolveNodeInstallDir();
@@ -4681,8 +4747,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4681
4747
  `${bunDir}/bin`,
4682
4748
  claudeDir,
4683
4749
  nodeDir ? `${nodeDir}/bin` : "",
4684
- realHome ? resolve21(realHome, ".local/bin") : "",
4685
- realHome ? resolve21(realHome, ".cargo/bin") : "",
4750
+ realHome ? resolve22(realHome, ".local/bin") : "",
4751
+ realHome ? resolve22(realHome, ".cargo/bin") : "",
4686
4752
  ...inheritedPath,
4687
4753
  "/usr/local/bin",
4688
4754
  "/usr/local/sbin",
@@ -4711,8 +4777,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4711
4777
  }
4712
4778
 
4713
4779
  // packages/runtime/src/control-plane/runtime/baked-secrets.ts
4714
- import { existsSync as existsSync21, readFileSync as readFileSync9 } from "fs";
4715
- import { resolve as resolve22 } from "path";
4780
+ import { existsSync as existsSync22, readFileSync as readFileSync10 } from "fs";
4781
+ import { resolve as resolve23 } from "path";
4716
4782
  var BAKED_RUNTIME_SECRETS = {
4717
4783
  ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
4718
4784
  OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
@@ -4755,12 +4821,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
4755
4821
  return resolved;
4756
4822
  }
4757
4823
  function loadDotEnvSecrets(projectRoot, env = process.env) {
4758
- const dotenvPath = resolve22(projectRoot, ".env");
4759
- if (!existsSync21(dotenvPath)) {
4824
+ const dotenvPath = resolve23(projectRoot, ".env");
4825
+ if (!existsSync22(dotenvPath)) {
4760
4826
  return {};
4761
4827
  }
4762
4828
  const parsed = {};
4763
- const lines = readFileSync9(dotenvPath, "utf-8").split(/\r?\n/);
4829
+ const lines = readFileSync10(dotenvPath, "utf-8").split(/\r?\n/);
4764
4830
  for (const rawLine of lines) {
4765
4831
  const line = rawLine.trim();
4766
4832
  if (!line || line.startsWith("#")) {
@@ -5117,16 +5183,16 @@ async function taskDeps(projectRoot, taskId) {
5117
5183
  for (const dep of deps) {
5118
5184
  const artifactDir = artifactDirForId(projectRoot, dep);
5119
5185
  console.log(`=== ${dep} ===`);
5120
- if (!existsSync22(artifactDir)) {
5186
+ if (!existsSync23(artifactDir)) {
5121
5187
  console.log(` (no artifacts yet)
5122
5188
  `);
5123
5189
  continue;
5124
5190
  }
5125
- printArtifactSection(resolve23(artifactDir, "decision-log.md"), "--- Decisions ---");
5126
- printArtifactSection(resolve23(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
5127
- const changedFiles = resolve23(artifactDir, "changed-files.txt");
5128
- if (existsSync22(changedFiles)) {
5129
- const lines = readFileSync10(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
5191
+ printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
5192
+ printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
5193
+ const changedFiles = resolve24(artifactDir, "changed-files.txt");
5194
+ if (existsSync23(changedFiles)) {
5195
+ const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
5130
5196
  console.log(`--- Changed Files (${lines.length}) ---`);
5131
5197
  for (const line of lines) {
5132
5198
  console.log(line);
@@ -5250,12 +5316,12 @@ function printIndented(text) {
5250
5316
  }
5251
5317
  }
5252
5318
  function readLocalBeadsTasks(projectRoot) {
5253
- const issuesPath = resolve23(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
5254
- if (!existsSync22(issuesPath)) {
5319
+ const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
5320
+ if (!existsSync23(issuesPath)) {
5255
5321
  return [];
5256
5322
  }
5257
5323
  const tasks = [];
5258
- for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
5324
+ for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
5259
5325
  const trimmed = line.trim();
5260
5326
  if (!trimmed) {
5261
5327
  continue;
@@ -5368,11 +5434,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
5368
5434
  return [...ids].sort();
5369
5435
  }
5370
5436
  function printArtifactSection(path, header) {
5371
- if (!existsSync22(path)) {
5437
+ if (!existsSync23(path)) {
5372
5438
  return;
5373
5439
  }
5374
5440
  console.log(header);
5375
- process.stdout.write(readFileSync10(path, "utf-8"));
5441
+ process.stdout.write(readFileSync11(path, "utf-8"));
5376
5442
  console.log("");
5377
5443
  }
5378
5444
 
@@ -5474,7 +5540,7 @@ init_layout();
5474
5540
 
5475
5541
  // packages/runtime/src/control-plane/runtime/overlay.ts
5476
5542
  init_layout();
5477
- import { mkdirSync as mkdirSync10 } from "fs";
5543
+ import { mkdirSync as mkdirSync11 } from "fs";
5478
5544
  function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
5479
5545
  const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
5480
5546
  const rootDir = layout.rigRoot;
@@ -5486,14 +5552,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
5486
5552
  const sessionDir = layout.sessionDir;
5487
5553
  const runtimeDir = layout.runtimeDir;
5488
5554
  const contextPath = layout.contextPath;
5489
- mkdirSync10(rootDir, { recursive: true });
5490
- mkdirSync10(homeDir, { recursive: true });
5491
- mkdirSync10(tmpDir, { recursive: true });
5492
- mkdirSync10(cacheDir, { recursive: true });
5493
- mkdirSync10(logsDir, { recursive: true });
5494
- mkdirSync10(stateDir, { recursive: true });
5495
- mkdirSync10(sessionDir, { recursive: true });
5496
- mkdirSync10(runtimeDir, { recursive: true });
5555
+ mkdirSync11(rootDir, { recursive: true });
5556
+ mkdirSync11(homeDir, { recursive: true });
5557
+ mkdirSync11(tmpDir, { recursive: true });
5558
+ mkdirSync11(cacheDir, { recursive: true });
5559
+ mkdirSync11(logsDir, { recursive: true });
5560
+ mkdirSync11(stateDir, { recursive: true });
5561
+ mkdirSync11(sessionDir, { recursive: true });
5562
+ mkdirSync11(runtimeDir, { recursive: true });
5497
5563
  return {
5498
5564
  rootDir,
5499
5565
  homeDir,
@@ -5511,17 +5577,17 @@ import {
5511
5577
  chmodSync as chmodSync5,
5512
5578
  copyFileSync as copyFileSync5,
5513
5579
  cpSync as cpSync2,
5514
- existsSync as existsSync24,
5515
- mkdirSync as mkdirSync11,
5580
+ existsSync as existsSync25,
5581
+ mkdirSync as mkdirSync12,
5516
5582
  statSync as statSync5,
5517
- writeFileSync as writeFileSync9
5583
+ writeFileSync as writeFileSync10
5518
5584
  } from "fs";
5519
5585
  import { mkdir } from "fs/promises";
5520
- import { basename as basename8, delimiter as delimiter2, resolve as resolve25 } from "path";
5586
+ import { basename as basename8, delimiter as delimiter2, resolve as resolve26 } from "path";
5521
5587
 
5522
5588
  // packages/runtime/src/control-plane/runtime/isolation/shared.ts
5523
- import { existsSync as existsSync23, readFileSync as readFileSync11, rmSync as rmSync8 } from "fs";
5524
- import { resolve as resolve24 } from "path";
5589
+ import { existsSync as existsSync24, readFileSync as readFileSync12, rmSync as rmSync9 } from "fs";
5590
+ import { resolve as resolve25 } from "path";
5525
5591
  var generatedCredentialFiles = new Set;
5526
5592
  var credentialCleanupRegistered = false;
5527
5593
  function resolveMonorepoRoot3(projectRoot) {
@@ -5545,7 +5611,7 @@ function resolveHostGitBinary() {
5545
5611
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
5546
5612
  continue;
5547
5613
  }
5548
- if (existsSync23(candidate)) {
5614
+ if (existsSync24(candidate)) {
5549
5615
  return candidate;
5550
5616
  }
5551
5617
  }
@@ -5611,7 +5677,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
5611
5677
  }
5612
5678
  }
5613
5679
  async function tryReadGitHead(repoRoot) {
5614
- if (!existsSync23(resolve24(repoRoot, ".git"))) {
5680
+ if (!existsSync24(resolve25(repoRoot, ".git"))) {
5615
5681
  return;
5616
5682
  }
5617
5683
  const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
@@ -5622,7 +5688,7 @@ async function tryReadGitHead(repoRoot) {
5622
5688
  return value || undefined;
5623
5689
  }
5624
5690
  async function captureRepoDirtyFiles(repoRoot) {
5625
- if (!existsSync23(resolve24(repoRoot, ".git"))) {
5691
+ if (!existsSync24(resolve25(repoRoot, ".git"))) {
5626
5692
  return [];
5627
5693
  }
5628
5694
  const files = new Set;
@@ -5658,7 +5724,7 @@ function registerCredentialCleanup(path) {
5658
5724
  const cleanup = () => {
5659
5725
  for (const filePath of generatedCredentialFiles) {
5660
5726
  try {
5661
- rmSync8(filePath, { force: true });
5727
+ rmSync9(filePath, { force: true });
5662
5728
  } catch {}
5663
5729
  }
5664
5730
  generatedCredentialFiles.clear();
@@ -5710,20 +5776,23 @@ function hashProjectPath(workspaceDir) {
5710
5776
  }
5711
5777
  function resolveGithubCliBinaryPath() {
5712
5778
  const explicit = process.env.RIG_GH_BIN?.trim();
5713
- if (explicit && existsSync23(explicit)) {
5779
+ if (explicit && existsSync24(explicit) && !isRuntimeGatewayGhPath(explicit)) {
5714
5780
  return explicit;
5715
5781
  }
5716
- const bunResolved = Bun.which("gh");
5717
- if (bunResolved && existsSync23(bunResolved)) {
5718
- return bunResolved;
5719
- }
5720
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
5721
- if (existsSync23(candidate)) {
5782
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
5783
+ if (existsSync24(candidate)) {
5722
5784
  return candidate;
5723
5785
  }
5724
5786
  }
5787
+ const bunResolved = Bun.which("gh");
5788
+ if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
5789
+ return bunResolved;
5790
+ }
5725
5791
  return "";
5726
5792
  }
5793
+ function isRuntimeGatewayGhPath(candidate) {
5794
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
5795
+ }
5727
5796
  async function resolveGithubCliAuthToken(ghBinary = "") {
5728
5797
  const gh = ghBinary || resolveGithubCliBinaryPath();
5729
5798
  if (!gh) {
@@ -5750,17 +5819,17 @@ function resolveSystemCertBundlePath() {
5750
5819
  "/opt/homebrew/etc/openssl@3/cert.pem"
5751
5820
  ];
5752
5821
  for (const candidate of candidates) {
5753
- if (candidate && existsSync23(candidate)) {
5754
- return resolve24(candidate);
5822
+ if (candidate && existsSync24(candidate)) {
5823
+ return resolve25(candidate);
5755
5824
  }
5756
5825
  }
5757
5826
  return "";
5758
5827
  }
5759
5828
  function readKnownHosts(path) {
5760
- if (!existsSync23(path)) {
5829
+ if (!existsSync24(path)) {
5761
5830
  return new Set;
5762
5831
  }
5763
- return new Set(readFileSync11(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
5832
+ return new Set(readFileSync12(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
5764
5833
  }
5765
5834
 
5766
5835
  // packages/runtime/src/control-plane/runtime/isolation/home.ts
@@ -5771,6 +5840,21 @@ var GITHUB_KNOWN_HOSTS = [
5771
5840
  "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
5772
5841
  ].join(`
5773
5842
  `);
5843
+ function resolveControlPlaneSourceRoot(projectRoot) {
5844
+ const candidates = [
5845
+ process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
5846
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
5847
+ resolve26(import.meta.dir, "../../../../.."),
5848
+ projectRoot
5849
+ ].filter((value) => Boolean(value));
5850
+ for (const candidate of candidates) {
5851
+ const root = resolve26(candidate);
5852
+ if (existsSync25(resolve26(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
5853
+ return root;
5854
+ }
5855
+ }
5856
+ return "";
5857
+ }
5774
5858
  async function runtimeEnv(projectRoot, runtime) {
5775
5859
  const bunBinaryPath = resolveBunBinaryPath();
5776
5860
  const bunDir = resolveBunInstallDir(bunBinaryPath);
@@ -5785,7 +5869,7 @@ async function runtimeEnv(projectRoot, runtime) {
5785
5869
  try {
5786
5870
  return resolveClaudeInstallDir();
5787
5871
  } catch {
5788
- return resolve25(claudeBinaryPath, "..");
5872
+ return resolve26(claudeBinaryPath, "..");
5789
5873
  }
5790
5874
  })() : "";
5791
5875
  const nodeDir = resolveNodeInstallDir();
@@ -5800,8 +5884,8 @@ async function runtimeEnv(projectRoot, runtime) {
5800
5884
  `${bunDir}/bin`,
5801
5885
  claudeDir,
5802
5886
  nodeDir ? `${nodeDir}/bin` : "",
5803
- realHome ? resolve25(realHome, ".local/bin") : "",
5804
- realHome ? resolve25(realHome, ".cargo/bin") : "",
5887
+ realHome ? resolve26(realHome, ".local/bin") : "",
5888
+ realHome ? resolve26(realHome, ".cargo/bin") : "",
5805
5889
  ...inheritedPath,
5806
5890
  "/usr/local/bin",
5807
5891
  "/usr/local/sbin",
@@ -5812,18 +5896,22 @@ async function runtimeEnv(projectRoot, runtime) {
5812
5896
  "/usr/sbin",
5813
5897
  "/sbin"
5814
5898
  ].filter(Boolean);
5815
- const runtimeBash = resolve25(runtime.binDir, "bash");
5816
- const runtimeRigGit = resolve25(runtime.binDir, runtimeRigGitFileName());
5817
- const preferredShell = existsSync24(runtimeBash) ? runtimeBash : "/bin/bash";
5899
+ const runtimeBash = resolve26(runtime.binDir, "bash");
5900
+ const runtimeRigGit = resolve26(runtime.binDir, runtimeRigGitFileName());
5901
+ const preferredShell = existsSync25(runtimeBash) ? runtimeBash : "/bin/bash";
5818
5902
  const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
5903
+ const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
5819
5904
  const env = {
5820
5905
  PROJECT_RIG_ROOT: projectRoot,
5821
5906
  RIG_HOST_PROJECT_ROOT: projectRoot,
5907
+ ...controlPlaneSourceRoot ? { RIG_CONTROL_PLANE_SOURCE_ROOT: controlPlaneSourceRoot } : {},
5822
5908
  HOME: runtime.homeDir,
5823
5909
  TMPDIR: runtime.tmpDir,
5824
5910
  XDG_CACHE_HOME: runtime.cacheDir,
5825
5911
  XDG_STATE_HOME: runtime.stateDir,
5826
5912
  RIG_AGENT_ID: runtime.id,
5913
+ ...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
5914
+ ...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
5827
5915
  RIG_TASK_ID: runtime.taskId,
5828
5916
  RIG_TASK_RUNTIME_ID: runtime.id,
5829
5917
  RIG_TASK_WORKSPACE: runtime.workspaceDir,
@@ -5831,30 +5919,30 @@ async function runtimeEnv(projectRoot, runtime) {
5831
5919
  RIG_RUNTIME_MODE: runtime.mode,
5832
5920
  RIG_RUNTIME_HOME: runtime.rootDir,
5833
5921
  RIG_RUNTIME_BIN_DIR: runtime.binDir,
5834
- ...existsSync24(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
5922
+ ...existsSync25(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
5835
5923
  RIG_BUN_PATH: bunBinaryPath,
5836
5924
  ...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
5837
- RIG_AGENT_BIN: resolve25(runtime.binDir, "rig-agent"),
5925
+ RIG_AGENT_BIN: resolve26(runtime.binDir, "rig-agent"),
5838
5926
  RIG_HOOKS_ACTIVE: "1",
5839
5927
  RIG_AUTO_PR_ON_COMPLETE: "1",
5840
- RIG_POLICY_FILE: resolve25(projectRoot, "rig/policy/policy.json"),
5928
+ RIG_POLICY_FILE: resolve26(projectRoot, "rig/policy/policy.json"),
5841
5929
  RIG_STATE_DIR: runtime.stateDir,
5842
5930
  RIG_LOGS_DIR: runtime.logsDir,
5843
- RIG_SESSION_FILE: resolve25(runtime.sessionDir, "session.json"),
5931
+ RIG_SESSION_FILE: resolve26(runtime.sessionDir, "session.json"),
5844
5932
  MONOREPO_ROOT: runtime.workspaceDir,
5845
5933
  MONOREPO_MAIN_ROOT: monorepoMainRoot,
5846
- TS_API_TESTS_DIR: resolve25(runtime.workspaceDir, "TSAPITests"),
5934
+ TS_API_TESTS_DIR: resolve26(runtime.workspaceDir, "TSAPITests"),
5847
5935
  BASH: preferredShell,
5848
5936
  SHELL: preferredShell,
5849
5937
  PATH: [...new Set(pathEntries)].join(delimiter2),
5850
5938
  LANG: process.env.LANG ?? "en_US.UTF-8",
5851
5939
  TERM: process.env.TERM ?? "xterm-256color",
5852
5940
  PYTHONDONTWRITEBYTECODE: "1",
5853
- PYTHONPYCACHEPREFIX: resolve25(runtime.cacheDir, "python"),
5941
+ PYTHONPYCACHEPREFIX: resolve26(runtime.cacheDir, "python"),
5854
5942
  ...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
5855
5943
  ...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
5856
5944
  CLAUDE_HOME: runtime.claudeHomeDir,
5857
- PI_CODING_AGENT_DIR: resolve25(runtime.homeDir, ".pi", "agent"),
5945
+ PI_CODING_AGENT_DIR: resolve26(runtime.homeDir, ".pi", "agent"),
5858
5946
  [RUNTIME_CONTEXT_ENV]: runtime.contextFile,
5859
5947
  ...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
5860
5948
  ...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
@@ -5865,16 +5953,16 @@ async function runtimeEnv(projectRoot, runtime) {
5865
5953
  NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
5866
5954
  } : {}
5867
5955
  };
5868
- const knownHostsPath = resolve25(runtime.homeDir, ".ssh", "known_hosts");
5869
- if (existsSync24(knownHostsPath)) {
5870
- const agentSshKey = resolve25(runtime.homeDir, ".ssh", "rig-agent-key");
5956
+ const knownHostsPath = resolve26(runtime.homeDir, ".ssh", "known_hosts");
5957
+ if (existsSync25(knownHostsPath)) {
5958
+ const agentSshKey = resolve26(runtime.homeDir, ".ssh", "rig-agent-key");
5871
5959
  const sshParts = [
5872
5960
  "ssh",
5873
5961
  `-o UserKnownHostsFile="${knownHostsPath}"`,
5874
5962
  "-o StrictHostKeyChecking=yes",
5875
5963
  "-F /dev/null"
5876
5964
  ];
5877
- if (existsSync24(agentSshKey)) {
5965
+ if (existsSync25(agentSshKey)) {
5878
5966
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
5879
5967
  }
5880
5968
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -5911,7 +5999,7 @@ async function runtimeEnv(projectRoot, runtime) {
5911
5999
  if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
5912
6000
  env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
5913
6001
  }
5914
- if (existsSync24(runtime.contextFile)) {
6002
+ if (existsSync25(runtime.contextFile)) {
5915
6003
  const runtimeContext = loadRuntimeContext(runtime.contextFile);
5916
6004
  Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
5917
6005
  Object.assign(env, browserEnvFromContext(runtimeContext.browser));
@@ -5925,30 +6013,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
5925
6013
  await mkdir(runtime.cacheDir, { recursive: true });
5926
6014
  await provisionAgentSshKey(runtime.homeDir);
5927
6015
  if (options.provider === "codex") {
5928
- const hasCodexAuth = await injectCodexAuth(resolve25(runtime.homeDir, ".codex"));
6016
+ const hasCodexAuth = await injectCodexAuth(resolve26(runtime.homeDir, ".codex"));
5929
6017
  if (!hasCodexAuth) {
5930
6018
  console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
5931
6019
  }
5932
6020
  }
5933
6021
  if (options.provider === "pi") {
5934
- const hasPiAuth = await injectPiAgentConfig(resolve25(runtime.homeDir, ".pi", "agent"));
6022
+ const hasPiAuth = await injectPiAgentConfig(resolve26(runtime.homeDir, ".pi", "agent"));
5935
6023
  if (!hasPiAuth) {
5936
6024
  console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
5937
6025
  }
5938
6026
  }
5939
6027
  }
5940
6028
  async function provisionClaudeHome(config) {
5941
- mkdirSync11(config.claudeHomeDir, { recursive: true });
5942
- const workspaceSettings = resolve25(config.workspaceDir, ".claude/settings.json");
5943
- const hostSettings = resolve25(config.hostProjectRoot, ".claude/settings.json");
5944
- const projectSettings = existsSync24(workspaceSettings) ? workspaceSettings : hostSettings;
6029
+ mkdirSync12(config.claudeHomeDir, { recursive: true });
6030
+ const workspaceSettings = resolve26(config.workspaceDir, ".claude/settings.json");
6031
+ const hostSettings = resolve26(config.hostProjectRoot, ".claude/settings.json");
6032
+ const projectSettings = existsSync25(workspaceSettings) ? workspaceSettings : hostSettings;
5945
6033
  const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
5946
- if (existsSync24(projectSettings)) {
5947
- writeFileSync9(resolve25(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
6034
+ if (existsSync25(projectSettings)) {
6035
+ writeFileSync10(resolve26(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
5948
6036
  `, "utf-8");
5949
6037
  }
5950
6038
  writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
5951
- writeFileSync9(resolve25(config.claudeHomeDir, "settings.json"), JSON.stringify({
6039
+ writeFileSync10(resolve26(config.claudeHomeDir, "settings.json"), JSON.stringify({
5952
6040
  permissions: { defaultMode: "bypassPermissions" },
5953
6041
  autoMemoryEnabled: false
5954
6042
  }, null, 2));
@@ -5956,12 +6044,12 @@ async function provisionClaudeHome(config) {
5956
6044
  if (!hasCredentials) {
5957
6045
  console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
5958
6046
  }
5959
- const realClaudeHome = resolve25(process.env.HOME ?? "", ".claude");
5960
- if (process.env.HOME && existsSync24(resolve25(realClaudeHome, "CLAUDE.md"))) {
5961
- cpSync2(resolve25(realClaudeHome, "CLAUDE.md"), resolve25(config.claudeHomeDir, "CLAUDE.md"));
6047
+ const realClaudeHome = resolve26(process.env.HOME ?? "", ".claude");
6048
+ if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "CLAUDE.md"))) {
6049
+ cpSync2(resolve26(realClaudeHome, "CLAUDE.md"), resolve26(config.claudeHomeDir, "CLAUDE.md"));
5962
6050
  }
5963
- if (process.env.HOME && existsSync24(resolve25(realClaudeHome, "agents"))) {
5964
- cpSync2(resolve25(realClaudeHome, "agents"), resolve25(config.claudeHomeDir, "agents"), { recursive: true });
6051
+ if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "agents"))) {
6052
+ cpSync2(resolve26(realClaudeHome, "agents"), resolve26(config.claudeHomeDir, "agents"), { recursive: true });
5965
6053
  }
5966
6054
  if (process.platform === "darwin" && process.env.HOME) {
5967
6055
  writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
@@ -5972,10 +6060,10 @@ async function materializeRuntimeCertBundle(runtime) {
5972
6060
  if (!sourcePath) {
5973
6061
  return "";
5974
6062
  }
5975
- const certsDir = resolve25(runtime.rootDir, "certs");
5976
- const targetPath = resolve25(certsDir, "ca-certificates.pem");
6063
+ const certsDir = resolve26(runtime.rootDir, "certs");
6064
+ const targetPath = resolve26(certsDir, "ca-certificates.pem");
5977
6065
  await mkdir(certsDir, { recursive: true });
5978
- let shouldCopy = !existsSync24(targetPath);
6066
+ let shouldCopy = !existsSync25(targetPath);
5979
6067
  if (!shouldCopy) {
5980
6068
  try {
5981
6069
  shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
@@ -5997,7 +6085,7 @@ function applyGitHubCredentialHelperEnv(env) {
5997
6085
  env.GIT_CONFIG_VALUE_1 = '!f() { test "$1" = get || exit 0; token="${GITHUB_TOKEN:-${GH_TOKEN:-${RIG_GITHUB_TOKEN:-}}}"; test -n "$token" || exit 0; echo username=x-access-token; echo password="$token"; }; f';
5998
6086
  }
5999
6087
  function persistRuntimeSecrets(runtimeRoot, env) {
6000
- const secretsPath = resolve25(runtimeRoot, "runtime-secrets.json");
6088
+ const secretsPath = resolve26(runtimeRoot, "runtime-secrets.json");
6001
6089
  const persisted = {};
6002
6090
  for (const key of [
6003
6091
  "GITHUB_TOKEN",
@@ -6016,12 +6104,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
6016
6104
  if (Object.keys(persisted).length === 0) {
6017
6105
  return;
6018
6106
  }
6019
- writeFileSync9(secretsPath, `${JSON.stringify(persisted, null, 2)}
6107
+ writeFileSync10(secretsPath, `${JSON.stringify(persisted, null, 2)}
6020
6108
  `, "utf-8");
6021
6109
  }
6022
6110
  async function provisionAgentSshKey(homeDir) {
6023
- const sshDir = resolve25(homeDir, ".ssh");
6024
- if (!existsSync24(sshDir)) {
6111
+ const sshDir = resolve26(homeDir, ".ssh");
6112
+ if (!existsSync25(sshDir)) {
6025
6113
  await mkdir(sshDir, { recursive: true });
6026
6114
  }
6027
6115
  seedKnownHosts(sshDir);
@@ -6029,27 +6117,27 @@ async function provisionAgentSshKey(homeDir) {
6029
6117
  const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
6030
6118
  if (!privateKey) {
6031
6119
  const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
6032
- if (!process.env.HOME || !existsSync24(hostKeyPath)) {
6120
+ if (!process.env.HOME || !existsSync25(hostKeyPath)) {
6033
6121
  return;
6034
6122
  }
6035
- const agentKeyPath2 = resolve25(sshDir, "rig-agent-key");
6036
- if (!existsSync24(agentKeyPath2)) {
6123
+ const agentKeyPath2 = resolve26(sshDir, "rig-agent-key");
6124
+ if (!existsSync25(agentKeyPath2)) {
6037
6125
  copyFileSync5(hostKeyPath, agentKeyPath2);
6038
6126
  chmodSync5(agentKeyPath2, 384);
6039
6127
  }
6040
6128
  const hostPubPath = `${hostKeyPath}.pub`;
6041
- if (existsSync24(hostPubPath)) {
6129
+ if (existsSync25(hostPubPath)) {
6042
6130
  const agentPubPath = `${agentKeyPath2}.pub`;
6043
- if (!existsSync24(agentPubPath)) {
6131
+ if (!existsSync25(agentPubPath)) {
6044
6132
  copyFileSync5(hostPubPath, agentPubPath);
6045
6133
  }
6046
6134
  }
6047
6135
  writeSshConfig(sshDir, agentKeyPath2);
6048
6136
  return;
6049
6137
  }
6050
- const agentKeyPath = resolve25(sshDir, "rig-agent-key");
6051
- if (!existsSync24(agentKeyPath)) {
6052
- writeFileSync9(agentKeyPath, privateKey, { mode: 384 });
6138
+ const agentKeyPath = resolve26(sshDir, "rig-agent-key");
6139
+ if (!existsSync25(agentKeyPath)) {
6140
+ writeFileSync10(agentKeyPath, privateKey, { mode: 384 });
6053
6141
  }
6054
6142
  writeSshConfig(sshDir, agentKeyPath);
6055
6143
  }
@@ -6066,21 +6154,21 @@ function decodeProvisionedSshKey(encodedKey) {
6066
6154
  `;
6067
6155
  }
6068
6156
  function resolveHostSshKeyPath(homeDir) {
6069
- const sshDir = resolve25(homeDir, ".ssh");
6157
+ const sshDir = resolve26(homeDir, ".ssh");
6070
6158
  const candidates = [
6071
6159
  "rig-agent-key",
6072
6160
  "id_ed25519",
6073
6161
  "id_ecdsa",
6074
6162
  "id_rsa"
6075
- ].map((name) => resolve25(sshDir, name));
6076
- return candidates.find((candidate) => existsSync24(candidate)) ?? resolve25(sshDir, "rig-agent-key");
6163
+ ].map((name) => resolve26(sshDir, name));
6164
+ return candidates.find((candidate) => existsSync25(candidate)) ?? resolve26(sshDir, "rig-agent-key");
6077
6165
  }
6078
6166
  function writeSshConfig(sshDir, keyPath) {
6079
- const configPath = resolve25(sshDir, "config");
6080
- if (existsSync24(configPath)) {
6167
+ const configPath = resolve26(sshDir, "config");
6168
+ if (existsSync25(configPath)) {
6081
6169
  return;
6082
6170
  }
6083
- const knownHostsPath = resolve25(sshDir, "known_hosts");
6171
+ const knownHostsPath = resolve26(sshDir, "known_hosts");
6084
6172
  const config = [
6085
6173
  "Host github.com",
6086
6174
  ` IdentityFile ${keyPath}`,
@@ -6090,10 +6178,10 @@ function writeSshConfig(sshDir, keyPath) {
6090
6178
  ""
6091
6179
  ].join(`
6092
6180
  `);
6093
- writeFileSync9(configPath, config, { mode: 420 });
6181
+ writeFileSync10(configPath, config, { mode: 420 });
6094
6182
  }
6095
6183
  function seedKnownHosts(sshDir) {
6096
- const knownHostsPath = resolve25(sshDir, "known_hosts");
6184
+ const knownHostsPath = resolve26(sshDir, "known_hosts");
6097
6185
  const existingLines = readKnownHosts(knownHostsPath);
6098
6186
  const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
6099
6187
  const missing = requiredLines.filter((line) => !existingLines.has(line));
@@ -6104,23 +6192,23 @@ function seedKnownHosts(sshDir) {
6104
6192
  for (const line of missing) {
6105
6193
  existingLines.add(line);
6106
6194
  }
6107
- writeFileSync9(knownHostsPath, `${Array.from(existingLines).join(`
6195
+ writeFileSync10(knownHostsPath, `${Array.from(existingLines).join(`
6108
6196
  `)}
6109
6197
  `, { mode: 420 });
6110
6198
  } catch (err) {
6111
- const hint = existsSync24(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
6199
+ const hint = existsSync25(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
6112
6200
  console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
6113
6201
  }
6114
6202
  }
6115
6203
  function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
6116
6204
  const projectHash = hashProjectPath(workspaceDir);
6117
- const projectDir = resolve25(claudeHomeDir, "projects", projectHash);
6118
- mkdirSync11(projectDir, { recursive: true });
6119
- writeFileSync9(resolve25(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
6205
+ const projectDir = resolve26(claudeHomeDir, "projects", projectHash);
6206
+ mkdirSync12(projectDir, { recursive: true });
6207
+ writeFileSync10(resolve26(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
6120
6208
  `, "utf-8");
6121
6209
  }
6122
6210
  async function loadRuntimeClaudeSettings(projectSettingsPath) {
6123
- if (!existsSync24(projectSettingsPath)) {
6211
+ if (!existsSync25(projectSettingsPath)) {
6124
6212
  return {};
6125
6213
  }
6126
6214
  let parsed;
@@ -6166,7 +6254,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
6166
6254
  return clone;
6167
6255
  }
6168
6256
  async function injectClaudeCredentials(claudeHomeDir, options = {}) {
6169
- const credentialsPath = resolve25(claudeHomeDir, ".credentials.json");
6257
+ const credentialsPath = resolve26(claudeHomeDir, ".credentials.json");
6170
6258
  const platform = options.platform ?? process.platform;
6171
6259
  if (platform === "darwin") {
6172
6260
  const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
@@ -6176,16 +6264,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
6176
6264
  if (raw) {
6177
6265
  try {
6178
6266
  JSON.parse(raw);
6179
- writeFileSync9(credentialsPath, raw, { mode: 384 });
6267
+ writeFileSync10(credentialsPath, raw, { mode: 384 });
6180
6268
  registerCredentialCleanup(credentialsPath);
6181
6269
  return true;
6182
6270
  } catch {}
6183
6271
  }
6184
6272
  }
6185
- const hostClaudeHome = options.hostClaudeHome ? resolve25(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve25(process.env.CLAUDE_HOME) : process.env.HOME ? resolve25(process.env.HOME, ".claude") : "";
6273
+ const hostClaudeHome = options.hostClaudeHome ? resolve26(options.hostClaudeHome) : process.env.CLAUDE_HOME?.trim() ? resolve26(process.env.CLAUDE_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".claude") : "";
6186
6274
  if (hostClaudeHome) {
6187
- const realCredentials = resolve25(hostClaudeHome, ".credentials.json");
6188
- if (existsSync24(realCredentials)) {
6275
+ const realCredentials = resolve26(hostClaudeHome, ".credentials.json");
6276
+ if (existsSync25(realCredentials)) {
6189
6277
  cpSync2(realCredentials, credentialsPath);
6190
6278
  return true;
6191
6279
  }
@@ -6193,36 +6281,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
6193
6281
  return false;
6194
6282
  }
6195
6283
  async function injectCodexAuth(codexHomeDir) {
6196
- mkdirSync11(codexHomeDir, { recursive: true });
6197
- const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve25(process.env.CODEX_HOME) : process.env.HOME ? resolve25(process.env.HOME, ".codex") : "";
6284
+ mkdirSync12(codexHomeDir, { recursive: true });
6285
+ const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve26(process.env.CODEX_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".codex") : "";
6198
6286
  if (!hostCodexHome) {
6199
6287
  return false;
6200
6288
  }
6201
- const hostAuthPath = resolve25(hostCodexHome, "auth.json");
6202
- if (!existsSync24(hostAuthPath)) {
6289
+ const hostAuthPath = resolve26(hostCodexHome, "auth.json");
6290
+ if (!existsSync25(hostAuthPath)) {
6203
6291
  return false;
6204
6292
  }
6205
- const runtimeAuthPath = resolve25(codexHomeDir, "auth.json");
6293
+ const runtimeAuthPath = resolve26(codexHomeDir, "auth.json");
6206
6294
  copyFileSync5(hostAuthPath, runtimeAuthPath);
6207
6295
  chmodSync5(runtimeAuthPath, 384);
6208
6296
  return true;
6209
6297
  }
6210
6298
  async function injectPiAgentConfig(piAgentDir) {
6211
- mkdirSync11(piAgentDir, { recursive: true });
6212
- const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve25(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve25(process.env.HOME, ".pi", "agent") : "";
6299
+ mkdirSync12(piAgentDir, { recursive: true });
6300
+ const hostPiAgentDir = process.env.PI_CODING_AGENT_DIR?.trim() ? resolve26(process.env.PI_CODING_AGENT_DIR) : process.env.HOME ? resolve26(process.env.HOME, ".pi", "agent") : "";
6213
6301
  if (!hostPiAgentDir) {
6214
6302
  return false;
6215
6303
  }
6216
- const hostAuthPath = resolve25(hostPiAgentDir, "auth.json");
6217
- if (!existsSync24(hostAuthPath)) {
6304
+ const hostAuthPath = resolve26(hostPiAgentDir, "auth.json");
6305
+ if (!existsSync25(hostAuthPath)) {
6218
6306
  return false;
6219
6307
  }
6220
- const runtimeAuthPath = resolve25(piAgentDir, "auth.json");
6308
+ const runtimeAuthPath = resolve26(piAgentDir, "auth.json");
6221
6309
  copyFileSync5(hostAuthPath, runtimeAuthPath);
6222
6310
  chmodSync5(runtimeAuthPath, 384);
6223
- const hostSettingsPath = resolve25(hostPiAgentDir, "settings.json");
6224
- if (existsSync24(hostSettingsPath)) {
6225
- const runtimeSettingsPath = resolve25(piAgentDir, "settings.json");
6311
+ const hostSettingsPath = resolve26(hostPiAgentDir, "settings.json");
6312
+ if (existsSync25(hostSettingsPath)) {
6313
+ const runtimeSettingsPath = resolve26(piAgentDir, "settings.json");
6226
6314
  copyFileSync5(hostSettingsPath, runtimeSettingsPath);
6227
6315
  chmodSync5(runtimeSettingsPath, 384);
6228
6316
  }
@@ -6230,8 +6318,8 @@ async function injectPiAgentConfig(piAgentDir) {
6230
6318
  }
6231
6319
 
6232
6320
  // packages/runtime/src/control-plane/runtime/tooling/claude-router.ts
6233
- import { existsSync as existsSync25, mkdirSync as mkdirSync12, statSync as statSync6, writeFileSync as writeFileSync10 } from "fs";
6234
- import { resolve as resolve26 } from "path";
6321
+ import { existsSync as existsSync26, mkdirSync as mkdirSync13, statSync as statSync6, writeFileSync as writeFileSync11 } from "fs";
6322
+ import { resolve as resolve27 } from "path";
6235
6323
  var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
6236
6324
  var CLAUDE_DISABLED_FILE_TOOLS = [
6237
6325
  "Read",
@@ -6329,7 +6417,7 @@ function claudeRuntimeToolCliArgs(configPath) {
6329
6417
  function buildRuntimeToolRouterServerConfig(options) {
6330
6418
  return {
6331
6419
  type: "stdio",
6332
- command: resolve26(options.binDir, "rig-tool-router"),
6420
+ command: resolve27(options.binDir, "rig-tool-router"),
6333
6421
  args: [],
6334
6422
  env: {
6335
6423
  RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
@@ -6363,14 +6451,14 @@ function codexRuntimeToolCliArgs(options) {
6363
6451
  ];
6364
6452
  }
6365
6453
  function writeClaudeRuntimeToolRouterConfig(options) {
6366
- const configPath = resolve26(options.stateDir, "claude-runtime-tools.mcp.json");
6367
- mkdirSync12(options.stateDir, { recursive: true });
6454
+ const configPath = resolve27(options.stateDir, "claude-runtime-tools.mcp.json");
6455
+ mkdirSync13(options.stateDir, { recursive: true });
6368
6456
  const payload = {
6369
6457
  mcpServers: {
6370
6458
  [CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
6371
6459
  }
6372
6460
  };
6373
- writeFileSync10(configPath, `${JSON.stringify(payload, null, 2)}
6461
+ writeFileSync11(configPath, `${JSON.stringify(payload, null, 2)}
6374
6462
  `, "utf-8");
6375
6463
  return configPath;
6376
6464
  }
@@ -6457,7 +6545,7 @@ function resolveRuntimeToolBinary(toolName, env) {
6457
6545
  grep: "rig-grep"
6458
6546
  };
6459
6547
  const executable = mapping[toolName];
6460
- return executable ? resolve26(binDir, executable) : "";
6548
+ return executable ? resolve27(binDir, executable) : "";
6461
6549
  }
6462
6550
  function renderToolText(toolName, payload) {
6463
6551
  if (toolName === "shell") {
@@ -6522,10 +6610,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
6522
6610
  isError: true
6523
6611
  };
6524
6612
  }
6525
- const workspaceRoot = resolve26(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
6613
+ const workspaceRoot = resolve27(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
6526
6614
  const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
6527
6615
  const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
6528
- if (!existsSync25(workdir)) {
6616
+ if (!existsSync26(workdir)) {
6529
6617
  return {
6530
6618
  content: [{
6531
6619
  type: "text",
@@ -6592,10 +6680,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
6592
6680
  }
6593
6681
  function resolveRuntimeShellBinary(shellName, env) {
6594
6682
  const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
6595
- return binDir ? resolve26(binDir, shellName) : "";
6683
+ return binDir ? resolve27(binDir, shellName) : "";
6596
6684
  }
6597
6685
  function resolveWithinWorkspace(workspaceRoot, target) {
6598
- const resolvedTarget = resolve26(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
6686
+ const resolvedTarget = resolve27(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
6599
6687
  const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
6600
6688
  const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
6601
6689
  if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
@@ -6633,8 +6721,8 @@ if (false) {}
6633
6721
  init_layout();
6634
6722
 
6635
6723
  // packages/runtime/src/control-plane/runtime/isolation/worktree.ts
6636
- import { existsSync as existsSync26, mkdirSync as mkdirSync13, rmSync as rmSync9 } from "fs";
6637
- import { dirname as dirname11, resolve as resolve27 } from "path";
6724
+ import { existsSync as existsSync27, mkdirSync as mkdirSync14, rmSync as rmSync10 } from "fs";
6725
+ import { dirname as dirname11, resolve as resolve28 } from "path";
6638
6726
  async function resolveMonorepoBaseRef(monorepoRoot) {
6639
6727
  const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
6640
6728
  if (explicit) {
@@ -6670,12 +6758,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
6670
6758
  }
6671
6759
  async function provisionRuntimeWorktree(config) {
6672
6760
  const branch = runtimeBranchName(config.taskId, config.runtimeId);
6673
- let hasValidWorktree = existsSync26(resolve27(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
6674
- if (existsSync26(config.workspaceDir) && !hasValidWorktree) {
6675
- rmSync9(config.workspaceDir, { recursive: true, force: true });
6761
+ let hasValidWorktree = existsSync27(resolve28(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
6762
+ if (existsSync27(config.workspaceDir) && !hasValidWorktree) {
6763
+ rmSync10(config.workspaceDir, { recursive: true, force: true });
6676
6764
  }
6677
6765
  if (!hasValidWorktree) {
6678
- mkdirSync13(dirname11(config.workspaceDir), { recursive: true });
6766
+ mkdirSync14(dirname11(config.workspaceDir), { recursive: true });
6679
6767
  const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
6680
6768
  const add = branchExists.exitCode === 0 ? await runGitCommand(config.monorepoRoot, ["worktree", "add", "--force", config.workspaceDir, branch]) : await runGitCommand(config.monorepoRoot, ["worktree", "add", "--force", "-b", branch, config.workspaceDir, config.baseRef]);
6681
6769
  if (add.exitCode !== 0) {
@@ -6851,31 +6939,31 @@ async function preferredBaseRemotes(repoRoot) {
6851
6939
 
6852
6940
  // packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
6853
6941
  import {
6854
- existsSync as existsSync28,
6942
+ existsSync as existsSync29,
6855
6943
  lstatSync,
6856
- mkdirSync as mkdirSync15,
6857
- readdirSync as readdirSync5,
6858
- readFileSync as readFileSync13,
6859
- rmSync as rmSync10,
6944
+ mkdirSync as mkdirSync16,
6945
+ readdirSync as readdirSync6,
6946
+ readFileSync as readFileSync14,
6947
+ rmSync as rmSync11,
6860
6948
  statSync as statSync8,
6861
6949
  symlinkSync as symlinkSync4
6862
6950
  } from "fs";
6863
6951
  import { mkdir as mkdir2, writeFile } from "fs/promises";
6864
- import { dirname as dirname13, resolve as resolve29 } from "path";
6952
+ import { dirname as dirname13, resolve as resolve30 } from "path";
6865
6953
 
6866
6954
  // packages/runtime/src/control-plane/runtime/tooling/claude-router-binary.ts
6867
- import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync27, mkdirSync as mkdirSync14, statSync as statSync7 } from "fs";
6955
+ import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync28, mkdirSync as mkdirSync15, statSync as statSync7 } from "fs";
6868
6956
  import { tmpdir as tmpdir6 } from "os";
6869
- import { dirname as dirname12, resolve as resolve28 } from "path";
6870
- var sharedRouterOutputDir = resolve28(tmpdir6(), "rig-native");
6871
- var sharedRouterOutputPath = resolve28(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
6957
+ import { dirname as dirname12, resolve as resolve29 } from "path";
6958
+ var sharedRouterOutputDir = resolve29(tmpdir6(), "rig-native");
6959
+ var sharedRouterOutputPath = resolve29(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
6872
6960
  function runtimeClaudeToolRouterFileName() {
6873
6961
  return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
6874
6962
  }
6875
6963
  async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = sharedRouterOutputPath) {
6876
- const sourcePath = resolve28(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
6877
- mkdirSync14(dirname12(outputPath), { recursive: true });
6878
- const needsBuild = !existsSync27(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
6964
+ const sourcePath = resolve29(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
6965
+ mkdirSync15(dirname12(outputPath), { recursive: true });
6966
+ const needsBuild = !existsSync28(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
6879
6967
  if (!needsBuild) {
6880
6968
  return outputPath;
6881
6969
  }
@@ -6889,9 +6977,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
6889
6977
  }
6890
6978
  async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
6891
6979
  const sourcePath = await ensureClaudeToolRouterBinaryPath(projectRoot);
6892
- const targetPath = resolve28(targetDir, runtimeClaudeToolRouterFileName());
6893
- mkdirSync14(targetDir, { recursive: true });
6894
- const needsCopy = !existsSync27(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
6980
+ const targetPath = resolve29(targetDir, runtimeClaudeToolRouterFileName());
6981
+ mkdirSync15(targetDir, { recursive: true });
6982
+ const needsCopy = !existsSync28(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
6895
6983
  if (needsCopy) {
6896
6984
  copyFileSync6(sourcePath, targetPath);
6897
6985
  chmodSync6(targetPath, 493);
@@ -6904,48 +6992,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
6904
6992
  var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
6905
6993
  function resolveRigSourceRoot(projectRoot) {
6906
6994
  const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
6907
- if (hostProjectRoot && existsSync28(resolve29(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
6995
+ if (hostProjectRoot && existsSync29(resolve30(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
6908
6996
  return hostProjectRoot;
6909
6997
  }
6910
- const fromModule = resolve29(import.meta.dir, "../../../../../..");
6911
- if (existsSync28(resolve29(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
6998
+ const fromModule = resolve30(import.meta.dir, "../../../../../..");
6999
+ if (existsSync29(resolve30(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
6912
7000
  return fromModule;
6913
7001
  }
6914
7002
  return projectRoot;
6915
7003
  }
6916
7004
  function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
6917
- for (const path of [logsDir, stateDir, sessionDir, resolve29(sessionDir, "session.json")]) {
7005
+ for (const path of [logsDir, stateDir, sessionDir, resolve30(sessionDir, "session.json")]) {
6918
7006
  removeSymbolicLink(path);
6919
7007
  }
6920
7008
  runtimePrepareTrackedPathsNative({
6921
7009
  logsDir,
6922
7010
  stateDir,
6923
7011
  sessionDir,
6924
- controlledBashLogFile: resolve29(logsDir, "controlled-bash.jsonl"),
6925
- eventsFile: resolve29(logsDir, "control-plane.events.jsonl")
7012
+ controlledBashLogFile: resolve30(logsDir, "controlled-bash.jsonl"),
7013
+ eventsFile: resolve30(logsDir, "control-plane.events.jsonl")
6926
7014
  });
6927
7015
  }
6928
7016
  async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
6929
7017
  await mkdir2(stateDir, { recursive: true });
6930
7018
  await mkdir2(sessionDir, { recursive: true });
6931
- const failedApproachesPath = resolve29(stateDir, "failed_approaches.md");
6932
- if (!existsSync28(failedApproachesPath)) {
7019
+ const failedApproachesPath = resolve30(stateDir, "failed_approaches.md");
7020
+ if (!existsSync29(failedApproachesPath)) {
6933
7021
  await writeFile(failedApproachesPath, `# Failed Approaches
6934
7022
 
6935
7023
  `);
6936
7024
  }
6937
- const hookTripsPath = resolve29(stateDir, "hook_trips.log");
6938
- if (!existsSync28(hookTripsPath)) {
7025
+ const hookTripsPath = resolve30(stateDir, "hook_trips.log");
7026
+ if (!existsSync29(hookTripsPath)) {
6939
7027
  await writeFile(hookTripsPath, "");
6940
7028
  }
6941
- const sessionFile = resolve29(sessionDir, "session.json");
7029
+ const sessionFile = resolve30(sessionDir, "session.json");
6942
7030
  if (taskId) {
6943
7031
  await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
6944
7032
  }
6945
7033
  }
6946
7034
  async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
6947
- const artifactDir = resolve29(workspaceDir, "artifacts", taskId);
6948
- const runtimeSnapshotDir = resolve29(artifactDir, "runtime-snapshots");
7035
+ const artifactDir = resolve30(workspaceDir, "artifacts", taskId);
7036
+ const runtimeSnapshotDir = resolve30(artifactDir, "runtime-snapshots");
6949
7037
  let preservedTrackedFiles = false;
6950
7038
  for (const file of [
6951
7039
  "changed-files.txt",
@@ -6961,13 +7049,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
6961
7049
  preservedTrackedFiles = true;
6962
7050
  continue;
6963
7051
  }
6964
- rmSync10(resolve29(artifactDir, file), { force: true });
7052
+ rmSync11(resolve30(artifactDir, file), { force: true });
6965
7053
  }
6966
7054
  const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
6967
7055
  if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
6968
7056
  preservedTrackedFiles = true;
6969
7057
  } else {
6970
- rmSync10(runtimeSnapshotDir, { recursive: true, force: true });
7058
+ rmSync11(runtimeSnapshotDir, { recursive: true, force: true });
6971
7059
  }
6972
7060
  if (preservedTrackedFiles) {
6973
7061
  console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
@@ -7000,28 +7088,28 @@ async function buildRuntimeToolchain(options) {
7000
7088
  throw new Error("Failed to provision the native Zig runtime library.");
7001
7089
  }
7002
7090
  const rigSourceRoot = resolveRigSourceRoot(options.projectRoot);
7003
- await buildBinary("packages/cli/bin/rig.ts", resolve29(options.binDir, "rig"), rigSourceRoot);
7004
- await buildBinary("packages/runtime/bin/rig-agent.ts", resolve29(options.binDir, "rig-agent"), rigSourceRoot, {
7091
+ await buildBinary("packages/cli/bin/rig.ts", resolve30(options.binDir, "rig"), rigSourceRoot);
7092
+ await buildBinary("packages/runtime/bin/rig-agent.ts", resolve30(options.binDir, "rig-agent"), rigSourceRoot, {
7005
7093
  ...options.runtimeSecretDefines,
7006
7094
  AGENT_TASK_ID: options.taskId,
7007
7095
  AGENT_PROJECT_ROOT: options.projectRoot,
7008
7096
  AGENT_RUNTIME_ID: options.runtimeId,
7009
7097
  AGENT_SCOPE_HASH: options.bakedScopeHash,
7010
7098
  AGENT_MANIFEST_PATH: options.manifestPath,
7011
- AGENT_BINARY_PATH: resolve29(options.binDir, "rig-agent"),
7099
+ AGENT_BINARY_PATH: resolve30(options.binDir, "rig-agent"),
7012
7100
  AGENT_INFO_OUTPUT: options.bakedInfoOutput,
7013
7101
  AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
7014
7102
  AGENT_STATUS_OUTPUT: options.bakedStatusOutput
7015
7103
  });
7016
- await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve29(options.binDir, "controlled-bash"), rigSourceRoot, {
7104
+ await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve30(options.binDir, "controlled-bash"), rigSourceRoot, {
7017
7105
  AGENT_PROJECT_ROOT: options.projectRoot,
7018
7106
  AGENT_LOGS_DIR: options.logsDir,
7019
7107
  AGENT_MONOREPO_ROOT: resolveMonorepoRoot3(options.projectRoot),
7020
- AGENT_TS_API_TESTS_DIR: resolve29(options.workspaceDir, "TSAPITests"),
7021
- AGENT_RIG_AGENT_BIN: resolve29(options.binDir, "rig-agent")
7108
+ AGENT_TS_API_TESTS_DIR: resolve30(options.workspaceDir, "TSAPITests"),
7109
+ AGENT_RIG_AGENT_BIN: resolve30(options.binDir, "rig-agent")
7022
7110
  });
7023
- await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve29(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
7024
- await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve29(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
7111
+ await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve30(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
7112
+ await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve30(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
7025
7113
  AGENT_PROJECT_ROOT: options.projectRoot,
7026
7114
  AGENT_BUN_PATH: resolveBunBinaryPath()
7027
7115
  });
@@ -7030,15 +7118,15 @@ async function buildRuntimeToolchain(options) {
7030
7118
  AGENT_BUN_PATH: resolveBunBinaryPath()
7031
7119
  };
7032
7120
  for (const hookName of hookNames) {
7033
- await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve29(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
7121
+ await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve30(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
7034
7122
  }
7035
- const pluginsDir = resolve29(options.projectRoot, "rig/plugins");
7036
- if (existsSync28(pluginsDir)) {
7037
- for (const entry of readdirSync5(pluginsDir, { withFileTypes: true })) {
7123
+ const pluginsDir = resolve30(options.projectRoot, "rig/plugins");
7124
+ if (existsSync29(pluginsDir)) {
7125
+ for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
7038
7126
  const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
7039
7127
  if (!match)
7040
7128
  continue;
7041
- await buildBinary(`rig/plugins/${entry.name}`, resolve29(runtimeBins.pluginsDir, match[1]), options.projectRoot);
7129
+ await buildBinary(`rig/plugins/${entry.name}`, resolve30(runtimeBins.pluginsDir, match[1]), options.projectRoot);
7042
7130
  }
7043
7131
  }
7044
7132
  await materializeRigGitBinary(options.binDir);
@@ -7048,8 +7136,8 @@ async function buildRuntimeToolchain(options) {
7048
7136
  }
7049
7137
  async function writeRuntimeManifest(config) {
7050
7138
  const scopeHash = sha256Hex(JSON.stringify(config.scopes));
7051
- const binarySha256 = sha256Hex(readFileSync13(config.binaryPath));
7052
- const manifestPath = resolve29(config.runtimeRoot, "manifest.json");
7139
+ const binarySha256 = sha256Hex(readFileSync14(config.binaryPath));
7140
+ const manifestPath = resolve30(config.runtimeRoot, "manifest.json");
7053
7141
  const manifest = {
7054
7142
  runtimeId: config.runtimeId,
7055
7143
  taskId: config.taskId,
@@ -7083,7 +7171,7 @@ function removeSymbolicLink(path) {
7083
7171
  } catch {
7084
7172
  return;
7085
7173
  }
7086
- rmSync10(path, { force: true, recursive: true });
7174
+ rmSync11(path, { force: true, recursive: true });
7087
7175
  }
7088
7176
  async function resetTrackedArtifactPath(workspaceDir, relativePath) {
7089
7177
  const tracked = await runGitLsFiles(workspaceDir, relativePath);
@@ -7109,7 +7197,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
7109
7197
  const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
7110
7198
  const now = options.now ?? Date.now;
7111
7199
  const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
7112
- const removeFile = options.removeFile ?? ((path) => rmSync10(path, { force: true }));
7200
+ const removeFile = options.removeFile ?? ((path) => rmSync11(path, { force: true }));
7113
7201
  const log = options.log ?? console.warn;
7114
7202
  let lastOutput = "";
7115
7203
  for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
@@ -7169,31 +7257,31 @@ function readFileMtimeMs(path) {
7169
7257
  }
7170
7258
  function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
7171
7259
  linkGenericNodeModulesLayers(monorepoRoot, workspaceDir);
7172
- const sourceNodeModules = resolve29(monorepoRoot, "humoongate", "node_modules");
7173
- if (!existsSync28(sourceNodeModules)) {} else {
7174
- const runtimeHumoongate = resolve29(workspaceDir, "humoongate");
7175
- if (existsSync28(resolve29(runtimeHumoongate, "package.json"))) {
7176
- const targetNodeModules = resolve29(runtimeHumoongate, "node_modules");
7260
+ const sourceNodeModules = resolve30(monorepoRoot, "humoongate", "node_modules");
7261
+ if (!existsSync29(sourceNodeModules)) {} else {
7262
+ const runtimeHumoongate = resolve30(workspaceDir, "humoongate");
7263
+ if (existsSync29(resolve30(runtimeHumoongate, "package.json"))) {
7264
+ const targetNodeModules = resolve30(runtimeHumoongate, "node_modules");
7177
7265
  runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
7178
7266
  }
7179
7267
  }
7180
- const runtimeHpNext = resolve29(workspaceDir, "microservices", "hp-next-frontend", "app");
7181
- if (!existsSync28(resolve29(runtimeHpNext, "package.json"))) {
7268
+ const runtimeHpNext = resolve30(workspaceDir, "microservices", "hp-next-frontend", "app");
7269
+ if (!existsSync29(resolve30(runtimeHpNext, "package.json"))) {
7182
7270
  return;
7183
7271
  }
7184
- const sourceHpNextNodeModules = resolve29(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
7185
- const sourceMonorepoNodeModules = resolve29(monorepoRoot, "node_modules");
7186
- const targetHpNextNodeModules = resolve29(runtimeHpNext, "node_modules");
7187
- if (existsSync28(sourceHpNextNodeModules)) {
7272
+ const sourceHpNextNodeModules = resolve30(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
7273
+ const sourceMonorepoNodeModules = resolve30(monorepoRoot, "node_modules");
7274
+ const targetHpNextNodeModules = resolve30(runtimeHpNext, "node_modules");
7275
+ if (existsSync29(sourceHpNextNodeModules)) {
7188
7276
  runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
7189
7277
  return;
7190
7278
  }
7191
- if (existsSync28(sourceMonorepoNodeModules)) {
7279
+ if (existsSync29(sourceMonorepoNodeModules)) {
7192
7280
  runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
7193
7281
  }
7194
7282
  }
7195
7283
  function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
7196
- linkNodeModulesLayer(resolve29(monorepoRoot, "node_modules"), resolve29(workspaceDir, "node_modules"));
7284
+ linkNodeModulesLayer(resolve30(monorepoRoot, "node_modules"), resolve30(workspaceDir, "node_modules"));
7197
7285
  for (const relativePackageDir of [
7198
7286
  "apps/native-app/apps/marketing",
7199
7287
  "apps/native-app/apps/web",
@@ -7215,15 +7303,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
7215
7303
  "packages/standard-plugin",
7216
7304
  "packages/validator-kit"
7217
7305
  ]) {
7218
- const workspacePackageDir = resolve29(workspaceDir, relativePackageDir);
7219
- if (!existsSync28(resolve29(workspacePackageDir, "package.json"))) {
7306
+ const workspacePackageDir = resolve30(workspaceDir, relativePackageDir);
7307
+ if (!existsSync29(resolve30(workspacePackageDir, "package.json"))) {
7220
7308
  continue;
7221
7309
  }
7222
- linkNodeModulesLayer(resolve29(monorepoRoot, relativePackageDir, "node_modules"), resolve29(workspacePackageDir, "node_modules"));
7310
+ linkNodeModulesLayer(resolve30(monorepoRoot, relativePackageDir, "node_modules"), resolve30(workspacePackageDir, "node_modules"));
7223
7311
  }
7224
7312
  }
7225
7313
  function linkNodeModulesLayer(sourceDir, targetDir) {
7226
- if (!existsSync28(sourceDir) || existsSync28(targetDir)) {
7314
+ if (!existsSync29(sourceDir) || existsSync29(targetDir)) {
7227
7315
  return;
7228
7316
  }
7229
7317
  try {
@@ -7232,30 +7320,30 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
7232
7320
  } catch (error) {
7233
7321
  console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
7234
7322
  }
7235
- mkdirSync15(dirname13(targetDir), { recursive: true });
7323
+ mkdirSync16(dirname13(targetDir), { recursive: true });
7236
7324
  symlinkSync4(sourceDir, targetDir, "dir");
7237
7325
  }
7238
7326
  function ensureRuntimeBinTrees(runtimeBinDir) {
7239
- const hooksDir = resolve29(runtimeBinDir, "hooks");
7240
- const pluginsDir = resolve29(runtimeBinDir, "plugins");
7241
- const validatorsDir = resolve29(runtimeBinDir, "validators");
7242
- mkdirSync15(hooksDir, { recursive: true });
7243
- mkdirSync15(pluginsDir, { recursive: true });
7244
- mkdirSync15(validatorsDir, { recursive: true });
7327
+ const hooksDir = resolve30(runtimeBinDir, "hooks");
7328
+ const pluginsDir = resolve30(runtimeBinDir, "plugins");
7329
+ const validatorsDir = resolve30(runtimeBinDir, "validators");
7330
+ mkdirSync16(hooksDir, { recursive: true });
7331
+ mkdirSync16(pluginsDir, { recursive: true });
7332
+ mkdirSync16(validatorsDir, { recursive: true });
7245
7333
  return { hooksDir, pluginsDir, validatorsDir };
7246
7334
  }
7247
7335
 
7248
7336
  // packages/runtime/src/control-plane/runtime/isolation/runner.ts
7249
- import { existsSync as existsSync31, rmSync as rmSync11, writeFileSync as writeFileSync12 } from "fs";
7250
- import { basename as basename9, resolve as resolve33 } from "path";
7337
+ import { existsSync as existsSync32, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
7338
+ import { basename as basename9, resolve as resolve34 } from "path";
7251
7339
 
7252
7340
  // packages/runtime/src/control-plane/runtime/sandbox/backend.ts
7253
- import { existsSync as existsSync30 } from "fs";
7341
+ import { existsSync as existsSync31 } from "fs";
7254
7342
 
7255
7343
  // packages/runtime/src/control-plane/runtime/guard.ts
7256
7344
  import { optimizeNextInvocation } from "bun:jsc";
7257
- import { existsSync as existsSync29, readFileSync as readFileSync14, statSync as statSync9 } from "fs";
7258
- import { resolve as resolve30 } from "path";
7345
+ import { existsSync as existsSync30, readFileSync as readFileSync15, statSync as statSync9 } from "fs";
7346
+ import { resolve as resolve31 } from "path";
7259
7347
 
7260
7348
  // packages/runtime/src/control-plane/runtime/guard-types.ts
7261
7349
  var POLICY_VERSION = 1;
@@ -7318,8 +7406,8 @@ function loadPolicy(projectRoot) {
7318
7406
  if (seededPolicyConfig) {
7319
7407
  return seededPolicyConfig;
7320
7408
  }
7321
- const configPath = resolve30(projectRoot, "rig/policy/policy.json");
7322
- if (!existsSync29(configPath)) {
7409
+ const configPath = resolve31(projectRoot, "rig/policy/policy.json");
7410
+ if (!existsSync30(configPath)) {
7323
7411
  return defaultPolicy();
7324
7412
  }
7325
7413
  let mtimeMs;
@@ -7333,7 +7421,7 @@ function loadPolicy(projectRoot) {
7333
7421
  }
7334
7422
  let parsed;
7335
7423
  try {
7336
- parsed = JSON.parse(readFileSync14(configPath, "utf-8"));
7424
+ parsed = JSON.parse(readFileSync15(configPath, "utf-8"));
7337
7425
  } catch {
7338
7426
  return defaultPolicy();
7339
7427
  }
@@ -7549,28 +7637,28 @@ function resolveAction(mode, matched) {
7549
7637
  }
7550
7638
  function resolveAbsolutePath(projectRoot, rawPath) {
7551
7639
  if (rawPath.startsWith("/"))
7552
- return resolve30(rawPath);
7553
- return resolve30(projectRoot, rawPath);
7640
+ return resolve31(rawPath);
7641
+ return resolve31(projectRoot, rawPath);
7554
7642
  }
7555
7643
  function isHarnessPath(projectRoot, rawPath) {
7556
7644
  const absPath = resolveAbsolutePath(projectRoot, rawPath);
7557
7645
  const managedRoots = [
7558
- resolve30(projectRoot, "rig"),
7559
- resolve30(projectRoot, ".rig"),
7560
- resolve30(projectRoot, "artifacts")
7646
+ resolve31(projectRoot, "rig"),
7647
+ resolve31(projectRoot, ".rig"),
7648
+ resolve31(projectRoot, "artifacts")
7561
7649
  ];
7562
7650
  return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
7563
7651
  }
7564
7652
  function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
7565
7653
  const absPath = resolveAbsolutePath(projectRoot, rawPath);
7566
7654
  if (taskWorkspace) {
7567
- const workspaceRigRoot = resolve30(taskWorkspace, ".rig");
7568
- const workspaceArtifactsRoot = resolve30(taskWorkspace, "artifacts");
7655
+ const workspaceRigRoot = resolve31(taskWorkspace, ".rig");
7656
+ const workspaceArtifactsRoot = resolve31(taskWorkspace, "artifacts");
7569
7657
  if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
7570
7658
  return true;
7571
7659
  }
7572
7660
  }
7573
- const runtimeRoot = resolve30(projectRoot, ".rig/runtime/agents");
7661
+ const runtimeRoot = resolve31(projectRoot, ".rig/runtime/agents");
7574
7662
  return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
7575
7663
  }
7576
7664
  function isTestFile(path) {
@@ -7618,7 +7706,7 @@ function evaluateScope(policy, context, filePath, access) {
7618
7706
  return allowed();
7619
7707
  }
7620
7708
  if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
7621
- const absPath = resolve30(filePath);
7709
+ const absPath = resolve31(filePath);
7622
7710
  if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
7623
7711
  const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
7624
7712
  const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
@@ -7946,13 +8034,13 @@ async function resolveBackend(projectRoot, options) {
7946
8034
  depRoots
7947
8035
  };
7948
8036
  const fsContext = {
7949
- pathExists: (p) => existsSync30(p),
8037
+ pathExists: (p) => existsSync31(p),
7950
8038
  realPath: toRealPath
7951
8039
  };
7952
8040
  if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
7953
8041
  const seatbelt = Bun.which("sandbox-exec");
7954
8042
  probed.push("sandbox-exec");
7955
- if (seatbelt && existsSync30(seatbelt)) {
8043
+ if (seatbelt && existsSync31(seatbelt)) {
7956
8044
  const SeatbeltBackendClass = loadSeatbeltBackend();
7957
8045
  if (SeatbeltBackendClass) {
7958
8046
  return {
@@ -8073,10 +8161,10 @@ init_layout();
8073
8161
  var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
8074
8162
  async function startRuntimeSnapshotSidecar(runtime, options = {}) {
8075
8163
  const instanceId = sanitizeRuntimeRefSegment(options.instanceId?.trim() || runtime.id);
8076
- const readyFile = resolve33(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
8077
- const requestFile = resolve33(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
8078
- rmSync11(readyFile, { force: true });
8079
- rmSync11(requestFile, { force: true });
8164
+ const readyFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
8165
+ const requestFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
8166
+ rmSync12(readyFile, { force: true });
8167
+ rmSync12(requestFile, { force: true });
8080
8168
  const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
8081
8169
  const useCompiledSidecar = shouldUseCompiledSnapshotSidecar(sidecarBinary);
8082
8170
  const bunCli = useCompiledSidecar ? null : resolveBunCliInvocation();
@@ -8114,19 +8202,19 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
8114
8202
  proc.kill("SIGTERM");
8115
8203
  } catch {}
8116
8204
  await proc.exited;
8117
- rmSync11(readyFile, { force: true });
8118
- rmSync11(requestFile, { force: true });
8205
+ rmSync12(readyFile, { force: true });
8206
+ rmSync12(requestFile, { force: true });
8119
8207
  },
8120
8208
  finalize: async (commandParts, exitCode) => {
8121
- writeFileSync12(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
8209
+ writeFileSync13(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
8122
8210
  `, "utf-8");
8123
8211
  const [sidecarExitCode, stdout, stderr] = await Promise.all([
8124
8212
  proc.exited,
8125
8213
  stdoutTextPromise,
8126
8214
  stderrTextPromise
8127
8215
  ]);
8128
- rmSync11(readyFile, { force: true });
8129
- rmSync11(requestFile, { force: true });
8216
+ rmSync12(readyFile, { force: true });
8217
+ rmSync12(requestFile, { force: true });
8130
8218
  if (sidecarExitCode !== 0) {
8131
8219
  throw new Error(`snapshot sidecar failed (${sidecarExitCode}): ${stderr || stdout}`);
8132
8220
  }
@@ -8146,10 +8234,10 @@ function resolveSnapshotSidecarScriptPath() {
8146
8234
  return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
8147
8235
  }
8148
8236
  function resolveSnapshotSidecarBinaryPath(binDir) {
8149
- return resolve33(binDir, "snapshot-sidecar");
8237
+ return resolve34(binDir, "snapshot-sidecar");
8150
8238
  }
8151
8239
  function shouldUseCompiledSnapshotSidecar(binaryPath) {
8152
- if (!existsSync31(binaryPath)) {
8240
+ if (!existsSync32(binaryPath)) {
8153
8241
  return false;
8154
8242
  }
8155
8243
  const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
@@ -8164,12 +8252,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
8164
8252
  process.env.PROJECT_RIG_ROOT?.trim()
8165
8253
  ].filter((value) => Boolean(value));
8166
8254
  for (const root of hostRoots) {
8167
- const candidate = resolve33(root, "packages/runtime/src/control-plane/runtime", fileName);
8168
- if (existsSync31(candidate)) {
8255
+ const candidate = resolve34(root, "packages/runtime/src/control-plane/runtime", fileName);
8256
+ if (existsSync32(candidate)) {
8169
8257
  return candidate;
8170
8258
  }
8171
8259
  }
8172
- return resolve33(import.meta.dir, "..", fileName);
8260
+ return resolve34(import.meta.dir, "..", fileName);
8173
8261
  }
8174
8262
  function resolveBunCliInvocation() {
8175
8263
  if (process.env.RIG_BUN_PATH?.trim()) {
@@ -8196,7 +8284,7 @@ function resolveBunCliInvocation() {
8196
8284
  async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
8197
8285
  const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
8198
8286
  while (Date.now() < deadline) {
8199
- if (existsSync31(readyFile)) {
8287
+ if (existsSync32(readyFile)) {
8200
8288
  return;
8201
8289
  }
8202
8290
  const exitCode = proc.exitCode;
@@ -8214,9 +8302,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
8214
8302
  async function hydrateRuntimeMemory(options) {
8215
8303
  const snapshot = await readCanonicalMemoryDb(options.projectRoot);
8216
8304
  const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
8217
- const hydratedPath = resolve34(workspaceLayout.stateDir, "memory", "project-memory.db");
8305
+ const hydratedPath = resolve35(workspaceLayout.stateDir, "memory", "project-memory.db");
8218
8306
  try {
8219
- await mkdir3(resolve34(workspaceLayout.stateDir, "memory"), { recursive: true });
8307
+ await mkdir3(resolve35(workspaceLayout.stateDir, "memory"), { recursive: true });
8220
8308
  await copyFile(snapshot.dbPath, hydratedPath);
8221
8309
  return {
8222
8310
  canonicalPath: CANONICAL_MEMORY_DB_PATH2,
@@ -8231,12 +8319,12 @@ async function hydrateRuntimeMemory(options) {
8231
8319
  }
8232
8320
  }
8233
8321
  async function createRuntimeTaskRecordReader(options) {
8234
- const legacyConfigPath = resolve34(options.projectRoot, ".rig", "task-config.json");
8322
+ const legacyConfigPath = resolve35(options.projectRoot, ".rig", "task-config.json");
8235
8323
  let pluginHostContext = null;
8236
8324
  try {
8237
8325
  pluginHostContext = await buildPluginHostContext(options.projectRoot);
8238
8326
  } catch (error) {
8239
- if (!existsSync32(legacyConfigPath)) {
8327
+ if (!existsSync33(legacyConfigPath)) {
8240
8328
  throw error;
8241
8329
  }
8242
8330
  const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
@@ -8256,7 +8344,7 @@ async function createRuntimeTaskRecordReader(options) {
8256
8344
  source: "plugin"
8257
8345
  };
8258
8346
  }
8259
- if (existsSync32(legacyConfigPath)) {
8347
+ if (existsSync33(legacyConfigPath)) {
8260
8348
  const message = "Using source-aware .rig/task-config.json task source compatibility path";
8261
8349
  options.diagnostics?.(message);
8262
8350
  console.warn(message);
@@ -8273,10 +8361,10 @@ async function createRuntimeTaskRecordReader(options) {
8273
8361
  };
8274
8362
  }
8275
8363
  function readConfiguredTaskSourceKindHint(projectRoot) {
8276
- const jsonPath = resolve34(projectRoot, "rig.config.json");
8277
- if (existsSync32(jsonPath)) {
8364
+ const jsonPath = resolve35(projectRoot, "rig.config.json");
8365
+ if (existsSync33(jsonPath)) {
8278
8366
  try {
8279
- const parsed = JSON.parse(readFileSync15(jsonPath, "utf8"));
8367
+ const parsed = JSON.parse(readFileSync16(jsonPath, "utf8"));
8280
8368
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
8281
8369
  const taskSource = parsed.taskSource;
8282
8370
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -8288,12 +8376,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
8288
8376
  return null;
8289
8377
  }
8290
8378
  }
8291
- const tsPath = resolve34(projectRoot, "rig.config.ts");
8292
- if (!existsSync32(tsPath)) {
8379
+ const tsPath = resolve35(projectRoot, "rig.config.ts");
8380
+ if (!existsSync33(tsPath)) {
8293
8381
  return null;
8294
8382
  }
8295
8383
  try {
8296
- const source = readFileSync15(tsPath, "utf8");
8384
+ const source = readFileSync16(tsPath, "utf8");
8297
8385
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
8298
8386
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
8299
8387
  return kind ?? null;
@@ -8363,8 +8451,8 @@ async function writeRuntimeTaskConfigProjection(options) {
8363
8451
  ...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
8364
8452
  ...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
8365
8453
  };
8366
- const configPath = resolve34(options.workspaceDir, ".rig", "task-config.json");
8367
- await mkdir3(resolve34(options.workspaceDir, ".rig"), { recursive: true });
8454
+ const configPath = resolve35(options.workspaceDir, ".rig", "task-config.json");
8455
+ await mkdir3(resolve35(options.workspaceDir, ".rig"), { recursive: true });
8368
8456
  await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
8369
8457
  `, "utf-8");
8370
8458
  }
@@ -8428,9 +8516,9 @@ async function ensureAgentRuntime(options) {
8428
8516
  }
8429
8517
  ensureProvisioningHostProjectRootEnv(options.projectRoot);
8430
8518
  const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
8431
- const workspaceDir = resolve34(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
8519
+ const workspaceDir = resolve35(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
8432
8520
  const createdAt = new Date().toISOString();
8433
- if (!existsSync32(resolve34(monorepoRoot, ".git"))) {
8521
+ if (!existsSync33(resolve35(monorepoRoot, ".git"))) {
8434
8522
  throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
8435
8523
  }
8436
8524
  const taskResolution = await resolveRuntimeTaskRecord({
@@ -8465,7 +8553,7 @@ async function ensureAgentRuntime(options) {
8465
8553
  logsDir: overlay.logsDir,
8466
8554
  stateDir: overlay.stateDir,
8467
8555
  sessionDir: overlay.sessionDir,
8468
- claudeHomeDir: resolve34(workspaceLayout.homeDir, ".claude"),
8556
+ claudeHomeDir: resolve35(workspaceLayout.homeDir, ".claude"),
8469
8557
  contextFile: overlay.contextPath,
8470
8558
  binDir: workspaceLayout.binDir,
8471
8559
  createdAt
@@ -8478,10 +8566,14 @@ async function ensureAgentRuntime(options) {
8478
8566
  projectRoot: options.projectRoot,
8479
8567
  workspaceDir
8480
8568
  });
8481
- mkdirSync18(runtime.binDir, { recursive: true });
8482
- mkdirSync18(workspaceLayout.distDir, { recursive: true });
8569
+ mkdirSync19(runtime.binDir, { recursive: true });
8570
+ mkdirSync19(workspaceLayout.distDir, { recursive: true });
8483
8571
  prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
8484
- await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8572
+ if (options.preserveTaskArtifacts) {
8573
+ console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
8574
+ } else {
8575
+ await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8576
+ }
8485
8577
  const ctx = {
8486
8578
  runtimeId: options.id,
8487
8579
  taskId: options.taskId,
@@ -8494,7 +8586,7 @@ async function ensureAgentRuntime(options) {
8494
8586
  runtimeId: options.id
8495
8587
  }),
8496
8588
  workspaceDir,
8497
- artifactRoot: resolve34(workspaceDir, "artifacts", options.taskId),
8589
+ artifactRoot: resolve35(workspaceDir, "artifacts", options.taskId),
8498
8590
  hostProjectRoot: options.projectRoot,
8499
8591
  monorepoMainRoot: monorepoRoot,
8500
8592
  monorepoBaseRef: baseRef,
@@ -8510,8 +8602,8 @@ async function ensureAgentRuntime(options) {
8510
8602
  stateDir: overlay.stateDir,
8511
8603
  logsDir: overlay.logsDir,
8512
8604
  sessionDir: overlay.sessionDir,
8513
- sessionFile: resolve34(overlay.sessionDir, "session.json"),
8514
- policyFile: resolve34(options.projectRoot, "rig/policy/policy.json"),
8605
+ sessionFile: resolve35(overlay.sessionDir, "session.json"),
8606
+ policyFile: resolve35(options.projectRoot, "rig/policy/policy.json"),
8515
8607
  binDir: runtime.binDir,
8516
8608
  createdAt,
8517
8609
  memory
@@ -8522,9 +8614,9 @@ async function ensureAgentRuntime(options) {
8522
8614
  task: taskResolution.task,
8523
8615
  taskEntry
8524
8616
  });
8525
- const manifestPath = resolve34(runtimeRoot, "manifest.json");
8617
+ const manifestPath = resolve35(runtimeRoot, "manifest.json");
8526
8618
  const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
8527
- const runtimeAgentBinary = resolve34(runtime.binDir, "rig-agent");
8619
+ const runtimeAgentBinary = resolve35(runtime.binDir, "rig-agent");
8528
8620
  await ensureRigGitBinaryPath();
8529
8621
  const bakedInfoOutput = await captureTaskInfoOutput({
8530
8622
  projectRoot: options.projectRoot,
@@ -8539,10 +8631,10 @@ async function ensureAgentRuntime(options) {
8539
8631
  const bakedStatusOutput = await captureStdout(async () => {
8540
8632
  taskStatus(options.projectRoot);
8541
8633
  });
8542
- rmSync12(runtime.binDir, { recursive: true, force: true });
8543
- rmSync12(workspaceLayout.distDir, { recursive: true, force: true });
8544
- mkdirSync18(runtime.binDir, { recursive: true });
8545
- mkdirSync18(workspaceLayout.distDir, { recursive: true });
8634
+ rmSync13(runtime.binDir, { recursive: true, force: true });
8635
+ rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
8636
+ mkdirSync19(runtime.binDir, { recursive: true });
8637
+ mkdirSync19(workspaceLayout.distDir, { recursive: true });
8546
8638
  await buildRuntimeToolchain({
8547
8639
  projectRoot: options.projectRoot,
8548
8640
  workspaceDir,
@@ -8579,9 +8671,9 @@ async function ensureAgentRuntime(options) {
8579
8671
  workspaceDir,
8580
8672
  taskEntry
8581
8673
  });
8582
- const sandboxDir = resolve34(runtimeRoot, "sandbox");
8674
+ const sandboxDir = resolve35(runtimeRoot, "sandbox");
8583
8675
  await mkdir3(sandboxDir, { recursive: true });
8584
- await writeFile2(resolve34(runtimeRoot, "runtime.json"), JSON.stringify({
8676
+ await writeFile2(resolve35(runtimeRoot, "runtime.json"), JSON.stringify({
8585
8677
  id: options.id,
8586
8678
  taskId: options.taskId,
8587
8679
  mode: "worktree",
@@ -8688,8 +8780,8 @@ async function runCodexAppServerTaskRun(options) {
8688
8780
  const sendRequest = async (method, params) => {
8689
8781
  const id = nextRequestId;
8690
8782
  nextRequestId += 1;
8691
- const resultPromise = new Promise((resolve35, reject) => {
8692
- pendingResponses.set(id, { resolve: resolve35, reject });
8783
+ const resultPromise = new Promise((resolve36, reject) => {
8784
+ pendingResponses.set(id, { resolve: resolve36, reject });
8693
8785
  });
8694
8786
  await sendMessage({ id, method, params });
8695
8787
  return resultPromise;
@@ -8888,8 +8980,8 @@ async function runCodexAppServerTaskRun(options) {
8888
8980
  console.error(line);
8889
8981
  }
8890
8982
  });
8891
- const exitPromise = new Promise((resolve35) => {
8892
- child.once("close", (code, signal) => resolve35({ code, signal }));
8983
+ const exitPromise = new Promise((resolve36) => {
8984
+ child.once("close", (code, signal) => resolve36({ code, signal }));
8893
8985
  });
8894
8986
  await sendRequest("initialize", {
8895
8987
  clientInfo: DEFAULT_CLIENT_INFO,
@@ -8930,7 +9022,7 @@ async function runCodexAppServerTaskRun(options) {
8930
9022
  while (!completionState.current) {
8931
9023
  exitResult = await Promise.race([
8932
9024
  exitPromise,
8933
- new Promise((resolve35) => setTimeout(() => resolve35(null), 100))
9025
+ new Promise((resolve36) => setTimeout(() => resolve36(null), 100))
8934
9026
  ]);
8935
9027
  if (exitResult) {
8936
9028
  break;
@@ -9079,13 +9171,13 @@ function sanitizeEnv(env) {
9079
9171
  return next;
9080
9172
  }
9081
9173
  function writeChildLine(child, line) {
9082
- return new Promise((resolve35, reject) => {
9174
+ return new Promise((resolve36, reject) => {
9083
9175
  child.stdin.write(line, (error) => {
9084
9176
  if (error) {
9085
9177
  reject(error);
9086
9178
  return;
9087
9179
  }
9088
- resolve35();
9180
+ resolve36();
9089
9181
  });
9090
9182
  });
9091
9183
  }
@@ -9131,7 +9223,175 @@ function formatJsonRpcError(error) {
9131
9223
  return parts.join(" ");
9132
9224
  }
9133
9225
 
9226
+ // packages/runtime/src/control-plane/pi-sessiond/launcher.ts
9227
+ import { randomBytes } from "crypto";
9228
+ import { existsSync as existsSync34, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync14 } from "fs";
9229
+ import { dirname as dirname14, resolve as resolve36 } from "path";
9230
+ import { fileURLToPath as fileURLToPath2 } from "url";
9231
+
9232
+ // packages/runtime/src/control-plane/pi-sessiond/client.ts
9233
+ class RigPiSessionDaemonClient {
9234
+ baseUrl;
9235
+ token;
9236
+ constructor(options) {
9237
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
9238
+ this.token = options.token;
9239
+ }
9240
+ static fromConnection(connection, token) {
9241
+ if (connection.mode === "http")
9242
+ return new RigPiSessionDaemonClient({ baseUrl: connection.baseUrl, token });
9243
+ throw new Error("Unix-socket Rig Pi daemon connections are not implemented in this build; use loopback HTTP.");
9244
+ }
9245
+ async request(method, path, body) {
9246
+ const response = await fetch(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`, {
9247
+ method,
9248
+ headers: {
9249
+ authorization: `Bearer ${this.token}`,
9250
+ ...body === undefined ? {} : { "content-type": "application/json" }
9251
+ },
9252
+ body: body === undefined ? undefined : JSON.stringify(body)
9253
+ });
9254
+ const text = await response.text();
9255
+ const payload = text.trim() ? JSON.parse(text) : undefined;
9256
+ if (!response.ok) {
9257
+ const message = payload && typeof payload === "object" && !Array.isArray(payload) && typeof payload.error === "string" ? payload.error : text || response.statusText;
9258
+ throw new Error(`Rig Pi session daemon request failed (${response.status}): ${message}`);
9259
+ }
9260
+ return payload;
9261
+ }
9262
+ webSocketUrl(path) {
9263
+ const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`);
9264
+ url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
9265
+ url.searchParams.set("token", this.token);
9266
+ return url.toString();
9267
+ }
9268
+ }
9269
+
9270
+ // packages/runtime/src/control-plane/pi-sessiond/launcher.ts
9271
+ var BUILD_CONFIG2 = {};
9272
+ var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
9273
+ async function ensureRigPiSessionDaemon(input) {
9274
+ const rootDir = resolve36(input.rootDir);
9275
+ mkdirSync20(rootDir, { recursive: true });
9276
+ const readyFile = resolve36(rootDir, "ready.json");
9277
+ const existing = readDaemonReadyFile(readyFile);
9278
+ const existingHandle = existing ? await tryReady(existing) : null;
9279
+ if (existingHandle)
9280
+ return existingHandle;
9281
+ try {
9282
+ rmSync14(readyFile, { force: true });
9283
+ } catch {}
9284
+ const token = randomBytes(32).toString("hex");
9285
+ const binPath = resolveRigPiSessionDaemonBinPath(input.env);
9286
+ const bunPath = input.env.RIG_BUN_PATH || process.execPath;
9287
+ const proc = Bun.spawn([bunPath, binPath], {
9288
+ cwd: rootDir,
9289
+ env: {
9290
+ ...input.env,
9291
+ RIG_PI_SESSIOND_ROOT: rootDir,
9292
+ RIG_PI_SESSIOND_TOKEN: token,
9293
+ RIG_PI_SESSIOND_READY_FILE: readyFile,
9294
+ RIG_PI_SESSIOND_HOST: "127.0.0.1",
9295
+ RIG_PI_SESSIOND_PORT: "0",
9296
+ ...input.version ? { RIG_VERSION: input.version } : {},
9297
+ ...input.commit ? { RIG_GIT_COMMIT: input.commit } : {}
9298
+ },
9299
+ stdin: "ignore",
9300
+ stdout: "ignore",
9301
+ stderr: "inherit"
9302
+ });
9303
+ proc.unref();
9304
+ const deadline = Date.now() + (input.timeoutMs ?? 15000);
9305
+ while (Date.now() < deadline) {
9306
+ const ready = readDaemonReadyFile(readyFile);
9307
+ const handle = ready ? await tryReady(ready) : null;
9308
+ if (handle)
9309
+ return handle;
9310
+ await sleep(100);
9311
+ }
9312
+ throw new Error([
9313
+ `Rig Pi session daemon did not become ready at ${readyFile}.`,
9314
+ "Usual causes: the bundled Pi runtime is missing or broken. Run `rig doctor` to check Pi wiring,",
9315
+ "set RIG_PI_BINARY to a working Pi build, or run without Pi via RIG_RUNTIME_ADAPTER=claude-code."
9316
+ ].join(`
9317
+ `));
9318
+ }
9319
+ function privateMetadataForDaemon(input) {
9320
+ return { public: input.publicMetadata, daemonConnection: input.connection };
9321
+ }
9322
+ async function tryReady(ready) {
9323
+ const host = typeof ready.host === "string" ? ready.host : "127.0.0.1";
9324
+ const port = typeof ready.port === "number" ? ready.port : Number(ready.port);
9325
+ const token = typeof ready.token === "string" ? ready.token : "";
9326
+ if (!Number.isFinite(port) || port <= 0 || !token)
9327
+ return null;
9328
+ const baseUrl = `http://${host}:${port}`;
9329
+ const client = new RigPiSessionDaemonClient({ baseUrl, token });
9330
+ try {
9331
+ await client.request("GET", "/health");
9332
+ } catch {
9333
+ return null;
9334
+ }
9335
+ return {
9336
+ client,
9337
+ connection: { mode: "http", baseUrl, tokenRef: tokenRefFromReady(ready) },
9338
+ token,
9339
+ ready
9340
+ };
9341
+ }
9342
+ function tokenRefFromReady(ready) {
9343
+ const token = typeof ready.token === "string" ? ready.token : "";
9344
+ return token ? `inline:${token}` : "missing";
9345
+ }
9346
+ function resolveRigPiSessionDaemonBinPath(env) {
9347
+ const explicit = env.RIG_PI_SESSIOND_BIN?.trim();
9348
+ if (explicit)
9349
+ return explicit;
9350
+ const roots = [
9351
+ env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
9352
+ BAKED_RIG_SOURCE_ROOT.trim(),
9353
+ process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
9354
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
9355
+ process.env.PROJECT_RIG_ROOT?.trim()
9356
+ ].filter((value) => Boolean(value));
9357
+ for (const root of roots) {
9358
+ const candidate = resolve36(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
9359
+ if (existsSync34(candidate))
9360
+ return candidate;
9361
+ }
9362
+ const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
9363
+ if (existsSync34(moduleCandidate))
9364
+ return moduleCandidate;
9365
+ throw new Error([
9366
+ "Unable to locate rig-pi-sessiond entrypoint.",
9367
+ "Set RIG_PI_SESSIOND_BIN or RIG_CONTROL_PLANE_SOURCE_ROOT to the Rig source checkout,",
9368
+ "or run without the Pi daemon via RIG_RUNTIME_ADAPTER=claude-code."
9369
+ ].join(`
9370
+ `));
9371
+ }
9372
+ function readDaemonReadyFile(path) {
9373
+ if (!existsSync34(path))
9374
+ return null;
9375
+ try {
9376
+ const parsed = JSON.parse(readFileSync17(path, "utf8"));
9377
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
9378
+ } catch {
9379
+ return null;
9380
+ }
9381
+ }
9382
+ function sleep(ms) {
9383
+ return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
9384
+ }
9385
+ function resolveRigPiSessionDaemonRoot(stateDir) {
9386
+ const root = resolve36(stateDir, "pi-sessiond");
9387
+ mkdirSync20(dirname14(root), { recursive: true });
9388
+ if (!existsSync34(root))
9389
+ mkdirSync20(root, { recursive: true });
9390
+ return root;
9391
+ }
9392
+
9134
9393
  // packages/runtime/src/control-plane/agent-wrapper.ts
9394
+ var requireFromRuntime = createRequire(import.meta.url);
9135
9395
  async function finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, context) {
9136
9396
  try {
9137
9397
  await snapshotSidecar.finalize(providerCommand, exitCode);
@@ -9164,7 +9424,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
9164
9424
  }
9165
9425
  }
9166
9426
  async function runAgentWrapper(options = {}) {
9167
- const projectRoot = resolve35(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
9427
+ const projectRoot = resolve37(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
9168
9428
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
9169
9429
  const argv = options.argv || process.argv.slice(2);
9170
9430
  if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
@@ -9193,7 +9453,8 @@ async function runAgentWrapper(options = {}) {
9193
9453
  taskId,
9194
9454
  mode: "worktree",
9195
9455
  provider,
9196
- taskRecordReader: taskRecordReaderFromEnv(taskId)
9456
+ taskRecordReader: taskRecordReaderFromEnv(taskId),
9457
+ preserveTaskArtifacts: process.env.RIG_RUN_RESUME === "1" || process.env.RIG_RUNTIME_ARTIFACT_CLEANUP === "preserve"
9197
9458
  });
9198
9459
  emitWrapperEvent("runtime.provision.completed", {
9199
9460
  runtimeId: runtime.id,
@@ -9226,7 +9487,8 @@ async function runAgentWrapper(options = {}) {
9226
9487
  return 1;
9227
9488
  }
9228
9489
  const providerArgs = buildProviderArgs(provider, runtime, argv);
9229
- const providerCommand = [providerBinary(provider), ...providerArgs];
9490
+ const normalPiDaemonPath = provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1";
9491
+ const providerCommand = normalPiDaemonPath ? ["rig-pi-sessiond", ...providerArgs] : [providerBinary(provider), ...providerArgs];
9230
9492
  emitWrapperEvent("provider.launch", {
9231
9493
  provider,
9232
9494
  runtimeId: runtime.id,
@@ -9238,11 +9500,11 @@ async function runAgentWrapper(options = {}) {
9238
9500
  const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
9239
9501
  const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
9240
9502
  if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
9241
- env.CLAUDE_HOME = resolve35(process.env.HOME.trim(), ".claude");
9503
+ env.CLAUDE_HOME = resolve37(process.env.HOME.trim(), ".claude");
9242
9504
  env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
9243
9505
  }
9244
9506
  if (provider === "pi") {
9245
- env.PI_CODING_AGENT_DIR = resolve35(runtime.homeDir, ".pi", "agent");
9507
+ env.PI_CODING_AGENT_DIR = resolve37(runtime.homeDir, ".pi", "agent");
9246
9508
  env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
9247
9509
  }
9248
9510
  env.RIG_RUNTIME_SANDBOX = "enforce";
@@ -9276,14 +9538,36 @@ async function runAgentWrapper(options = {}) {
9276
9538
  },
9277
9539
  command: providerCommand
9278
9540
  })).command;
9279
- const proc = Bun.spawn(command, {
9280
- cwd: runtime.workspaceDir,
9281
- env,
9282
- stdin: "inherit",
9283
- stdout: "inherit",
9284
- stderr: "inherit"
9285
- });
9286
- exitCode = await proc.exited;
9541
+ if (provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1") {
9542
+ const prompt = await readProcessStdin();
9543
+ exitCode = await runPiSessionDaemonProvider({
9544
+ projectRoot,
9545
+ runtime,
9546
+ env,
9547
+ prompt,
9548
+ runId: process.env.RIG_SERVER_RUN_ID?.trim() || process.env.RIG_RUN_ID?.trim() || undefined,
9549
+ sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
9550
+ });
9551
+ } else if (provider === "pi" && isPiRpcArgs(providerArgs)) {
9552
+ const prompt = await readProcessStdin();
9553
+ exitCode = await runPiRpcProviderFallback({
9554
+ command,
9555
+ cwd: runtime.workspaceDir,
9556
+ env,
9557
+ prompt,
9558
+ runId: process.env.RIG_SERVER_RUN_ID?.trim() || undefined,
9559
+ sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
9560
+ });
9561
+ } else {
9562
+ const proc = Bun.spawn(command, {
9563
+ cwd: runtime.workspaceDir,
9564
+ env,
9565
+ stdin: "inherit",
9566
+ stdout: "inherit",
9567
+ stderr: "inherit"
9568
+ });
9569
+ exitCode = await proc.exited;
9570
+ }
9287
9571
  }
9288
9572
  if (snapshotSidecar) {
9289
9573
  await finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, {
@@ -9298,15 +9582,13 @@ async function runAgentWrapper(options = {}) {
9298
9582
  throw error;
9299
9583
  }
9300
9584
  const serverManagedRun = Boolean(process.env.RIG_SERVER_RUN_ID?.trim());
9301
- if (exitCode === 0 && serverManagedRun) {
9302
- await updateTaskSourceAfterRun(monorepoRoot, taskId, runtime);
9303
- }
9304
9585
  const taskClosed = await isTaskClosed(monorepoRoot, taskId);
9305
9586
  const finalExitCode = resolveFinalProviderExitCode({
9306
9587
  providerExitCode: exitCode,
9307
9588
  taskClosed,
9308
9589
  serverManagedRun
9309
9590
  });
9591
+ const handoffRequired = exitCode !== 0 || !taskClosed && !serverManagedRun;
9310
9592
  emitWrapperEvent("provider.completed", {
9311
9593
  provider,
9312
9594
  runtimeId: runtime.id,
@@ -9315,24 +9597,353 @@ async function runAgentWrapper(options = {}) {
9315
9597
  providerExitCode: exitCode,
9316
9598
  taskClosed,
9317
9599
  serverManagedRun,
9318
- handoffRequired: exitCode !== 0 || !taskClosed
9600
+ handoffRequired
9319
9601
  });
9320
- if (exitCode !== 0 || !taskClosed) {
9602
+ if (handoffRequired) {
9321
9603
  recordRuntimeHandoff(projectRoot, runtime, taskId, exitCode);
9322
9604
  }
9323
- if (exitCode === 0 && !taskClosed && serverManagedRun) {
9324
- console.error(`[rig-agent] Server-managed task run cannot finish successfully while ${taskId} is still open.`);
9325
- }
9326
9605
  return finalExitCode;
9327
9606
  }
9607
+ function parseJsonRecord(line) {
9608
+ try {
9609
+ const parsed = JSON.parse(line);
9610
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
9611
+ } catch {
9612
+ return null;
9613
+ }
9614
+ }
9615
+ async function readProcessStdin() {
9616
+ if (process.stdin.isTTY)
9617
+ return "";
9618
+ return await new Promise((resolveRead) => {
9619
+ let data = "";
9620
+ process.stdin.setEncoding("utf8");
9621
+ process.stdin.on("data", (chunk) => {
9622
+ data += String(chunk);
9623
+ });
9624
+ process.stdin.on("end", () => resolveRead(data));
9625
+ process.stdin.resume();
9626
+ });
9627
+ }
9628
+ async function pumpReadableLines(stream, onLine) {
9629
+ if (!stream)
9630
+ return;
9631
+ const reader = stream.getReader();
9632
+ const decoder = new TextDecoder;
9633
+ let buffer = "";
9634
+ try {
9635
+ while (true) {
9636
+ const { done, value } = await reader.read();
9637
+ if (done)
9638
+ break;
9639
+ buffer += decoder.decode(value, { stream: true });
9640
+ const parts = buffer.split(/\r?\n/);
9641
+ buffer = parts.pop() ?? "";
9642
+ for (const part of parts)
9643
+ onLine(part);
9644
+ }
9645
+ buffer += decoder.decode();
9646
+ if (buffer)
9647
+ onLine(buffer);
9648
+ } finally {
9649
+ reader.releaseLock();
9650
+ }
9651
+ }
9652
+ function isBlockingPiRpcUiRequest(record) {
9653
+ if (record.type !== "extension_ui_request")
9654
+ return false;
9655
+ return record.method === "select" || record.method === "confirm" || record.method === "input" || record.method === "editor";
9656
+ }
9657
+ function writeRpcCommand(stdin, command) {
9658
+ stdin.write(`${JSON.stringify(command)}
9659
+ `);
9660
+ }
9661
+ function joinUrl(baseUrl, pathname) {
9662
+ return `${baseUrl.replace(/\/+$/, "")}${pathname.startsWith("/") ? pathname : `/${pathname}`}`;
9663
+ }
9664
+ async function readQueuedSteeringFromServer(input) {
9665
+ if (!input.serverUrl || !input.runId)
9666
+ return [];
9667
+ const headers = {};
9668
+ if (input.authToken)
9669
+ headers.authorization = `Bearer ${input.authToken}`;
9670
+ const response = await fetch(joinUrl(input.serverUrl, `/api/runs/${encodeURIComponent(input.runId)}/steering?ack=1`), { headers });
9671
+ if (!response.ok)
9672
+ return [];
9673
+ const payload = await response.json().catch(() => null);
9674
+ const messages = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.messages : null;
9675
+ return Array.isArray(messages) ? messages.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
9676
+ }
9677
+ function steeringMessageText(entry) {
9678
+ const message = typeof entry.message === "string" ? entry.message.trim() : "";
9679
+ return message || null;
9680
+ }
9681
+ function isPiRpcArgs(args) {
9682
+ return cliOptionValue(args, "--mode") === "rpc";
9683
+ }
9684
+ async function runPiSessionDaemonProvider(input) {
9685
+ const stdout = input.stdout ?? process.stdout;
9686
+ const stderr = input.stderr ?? process.stderr;
9687
+ const runId = input.runId ?? input.runtime.taskId;
9688
+ emitWrapperEvent("pi.sessiond.starting", {
9689
+ runId,
9690
+ runtimeId: input.runtime.id,
9691
+ workspaceDir: input.runtime.workspaceDir
9692
+ });
9693
+ const daemon = await ensureRigPiSessionDaemon({
9694
+ rootDir: resolveRigPiSessionDaemonRoot(input.runtime.stateDir),
9695
+ env: input.env,
9696
+ version: process.env.RIG_VERSION?.trim() || "dev",
9697
+ commit: process.env.RIG_GIT_COMMIT?.trim() || undefined
9698
+ });
9699
+ emitWrapperEvent("pi.sessiond.ready", {
9700
+ runId,
9701
+ runtimeId: input.runtime.id,
9702
+ connection: daemon.connection,
9703
+ ready: daemon.ready
9704
+ });
9705
+ const start = await daemon.client.request("POST", "/sessions", {
9706
+ runId,
9707
+ cwd: input.runtime.workspaceDir,
9708
+ agentDir: input.env.PI_CODING_AGENT_DIR || resolve37(input.runtime.homeDir, ".pi", "agent"),
9709
+ sessionDir: input.runtime.sessionDir,
9710
+ sessionName: input.sessionName
9711
+ });
9712
+ const privateMetadata = privateMetadataForDaemon({ publicMetadata: start.metadata, connection: daemon.connection });
9713
+ emitWrapperEvent("pi.session.ready", {
9714
+ runId,
9715
+ runtimeId: input.runtime.id,
9716
+ metadata: start.metadata,
9717
+ privateMetadata
9718
+ });
9719
+ const eventStream = waitForPiSessionEvents({
9720
+ url: daemon.client.webSocketUrl(`/sessions/${encodeURIComponent(start.metadata.sessionId)}/events`),
9721
+ stdout,
9722
+ stderr,
9723
+ runId
9724
+ });
9725
+ emitWrapperEvent("pi.session.event_stream.connected", { runId, sessionId: start.metadata.sessionId });
9726
+ const forwardSigterm = () => {
9727
+ daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/abort`).catch(() => {
9728
+ return;
9729
+ });
9730
+ eventStream.close();
9731
+ };
9732
+ process.once("SIGTERM", forwardSigterm);
9733
+ try {
9734
+ if (input.prompt.trim()) {
9735
+ await daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/prompt`, { text: input.prompt });
9736
+ emitWrapperEvent("pi.prompt.sent", { runId, sessionId: start.metadata.sessionId, bytes: Buffer.byteLength(input.prompt) });
9737
+ } else {
9738
+ emitWrapperEvent("pi.prompt.waiting", { runId, sessionId: start.metadata.sessionId, reason: "empty-initial-prompt" });
9739
+ }
9740
+ const result = await eventStream.done;
9741
+ if (result.error) {
9742
+ stderr.write(`[rig-agent] Pi session daemon stream failed: ${result.error}
9743
+ `);
9744
+ return 1;
9745
+ }
9746
+ return 0;
9747
+ } finally {
9748
+ process.off("SIGTERM", forwardSigterm);
9749
+ eventStream.close();
9750
+ }
9751
+ }
9752
+ function waitForPiSessionEvents(input) {
9753
+ let closed = false;
9754
+ let resolved = false;
9755
+ let socket = null;
9756
+ let resolveDone = () => {
9757
+ return;
9758
+ };
9759
+ const done = new Promise((resolveDoneInner) => {
9760
+ resolveDone = resolveDoneInner;
9761
+ });
9762
+ const finish = (value) => {
9763
+ if (resolved)
9764
+ return;
9765
+ resolved = true;
9766
+ resolveDone(value);
9767
+ };
9768
+ socket = new WebSocket(input.url);
9769
+ socket.addEventListener("message", (message) => {
9770
+ const text = typeof message.data === "string" ? message.data : Buffer.from(message.data).toString("utf8");
9771
+ input.stdout.write(`${text}
9772
+ `);
9773
+ const envelope = parseJsonRecord(text);
9774
+ if (!envelope)
9775
+ return;
9776
+ if (envelope.type === "pi.event") {
9777
+ const event = envelope.event && typeof envelope.event === "object" && !Array.isArray(envelope.event) ? envelope.event : null;
9778
+ if (event?.type === "agent_end") {
9779
+ emitWrapperEvent("pi.session.agent_end", { runId: input.runId, sessionId: envelope.sessionId });
9780
+ finish({});
9781
+ }
9782
+ }
9783
+ if (envelope.type === "error") {
9784
+ emitWrapperEvent("pi.session.error", { runId: input.runId, message: envelope.message, detail: envelope.detail ?? null });
9785
+ finish({ error: envelope.message });
9786
+ }
9787
+ });
9788
+ socket.addEventListener("error", () => {
9789
+ if (!closed)
9790
+ finish({ error: "WebSocket error" });
9791
+ });
9792
+ socket.addEventListener("close", () => {
9793
+ if (!closed && !resolved)
9794
+ finish({ error: "WebSocket closed before agent_end" });
9795
+ });
9796
+ return {
9797
+ done,
9798
+ close: () => {
9799
+ closed = true;
9800
+ try {
9801
+ socket?.close();
9802
+ } catch {}
9803
+ }
9804
+ };
9805
+ }
9806
+ async function runPiRpcProviderFallback(input) {
9807
+ const stdout = input.stdout ?? process.stdout;
9808
+ const stderr = input.stderr ?? process.stderr;
9809
+ const proc = Bun.spawn(input.command, {
9810
+ cwd: input.cwd,
9811
+ env: input.env,
9812
+ stdin: "pipe",
9813
+ stdout: "pipe",
9814
+ stderr: "pipe"
9815
+ });
9816
+ let sawAgentEnd = false;
9817
+ let promptError = null;
9818
+ let stdinOpen = true;
9819
+ let steeringPollStopped = false;
9820
+ const closeStdin = () => {
9821
+ if (!stdinOpen)
9822
+ return;
9823
+ stdinOpen = false;
9824
+ try {
9825
+ steeringPollStopped = true;
9826
+ proc.stdin.end();
9827
+ } catch {}
9828
+ };
9829
+ const send = (command) => {
9830
+ if (!stdinOpen)
9831
+ return;
9832
+ try {
9833
+ writeRpcCommand(proc.stdin, command);
9834
+ } catch (error) {
9835
+ promptError ??= error instanceof Error ? error.message : String(error);
9836
+ }
9837
+ };
9838
+ const forwardSigterm = () => {
9839
+ try {
9840
+ proc.kill("SIGTERM");
9841
+ } catch {}
9842
+ };
9843
+ process.once("SIGTERM", forwardSigterm);
9844
+ const pollSteering = async () => {
9845
+ const serverUrl = input.env.RIG_SERVER_URL || input.env.RIG_SERVER_BASE_URL;
9846
+ const authToken = input.env.RIG_AUTH_TOKEN || input.env.RIG_SERVER_AUTH_TOKEN;
9847
+ while (!steeringPollStopped && stdinOpen) {
9848
+ try {
9849
+ const messages = await readQueuedSteeringFromServer({ serverUrl, authToken, runId: input.runId });
9850
+ for (const message of messages) {
9851
+ const text = steeringMessageText(message);
9852
+ if (!text || !stdinOpen)
9853
+ continue;
9854
+ send({
9855
+ id: typeof message.id === "string" ? `rig_steer_${message.id}` : `rig_steer_${Date.now()}`,
9856
+ type: "prompt",
9857
+ message: text,
9858
+ streamingBehavior: "steer"
9859
+ });
9860
+ emitWrapperEvent("pi.rpc.steering.delivered", {
9861
+ runId: input.runId ?? null,
9862
+ steeringId: typeof message.id === "string" ? message.id : null,
9863
+ actor: typeof message.actor === "string" ? message.actor : "operator",
9864
+ message: text
9865
+ });
9866
+ }
9867
+ } catch (error) {
9868
+ emitWrapperEvent("pi.rpc.steering.poll.failed", {
9869
+ runId: input.runId ?? null,
9870
+ error: error instanceof Error ? error.message : String(error)
9871
+ });
9872
+ }
9873
+ await sleep2(1000);
9874
+ }
9875
+ };
9876
+ const stdoutPump = pumpReadableLines(proc.stdout, (line) => {
9877
+ stdout.write(`${line}
9878
+ `);
9879
+ const record = parseJsonRecord(line.trim());
9880
+ if (!record)
9881
+ return;
9882
+ if (record.type === "agent_end") {
9883
+ sawAgentEnd = true;
9884
+ closeStdin();
9885
+ return;
9886
+ }
9887
+ if (record.type === "response" && record.command === "prompt" && record.success === false) {
9888
+ promptError = typeof record.error === "string" ? record.error : "Pi RPC prompt failed.";
9889
+ closeStdin();
9890
+ return;
9891
+ }
9892
+ if (isBlockingPiRpcUiRequest(record)) {
9893
+ const id = typeof record.id === "string" ? record.id : "";
9894
+ if (id) {
9895
+ send({ type: "extension_ui_response", id, cancelled: true });
9896
+ emitWrapperEvent("pi.rpc.extension_ui.cancelled", {
9897
+ id,
9898
+ method: record.method,
9899
+ reason: "noninteractive Rig worker RPC session"
9900
+ });
9901
+ }
9902
+ }
9903
+ });
9904
+ const stderrPump = pumpReadableLines(proc.stderr, (line) => {
9905
+ stderr.write(`${line}
9906
+ `);
9907
+ });
9908
+ if (input.sessionName?.trim()) {
9909
+ send({ id: "rig_set_session_name", type: "set_session_name", name: input.sessionName.trim() });
9910
+ }
9911
+ const steeringPollPromise = pollSteering();
9912
+ if (input.prompt.trim()) {
9913
+ send({ id: "rig_initial_prompt", type: "prompt", message: input.prompt });
9914
+ emitWrapperEvent("pi.rpc.prompt.sent", {
9915
+ runId: input.runId ?? null,
9916
+ kind: "initial",
9917
+ bytes: Buffer.byteLength(input.prompt)
9918
+ });
9919
+ } else {
9920
+ closeStdin();
9921
+ }
9922
+ const exitCode = await proc.exited;
9923
+ process.off("SIGTERM", forwardSigterm);
9924
+ steeringPollStopped = true;
9925
+ await Promise.all([stdoutPump, stderrPump, steeringPollPromise]);
9926
+ if (promptError) {
9927
+ stderr.write(`[rig-agent] Pi RPC prompt failed: ${promptError}
9928
+ `);
9929
+ return exitCode === 0 ? 1 : exitCode;
9930
+ }
9931
+ if (input.prompt.trim() && !sawAgentEnd && exitCode === 0) {
9932
+ stderr.write(`[rig-agent] Pi RPC exited before emitting agent_end.
9933
+ `);
9934
+ return 1;
9935
+ }
9936
+ return exitCode;
9937
+ }
9938
+ var runPiRpcProvider = runPiRpcProviderFallback;
9328
9939
  function resolveFinalProviderExitCode(input) {
9329
9940
  if (input.providerExitCode !== 0) {
9330
9941
  return input.providerExitCode;
9331
9942
  }
9332
- if (input.taskClosed) {
9943
+ if (input.taskClosed || input.serverManagedRun) {
9333
9944
  return 0;
9334
9945
  }
9335
- return input.serverManagedRun ? 2 : 0;
9946
+ return 0;
9336
9947
  }
9337
9948
  function shouldBypassProviderSandboxOnPlatform(provider, platform) {
9338
9949
  if (platform !== "darwin") {
@@ -9356,14 +9967,27 @@ function buildProviderArgs(provider, runtime, argv) {
9356
9967
  }
9357
9968
  if (provider === "pi") {
9358
9969
  const piArgs = [...argv];
9970
+ if (piArgs.includes("__rig_pi_session_daemon__")) {
9971
+ return piArgs.filter((arg) => arg !== "__rig_pi_session_daemon__");
9972
+ }
9973
+ const piProvider = cliOptionValue(piArgs, "--provider") || process.env.RIG_PI_PROVIDER?.trim() || "openai-codex";
9359
9974
  if (!hasCliOption(piArgs, "--provider")) {
9360
- piArgs.unshift(process.env.RIG_PI_PROVIDER?.trim() || "openai-codex");
9975
+ piArgs.unshift(piProvider);
9361
9976
  piArgs.unshift("--provider");
9362
9977
  }
9363
- if (!hasCliOption(piArgs, "--model")) {
9364
- piArgs.unshift(process.env.RIG_PI_MODEL?.trim() || "gpt-5.5");
9978
+ const model = cliOptionValue(piArgs, "--model") || process.env.RIG_PI_MODEL?.trim() || "gpt-5.5";
9979
+ if (hasCliOption(piArgs, "--model")) {
9980
+ rewriteCliOptionValue(piArgs, "--model", normalizePiModelForProvider(model, piProvider));
9981
+ } else {
9982
+ piArgs.unshift(normalizePiModelForProvider(model, piProvider));
9365
9983
  piArgs.unshift("--model");
9366
9984
  }
9985
+ if (!hasCliOption(piArgs, "--mode")) {
9986
+ piArgs.push("--mode", process.env.RIG_PI_TRANSPORT?.trim() === "print" ? "json" : "rpc");
9987
+ if (process.env.RIG_PI_TRANSPORT?.trim() === "print" && !hasCliOption(piArgs, "--print")) {
9988
+ piArgs.push("--print");
9989
+ }
9990
+ }
9367
9991
  return piArgs;
9368
9992
  }
9369
9993
  return [
@@ -9413,6 +10037,7 @@ async function runBeadsJson(projectRoot, args) {
9413
10037
  return null;
9414
10038
  }
9415
10039
  }
10040
+ var warnedUnknownRuntimeAdapter = false;
9416
10041
  function resolveProvider() {
9417
10042
  const value = process.env.RIG_RUNTIME_ADAPTER?.trim().toLowerCase();
9418
10043
  if (!value) {
@@ -9424,28 +10049,85 @@ function resolveProvider() {
9424
10049
  if (value === "pi" || value === "rig-pi" || value === "@rig/pi") {
9425
10050
  return "pi";
9426
10051
  }
10052
+ if (value !== "claude-code" && value !== "claude" && !warnedUnknownRuntimeAdapter) {
10053
+ warnedUnknownRuntimeAdapter = true;
10054
+ console.warn(`[rig-agent] Unknown RIG_RUNTIME_ADAPTER value "${value}"; falling back to claude-code. Use pi|claude-code|codex.`);
10055
+ }
9427
10056
  return "claude-code";
9428
10057
  }
9429
10058
  function hasCliOption(argv, option) {
9430
10059
  return argv.some((arg) => arg === option || arg.startsWith(`${option}=`));
9431
10060
  }
10061
+ function cliOptionValue(argv, option) {
10062
+ for (let index = 0;index < argv.length; index += 1) {
10063
+ const arg = argv[index];
10064
+ if (arg === option) {
10065
+ const next = argv[index + 1];
10066
+ return next && !next.startsWith("--") ? next : undefined;
10067
+ }
10068
+ if (arg?.startsWith(`${option}=`)) {
10069
+ return arg.slice(option.length + 1);
10070
+ }
10071
+ }
10072
+ return;
10073
+ }
10074
+ function rewriteCliOptionValue(argv, option, value) {
10075
+ for (let index = 0;index < argv.length; index += 1) {
10076
+ const arg = argv[index];
10077
+ if (arg === option && argv[index + 1] && !argv[index + 1].startsWith("--")) {
10078
+ argv[index + 1] = value;
10079
+ return;
10080
+ }
10081
+ if (arg?.startsWith(`${option}=`)) {
10082
+ argv[index] = `${option}=${value}`;
10083
+ return;
10084
+ }
10085
+ }
10086
+ }
10087
+ function normalizePiModelForProvider(model, provider) {
10088
+ if (provider === "openrouter" && model === "openai-codex/gpt-5.5") {
10089
+ return "openai/gpt-5.5";
10090
+ }
10091
+ return model;
10092
+ }
10093
+ function resolveFromShellPath(binary) {
10094
+ const resolved = Bun.spawnSync(["sh", "-lc", `command -v ${binary}`], {
10095
+ stdout: "pipe",
10096
+ stderr: "ignore",
10097
+ stdin: "ignore",
10098
+ env: process.env
10099
+ });
10100
+ if (resolved.exitCode !== 0)
10101
+ return null;
10102
+ const path = resolved.stdout.toString().trim().split(/\r?\n/)[0]?.trim();
10103
+ return path || null;
10104
+ }
10105
+ function resolveBundledPiBinary() {
10106
+ try {
10107
+ const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
10108
+ const binaryPath = resolve37(packageJson, "..", "dist", "cli.js");
10109
+ return existsSync35(binaryPath) ? binaryPath : null;
10110
+ } catch {
10111
+ return null;
10112
+ }
10113
+ }
9432
10114
  function providerBinary(provider) {
9433
10115
  if (provider === "codex") {
9434
- return Bun.which("codex") || "codex";
10116
+ return resolveFromShellPath("codex") || Bun.which("codex") || "codex";
9435
10117
  }
9436
10118
  if (provider === "pi") {
9437
- return Bun.which("pi") || "pi";
10119
+ return process.env.RIG_PI_BINARY?.trim() || resolveBundledPiBinary() || resolveFromShellPath("pi") || Bun.which("pi") || "pi";
9438
10120
  }
9439
10121
  try {
9440
10122
  return resolveClaudeBinaryPath();
9441
10123
  } catch {
9442
- return Bun.which("claude") || "claude";
10124
+ return resolveFromShellPath("claude") || Bun.which("claude") || "claude";
9443
10125
  }
9444
10126
  }
9445
10127
  function emitWrapperEvent(type, payload) {
9446
10128
  console.log(`__RIG_WRAPPER_EVENT__${JSON.stringify({ type, payload, at: new Date().toISOString() })}`);
9447
10129
  }
9448
- function sleep(ms) {
10130
+ function sleep2(ms) {
9449
10131
  return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
9450
10132
  }
9451
10133
  async function waitForDirtyBaselineReady(runtime, taskId) {
@@ -9460,11 +10142,11 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
9460
10142
  workspaceDir: runtime.workspaceDir,
9461
10143
  readyFile
9462
10144
  });
9463
- while (!existsSync33(readyFile)) {
10145
+ while (!existsSync35(readyFile)) {
9464
10146
  if (Date.now() >= deadline) {
9465
10147
  throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
9466
10148
  }
9467
- await sleep(50);
10149
+ await sleep2(50);
9468
10150
  }
9469
10151
  emitWrapperEvent("runtime.baseline.completed", {
9470
10152
  runtimeId: runtime.id,
@@ -9530,8 +10212,8 @@ async function readPluginTaskStatus(projectRoot, taskId) {
9530
10212
  async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
9531
10213
  const comment = buildTaskRunLifecycleComment({
9532
10214
  runId: process.env.RIG_SERVER_RUN_ID || "(unknown)",
9533
- status: "closed",
9534
- summary: "Rig task run completed and closed this task.",
10215
+ status: "completed",
10216
+ summary: "Rig task run completed; source closeout waits for approved PR merge.",
9535
10217
  runtimeWorkspace: runtime.workspaceDir,
9536
10218
  logsDir: runtime.logsDir,
9537
10219
  sessionDir: runtime.sessionDir
@@ -9539,7 +10221,7 @@ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
9539
10221
  try {
9540
10222
  const result = await updateConfiguredTaskSourceTask(projectRoot, {
9541
10223
  taskId,
9542
- update: { status: "closed", comment }
10224
+ update: { status: "completed", comment }
9543
10225
  });
9544
10226
  if (result.updated) {
9545
10227
  return;
@@ -9548,7 +10230,9 @@ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
9548
10230
  } catch (error) {
9549
10231
  let fallbackUpdated = false;
9550
10232
  try {
9551
- fallbackUpdated = updateSourceAwareTaskConfigTask(projectRoot, taskId, { status: "closed", comment });
10233
+ const sourceIssueId = loadRuntimeContextFromEnv()?.sourceTask?.sourceIssueId;
10234
+ fallbackUpdated = updateGithubIssueTaskBySourceIssueId(sourceIssueId, taskId, { status: "completed", comment });
10235
+ fallbackUpdated = updateSourceAwareTaskConfigTask(projectRoot, taskId, { status: "completed", comment }) || fallbackUpdated;
9552
10236
  } catch (fallbackError) {
9553
10237
  console.error(`[rig-agent] Source-aware compatibility update also failed for ${taskId}: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
9554
10238
  }
@@ -9561,9 +10245,9 @@ async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
9561
10245
  }
9562
10246
  }
9563
10247
  function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
9564
- const handoffDir = resolve35(hostProjectRoot, ".rig/runtime/handoffs");
9565
- mkdirSync19(handoffDir, { recursive: true });
9566
- const handoffPath = resolve35(handoffDir, `${taskId}-${Date.now()}.json`);
10248
+ const handoffDir = resolve37(hostProjectRoot, ".rig/runtime/handoffs");
10249
+ mkdirSync21(handoffDir, { recursive: true });
10250
+ const handoffPath = resolve37(handoffDir, `${taskId}-${Date.now()}.json`);
9567
10251
  const handoff = {
9568
10252
  taskId,
9569
10253
  runtimeId: runtime.id,
@@ -9579,7 +10263,7 @@ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
9579
10263
  `rig git open-pr --task ${taskId}`
9580
10264
  ]
9581
10265
  };
9582
- writeFileSync13(handoffPath, `${JSON.stringify(handoff, null, 2)}
10266
+ writeFileSync14(handoffPath, `${JSON.stringify(handoff, null, 2)}
9583
10267
  `, "utf-8");
9584
10268
  console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
9585
10269
  console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
@@ -9629,13 +10313,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
9629
10313
  async function readTaskConfigHints(taskRoot, taskId) {
9630
10314
  const runtimeContext = loadRuntimeContextFromEnv();
9631
10315
  const candidates = [
9632
- runtimeContext?.monorepoMainRoot ? resolve35(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
9633
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve35(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
9634
- resolve35(taskRoot, ".rig", "task-config.json"),
9635
- resolve35(taskRoot, "rig", "task-config.json")
10316
+ runtimeContext?.monorepoMainRoot ? resolve37(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
10317
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve37(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
10318
+ resolve37(taskRoot, ".rig", "task-config.json"),
10319
+ resolve37(taskRoot, "rig", "task-config.json")
9636
10320
  ].filter(Boolean);
9637
10321
  for (const configPath of candidates) {
9638
- if (!existsSync33(configPath)) {
10322
+ if (!existsSync35(configPath)) {
9639
10323
  continue;
9640
10324
  }
9641
10325
  try {
@@ -9672,6 +10356,9 @@ export {
9672
10356
  updateTaskSourceAfterRun,
9673
10357
  startOptionalRuntimeSnapshotSidecar,
9674
10358
  shouldBypassProviderSandboxOnPlatform,
10359
+ runPiSessionDaemonProvider,
10360
+ runPiRpcProviderFallback,
10361
+ runPiRpcProvider,
9675
10362
  runAgentWrapper,
9676
10363
  resolveTaskFromBeads,
9677
10364
  resolveFinalProviderExitCode,