@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,34 +3006,6 @@ async function readSourceAwareTaskStatus(projectRoot, taskId, options = {}) {
2951
3006
  return null;
2952
3007
  }
2953
3008
  }
2954
- function updateSourceAwareTaskConfigTask(projectRoot, taskId, update, options = {}) {
2955
- const configPath = options.configPath ?? resolve13(projectRoot, ".rig", "task-config.json");
2956
- const rawEntry = readRawTaskEntry(configPath, taskId);
2957
- if (!rawEntry) {
2958
- const configuredFilesPath = readConfiguredFilesTaskSourcePath(projectRoot);
2959
- return configuredFilesPath ? updateFileBackedTask(projectRoot, configuredFilesPath, taskId, update) : false;
2960
- }
2961
- const metadata = readMaterializedTaskMetadata(rawEntry);
2962
- const source = metadata.taskSource;
2963
- if (source?.kind === "github-issues") {
2964
- applyGithubIssueUpdate(options.ghBinary ?? "gh", options.spawn ?? spawnSync, taskId, metadata, update);
2965
- return true;
2966
- }
2967
- if (source?.kind === "files" && source.path) {
2968
- return updateFileBackedTask(projectRoot, source.path, taskId, update);
2969
- }
2970
- if (source?.kind && source.kind !== "files" && source.kind !== "legacy-task-config") {
2971
- return false;
2972
- }
2973
- if (!source && options.allowLocalTaskConfigStatusFallback === false) {
2974
- return false;
2975
- }
2976
- if (typeof update.status !== "string" || update.status.trim().length === 0) {
2977
- return false;
2978
- }
2979
- writeLegacyTaskStatus(configPath, taskId, update.status);
2980
- return true;
2981
- }
2982
3009
  function readMaterializedTaskMetadata(entry) {
2983
3010
  const rawRig = entry._rig;
2984
3011
  if (!isPlainRecord2(rawRig)) {
@@ -3005,10 +3032,10 @@ function readMaterializedTaskMetadata(entry) {
3005
3032
  return metadata;
3006
3033
  }
3007
3034
  function readConfiguredFilesTaskSourcePath(projectRoot) {
3008
- const jsonPath = resolve13(projectRoot, "rig.config.json");
3009
- if (existsSync13(jsonPath)) {
3035
+ const jsonPath = resolve14(projectRoot, "rig.config.json");
3036
+ if (existsSync14(jsonPath)) {
3010
3037
  try {
3011
- const parsed = JSON.parse(readFileSync6(jsonPath, "utf8"));
3038
+ const parsed = JSON.parse(readFileSync7(jsonPath, "utf8"));
3012
3039
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
3013
3040
  const source = parsed.taskSource;
3014
3041
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -3017,12 +3044,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
3017
3044
  return null;
3018
3045
  }
3019
3046
  }
3020
- const tsPath = resolve13(projectRoot, "rig.config.ts");
3021
- if (!existsSync13(tsPath)) {
3047
+ const tsPath = resolve14(projectRoot, "rig.config.ts");
3048
+ if (!existsSync14(tsPath)) {
3022
3049
  return null;
3023
3050
  }
3024
3051
  try {
3025
- const source = readFileSync6(tsPath, "utf8");
3052
+ const source = readFileSync7(tsPath, "utf8");
3026
3053
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
3027
3054
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
3028
3055
  if (kind !== "files") {
@@ -3042,63 +3069,23 @@ function readRawTaskEntry(configPath, taskId) {
3042
3069
  return isPlainRecord2(entry) ? entry : null;
3043
3070
  }
3044
3071
  function readRawTaskConfig(configPath) {
3045
- if (!existsSync13(configPath)) {
3072
+ if (!existsSync14(configPath)) {
3046
3073
  return null;
3047
3074
  }
3048
- const parsed = JSON.parse(readFileSync6(configPath, "utf8"));
3075
+ const parsed = JSON.parse(readFileSync7(configPath, "utf8"));
3049
3076
  return isPlainRecord2(parsed) ? parsed : null;
3050
3077
  }
3051
3078
  function stripLegacyTaskConfigMetadata2(raw) {
3052
3079
  const { validation_descriptions: _legacyDescriptions, _meta, ...tasks } = raw;
3053
3080
  return tasks;
3054
3081
  }
3055
- function writeLegacyTaskStatus(configPath, taskId, status) {
3056
- const rawConfig = readRawTaskConfig(configPath);
3057
- if (!rawConfig) {
3058
- return;
3059
- }
3060
- const entry = rawConfig[taskId];
3061
- if (!isPlainRecord2(entry)) {
3062
- return;
3063
- }
3064
- entry.status = status;
3065
- writeFileSync5(configPath, `${JSON.stringify(rawConfig, null, 2)}
3066
- `, "utf8");
3067
- }
3068
- function updateFileBackedTask(projectRoot, sourcePath, taskId, update) {
3069
- const directory = resolve13(projectRoot, sourcePath);
3070
- const file = findFileBackedTaskFile(directory, taskId);
3071
- if (!file) {
3072
- return false;
3073
- }
3074
- const raw = JSON.parse(readFileSync6(file, "utf8"));
3075
- if (!isPlainRecord2(raw)) {
3076
- return false;
3077
- }
3078
- if (update.status)
3079
- raw.status = update.status;
3080
- if (update.title !== undefined)
3081
- raw.title = update.title;
3082
- if (update.body !== undefined)
3083
- raw.body = update.body;
3084
- if (update.comment?.trim()) {
3085
- const existing = Array.isArray(raw.comments) ? raw.comments : [];
3086
- raw.comments = [
3087
- ...existing,
3088
- { body: update.comment, createdAt: new Date().toISOString(), source: "rig" }
3089
- ];
3090
- }
3091
- writeFileSync5(file, `${JSON.stringify(raw, null, 2)}
3092
- `, "utf8");
3093
- return true;
3094
- }
3095
3082
  function listFileBackedTasks(projectRoot, sourcePath) {
3096
- const directory = resolve13(projectRoot, sourcePath);
3097
- if (!existsSync13(directory)) {
3083
+ const directory = resolve14(projectRoot, sourcePath);
3084
+ if (!existsSync14(directory)) {
3098
3085
  return [];
3099
3086
  }
3100
3087
  const tasks = [];
3101
- for (const name of readdirSync(directory)) {
3088
+ for (const name of readdirSync2(directory)) {
3102
3089
  if (!FILE_TASK_PATTERN.test(name))
3103
3090
  continue;
3104
3091
  const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
@@ -3109,11 +3096,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
3109
3096
  return tasks;
3110
3097
  }
3111
3098
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
3112
- const file = findFileBackedTaskFile(resolve13(projectRoot, sourcePath), taskId);
3099
+ const file = findFileBackedTaskFile(resolve14(projectRoot, sourcePath), taskId);
3113
3100
  if (!file) {
3114
3101
  return null;
3115
3102
  }
3116
- const raw = JSON.parse(readFileSync6(file, "utf8"));
3103
+ const raw = JSON.parse(readFileSync7(file, "utf8"));
3117
3104
  if (!isPlainRecord2(raw)) {
3118
3105
  return null;
3119
3106
  }
@@ -3126,17 +3113,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
3126
3113
  };
3127
3114
  }
3128
3115
  function findFileBackedTaskFile(directory, taskId) {
3129
- if (!existsSync13(directory)) {
3116
+ if (!existsSync14(directory)) {
3130
3117
  return null;
3131
3118
  }
3132
- for (const name of readdirSync(directory)) {
3119
+ for (const name of readdirSync2(directory)) {
3133
3120
  if (!FILE_TASK_PATTERN.test(name))
3134
3121
  continue;
3135
3122
  const file = join3(directory, name);
3136
3123
  try {
3137
3124
  if (!statSync3(file).isFile())
3138
3125
  continue;
3139
- const raw = JSON.parse(readFileSync6(file, "utf8"));
3126
+ const raw = JSON.parse(readFileSync7(file, "utf8"));
3140
3127
  const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
3141
3128
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
3142
3129
  if (id === taskId) {
@@ -3159,26 +3146,6 @@ function readGithubIssueTask(bin, spawnFn, id, metadata, rawEntry) {
3159
3146
  ], spawnFn);
3160
3147
  return githubIssueToTask(issue, source, rawEntry);
3161
3148
  }
3162
- function applyGithubIssueUpdate(bin, spawnFn, id, metadata, update) {
3163
- const source = requireGithubIssueSource(metadata, id);
3164
- const repo = `${source.owner}/${source.repo}`;
3165
- if (update.status) {
3166
- applyGithubIssueStatus(bin, repo, spawnFn, id, update.status);
3167
- }
3168
- if (typeof update.comment === "string" && update.comment.trim().length > 0) {
3169
- runGhVoid(bin, ["issue", "comment", String(id), "--repo", repo, "--body", update.comment], spawnFn);
3170
- }
3171
- const editArgs = ["issue", "edit", String(id), "--repo", repo];
3172
- if (typeof update.title === "string" && update.title.trim().length > 0) {
3173
- editArgs.push("--title", update.title.trim());
3174
- }
3175
- if (typeof update.body === "string") {
3176
- editArgs.push("--body", update.body);
3177
- }
3178
- if (editArgs.length > 5) {
3179
- runGhVoid(bin, editArgs, spawnFn);
3180
- }
3181
- }
3182
3149
  function requireGithubIssueSource(metadata, id) {
3183
3150
  const source = metadata.taskSource;
3184
3151
  if (source?.kind === "github-issues" && source.owner && source.repo) {
@@ -3238,76 +3205,9 @@ function githubStatusFor(issue) {
3238
3205
  return "cancelled";
3239
3206
  return "open";
3240
3207
  }
3241
- function applyGithubIssueStatus(bin, repo, spawnFn, id, status) {
3242
- if (status === "closed") {
3243
- runGhVoid(bin, ["issue", "close", String(id), "--repo", repo], spawnFn);
3244
- return;
3245
- }
3246
- const targetLabel = statusLabelFor(status);
3247
- for (const label of STATUS_LABELS) {
3248
- if (targetLabel !== null && label === targetLabel) {
3249
- continue;
3250
- }
3251
- try {
3252
- runGhVoid(bin, ["issue", "edit", String(id), "--repo", repo, "--remove-label", label], spawnFn);
3253
- } catch {}
3254
- }
3255
- if (targetLabel !== null) {
3256
- try {
3257
- runGhVoid(bin, ["issue", "edit", String(id), "--repo", repo, "--add-label", targetLabel], spawnFn);
3258
- } catch (error) {
3259
- const message = error instanceof Error ? error.message : String(error);
3260
- if (!/not found/i.test(message)) {
3261
- throw error;
3262
- }
3263
- ensureStatusLabel(bin, repo, spawnFn, targetLabel);
3264
- runGhVoid(bin, ["issue", "edit", String(id), "--repo", repo, "--add-label", targetLabel], spawnFn);
3265
- }
3266
- }
3267
- }
3268
- function statusLabelFor(status) {
3269
- switch (status) {
3270
- case "in_progress":
3271
- return "in-progress";
3272
- case "blocked":
3273
- return "blocked";
3274
- case "ready":
3275
- return "ready";
3276
- case "under_review":
3277
- return "under-review";
3278
- case "failed":
3279
- return "failed";
3280
- case "cancelled":
3281
- return "cancelled";
3282
- case "open":
3283
- return null;
3284
- default:
3285
- throw new Error(`unsupported status: ${status}`);
3286
- }
3287
- }
3288
- function ensureStatusLabel(bin, repo, spawnFn, label) {
3289
- try {
3290
- runGhVoid(bin, [
3291
- "label",
3292
- "create",
3293
- label,
3294
- "--repo",
3295
- repo,
3296
- "--color",
3297
- "6f42c1",
3298
- "--description",
3299
- "Task status managed by Rig"
3300
- ], spawnFn);
3301
- } catch (error) {
3302
- const message = error instanceof Error ? error.message : String(error);
3303
- if (!/already exists/i.test(message)) {
3304
- throw error;
3305
- }
3306
- }
3307
- }
3308
3208
  function selectedGitHubEnv() {
3309
- const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() ?? "";
3310
- return { GH_TOKEN: token, GITHUB_TOKEN: token };
3209
+ const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
3210
+ return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
3311
3211
  }
3312
3212
  function ghSpawnOptions() {
3313
3213
  return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
@@ -3320,10 +3220,6 @@ function runGh(bin, args, spawnFn) {
3320
3220
  }
3321
3221
  return JSON.parse(res.stdout);
3322
3222
  }
3323
- function runGhVoid(bin, args, spawnFn) {
3324
- const res = spawnFn(bin, [...args], ghSpawnOptions());
3325
- assertGhSuccess(args, res);
3326
- }
3327
3223
  function assertGhSuccess(args, res) {
3328
3224
  if (res.error) {
3329
3225
  const msg = res.error.message ?? String(res.error);
@@ -3361,19 +3257,6 @@ function isPlainRecord2(candidate) {
3361
3257
  function hasRunnableTaskSource(source) {
3362
3258
  return Boolean(source && typeof source === "object" && !Array.isArray(source));
3363
3259
  }
3364
- function cleanString(value) {
3365
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
3366
- }
3367
- function taskIdFromSourceIssueId(value) {
3368
- const raw = cleanString(value);
3369
- if (!raw)
3370
- return null;
3371
- const issueNumber = raw.match(/#([^#\s]+)$/)?.[1];
3372
- return issueNumber ?? raw;
3373
- }
3374
- function resolveSourceTaskId(taskId, sourceTask) {
3375
- return cleanString(sourceTask?.id) ?? taskIdFromSourceIssueId(sourceTask?.sourceIssueId) ?? taskIdFromSourceIssueId(sourceTask?.source_issue_id) ?? taskId;
3376
- }
3377
3260
  async function getPluginTask(projectRoot, taskId) {
3378
3261
  const ctx = await buildPluginHostContext(projectRoot);
3379
3262
  const [source] = ctx?.taskSourceRegistry.list() ?? [];
@@ -3398,95 +3281,10 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
3398
3281
  task
3399
3282
  };
3400
3283
  }
3401
- async function updatePluginTaskSourceTask(projectRoot, taskId, update) {
3402
- const ctx = await buildPluginHostContext(projectRoot);
3403
- const [source] = ctx?.taskSourceRegistry.list() ?? [];
3404
- if (!hasRunnableTaskSource(source)) {
3405
- return ctx ? { taskId, updated: false, source: "none", sourceKind: null, status: null } : null;
3406
- }
3407
- if (source.updateTask) {
3408
- await source.updateTask(taskId, update);
3409
- } else if (update.status && source.updateStatus) {
3410
- await source.updateStatus(taskId, update.status);
3411
- } else {
3412
- return {
3413
- taskId,
3414
- updated: false,
3415
- source: "plugin",
3416
- sourceKind: source.kind,
3417
- status: null
3418
- };
3419
- }
3420
- const status = source.get ? (await source.get(taskId))?.status ?? update.status ?? null : update.status ?? null;
3421
- return {
3422
- taskId,
3423
- updated: true,
3424
- source: "plugin",
3425
- sourceKind: source.kind,
3426
- status
3427
- };
3428
- }
3429
- async function updateConfiguredTaskSourceTask(projectRoot, input) {
3430
- const taskId = resolveSourceTaskId(input.taskId, input.sourceTask);
3431
- let pluginResult = null;
3432
- try {
3433
- pluginResult = await updatePluginTaskSourceTask(projectRoot, taskId, input.update);
3434
- } catch (error) {
3435
- const fallbackUpdated = updateSourceAwareTaskConfigTask(projectRoot, taskId, input.update, {
3436
- allowLocalTaskConfigStatusFallback: false
3437
- });
3438
- if (!fallbackUpdated) {
3439
- throw error;
3440
- }
3441
- return {
3442
- taskId,
3443
- updated: true,
3444
- source: "compat",
3445
- sourceKind: null,
3446
- status: await readSourceAwareTaskStatus(projectRoot, taskId)
3447
- };
3448
- }
3449
- if (pluginResult) {
3450
- return pluginResult;
3451
- }
3452
- const updated = updateSourceAwareTaskConfigTask(projectRoot, taskId, input.update);
3453
- return {
3454
- taskId,
3455
- updated,
3456
- source: updated ? "compat" : "none",
3457
- sourceKind: null,
3458
- status: await readSourceAwareTaskStatus(projectRoot, taskId)
3459
- };
3460
- }
3461
- function buildTaskRunLifecycleComment(input) {
3462
- const lines = [
3463
- "<!-- rig:status-comment -->",
3464
- `### Rig status: ${input.status}`,
3465
- "",
3466
- input.summary,
3467
- "",
3468
- `- Run: ${input.runId}`,
3469
- `- Status: ${input.status}`
3470
- ];
3471
- if (input.errorText?.trim()) {
3472
- lines.push(`- Error: ${input.errorText.trim()}`);
3473
- }
3474
- if (input.runtimeWorkspace?.trim()) {
3475
- lines.push(`- Runtime workspace: ${input.runtimeWorkspace.trim()}`);
3476
- }
3477
- if (input.logsDir?.trim()) {
3478
- lines.push(`- Logs: ${input.logsDir.trim()}`);
3479
- }
3480
- if (input.sessionDir?.trim()) {
3481
- lines.push(`- Session: ${input.sessionDir.trim()}`);
3482
- }
3483
- return lines.join(`
3484
- `);
3485
- }
3486
3284
 
3487
3285
  // 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";
3286
+ import { existsSync as existsSync18, readFileSync as readFileSync9, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
3287
+ import { basename as basename6, resolve as resolve18 } from "path";
3490
3288
 
3491
3289
  // packages/runtime/src/control-plane/state-sync/types.ts
3492
3290
  var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
@@ -3594,39 +3392,39 @@ function readTaskStateMetadataEnvelope(raw) {
3594
3392
  };
3595
3393
  }
3596
3394
  // 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";
3395
+ import { existsSync as existsSync17, readFileSync as readFileSync8 } from "fs";
3396
+ import { resolve as resolve17 } from "path";
3599
3397
 
3600
3398
  // packages/runtime/src/control-plane/state-sync/repo.ts
3601
- import { existsSync as existsSync15 } from "fs";
3602
- import { resolve as resolve15 } from "path";
3399
+ import { existsSync as existsSync16 } from "fs";
3400
+ import { resolve as resolve16 } from "path";
3603
3401
 
3604
3402
  // packages/runtime/src/control-plane/repos/layout.ts
3605
3403
  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";
3404
+ import { existsSync as existsSync15 } from "fs";
3405
+ import { basename as basename5, dirname as dirname9, join as join4, resolve as resolve15 } from "path";
3608
3406
  function resolveRepoStateDir(projectRoot) {
3609
- const normalizedProjectRoot = resolve14(projectRoot);
3407
+ const normalizedProjectRoot = resolve15(projectRoot);
3610
3408
  const projectParent = dirname9(normalizedProjectRoot);
3611
3409
  if (basename5(projectParent) === ".worktrees") {
3612
3410
  const ownerRoot = dirname9(projectParent);
3613
- const ownerHasRepoMarkers = existsSync14(resolve14(ownerRoot, ".git")) || existsSync14(resolve14(ownerRoot, ".rig", "state"));
3411
+ const ownerHasRepoMarkers = existsSync15(resolve15(ownerRoot, ".git")) || existsSync15(resolve15(ownerRoot, ".rig", "state"));
3614
3412
  if (ownerHasRepoMarkers) {
3615
- return resolve14(ownerRoot, ".rig", "state");
3413
+ return resolve15(ownerRoot, ".rig", "state");
3616
3414
  }
3617
3415
  }
3618
- return resolve14(projectRoot, ".rig", "state");
3416
+ return resolve15(projectRoot, ".rig", "state");
3619
3417
  }
3620
3418
  function resolveManagedRepoLayout(projectRoot, repoId) {
3621
- const normalizedProjectRoot = resolve14(projectRoot);
3419
+ const normalizedProjectRoot = resolve15(projectRoot);
3622
3420
  const entry = getManagedRepoEntry(repoId);
3623
3421
  const stateDir = resolveRepoStateDir(normalizedProjectRoot);
3624
3422
  const metadataRelativePath = join4("repos", entry.id);
3625
- const metadataRoot = resolve14(stateDir, metadataRelativePath);
3423
+ const metadataRoot = resolve15(stateDir, metadataRelativePath);
3626
3424
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
3627
- const runsInsideTaskWorktree = runtimeWorkspace && resolve14(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
3425
+ const runsInsideTaskWorktree = runtimeWorkspace && resolve15(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname9(normalizedProjectRoot)) === ".worktrees";
3628
3426
  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);
3427
+ const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve15(process.env[entry.checkoutEnvVar].trim()) : resolve15(normalizedProjectRoot, entry.alias);
3630
3428
  return {
3631
3429
  projectRoot: normalizedProjectRoot,
3632
3430
  repoId: entry.id,
@@ -3634,12 +3432,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
3634
3432
  defaultBranch: entry.defaultBranch,
3635
3433
  remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
3636
3434
  checkoutRoot,
3637
- worktreesRoot: resolve14(checkoutRoot, ".worktrees"),
3435
+ worktreesRoot: resolve15(checkoutRoot, ".worktrees"),
3638
3436
  stateDir,
3639
3437
  metadataRoot,
3640
3438
  metadataRelativePath,
3641
- mirrorRoot: resolve14(metadataRoot, "mirror.git"),
3642
- mirrorStatePath: resolve14(metadataRoot, "mirror-state.json"),
3439
+ mirrorRoot: resolve15(metadataRoot, "mirror.git"),
3440
+ mirrorStatePath: resolve15(metadataRoot, "mirror-state.json"),
3643
3441
  mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
3644
3442
  };
3645
3443
  }
@@ -3657,7 +3455,7 @@ function resolveTrackerRepoPath(projectRoot) {
3657
3455
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
3658
3456
  try {
3659
3457
  const layout = resolveMonorepoRepoLayout(projectRoot);
3660
- if (existsSync15(resolve15(layout.mirrorRoot, "HEAD"))) {
3458
+ if (existsSync16(resolve16(layout.mirrorRoot, "HEAD"))) {
3661
3459
  return layout.mirrorRoot;
3662
3460
  }
3663
3461
  } catch {}
@@ -3668,8 +3466,8 @@ function resolveTrackerRepoPath(projectRoot) {
3668
3466
  var DEFAULT_READ_DEPS2 = {
3669
3467
  fetchRef: nativeFetchRef,
3670
3468
  readBlobAtRef: nativeReadBlobAtRef,
3671
- exists: existsSync16,
3672
- readFile: (path) => readFileSync7(path, "utf8")
3469
+ exists: existsSync17,
3470
+ readFile: (path) => readFileSync8(path, "utf8")
3673
3471
  };
3674
3472
  function parseIssueStatus(rawStatus) {
3675
3473
  const normalized = normalizeTaskLifecycleStatus(rawStatus);
@@ -3750,12 +3548,12 @@ function shouldPreferLocalTrackerState(options) {
3750
3548
  if (runtimeContextPath) {
3751
3549
  return true;
3752
3550
  }
3753
- return existsSync16(resolve16(runtimeWorkspace, ".rig", "runtime-context.json"));
3551
+ return existsSync17(resolve17(runtimeWorkspace, ".rig", "runtime-context.json"));
3754
3552
  }
3755
3553
  function readLocalTrackerState(projectRoot, deps) {
3756
3554
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
3757
- const issuesPath = resolve16(monorepoRoot, ".beads", "issues.jsonl");
3758
- const taskStatePath = resolve16(monorepoRoot, ".beads", "task-state.json");
3555
+ const issuesPath = resolve17(monorepoRoot, ".beads", "issues.jsonl");
3556
+ const taskStatePath = resolve17(monorepoRoot, ".beads", "task-state.json");
3759
3557
  return projectSyncedTrackerSnapshot({
3760
3558
  source: "local",
3761
3559
  issuesBaseOid: null,
@@ -3817,7 +3615,7 @@ function readValidationDescriptions(projectRoot) {
3817
3615
  return readValidationDescriptionMap(raw);
3818
3616
  }
3819
3617
  function readSourceValidationDescriptions(projectRoot) {
3820
- const rootRaw = readJsonFile(resolve17(projectRoot, "rig", "task-config.json"), {});
3618
+ const rootRaw = readJsonFile(resolve18(projectRoot, "rig", "task-config.json"), {});
3821
3619
  const sourcePath = findSourceTaskConfigPath(projectRoot);
3822
3620
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
3823
3621
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -3893,15 +3691,15 @@ function readValidationDescriptionsFromMeta(meta) {
3893
3691
  return meta.validation_descriptions;
3894
3692
  }
3895
3693
  function readLocalSourceTaskStateEnvelope(projectRoot) {
3896
- const taskStatePath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
3694
+ const taskStatePath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
3897
3695
  return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
3898
3696
  }
3899
3697
  function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
3900
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
3901
- if (!existsSync17(issuesPath)) {
3698
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
3699
+ if (!existsSync18(issuesPath)) {
3902
3700
  return null;
3903
3701
  }
3904
- for (const line of readFileSync8(issuesPath, "utf8").split(/\r?\n/)) {
3702
+ for (const line of readFileSync9(issuesPath, "utf8").split(/\r?\n/)) {
3905
3703
  const trimmed = line.trim();
3906
3704
  if (!trimmed) {
3907
3705
  continue;
@@ -3926,25 +3724,25 @@ function inferTaskIdFromRuntimePath(path) {
3926
3724
  function artifactDirForId(projectRoot, id) {
3927
3725
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
3928
3726
  if (workspaceDir) {
3929
- const worktreeArtifacts = resolve17(workspaceDir, "artifacts", id);
3930
- if (existsSync17(worktreeArtifacts) || existsSync17(resolve17(workspaceDir, "artifacts"))) {
3727
+ const worktreeArtifacts = resolve18(workspaceDir, "artifacts", id);
3728
+ if (existsSync18(worktreeArtifacts) || existsSync18(resolve18(workspaceDir, "artifacts"))) {
3931
3729
  return worktreeArtifacts;
3932
3730
  }
3933
3731
  }
3934
3732
  try {
3935
3733
  const paths = resolveHarnessPaths(projectRoot);
3936
- return resolve17(paths.artifactsDir, id);
3734
+ return resolve18(paths.artifactsDir, id);
3937
3735
  } catch {
3938
- return resolve17(resolveMonorepoRoot2(projectRoot), "artifacts", id);
3736
+ return resolve18(resolveMonorepoRoot2(projectRoot), "artifacts", id);
3939
3737
  }
3940
3738
  }
3941
3739
  function resolveTaskConfigPath(projectRoot) {
3942
3740
  const paths = resolveHarnessPaths(projectRoot);
3943
- if (existsSync17(paths.taskConfigPath)) {
3741
+ if (existsSync18(paths.taskConfigPath)) {
3944
3742
  return paths.taskConfigPath;
3945
3743
  }
3946
3744
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
3947
- if (existsSync17(candidate)) {
3745
+ if (existsSync18(candidate)) {
3948
3746
  return candidate;
3949
3747
  }
3950
3748
  }
@@ -3952,7 +3750,7 @@ function resolveTaskConfigPath(projectRoot) {
3952
3750
  }
3953
3751
  function findSourceTaskConfigPath(projectRoot) {
3954
3752
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
3955
- if (existsSync17(candidate)) {
3753
+ if (existsSync18(candidate)) {
3956
3754
  return candidate;
3957
3755
  }
3958
3756
  }
@@ -3965,7 +3763,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
3965
3763
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
3966
3764
  if (sourcePath && synced.updated) {
3967
3765
  try {
3968
- writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
3766
+ writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
3969
3767
  `, "utf-8");
3970
3768
  } catch {}
3971
3769
  }
@@ -4017,12 +3815,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
4017
3815
  return !candidate.role;
4018
3816
  }
4019
3817
  function readSourceIssueRecords(projectRoot) {
4020
- const issuesPath = resolve17(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
4021
- if (!existsSync17(issuesPath)) {
3818
+ const issuesPath = resolve18(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
3819
+ if (!existsSync18(issuesPath)) {
4022
3820
  return [];
4023
3821
  }
4024
3822
  const records = [];
4025
- for (const line of readFileSync8(issuesPath, "utf-8").split(/\r?\n/)) {
3823
+ for (const line of readFileSync9(issuesPath, "utf-8").split(/\r?\n/)) {
4026
3824
  const trimmed = line.trim();
4027
3825
  if (!trimmed) {
4028
3826
  continue;
@@ -4078,19 +3876,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
4078
3876
  if (!sourcePath) {
4079
3877
  return {};
4080
3878
  }
4081
- const directory = resolve17(projectRoot, sourcePath);
4082
- if (!existsSync17(directory)) {
3879
+ const directory = resolve18(projectRoot, sourcePath);
3880
+ if (!existsSync18(directory)) {
4083
3881
  return {};
4084
3882
  }
4085
3883
  const config = {};
4086
- for (const name of readdirSync2(directory)) {
3884
+ for (const name of readdirSync3(directory)) {
4087
3885
  if (!FILE_TASK_PATTERN2.test(name))
4088
3886
  continue;
4089
- const file = resolve17(directory, name);
3887
+ const file = resolve18(directory, name);
4090
3888
  try {
4091
3889
  if (!statSync4(file).isFile())
4092
3890
  continue;
4093
- const raw = JSON.parse(readFileSync8(file, "utf8"));
3891
+ const raw = JSON.parse(readFileSync9(file, "utf8"));
4094
3892
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
4095
3893
  continue;
4096
3894
  const record = raw;
@@ -4132,10 +3930,10 @@ function firstStringList2(...candidates) {
4132
3930
  return [];
4133
3931
  }
4134
3932
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
4135
- const jsonPath = resolve17(projectRoot, "rig.config.json");
4136
- if (existsSync17(jsonPath)) {
3933
+ const jsonPath = resolve18(projectRoot, "rig.config.json");
3934
+ if (existsSync18(jsonPath)) {
4137
3935
  try {
4138
- const parsed = JSON.parse(readFileSync8(jsonPath, "utf8"));
3936
+ const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
4139
3937
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
4140
3938
  const taskSource = parsed.taskSource;
4141
3939
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -4147,12 +3945,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
4147
3945
  return null;
4148
3946
  }
4149
3947
  }
4150
- const tsPath = resolve17(projectRoot, "rig.config.ts");
4151
- if (!existsSync17(tsPath)) {
3948
+ const tsPath = resolve18(projectRoot, "rig.config.ts");
3949
+ if (!existsSync18(tsPath)) {
4152
3950
  return null;
4153
3951
  }
4154
3952
  try {
4155
- const source = readFileSync8(tsPath, "utf8");
3953
+ const source = readFileSync9(tsPath, "utf8");
4156
3954
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
4157
3955
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
4158
3956
  if (kind !== "files") {
@@ -4166,9 +3964,9 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
4166
3964
  function sourceTaskConfigCandidates(projectRoot) {
4167
3965
  const runtimeContext = loadRuntimeContextFromEnv();
4168
3966
  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")
3967
+ runtimeContext?.monorepoMainRoot ? resolve18(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
3968
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve18(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
3969
+ resolve18(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
4172
3970
  ].filter(Boolean);
4173
3971
  }
4174
3972
 
@@ -4177,8 +3975,8 @@ init_layout();
4177
3975
 
4178
3976
  // packages/runtime/src/binary-run.ts
4179
3977
  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";
3978
+ import { chmodSync as chmodSync4, cpSync, existsSync as existsSync19, mkdirSync as mkdirSync9, renameSync as renameSync3, rmSync as rmSync8, writeFileSync as writeFileSync8 } from "fs";
3979
+ import { basename as basename7, dirname as dirname10, resolve as resolve19 } from "path";
4182
3980
  import { fileURLToPath } from "url";
4183
3981
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
4184
3982
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -4204,9 +4002,9 @@ async function buildRuntimeBinary(options) {
4204
4002
  });
4205
4003
  }
4206
4004
  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 });
4005
+ const tempBuildDir = resolve19(dirname10(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
4006
+ const tempOutputPath = resolve19(tempBuildDir, basename7(options.outputPath));
4007
+ mkdirSync9(tempBuildDir, { recursive: true });
4210
4008
  await withTemporaryEnv({
4211
4009
  ...options.env,
4212
4010
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -4231,7 +4029,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
4231
4029
  `);
4232
4030
  throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
4233
4031
  }
4234
- if (!existsSync18(tempOutputPath)) {
4032
+ if (!existsSync19(tempOutputPath)) {
4235
4033
  const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
4236
4034
  throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
4237
4035
  }
@@ -4246,7 +4044,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
4246
4044
  });
4247
4045
  }
4248
4046
  })).finally(() => {
4249
- rmSync7(tempBuildDir, { recursive: true, force: true });
4047
+ rmSync8(tempBuildDir, { recursive: true, force: true });
4250
4048
  });
4251
4049
  }
4252
4050
  function runBestEffortBuildGc() {
@@ -4263,8 +4061,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
4263
4061
  function resolveRuntimeBinaryBuildOptions(options) {
4264
4062
  return {
4265
4063
  ...options,
4266
- entrypoint: resolve18(options.cwd, options.sourcePath),
4267
- outputPath: resolve18(options.outputPath)
4064
+ entrypoint: resolve19(options.cwd, options.sourcePath),
4065
+ outputPath: resolve19(options.outputPath)
4268
4066
  };
4269
4067
  }
4270
4068
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -4278,7 +4076,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
4278
4076
  }
4279
4077
  async function buildRuntimeBinaryViaWorker(options) {
4280
4078
  const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
4281
- if (!workerSourcePath || !existsSync18(workerSourcePath)) {
4079
+ if (!workerSourcePath || !existsSync19(workerSourcePath)) {
4282
4080
  await buildRuntimeBinaryInProcess(options, {
4283
4081
  manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
4284
4082
  buildKey: createRuntimeBinaryBuildKey({
@@ -4309,13 +4107,13 @@ async function buildRuntimeBinaryViaWorker(options) {
4309
4107
  new Response(build.stdout).text(),
4310
4108
  new Response(build.stderr).text()
4311
4109
  ]);
4312
- rmSync7(payloadPath, { force: true });
4110
+ rmSync8(payloadPath, { force: true });
4313
4111
  if (exitCode !== 0) {
4314
4112
  throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
4315
4113
  }
4316
4114
  }
4317
4115
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
4318
- return resolve18(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
4116
+ return resolve19(dirname10(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
4319
4117
  }
4320
4118
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
4321
4119
  const envRoots = [
@@ -4324,13 +4122,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
4324
4122
  process.env.PROJECT_RIG_ROOT?.trim()
4325
4123
  ].filter(Boolean);
4326
4124
  for (const root of envRoots) {
4327
- const candidate = resolve18(root, "packages/runtime/src/binary-build-worker.ts");
4328
- if (existsSync18(candidate)) {
4125
+ const candidate = resolve19(root, "packages/runtime/src/binary-build-worker.ts");
4126
+ if (existsSync19(candidate)) {
4329
4127
  return candidate;
4330
4128
  }
4331
4129
  }
4332
- const localCandidate = resolve18(import.meta.dir, "binary-build-worker.ts");
4333
- return existsSync18(localCandidate) ? localCandidate : null;
4130
+ const localCandidate = resolve19(import.meta.dir, "binary-build-worker.ts");
4131
+ return existsSync19(localCandidate) ? localCandidate : null;
4334
4132
  }
4335
4133
  function resolveRuntimeBinaryBuildWorkerInvocation() {
4336
4134
  const bunPath = Bun.which("bun");
@@ -4366,7 +4164,7 @@ function createRuntimeBinaryBuildKey(input) {
4366
4164
  });
4367
4165
  }
4368
4166
  async function isRuntimeBinaryBuildFresh(input) {
4369
- if (!existsSync18(input.outputPath) || !existsSync18(input.manifestPath)) {
4167
+ if (!existsSync19(input.outputPath) || !existsSync19(input.manifestPath)) {
4370
4168
  return false;
4371
4169
  }
4372
4170
  let manifest = null;
@@ -4379,7 +4177,7 @@ async function isRuntimeBinaryBuildFresh(input) {
4379
4177
  return false;
4380
4178
  }
4381
4179
  for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
4382
- if (!existsSync18(filePath)) {
4180
+ if (!existsSync19(filePath)) {
4383
4181
  return false;
4384
4182
  }
4385
4183
  if (await sha256File4(filePath) !== expectedDigest) {
@@ -4392,7 +4190,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
4392
4190
  const inputs = {};
4393
4191
  for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
4394
4192
  const normalized = normalizeBuildInputPath(input.cwd, inputPath);
4395
- if (!normalized || !existsSync18(normalized)) {
4193
+ if (!normalized || !existsSync19(normalized)) {
4396
4194
  continue;
4397
4195
  }
4398
4196
  inputs[normalized] = await sha256File4(normalized);
@@ -4415,7 +4213,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
4415
4213
  if (inputPath.startsWith("<")) {
4416
4214
  return null;
4417
4215
  }
4418
- return resolve18(cwd, inputPath);
4216
+ return resolve19(cwd, inputPath);
4419
4217
  }
4420
4218
  async function sha256File4(path) {
4421
4219
  const hasher = new Bun.CryptoHasher("sha256");
@@ -4431,8 +4229,8 @@ function sortRecord(value) {
4431
4229
  async function runSerializedRuntimeBinaryBuild(action) {
4432
4230
  const previous = runtimeBinaryBuildQueue;
4433
4231
  let release;
4434
- runtimeBinaryBuildQueue = new Promise((resolve19) => {
4435
- release = resolve19;
4232
+ runtimeBinaryBuildQueue = new Promise((resolve20) => {
4233
+ release = resolve20;
4436
4234
  });
4437
4235
  await previous;
4438
4236
  try {
@@ -4477,11 +4275,11 @@ async function withTemporaryCwd(cwd, action) {
4477
4275
  }
4478
4276
 
4479
4277
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
4480
- import { delimiter, resolve as resolve21 } from "path";
4278
+ import { delimiter, resolve as resolve22 } from "path";
4481
4279
 
4482
4280
  // 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";
4281
+ import { existsSync as existsSync21, readdirSync as readdirSync5, realpathSync as realpathSync2 } from "fs";
4282
+ import { resolve as resolve21 } from "path";
4485
4283
 
4486
4284
  // packages/runtime/src/control-plane/runtime/sandbox-utils.ts
4487
4285
  init_utils();
@@ -4498,7 +4296,7 @@ function resolveBunBinaryPath() {
4498
4296
  }
4499
4297
  const home = process.env.HOME?.trim();
4500
4298
  const fallbackCandidates = [
4501
- home ? resolve20(home, ".bun/bin/bun") : "",
4299
+ home ? resolve21(home, ".bun/bin/bun") : "",
4502
4300
  "/opt/homebrew/bin/bun",
4503
4301
  "/usr/local/bin/bun",
4504
4302
  "/usr/bin/bun"
@@ -4526,8 +4324,8 @@ function resolveClaudeBinaryPath() {
4526
4324
  }
4527
4325
  const home = process.env.HOME?.trim();
4528
4326
  const fallbackCandidates = [
4529
- home ? resolve20(home, ".local/bin/claude") : "",
4530
- home ? resolve20(home, ".local/share/claude/local/claude") : "",
4327
+ home ? resolve21(home, ".local/bin/claude") : "",
4328
+ home ? resolve21(home, ".local/share/claude/local/claude") : "",
4531
4329
  "/opt/homebrew/bin/claude",
4532
4330
  "/usr/local/bin/claude",
4533
4331
  "/usr/bin/claude"
@@ -4541,35 +4339,35 @@ function resolveClaudeBinaryPath() {
4541
4339
  throw new Error("claude not found in PATH");
4542
4340
  }
4543
4341
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
4544
- return resolve20(bunBinaryPath, "../..");
4342
+ return resolve21(bunBinaryPath, "../..");
4545
4343
  }
4546
4344
  function resolveClaudeInstallDir() {
4547
4345
  const realPath = resolveClaudeBinaryPath();
4548
- return resolve20(realPath, "..");
4346
+ return resolve21(realPath, "..");
4549
4347
  }
4550
4348
  function resolveNodeInstallDir() {
4551
4349
  const preferredNode = resolvePreferredNodeBinary();
4552
4350
  if (!preferredNode)
4553
4351
  return null;
4554
4352
  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, "..");
4353
+ if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
4354
+ return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
4557
4355
  }
4558
4356
  try {
4559
4357
  const realPath = realpathSync2(preferredNode);
4560
4358
  if (realPath.endsWith("/bin/node")) {
4561
- return resolve20(realPath, "../..");
4359
+ return resolve21(realPath, "../..");
4562
4360
  }
4563
- return resolve20(realPath, "..");
4361
+ return resolve21(realPath, "..");
4564
4362
  } catch {
4565
- return resolve20(preferredNode, "..");
4363
+ return resolve21(preferredNode, "..");
4566
4364
  }
4567
4365
  }
4568
4366
  function resolveRuntimeDependencyRoots(runtimeDirs) {
4569
4367
  const roots = [];
4570
4368
  if (process.platform === "darwin") {
4571
4369
  for (const macPath of ["/opt/homebrew", "/opt/homebrew/opt"]) {
4572
- if (existsSync20(macPath)) {
4370
+ if (existsSync21(macPath)) {
4573
4371
  roots.push(macPath);
4574
4372
  }
4575
4373
  }
@@ -4587,23 +4385,23 @@ function resolvePreferredNodeBinary() {
4587
4385
  const candidates = [];
4588
4386
  const envNode = process.env.RIG_NODE_BIN?.trim();
4589
4387
  if (envNode) {
4590
- const explicit = resolve20(envNode);
4591
- if (existsSync20(explicit)) {
4388
+ const explicit = resolve21(envNode);
4389
+ if (existsSync21(explicit)) {
4592
4390
  return explicit;
4593
4391
  }
4594
4392
  }
4595
4393
  const nvmBin = process.env.NVM_BIN?.trim();
4596
4394
  if (nvmBin) {
4597
- candidates.push(resolve20(nvmBin, "node"));
4395
+ candidates.push(resolve21(nvmBin, "node"));
4598
4396
  }
4599
4397
  const home = process.env.HOME?.trim();
4600
4398
  if (home) {
4601
- const nvmVersionsDir = resolve20(home, ".nvm/versions/node");
4602
- if (existsSync20(nvmVersionsDir)) {
4399
+ const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
4400
+ if (existsSync21(nvmVersionsDir)) {
4603
4401
  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/, "")));
4402
+ 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
4403
  for (const versionDir of versionDirs) {
4606
- candidates.push(resolve20(nvmVersionsDir, versionDir, "bin/node"));
4404
+ candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
4607
4405
  }
4608
4406
  } catch {}
4609
4407
  }
@@ -4612,8 +4410,8 @@ function resolvePreferredNodeBinary() {
4612
4410
  if (whichNode) {
4613
4411
  candidates.push(whichNode);
4614
4412
  }
4615
- const deduped = uniq(candidates.map((candidate) => resolve20(candidate)));
4616
- const existing = deduped.filter((candidate) => existsSync20(candidate));
4413
+ const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
4414
+ const existing = deduped.filter((candidate) => existsSync21(candidate));
4617
4415
  if (existing.length === 0) {
4618
4416
  return null;
4619
4417
  }
@@ -4627,7 +4425,7 @@ function resolvePreferredNodeBinary() {
4627
4425
  return existing[0] ?? null;
4628
4426
  }
4629
4427
  function inferNodeMajor(nodeBinaryPath) {
4630
- const normalized = resolve20(nodeBinaryPath).replace(/\\/g, "/");
4428
+ const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
4631
4429
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
4632
4430
  if (!match) {
4633
4431
  return null;
@@ -4639,8 +4437,8 @@ function normalizeExecutablePath(candidate) {
4639
4437
  if (!candidate) {
4640
4438
  return "";
4641
4439
  }
4642
- const normalized = resolve20(candidate);
4643
- if (!existsSync20(normalized)) {
4440
+ const normalized = resolve21(candidate);
4441
+ if (!existsSync21(normalized)) {
4644
4442
  return "";
4645
4443
  }
4646
4444
  try {
@@ -4650,7 +4448,7 @@ function normalizeExecutablePath(candidate) {
4650
4448
  }
4651
4449
  }
4652
4450
  function looksLikeRuntimeGateway(candidate) {
4653
- const normalized = resolve20(candidate).replace(/\\/g, "/");
4451
+ const normalized = resolve21(candidate).replace(/\\/g, "/");
4654
4452
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
4655
4453
  }
4656
4454
 
@@ -4671,7 +4469,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4671
4469
  try {
4672
4470
  return resolveClaudeInstallDir();
4673
4471
  } catch {
4674
- return resolve21(claudeBinary, "..");
4472
+ return resolve22(claudeBinary, "..");
4675
4473
  }
4676
4474
  })() : "";
4677
4475
  const nodeDir = resolveNodeInstallDir();
@@ -4681,8 +4479,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4681
4479
  `${bunDir}/bin`,
4682
4480
  claudeDir,
4683
4481
  nodeDir ? `${nodeDir}/bin` : "",
4684
- realHome ? resolve21(realHome, ".local/bin") : "",
4685
- realHome ? resolve21(realHome, ".cargo/bin") : "",
4482
+ realHome ? resolve22(realHome, ".local/bin") : "",
4483
+ realHome ? resolve22(realHome, ".cargo/bin") : "",
4686
4484
  ...inheritedPath,
4687
4485
  "/usr/local/bin",
4688
4486
  "/usr/local/sbin",
@@ -4711,8 +4509,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
4711
4509
  }
4712
4510
 
4713
4511
  // 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";
4512
+ import { existsSync as existsSync22, readFileSync as readFileSync10 } from "fs";
4513
+ import { resolve as resolve23 } from "path";
4716
4514
  var BAKED_RUNTIME_SECRETS = {
4717
4515
  ANTHROPIC_API_KEY: typeof RIG_BAKED_ANTHROPIC_API_KEY !== "undefined" ? RIG_BAKED_ANTHROPIC_API_KEY : "",
4718
4516
  OPENAI_API_KEY: typeof RIG_BAKED_OPENAI_API_KEY !== "undefined" ? RIG_BAKED_OPENAI_API_KEY : "",
@@ -4755,12 +4553,12 @@ function resolveRuntimeSecrets(env, baked = BAKED_RUNTIME_SECRETS) {
4755
4553
  return resolved;
4756
4554
  }
4757
4555
  function loadDotEnvSecrets(projectRoot, env = process.env) {
4758
- const dotenvPath = resolve22(projectRoot, ".env");
4759
- if (!existsSync21(dotenvPath)) {
4556
+ const dotenvPath = resolve23(projectRoot, ".env");
4557
+ if (!existsSync22(dotenvPath)) {
4760
4558
  return {};
4761
4559
  }
4762
4560
  const parsed = {};
4763
- const lines = readFileSync9(dotenvPath, "utf-8").split(/\r?\n/);
4561
+ const lines = readFileSync10(dotenvPath, "utf-8").split(/\r?\n/);
4764
4562
  for (const rawLine of lines) {
4765
4563
  const line = rawLine.trim();
4766
4564
  if (!line || line.startsWith("#")) {
@@ -5117,16 +4915,16 @@ async function taskDeps(projectRoot, taskId) {
5117
4915
  for (const dep of deps) {
5118
4916
  const artifactDir = artifactDirForId(projectRoot, dep);
5119
4917
  console.log(`=== ${dep} ===`);
5120
- if (!existsSync22(artifactDir)) {
4918
+ if (!existsSync23(artifactDir)) {
5121
4919
  console.log(` (no artifacts yet)
5122
4920
  `);
5123
4921
  continue;
5124
4922
  }
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);
4923
+ printArtifactSection(resolve24(artifactDir, "decision-log.md"), "--- Decisions ---");
4924
+ printArtifactSection(resolve24(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
4925
+ const changedFiles = resolve24(artifactDir, "changed-files.txt");
4926
+ if (existsSync23(changedFiles)) {
4927
+ const lines = readFileSync11(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
5130
4928
  console.log(`--- Changed Files (${lines.length}) ---`);
5131
4929
  for (const line of lines) {
5132
4930
  console.log(line);
@@ -5250,12 +5048,12 @@ function printIndented(text) {
5250
5048
  }
5251
5049
  }
5252
5050
  function readLocalBeadsTasks(projectRoot) {
5253
- const issuesPath = resolve23(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
5254
- if (!existsSync22(issuesPath)) {
5051
+ const issuesPath = resolve24(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
5052
+ if (!existsSync23(issuesPath)) {
5255
5053
  return [];
5256
5054
  }
5257
5055
  const tasks = [];
5258
- for (const line of readFileSync10(issuesPath, "utf-8").split(/\r?\n/)) {
5056
+ for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
5259
5057
  const trimmed = line.trim();
5260
5058
  if (!trimmed) {
5261
5059
  continue;
@@ -5368,11 +5166,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
5368
5166
  return [...ids].sort();
5369
5167
  }
5370
5168
  function printArtifactSection(path, header) {
5371
- if (!existsSync22(path)) {
5169
+ if (!existsSync23(path)) {
5372
5170
  return;
5373
5171
  }
5374
5172
  console.log(header);
5375
- process.stdout.write(readFileSync10(path, "utf-8"));
5173
+ process.stdout.write(readFileSync11(path, "utf-8"));
5376
5174
  console.log("");
5377
5175
  }
5378
5176
 
@@ -5474,7 +5272,7 @@ init_layout();
5474
5272
 
5475
5273
  // packages/runtime/src/control-plane/runtime/overlay.ts
5476
5274
  init_layout();
5477
- import { mkdirSync as mkdirSync10 } from "fs";
5275
+ import { mkdirSync as mkdirSync11 } from "fs";
5478
5276
  function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
5479
5277
  const layout = resolveRuntimeWorkspaceLayout(workspaceDir ?? projectRoot);
5480
5278
  const rootDir = layout.rigRoot;
@@ -5486,14 +5284,14 @@ function ensureRuntimeOverlay(projectRoot, runtimeId, workspaceDir) {
5486
5284
  const sessionDir = layout.sessionDir;
5487
5285
  const runtimeDir = layout.runtimeDir;
5488
5286
  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 });
5287
+ mkdirSync11(rootDir, { recursive: true });
5288
+ mkdirSync11(homeDir, { recursive: true });
5289
+ mkdirSync11(tmpDir, { recursive: true });
5290
+ mkdirSync11(cacheDir, { recursive: true });
5291
+ mkdirSync11(logsDir, { recursive: true });
5292
+ mkdirSync11(stateDir, { recursive: true });
5293
+ mkdirSync11(sessionDir, { recursive: true });
5294
+ mkdirSync11(runtimeDir, { recursive: true });
5497
5295
  return {
5498
5296
  rootDir,
5499
5297
  homeDir,
@@ -5511,17 +5309,17 @@ import {
5511
5309
  chmodSync as chmodSync5,
5512
5310
  copyFileSync as copyFileSync5,
5513
5311
  cpSync as cpSync2,
5514
- existsSync as existsSync24,
5515
- mkdirSync as mkdirSync11,
5312
+ existsSync as existsSync25,
5313
+ mkdirSync as mkdirSync12,
5516
5314
  statSync as statSync5,
5517
- writeFileSync as writeFileSync9
5315
+ writeFileSync as writeFileSync10
5518
5316
  } from "fs";
5519
5317
  import { mkdir } from "fs/promises";
5520
- import { basename as basename8, delimiter as delimiter2, resolve as resolve25 } from "path";
5318
+ import { basename as basename8, delimiter as delimiter2, resolve as resolve26 } from "path";
5521
5319
 
5522
5320
  // 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";
5321
+ import { existsSync as existsSync24, readFileSync as readFileSync12, rmSync as rmSync9 } from "fs";
5322
+ import { resolve as resolve25 } from "path";
5525
5323
  var generatedCredentialFiles = new Set;
5526
5324
  var credentialCleanupRegistered = false;
5527
5325
  function resolveMonorepoRoot3(projectRoot) {
@@ -5545,7 +5343,7 @@ function resolveHostGitBinary() {
5545
5343
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
5546
5344
  continue;
5547
5345
  }
5548
- if (existsSync23(candidate)) {
5346
+ if (existsSync24(candidate)) {
5549
5347
  return candidate;
5550
5348
  }
5551
5349
  }
@@ -5611,7 +5409,7 @@ async function refreshRemoteBranch(repoRoot, remote, branch) {
5611
5409
  }
5612
5410
  }
5613
5411
  async function tryReadGitHead(repoRoot) {
5614
- if (!existsSync23(resolve24(repoRoot, ".git"))) {
5412
+ if (!existsSync24(resolve25(repoRoot, ".git"))) {
5615
5413
  return;
5616
5414
  }
5617
5415
  const result = await runGitCommand(repoRoot, ["rev-parse", "HEAD"]);
@@ -5622,7 +5420,7 @@ async function tryReadGitHead(repoRoot) {
5622
5420
  return value || undefined;
5623
5421
  }
5624
5422
  async function captureRepoDirtyFiles(repoRoot) {
5625
- if (!existsSync23(resolve24(repoRoot, ".git"))) {
5423
+ if (!existsSync24(resolve25(repoRoot, ".git"))) {
5626
5424
  return [];
5627
5425
  }
5628
5426
  const files = new Set;
@@ -5658,7 +5456,7 @@ function registerCredentialCleanup(path) {
5658
5456
  const cleanup = () => {
5659
5457
  for (const filePath of generatedCredentialFiles) {
5660
5458
  try {
5661
- rmSync8(filePath, { force: true });
5459
+ rmSync9(filePath, { force: true });
5662
5460
  } catch {}
5663
5461
  }
5664
5462
  generatedCredentialFiles.clear();
@@ -5710,20 +5508,23 @@ function hashProjectPath(workspaceDir) {
5710
5508
  }
5711
5509
  function resolveGithubCliBinaryPath() {
5712
5510
  const explicit = process.env.RIG_GH_BIN?.trim();
5713
- if (explicit && existsSync23(explicit)) {
5511
+ if (explicit && existsSync24(explicit) && !isRuntimeGatewayGhPath(explicit)) {
5714
5512
  return explicit;
5715
5513
  }
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)) {
5514
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
5515
+ if (existsSync24(candidate)) {
5722
5516
  return candidate;
5723
5517
  }
5724
5518
  }
5519
+ const bunResolved = Bun.which("gh");
5520
+ if (bunResolved && existsSync24(bunResolved) && !isRuntimeGatewayGhPath(bunResolved)) {
5521
+ return bunResolved;
5522
+ }
5725
5523
  return "";
5726
5524
  }
5525
+ function isRuntimeGatewayGhPath(candidate) {
5526
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
5527
+ }
5727
5528
  async function resolveGithubCliAuthToken(ghBinary = "") {
5728
5529
  const gh = ghBinary || resolveGithubCliBinaryPath();
5729
5530
  if (!gh) {
@@ -5750,17 +5551,17 @@ function resolveSystemCertBundlePath() {
5750
5551
  "/opt/homebrew/etc/openssl@3/cert.pem"
5751
5552
  ];
5752
5553
  for (const candidate of candidates) {
5753
- if (candidate && existsSync23(candidate)) {
5754
- return resolve24(candidate);
5554
+ if (candidate && existsSync24(candidate)) {
5555
+ return resolve25(candidate);
5755
5556
  }
5756
5557
  }
5757
5558
  return "";
5758
5559
  }
5759
5560
  function readKnownHosts(path) {
5760
- if (!existsSync23(path)) {
5561
+ if (!existsSync24(path)) {
5761
5562
  return new Set;
5762
5563
  }
5763
- return new Set(readFileSync11(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
5564
+ return new Set(readFileSync12(path, "utf-8").split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
5764
5565
  }
5765
5566
 
5766
5567
  // packages/runtime/src/control-plane/runtime/isolation/home.ts
@@ -5771,6 +5572,21 @@ var GITHUB_KNOWN_HOSTS = [
5771
5572
  "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
5772
5573
  ].join(`
5773
5574
  `);
5575
+ function resolveControlPlaneSourceRoot(projectRoot) {
5576
+ const candidates = [
5577
+ process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
5578
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
5579
+ resolve26(import.meta.dir, "../../../../.."),
5580
+ projectRoot
5581
+ ].filter((value) => Boolean(value));
5582
+ for (const candidate of candidates) {
5583
+ const root = resolve26(candidate);
5584
+ if (existsSync25(resolve26(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts"))) {
5585
+ return root;
5586
+ }
5587
+ }
5588
+ return "";
5589
+ }
5774
5590
  async function runtimeEnv(projectRoot, runtime) {
5775
5591
  const bunBinaryPath = resolveBunBinaryPath();
5776
5592
  const bunDir = resolveBunInstallDir(bunBinaryPath);
@@ -5785,7 +5601,7 @@ async function runtimeEnv(projectRoot, runtime) {
5785
5601
  try {
5786
5602
  return resolveClaudeInstallDir();
5787
5603
  } catch {
5788
- return resolve25(claudeBinaryPath, "..");
5604
+ return resolve26(claudeBinaryPath, "..");
5789
5605
  }
5790
5606
  })() : "";
5791
5607
  const nodeDir = resolveNodeInstallDir();
@@ -5800,8 +5616,8 @@ async function runtimeEnv(projectRoot, runtime) {
5800
5616
  `${bunDir}/bin`,
5801
5617
  claudeDir,
5802
5618
  nodeDir ? `${nodeDir}/bin` : "",
5803
- realHome ? resolve25(realHome, ".local/bin") : "",
5804
- realHome ? resolve25(realHome, ".cargo/bin") : "",
5619
+ realHome ? resolve26(realHome, ".local/bin") : "",
5620
+ realHome ? resolve26(realHome, ".cargo/bin") : "",
5805
5621
  ...inheritedPath,
5806
5622
  "/usr/local/bin",
5807
5623
  "/usr/local/sbin",
@@ -5812,18 +5628,22 @@ async function runtimeEnv(projectRoot, runtime) {
5812
5628
  "/usr/sbin",
5813
5629
  "/sbin"
5814
5630
  ].filter(Boolean);
5815
- const runtimeBash = resolve25(runtime.binDir, "bash");
5816
- const runtimeRigGit = resolve25(runtime.binDir, runtimeRigGitFileName());
5817
- const preferredShell = existsSync24(runtimeBash) ? runtimeBash : "/bin/bash";
5631
+ const runtimeBash = resolve26(runtime.binDir, "bash");
5632
+ const runtimeRigGit = resolve26(runtime.binDir, runtimeRigGitFileName());
5633
+ const preferredShell = existsSync25(runtimeBash) ? runtimeBash : "/bin/bash";
5818
5634
  const nativeRuntimeLibraryPath = await materializeNativeRuntimeLibrary(runtime.binDir);
5635
+ const controlPlaneSourceRoot = resolveControlPlaneSourceRoot(projectRoot);
5819
5636
  const env = {
5820
5637
  PROJECT_RIG_ROOT: projectRoot,
5821
5638
  RIG_HOST_PROJECT_ROOT: projectRoot,
5639
+ ...controlPlaneSourceRoot ? { RIG_CONTROL_PLANE_SOURCE_ROOT: controlPlaneSourceRoot } : {},
5822
5640
  HOME: runtime.homeDir,
5823
5641
  TMPDIR: runtime.tmpDir,
5824
5642
  XDG_CACHE_HOME: runtime.cacheDir,
5825
5643
  XDG_STATE_HOME: runtime.stateDir,
5826
5644
  RIG_AGENT_ID: runtime.id,
5645
+ ...process.env.RIG_RUN_ID?.trim() ? { RIG_RUN_ID: process.env.RIG_RUN_ID.trim() } : {},
5646
+ ...process.env.RIG_SERVER_RUN_ID?.trim() ? { RIG_SERVER_RUN_ID: process.env.RIG_SERVER_RUN_ID.trim() } : {},
5827
5647
  RIG_TASK_ID: runtime.taskId,
5828
5648
  RIG_TASK_RUNTIME_ID: runtime.id,
5829
5649
  RIG_TASK_WORKSPACE: runtime.workspaceDir,
@@ -5831,30 +5651,30 @@ async function runtimeEnv(projectRoot, runtime) {
5831
5651
  RIG_RUNTIME_MODE: runtime.mode,
5832
5652
  RIG_RUNTIME_HOME: runtime.rootDir,
5833
5653
  RIG_RUNTIME_BIN_DIR: runtime.binDir,
5834
- ...existsSync24(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
5654
+ ...existsSync25(runtimeRigGit) ? { RIG_NATIVE_GIT_BIN: runtimeRigGit } : {},
5835
5655
  RIG_BUN_PATH: bunBinaryPath,
5836
5656
  ...claudeBinaryPath ? { RIG_CLAUDE_PATH: claudeBinaryPath } : {},
5837
- RIG_AGENT_BIN: resolve25(runtime.binDir, "rig-agent"),
5657
+ RIG_AGENT_BIN: resolve26(runtime.binDir, "rig-agent"),
5838
5658
  RIG_HOOKS_ACTIVE: "1",
5839
5659
  RIG_AUTO_PR_ON_COMPLETE: "1",
5840
- RIG_POLICY_FILE: resolve25(projectRoot, "rig/policy/policy.json"),
5660
+ RIG_POLICY_FILE: resolve26(projectRoot, "rig/policy/policy.json"),
5841
5661
  RIG_STATE_DIR: runtime.stateDir,
5842
5662
  RIG_LOGS_DIR: runtime.logsDir,
5843
- RIG_SESSION_FILE: resolve25(runtime.sessionDir, "session.json"),
5663
+ RIG_SESSION_FILE: resolve26(runtime.sessionDir, "session.json"),
5844
5664
  MONOREPO_ROOT: runtime.workspaceDir,
5845
5665
  MONOREPO_MAIN_ROOT: monorepoMainRoot,
5846
- TS_API_TESTS_DIR: resolve25(runtime.workspaceDir, "TSAPITests"),
5666
+ TS_API_TESTS_DIR: resolve26(runtime.workspaceDir, "TSAPITests"),
5847
5667
  BASH: preferredShell,
5848
5668
  SHELL: preferredShell,
5849
5669
  PATH: [...new Set(pathEntries)].join(delimiter2),
5850
5670
  LANG: process.env.LANG ?? "en_US.UTF-8",
5851
5671
  TERM: process.env.TERM ?? "xterm-256color",
5852
5672
  PYTHONDONTWRITEBYTECODE: "1",
5853
- PYTHONPYCACHEPREFIX: resolve25(runtime.cacheDir, "python"),
5673
+ PYTHONPYCACHEPREFIX: resolve26(runtime.cacheDir, "python"),
5854
5674
  ...process.env.RIG_PR_BASE_PROJECT && { RIG_PR_BASE_PROJECT: process.env.RIG_PR_BASE_PROJECT },
5855
5675
  ...process.env.RIG_PR_BASE_MONOREPO && { RIG_PR_BASE_MONOREPO: process.env.RIG_PR_BASE_MONOREPO },
5856
5676
  CLAUDE_HOME: runtime.claudeHomeDir,
5857
- PI_CODING_AGENT_DIR: resolve25(runtime.homeDir, ".pi", "agent"),
5677
+ PI_CODING_AGENT_DIR: resolve26(runtime.homeDir, ".pi", "agent"),
5858
5678
  [RUNTIME_CONTEXT_ENV]: runtime.contextFile,
5859
5679
  ...nativeRuntimeLibraryPath ? { RIG_NATIVE_RUNTIME_LIB: nativeRuntimeLibraryPath } : {},
5860
5680
  ...hostGhBinary ? { RIG_GH_BIN: hostGhBinary } : {},
@@ -5865,16 +5685,16 @@ async function runtimeEnv(projectRoot, runtime) {
5865
5685
  NODE_EXTRA_CA_CERTS: runtimeCertBundlePath
5866
5686
  } : {}
5867
5687
  };
5868
- const knownHostsPath = resolve25(runtime.homeDir, ".ssh", "known_hosts");
5869
- if (existsSync24(knownHostsPath)) {
5870
- const agentSshKey = resolve25(runtime.homeDir, ".ssh", "rig-agent-key");
5688
+ const knownHostsPath = resolve26(runtime.homeDir, ".ssh", "known_hosts");
5689
+ if (existsSync25(knownHostsPath)) {
5690
+ const agentSshKey = resolve26(runtime.homeDir, ".ssh", "rig-agent-key");
5871
5691
  const sshParts = [
5872
5692
  "ssh",
5873
5693
  `-o UserKnownHostsFile="${knownHostsPath}"`,
5874
5694
  "-o StrictHostKeyChecking=yes",
5875
5695
  "-F /dev/null"
5876
5696
  ];
5877
- if (existsSync24(agentSshKey)) {
5697
+ if (existsSync25(agentSshKey)) {
5878
5698
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
5879
5699
  }
5880
5700
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -5911,7 +5731,7 @@ async function runtimeEnv(projectRoot, runtime) {
5911
5731
  if (!env.GREPTILE_GITHUB_TOKEN && env.GITHUB_TOKEN) {
5912
5732
  env.GREPTILE_GITHUB_TOKEN = env.GITHUB_TOKEN;
5913
5733
  }
5914
- if (existsSync24(runtime.contextFile)) {
5734
+ if (existsSync25(runtime.contextFile)) {
5915
5735
  const runtimeContext = loadRuntimeContext(runtime.contextFile);
5916
5736
  Object.assign(env, runtimeMemoryEnvFromContext(runtimeContext));
5917
5737
  Object.assign(env, browserEnvFromContext(runtimeContext.browser));
@@ -5925,30 +5745,30 @@ async function provisionRuntimeHome(runtime, options = {}) {
5925
5745
  await mkdir(runtime.cacheDir, { recursive: true });
5926
5746
  await provisionAgentSshKey(runtime.homeDir);
5927
5747
  if (options.provider === "codex") {
5928
- const hasCodexAuth = await injectCodexAuth(resolve25(runtime.homeDir, ".codex"));
5748
+ const hasCodexAuth = await injectCodexAuth(resolve26(runtime.homeDir, ".codex"));
5929
5749
  if (!hasCodexAuth) {
5930
5750
  console.warn("[rig] No Codex auth.json found for isolated runtime. " + "Run `codex login` in your host shell, then retry the agent run.");
5931
5751
  }
5932
5752
  }
5933
5753
  if (options.provider === "pi") {
5934
- const hasPiAuth = await injectPiAgentConfig(resolve25(runtime.homeDir, ".pi", "agent"));
5754
+ const hasPiAuth = await injectPiAgentConfig(resolve26(runtime.homeDir, ".pi", "agent"));
5935
5755
  if (!hasPiAuth) {
5936
5756
  console.warn("[rig] No Pi auth.json found for isolated runtime. " + "Run `pi /login` in your host shell, then retry the agent run.");
5937
5757
  }
5938
5758
  }
5939
5759
  }
5940
5760
  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;
5761
+ mkdirSync12(config.claudeHomeDir, { recursive: true });
5762
+ const workspaceSettings = resolve26(config.workspaceDir, ".claude/settings.json");
5763
+ const hostSettings = resolve26(config.hostProjectRoot, ".claude/settings.json");
5764
+ const projectSettings = existsSync25(workspaceSettings) ? workspaceSettings : hostSettings;
5945
5765
  const runtimeSettings = await loadRuntimeClaudeSettings(projectSettings);
5946
- if (existsSync24(projectSettings)) {
5947
- writeFileSync9(resolve25(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
5766
+ if (existsSync25(projectSettings)) {
5767
+ writeFileSync10(resolve26(config.claudeHomeDir, "settings.local.json"), `${JSON.stringify(runtimeSettings, null, 2)}
5948
5768
  `, "utf-8");
5949
5769
  }
5950
5770
  writeClaudeProjectSettings(config.claudeHomeDir, config.workspaceDir, runtimeSettings);
5951
- writeFileSync9(resolve25(config.claudeHomeDir, "settings.json"), JSON.stringify({
5771
+ writeFileSync10(resolve26(config.claudeHomeDir, "settings.json"), JSON.stringify({
5952
5772
  permissions: { defaultMode: "bypassPermissions" },
5953
5773
  autoMemoryEnabled: false
5954
5774
  }, null, 2));
@@ -5956,12 +5776,12 @@ async function provisionClaudeHome(config) {
5956
5776
  if (!hasCredentials) {
5957
5777
  console.warn("[rig] No Claude credentials found for isolated runtime. " + "Run `claude /login` in your host shell, then retry the agent run.");
5958
5778
  }
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"));
5779
+ const realClaudeHome = resolve26(process.env.HOME ?? "", ".claude");
5780
+ if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "CLAUDE.md"))) {
5781
+ cpSync2(resolve26(realClaudeHome, "CLAUDE.md"), resolve26(config.claudeHomeDir, "CLAUDE.md"));
5962
5782
  }
5963
- if (process.env.HOME && existsSync24(resolve25(realClaudeHome, "agents"))) {
5964
- cpSync2(resolve25(realClaudeHome, "agents"), resolve25(config.claudeHomeDir, "agents"), { recursive: true });
5783
+ if (process.env.HOME && existsSync25(resolve26(realClaudeHome, "agents"))) {
5784
+ cpSync2(resolve26(realClaudeHome, "agents"), resolve26(config.claudeHomeDir, "agents"), { recursive: true });
5965
5785
  }
5966
5786
  if (process.platform === "darwin" && process.env.HOME) {
5967
5787
  writeClaudeProjectSettings(realClaudeHome, config.workspaceDir, runtimeSettings);
@@ -5972,10 +5792,10 @@ async function materializeRuntimeCertBundle(runtime) {
5972
5792
  if (!sourcePath) {
5973
5793
  return "";
5974
5794
  }
5975
- const certsDir = resolve25(runtime.rootDir, "certs");
5976
- const targetPath = resolve25(certsDir, "ca-certificates.pem");
5795
+ const certsDir = resolve26(runtime.rootDir, "certs");
5796
+ const targetPath = resolve26(certsDir, "ca-certificates.pem");
5977
5797
  await mkdir(certsDir, { recursive: true });
5978
- let shouldCopy = !existsSync24(targetPath);
5798
+ let shouldCopy = !existsSync25(targetPath);
5979
5799
  if (!shouldCopy) {
5980
5800
  try {
5981
5801
  shouldCopy = statSync5(sourcePath).mtimeMs > statSync5(targetPath).mtimeMs;
@@ -5997,7 +5817,7 @@ function applyGitHubCredentialHelperEnv(env) {
5997
5817
  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
5818
  }
5999
5819
  function persistRuntimeSecrets(runtimeRoot, env) {
6000
- const secretsPath = resolve25(runtimeRoot, "runtime-secrets.json");
5820
+ const secretsPath = resolve26(runtimeRoot, "runtime-secrets.json");
6001
5821
  const persisted = {};
6002
5822
  for (const key of [
6003
5823
  "GITHUB_TOKEN",
@@ -6016,12 +5836,12 @@ function persistRuntimeSecrets(runtimeRoot, env) {
6016
5836
  if (Object.keys(persisted).length === 0) {
6017
5837
  return;
6018
5838
  }
6019
- writeFileSync9(secretsPath, `${JSON.stringify(persisted, null, 2)}
5839
+ writeFileSync10(secretsPath, `${JSON.stringify(persisted, null, 2)}
6020
5840
  `, "utf-8");
6021
5841
  }
6022
5842
  async function provisionAgentSshKey(homeDir) {
6023
- const sshDir = resolve25(homeDir, ".ssh");
6024
- if (!existsSync24(sshDir)) {
5843
+ const sshDir = resolve26(homeDir, ".ssh");
5844
+ if (!existsSync25(sshDir)) {
6025
5845
  await mkdir(sshDir, { recursive: true });
6026
5846
  }
6027
5847
  seedKnownHosts(sshDir);
@@ -6029,27 +5849,27 @@ async function provisionAgentSshKey(homeDir) {
6029
5849
  const privateKey = decodeProvisionedSshKey(secrets.GITHUB_SSH_KEY);
6030
5850
  if (!privateKey) {
6031
5851
  const hostKeyPath = resolveHostSshKeyPath(process.env.HOME ?? "");
6032
- if (!process.env.HOME || !existsSync24(hostKeyPath)) {
5852
+ if (!process.env.HOME || !existsSync25(hostKeyPath)) {
6033
5853
  return;
6034
5854
  }
6035
- const agentKeyPath2 = resolve25(sshDir, "rig-agent-key");
6036
- if (!existsSync24(agentKeyPath2)) {
5855
+ const agentKeyPath2 = resolve26(sshDir, "rig-agent-key");
5856
+ if (!existsSync25(agentKeyPath2)) {
6037
5857
  copyFileSync5(hostKeyPath, agentKeyPath2);
6038
5858
  chmodSync5(agentKeyPath2, 384);
6039
5859
  }
6040
5860
  const hostPubPath = `${hostKeyPath}.pub`;
6041
- if (existsSync24(hostPubPath)) {
5861
+ if (existsSync25(hostPubPath)) {
6042
5862
  const agentPubPath = `${agentKeyPath2}.pub`;
6043
- if (!existsSync24(agentPubPath)) {
5863
+ if (!existsSync25(agentPubPath)) {
6044
5864
  copyFileSync5(hostPubPath, agentPubPath);
6045
5865
  }
6046
5866
  }
6047
5867
  writeSshConfig(sshDir, agentKeyPath2);
6048
5868
  return;
6049
5869
  }
6050
- const agentKeyPath = resolve25(sshDir, "rig-agent-key");
6051
- if (!existsSync24(agentKeyPath)) {
6052
- writeFileSync9(agentKeyPath, privateKey, { mode: 384 });
5870
+ const agentKeyPath = resolve26(sshDir, "rig-agent-key");
5871
+ if (!existsSync25(agentKeyPath)) {
5872
+ writeFileSync10(agentKeyPath, privateKey, { mode: 384 });
6053
5873
  }
6054
5874
  writeSshConfig(sshDir, agentKeyPath);
6055
5875
  }
@@ -6066,21 +5886,21 @@ function decodeProvisionedSshKey(encodedKey) {
6066
5886
  `;
6067
5887
  }
6068
5888
  function resolveHostSshKeyPath(homeDir) {
6069
- const sshDir = resolve25(homeDir, ".ssh");
5889
+ const sshDir = resolve26(homeDir, ".ssh");
6070
5890
  const candidates = [
6071
5891
  "rig-agent-key",
6072
5892
  "id_ed25519",
6073
5893
  "id_ecdsa",
6074
5894
  "id_rsa"
6075
- ].map((name) => resolve25(sshDir, name));
6076
- return candidates.find((candidate) => existsSync24(candidate)) ?? resolve25(sshDir, "rig-agent-key");
5895
+ ].map((name) => resolve26(sshDir, name));
5896
+ return candidates.find((candidate) => existsSync25(candidate)) ?? resolve26(sshDir, "rig-agent-key");
6077
5897
  }
6078
5898
  function writeSshConfig(sshDir, keyPath) {
6079
- const configPath = resolve25(sshDir, "config");
6080
- if (existsSync24(configPath)) {
5899
+ const configPath = resolve26(sshDir, "config");
5900
+ if (existsSync25(configPath)) {
6081
5901
  return;
6082
5902
  }
6083
- const knownHostsPath = resolve25(sshDir, "known_hosts");
5903
+ const knownHostsPath = resolve26(sshDir, "known_hosts");
6084
5904
  const config = [
6085
5905
  "Host github.com",
6086
5906
  ` IdentityFile ${keyPath}`,
@@ -6090,10 +5910,10 @@ function writeSshConfig(sshDir, keyPath) {
6090
5910
  ""
6091
5911
  ].join(`
6092
5912
  `);
6093
- writeFileSync9(configPath, config, { mode: 420 });
5913
+ writeFileSync10(configPath, config, { mode: 420 });
6094
5914
  }
6095
5915
  function seedKnownHosts(sshDir) {
6096
- const knownHostsPath = resolve25(sshDir, "known_hosts");
5916
+ const knownHostsPath = resolve26(sshDir, "known_hosts");
6097
5917
  const existingLines = readKnownHosts(knownHostsPath);
6098
5918
  const requiredLines = GITHUB_KNOWN_HOSTS.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
6099
5919
  const missing = requiredLines.filter((line) => !existingLines.has(line));
@@ -6104,23 +5924,23 @@ function seedKnownHosts(sshDir) {
6104
5924
  for (const line of missing) {
6105
5925
  existingLines.add(line);
6106
5926
  }
6107
- writeFileSync9(knownHostsPath, `${Array.from(existingLines).join(`
5927
+ writeFileSync10(knownHostsPath, `${Array.from(existingLines).join(`
6108
5928
  `)}
6109
5929
  `, { mode: 420 });
6110
5930
  } catch (err) {
6111
- const hint = existsSync24(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
5931
+ const hint = existsSync25(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
6112
5932
  console.warn(`[rig] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
6113
5933
  }
6114
5934
  }
6115
5935
  function writeClaudeProjectSettings(claudeHomeDir, workspaceDir, runtimeSettings) {
6116
5936
  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)}
5937
+ const projectDir = resolve26(claudeHomeDir, "projects", projectHash);
5938
+ mkdirSync12(projectDir, { recursive: true });
5939
+ writeFileSync10(resolve26(projectDir, "settings.json"), `${JSON.stringify(runtimeSettings, null, 2)}
6120
5940
  `, "utf-8");
6121
5941
  }
6122
5942
  async function loadRuntimeClaudeSettings(projectSettingsPath) {
6123
- if (!existsSync24(projectSettingsPath)) {
5943
+ if (!existsSync25(projectSettingsPath)) {
6124
5944
  return {};
6125
5945
  }
6126
5946
  let parsed;
@@ -6166,7 +5986,7 @@ async function loadRuntimeClaudeSettings(projectSettingsPath) {
6166
5986
  return clone;
6167
5987
  }
6168
5988
  async function injectClaudeCredentials(claudeHomeDir, options = {}) {
6169
- const credentialsPath = resolve25(claudeHomeDir, ".credentials.json");
5989
+ const credentialsPath = resolve26(claudeHomeDir, ".credentials.json");
6170
5990
  const platform = options.platform ?? process.platform;
6171
5991
  if (platform === "darwin") {
6172
5992
  const raw = options.loadKeychainCredentials ? await options.loadKeychainCredentials() : await (async () => {
@@ -6176,16 +5996,16 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
6176
5996
  if (raw) {
6177
5997
  try {
6178
5998
  JSON.parse(raw);
6179
- writeFileSync9(credentialsPath, raw, { mode: 384 });
5999
+ writeFileSync10(credentialsPath, raw, { mode: 384 });
6180
6000
  registerCredentialCleanup(credentialsPath);
6181
6001
  return true;
6182
6002
  } catch {}
6183
6003
  }
6184
6004
  }
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") : "";
6005
+ 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
6006
  if (hostClaudeHome) {
6187
- const realCredentials = resolve25(hostClaudeHome, ".credentials.json");
6188
- if (existsSync24(realCredentials)) {
6007
+ const realCredentials = resolve26(hostClaudeHome, ".credentials.json");
6008
+ if (existsSync25(realCredentials)) {
6189
6009
  cpSync2(realCredentials, credentialsPath);
6190
6010
  return true;
6191
6011
  }
@@ -6193,36 +6013,36 @@ async function injectClaudeCredentials(claudeHomeDir, options = {}) {
6193
6013
  return false;
6194
6014
  }
6195
6015
  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") : "";
6016
+ mkdirSync12(codexHomeDir, { recursive: true });
6017
+ const hostCodexHome = process.env.CODEX_HOME?.trim() ? resolve26(process.env.CODEX_HOME) : process.env.HOME ? resolve26(process.env.HOME, ".codex") : "";
6198
6018
  if (!hostCodexHome) {
6199
6019
  return false;
6200
6020
  }
6201
- const hostAuthPath = resolve25(hostCodexHome, "auth.json");
6202
- if (!existsSync24(hostAuthPath)) {
6021
+ const hostAuthPath = resolve26(hostCodexHome, "auth.json");
6022
+ if (!existsSync25(hostAuthPath)) {
6203
6023
  return false;
6204
6024
  }
6205
- const runtimeAuthPath = resolve25(codexHomeDir, "auth.json");
6025
+ const runtimeAuthPath = resolve26(codexHomeDir, "auth.json");
6206
6026
  copyFileSync5(hostAuthPath, runtimeAuthPath);
6207
6027
  chmodSync5(runtimeAuthPath, 384);
6208
6028
  return true;
6209
6029
  }
6210
6030
  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") : "";
6031
+ mkdirSync12(piAgentDir, { recursive: true });
6032
+ 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
6033
  if (!hostPiAgentDir) {
6214
6034
  return false;
6215
6035
  }
6216
- const hostAuthPath = resolve25(hostPiAgentDir, "auth.json");
6217
- if (!existsSync24(hostAuthPath)) {
6036
+ const hostAuthPath = resolve26(hostPiAgentDir, "auth.json");
6037
+ if (!existsSync25(hostAuthPath)) {
6218
6038
  return false;
6219
6039
  }
6220
- const runtimeAuthPath = resolve25(piAgentDir, "auth.json");
6040
+ const runtimeAuthPath = resolve26(piAgentDir, "auth.json");
6221
6041
  copyFileSync5(hostAuthPath, runtimeAuthPath);
6222
6042
  chmodSync5(runtimeAuthPath, 384);
6223
- const hostSettingsPath = resolve25(hostPiAgentDir, "settings.json");
6224
- if (existsSync24(hostSettingsPath)) {
6225
- const runtimeSettingsPath = resolve25(piAgentDir, "settings.json");
6043
+ const hostSettingsPath = resolve26(hostPiAgentDir, "settings.json");
6044
+ if (existsSync25(hostSettingsPath)) {
6045
+ const runtimeSettingsPath = resolve26(piAgentDir, "settings.json");
6226
6046
  copyFileSync5(hostSettingsPath, runtimeSettingsPath);
6227
6047
  chmodSync5(runtimeSettingsPath, 384);
6228
6048
  }
@@ -6230,8 +6050,8 @@ async function injectPiAgentConfig(piAgentDir) {
6230
6050
  }
6231
6051
 
6232
6052
  // 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";
6053
+ import { existsSync as existsSync26, mkdirSync as mkdirSync13, statSync as statSync6, writeFileSync as writeFileSync11 } from "fs";
6054
+ import { resolve as resolve27 } from "path";
6235
6055
  var CLAUDE_ROUTER_SERVER_NAME = "rig_runtime_tools";
6236
6056
  var CLAUDE_DISABLED_FILE_TOOLS = [
6237
6057
  "Read",
@@ -6329,7 +6149,7 @@ function claudeRuntimeToolCliArgs(configPath) {
6329
6149
  function buildRuntimeToolRouterServerConfig(options) {
6330
6150
  return {
6331
6151
  type: "stdio",
6332
- command: resolve26(options.binDir, "rig-tool-router"),
6152
+ command: resolve27(options.binDir, "rig-tool-router"),
6333
6153
  args: [],
6334
6154
  env: {
6335
6155
  RIG_RUNTIME_CONTEXT_FILE: options.contextFile,
@@ -6363,14 +6183,14 @@ function codexRuntimeToolCliArgs(options) {
6363
6183
  ];
6364
6184
  }
6365
6185
  function writeClaudeRuntimeToolRouterConfig(options) {
6366
- const configPath = resolve26(options.stateDir, "claude-runtime-tools.mcp.json");
6367
- mkdirSync12(options.stateDir, { recursive: true });
6186
+ const configPath = resolve27(options.stateDir, "claude-runtime-tools.mcp.json");
6187
+ mkdirSync13(options.stateDir, { recursive: true });
6368
6188
  const payload = {
6369
6189
  mcpServers: {
6370
6190
  [CLAUDE_ROUTER_SERVER_NAME]: buildRuntimeToolRouterServerConfig(options)
6371
6191
  }
6372
6192
  };
6373
- writeFileSync10(configPath, `${JSON.stringify(payload, null, 2)}
6193
+ writeFileSync11(configPath, `${JSON.stringify(payload, null, 2)}
6374
6194
  `, "utf-8");
6375
6195
  return configPath;
6376
6196
  }
@@ -6457,7 +6277,7 @@ function resolveRuntimeToolBinary(toolName, env) {
6457
6277
  grep: "rig-grep"
6458
6278
  };
6459
6279
  const executable = mapping[toolName];
6460
- return executable ? resolve26(binDir, executable) : "";
6280
+ return executable ? resolve27(binDir, executable) : "";
6461
6281
  }
6462
6282
  function renderToolText(toolName, payload) {
6463
6283
  if (toolName === "shell") {
@@ -6522,10 +6342,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
6522
6342
  isError: true
6523
6343
  };
6524
6344
  }
6525
- const workspaceRoot = resolve26(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
6345
+ const workspaceRoot = resolve27(invocationEnv.RIG_TASK_WORKSPACE?.trim() || process.cwd());
6526
6346
  const requestedWorkdir = typeof args.workdir === "string" ? args.workdir.trim() : "";
6527
6347
  const workdir = requestedWorkdir ? resolveWithinWorkspace(workspaceRoot, requestedWorkdir) : workspaceRoot;
6528
- if (!existsSync25(workdir)) {
6348
+ if (!existsSync26(workdir)) {
6529
6349
  return {
6530
6350
  content: [{
6531
6351
  type: "text",
@@ -6592,10 +6412,10 @@ async function invokeRuntimeShellTool(args, options = {}) {
6592
6412
  }
6593
6413
  function resolveRuntimeShellBinary(shellName, env) {
6594
6414
  const binDir = env.RIG_RUNTIME_BIN_DIR?.trim() || "";
6595
- return binDir ? resolve26(binDir, shellName) : "";
6415
+ return binDir ? resolve27(binDir, shellName) : "";
6596
6416
  }
6597
6417
  function resolveWithinWorkspace(workspaceRoot, target) {
6598
- const resolvedTarget = resolve26(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
6418
+ const resolvedTarget = resolve27(workspaceRoot, normalizeWorkspaceRelativeTarget(target));
6599
6419
  const normalizedWorkspace = workspaceRoot.endsWith("/") ? workspaceRoot : `${workspaceRoot}/`;
6600
6420
  const normalizedTarget = resolvedTarget.endsWith("/") ? resolvedTarget : `${resolvedTarget}/`;
6601
6421
  if (resolvedTarget === workspaceRoot || normalizedTarget.startsWith(normalizedWorkspace)) {
@@ -6633,8 +6453,8 @@ if (false) {}
6633
6453
  init_layout();
6634
6454
 
6635
6455
  // 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";
6456
+ import { existsSync as existsSync27, mkdirSync as mkdirSync14, rmSync as rmSync10 } from "fs";
6457
+ import { dirname as dirname11, resolve as resolve28 } from "path";
6638
6458
  async function resolveMonorepoBaseRef(monorepoRoot) {
6639
6459
  const explicit = process.env.RIG_RUNTIME_BASE_REF?.trim();
6640
6460
  if (explicit) {
@@ -6670,12 +6490,12 @@ function ensureProvisioningHostProjectRootEnv(projectRoot) {
6670
6490
  }
6671
6491
  async function provisionRuntimeWorktree(config) {
6672
6492
  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 });
6493
+ let hasValidWorktree = existsSync27(resolve28(config.workspaceDir, ".git")) && (await runGitCommand(config.workspaceDir, ["rev-parse", "--show-toplevel"])).exitCode === 0;
6494
+ if (existsSync27(config.workspaceDir) && !hasValidWorktree) {
6495
+ rmSync10(config.workspaceDir, { recursive: true, force: true });
6676
6496
  }
6677
6497
  if (!hasValidWorktree) {
6678
- mkdirSync13(dirname11(config.workspaceDir), { recursive: true });
6498
+ mkdirSync14(dirname11(config.workspaceDir), { recursive: true });
6679
6499
  const branchExists = await runGitCommand(config.monorepoRoot, ["show-ref", "--verify", "--quiet", `refs/heads/${branch}`]);
6680
6500
  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
6501
  if (add.exitCode !== 0) {
@@ -6851,31 +6671,31 @@ async function preferredBaseRemotes(repoRoot) {
6851
6671
 
6852
6672
  // packages/runtime/src/control-plane/runtime/isolation/toolchain.ts
6853
6673
  import {
6854
- existsSync as existsSync28,
6674
+ existsSync as existsSync29,
6855
6675
  lstatSync,
6856
- mkdirSync as mkdirSync15,
6857
- readdirSync as readdirSync5,
6858
- readFileSync as readFileSync13,
6859
- rmSync as rmSync10,
6676
+ mkdirSync as mkdirSync16,
6677
+ readdirSync as readdirSync6,
6678
+ readFileSync as readFileSync14,
6679
+ rmSync as rmSync11,
6860
6680
  statSync as statSync8,
6861
6681
  symlinkSync as symlinkSync4
6862
6682
  } from "fs";
6863
6683
  import { mkdir as mkdir2, writeFile } from "fs/promises";
6864
- import { dirname as dirname13, resolve as resolve29 } from "path";
6684
+ import { dirname as dirname13, resolve as resolve30 } from "path";
6865
6685
 
6866
6686
  // 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";
6687
+ import { chmodSync as chmodSync6, copyFileSync as copyFileSync6, existsSync as existsSync28, mkdirSync as mkdirSync15, statSync as statSync7 } from "fs";
6868
6688
  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" : ""}`);
6689
+ import { dirname as dirname12, resolve as resolve29 } from "path";
6690
+ var sharedRouterOutputDir = resolve29(tmpdir6(), "rig-native");
6691
+ var sharedRouterOutputPath = resolve29(sharedRouterOutputDir, `rig-tool-router-${process.platform}-${process.arch}${process.platform === "win32" ? ".exe" : ""}`);
6872
6692
  function runtimeClaudeToolRouterFileName() {
6873
6693
  return `rig-tool-router${process.platform === "win32" ? ".exe" : ""}`;
6874
6694
  }
6875
6695
  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;
6696
+ const sourcePath = resolve29(projectRoot, "packages/runtime/src/control-plane/runtime/tooling/claude-router.ts");
6697
+ mkdirSync15(dirname12(outputPath), { recursive: true });
6698
+ const needsBuild = !existsSync28(outputPath) || statSync7(sourcePath).mtimeMs > statSync7(outputPath).mtimeMs;
6879
6699
  if (!needsBuild) {
6880
6700
  return outputPath;
6881
6701
  }
@@ -6889,9 +6709,9 @@ async function ensureClaudeToolRouterBinaryPath(projectRoot, outputPath = shared
6889
6709
  }
6890
6710
  async function materializeClaudeToolRouterBinary(projectRoot, targetDir) {
6891
6711
  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;
6712
+ const targetPath = resolve29(targetDir, runtimeClaudeToolRouterFileName());
6713
+ mkdirSync15(targetDir, { recursive: true });
6714
+ const needsCopy = !existsSync28(targetPath) || statSync7(sourcePath).mtimeMs > statSync7(targetPath).mtimeMs;
6895
6715
  if (needsCopy) {
6896
6716
  copyFileSync6(sourcePath, targetPath);
6897
6717
  chmodSync6(targetPath, 493);
@@ -6904,48 +6724,48 @@ var GIT_INDEX_LOCK_RETRY_DELAY_MS = 250;
6904
6724
  var GIT_INDEX_LOCK_STALE_AFTER_MS = 5000;
6905
6725
  function resolveRigSourceRoot(projectRoot) {
6906
6726
  const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
6907
- if (hostProjectRoot && existsSync28(resolve29(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
6727
+ if (hostProjectRoot && existsSync29(resolve30(hostProjectRoot, "packages/runtime/bin/rig-agent.ts"))) {
6908
6728
  return hostProjectRoot;
6909
6729
  }
6910
- const fromModule = resolve29(import.meta.dir, "../../../../../..");
6911
- if (existsSync28(resolve29(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
6730
+ const fromModule = resolve30(import.meta.dir, "../../../../../..");
6731
+ if (existsSync29(resolve30(fromModule, "packages/runtime/bin/rig-agent.ts"))) {
6912
6732
  return fromModule;
6913
6733
  }
6914
6734
  return projectRoot;
6915
6735
  }
6916
6736
  function prepareTrackedRuntimePaths(logsDir, stateDir, sessionDir) {
6917
- for (const path of [logsDir, stateDir, sessionDir, resolve29(sessionDir, "session.json")]) {
6737
+ for (const path of [logsDir, stateDir, sessionDir, resolve30(sessionDir, "session.json")]) {
6918
6738
  removeSymbolicLink(path);
6919
6739
  }
6920
6740
  runtimePrepareTrackedPathsNative({
6921
6741
  logsDir,
6922
6742
  stateDir,
6923
6743
  sessionDir,
6924
- controlledBashLogFile: resolve29(logsDir, "controlled-bash.jsonl"),
6925
- eventsFile: resolve29(logsDir, "control-plane.events.jsonl")
6744
+ controlledBashLogFile: resolve30(logsDir, "controlled-bash.jsonl"),
6745
+ eventsFile: resolve30(logsDir, "control-plane.events.jsonl")
6926
6746
  });
6927
6747
  }
6928
6748
  async function initializeRuntimeStateFiles(stateDir, sessionDir, taskId) {
6929
6749
  await mkdir2(stateDir, { recursive: true });
6930
6750
  await mkdir2(sessionDir, { recursive: true });
6931
- const failedApproachesPath = resolve29(stateDir, "failed_approaches.md");
6932
- if (!existsSync28(failedApproachesPath)) {
6751
+ const failedApproachesPath = resolve30(stateDir, "failed_approaches.md");
6752
+ if (!existsSync29(failedApproachesPath)) {
6933
6753
  await writeFile(failedApproachesPath, `# Failed Approaches
6934
6754
 
6935
6755
  `);
6936
6756
  }
6937
- const hookTripsPath = resolve29(stateDir, "hook_trips.log");
6938
- if (!existsSync28(hookTripsPath)) {
6757
+ const hookTripsPath = resolve30(stateDir, "hook_trips.log");
6758
+ if (!existsSync29(hookTripsPath)) {
6939
6759
  await writeFile(hookTripsPath, "");
6940
6760
  }
6941
- const sessionFile = resolve29(sessionDir, "session.json");
6761
+ const sessionFile = resolve30(sessionDir, "session.json");
6942
6762
  if (taskId) {
6943
6763
  await writeFile(sessionFile, JSON.stringify({ activeTaskIds: [taskId] }));
6944
6764
  }
6945
6765
  }
6946
6766
  async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
6947
- const artifactDir = resolve29(workspaceDir, "artifacts", taskId);
6948
- const runtimeSnapshotDir = resolve29(artifactDir, "runtime-snapshots");
6767
+ const artifactDir = resolve30(workspaceDir, "artifacts", taskId);
6768
+ const runtimeSnapshotDir = resolve30(artifactDir, "runtime-snapshots");
6949
6769
  let preservedTrackedFiles = false;
6950
6770
  for (const file of [
6951
6771
  "changed-files.txt",
@@ -6961,13 +6781,13 @@ async function resetEphemeralTaskArtifacts(workspaceDir, taskId) {
6961
6781
  preservedTrackedFiles = true;
6962
6782
  continue;
6963
6783
  }
6964
- rmSync10(resolve29(artifactDir, file), { force: true });
6784
+ rmSync11(resolve30(artifactDir, file), { force: true });
6965
6785
  }
6966
6786
  const runtimeSnapshotRelativePath = `artifacts/${taskId}/runtime-snapshots`;
6967
6787
  if (await resetTrackedArtifactPath(workspaceDir, runtimeSnapshotRelativePath)) {
6968
6788
  preservedTrackedFiles = true;
6969
6789
  } else {
6970
- rmSync10(runtimeSnapshotDir, { recursive: true, force: true });
6790
+ rmSync11(runtimeSnapshotDir, { recursive: true, force: true });
6971
6791
  }
6972
6792
  if (preservedTrackedFiles) {
6973
6793
  console.log(`[rig-agent] Preserved tracked runtime artifact files in ${taskId}; skipped ephemeral cleanup for committed paths.`);
@@ -7000,28 +6820,28 @@ async function buildRuntimeToolchain(options) {
7000
6820
  throw new Error("Failed to provision the native Zig runtime library.");
7001
6821
  }
7002
6822
  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, {
6823
+ await buildBinary("packages/cli/bin/rig.ts", resolve30(options.binDir, "rig"), rigSourceRoot);
6824
+ await buildBinary("packages/runtime/bin/rig-agent.ts", resolve30(options.binDir, "rig-agent"), rigSourceRoot, {
7005
6825
  ...options.runtimeSecretDefines,
7006
6826
  AGENT_TASK_ID: options.taskId,
7007
6827
  AGENT_PROJECT_ROOT: options.projectRoot,
7008
6828
  AGENT_RUNTIME_ID: options.runtimeId,
7009
6829
  AGENT_SCOPE_HASH: options.bakedScopeHash,
7010
6830
  AGENT_MANIFEST_PATH: options.manifestPath,
7011
- AGENT_BINARY_PATH: resolve29(options.binDir, "rig-agent"),
6831
+ AGENT_BINARY_PATH: resolve30(options.binDir, "rig-agent"),
7012
6832
  AGENT_INFO_OUTPUT: options.bakedInfoOutput,
7013
6833
  AGENT_DEPS_OUTPUT: options.bakedDepsOutput,
7014
6834
  AGENT_STATUS_OUTPUT: options.bakedStatusOutput
7015
6835
  });
7016
- await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve29(options.binDir, "controlled-bash"), rigSourceRoot, {
6836
+ await buildBinary("packages/runtime/src/control-plane/controlled-bash.ts", resolve30(options.binDir, "controlled-bash"), rigSourceRoot, {
7017
6837
  AGENT_PROJECT_ROOT: options.projectRoot,
7018
6838
  AGENT_LOGS_DIR: options.logsDir,
7019
6839
  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")
6840
+ AGENT_TS_API_TESTS_DIR: resolve30(options.workspaceDir, "TSAPITests"),
6841
+ AGENT_RIG_AGENT_BIN: resolve30(options.binDir, "rig-agent")
7022
6842
  });
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, {
6843
+ await buildBinary("packages/runtime/bin/rig-browser-tool.ts", resolve30(options.binDir, runtimeBrowserToolBinaryName()), rigSourceRoot);
6844
+ await buildBinary("packages/runtime/src/control-plane/runtime/snapshot/sidecar.ts", resolve30(options.binDir, "snapshot-sidecar"), rigSourceRoot, {
7025
6845
  AGENT_PROJECT_ROOT: options.projectRoot,
7026
6846
  AGENT_BUN_PATH: resolveBunBinaryPath()
7027
6847
  });
@@ -7030,15 +6850,15 @@ async function buildRuntimeToolchain(options) {
7030
6850
  AGENT_BUN_PATH: resolveBunBinaryPath()
7031
6851
  };
7032
6852
  for (const hookName of hookNames) {
7033
- await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve29(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
6853
+ await buildBinary(`packages/runtime/src/control-plane/hooks/${hookName}.ts`, resolve30(runtimeBins.hooksDir, hookName), rigSourceRoot, hookDefines);
7034
6854
  }
7035
- const pluginsDir = resolve29(options.projectRoot, "rig/plugins");
7036
- if (existsSync28(pluginsDir)) {
7037
- for (const entry of readdirSync5(pluginsDir, { withFileTypes: true })) {
6855
+ const pluginsDir = resolve30(options.projectRoot, "rig/plugins");
6856
+ if (existsSync29(pluginsDir)) {
6857
+ for (const entry of readdirSync6(pluginsDir, { withFileTypes: true })) {
7038
6858
  const match = entry.name.match(/^(.+)\.plugin\.(ts|js|mjs|cjs)$/);
7039
6859
  if (!match)
7040
6860
  continue;
7041
- await buildBinary(`rig/plugins/${entry.name}`, resolve29(runtimeBins.pluginsDir, match[1]), options.projectRoot);
6861
+ await buildBinary(`rig/plugins/${entry.name}`, resolve30(runtimeBins.pluginsDir, match[1]), options.projectRoot);
7042
6862
  }
7043
6863
  }
7044
6864
  await materializeRigGitBinary(options.binDir);
@@ -7048,8 +6868,8 @@ async function buildRuntimeToolchain(options) {
7048
6868
  }
7049
6869
  async function writeRuntimeManifest(config) {
7050
6870
  const scopeHash = sha256Hex(JSON.stringify(config.scopes));
7051
- const binarySha256 = sha256Hex(readFileSync13(config.binaryPath));
7052
- const manifestPath = resolve29(config.runtimeRoot, "manifest.json");
6871
+ const binarySha256 = sha256Hex(readFileSync14(config.binaryPath));
6872
+ const manifestPath = resolve30(config.runtimeRoot, "manifest.json");
7053
6873
  const manifest = {
7054
6874
  runtimeId: config.runtimeId,
7055
6875
  taskId: config.taskId,
@@ -7083,7 +6903,7 @@ function removeSymbolicLink(path) {
7083
6903
  } catch {
7084
6904
  return;
7085
6905
  }
7086
- rmSync10(path, { force: true, recursive: true });
6906
+ rmSync11(path, { force: true, recursive: true });
7087
6907
  }
7088
6908
  async function resetTrackedArtifactPath(workspaceDir, relativePath) {
7089
6909
  const tracked = await runGitLsFiles(workspaceDir, relativePath);
@@ -7109,7 +6929,7 @@ async function restoreTrackedArtifactPathWithRetry(workspaceDir, relativePath, r
7109
6929
  const retryDelayMs = options.retryDelayMs ?? GIT_INDEX_LOCK_RETRY_DELAY_MS;
7110
6930
  const now = options.now ?? Date.now;
7111
6931
  const statMtimeMs = options.statMtimeMs ?? readFileMtimeMs;
7112
- const removeFile = options.removeFile ?? ((path) => rmSync10(path, { force: true }));
6932
+ const removeFile = options.removeFile ?? ((path) => rmSync11(path, { force: true }));
7113
6933
  const log = options.log ?? console.warn;
7114
6934
  let lastOutput = "";
7115
6935
  for (let attempt = 0;attempt <= maxRetries; attempt += 1) {
@@ -7169,31 +6989,31 @@ function readFileMtimeMs(path) {
7169
6989
  }
7170
6990
  function linkRuntimeDependencyLayers(monorepoRoot, workspaceDir) {
7171
6991
  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");
6992
+ const sourceNodeModules = resolve30(monorepoRoot, "humoongate", "node_modules");
6993
+ if (!existsSync29(sourceNodeModules)) {} else {
6994
+ const runtimeHumoongate = resolve30(workspaceDir, "humoongate");
6995
+ if (existsSync29(resolve30(runtimeHumoongate, "package.json"))) {
6996
+ const targetNodeModules = resolve30(runtimeHumoongate, "node_modules");
7177
6997
  runtimeLinkDependencyLayerNative(sourceNodeModules, targetNodeModules);
7178
6998
  }
7179
6999
  }
7180
- const runtimeHpNext = resolve29(workspaceDir, "microservices", "hp-next-frontend", "app");
7181
- if (!existsSync28(resolve29(runtimeHpNext, "package.json"))) {
7000
+ const runtimeHpNext = resolve30(workspaceDir, "microservices", "hp-next-frontend", "app");
7001
+ if (!existsSync29(resolve30(runtimeHpNext, "package.json"))) {
7182
7002
  return;
7183
7003
  }
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)) {
7004
+ const sourceHpNextNodeModules = resolve30(monorepoRoot, "microservices", "hp-next-frontend", "app", "node_modules");
7005
+ const sourceMonorepoNodeModules = resolve30(monorepoRoot, "node_modules");
7006
+ const targetHpNextNodeModules = resolve30(runtimeHpNext, "node_modules");
7007
+ if (existsSync29(sourceHpNextNodeModules)) {
7188
7008
  runtimeLinkDependencyLayerNative(sourceHpNextNodeModules, targetHpNextNodeModules);
7189
7009
  return;
7190
7010
  }
7191
- if (existsSync28(sourceMonorepoNodeModules)) {
7011
+ if (existsSync29(sourceMonorepoNodeModules)) {
7192
7012
  runtimeLinkDependencyLayerNative(sourceMonorepoNodeModules, targetHpNextNodeModules);
7193
7013
  }
7194
7014
  }
7195
7015
  function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
7196
- linkNodeModulesLayer(resolve29(monorepoRoot, "node_modules"), resolve29(workspaceDir, "node_modules"));
7016
+ linkNodeModulesLayer(resolve30(monorepoRoot, "node_modules"), resolve30(workspaceDir, "node_modules"));
7197
7017
  for (const relativePackageDir of [
7198
7018
  "apps/native-app/apps/marketing",
7199
7019
  "apps/native-app/apps/web",
@@ -7215,15 +7035,15 @@ function linkGenericNodeModulesLayers(monorepoRoot, workspaceDir) {
7215
7035
  "packages/standard-plugin",
7216
7036
  "packages/validator-kit"
7217
7037
  ]) {
7218
- const workspacePackageDir = resolve29(workspaceDir, relativePackageDir);
7219
- if (!existsSync28(resolve29(workspacePackageDir, "package.json"))) {
7038
+ const workspacePackageDir = resolve30(workspaceDir, relativePackageDir);
7039
+ if (!existsSync29(resolve30(workspacePackageDir, "package.json"))) {
7220
7040
  continue;
7221
7041
  }
7222
- linkNodeModulesLayer(resolve29(monorepoRoot, relativePackageDir, "node_modules"), resolve29(workspacePackageDir, "node_modules"));
7042
+ linkNodeModulesLayer(resolve30(monorepoRoot, relativePackageDir, "node_modules"), resolve30(workspacePackageDir, "node_modules"));
7223
7043
  }
7224
7044
  }
7225
7045
  function linkNodeModulesLayer(sourceDir, targetDir) {
7226
- if (!existsSync28(sourceDir) || existsSync28(targetDir)) {
7046
+ if (!existsSync29(sourceDir) || existsSync29(targetDir)) {
7227
7047
  return;
7228
7048
  }
7229
7049
  try {
@@ -7232,30 +7052,30 @@ function linkNodeModulesLayer(sourceDir, targetDir) {
7232
7052
  } catch (error) {
7233
7053
  console.warn(`[rig-agent] Native dependency-layer linking failed for ${targetDir}; using symlink fallback: ${error instanceof Error ? error.message : String(error)}`);
7234
7054
  }
7235
- mkdirSync15(dirname13(targetDir), { recursive: true });
7055
+ mkdirSync16(dirname13(targetDir), { recursive: true });
7236
7056
  symlinkSync4(sourceDir, targetDir, "dir");
7237
7057
  }
7238
7058
  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 });
7059
+ const hooksDir = resolve30(runtimeBinDir, "hooks");
7060
+ const pluginsDir = resolve30(runtimeBinDir, "plugins");
7061
+ const validatorsDir = resolve30(runtimeBinDir, "validators");
7062
+ mkdirSync16(hooksDir, { recursive: true });
7063
+ mkdirSync16(pluginsDir, { recursive: true });
7064
+ mkdirSync16(validatorsDir, { recursive: true });
7245
7065
  return { hooksDir, pluginsDir, validatorsDir };
7246
7066
  }
7247
7067
 
7248
7068
  // 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";
7069
+ import { existsSync as existsSync32, rmSync as rmSync12, writeFileSync as writeFileSync13 } from "fs";
7070
+ import { basename as basename9, resolve as resolve34 } from "path";
7251
7071
 
7252
7072
  // packages/runtime/src/control-plane/runtime/sandbox/backend.ts
7253
- import { existsSync as existsSync30 } from "fs";
7073
+ import { existsSync as existsSync31 } from "fs";
7254
7074
 
7255
7075
  // packages/runtime/src/control-plane/runtime/guard.ts
7256
7076
  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";
7077
+ import { existsSync as existsSync30, readFileSync as readFileSync15, statSync as statSync9 } from "fs";
7078
+ import { resolve as resolve31 } from "path";
7259
7079
 
7260
7080
  // packages/runtime/src/control-plane/runtime/guard-types.ts
7261
7081
  var POLICY_VERSION = 1;
@@ -7318,8 +7138,8 @@ function loadPolicy(projectRoot) {
7318
7138
  if (seededPolicyConfig) {
7319
7139
  return seededPolicyConfig;
7320
7140
  }
7321
- const configPath = resolve30(projectRoot, "rig/policy/policy.json");
7322
- if (!existsSync29(configPath)) {
7141
+ const configPath = resolve31(projectRoot, "rig/policy/policy.json");
7142
+ if (!existsSync30(configPath)) {
7323
7143
  return defaultPolicy();
7324
7144
  }
7325
7145
  let mtimeMs;
@@ -7333,7 +7153,7 @@ function loadPolicy(projectRoot) {
7333
7153
  }
7334
7154
  let parsed;
7335
7155
  try {
7336
- parsed = JSON.parse(readFileSync14(configPath, "utf-8"));
7156
+ parsed = JSON.parse(readFileSync15(configPath, "utf-8"));
7337
7157
  } catch {
7338
7158
  return defaultPolicy();
7339
7159
  }
@@ -7549,28 +7369,28 @@ function resolveAction(mode, matched) {
7549
7369
  }
7550
7370
  function resolveAbsolutePath(projectRoot, rawPath) {
7551
7371
  if (rawPath.startsWith("/"))
7552
- return resolve30(rawPath);
7553
- return resolve30(projectRoot, rawPath);
7372
+ return resolve31(rawPath);
7373
+ return resolve31(projectRoot, rawPath);
7554
7374
  }
7555
7375
  function isHarnessPath(projectRoot, rawPath) {
7556
7376
  const absPath = resolveAbsolutePath(projectRoot, rawPath);
7557
7377
  const managedRoots = [
7558
- resolve30(projectRoot, "rig"),
7559
- resolve30(projectRoot, ".rig"),
7560
- resolve30(projectRoot, "artifacts")
7378
+ resolve31(projectRoot, "rig"),
7379
+ resolve31(projectRoot, ".rig"),
7380
+ resolve31(projectRoot, "artifacts")
7561
7381
  ];
7562
7382
  return managedRoots.some((root) => absPath === root || absPath.startsWith(root + "/"));
7563
7383
  }
7564
7384
  function isRuntimePath(projectRoot, rawPath, taskWorkspace) {
7565
7385
  const absPath = resolveAbsolutePath(projectRoot, rawPath);
7566
7386
  if (taskWorkspace) {
7567
- const workspaceRigRoot = resolve30(taskWorkspace, ".rig");
7568
- const workspaceArtifactsRoot = resolve30(taskWorkspace, "artifacts");
7387
+ const workspaceRigRoot = resolve31(taskWorkspace, ".rig");
7388
+ const workspaceArtifactsRoot = resolve31(taskWorkspace, "artifacts");
7569
7389
  if (absPath === workspaceRigRoot || absPath.startsWith(workspaceRigRoot + "/") || absPath === workspaceArtifactsRoot || absPath.startsWith(workspaceArtifactsRoot + "/")) {
7570
7390
  return true;
7571
7391
  }
7572
7392
  }
7573
- const runtimeRoot = resolve30(projectRoot, ".rig/runtime/agents");
7393
+ const runtimeRoot = resolve31(projectRoot, ".rig/runtime/agents");
7574
7394
  return absPath === runtimeRoot || absPath.startsWith(runtimeRoot + "/");
7575
7395
  }
7576
7396
  function isTestFile(path) {
@@ -7618,7 +7438,7 @@ function evaluateScope(policy, context, filePath, access) {
7618
7438
  return allowed();
7619
7439
  }
7620
7440
  if (context.taskWorkspace && context.taskWorkspace !== context.projectRoot && filePath.startsWith("/")) {
7621
- const absPath = resolve30(filePath);
7441
+ const absPath = resolve31(filePath);
7622
7442
  if (!absPath.startsWith(context.taskWorkspace + "/") && !isHarnessPath(context.projectRoot, filePath)) {
7623
7443
  const reason2 = `Absolute path '${filePath}' is outside task runtime boundary. Allowed root: ${context.taskWorkspace}`;
7624
7444
  const matched2 = [{ id: "scope:workspace-boundary", category: "command", reason: reason2 }];
@@ -7946,13 +7766,13 @@ async function resolveBackend(projectRoot, options) {
7946
7766
  depRoots
7947
7767
  };
7948
7768
  const fsContext = {
7949
- pathExists: (p) => existsSync30(p),
7769
+ pathExists: (p) => existsSync31(p),
7950
7770
  realPath: toRealPath
7951
7771
  };
7952
7772
  if (process.platform === "darwin" && (!requestedBackend || requestedBackend === "macos-seatbelt")) {
7953
7773
  const seatbelt = Bun.which("sandbox-exec");
7954
7774
  probed.push("sandbox-exec");
7955
- if (seatbelt && existsSync30(seatbelt)) {
7775
+ if (seatbelt && existsSync31(seatbelt)) {
7956
7776
  const SeatbeltBackendClass = loadSeatbeltBackend();
7957
7777
  if (SeatbeltBackendClass) {
7958
7778
  return {
@@ -8073,10 +7893,10 @@ init_layout();
8073
7893
  var SNAPSHOT_SIDECAR_READY_TIMEOUT_MS = 1e4;
8074
7894
  async function startRuntimeSnapshotSidecar(runtime, options = {}) {
8075
7895
  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 });
7896
+ const readyFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.ready`);
7897
+ const requestFile = resolve34(runtime.stateDir, `runtime-snapshot-sidecar-${instanceId}.request.json`);
7898
+ rmSync12(readyFile, { force: true });
7899
+ rmSync12(requestFile, { force: true });
8080
7900
  const sidecarBinary = resolveSnapshotSidecarBinaryPath(runtime.binDir);
8081
7901
  const useCompiledSidecar = shouldUseCompiledSnapshotSidecar(sidecarBinary);
8082
7902
  const bunCli = useCompiledSidecar ? null : resolveBunCliInvocation();
@@ -8114,19 +7934,19 @@ async function startRuntimeSnapshotSidecar(runtime, options = {}) {
8114
7934
  proc.kill("SIGTERM");
8115
7935
  } catch {}
8116
7936
  await proc.exited;
8117
- rmSync11(readyFile, { force: true });
8118
- rmSync11(requestFile, { force: true });
7937
+ rmSync12(readyFile, { force: true });
7938
+ rmSync12(requestFile, { force: true });
8119
7939
  },
8120
7940
  finalize: async (commandParts, exitCode) => {
8121
- writeFileSync12(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
7941
+ writeFileSync13(requestFile, `${JSON.stringify({ command: commandParts, exitCode })}
8122
7942
  `, "utf-8");
8123
7943
  const [sidecarExitCode, stdout, stderr] = await Promise.all([
8124
7944
  proc.exited,
8125
7945
  stdoutTextPromise,
8126
7946
  stderrTextPromise
8127
7947
  ]);
8128
- rmSync11(readyFile, { force: true });
8129
- rmSync11(requestFile, { force: true });
7948
+ rmSync12(readyFile, { force: true });
7949
+ rmSync12(requestFile, { force: true });
8130
7950
  if (sidecarExitCode !== 0) {
8131
7951
  throw new Error(`snapshot sidecar failed (${sidecarExitCode}): ${stderr || stdout}`);
8132
7952
  }
@@ -8146,10 +7966,10 @@ function resolveSnapshotSidecarScriptPath() {
8146
7966
  return resolveRuntimeSourceScriptPath("snapshot-sidecar.ts");
8147
7967
  }
8148
7968
  function resolveSnapshotSidecarBinaryPath(binDir) {
8149
- return resolve33(binDir, "snapshot-sidecar");
7969
+ return resolve34(binDir, "snapshot-sidecar");
8150
7970
  }
8151
7971
  function shouldUseCompiledSnapshotSidecar(binaryPath) {
8152
- if (!existsSync31(binaryPath)) {
7972
+ if (!existsSync32(binaryPath)) {
8153
7973
  return false;
8154
7974
  }
8155
7975
  const preference = process.env.RIG_USE_COMPILED_SNAPSHOT_SIDECAR?.trim().toLowerCase();
@@ -8164,12 +7984,12 @@ function resolveRuntimeSourceScriptPath(fileName) {
8164
7984
  process.env.PROJECT_RIG_ROOT?.trim()
8165
7985
  ].filter((value) => Boolean(value));
8166
7986
  for (const root of hostRoots) {
8167
- const candidate = resolve33(root, "packages/runtime/src/control-plane/runtime", fileName);
8168
- if (existsSync31(candidate)) {
7987
+ const candidate = resolve34(root, "packages/runtime/src/control-plane/runtime", fileName);
7988
+ if (existsSync32(candidate)) {
8169
7989
  return candidate;
8170
7990
  }
8171
7991
  }
8172
- return resolve33(import.meta.dir, "..", fileName);
7992
+ return resolve34(import.meta.dir, "..", fileName);
8173
7993
  }
8174
7994
  function resolveBunCliInvocation() {
8175
7995
  if (process.env.RIG_BUN_PATH?.trim()) {
@@ -8196,7 +8016,7 @@ function resolveBunCliInvocation() {
8196
8016
  async function waitForSnapshotSidecarReady(readyFile, proc, stdoutTextPromise, stderrTextPromise) {
8197
8017
  const deadline = Date.now() + SNAPSHOT_SIDECAR_READY_TIMEOUT_MS;
8198
8018
  while (Date.now() < deadline) {
8199
- if (existsSync31(readyFile)) {
8019
+ if (existsSync32(readyFile)) {
8200
8020
  return;
8201
8021
  }
8202
8022
  const exitCode = proc.exitCode;
@@ -8214,9 +8034,9 @@ var CANONICAL_MEMORY_DB_PATH2 = "rig/memory/project-memory.db";
8214
8034
  async function hydrateRuntimeMemory(options) {
8215
8035
  const snapshot = await readCanonicalMemoryDb(options.projectRoot);
8216
8036
  const workspaceLayout = resolveRuntimeWorkspaceLayout(options.workspaceDir);
8217
- const hydratedPath = resolve34(workspaceLayout.stateDir, "memory", "project-memory.db");
8037
+ const hydratedPath = resolve35(workspaceLayout.stateDir, "memory", "project-memory.db");
8218
8038
  try {
8219
- await mkdir3(resolve34(workspaceLayout.stateDir, "memory"), { recursive: true });
8039
+ await mkdir3(resolve35(workspaceLayout.stateDir, "memory"), { recursive: true });
8220
8040
  await copyFile(snapshot.dbPath, hydratedPath);
8221
8041
  return {
8222
8042
  canonicalPath: CANONICAL_MEMORY_DB_PATH2,
@@ -8231,12 +8051,12 @@ async function hydrateRuntimeMemory(options) {
8231
8051
  }
8232
8052
  }
8233
8053
  async function createRuntimeTaskRecordReader(options) {
8234
- const legacyConfigPath = resolve34(options.projectRoot, ".rig", "task-config.json");
8054
+ const legacyConfigPath = resolve35(options.projectRoot, ".rig", "task-config.json");
8235
8055
  let pluginHostContext = null;
8236
8056
  try {
8237
8057
  pluginHostContext = await buildPluginHostContext(options.projectRoot);
8238
8058
  } catch (error) {
8239
- if (!existsSync32(legacyConfigPath)) {
8059
+ if (!existsSync33(legacyConfigPath)) {
8240
8060
  throw error;
8241
8061
  }
8242
8062
  const message = `Plugin task source unavailable; using source-aware .rig/task-config.json compatibility path: ${error instanceof Error ? error.message : String(error)}`;
@@ -8256,7 +8076,7 @@ async function createRuntimeTaskRecordReader(options) {
8256
8076
  source: "plugin"
8257
8077
  };
8258
8078
  }
8259
- if (existsSync32(legacyConfigPath)) {
8079
+ if (existsSync33(legacyConfigPath)) {
8260
8080
  const message = "Using source-aware .rig/task-config.json task source compatibility path";
8261
8081
  options.diagnostics?.(message);
8262
8082
  console.warn(message);
@@ -8273,10 +8093,10 @@ async function createRuntimeTaskRecordReader(options) {
8273
8093
  };
8274
8094
  }
8275
8095
  function readConfiguredTaskSourceKindHint(projectRoot) {
8276
- const jsonPath = resolve34(projectRoot, "rig.config.json");
8277
- if (existsSync32(jsonPath)) {
8096
+ const jsonPath = resolve35(projectRoot, "rig.config.json");
8097
+ if (existsSync33(jsonPath)) {
8278
8098
  try {
8279
- const parsed = JSON.parse(readFileSync15(jsonPath, "utf8"));
8099
+ const parsed = JSON.parse(readFileSync16(jsonPath, "utf8"));
8280
8100
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
8281
8101
  const taskSource = parsed.taskSource;
8282
8102
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -8288,12 +8108,12 @@ function readConfiguredTaskSourceKindHint(projectRoot) {
8288
8108
  return null;
8289
8109
  }
8290
8110
  }
8291
- const tsPath = resolve34(projectRoot, "rig.config.ts");
8292
- if (!existsSync32(tsPath)) {
8111
+ const tsPath = resolve35(projectRoot, "rig.config.ts");
8112
+ if (!existsSync33(tsPath)) {
8293
8113
  return null;
8294
8114
  }
8295
8115
  try {
8296
- const source = readFileSync15(tsPath, "utf8");
8116
+ const source = readFileSync16(tsPath, "utf8");
8297
8117
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
8298
8118
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
8299
8119
  return kind ?? null;
@@ -8363,8 +8183,8 @@ async function writeRuntimeTaskConfigProjection(options) {
8363
8183
  ...options.taskEntry.validation && options.taskEntry.validation.length > 0 ? { validation: options.taskEntry.validation } : {},
8364
8184
  ...options.taskEntry.browser ? { browser: options.taskEntry.browser } : {}
8365
8185
  };
8366
- const configPath = resolve34(options.workspaceDir, ".rig", "task-config.json");
8367
- await mkdir3(resolve34(options.workspaceDir, ".rig"), { recursive: true });
8186
+ const configPath = resolve35(options.workspaceDir, ".rig", "task-config.json");
8187
+ await mkdir3(resolve35(options.workspaceDir, ".rig"), { recursive: true });
8368
8188
  await writeFile2(configPath, `${JSON.stringify({ [options.task.id]: entry }, null, 2)}
8369
8189
  `, "utf-8");
8370
8190
  }
@@ -8428,9 +8248,9 @@ async function ensureAgentRuntime(options) {
8428
8248
  }
8429
8249
  ensureProvisioningHostProjectRootEnv(options.projectRoot);
8430
8250
  const monorepoRoot = resolveMonorepoRoot3(options.projectRoot);
8431
- const workspaceDir = resolve34(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
8251
+ const workspaceDir = resolve35(monorepoRoot, ".worktrees", runtimeWorktreeName(options.taskId, options.id));
8432
8252
  const createdAt = new Date().toISOString();
8433
- if (!existsSync32(resolve34(monorepoRoot, ".git"))) {
8253
+ if (!existsSync33(resolve35(monorepoRoot, ".git"))) {
8434
8254
  throw new Error(`Monorepo root is not a git checkout: ${monorepoRoot}`);
8435
8255
  }
8436
8256
  const taskResolution = await resolveRuntimeTaskRecord({
@@ -8465,7 +8285,7 @@ async function ensureAgentRuntime(options) {
8465
8285
  logsDir: overlay.logsDir,
8466
8286
  stateDir: overlay.stateDir,
8467
8287
  sessionDir: overlay.sessionDir,
8468
- claudeHomeDir: resolve34(workspaceLayout.homeDir, ".claude"),
8288
+ claudeHomeDir: resolve35(workspaceLayout.homeDir, ".claude"),
8469
8289
  contextFile: overlay.contextPath,
8470
8290
  binDir: workspaceLayout.binDir,
8471
8291
  createdAt
@@ -8478,10 +8298,14 @@ async function ensureAgentRuntime(options) {
8478
8298
  projectRoot: options.projectRoot,
8479
8299
  workspaceDir
8480
8300
  });
8481
- mkdirSync18(runtime.binDir, { recursive: true });
8482
- mkdirSync18(workspaceLayout.distDir, { recursive: true });
8301
+ mkdirSync19(runtime.binDir, { recursive: true });
8302
+ mkdirSync19(workspaceLayout.distDir, { recursive: true });
8483
8303
  prepareRuntimeWorkspace(options.projectRoot, workspaceDir);
8484
- await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8304
+ if (options.preserveTaskArtifacts) {
8305
+ console.log(`[rig-agent] Preserving runtime task artifacts for resume of ${options.taskId}.`);
8306
+ } else {
8307
+ await resetEphemeralTaskArtifacts(workspaceDir, options.taskId);
8308
+ }
8485
8309
  const ctx = {
8486
8310
  runtimeId: options.id,
8487
8311
  taskId: options.taskId,
@@ -8494,7 +8318,7 @@ async function ensureAgentRuntime(options) {
8494
8318
  runtimeId: options.id
8495
8319
  }),
8496
8320
  workspaceDir,
8497
- artifactRoot: resolve34(workspaceDir, "artifacts", options.taskId),
8321
+ artifactRoot: resolve35(workspaceDir, "artifacts", options.taskId),
8498
8322
  hostProjectRoot: options.projectRoot,
8499
8323
  monorepoMainRoot: monorepoRoot,
8500
8324
  monorepoBaseRef: baseRef,
@@ -8510,8 +8334,8 @@ async function ensureAgentRuntime(options) {
8510
8334
  stateDir: overlay.stateDir,
8511
8335
  logsDir: overlay.logsDir,
8512
8336
  sessionDir: overlay.sessionDir,
8513
- sessionFile: resolve34(overlay.sessionDir, "session.json"),
8514
- policyFile: resolve34(options.projectRoot, "rig/policy/policy.json"),
8337
+ sessionFile: resolve35(overlay.sessionDir, "session.json"),
8338
+ policyFile: resolve35(options.projectRoot, "rig/policy/policy.json"),
8515
8339
  binDir: runtime.binDir,
8516
8340
  createdAt,
8517
8341
  memory
@@ -8522,9 +8346,9 @@ async function ensureAgentRuntime(options) {
8522
8346
  task: taskResolution.task,
8523
8347
  taskEntry
8524
8348
  });
8525
- const manifestPath = resolve34(runtimeRoot, "manifest.json");
8349
+ const manifestPath = resolve35(runtimeRoot, "manifest.json");
8526
8350
  const bakedScopeHash = sha256Hex(JSON.stringify(taskEntry.scope || []));
8527
- const runtimeAgentBinary = resolve34(runtime.binDir, "rig-agent");
8351
+ const runtimeAgentBinary = resolve35(runtime.binDir, "rig-agent");
8528
8352
  await ensureRigGitBinaryPath();
8529
8353
  const bakedInfoOutput = await captureTaskInfoOutput({
8530
8354
  projectRoot: options.projectRoot,
@@ -8539,10 +8363,10 @@ async function ensureAgentRuntime(options) {
8539
8363
  const bakedStatusOutput = await captureStdout(async () => {
8540
8364
  taskStatus(options.projectRoot);
8541
8365
  });
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 });
8366
+ rmSync13(runtime.binDir, { recursive: true, force: true });
8367
+ rmSync13(workspaceLayout.distDir, { recursive: true, force: true });
8368
+ mkdirSync19(runtime.binDir, { recursive: true });
8369
+ mkdirSync19(workspaceLayout.distDir, { recursive: true });
8546
8370
  await buildRuntimeToolchain({
8547
8371
  projectRoot: options.projectRoot,
8548
8372
  workspaceDir,
@@ -8579,9 +8403,9 @@ async function ensureAgentRuntime(options) {
8579
8403
  workspaceDir,
8580
8404
  taskEntry
8581
8405
  });
8582
- const sandboxDir = resolve34(runtimeRoot, "sandbox");
8406
+ const sandboxDir = resolve35(runtimeRoot, "sandbox");
8583
8407
  await mkdir3(sandboxDir, { recursive: true });
8584
- await writeFile2(resolve34(runtimeRoot, "runtime.json"), JSON.stringify({
8408
+ await writeFile2(resolve35(runtimeRoot, "runtime.json"), JSON.stringify({
8585
8409
  id: options.id,
8586
8410
  taskId: options.taskId,
8587
8411
  mode: "worktree",
@@ -8688,8 +8512,8 @@ async function runCodexAppServerTaskRun(options) {
8688
8512
  const sendRequest = async (method, params) => {
8689
8513
  const id = nextRequestId;
8690
8514
  nextRequestId += 1;
8691
- const resultPromise = new Promise((resolve35, reject) => {
8692
- pendingResponses.set(id, { resolve: resolve35, reject });
8515
+ const resultPromise = new Promise((resolve36, reject) => {
8516
+ pendingResponses.set(id, { resolve: resolve36, reject });
8693
8517
  });
8694
8518
  await sendMessage({ id, method, params });
8695
8519
  return resultPromise;
@@ -8888,8 +8712,8 @@ async function runCodexAppServerTaskRun(options) {
8888
8712
  console.error(line);
8889
8713
  }
8890
8714
  });
8891
- const exitPromise = new Promise((resolve35) => {
8892
- child.once("close", (code, signal) => resolve35({ code, signal }));
8715
+ const exitPromise = new Promise((resolve36) => {
8716
+ child.once("close", (code, signal) => resolve36({ code, signal }));
8893
8717
  });
8894
8718
  await sendRequest("initialize", {
8895
8719
  clientInfo: DEFAULT_CLIENT_INFO,
@@ -8930,7 +8754,7 @@ async function runCodexAppServerTaskRun(options) {
8930
8754
  while (!completionState.current) {
8931
8755
  exitResult = await Promise.race([
8932
8756
  exitPromise,
8933
- new Promise((resolve35) => setTimeout(() => resolve35(null), 100))
8757
+ new Promise((resolve36) => setTimeout(() => resolve36(null), 100))
8934
8758
  ]);
8935
8759
  if (exitResult) {
8936
8760
  break;
@@ -9079,13 +8903,13 @@ function sanitizeEnv(env) {
9079
8903
  return next;
9080
8904
  }
9081
8905
  function writeChildLine(child, line) {
9082
- return new Promise((resolve35, reject) => {
8906
+ return new Promise((resolve36, reject) => {
9083
8907
  child.stdin.write(line, (error) => {
9084
8908
  if (error) {
9085
8909
  reject(error);
9086
8910
  return;
9087
8911
  }
9088
- resolve35();
8912
+ resolve36();
9089
8913
  });
9090
8914
  });
9091
8915
  }
@@ -9131,7 +8955,175 @@ function formatJsonRpcError(error) {
9131
8955
  return parts.join(" ");
9132
8956
  }
9133
8957
 
8958
+ // packages/runtime/src/control-plane/pi-sessiond/launcher.ts
8959
+ import { randomBytes } from "crypto";
8960
+ import { existsSync as existsSync34, mkdirSync as mkdirSync20, readFileSync as readFileSync17, rmSync as rmSync14 } from "fs";
8961
+ import { dirname as dirname14, resolve as resolve36 } from "path";
8962
+ import { fileURLToPath as fileURLToPath2 } from "url";
8963
+
8964
+ // packages/runtime/src/control-plane/pi-sessiond/client.ts
8965
+ class RigPiSessionDaemonClient {
8966
+ baseUrl;
8967
+ token;
8968
+ constructor(options) {
8969
+ this.baseUrl = options.baseUrl.replace(/\/+$/, "");
8970
+ this.token = options.token;
8971
+ }
8972
+ static fromConnection(connection, token) {
8973
+ if (connection.mode === "http")
8974
+ return new RigPiSessionDaemonClient({ baseUrl: connection.baseUrl, token });
8975
+ throw new Error("Unix-socket Rig Pi daemon connections are not implemented in this build; use loopback HTTP.");
8976
+ }
8977
+ async request(method, path, body) {
8978
+ const response = await fetch(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`, {
8979
+ method,
8980
+ headers: {
8981
+ authorization: `Bearer ${this.token}`,
8982
+ ...body === undefined ? {} : { "content-type": "application/json" }
8983
+ },
8984
+ body: body === undefined ? undefined : JSON.stringify(body)
8985
+ });
8986
+ const text = await response.text();
8987
+ const payload = text.trim() ? JSON.parse(text) : undefined;
8988
+ if (!response.ok) {
8989
+ const message = payload && typeof payload === "object" && !Array.isArray(payload) && typeof payload.error === "string" ? payload.error : text || response.statusText;
8990
+ throw new Error(`Rig Pi session daemon request failed (${response.status}): ${message}`);
8991
+ }
8992
+ return payload;
8993
+ }
8994
+ webSocketUrl(path) {
8995
+ const url = new URL(`${this.baseUrl}${path.startsWith("/") ? path : `/${path}`}`);
8996
+ url.protocol = url.protocol === "https:" ? "wss:" : "ws:";
8997
+ url.searchParams.set("token", this.token);
8998
+ return url.toString();
8999
+ }
9000
+ }
9001
+
9002
+ // packages/runtime/src/control-plane/pi-sessiond/launcher.ts
9003
+ var BUILD_CONFIG2 = {};
9004
+ var BAKED_RIG_SOURCE_ROOT = BUILD_CONFIG2.RIG_SOURCE_ROOT ?? "";
9005
+ async function ensureRigPiSessionDaemon(input) {
9006
+ const rootDir = resolve36(input.rootDir);
9007
+ mkdirSync20(rootDir, { recursive: true });
9008
+ const readyFile = resolve36(rootDir, "ready.json");
9009
+ const existing = readDaemonReadyFile(readyFile);
9010
+ const existingHandle = existing ? await tryReady(existing) : null;
9011
+ if (existingHandle)
9012
+ return existingHandle;
9013
+ try {
9014
+ rmSync14(readyFile, { force: true });
9015
+ } catch {}
9016
+ const token = randomBytes(32).toString("hex");
9017
+ const binPath = resolveRigPiSessionDaemonBinPath(input.env);
9018
+ const bunPath = input.env.RIG_BUN_PATH || process.execPath;
9019
+ const proc = Bun.spawn([bunPath, binPath], {
9020
+ cwd: rootDir,
9021
+ env: {
9022
+ ...input.env,
9023
+ RIG_PI_SESSIOND_ROOT: rootDir,
9024
+ RIG_PI_SESSIOND_TOKEN: token,
9025
+ RIG_PI_SESSIOND_READY_FILE: readyFile,
9026
+ RIG_PI_SESSIOND_HOST: "127.0.0.1",
9027
+ RIG_PI_SESSIOND_PORT: "0",
9028
+ ...input.version ? { RIG_VERSION: input.version } : {},
9029
+ ...input.commit ? { RIG_GIT_COMMIT: input.commit } : {}
9030
+ },
9031
+ stdin: "ignore",
9032
+ stdout: "ignore",
9033
+ stderr: "inherit"
9034
+ });
9035
+ proc.unref();
9036
+ const deadline = Date.now() + (input.timeoutMs ?? 15000);
9037
+ while (Date.now() < deadline) {
9038
+ const ready = readDaemonReadyFile(readyFile);
9039
+ const handle = ready ? await tryReady(ready) : null;
9040
+ if (handle)
9041
+ return handle;
9042
+ await sleep(100);
9043
+ }
9044
+ throw new Error([
9045
+ `Rig Pi session daemon did not become ready at ${readyFile}.`,
9046
+ "Usual causes: the bundled Pi runtime is missing or broken. Run `rig doctor` to check Pi wiring,",
9047
+ "set RIG_PI_BINARY to a working Pi build, or run without Pi via RIG_RUNTIME_ADAPTER=claude-code."
9048
+ ].join(`
9049
+ `));
9050
+ }
9051
+ function privateMetadataForDaemon(input) {
9052
+ return { public: input.publicMetadata, daemonConnection: input.connection };
9053
+ }
9054
+ async function tryReady(ready) {
9055
+ const host = typeof ready.host === "string" ? ready.host : "127.0.0.1";
9056
+ const port = typeof ready.port === "number" ? ready.port : Number(ready.port);
9057
+ const token = typeof ready.token === "string" ? ready.token : "";
9058
+ if (!Number.isFinite(port) || port <= 0 || !token)
9059
+ return null;
9060
+ const baseUrl = `http://${host}:${port}`;
9061
+ const client = new RigPiSessionDaemonClient({ baseUrl, token });
9062
+ try {
9063
+ await client.request("GET", "/health");
9064
+ } catch {
9065
+ return null;
9066
+ }
9067
+ return {
9068
+ client,
9069
+ connection: { mode: "http", baseUrl, tokenRef: tokenRefFromReady(ready) },
9070
+ token,
9071
+ ready
9072
+ };
9073
+ }
9074
+ function tokenRefFromReady(ready) {
9075
+ const token = typeof ready.token === "string" ? ready.token : "";
9076
+ return token ? `inline:${token}` : "missing";
9077
+ }
9078
+ function resolveRigPiSessionDaemonBinPath(env) {
9079
+ const explicit = env.RIG_PI_SESSIOND_BIN?.trim();
9080
+ if (explicit)
9081
+ return explicit;
9082
+ const roots = [
9083
+ env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
9084
+ BAKED_RIG_SOURCE_ROOT.trim(),
9085
+ process.env.RIG_CONTROL_PLANE_SOURCE_ROOT?.trim(),
9086
+ process.env.RIG_HOST_PROJECT_ROOT?.trim(),
9087
+ process.env.PROJECT_RIG_ROOT?.trim()
9088
+ ].filter((value) => Boolean(value));
9089
+ for (const root of roots) {
9090
+ const candidate = resolve36(root, "packages/runtime/src/control-plane/pi-sessiond/bin.ts");
9091
+ if (existsSync34(candidate))
9092
+ return candidate;
9093
+ }
9094
+ const moduleCandidate = fileURLToPath2(new URL("./bin.ts", import.meta.url));
9095
+ if (existsSync34(moduleCandidate))
9096
+ return moduleCandidate;
9097
+ throw new Error([
9098
+ "Unable to locate rig-pi-sessiond entrypoint.",
9099
+ "Set RIG_PI_SESSIOND_BIN or RIG_CONTROL_PLANE_SOURCE_ROOT to the Rig source checkout,",
9100
+ "or run without the Pi daemon via RIG_RUNTIME_ADAPTER=claude-code."
9101
+ ].join(`
9102
+ `));
9103
+ }
9104
+ function readDaemonReadyFile(path) {
9105
+ if (!existsSync34(path))
9106
+ return null;
9107
+ try {
9108
+ const parsed = JSON.parse(readFileSync17(path, "utf8"));
9109
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
9110
+ } catch {
9111
+ return null;
9112
+ }
9113
+ }
9114
+ function sleep(ms) {
9115
+ return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
9116
+ }
9117
+ function resolveRigPiSessionDaemonRoot(stateDir) {
9118
+ const root = resolve36(stateDir, "pi-sessiond");
9119
+ mkdirSync20(dirname14(root), { recursive: true });
9120
+ if (!existsSync34(root))
9121
+ mkdirSync20(root, { recursive: true });
9122
+ return root;
9123
+ }
9124
+
9134
9125
  // packages/runtime/src/control-plane/agent-wrapper.ts
9126
+ var requireFromRuntime = createRequire(import.meta.url);
9135
9127
  async function finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, context) {
9136
9128
  try {
9137
9129
  await snapshotSidecar.finalize(providerCommand, exitCode);
@@ -9164,7 +9156,7 @@ async function startOptionalRuntimeSnapshotSidecar(runtime, startSidecar = start
9164
9156
  }
9165
9157
  }
9166
9158
  async function runAgentWrapper(options = {}) {
9167
- const projectRoot = resolve35(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
9159
+ const projectRoot = resolve37(options.projectRoot || process.env.PROJECT_RIG_ROOT || process.cwd());
9168
9160
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
9169
9161
  const argv = options.argv || process.argv.slice(2);
9170
9162
  if (argv.length === 0 || argv[0] === "--version" || argv[0] === "--help" || argv[0] === "help") {
@@ -9193,7 +9185,8 @@ async function runAgentWrapper(options = {}) {
9193
9185
  taskId,
9194
9186
  mode: "worktree",
9195
9187
  provider,
9196
- taskRecordReader: taskRecordReaderFromEnv(taskId)
9188
+ taskRecordReader: taskRecordReaderFromEnv(taskId),
9189
+ preserveTaskArtifacts: process.env.RIG_RUN_RESUME === "1" || process.env.RIG_RUNTIME_ARTIFACT_CLEANUP === "preserve"
9197
9190
  });
9198
9191
  emitWrapperEvent("runtime.provision.completed", {
9199
9192
  runtimeId: runtime.id,
@@ -9226,7 +9219,8 @@ async function runAgentWrapper(options = {}) {
9226
9219
  return 1;
9227
9220
  }
9228
9221
  const providerArgs = buildProviderArgs(provider, runtime, argv);
9229
- const providerCommand = [providerBinary(provider), ...providerArgs];
9222
+ const normalPiDaemonPath = provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1";
9223
+ const providerCommand = normalPiDaemonPath ? ["rig-pi-sessiond", ...providerArgs] : [providerBinary(provider), ...providerArgs];
9230
9224
  emitWrapperEvent("provider.launch", {
9231
9225
  provider,
9232
9226
  runtimeId: runtime.id,
@@ -9238,11 +9232,11 @@ async function runAgentWrapper(options = {}) {
9238
9232
  const bypassOuterRuntimeSandbox = shouldBypassProviderSandboxOnPlatform(provider, process.platform);
9239
9233
  const runClaudeCompatUnsandboxed = provider === "claude-code" && bypassOuterRuntimeSandbox;
9240
9234
  if (runClaudeCompatUnsandboxed && process.env.HOME?.trim()) {
9241
- env.CLAUDE_HOME = resolve35(process.env.HOME.trim(), ".claude");
9235
+ env.CLAUDE_HOME = resolve37(process.env.HOME.trim(), ".claude");
9242
9236
  env.RIG_CLAUDE_RUNTIME_HOME = runtime.claudeHomeDir;
9243
9237
  }
9244
9238
  if (provider === "pi") {
9245
- env.PI_CODING_AGENT_DIR = resolve35(runtime.homeDir, ".pi", "agent");
9239
+ env.PI_CODING_AGENT_DIR = resolve37(runtime.homeDir, ".pi", "agent");
9246
9240
  env.PI_CODING_AGENT_SESSION_DIR = runtime.sessionDir;
9247
9241
  }
9248
9242
  env.RIG_RUNTIME_SANDBOX = "enforce";
@@ -9276,14 +9270,36 @@ async function runAgentWrapper(options = {}) {
9276
9270
  },
9277
9271
  command: providerCommand
9278
9272
  })).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;
9273
+ if (provider === "pi" && process.env.RIG_PI_RPC_FALLBACK !== "1") {
9274
+ const prompt = await readProcessStdin();
9275
+ exitCode = await runPiSessionDaemonProvider({
9276
+ projectRoot,
9277
+ runtime,
9278
+ env,
9279
+ prompt,
9280
+ runId: process.env.RIG_SERVER_RUN_ID?.trim() || process.env.RIG_RUN_ID?.trim() || undefined,
9281
+ sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
9282
+ });
9283
+ } else if (provider === "pi" && isPiRpcArgs(providerArgs)) {
9284
+ const prompt = await readProcessStdin();
9285
+ exitCode = await runPiRpcProviderFallback({
9286
+ command,
9287
+ cwd: runtime.workspaceDir,
9288
+ env,
9289
+ prompt,
9290
+ runId: process.env.RIG_SERVER_RUN_ID?.trim() || undefined,
9291
+ sessionName: process.env.RIG_SERVER_RUN_ID?.trim() ? `Rig ${process.env.RIG_SERVER_RUN_ID.trim()}` : `Rig ${runtime.taskId}`
9292
+ });
9293
+ } else {
9294
+ const proc = Bun.spawn(command, {
9295
+ cwd: runtime.workspaceDir,
9296
+ env,
9297
+ stdin: "inherit",
9298
+ stdout: "inherit",
9299
+ stderr: "inherit"
9300
+ });
9301
+ exitCode = await proc.exited;
9302
+ }
9287
9303
  }
9288
9304
  if (snapshotSidecar) {
9289
9305
  await finalizeRuntimeSnapshot(snapshotSidecar, providerCommand, exitCode, {
@@ -9298,15 +9314,13 @@ async function runAgentWrapper(options = {}) {
9298
9314
  throw error;
9299
9315
  }
9300
9316
  const serverManagedRun = Boolean(process.env.RIG_SERVER_RUN_ID?.trim());
9301
- if (exitCode === 0 && serverManagedRun) {
9302
- await updateTaskSourceAfterRun(monorepoRoot, taskId, runtime);
9303
- }
9304
9317
  const taskClosed = await isTaskClosed(monorepoRoot, taskId);
9305
9318
  const finalExitCode = resolveFinalProviderExitCode({
9306
9319
  providerExitCode: exitCode,
9307
9320
  taskClosed,
9308
9321
  serverManagedRun
9309
9322
  });
9323
+ const handoffRequired = exitCode !== 0 || !taskClosed && !serverManagedRun;
9310
9324
  emitWrapperEvent("provider.completed", {
9311
9325
  provider,
9312
9326
  runtimeId: runtime.id,
@@ -9315,24 +9329,352 @@ async function runAgentWrapper(options = {}) {
9315
9329
  providerExitCode: exitCode,
9316
9330
  taskClosed,
9317
9331
  serverManagedRun,
9318
- handoffRequired: exitCode !== 0 || !taskClosed
9332
+ handoffRequired
9319
9333
  });
9320
- if (exitCode !== 0 || !taskClosed) {
9334
+ if (handoffRequired) {
9321
9335
  recordRuntimeHandoff(projectRoot, runtime, taskId, exitCode);
9322
9336
  }
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
9337
  return finalExitCode;
9327
9338
  }
9339
+ function parseJsonRecord(line) {
9340
+ try {
9341
+ const parsed = JSON.parse(line);
9342
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
9343
+ } catch {
9344
+ return null;
9345
+ }
9346
+ }
9347
+ async function readProcessStdin() {
9348
+ if (process.stdin.isTTY)
9349
+ return "";
9350
+ return await new Promise((resolveRead) => {
9351
+ let data = "";
9352
+ process.stdin.setEncoding("utf8");
9353
+ process.stdin.on("data", (chunk) => {
9354
+ data += String(chunk);
9355
+ });
9356
+ process.stdin.on("end", () => resolveRead(data));
9357
+ process.stdin.resume();
9358
+ });
9359
+ }
9360
+ async function pumpReadableLines(stream, onLine) {
9361
+ if (!stream)
9362
+ return;
9363
+ const reader = stream.getReader();
9364
+ const decoder = new TextDecoder;
9365
+ let buffer = "";
9366
+ try {
9367
+ while (true) {
9368
+ const { done, value } = await reader.read();
9369
+ if (done)
9370
+ break;
9371
+ buffer += decoder.decode(value, { stream: true });
9372
+ const parts = buffer.split(/\r?\n/);
9373
+ buffer = parts.pop() ?? "";
9374
+ for (const part of parts)
9375
+ onLine(part);
9376
+ }
9377
+ buffer += decoder.decode();
9378
+ if (buffer)
9379
+ onLine(buffer);
9380
+ } finally {
9381
+ reader.releaseLock();
9382
+ }
9383
+ }
9384
+ function isBlockingPiRpcUiRequest(record) {
9385
+ if (record.type !== "extension_ui_request")
9386
+ return false;
9387
+ return record.method === "select" || record.method === "confirm" || record.method === "input" || record.method === "editor";
9388
+ }
9389
+ function writeRpcCommand(stdin, command) {
9390
+ stdin.write(`${JSON.stringify(command)}
9391
+ `);
9392
+ }
9393
+ function joinUrl(baseUrl, pathname) {
9394
+ return `${baseUrl.replace(/\/+$/, "")}${pathname.startsWith("/") ? pathname : `/${pathname}`}`;
9395
+ }
9396
+ async function readQueuedSteeringFromServer(input) {
9397
+ if (!input.serverUrl || !input.runId)
9398
+ return [];
9399
+ const headers = {};
9400
+ if (input.authToken)
9401
+ headers.authorization = `Bearer ${input.authToken}`;
9402
+ const response = await fetch(joinUrl(input.serverUrl, `/api/runs/${encodeURIComponent(input.runId)}/steering?ack=1`), { headers });
9403
+ if (!response.ok)
9404
+ return [];
9405
+ const payload = await response.json().catch(() => null);
9406
+ const messages = payload && typeof payload === "object" && !Array.isArray(payload) ? payload.messages : null;
9407
+ return Array.isArray(messages) ? messages.filter((entry) => Boolean(entry && typeof entry === "object" && !Array.isArray(entry))) : [];
9408
+ }
9409
+ function steeringMessageText(entry) {
9410
+ const message = typeof entry.message === "string" ? entry.message.trim() : "";
9411
+ return message || null;
9412
+ }
9413
+ function isPiRpcArgs(args) {
9414
+ return cliOptionValue(args, "--mode") === "rpc";
9415
+ }
9416
+ async function runPiSessionDaemonProvider(input) {
9417
+ const stdout = input.stdout ?? process.stdout;
9418
+ const stderr = input.stderr ?? process.stderr;
9419
+ const runId = input.runId ?? input.runtime.taskId;
9420
+ emitWrapperEvent("pi.sessiond.starting", {
9421
+ runId,
9422
+ runtimeId: input.runtime.id,
9423
+ workspaceDir: input.runtime.workspaceDir
9424
+ });
9425
+ const daemon = await ensureRigPiSessionDaemon({
9426
+ rootDir: resolveRigPiSessionDaemonRoot(input.runtime.stateDir),
9427
+ env: input.env,
9428
+ version: process.env.RIG_VERSION?.trim() || "dev",
9429
+ commit: process.env.RIG_GIT_COMMIT?.trim() || undefined
9430
+ });
9431
+ emitWrapperEvent("pi.sessiond.ready", {
9432
+ runId,
9433
+ runtimeId: input.runtime.id,
9434
+ connection: daemon.connection,
9435
+ ready: daemon.ready
9436
+ });
9437
+ const start = await daemon.client.request("POST", "/sessions", {
9438
+ runId,
9439
+ cwd: input.runtime.workspaceDir,
9440
+ agentDir: input.env.PI_CODING_AGENT_DIR || resolve37(input.runtime.homeDir, ".pi", "agent"),
9441
+ sessionDir: input.runtime.sessionDir,
9442
+ sessionName: input.sessionName
9443
+ });
9444
+ const privateMetadata = privateMetadataForDaemon({ publicMetadata: start.metadata, connection: daemon.connection });
9445
+ emitWrapperEvent("pi.session.ready", {
9446
+ runId,
9447
+ runtimeId: input.runtime.id,
9448
+ metadata: start.metadata,
9449
+ privateMetadata
9450
+ });
9451
+ const eventStream = waitForPiSessionEvents({
9452
+ url: daemon.client.webSocketUrl(`/sessions/${encodeURIComponent(start.metadata.sessionId)}/events`),
9453
+ stdout,
9454
+ stderr,
9455
+ runId
9456
+ });
9457
+ emitWrapperEvent("pi.session.event_stream.connected", { runId, sessionId: start.metadata.sessionId });
9458
+ const forwardSigterm = () => {
9459
+ daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/abort`).catch(() => {
9460
+ return;
9461
+ });
9462
+ eventStream.close();
9463
+ };
9464
+ process.once("SIGTERM", forwardSigterm);
9465
+ try {
9466
+ if (input.prompt.trim()) {
9467
+ await daemon.client.request("POST", `/sessions/${encodeURIComponent(start.metadata.sessionId)}/prompt`, { text: input.prompt });
9468
+ emitWrapperEvent("pi.prompt.sent", { runId, sessionId: start.metadata.sessionId, bytes: Buffer.byteLength(input.prompt) });
9469
+ } else {
9470
+ emitWrapperEvent("pi.prompt.waiting", { runId, sessionId: start.metadata.sessionId, reason: "empty-initial-prompt" });
9471
+ }
9472
+ const result = await eventStream.done;
9473
+ if (result.error) {
9474
+ stderr.write(`[rig-agent] Pi session daemon stream failed: ${result.error}
9475
+ `);
9476
+ return 1;
9477
+ }
9478
+ return 0;
9479
+ } finally {
9480
+ process.off("SIGTERM", forwardSigterm);
9481
+ eventStream.close();
9482
+ }
9483
+ }
9484
+ function waitForPiSessionEvents(input) {
9485
+ let closed = false;
9486
+ let resolved = false;
9487
+ let socket = null;
9488
+ let resolveDone = () => {
9489
+ return;
9490
+ };
9491
+ const done = new Promise((resolveDoneInner) => {
9492
+ resolveDone = resolveDoneInner;
9493
+ });
9494
+ const finish = (value) => {
9495
+ if (resolved)
9496
+ return;
9497
+ resolved = true;
9498
+ resolveDone(value);
9499
+ };
9500
+ socket = new WebSocket(input.url);
9501
+ socket.addEventListener("message", (message) => {
9502
+ const text = typeof message.data === "string" ? message.data : Buffer.from(message.data).toString("utf8");
9503
+ input.stdout.write(`${text}
9504
+ `);
9505
+ const envelope = parseJsonRecord(text);
9506
+ if (!envelope)
9507
+ return;
9508
+ if (envelope.type === "pi.event") {
9509
+ const event = envelope.event && typeof envelope.event === "object" && !Array.isArray(envelope.event) ? envelope.event : null;
9510
+ if (event?.type === "agent_end") {
9511
+ emitWrapperEvent("pi.session.agent_end", { runId: input.runId, sessionId: envelope.sessionId });
9512
+ finish({});
9513
+ }
9514
+ }
9515
+ if (envelope.type === "error") {
9516
+ emitWrapperEvent("pi.session.error", { runId: input.runId, message: envelope.message, detail: envelope.detail ?? null });
9517
+ finish({ error: envelope.message });
9518
+ }
9519
+ });
9520
+ socket.addEventListener("error", () => {
9521
+ if (!closed)
9522
+ finish({ error: "WebSocket error" });
9523
+ });
9524
+ socket.addEventListener("close", () => {
9525
+ if (!closed && !resolved)
9526
+ finish({ error: "WebSocket closed before agent_end" });
9527
+ });
9528
+ return {
9529
+ done,
9530
+ close: () => {
9531
+ closed = true;
9532
+ try {
9533
+ socket?.close();
9534
+ } catch {}
9535
+ }
9536
+ };
9537
+ }
9538
+ async function runPiRpcProviderFallback(input) {
9539
+ const stdout = input.stdout ?? process.stdout;
9540
+ const stderr = input.stderr ?? process.stderr;
9541
+ const proc = Bun.spawn(input.command, {
9542
+ cwd: input.cwd,
9543
+ env: input.env,
9544
+ stdin: "pipe",
9545
+ stdout: "pipe",
9546
+ stderr: "pipe"
9547
+ });
9548
+ let sawAgentEnd = false;
9549
+ let promptError = null;
9550
+ let stdinOpen = true;
9551
+ let steeringPollStopped = false;
9552
+ const closeStdin = () => {
9553
+ if (!stdinOpen)
9554
+ return;
9555
+ stdinOpen = false;
9556
+ try {
9557
+ steeringPollStopped = true;
9558
+ proc.stdin.end();
9559
+ } catch {}
9560
+ };
9561
+ const send = (command) => {
9562
+ if (!stdinOpen)
9563
+ return;
9564
+ try {
9565
+ writeRpcCommand(proc.stdin, command);
9566
+ } catch (error) {
9567
+ promptError ??= error instanceof Error ? error.message : String(error);
9568
+ }
9569
+ };
9570
+ const forwardSigterm = () => {
9571
+ try {
9572
+ proc.kill("SIGTERM");
9573
+ } catch {}
9574
+ };
9575
+ process.once("SIGTERM", forwardSigterm);
9576
+ const pollSteering = async () => {
9577
+ const serverUrl = input.env.RIG_SERVER_URL || input.env.RIG_SERVER_BASE_URL;
9578
+ const authToken = input.env.RIG_AUTH_TOKEN || input.env.RIG_SERVER_AUTH_TOKEN;
9579
+ while (!steeringPollStopped && stdinOpen) {
9580
+ try {
9581
+ const messages = await readQueuedSteeringFromServer({ serverUrl, authToken, runId: input.runId });
9582
+ for (const message of messages) {
9583
+ const text = steeringMessageText(message);
9584
+ if (!text || !stdinOpen)
9585
+ continue;
9586
+ send({
9587
+ id: typeof message.id === "string" ? `rig_steer_${message.id}` : `rig_steer_${Date.now()}`,
9588
+ type: "prompt",
9589
+ message: text,
9590
+ streamingBehavior: "steer"
9591
+ });
9592
+ emitWrapperEvent("pi.rpc.steering.delivered", {
9593
+ runId: input.runId ?? null,
9594
+ steeringId: typeof message.id === "string" ? message.id : null,
9595
+ actor: typeof message.actor === "string" ? message.actor : "operator",
9596
+ message: text
9597
+ });
9598
+ }
9599
+ } catch (error) {
9600
+ emitWrapperEvent("pi.rpc.steering.poll.failed", {
9601
+ runId: input.runId ?? null,
9602
+ error: error instanceof Error ? error.message : String(error)
9603
+ });
9604
+ }
9605
+ await sleep2(1000);
9606
+ }
9607
+ };
9608
+ const stdoutPump = pumpReadableLines(proc.stdout, (line) => {
9609
+ stdout.write(`${line}
9610
+ `);
9611
+ const record = parseJsonRecord(line.trim());
9612
+ if (!record)
9613
+ return;
9614
+ if (record.type === "agent_end") {
9615
+ sawAgentEnd = true;
9616
+ closeStdin();
9617
+ return;
9618
+ }
9619
+ if (record.type === "response" && record.command === "prompt" && record.success === false) {
9620
+ promptError = typeof record.error === "string" ? record.error : "Pi RPC prompt failed.";
9621
+ closeStdin();
9622
+ return;
9623
+ }
9624
+ if (isBlockingPiRpcUiRequest(record)) {
9625
+ const id = typeof record.id === "string" ? record.id : "";
9626
+ if (id) {
9627
+ send({ type: "extension_ui_response", id, cancelled: true });
9628
+ emitWrapperEvent("pi.rpc.extension_ui.cancelled", {
9629
+ id,
9630
+ method: record.method,
9631
+ reason: "noninteractive Rig worker RPC session"
9632
+ });
9633
+ }
9634
+ }
9635
+ });
9636
+ const stderrPump = pumpReadableLines(proc.stderr, (line) => {
9637
+ stderr.write(`${line}
9638
+ `);
9639
+ });
9640
+ if (input.sessionName?.trim()) {
9641
+ send({ id: "rig_set_session_name", type: "set_session_name", name: input.sessionName.trim() });
9642
+ }
9643
+ const steeringPollPromise = pollSteering();
9644
+ if (input.prompt.trim()) {
9645
+ send({ id: "rig_initial_prompt", type: "prompt", message: input.prompt });
9646
+ emitWrapperEvent("pi.rpc.prompt.sent", {
9647
+ runId: input.runId ?? null,
9648
+ kind: "initial",
9649
+ bytes: Buffer.byteLength(input.prompt)
9650
+ });
9651
+ } else {
9652
+ closeStdin();
9653
+ }
9654
+ const exitCode = await proc.exited;
9655
+ process.off("SIGTERM", forwardSigterm);
9656
+ steeringPollStopped = true;
9657
+ await Promise.all([stdoutPump, stderrPump, steeringPollPromise]);
9658
+ if (promptError) {
9659
+ stderr.write(`[rig-agent] Pi RPC prompt failed: ${promptError}
9660
+ `);
9661
+ return exitCode === 0 ? 1 : exitCode;
9662
+ }
9663
+ if (input.prompt.trim() && !sawAgentEnd && exitCode === 0) {
9664
+ stderr.write(`[rig-agent] Pi RPC exited before emitting agent_end.
9665
+ `);
9666
+ return 1;
9667
+ }
9668
+ return exitCode;
9669
+ }
9328
9670
  function resolveFinalProviderExitCode(input) {
9329
9671
  if (input.providerExitCode !== 0) {
9330
9672
  return input.providerExitCode;
9331
9673
  }
9332
- if (input.taskClosed) {
9674
+ if (input.taskClosed || input.serverManagedRun) {
9333
9675
  return 0;
9334
9676
  }
9335
- return input.serverManagedRun ? 2 : 0;
9677
+ return 0;
9336
9678
  }
9337
9679
  function shouldBypassProviderSandboxOnPlatform(provider, platform) {
9338
9680
  if (platform !== "darwin") {
@@ -9356,14 +9698,27 @@ function buildProviderArgs(provider, runtime, argv) {
9356
9698
  }
9357
9699
  if (provider === "pi") {
9358
9700
  const piArgs = [...argv];
9701
+ if (piArgs.includes("__rig_pi_session_daemon__")) {
9702
+ return piArgs.filter((arg) => arg !== "__rig_pi_session_daemon__");
9703
+ }
9704
+ const piProvider = cliOptionValue(piArgs, "--provider") || process.env.RIG_PI_PROVIDER?.trim() || "openai-codex";
9359
9705
  if (!hasCliOption(piArgs, "--provider")) {
9360
- piArgs.unshift(process.env.RIG_PI_PROVIDER?.trim() || "openai-codex");
9706
+ piArgs.unshift(piProvider);
9361
9707
  piArgs.unshift("--provider");
9362
9708
  }
9363
- if (!hasCliOption(piArgs, "--model")) {
9364
- piArgs.unshift(process.env.RIG_PI_MODEL?.trim() || "gpt-5.5");
9709
+ const model = cliOptionValue(piArgs, "--model") || process.env.RIG_PI_MODEL?.trim() || "gpt-5.5";
9710
+ if (hasCliOption(piArgs, "--model")) {
9711
+ rewriteCliOptionValue(piArgs, "--model", normalizePiModelForProvider(model, piProvider));
9712
+ } else {
9713
+ piArgs.unshift(normalizePiModelForProvider(model, piProvider));
9365
9714
  piArgs.unshift("--model");
9366
9715
  }
9716
+ if (!hasCliOption(piArgs, "--mode")) {
9717
+ piArgs.push("--mode", process.env.RIG_PI_TRANSPORT?.trim() === "print" ? "json" : "rpc");
9718
+ if (process.env.RIG_PI_TRANSPORT?.trim() === "print" && !hasCliOption(piArgs, "--print")) {
9719
+ piArgs.push("--print");
9720
+ }
9721
+ }
9367
9722
  return piArgs;
9368
9723
  }
9369
9724
  return [
@@ -9413,6 +9768,7 @@ async function runBeadsJson(projectRoot, args) {
9413
9768
  return null;
9414
9769
  }
9415
9770
  }
9771
+ var warnedUnknownRuntimeAdapter = false;
9416
9772
  function resolveProvider() {
9417
9773
  const value = process.env.RIG_RUNTIME_ADAPTER?.trim().toLowerCase();
9418
9774
  if (!value) {
@@ -9424,28 +9780,85 @@ function resolveProvider() {
9424
9780
  if (value === "pi" || value === "rig-pi" || value === "@rig/pi") {
9425
9781
  return "pi";
9426
9782
  }
9783
+ if (value !== "claude-code" && value !== "claude" && !warnedUnknownRuntimeAdapter) {
9784
+ warnedUnknownRuntimeAdapter = true;
9785
+ console.warn(`[rig-agent] Unknown RIG_RUNTIME_ADAPTER value "${value}"; falling back to claude-code. Use pi|claude-code|codex.`);
9786
+ }
9427
9787
  return "claude-code";
9428
9788
  }
9429
9789
  function hasCliOption(argv, option) {
9430
9790
  return argv.some((arg) => arg === option || arg.startsWith(`${option}=`));
9431
9791
  }
9792
+ function cliOptionValue(argv, option) {
9793
+ for (let index = 0;index < argv.length; index += 1) {
9794
+ const arg = argv[index];
9795
+ if (arg === option) {
9796
+ const next = argv[index + 1];
9797
+ return next && !next.startsWith("--") ? next : undefined;
9798
+ }
9799
+ if (arg?.startsWith(`${option}=`)) {
9800
+ return arg.slice(option.length + 1);
9801
+ }
9802
+ }
9803
+ return;
9804
+ }
9805
+ function rewriteCliOptionValue(argv, option, value) {
9806
+ for (let index = 0;index < argv.length; index += 1) {
9807
+ const arg = argv[index];
9808
+ if (arg === option && argv[index + 1] && !argv[index + 1].startsWith("--")) {
9809
+ argv[index + 1] = value;
9810
+ return;
9811
+ }
9812
+ if (arg?.startsWith(`${option}=`)) {
9813
+ argv[index] = `${option}=${value}`;
9814
+ return;
9815
+ }
9816
+ }
9817
+ }
9818
+ function normalizePiModelForProvider(model, provider) {
9819
+ if (provider === "openrouter" && model === "openai-codex/gpt-5.5") {
9820
+ return "openai/gpt-5.5";
9821
+ }
9822
+ return model;
9823
+ }
9824
+ function resolveFromShellPath(binary) {
9825
+ const resolved = Bun.spawnSync(["sh", "-lc", `command -v ${binary}`], {
9826
+ stdout: "pipe",
9827
+ stderr: "ignore",
9828
+ stdin: "ignore",
9829
+ env: process.env
9830
+ });
9831
+ if (resolved.exitCode !== 0)
9832
+ return null;
9833
+ const path = resolved.stdout.toString().trim().split(/\r?\n/)[0]?.trim();
9834
+ return path || null;
9835
+ }
9836
+ function resolveBundledPiBinary() {
9837
+ try {
9838
+ const packageJson = requireFromRuntime.resolve("@earendil-works/pi-coding-agent/package.json");
9839
+ const binaryPath = resolve37(packageJson, "..", "dist", "cli.js");
9840
+ return existsSync35(binaryPath) ? binaryPath : null;
9841
+ } catch {
9842
+ return null;
9843
+ }
9844
+ }
9432
9845
  function providerBinary(provider) {
9433
9846
  if (provider === "codex") {
9434
- return Bun.which("codex") || "codex";
9847
+ return resolveFromShellPath("codex") || Bun.which("codex") || "codex";
9435
9848
  }
9436
9849
  if (provider === "pi") {
9437
- return Bun.which("pi") || "pi";
9850
+ return process.env.RIG_PI_BINARY?.trim() || resolveBundledPiBinary() || resolveFromShellPath("pi") || Bun.which("pi") || "pi";
9438
9851
  }
9439
9852
  try {
9440
9853
  return resolveClaudeBinaryPath();
9441
9854
  } catch {
9442
- return Bun.which("claude") || "claude";
9855
+ return resolveFromShellPath("claude") || Bun.which("claude") || "claude";
9443
9856
  }
9444
9857
  }
9445
9858
  function emitWrapperEvent(type, payload) {
9446
9859
  console.log(`__RIG_WRAPPER_EVENT__${JSON.stringify({ type, payload, at: new Date().toISOString() })}`);
9447
9860
  }
9448
- function sleep(ms) {
9861
+ function sleep2(ms) {
9449
9862
  return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
9450
9863
  }
9451
9864
  async function waitForDirtyBaselineReady(runtime, taskId) {
@@ -9460,11 +9873,11 @@ async function waitForDirtyBaselineReady(runtime, taskId) {
9460
9873
  workspaceDir: runtime.workspaceDir,
9461
9874
  readyFile
9462
9875
  });
9463
- while (!existsSync33(readyFile)) {
9876
+ while (!existsSync35(readyFile)) {
9464
9877
  if (Date.now() >= deadline) {
9465
9878
  throw new Error(`Timed out waiting for dirty baseline ready file: ${readyFile}`);
9466
9879
  }
9467
- await sleep(50);
9880
+ await sleep2(50);
9468
9881
  }
9469
9882
  emitWrapperEvent("runtime.baseline.completed", {
9470
9883
  runtimeId: runtime.id,
@@ -9527,43 +9940,10 @@ async function readPluginTaskStatus(projectRoot, taskId) {
9527
9940
  return readSourceAwareTaskStatus(projectRoot, taskId);
9528
9941
  }
9529
9942
  }
9530
- async function updateTaskSourceAfterRun(projectRoot, taskId, runtime) {
9531
- const comment = buildTaskRunLifecycleComment({
9532
- runId: process.env.RIG_SERVER_RUN_ID || "(unknown)",
9533
- status: "closed",
9534
- summary: "Rig task run completed and closed this task.",
9535
- runtimeWorkspace: runtime.workspaceDir,
9536
- logsDir: runtime.logsDir,
9537
- sessionDir: runtime.sessionDir
9538
- });
9539
- try {
9540
- const result = await updateConfiguredTaskSourceTask(projectRoot, {
9541
- taskId,
9542
- update: { status: "closed", comment }
9543
- });
9544
- if (result.updated) {
9545
- return;
9546
- }
9547
- throw new Error(result.source === "plugin" || result.sourceKind ? `configured task source${result.sourceKind ? ` (${result.sourceKind})` : ""} does not support lifecycle updates` : "no source-aware task source is configured");
9548
- } catch (error) {
9549
- let fallbackUpdated = false;
9550
- try {
9551
- fallbackUpdated = updateSourceAwareTaskConfigTask(projectRoot, taskId, { status: "closed", comment });
9552
- } catch (fallbackError) {
9553
- console.error(`[rig-agent] Source-aware compatibility update also failed for ${taskId}: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`);
9554
- }
9555
- const message = `[rig-agent] Failed to update task source for ${taskId}${fallbackUpdated ? "; applied source-aware compatibility update" : ""}: ${error instanceof Error ? error.message : String(error)}`;
9556
- if (fallbackUpdated) {
9557
- console.log(message);
9558
- } else {
9559
- console.error(message);
9560
- }
9561
- }
9562
- }
9563
9943
  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`);
9944
+ const handoffDir = resolve37(hostProjectRoot, ".rig/runtime/handoffs");
9945
+ mkdirSync21(handoffDir, { recursive: true });
9946
+ const handoffPath = resolve37(handoffDir, `${taskId}-${Date.now()}.json`);
9567
9947
  const handoff = {
9568
9948
  taskId,
9569
9949
  runtimeId: runtime.id,
@@ -9579,7 +9959,7 @@ function recordRuntimeHandoff(hostProjectRoot, runtime, taskId, exitCode) {
9579
9959
  `rig git open-pr --task ${taskId}`
9580
9960
  ]
9581
9961
  };
9582
- writeFileSync13(handoffPath, `${JSON.stringify(handoff, null, 2)}
9962
+ writeFileSync14(handoffPath, `${JSON.stringify(handoff, null, 2)}
9583
9963
  `, "utf-8");
9584
9964
  console.log(`[rig-agent] Completion verification paused for ${taskId}.`);
9585
9965
  console.log(`[rig-agent] Runtime handoff saved: ${handoffPath}`);
@@ -9629,13 +10009,13 @@ async function readTaskMetadata2(taskRoot, taskId) {
9629
10009
  async function readTaskConfigHints(taskRoot, taskId) {
9630
10010
  const runtimeContext = loadRuntimeContextFromEnv();
9631
10011
  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")
10012
+ runtimeContext?.monorepoMainRoot ? resolve37(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
10013
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve37(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
10014
+ resolve37(taskRoot, ".rig", "task-config.json"),
10015
+ resolve37(taskRoot, "rig", "task-config.json")
9636
10016
  ].filter(Boolean);
9637
10017
  for (const configPath of candidates) {
9638
- if (!existsSync33(configPath)) {
10018
+ if (!existsSync35(configPath)) {
9639
10019
  continue;
9640
10020
  }
9641
10021
  try {