@h-rig/runtime 0.0.6-alpha.27 → 0.0.6-alpha.29

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 (39) hide show
  1. package/dist/bin/rig-agent-dispatch.js +552 -483
  2. package/dist/bin/rig-agent.js +418 -364
  3. package/dist/src/control-plane/agent-wrapper.js +557 -488
  4. package/dist/src/control-plane/harness-main.js +559 -1418
  5. package/dist/src/control-plane/hooks/completion-verification.js +451 -808
  6. package/dist/src/control-plane/hooks/inject-context.js +191 -137
  7. package/dist/src/control-plane/hooks/submodule-branch.js +596 -542
  8. package/dist/src/control-plane/hooks/task-runtime-start.js +596 -542
  9. package/dist/src/control-plane/materialize-task-config.js +64 -8
  10. package/dist/src/control-plane/native/git-ops.js +3 -0
  11. package/dist/src/control-plane/native/harness-cli.js +544 -496
  12. package/dist/src/control-plane/native/repo-ops.js +3 -0
  13. package/dist/src/control-plane/native/run-ops.js +3 -0
  14. package/dist/src/control-plane/native/task-ops.js +418 -370
  15. package/dist/src/control-plane/native/validator.js +161 -107
  16. package/dist/src/control-plane/native/verifier.js +217 -169
  17. package/dist/src/control-plane/pi-sessiond/launcher.js +12 -2
  18. package/dist/src/control-plane/plugin-host-context.js +54 -0
  19. package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
  20. package/dist/src/control-plane/runtime/image/index.js +3 -0
  21. package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
  22. package/dist/src/control-plane/runtime/image.js +3 -0
  23. package/dist/src/control-plane/runtime/index.js +487 -718
  24. package/dist/src/control-plane/runtime/isolation/index.js +511 -457
  25. package/dist/src/control-plane/runtime/isolation.js +511 -457
  26. package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
  27. package/dist/src/control-plane/runtime/queue.js +428 -381
  28. package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
  29. package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
  30. package/dist/src/control-plane/skill-materializer.js +46 -0
  31. package/dist/src/control-plane/tasks/source-lifecycle.js +84 -30
  32. package/dist/src/index.js +0 -278
  33. package/native/darwin-arm64/rig-shell +0 -0
  34. package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
  35. package/native/darwin-arm64/rig-tools +0 -0
  36. package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
  37. package/package.json +8 -7
  38. package/dist/src/control-plane/runtime/plugins.js +0 -1131
  39. package/dist/src/plugins.js +0 -329
@@ -2,8 +2,8 @@
2
2
  // @bun
3
3
 
4
4
  // packages/runtime/bin/rig-agent.ts
5
- import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "fs";
6
- import { dirname as dirname17, resolve as resolve31 } from "path";
5
+ import { existsSync as existsSync29, mkdirSync as mkdirSync17, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "fs";
6
+ import { dirname as dirname17, resolve as resolve32 } from "path";
7
7
 
8
8
  // packages/runtime/src/control-plane/controlled-bash.ts
9
9
  import { readFileSync as readFileSync3 } from "fs";
@@ -3616,13 +3616,13 @@ class GeneralCliEventBus {
3616
3616
  }
3617
3617
 
3618
3618
  // packages/runtime/src/control-plane/native/git-ops.ts
3619
- import { existsSync as existsSync22, lstatSync, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "fs";
3620
- import { dirname as dirname14, isAbsolute as isAbsolute2, resolve as resolve26 } from "path";
3619
+ import { existsSync as existsSync23, lstatSync, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "fs";
3620
+ import { dirname as dirname14, isAbsolute as isAbsolute2, resolve as resolve27 } from "path";
3621
3621
  import { fileURLToPath as fileURLToPath2 } from "url";
3622
3622
 
3623
3623
  // packages/runtime/src/control-plane/native/task-ops.ts
3624
- import { appendFileSync, existsSync as existsSync21, mkdirSync as mkdirSync9, readFileSync as readFileSync12, writeFileSync as writeFileSync9 } from "fs";
3625
- import { resolve as resolve25 } from "path";
3624
+ import { appendFileSync, existsSync as existsSync22, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "fs";
3625
+ import { resolve as resolve26 } from "path";
3626
3626
 
3627
3627
  // packages/runtime/src/control-plane/runtime/tooling/shell.ts
3628
3628
  import { tmpdir as tmpdir4 } from "os";
@@ -3983,6 +3983,49 @@ function safeReadJson(path) {
3983
3983
  }
3984
3984
  }
3985
3985
 
3986
+ // packages/runtime/src/control-plane/skill-materializer.ts
3987
+ import { existsSync as existsSync11, mkdirSync as mkdirSync6, readFileSync as readFileSync8, readdirSync, rmSync as rmSync4, writeFileSync as writeFileSync5 } from "fs";
3988
+ import { resolve as resolve14 } from "path";
3989
+ import { loadSkill } from "@rig/skill-loader";
3990
+ var MARKER_FILENAME = ".rig-plugin";
3991
+ function skillDirName(id) {
3992
+ return id.replace(/[^a-zA-Z0-9._-]+/g, "-");
3993
+ }
3994
+ async function materializeSkills(projectRoot, entries) {
3995
+ const skillsRoot = resolve14(projectRoot, ".pi", "skills");
3996
+ if (existsSync11(skillsRoot)) {
3997
+ for (const name of readdirSync(skillsRoot)) {
3998
+ const dir = resolve14(skillsRoot, name);
3999
+ if (existsSync11(resolve14(dir, MARKER_FILENAME))) {
4000
+ rmSync4(dir, { recursive: true, force: true });
4001
+ }
4002
+ }
4003
+ }
4004
+ const written = [];
4005
+ for (const { pluginName, skill } of entries) {
4006
+ const sourcePath = resolve14(projectRoot, skill.path);
4007
+ if (!existsSync11(sourcePath)) {
4008
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${sourcePath} does not exist`);
4009
+ continue;
4010
+ }
4011
+ let body;
4012
+ try {
4013
+ await loadSkill(sourcePath);
4014
+ body = readFileSync8(sourcePath, "utf-8");
4015
+ } catch (err) {
4016
+ console.warn(`[plugin-host] skill "${skill.id}" from plugin "${pluginName}" not materialized: ${err instanceof Error ? err.message : err}`);
4017
+ continue;
4018
+ }
4019
+ const dir = resolve14(skillsRoot, skillDirName(skill.id));
4020
+ mkdirSync6(dir, { recursive: true });
4021
+ writeFileSync5(resolve14(dir, "SKILL.md"), body, "utf-8");
4022
+ writeFileSync5(resolve14(dir, MARKER_FILENAME), `${JSON.stringify({ plugin: pluginName, skillId: skill.id }, null, 2)}
4023
+ `, "utf-8");
4024
+ written.push({ id: skill.id, pluginName, directory: dir });
4025
+ }
4026
+ return written;
4027
+ }
4028
+
3986
4029
  // packages/runtime/src/control-plane/plugin-host-context.ts
3987
4030
  async function buildPluginHostContext(projectRoot) {
3988
4031
  let config;
@@ -4019,6 +4062,17 @@ async function buildPluginHostContext(projectRoot) {
4019
4062
  } catch (err) {
4020
4063
  console.warn(`[plugin-host] hook materialization failed: ${err instanceof Error ? err.message : err}`);
4021
4064
  }
4065
+ try {
4066
+ const skillEntries = config.plugins.flatMap((plugin) => (plugin.contributes?.skills ?? []).map((skill) => ({
4067
+ pluginName: plugin.name,
4068
+ skill
4069
+ })));
4070
+ if (skillEntries.length > 0) {
4071
+ await materializeSkills(projectRoot, skillEntries);
4072
+ }
4073
+ } catch (err) {
4074
+ console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
4075
+ }
4022
4076
  return {
4023
4077
  config,
4024
4078
  pluginHost,
@@ -4032,12 +4086,12 @@ async function buildPluginHostContext(projectRoot) {
4032
4086
 
4033
4087
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
4034
4088
  import { spawnSync } from "child_process";
4035
- import { existsSync as existsSync12, readFileSync as readFileSync9, readdirSync, statSync as statSync3, writeFileSync as writeFileSync5 } from "fs";
4036
- import { basename as basename4, join as join3, resolve as resolve15 } from "path";
4089
+ import { existsSync as existsSync13, readFileSync as readFileSync10, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync6 } from "fs";
4090
+ import { basename as basename4, join as join3, resolve as resolve16 } from "path";
4037
4091
 
4038
4092
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
4039
- import { existsSync as existsSync11, readFileSync as readFileSync8 } from "fs";
4040
- import { resolve as resolve14 } from "path";
4093
+ import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
4094
+ import { resolve as resolve15 } from "path";
4041
4095
 
4042
4096
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
4043
4097
  async function findTaskById(reader, id) {
@@ -4060,7 +4114,7 @@ class LegacyTaskConfigReadError extends Error {
4060
4114
  }
4061
4115
  }
4062
4116
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
4063
- const configPath = options.configPath ?? resolve14(projectRoot, ".rig", "task-config.json");
4117
+ const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
4064
4118
  const reader = {
4065
4119
  async listTasks() {
4066
4120
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -4071,8 +4125,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
4071
4125
  };
4072
4126
  return reader;
4073
4127
  }
4074
- function readLegacyTaskRecords(projectRoot, configPath = resolve14(projectRoot, ".rig", "task-config.json")) {
4075
- if (!existsSync11(configPath)) {
4128
+ function readLegacyTaskRecords(projectRoot, configPath = resolve15(projectRoot, ".rig", "task-config.json")) {
4129
+ if (!existsSync12(configPath)) {
4076
4130
  return [];
4077
4131
  }
4078
4132
  const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
@@ -4080,7 +4134,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve14(projectRoot,
4080
4134
  }
4081
4135
  function readLegacyTaskConfigJson(projectRoot, configPath) {
4082
4136
  try {
4083
- const parsed = JSON.parse(readFileSync8(configPath, "utf8"));
4137
+ const parsed = JSON.parse(readFileSync9(configPath, "utf8"));
4084
4138
  if (isPlainRecord(parsed)) {
4085
4139
  return parsed;
4086
4140
  }
@@ -4164,7 +4218,7 @@ function isPlainRecord(candidate) {
4164
4218
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
4165
4219
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
4166
4220
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
4167
- const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
4221
+ const configPath = options.configPath ?? resolve16(projectRoot, ".rig", "task-config.json");
4168
4222
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
4169
4223
  const spawnFn = options.spawn ?? spawnSync;
4170
4224
  const ghBinary = options.ghBinary ?? "gh";
@@ -4247,10 +4301,10 @@ function readMaterializedTaskMetadata(entry) {
4247
4301
  return metadata;
4248
4302
  }
4249
4303
  function readConfiguredFilesTaskSourcePath(projectRoot) {
4250
- const jsonPath = resolve15(projectRoot, "rig.config.json");
4251
- if (existsSync12(jsonPath)) {
4304
+ const jsonPath = resolve16(projectRoot, "rig.config.json");
4305
+ if (existsSync13(jsonPath)) {
4252
4306
  try {
4253
- const parsed = JSON.parse(readFileSync9(jsonPath, "utf8"));
4307
+ const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
4254
4308
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
4255
4309
  const source = parsed.taskSource;
4256
4310
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -4259,12 +4313,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
4259
4313
  return null;
4260
4314
  }
4261
4315
  }
4262
- const tsPath = resolve15(projectRoot, "rig.config.ts");
4263
- if (!existsSync12(tsPath)) {
4316
+ const tsPath = resolve16(projectRoot, "rig.config.ts");
4317
+ if (!existsSync13(tsPath)) {
4264
4318
  return null;
4265
4319
  }
4266
4320
  try {
4267
- const source = readFileSync9(tsPath, "utf8");
4321
+ const source = readFileSync10(tsPath, "utf8");
4268
4322
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
4269
4323
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
4270
4324
  if (kind !== "files") {
@@ -4284,10 +4338,10 @@ function readRawTaskEntry(configPath, taskId) {
4284
4338
  return isPlainRecord2(entry) ? entry : null;
4285
4339
  }
4286
4340
  function readRawTaskConfig(configPath) {
4287
- if (!existsSync12(configPath)) {
4341
+ if (!existsSync13(configPath)) {
4288
4342
  return null;
4289
4343
  }
4290
- const parsed = JSON.parse(readFileSync9(configPath, "utf8"));
4344
+ const parsed = JSON.parse(readFileSync10(configPath, "utf8"));
4291
4345
  return isPlainRecord2(parsed) ? parsed : null;
4292
4346
  }
4293
4347
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -4295,12 +4349,12 @@ function stripLegacyTaskConfigMetadata2(raw) {
4295
4349
  return tasks;
4296
4350
  }
4297
4351
  function listFileBackedTasks(projectRoot, sourcePath) {
4298
- const directory = resolve15(projectRoot, sourcePath);
4299
- if (!existsSync12(directory)) {
4352
+ const directory = resolve16(projectRoot, sourcePath);
4353
+ if (!existsSync13(directory)) {
4300
4354
  return [];
4301
4355
  }
4302
4356
  const tasks = [];
4303
- for (const name of readdirSync(directory)) {
4357
+ for (const name of readdirSync2(directory)) {
4304
4358
  if (!FILE_TASK_PATTERN.test(name))
4305
4359
  continue;
4306
4360
  const inferredId = basename4(name).replace(FILE_TASK_PATTERN, "");
@@ -4311,11 +4365,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
4311
4365
  return tasks;
4312
4366
  }
4313
4367
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
4314
- const file = findFileBackedTaskFile(resolve15(projectRoot, sourcePath), taskId);
4368
+ const file = findFileBackedTaskFile(resolve16(projectRoot, sourcePath), taskId);
4315
4369
  if (!file) {
4316
4370
  return null;
4317
4371
  }
4318
- const raw = JSON.parse(readFileSync9(file, "utf8"));
4372
+ const raw = JSON.parse(readFileSync10(file, "utf8"));
4319
4373
  if (!isPlainRecord2(raw)) {
4320
4374
  return null;
4321
4375
  }
@@ -4328,17 +4382,17 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
4328
4382
  };
4329
4383
  }
4330
4384
  function findFileBackedTaskFile(directory, taskId) {
4331
- if (!existsSync12(directory)) {
4385
+ if (!existsSync13(directory)) {
4332
4386
  return null;
4333
4387
  }
4334
- for (const name of readdirSync(directory)) {
4388
+ for (const name of readdirSync2(directory)) {
4335
4389
  if (!FILE_TASK_PATTERN.test(name))
4336
4390
  continue;
4337
4391
  const file = join3(directory, name);
4338
4392
  try {
4339
4393
  if (!statSync3(file).isFile())
4340
4394
  continue;
4341
- const raw = JSON.parse(readFileSync9(file, "utf8"));
4395
+ const raw = JSON.parse(readFileSync10(file, "utf8"));
4342
4396
  const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
4343
4397
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
4344
4398
  if (id === taskId) {
@@ -4498,8 +4552,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
4498
4552
  }
4499
4553
 
4500
4554
  // packages/runtime/src/control-plane/native/task-state.ts
4501
- import { existsSync as existsSync16, readFileSync as readFileSync11, readdirSync as readdirSync2, statSync as statSync4, writeFileSync as writeFileSync6 } from "fs";
4502
- import { basename as basename6, resolve as resolve19 } from "path";
4555
+ import { existsSync as existsSync17, readFileSync as readFileSync12, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync7 } from "fs";
4556
+ import { basename as basename6, resolve as resolve20 } from "path";
4503
4557
 
4504
4558
  // packages/runtime/src/control-plane/state-sync/types.ts
4505
4559
  var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
@@ -4607,38 +4661,38 @@ function readTaskStateMetadataEnvelope(raw) {
4607
4661
  };
4608
4662
  }
4609
4663
  // packages/runtime/src/control-plane/state-sync/read.ts
4610
- import { existsSync as existsSync15, readFileSync as readFileSync10 } from "fs";
4611
- import { resolve as resolve18 } from "path";
4664
+ import { existsSync as existsSync16, readFileSync as readFileSync11 } from "fs";
4665
+ import { resolve as resolve19 } from "path";
4612
4666
 
4613
4667
  // packages/runtime/src/control-plane/state-sync/repo.ts
4614
- import { existsSync as existsSync14 } from "fs";
4615
- import { resolve as resolve17 } from "path";
4668
+ import { existsSync as existsSync15 } from "fs";
4669
+ import { resolve as resolve18 } from "path";
4616
4670
 
4617
4671
  // packages/runtime/src/control-plane/repos/layout.ts
4618
- import { existsSync as existsSync13 } from "fs";
4619
- import { basename as basename5, dirname as dirname11, join as join4, resolve as resolve16 } from "path";
4672
+ import { existsSync as existsSync14 } from "fs";
4673
+ import { basename as basename5, dirname as dirname11, join as join4, resolve as resolve17 } from "path";
4620
4674
  function resolveRepoStateDir(projectRoot) {
4621
- const normalizedProjectRoot = resolve16(projectRoot);
4675
+ const normalizedProjectRoot = resolve17(projectRoot);
4622
4676
  const projectParent = dirname11(normalizedProjectRoot);
4623
4677
  if (basename5(projectParent) === ".worktrees") {
4624
4678
  const ownerRoot = dirname11(projectParent);
4625
- const ownerHasRepoMarkers = existsSync13(resolve16(ownerRoot, ".git")) || existsSync13(resolve16(ownerRoot, ".rig", "state"));
4679
+ const ownerHasRepoMarkers = existsSync14(resolve17(ownerRoot, ".git")) || existsSync14(resolve17(ownerRoot, ".rig", "state"));
4626
4680
  if (ownerHasRepoMarkers) {
4627
- return resolve16(ownerRoot, ".rig", "state");
4681
+ return resolve17(ownerRoot, ".rig", "state");
4628
4682
  }
4629
4683
  }
4630
- return resolve16(projectRoot, ".rig", "state");
4684
+ return resolve17(projectRoot, ".rig", "state");
4631
4685
  }
4632
4686
  function resolveManagedRepoLayout(projectRoot, repoId) {
4633
- const normalizedProjectRoot = resolve16(projectRoot);
4687
+ const normalizedProjectRoot = resolve17(projectRoot);
4634
4688
  const entry = getManagedRepoEntry(repoId);
4635
4689
  const stateDir = resolveRepoStateDir(normalizedProjectRoot);
4636
4690
  const metadataRelativePath = join4("repos", entry.id);
4637
- const metadataRoot = resolve16(stateDir, metadataRelativePath);
4691
+ const metadataRoot = resolve17(stateDir, metadataRelativePath);
4638
4692
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
4639
- const runsInsideTaskWorktree = runtimeWorkspace && resolve16(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname11(normalizedProjectRoot)) === ".worktrees";
4693
+ const runsInsideTaskWorktree = runtimeWorkspace && resolve17(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname11(normalizedProjectRoot)) === ".worktrees";
4640
4694
  const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
4641
- const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve16(process.env[entry.checkoutEnvVar].trim()) : resolve16(normalizedProjectRoot, entry.alias);
4695
+ const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve17(process.env[entry.checkoutEnvVar].trim()) : resolve17(normalizedProjectRoot, entry.alias);
4642
4696
  return {
4643
4697
  projectRoot: normalizedProjectRoot,
4644
4698
  repoId: entry.id,
@@ -4646,12 +4700,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
4646
4700
  defaultBranch: entry.defaultBranch,
4647
4701
  remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
4648
4702
  checkoutRoot,
4649
- worktreesRoot: resolve16(checkoutRoot, ".worktrees"),
4703
+ worktreesRoot: resolve17(checkoutRoot, ".worktrees"),
4650
4704
  stateDir,
4651
4705
  metadataRoot,
4652
4706
  metadataRelativePath,
4653
- mirrorRoot: resolve16(metadataRoot, "mirror.git"),
4654
- mirrorStatePath: resolve16(metadataRoot, "mirror-state.json"),
4707
+ mirrorRoot: resolve17(metadataRoot, "mirror.git"),
4708
+ mirrorStatePath: resolve17(metadataRoot, "mirror-state.json"),
4655
4709
  mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
4656
4710
  };
4657
4711
  }
@@ -4673,7 +4727,7 @@ function resolveTrackerRepoPath(projectRoot) {
4673
4727
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
4674
4728
  try {
4675
4729
  const layout = resolveMonorepoRepoLayout(projectRoot);
4676
- if (existsSync14(resolve17(layout.mirrorRoot, "HEAD"))) {
4730
+ if (existsSync15(resolve18(layout.mirrorRoot, "HEAD"))) {
4677
4731
  return layout.mirrorRoot;
4678
4732
  }
4679
4733
  } catch {}
@@ -4684,8 +4738,8 @@ function resolveTrackerRepoPath(projectRoot) {
4684
4738
  var DEFAULT_READ_DEPS2 = {
4685
4739
  fetchRef: nativeFetchRef,
4686
4740
  readBlobAtRef: nativeReadBlobAtRef,
4687
- exists: existsSync15,
4688
- readFile: (path) => readFileSync10(path, "utf8")
4741
+ exists: existsSync16,
4742
+ readFile: (path) => readFileSync11(path, "utf8")
4689
4743
  };
4690
4744
  function parseIssueStatus(rawStatus) {
4691
4745
  const normalized = normalizeTaskLifecycleStatus(rawStatus);
@@ -4766,12 +4820,12 @@ function shouldPreferLocalTrackerState(options) {
4766
4820
  if (runtimeContextPath) {
4767
4821
  return true;
4768
4822
  }
4769
- return existsSync15(resolve18(runtimeWorkspace, ".rig", "runtime-context.json"));
4823
+ return existsSync16(resolve19(runtimeWorkspace, ".rig", "runtime-context.json"));
4770
4824
  }
4771
4825
  function readLocalTrackerState(projectRoot, deps) {
4772
4826
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
4773
- const issuesPath = resolve18(monorepoRoot, ".beads", "issues.jsonl");
4774
- const taskStatePath = resolve18(monorepoRoot, ".beads", "task-state.json");
4827
+ const issuesPath = resolve19(monorepoRoot, ".beads", "issues.jsonl");
4828
+ const taskStatePath = resolve19(monorepoRoot, ".beads", "task-state.json");
4775
4829
  return projectSyncedTrackerSnapshot({
4776
4830
  source: "local",
4777
4831
  issuesBaseOid: null,
@@ -4833,7 +4887,7 @@ function readValidationDescriptions(projectRoot) {
4833
4887
  return readValidationDescriptionMap(raw);
4834
4888
  }
4835
4889
  function readSourceValidationDescriptions(projectRoot) {
4836
- const rootRaw = readJsonFile(resolve19(projectRoot, "rig", "task-config.json"), {});
4890
+ const rootRaw = readJsonFile(resolve20(projectRoot, "rig", "task-config.json"), {});
4837
4891
  const sourcePath = findSourceTaskConfigPath(projectRoot);
4838
4892
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
4839
4893
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -4909,15 +4963,15 @@ function readValidationDescriptionsFromMeta(meta) {
4909
4963
  return meta.validation_descriptions;
4910
4964
  }
4911
4965
  function readLocalSourceTaskStateEnvelope(projectRoot) {
4912
- const taskStatePath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
4966
+ const taskStatePath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
4913
4967
  return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
4914
4968
  }
4915
4969
  function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
4916
- const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
4917
- if (!existsSync16(issuesPath)) {
4970
+ const issuesPath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
4971
+ if (!existsSync17(issuesPath)) {
4918
4972
  return null;
4919
4973
  }
4920
- for (const line of readFileSync11(issuesPath, "utf8").split(/\r?\n/)) {
4974
+ for (const line of readFileSync12(issuesPath, "utf8").split(/\r?\n/)) {
4921
4975
  const trimmed = line.trim();
4922
4976
  if (!trimmed) {
4923
4977
  continue;
@@ -4958,25 +5012,25 @@ function lookupTask(projectRoot, input) {
4958
5012
  function artifactDirForId(projectRoot, id) {
4959
5013
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
4960
5014
  if (workspaceDir) {
4961
- const worktreeArtifacts = resolve19(workspaceDir, "artifacts", id);
4962
- if (existsSync16(worktreeArtifacts) || existsSync16(resolve19(workspaceDir, "artifacts"))) {
5015
+ const worktreeArtifacts = resolve20(workspaceDir, "artifacts", id);
5016
+ if (existsSync17(worktreeArtifacts) || existsSync17(resolve20(workspaceDir, "artifacts"))) {
4963
5017
  return worktreeArtifacts;
4964
5018
  }
4965
5019
  }
4966
5020
  try {
4967
5021
  const paths = resolveHarnessPaths(projectRoot);
4968
- return resolve19(paths.artifactsDir, id);
5022
+ return resolve20(paths.artifactsDir, id);
4969
5023
  } catch {
4970
- return resolve19(resolveMonorepoRoot2(projectRoot), "artifacts", id);
5024
+ return resolve20(resolveMonorepoRoot2(projectRoot), "artifacts", id);
4971
5025
  }
4972
5026
  }
4973
5027
  function resolveTaskConfigPath(projectRoot) {
4974
5028
  const paths = resolveHarnessPaths(projectRoot);
4975
- if (existsSync16(paths.taskConfigPath)) {
5029
+ if (existsSync17(paths.taskConfigPath)) {
4976
5030
  return paths.taskConfigPath;
4977
5031
  }
4978
5032
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
4979
- if (existsSync16(candidate)) {
5033
+ if (existsSync17(candidate)) {
4980
5034
  return candidate;
4981
5035
  }
4982
5036
  }
@@ -4984,7 +5038,7 @@ function resolveTaskConfigPath(projectRoot) {
4984
5038
  }
4985
5039
  function findSourceTaskConfigPath(projectRoot) {
4986
5040
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
4987
- if (existsSync16(candidate)) {
5041
+ if (existsSync17(candidate)) {
4988
5042
  return candidate;
4989
5043
  }
4990
5044
  }
@@ -4997,7 +5051,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
4997
5051
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
4998
5052
  if (sourcePath && synced.updated) {
4999
5053
  try {
5000
- writeFileSync6(sourcePath, `${JSON.stringify(synced.config, null, 2)}
5054
+ writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
5001
5055
  `, "utf-8");
5002
5056
  } catch {}
5003
5057
  }
@@ -5049,12 +5103,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
5049
5103
  return !candidate.role;
5050
5104
  }
5051
5105
  function readSourceIssueRecords(projectRoot) {
5052
- const issuesPath = resolve19(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
5053
- if (!existsSync16(issuesPath)) {
5106
+ const issuesPath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
5107
+ if (!existsSync17(issuesPath)) {
5054
5108
  return [];
5055
5109
  }
5056
5110
  const records = [];
5057
- for (const line of readFileSync11(issuesPath, "utf-8").split(/\r?\n/)) {
5111
+ for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
5058
5112
  const trimmed = line.trim();
5059
5113
  if (!trimmed) {
5060
5114
  continue;
@@ -5110,19 +5164,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
5110
5164
  if (!sourcePath) {
5111
5165
  return {};
5112
5166
  }
5113
- const directory = resolve19(projectRoot, sourcePath);
5114
- if (!existsSync16(directory)) {
5167
+ const directory = resolve20(projectRoot, sourcePath);
5168
+ if (!existsSync17(directory)) {
5115
5169
  return {};
5116
5170
  }
5117
5171
  const config = {};
5118
- for (const name of readdirSync2(directory)) {
5172
+ for (const name of readdirSync3(directory)) {
5119
5173
  if (!FILE_TASK_PATTERN2.test(name))
5120
5174
  continue;
5121
- const file = resolve19(directory, name);
5175
+ const file = resolve20(directory, name);
5122
5176
  try {
5123
5177
  if (!statSync4(file).isFile())
5124
5178
  continue;
5125
- const raw = JSON.parse(readFileSync11(file, "utf8"));
5179
+ const raw = JSON.parse(readFileSync12(file, "utf8"));
5126
5180
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
5127
5181
  continue;
5128
5182
  const record = raw;
@@ -5164,10 +5218,10 @@ function firstStringList2(...candidates) {
5164
5218
  return [];
5165
5219
  }
5166
5220
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
5167
- const jsonPath = resolve19(projectRoot, "rig.config.json");
5168
- if (existsSync16(jsonPath)) {
5221
+ const jsonPath = resolve20(projectRoot, "rig.config.json");
5222
+ if (existsSync17(jsonPath)) {
5169
5223
  try {
5170
- const parsed = JSON.parse(readFileSync11(jsonPath, "utf8"));
5224
+ const parsed = JSON.parse(readFileSync12(jsonPath, "utf8"));
5171
5225
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
5172
5226
  const taskSource = parsed.taskSource;
5173
5227
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -5179,12 +5233,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
5179
5233
  return null;
5180
5234
  }
5181
5235
  }
5182
- const tsPath = resolve19(projectRoot, "rig.config.ts");
5183
- if (!existsSync16(tsPath)) {
5236
+ const tsPath = resolve20(projectRoot, "rig.config.ts");
5237
+ if (!existsSync17(tsPath)) {
5184
5238
  return null;
5185
5239
  }
5186
5240
  try {
5187
- const source = readFileSync11(tsPath, "utf8");
5241
+ const source = readFileSync12(tsPath, "utf8");
5188
5242
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
5189
5243
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
5190
5244
  if (kind !== "files") {
@@ -5198,23 +5252,23 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
5198
5252
  function sourceTaskConfigCandidates(projectRoot) {
5199
5253
  const runtimeContext = loadRuntimeContextFromEnv();
5200
5254
  return [
5201
- runtimeContext?.monorepoMainRoot ? resolve19(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
5202
- process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve19(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
5203
- resolve19(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
5255
+ runtimeContext?.monorepoMainRoot ? resolve20(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
5256
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve20(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
5257
+ resolve20(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
5204
5258
  ].filter(Boolean);
5205
5259
  }
5206
5260
 
5207
5261
  // packages/runtime/src/control-plane/native/validator.ts
5208
- import { existsSync as existsSync20, mkdirSync as mkdirSync8, writeFileSync as writeFileSync8 } from "fs";
5209
- import { resolve as resolve24 } from "path";
5262
+ import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
5263
+ import { resolve as resolve25 } from "path";
5210
5264
 
5211
5265
  // packages/runtime/src/control-plane/native/validator-binaries.ts
5212
- import { existsSync as existsSync19, mkdirSync as mkdirSync7, rmSync as rmSync5, statSync as statSync5 } from "fs";
5213
- import { dirname as dirname13, resolve as resolve23 } from "path";
5266
+ import { existsSync as existsSync20, mkdirSync as mkdirSync8, rmSync as rmSync6, statSync as statSync5 } from "fs";
5267
+ import { dirname as dirname13, resolve as resolve24 } from "path";
5214
5268
 
5215
5269
  // packages/runtime/src/binary-run.ts
5216
- import { chmodSync as chmodSync2, cpSync, existsSync as existsSync17, mkdirSync as mkdirSync6, renameSync as renameSync3, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "fs";
5217
- import { basename as basename7, dirname as dirname12, resolve as resolve20 } from "path";
5270
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync18, mkdirSync as mkdirSync7, renameSync as renameSync3, rmSync as rmSync5, writeFileSync as writeFileSync8 } from "fs";
5271
+ import { basename as basename7, dirname as dirname12, resolve as resolve21 } from "path";
5218
5272
  import { fileURLToPath } from "url";
5219
5273
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
5220
5274
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -5240,9 +5294,9 @@ async function buildRuntimeBinary(options) {
5240
5294
  });
5241
5295
  }
5242
5296
  async function buildRuntimeBinaryInProcess(options, manifest) {
5243
- const tempBuildDir = resolve20(dirname12(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
5244
- const tempOutputPath = resolve20(tempBuildDir, basename7(options.outputPath));
5245
- mkdirSync6(tempBuildDir, { recursive: true });
5297
+ const tempBuildDir = resolve21(dirname12(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
5298
+ const tempOutputPath = resolve21(tempBuildDir, basename7(options.outputPath));
5299
+ mkdirSync7(tempBuildDir, { recursive: true });
5246
5300
  await withTemporaryEnv({
5247
5301
  ...options.env,
5248
5302
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -5267,7 +5321,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
5267
5321
  `);
5268
5322
  throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
5269
5323
  }
5270
- if (!existsSync17(tempOutputPath)) {
5324
+ if (!existsSync18(tempOutputPath)) {
5271
5325
  const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
5272
5326
  throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
5273
5327
  }
@@ -5282,7 +5336,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
5282
5336
  });
5283
5337
  }
5284
5338
  })).finally(() => {
5285
- rmSync4(tempBuildDir, { recursive: true, force: true });
5339
+ rmSync5(tempBuildDir, { recursive: true, force: true });
5286
5340
  });
5287
5341
  }
5288
5342
  function runBestEffortBuildGc() {
@@ -5299,8 +5353,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
5299
5353
  function resolveRuntimeBinaryBuildOptions(options) {
5300
5354
  return {
5301
5355
  ...options,
5302
- entrypoint: resolve20(options.cwd, options.sourcePath),
5303
- outputPath: resolve20(options.outputPath)
5356
+ entrypoint: resolve21(options.cwd, options.sourcePath),
5357
+ outputPath: resolve21(options.outputPath)
5304
5358
  };
5305
5359
  }
5306
5360
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -5314,7 +5368,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
5314
5368
  }
5315
5369
  async function buildRuntimeBinaryViaWorker(options) {
5316
5370
  const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
5317
- if (!workerSourcePath || !existsSync17(workerSourcePath)) {
5371
+ if (!workerSourcePath || !existsSync18(workerSourcePath)) {
5318
5372
  await buildRuntimeBinaryInProcess(options, {
5319
5373
  manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
5320
5374
  buildKey: createRuntimeBinaryBuildKey({
@@ -5345,13 +5399,13 @@ async function buildRuntimeBinaryViaWorker(options) {
5345
5399
  new Response(build.stdout).text(),
5346
5400
  new Response(build.stderr).text()
5347
5401
  ]);
5348
- rmSync4(payloadPath, { force: true });
5402
+ rmSync5(payloadPath, { force: true });
5349
5403
  if (exitCode !== 0) {
5350
5404
  throw new Error(`Failed to build ${options.entrypoint}: ${(stderr || stdout || `worker exited ${exitCode}`).trim()}`);
5351
5405
  }
5352
5406
  }
5353
5407
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
5354
- return resolve20(dirname12(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
5408
+ return resolve21(dirname12(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
5355
5409
  }
5356
5410
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
5357
5411
  const envRoots = [
@@ -5360,13 +5414,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
5360
5414
  process.env.PROJECT_RIG_ROOT?.trim()
5361
5415
  ].filter(Boolean);
5362
5416
  for (const root of envRoots) {
5363
- const candidate = resolve20(root, "packages/runtime/src/binary-build-worker.ts");
5364
- if (existsSync17(candidate)) {
5417
+ const candidate = resolve21(root, "packages/runtime/src/binary-build-worker.ts");
5418
+ if (existsSync18(candidate)) {
5365
5419
  return candidate;
5366
5420
  }
5367
5421
  }
5368
- const localCandidate = resolve20(import.meta.dir, "binary-build-worker.ts");
5369
- return existsSync17(localCandidate) ? localCandidate : null;
5422
+ const localCandidate = resolve21(import.meta.dir, "binary-build-worker.ts");
5423
+ return existsSync18(localCandidate) ? localCandidate : null;
5370
5424
  }
5371
5425
  function resolveRuntimeBinaryBuildWorkerInvocation() {
5372
5426
  const bunPath = Bun.which("bun");
@@ -5402,7 +5456,7 @@ function createRuntimeBinaryBuildKey(input) {
5402
5456
  });
5403
5457
  }
5404
5458
  async function isRuntimeBinaryBuildFresh(input) {
5405
- if (!existsSync17(input.outputPath) || !existsSync17(input.manifestPath)) {
5459
+ if (!existsSync18(input.outputPath) || !existsSync18(input.manifestPath)) {
5406
5460
  return false;
5407
5461
  }
5408
5462
  let manifest = null;
@@ -5415,7 +5469,7 @@ async function isRuntimeBinaryBuildFresh(input) {
5415
5469
  return false;
5416
5470
  }
5417
5471
  for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
5418
- if (!existsSync17(filePath)) {
5472
+ if (!existsSync18(filePath)) {
5419
5473
  return false;
5420
5474
  }
5421
5475
  if (await sha256File(filePath) !== expectedDigest) {
@@ -5428,7 +5482,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
5428
5482
  const inputs = {};
5429
5483
  for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
5430
5484
  const normalized = normalizeBuildInputPath(input.cwd, inputPath);
5431
- if (!normalized || !existsSync17(normalized)) {
5485
+ if (!normalized || !existsSync18(normalized)) {
5432
5486
  continue;
5433
5487
  }
5434
5488
  inputs[normalized] = await sha256File(normalized);
@@ -5451,7 +5505,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
5451
5505
  if (inputPath.startsWith("<")) {
5452
5506
  return null;
5453
5507
  }
5454
- return resolve20(cwd, inputPath);
5508
+ return resolve21(cwd, inputPath);
5455
5509
  }
5456
5510
  async function sha256File(path) {
5457
5511
  const hasher = new Bun.CryptoHasher("sha256");
@@ -5467,8 +5521,8 @@ function sortRecord(value) {
5467
5521
  async function runSerializedRuntimeBinaryBuild(action) {
5468
5522
  const previous = runtimeBinaryBuildQueue;
5469
5523
  let release;
5470
- runtimeBinaryBuildQueue = new Promise((resolve21) => {
5471
- release = resolve21;
5524
+ runtimeBinaryBuildQueue = new Promise((resolve22) => {
5525
+ release = resolve22;
5472
5526
  });
5473
5527
  await previous;
5474
5528
  try {
@@ -5513,11 +5567,11 @@ async function withTemporaryCwd(cwd, action) {
5513
5567
  }
5514
5568
 
5515
5569
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
5516
- import { delimiter, resolve as resolve22 } from "path";
5570
+ import { delimiter, resolve as resolve23 } from "path";
5517
5571
 
5518
5572
  // packages/runtime/src/control-plane/runtime/runtime-paths.ts
5519
- import { existsSync as existsSync18, readdirSync as readdirSync3, realpathSync } from "fs";
5520
- import { resolve as resolve21 } from "path";
5573
+ import { existsSync as existsSync19, readdirSync as readdirSync4, realpathSync } from "fs";
5574
+ import { resolve as resolve22 } from "path";
5521
5575
 
5522
5576
  // packages/runtime/src/control-plane/runtime/sandbox/utils.ts
5523
5577
  function uniq(values) {
@@ -5535,7 +5589,7 @@ function resolveBunBinaryPath() {
5535
5589
  }
5536
5590
  const home = process.env.HOME?.trim();
5537
5591
  const fallbackCandidates = [
5538
- home ? resolve21(home, ".bun/bin/bun") : "",
5592
+ home ? resolve22(home, ".bun/bin/bun") : "",
5539
5593
  "/opt/homebrew/bin/bun",
5540
5594
  "/usr/local/bin/bun",
5541
5595
  "/usr/bin/bun"
@@ -5563,8 +5617,8 @@ function resolveClaudeBinaryPath() {
5563
5617
  }
5564
5618
  const home = process.env.HOME?.trim();
5565
5619
  const fallbackCandidates = [
5566
- home ? resolve21(home, ".local/bin/claude") : "",
5567
- home ? resolve21(home, ".local/share/claude/local/claude") : "",
5620
+ home ? resolve22(home, ".local/bin/claude") : "",
5621
+ home ? resolve22(home, ".local/share/claude/local/claude") : "",
5568
5622
  "/opt/homebrew/bin/claude",
5569
5623
  "/usr/local/bin/claude",
5570
5624
  "/usr/bin/claude"
@@ -5578,51 +5632,51 @@ function resolveClaudeBinaryPath() {
5578
5632
  throw new Error("claude not found in PATH");
5579
5633
  }
5580
5634
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
5581
- return resolve21(bunBinaryPath, "../..");
5635
+ return resolve22(bunBinaryPath, "../..");
5582
5636
  }
5583
5637
  function resolveClaudeInstallDir() {
5584
5638
  const realPath = resolveClaudeBinaryPath();
5585
- return resolve21(realPath, "..");
5639
+ return resolve22(realPath, "..");
5586
5640
  }
5587
5641
  function resolveNodeInstallDir() {
5588
5642
  const preferredNode = resolvePreferredNodeBinary();
5589
5643
  if (!preferredNode)
5590
5644
  return null;
5591
5645
  const explicitNode = process.env.RIG_NODE_BIN?.trim();
5592
- if (explicitNode && resolve21(explicitNode) === resolve21(preferredNode)) {
5593
- return preferredNode.endsWith("/bin/node") ? resolve21(preferredNode, "../..") : resolve21(preferredNode, "..");
5646
+ if (explicitNode && resolve22(explicitNode) === resolve22(preferredNode)) {
5647
+ return preferredNode.endsWith("/bin/node") ? resolve22(preferredNode, "../..") : resolve22(preferredNode, "..");
5594
5648
  }
5595
5649
  try {
5596
5650
  const realPath = realpathSync(preferredNode);
5597
5651
  if (realPath.endsWith("/bin/node")) {
5598
- return resolve21(realPath, "../..");
5652
+ return resolve22(realPath, "../..");
5599
5653
  }
5600
- return resolve21(realPath, "..");
5654
+ return resolve22(realPath, "..");
5601
5655
  } catch {
5602
- return resolve21(preferredNode, "..");
5656
+ return resolve22(preferredNode, "..");
5603
5657
  }
5604
5658
  }
5605
5659
  function resolvePreferredNodeBinary() {
5606
5660
  const candidates = [];
5607
5661
  const envNode = process.env.RIG_NODE_BIN?.trim();
5608
5662
  if (envNode) {
5609
- const explicit = resolve21(envNode);
5610
- if (existsSync18(explicit)) {
5663
+ const explicit = resolve22(envNode);
5664
+ if (existsSync19(explicit)) {
5611
5665
  return explicit;
5612
5666
  }
5613
5667
  }
5614
5668
  const nvmBin = process.env.NVM_BIN?.trim();
5615
5669
  if (nvmBin) {
5616
- candidates.push(resolve21(nvmBin, "node"));
5670
+ candidates.push(resolve22(nvmBin, "node"));
5617
5671
  }
5618
5672
  const home = process.env.HOME?.trim();
5619
5673
  if (home) {
5620
- const nvmVersionsDir = resolve21(home, ".nvm/versions/node");
5621
- if (existsSync18(nvmVersionsDir)) {
5674
+ const nvmVersionsDir = resolve22(home, ".nvm/versions/node");
5675
+ if (existsSync19(nvmVersionsDir)) {
5622
5676
  try {
5623
- const versionDirs = readdirSync3(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/, "")));
5677
+ 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/, "")));
5624
5678
  for (const versionDir of versionDirs) {
5625
- candidates.push(resolve21(nvmVersionsDir, versionDir, "bin/node"));
5679
+ candidates.push(resolve22(nvmVersionsDir, versionDir, "bin/node"));
5626
5680
  }
5627
5681
  } catch {}
5628
5682
  }
@@ -5631,8 +5685,8 @@ function resolvePreferredNodeBinary() {
5631
5685
  if (whichNode) {
5632
5686
  candidates.push(whichNode);
5633
5687
  }
5634
- const deduped = uniq(candidates.map((candidate) => resolve21(candidate)));
5635
- const existing = deduped.filter((candidate) => existsSync18(candidate));
5688
+ const deduped = uniq(candidates.map((candidate) => resolve22(candidate)));
5689
+ const existing = deduped.filter((candidate) => existsSync19(candidate));
5636
5690
  if (existing.length === 0) {
5637
5691
  return null;
5638
5692
  }
@@ -5646,7 +5700,7 @@ function resolvePreferredNodeBinary() {
5646
5700
  return existing[0] ?? null;
5647
5701
  }
5648
5702
  function inferNodeMajor(nodeBinaryPath) {
5649
- const normalized = resolve21(nodeBinaryPath).replace(/\\/g, "/");
5703
+ const normalized = resolve22(nodeBinaryPath).replace(/\\/g, "/");
5650
5704
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
5651
5705
  if (!match) {
5652
5706
  return null;
@@ -5658,8 +5712,8 @@ function normalizeExecutablePath(candidate) {
5658
5712
  if (!candidate) {
5659
5713
  return "";
5660
5714
  }
5661
- const normalized = resolve21(candidate);
5662
- if (!existsSync18(normalized)) {
5715
+ const normalized = resolve22(candidate);
5716
+ if (!existsSync19(normalized)) {
5663
5717
  return "";
5664
5718
  }
5665
5719
  try {
@@ -5669,7 +5723,7 @@ function normalizeExecutablePath(candidate) {
5669
5723
  }
5670
5724
  }
5671
5725
  function looksLikeRuntimeGateway(candidate) {
5672
- const normalized = resolve21(candidate).replace(/\\/g, "/");
5726
+ const normalized = resolve22(candidate).replace(/\\/g, "/");
5673
5727
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
5674
5728
  }
5675
5729
 
@@ -5690,7 +5744,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
5690
5744
  try {
5691
5745
  return resolveClaudeInstallDir();
5692
5746
  } catch {
5693
- return resolve22(claudeBinary, "..");
5747
+ return resolve23(claudeBinary, "..");
5694
5748
  }
5695
5749
  })() : "";
5696
5750
  const nodeDir = resolveNodeInstallDir();
@@ -5700,8 +5754,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
5700
5754
  `${bunDir}/bin`,
5701
5755
  claudeDir,
5702
5756
  nodeDir ? `${nodeDir}/bin` : "",
5703
- realHome ? resolve22(realHome, ".local/bin") : "",
5704
- realHome ? resolve22(realHome, ".cargo/bin") : "",
5757
+ realHome ? resolve23(realHome, ".local/bin") : "",
5758
+ realHome ? resolve23(realHome, ".cargo/bin") : "",
5705
5759
  ...inheritedPath,
5706
5760
  "/usr/local/bin",
5707
5761
  "/usr/local/sbin",
@@ -5732,9 +5786,9 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
5732
5786
  // packages/runtime/src/control-plane/native/validator-binaries.ts
5733
5787
  function resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext) {
5734
5788
  if (runtimeContext) {
5735
- return resolve23(runtimeContext.binDir, "validators", binaryName);
5789
+ return resolve24(runtimeContext.binDir, "validators", binaryName);
5736
5790
  }
5737
- return resolve23(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
5791
+ return resolve24(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
5738
5792
  }
5739
5793
  async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
5740
5794
  const match = checkId.match(/^([a-z][\w-]*):([a-z][\w-]*)$/);
@@ -5749,19 +5803,19 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
5749
5803
  const binaryName = `${category}-${check}`;
5750
5804
  const binaryPath = resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
5751
5805
  const hostProjectRoot = runtimeContext?.hostProjectRoot?.trim() || projectRoot;
5752
- const sourcePath = resolve23(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
5753
- if (!existsSync19(sourcePath)) {
5806
+ const sourcePath = resolve24(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
5807
+ if (!existsSync20(sourcePath)) {
5754
5808
  return null;
5755
5809
  }
5756
5810
  const sourceMtime = statSync5(sourcePath).mtimeMs;
5757
- const binaryExists = existsSync19(binaryPath);
5811
+ const binaryExists = existsSync20(binaryPath);
5758
5812
  const binaryMtime = binaryExists ? statSync5(binaryPath).mtimeMs : 0;
5759
5813
  if (!binaryExists || sourceMtime > binaryMtime) {
5760
5814
  if (binaryExists) {
5761
- rmSync5(binaryPath, { force: true });
5762
- rmSync5(`${binaryPath}.build-manifest.json`, { force: true });
5815
+ rmSync6(binaryPath, { force: true });
5816
+ rmSync6(`${binaryPath}.build-manifest.json`, { force: true });
5763
5817
  }
5764
- mkdirSync7(dirname13(binaryPath), { recursive: true });
5818
+ mkdirSync8(dirname13(binaryPath), { recursive: true });
5765
5819
  await buildRuntimeBinary({
5766
5820
  sourcePath: `packages/runtime/src/control-plane/validators/${category}/${check}.ts`,
5767
5821
  outputPath: binaryPath,
@@ -5770,7 +5824,7 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
5770
5824
  env: runtimeProvisioningEnv()
5771
5825
  });
5772
5826
  }
5773
- return existsSync19(binaryPath) ? binaryPath : null;
5827
+ return existsSync20(binaryPath) ? binaryPath : null;
5774
5828
  }
5775
5829
 
5776
5830
  // packages/runtime/src/control-plane/native/validator.ts
@@ -5807,20 +5861,20 @@ async function readTaskSourceValidation(projectRoot, taskId) {
5807
5861
  function resolveValidationPaths(projectRoot, taskId, runtimeContext) {
5808
5862
  if (runtimeContext) {
5809
5863
  return {
5810
- taskLogDir: resolve24(runtimeContext.logsDir, taskId),
5811
- artifactDir: resolve24(runtimeContext.workspaceDir, "artifacts", taskId)
5864
+ taskLogDir: resolve25(runtimeContext.logsDir, taskId),
5865
+ artifactDir: resolve25(runtimeContext.workspaceDir, "artifacts", taskId)
5812
5866
  };
5813
5867
  }
5814
5868
  const paths = resolveHarnessPaths(projectRoot);
5815
5869
  return {
5816
- taskLogDir: resolve24(paths.logsDir, taskId),
5817
- artifactDir: resolve24(paths.artifactsDir, taskId)
5870
+ taskLogDir: resolve25(paths.logsDir, taskId),
5871
+ artifactDir: resolve25(paths.artifactsDir, taskId)
5818
5872
  };
5819
5873
  }
5820
5874
  async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext) {
5821
5875
  const binaryName = checkId.replace(":", "-");
5822
5876
  const binaryPath = await ensureValidatorBinary(projectRoot, checkId, runtimeContext) ?? resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
5823
- if (!existsSync20(binaryPath)) {
5877
+ if (!existsSync21(binaryPath)) {
5824
5878
  return {
5825
5879
  result: {
5826
5880
  id: checkId,
@@ -5831,7 +5885,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
5831
5885
  };
5832
5886
  }
5833
5887
  const validatorCwd = runtimeContext?.workspaceDir || resolveMonorepoRoot(projectRoot);
5834
- const runtimeShellPath = runtimeContext ? resolve24(runtimeContext.binDir, "rig-shell") : "";
5888
+ const runtimeShellPath = runtimeContext ? resolve25(runtimeContext.binDir, "rig-shell") : "";
5835
5889
  const monorepoMainRoot = runtimeContext?.monorepoMainRoot || process.env.MONOREPO_MAIN_ROOT?.trim() || resolveMonorepoRoot(projectRoot);
5836
5890
  const validatorEnv = {
5837
5891
  PROJECT_RIG_ROOT: runtimeContext?.hostProjectRoot || projectRoot,
@@ -5846,7 +5900,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
5846
5900
  validatorEnv.RIG_LOGS_DIR = runtimeContext.logsDir;
5847
5901
  validatorEnv.RIG_RUNTIME_BIN_DIR = runtimeContext.binDir;
5848
5902
  }
5849
- const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync20(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
5903
+ const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync21(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
5850
5904
  try {
5851
5905
  const result = JSON.parse(stdout.trim());
5852
5906
  return { result, exitCode };
@@ -5886,8 +5940,8 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
5886
5940
  const configuredValidation = stringArray(taskConfig[taskId]?.validation);
5887
5941
  const commands = resolvedContext?.validation?.length ? resolvedContext.validation : configuredValidation.length > 0 ? configuredValidation : sourceValidation.validation;
5888
5942
  const { taskLogDir, artifactDir } = resolveValidationPaths(projectRoot, taskId, resolvedContext);
5889
- mkdirSync8(taskLogDir, { recursive: true });
5890
- mkdirSync8(artifactDir, { recursive: true });
5943
+ mkdirSync9(taskLogDir, { recursive: true });
5944
+ mkdirSync9(artifactDir, { recursive: true });
5891
5945
  if (commands.length === 0) {
5892
5946
  const skipped = {
5893
5947
  status: "skipped",
@@ -5896,7 +5950,7 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
5896
5950
  failed: 0,
5897
5951
  categories: []
5898
5952
  };
5899
- writeFileSync8(resolve24(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
5953
+ writeFileSync9(resolve25(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
5900
5954
  `, "utf-8");
5901
5955
  return skipped;
5902
5956
  }
@@ -5931,18 +5985,18 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
5931
5985
  exit_code: 2,
5932
5986
  duration_seconds: 0
5933
5987
  });
5934
- const logFile2 = resolve24(taskLogDir, `invalid-entry-validation.log`);
5935
- mkdirSync8(taskLogDir, { recursive: true });
5936
- writeFileSync8(logFile2, `=== ${nowIso()} :: ${cmd} ===
5988
+ const logFile2 = resolve25(taskLogDir, `invalid-entry-validation.log`);
5989
+ mkdirSync9(taskLogDir, { recursive: true });
5990
+ writeFileSync9(logFile2, `=== ${nowIso()} :: ${cmd} ===
5937
5991
  Invalid validation entry: not a check-ID. All entries must use format "category:check-name".
5938
5992
  `, "utf-8");
5939
5993
  continue;
5940
5994
  }
5941
5995
  const { result, exitCode } = await dispatchValidator(cmd, effectiveRegistry, validatorCtx, (id) => runValidatorBinary(projectRoot, taskId, id, resolvedContext));
5942
5996
  const durationSeconds = Math.max(0, Math.round((Date.now() - startedAt) / 1000));
5943
- const logFile = resolve24(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
5944
- mkdirSync8(taskLogDir, { recursive: true });
5945
- writeFileSync8(logFile, `=== ${nowIso()} :: ${cmd} ===
5997
+ const logFile = resolve25(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
5998
+ mkdirSync9(taskLogDir, { recursive: true });
5999
+ writeFileSync9(logFile, `=== ${nowIso()} :: ${cmd} ===
5946
6000
  ${JSON.stringify(result, null, 2)}
5947
6001
  `, "utf-8");
5948
6002
  if (result.passed) {
@@ -5964,8 +6018,8 @@ ${JSON.stringify(result, null, 2)}
5964
6018
  failed,
5965
6019
  categories
5966
6020
  };
5967
- mkdirSync8(artifactDir, { recursive: true });
5968
- writeFileSync8(resolve24(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
6021
+ mkdirSync9(artifactDir, { recursive: true });
6022
+ writeFileSync9(resolve25(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
5969
6023
  `, "utf-8");
5970
6024
  return summary;
5971
6025
  }
@@ -6312,16 +6366,16 @@ async function taskDeps(projectRoot, taskId) {
6312
6366
  for (const dep of deps) {
6313
6367
  const artifactDir = artifactDirForId(projectRoot, dep);
6314
6368
  console.log(`=== ${dep} ===`);
6315
- if (!existsSync21(artifactDir)) {
6369
+ if (!existsSync22(artifactDir)) {
6316
6370
  console.log(` (no artifacts yet)
6317
6371
  `);
6318
6372
  continue;
6319
6373
  }
6320
- printArtifactSection(resolve25(artifactDir, "decision-log.md"), "--- Decisions ---");
6321
- printArtifactSection(resolve25(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6322
- const changedFiles = resolve25(artifactDir, "changed-files.txt");
6323
- if (existsSync21(changedFiles)) {
6324
- const lines = readFileSync12(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6374
+ printArtifactSection(resolve26(artifactDir, "decision-log.md"), "--- Decisions ---");
6375
+ printArtifactSection(resolve26(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6376
+ const changedFiles = resolve26(artifactDir, "changed-files.txt");
6377
+ if (existsSync22(changedFiles)) {
6378
+ const lines = readFileSync13(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6325
6379
  console.log(`--- Changed Files (${lines.length}) ---`);
6326
6380
  for (const line of lines) {
6327
6381
  console.log(line);
@@ -6366,12 +6420,12 @@ function taskRecord(projectRoot, type, text, taskId) {
6366
6420
  throw new Error("No active task.");
6367
6421
  }
6368
6422
  const paths = resolveHarnessPaths(projectRoot);
6369
- mkdirSync9(paths.stateDir, { recursive: true });
6423
+ mkdirSync10(paths.stateDir, { recursive: true });
6370
6424
  if (type === "decision") {
6371
- const artifactDir = resolve25(paths.artifactsDir, activeTask);
6372
- mkdirSync9(artifactDir, { recursive: true });
6425
+ const artifactDir = resolve26(paths.artifactsDir, activeTask);
6426
+ mkdirSync10(artifactDir, { recursive: true });
6373
6427
  const timestamp = nowIso();
6374
- appendFileSync(resolve25(artifactDir, "decision-log.md"), `
6428
+ appendFileSync(resolve26(artifactDir, "decision-log.md"), `
6375
6429
  ### ${timestamp}
6376
6430
 
6377
6431
  ${text}
@@ -6381,14 +6435,14 @@ ${text}
6381
6435
  return;
6382
6436
  }
6383
6437
  const failedPath = paths.failedApproachesPath;
6384
- if (!existsSync21(failedPath)) {
6385
- writeFileSync9(failedPath, `# Failed Approaches Log
6438
+ if (!existsSync22(failedPath)) {
6439
+ writeFileSync10(failedPath, `# Failed Approaches Log
6386
6440
 
6387
6441
  This file records approaches that did not work.
6388
6442
 
6389
6443
  `, "utf-8");
6390
6444
  }
6391
- const content = readFileSync12(failedPath, "utf-8");
6445
+ const content = readFileSync13(failedPath, "utf-8");
6392
6446
  const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
6393
6447
  appendFileSync(failedPath, `
6394
6448
  ## ${activeTask} - Attempt ${attempts} (${nowIso()})
@@ -6405,40 +6459,40 @@ function taskArtifacts(projectRoot, taskId) {
6405
6459
  throw new Error("No active task.");
6406
6460
  }
6407
6461
  const paths = resolveHarnessPaths(projectRoot);
6408
- const artifactDir = resolve25(paths.artifactsDir, activeTask);
6409
- mkdirSync9(artifactDir, { recursive: true });
6462
+ const artifactDir = resolve26(paths.artifactsDir, activeTask);
6463
+ mkdirSync10(artifactDir, { recursive: true });
6410
6464
  const changed = changedFilesForTask(projectRoot, activeTask, true);
6411
- writeFileSync9(resolve25(artifactDir, "changed-files.txt"), `${changed.join(`
6465
+ writeFileSync10(resolve26(artifactDir, "changed-files.txt"), `${changed.join(`
6412
6466
  `)}
6413
6467
  `, "utf-8");
6414
6468
  console.log(`changed-files.txt: ${changed.length} files`);
6415
- const taskResultPath = resolve25(artifactDir, "task-result.json");
6416
- if (!existsSync21(taskResultPath)) {
6469
+ const taskResultPath = resolve26(artifactDir, "task-result.json");
6470
+ if (!existsSync22(taskResultPath)) {
6417
6471
  const template = {
6418
6472
  task_id: activeTask,
6419
6473
  status: "completed",
6420
6474
  summary: "TODO: Write a one-line summary of what you did",
6421
6475
  completed_at: nowIso()
6422
6476
  };
6423
- writeFileSync9(taskResultPath, `${JSON.stringify(template, null, 2)}
6477
+ writeFileSync10(taskResultPath, `${JSON.stringify(template, null, 2)}
6424
6478
  `, "utf-8");
6425
6479
  console.log("task-result.json: created (update the summary!)");
6426
6480
  } else {
6427
6481
  console.log("task-result.json: already exists");
6428
6482
  }
6429
- const decisionLogPath = resolve25(artifactDir, "decision-log.md");
6430
- if (!existsSync21(decisionLogPath)) {
6483
+ const decisionLogPath = resolve26(artifactDir, "decision-log.md");
6484
+ if (!existsSync22(decisionLogPath)) {
6431
6485
  const content = `# Decision Log: ${activeTask}
6432
6486
 
6433
6487
  Record key decisions here using: rig-agent record decision "..."
6434
6488
  `;
6435
- writeFileSync9(decisionLogPath, content, "utf-8");
6489
+ writeFileSync10(decisionLogPath, content, "utf-8");
6436
6490
  console.log("decision-log.md: created (record your decisions!)");
6437
6491
  } else {
6438
6492
  console.log("decision-log.md: already exists");
6439
6493
  }
6440
- const nextActionsPath = resolve25(artifactDir, "next-actions.md");
6441
- if (!existsSync21(nextActionsPath)) {
6494
+ const nextActionsPath = resolve26(artifactDir, "next-actions.md");
6495
+ if (!existsSync22(nextActionsPath)) {
6442
6496
  const content = [
6443
6497
  `# Next Actions: ${activeTask}`,
6444
6498
  "",
@@ -6455,13 +6509,13 @@ Record key decisions here using: rig-agent record decision "..."
6455
6509
  ""
6456
6510
  ].join(`
6457
6511
  `);
6458
- writeFileSync9(nextActionsPath, content, "utf-8");
6512
+ writeFileSync10(nextActionsPath, content, "utf-8");
6459
6513
  console.log("next-actions.md: created (add recommendations for downstream tasks!)");
6460
6514
  } else {
6461
6515
  console.log("next-actions.md: already exists");
6462
6516
  }
6463
- const validationSummaryPath = resolve25(artifactDir, "validation-summary.json");
6464
- if (existsSync21(validationSummaryPath)) {
6517
+ const validationSummaryPath = resolve26(artifactDir, "validation-summary.json");
6518
+ if (existsSync22(validationSummaryPath)) {
6465
6519
  console.log("validation-summary.json: already exists");
6466
6520
  } else {
6467
6521
  console.log("validation-summary.json: not yet created (run: rig-agent validate)");
@@ -6475,8 +6529,8 @@ function taskArtifactDir(projectRoot, taskId) {
6475
6529
  throw new Error("No active task.");
6476
6530
  }
6477
6531
  const paths = resolveHarnessPaths(projectRoot);
6478
- const artifactDir = resolve25(paths.artifactsDir, activeTask);
6479
- mkdirSync9(artifactDir, { recursive: true });
6532
+ const artifactDir = resolve26(paths.artifactsDir, activeTask);
6533
+ mkdirSync10(artifactDir, { recursive: true });
6480
6534
  return artifactDir;
6481
6535
  }
6482
6536
  function taskArtifactWrite(projectRoot, filename, content, taskId) {
@@ -6485,10 +6539,10 @@ function taskArtifactWrite(projectRoot, filename, content, taskId) {
6485
6539
  throw new Error("No active task.");
6486
6540
  }
6487
6541
  const paths = resolveHarnessPaths(projectRoot);
6488
- const artifactDir = resolve25(paths.artifactsDir, activeTask);
6489
- mkdirSync9(artifactDir, { recursive: true });
6490
- const targetPath = resolve25(artifactDir, filename);
6491
- writeFileSync9(targetPath, content, "utf-8");
6542
+ const artifactDir = resolve26(paths.artifactsDir, activeTask);
6543
+ mkdirSync10(artifactDir, { recursive: true });
6544
+ const targetPath = resolve26(artifactDir, filename);
6545
+ writeFileSync10(targetPath, content, "utf-8");
6492
6546
  console.log(`Wrote: ${targetPath}`);
6493
6547
  }
6494
6548
  async function taskValidate(projectRoot, taskId, validatorRegistry) {
@@ -6549,7 +6603,7 @@ function collectTaskChangedFiles(projectRoot, taskId, includeCommitted) {
6549
6603
  [projectRoot, ""],
6550
6604
  [monorepoRepoRoot, ""]
6551
6605
  ]) {
6552
- if (!existsSync21(resolve25(repo, ".git"))) {
6606
+ if (!existsSync22(resolve26(repo, ".git"))) {
6553
6607
  continue;
6554
6608
  }
6555
6609
  if (includeCommitted && repo === monorepoRepoRoot) {
@@ -6587,8 +6641,8 @@ function filterTaskChangedFiles(projectRoot, taskId, files, scoped) {
6587
6641
  }
6588
6642
  function resolveTaskMonorepoRoot(projectRoot) {
6589
6643
  const runtimeWorkspace = loadRuntimeContextFromEnv()?.workspaceDir || process.env.RIG_TASK_WORKSPACE?.trim();
6590
- if (runtimeWorkspace && existsSync21(resolve25(runtimeWorkspace, ".git"))) {
6591
- return resolve25(runtimeWorkspace);
6644
+ if (runtimeWorkspace && existsSync22(resolve26(runtimeWorkspace, ".git"))) {
6645
+ return resolve26(runtimeWorkspace);
6592
6646
  }
6593
6647
  return resolveHarnessPaths(projectRoot).monorepoRoot;
6594
6648
  }
@@ -6616,7 +6670,7 @@ function resolveRuntimeInitialHeadCommit(projectRoot, repo) {
6616
6670
  const runtimeContext = loadRuntimeContextFromEnv();
6617
6671
  if (runtimeContext?.initialHeadCommits?.monorepo?.trim()) {
6618
6672
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6619
- if (resolve25(monorepoRoot) === resolve25(repo)) {
6673
+ if (resolve26(monorepoRoot) === resolve26(repo)) {
6620
6674
  return runtimeContext.initialHeadCommits.monorepo.trim();
6621
6675
  }
6622
6676
  }
@@ -6626,7 +6680,7 @@ function resolveMonorepoBaseCommit(projectRoot, repo) {
6626
6680
  const runtimeContext = loadRuntimeContextFromEnv();
6627
6681
  if (runtimeContext?.monorepoBaseCommit?.trim()) {
6628
6682
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6629
- if (resolve25(monorepoRoot) === resolve25(repo)) {
6683
+ if (resolve26(monorepoRoot) === resolve26(repo)) {
6630
6684
  return runtimeContext.monorepoBaseCommit.trim();
6631
6685
  }
6632
6686
  }
@@ -6660,7 +6714,7 @@ function resolveRuntimeDirtyBaseline(projectRoot, repo) {
6660
6714
  return new Set;
6661
6715
  }
6662
6716
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6663
- const selected = resolve25(repo) === resolve25(monorepoRoot) ? dirtyFiles.monorepo : resolve25(repo) === resolve25(projectRoot) ? dirtyFiles.project : undefined;
6717
+ const selected = resolve26(repo) === resolve26(monorepoRoot) ? dirtyFiles.monorepo : resolve26(repo) === resolve26(projectRoot) ? dirtyFiles.project : undefined;
6664
6718
  return new Set((selected || []).map((file) => normalizeChangedFilePath(file)).filter(Boolean));
6665
6719
  }
6666
6720
  function normalizeChangedFilePath(file) {
@@ -6760,12 +6814,12 @@ function printIndented(text) {
6760
6814
  }
6761
6815
  }
6762
6816
  function readLocalBeadsTasks(projectRoot) {
6763
- const issuesPath = resolve25(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
6764
- if (!existsSync21(issuesPath)) {
6817
+ const issuesPath = resolve26(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
6818
+ if (!existsSync22(issuesPath)) {
6765
6819
  return [];
6766
6820
  }
6767
6821
  const tasks = [];
6768
- for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
6822
+ for (const line of readFileSync13(issuesPath, "utf-8").split(/\r?\n/)) {
6769
6823
  const trimmed = line.trim();
6770
6824
  if (!trimmed) {
6771
6825
  continue;
@@ -6878,11 +6932,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
6878
6932
  return [...ids].sort();
6879
6933
  }
6880
6934
  function printArtifactSection(path, header) {
6881
- if (!existsSync21(path)) {
6935
+ if (!existsSync22(path)) {
6882
6936
  return;
6883
6937
  }
6884
6938
  console.log(header);
6885
- process.stdout.write(readFileSync12(path, "utf-8"));
6939
+ process.stdout.write(readFileSync13(path, "utf-8"));
6886
6940
  console.log("");
6887
6941
  }
6888
6942
  function escapeRegExp(value) {
@@ -6922,8 +6976,8 @@ function isRuntimeGatewayGhPath(candidate) {
6922
6976
  }
6923
6977
  function resolveOptionalMonorepoRoot(projectRoot) {
6924
6978
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
6925
- if (runtimeWorkspace && existsSync22(resolve26(runtimeWorkspace, ".git"))) {
6926
- return resolve26(runtimeWorkspace);
6979
+ if (runtimeWorkspace && existsSync23(resolve27(runtimeWorkspace, ".git"))) {
6980
+ return resolve27(runtimeWorkspace);
6927
6981
  }
6928
6982
  try {
6929
6983
  return resolveMonorepoRoot2(projectRoot);
@@ -6948,7 +7002,7 @@ function resolveGitBinary(projectRoot) {
6948
7002
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
6949
7003
  continue;
6950
7004
  }
6951
- if (existsSync22(candidate)) {
7005
+ if (existsSync23(candidate)) {
6952
7006
  return candidate;
6953
7007
  }
6954
7008
  }
@@ -7008,11 +7062,11 @@ function gitPreflight(projectRoot, taskId, strict) {
7008
7062
  const expected = resolvedTask ? `rig/${resolveTaskBranchId(projectRoot, resolvedTask)}` : "";
7009
7063
  console.log("=== Git Flow Preflight ===");
7010
7064
  let issues = 0;
7011
- if (!existsSync22(resolve26(projectRoot, ".git"))) {
7065
+ if (!existsSync23(resolve27(projectRoot, ".git"))) {
7012
7066
  console.log(`ERROR: project root is not a git repo (${projectRoot})`);
7013
7067
  issues += 1;
7014
7068
  }
7015
- if (monorepoRoot && existsSync22(resolve26(monorepoRoot, ".git"))) {
7069
+ if (monorepoRoot && existsSync23(resolve27(monorepoRoot, ".git"))) {
7016
7070
  const monoBranch = branchName(projectRoot, monorepoRoot);
7017
7071
  if (expected && monoBranch !== expected) {
7018
7072
  console.log(`WARN: monorepo branch is ${monoBranch}, expected ${expected} for task ${resolvedTask}`);
@@ -7046,7 +7100,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7046
7100
  }
7047
7101
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7048
7102
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7049
- if (!existsSync22(resolve26(repoRoot, ".git"))) {
7103
+ if (!existsSync23(resolve27(repoRoot, ".git"))) {
7050
7104
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7051
7105
  }
7052
7106
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7090,8 +7144,8 @@ function gitCommit(options) {
7090
7144
  function gitSnapshot(projectRoot, taskId, outputPath) {
7091
7145
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
7092
7146
  const resolvedTask = taskId || safeCurrentTaskId(projectRoot);
7093
- const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve26(resolve26(projectRoot, ".rig", "state"), "git-state.txt"));
7094
- mkdirSync10(dirname14(output), { recursive: true });
7147
+ const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve27(resolve27(projectRoot, ".rig", "state"), "git-state.txt"));
7148
+ mkdirSync11(dirname14(output), { recursive: true });
7095
7149
  const lines = ["# Git Snapshot", `timestamp: ${nowIso()}`];
7096
7150
  if (resolvedTask) {
7097
7151
  lines.push(`task: ${resolvedTask}`);
@@ -7101,7 +7155,7 @@ function gitSnapshot(projectRoot, taskId, outputPath) {
7101
7155
  if (monorepoRoot && monorepoRoot !== projectRoot) {
7102
7156
  lines.push(...snapshotRepo(projectRoot, "monorepo", monorepoRoot));
7103
7157
  }
7104
- writeFileSync10(output, `${lines.join(`
7158
+ writeFileSync11(output, `${lines.join(`
7105
7159
  `)}
7106
7160
  `, "utf-8");
7107
7161
  return output;
@@ -7125,7 +7179,7 @@ function gitOpenPr(options) {
7125
7179
  } else if (taskId) {
7126
7180
  gitSyncBranch(options.projectRoot, taskId, "project");
7127
7181
  }
7128
- if (!existsSync22(resolve26(repoRoot, ".git"))) {
7182
+ if (!existsSync23(resolve27(repoRoot, ".git"))) {
7129
7183
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7130
7184
  }
7131
7185
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7338,12 +7392,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7338
7392
  }
7339
7393
  function writePrMetadata(projectRoot, taskId, result) {
7340
7394
  const dir = artifactDirForId(projectRoot, taskId);
7341
- mkdirSync10(dir, { recursive: true });
7342
- const path = resolve26(dir, "pr-state.json");
7395
+ mkdirSync11(dir, { recursive: true });
7396
+ const path = resolve27(dir, "pr-state.json");
7343
7397
  let prs = {};
7344
- if (existsSync22(path)) {
7398
+ if (existsSync23(path)) {
7345
7399
  try {
7346
- const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7400
+ const parsed = JSON.parse(readFileSync14(path, "utf-8"));
7347
7401
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7348
7402
  prs = parsed.prs;
7349
7403
  }
@@ -7359,12 +7413,12 @@ function writePrMetadata(projectRoot, taskId, result) {
7359
7413
  ...primary || {},
7360
7414
  updated_at: nowIso()
7361
7415
  };
7362
- writeFileSync10(path, `${JSON.stringify(artifact, null, 2)}
7416
+ writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7363
7417
  `, "utf-8");
7364
7418
  }
7365
7419
  function resolveArtifactSnapshot(projectRoot, taskId) {
7366
- const artifactDir = resolve26(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7367
- return resolve26(artifactDir, "git-state.txt");
7420
+ const artifactDir = resolve27(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7421
+ return resolve27(artifactDir, "git-state.txt");
7368
7422
  }
7369
7423
  function ensureFullGitHistory(projectRoot, repoRoot, remoteName = "origin") {
7370
7424
  const shallow = runCapture2(gitCmd(projectRoot, repoRoot, "rev-parse", "--is-shallow-repository"), projectRoot);
@@ -7416,14 +7470,14 @@ function resolveGithubCliBinary(projectRoot) {
7416
7470
  }
7417
7471
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7418
7472
  for (const entry of explicitPathEntries) {
7419
- candidates.add(resolve26(entry, "gh"));
7473
+ candidates.add(resolve27(entry, "gh"));
7420
7474
  }
7421
7475
  const bunResolved = Bun.which("gh");
7422
7476
  if (bunResolved) {
7423
7477
  candidates.add(bunResolved);
7424
7478
  }
7425
7479
  for (const candidate of candidates) {
7426
- if (candidate && existsSync22(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7480
+ if (candidate && existsSync23(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7427
7481
  return candidate;
7428
7482
  }
7429
7483
  }
@@ -7453,7 +7507,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7453
7507
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7454
7508
  }
7455
7509
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7456
- const normalizedGitRoot = resolve26(gitRoot);
7510
+ const normalizedGitRoot = resolve27(gitRoot);
7457
7511
  if (visited.has(normalizedGitRoot)) {
7458
7512
  return "";
7459
7513
  }
@@ -7525,7 +7579,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
7525
7579
  return remotes.includes("origin") ? "origin" : remotes[0];
7526
7580
  }
7527
7581
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
7528
- const gitArgs = existsSync22(resolve26(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7582
+ const gitArgs = existsSync23(resolve27(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7529
7583
  return runCapture2(gitArgs, cwd, projectRoot);
7530
7584
  }
7531
7585
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -7543,9 +7597,9 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
7543
7597
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
7544
7598
  return "";
7545
7599
  } else if (!isAbsolute2(normalized)) {
7546
- candidate = resolve26(gitRoot, normalized);
7600
+ candidate = resolve27(gitRoot, normalized);
7547
7601
  }
7548
- return existsSync22(candidate) ? candidate : "";
7602
+ return existsSync23(candidate) ? candidate : "";
7549
7603
  }
7550
7604
  function normalizeGithubRepoNameWithOwner(value) {
7551
7605
  const normalized = value.trim();
@@ -7672,7 +7726,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
7672
7726
  return best;
7673
7727
  }
7674
7728
  function snapshotRepo(projectRoot, label, repo) {
7675
- if (!existsSync22(resolve26(repo, ".git"))) {
7729
+ if (!existsSync23(resolve27(repo, ".git"))) {
7676
7730
  return [`## ${label}`, `repo: ${repo}`, "status: unavailable", ""];
7677
7731
  }
7678
7732
  const status = runCapture2(gitCmd(projectRoot, repo, "status", "--short"), projectRoot).stdout.trim();
@@ -7695,7 +7749,7 @@ function snapshotRepo(projectRoot, label, repo) {
7695
7749
  ];
7696
7750
  }
7697
7751
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
7698
- if (!existsSync22(resolve26(repo, ".git"))) {
7752
+ if (!existsSync23(resolve27(repo, ".git"))) {
7699
7753
  console.log(`Skipping ${label}: repo not available (${repo})`);
7700
7754
  return;
7701
7755
  }
@@ -7727,18 +7781,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
7727
7781
  console.log(`Committed ${label}: ${message}`);
7728
7782
  }
7729
7783
  function readChangedFilesManifest(projectRoot, taskId) {
7730
- const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7731
- if (!existsSync22(manifestPath)) {
7784
+ const manifestPath = resolve27(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7785
+ if (!existsSync23(manifestPath)) {
7732
7786
  return [];
7733
7787
  }
7734
- const files = readFileSync13(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
7788
+ const files = readFileSync14(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
7735
7789
  return [...new Set(files)];
7736
7790
  }
7737
7791
  function refreshChangedFilesManifest(projectRoot, taskId) {
7738
- const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7739
- mkdirSync10(dirname14(manifestPath), { recursive: true });
7792
+ const manifestPath = resolve27(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7793
+ mkdirSync11(dirname14(manifestPath), { recursive: true });
7740
7794
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
7741
- writeFileSync10(manifestPath, `${changedFiles.join(`
7795
+ writeFileSync11(manifestPath, `${changedFiles.join(`
7742
7796
  `)}
7743
7797
  `, "utf-8");
7744
7798
  return manifestPath;
@@ -7851,7 +7905,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
7851
7905
  return result.exitCode === 0 && result.stdout.trim().length > 0;
7852
7906
  }
7853
7907
  function stageExcludePathspecs(repoRoot) {
7854
- const patterns = existsSync22(resolve26(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
7908
+ const patterns = existsSync23(resolve27(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
7855
7909
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
7856
7910
  }
7857
7911
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -7861,7 +7915,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
7861
7915
  }
7862
7916
  let current = repoRoot;
7863
7917
  for (let index = 0;index < parts.length - 1; index += 1) {
7864
- current = resolve26(current, parts[index]);
7918
+ current = resolve27(current, parts[index]);
7865
7919
  try {
7866
7920
  if (lstatSync(current).isSymbolicLink()) {
7867
7921
  return true;
@@ -7873,7 +7927,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
7873
7927
  return false;
7874
7928
  }
7875
7929
  function printRepoStatus(projectRoot, label, repo, expectedBranch) {
7876
- if (!existsSync22(resolve26(repo, ".git"))) {
7930
+ if (!existsSync23(resolve27(repo, ".git"))) {
7877
7931
  console.log(`${label}: unavailable (${repo})`);
7878
7932
  return;
7879
7933
  }
@@ -7909,7 +7963,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
7909
7963
  }
7910
7964
  } catch {}
7911
7965
  const artifactDir = artifactDirForId(projectRoot, taskId);
7912
- if (existsSync22(artifactDir)) {
7966
+ if (existsSync23(artifactDir)) {
7913
7967
  return taskId;
7914
7968
  }
7915
7969
  throw new Error(`Unknown task id: ${taskId}`);
@@ -7945,11 +7999,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
7945
7999
  }
7946
8000
  function runtimeGitEnv(projectRoot) {
7947
8001
  const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
7948
- const runtimeHome = runtimeRoot ? resolve26(runtimeRoot, "home") : "";
7949
- const runtimeTmp = runtimeRoot ? resolve26(runtimeRoot, "tmp") : "";
7950
- const runtimeCache = runtimeRoot ? resolve26(runtimeRoot, "cache") : "";
7951
- const runtimeKnownHosts = runtimeHome ? resolve26(runtimeHome, ".ssh", "known_hosts") : "";
7952
- const runtimeKey = runtimeHome ? resolve26(runtimeHome, ".ssh", "rig-agent-key") : "";
8002
+ const runtimeHome = runtimeRoot ? resolve27(runtimeRoot, "home") : "";
8003
+ const runtimeTmp = runtimeRoot ? resolve27(runtimeRoot, "tmp") : "";
8004
+ const runtimeCache = runtimeRoot ? resolve27(runtimeRoot, "cache") : "";
8005
+ const runtimeKnownHosts = runtimeHome ? resolve27(runtimeHome, ".ssh", "known_hosts") : "";
8006
+ const runtimeKey = runtimeHome ? resolve27(runtimeHome, ".ssh", "rig-agent-key") : "";
7953
8007
  const env = {};
7954
8008
  if (ctx?.workspaceDir) {
7955
8009
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -7962,14 +8016,14 @@ function runtimeGitEnv(projectRoot) {
7962
8016
  if (runtimeRoot) {
7963
8017
  env.RIG_RUNTIME_HOME = runtimeRoot;
7964
8018
  }
7965
- if (runtimeHome && existsSync22(runtimeHome)) {
8019
+ if (runtimeHome && existsSync23(runtimeHome)) {
7966
8020
  env.HOME = runtimeHome;
7967
8021
  env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
7968
8022
  }
7969
- if (runtimeTmp && existsSync22(runtimeTmp)) {
8023
+ if (runtimeTmp && existsSync23(runtimeTmp)) {
7970
8024
  env.TMPDIR = runtimeTmp;
7971
8025
  }
7972
- if (runtimeCache && existsSync22(runtimeCache)) {
8026
+ if (runtimeCache && existsSync23(runtimeCache)) {
7973
8027
  env.XDG_CACHE_HOME = runtimeCache;
7974
8028
  }
7975
8029
  const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
@@ -8013,14 +8067,14 @@ function runtimeGitEnv(projectRoot) {
8013
8067
  env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
8014
8068
  applyGitHubCredentialHelperEnv(env);
8015
8069
  }
8016
- if (runtimeKnownHosts && existsSync22(runtimeKnownHosts)) {
8070
+ if (runtimeKnownHosts && existsSync23(runtimeKnownHosts)) {
8017
8071
  const sshParts = [
8018
8072
  "ssh",
8019
8073
  `-o UserKnownHostsFile="${runtimeKnownHosts}"`,
8020
8074
  "-o StrictHostKeyChecking=yes",
8021
8075
  "-F /dev/null"
8022
8076
  ];
8023
- if (runtimeKey && existsSync22(runtimeKey)) {
8077
+ if (runtimeKey && existsSync23(runtimeKey)) {
8024
8078
  sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
8025
8079
  }
8026
8080
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -8041,12 +8095,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8041
8095
  if (!runtimeRoot) {
8042
8096
  return {};
8043
8097
  }
8044
- const path = resolve26(runtimeRoot, "runtime-secrets.json");
8045
- if (!existsSync22(path)) {
8098
+ const path = resolve27(runtimeRoot, "runtime-secrets.json");
8099
+ if (!existsSync23(path)) {
8046
8100
  return {};
8047
8101
  }
8048
8102
  try {
8049
- const parsed = JSON.parse(readFileSync13(path, "utf-8"));
8103
+ const parsed = JSON.parse(readFileSync14(path, "utf-8"));
8050
8104
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8051
8105
  return Object.fromEntries(entries);
8052
8106
  } catch {
@@ -8054,13 +8108,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8054
8108
  }
8055
8109
  }
8056
8110
  function ensureRuntimeOpenSslConfig(runtimeHome) {
8057
- const sslDir = resolve26(runtimeHome, ".ssl");
8058
- const sslConfig = resolve26(sslDir, "openssl.cnf");
8059
- if (!existsSync22(sslDir)) {
8060
- mkdirSync10(sslDir, { recursive: true });
8111
+ const sslDir = resolve27(runtimeHome, ".ssl");
8112
+ const sslConfig = resolve27(sslDir, "openssl.cnf");
8113
+ if (!existsSync23(sslDir)) {
8114
+ mkdirSync11(sslDir, { recursive: true });
8061
8115
  }
8062
- if (!existsSync22(sslConfig)) {
8063
- writeFileSync10(sslConfig, `# Rig runtime OpenSSL config placeholder
8116
+ if (!existsSync23(sslConfig)) {
8117
+ writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8064
8118
  `);
8065
8119
  }
8066
8120
  return sslConfig;
@@ -8078,11 +8132,11 @@ function resolveRuntimeMetadata(projectRoot) {
8078
8132
  if (contextFile) {
8079
8133
  return {
8080
8134
  ctx,
8081
- runtimeRoot: dirname14(resolve26(contextFile))
8135
+ runtimeRoot: dirname14(resolve27(contextFile))
8082
8136
  };
8083
8137
  }
8084
8138
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
8085
- if (existsSync22(inferredContextFile)) {
8139
+ if (existsSync23(inferredContextFile)) {
8086
8140
  try {
8087
8141
  ctx = loadRuntimeContext(inferredContextFile);
8088
8142
  } catch {}
@@ -8094,10 +8148,10 @@ function resolveRuntimeMetadata(projectRoot) {
8094
8148
  return { ctx, runtimeRoot: "" };
8095
8149
  }
8096
8150
  function findRuntimeContextFile2(startPath) {
8097
- let current = resolve26(startPath);
8151
+ let current = resolve27(startPath);
8098
8152
  while (true) {
8099
- const candidate = resolve26(current, "runtime-context.json");
8100
- if (existsSync22(candidate)) {
8153
+ const candidate = resolve27(current, "runtime-context.json");
8154
+ if (existsSync23(candidate)) {
8101
8155
  return candidate;
8102
8156
  }
8103
8157
  const parent = dirname14(current);
@@ -8109,7 +8163,7 @@ function findRuntimeContextFile2(startPath) {
8109
8163
  }
8110
8164
 
8111
8165
  // packages/runtime/src/control-plane/native/profile-ops.ts
8112
- import { existsSync as existsSync23, mkdirSync as mkdirSync11, writeFileSync as writeFileSync11 } from "fs";
8166
+ import { existsSync as existsSync24, mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "fs";
8113
8167
  var DEFAULTS = {
8114
8168
  model: parseEnvOrDefault(process.env.DEFAULT_AGENT_MODEL, ["claude", "gpt-codex", "pi"], "pi"),
8115
8169
  runtime: parseEnvOrDefault(process.env.DEFAULT_AGENT_RUNTIME, ["claude-code", "codex-app-server", "pi"], "pi"),
@@ -8124,7 +8178,7 @@ function parseEnvOrDefault(value, allowed, fallback) {
8124
8178
  return allowed.includes(value) ? value : fallback;
8125
8179
  }
8126
8180
  async function readProfileFile(path) {
8127
- if (!existsSync23(path)) {
8181
+ if (!existsSync24(path)) {
8128
8182
  return null;
8129
8183
  }
8130
8184
  try {
@@ -8177,14 +8231,14 @@ async function setProfile(projectRoot, options) {
8177
8231
  plugin = model === "gpt-codex" ? "codex" : model === "pi" ? "pi" : "claude";
8178
8232
  }
8179
8233
  const paths = resolveHarnessPaths(projectRoot);
8180
- mkdirSync11(paths.stateDir, { recursive: true });
8234
+ mkdirSync12(paths.stateDir, { recursive: true });
8181
8235
  const next = {
8182
8236
  model,
8183
8237
  runtime,
8184
8238
  agent_plugin: plugin,
8185
8239
  updated_at: new Date().toISOString()
8186
8240
  };
8187
- writeFileSync11(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8241
+ writeFileSync12(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8188
8242
  `, "utf-8");
8189
8243
  await showProfile(projectRoot, false);
8190
8244
  }
@@ -8220,13 +8274,13 @@ async function setReviewProfile(projectRoot, mode, provider) {
8220
8274
  throw new Error(`Invalid provider: ${resolvedProvider}. Supported: greptile.`);
8221
8275
  }
8222
8276
  const paths = resolveHarnessPaths(projectRoot);
8223
- mkdirSync11(paths.stateDir, { recursive: true });
8277
+ mkdirSync12(paths.stateDir, { recursive: true });
8224
8278
  const next = {
8225
8279
  mode,
8226
8280
  provider: resolvedProvider,
8227
8281
  updated_at: new Date().toISOString()
8228
8282
  };
8229
- writeFileSync11(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8283
+ writeFileSync12(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8230
8284
  `, "utf-8");
8231
8285
  await showReviewProfile(projectRoot);
8232
8286
  }
@@ -8264,44 +8318,44 @@ async function loadReviewProfile(path) {
8264
8318
  }
8265
8319
 
8266
8320
  // packages/runtime/src/control-plane/native/repo-ops.ts
8267
- import { existsSync as existsSync27, mkdirSync as mkdirSync15, readFileSync as readFileSync15, readdirSync as readdirSync5, rmSync as rmSync7, writeFileSync as writeFileSync13 } from "fs";
8268
- import { basename as basename8, dirname as dirname16, resolve as resolve30 } from "path";
8321
+ import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync16, readdirSync as readdirSync6, rmSync as rmSync8, writeFileSync as writeFileSync14 } from "fs";
8322
+ import { basename as basename8, dirname as dirname16, resolve as resolve31 } from "path";
8269
8323
  // packages/runtime/src/control-plane/repos/mirror/bootstrap.ts
8270
- import { existsSync as existsSync25, mkdirSync as mkdirSync13, realpathSync as realpathSync2 } from "fs";
8271
- import { resolve as resolve28 } from "path";
8324
+ import { existsSync as existsSync26, mkdirSync as mkdirSync14, realpathSync as realpathSync2 } from "fs";
8325
+ import { resolve as resolve29 } from "path";
8272
8326
 
8273
8327
  // packages/runtime/src/control-plane/authority-files.ts
8274
- import { existsSync as existsSync24, mkdirSync as mkdirSync12, readFileSync as readFileSync14, writeFileSync as writeFileSync12, appendFileSync as appendFileSync2, copyFileSync as copyFileSync3, statSync as statSync6, readdirSync as readdirSync4, chmodSync as chmodSync3 } from "fs";
8275
- import { dirname as dirname15, join as join5, relative, resolve as resolve27 } from "path";
8328
+ import { existsSync as existsSync25, mkdirSync as mkdirSync13, readFileSync as readFileSync15, writeFileSync as writeFileSync13, appendFileSync as appendFileSync2, copyFileSync as copyFileSync3, statSync as statSync6, readdirSync as readdirSync5, chmodSync as chmodSync3 } from "fs";
8329
+ import { dirname as dirname15, join as join5, relative, resolve as resolve28 } from "path";
8276
8330
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8277
8331
  function resolveAuthorityProjectStateDir(projectRoot) {
8278
8332
  const explicit = process.env.RIG_STATE_DIR?.trim();
8279
8333
  if (explicit) {
8280
- return resolve27(explicit);
8334
+ return resolve28(explicit);
8281
8335
  }
8282
- return resolve27(resolve27(projectRoot), ".rig", "state");
8336
+ return resolve28(resolve28(projectRoot), ".rig", "state");
8283
8337
  }
8284
8338
  function readJsonAtPath(path, fallback) {
8285
- if (!existsSync24(path)) {
8339
+ if (!existsSync25(path)) {
8286
8340
  return fallback;
8287
8341
  }
8288
8342
  try {
8289
- return JSON.parse(readFileSync14(path, "utf-8"));
8343
+ return JSON.parse(readFileSync15(path, "utf-8"));
8290
8344
  } catch {
8291
8345
  return fallback;
8292
8346
  }
8293
8347
  }
8294
8348
  function writeJsonAtPath(path, value) {
8295
- mkdirSync12(dirname15(path), { recursive: true });
8296
- writeFileSync12(path, `${JSON.stringify(value, null, 2)}
8349
+ mkdirSync13(dirname15(path), { recursive: true });
8350
+ writeFileSync13(path, `${JSON.stringify(value, null, 2)}
8297
8351
  `, "utf8");
8298
8352
  return path;
8299
8353
  }
8300
8354
  function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
8301
- return readJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8355
+ return readJsonAtPath(resolve28(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8302
8356
  }
8303
8357
  function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
8304
- return writeJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8358
+ return writeJsonAtPath(resolve28(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8305
8359
  }
8306
8360
 
8307
8361
  // packages/runtime/src/control-plane/repos/mirror/state.ts
@@ -8361,7 +8415,7 @@ function sameExistingPath(left, right) {
8361
8415
  try {
8362
8416
  return realpathSync2(left) === realpathSync2(right);
8363
8417
  } catch {
8364
- return resolve28(left) === resolve28(right);
8418
+ return resolve29(left) === resolve29(right);
8365
8419
  }
8366
8420
  }
8367
8421
  function repoLooksUsable(repoRoot, projectRoot) {
@@ -8397,7 +8451,7 @@ function resolveMirrorRemoteUrl(layout) {
8397
8451
  }
8398
8452
  }
8399
8453
  }
8400
- if (existsSync25(resolve28(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8454
+ if (existsSync26(resolve29(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8401
8455
  const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
8402
8456
  if (checkoutOrigin.exitCode === 0) {
8403
8457
  const currentOrigin = checkoutOrigin.stdout.trim();
@@ -8410,9 +8464,9 @@ function resolveMirrorRemoteUrl(layout) {
8410
8464
  }
8411
8465
  function ensureManagedRepoMirror(projectRoot, repoId) {
8412
8466
  const layout = resolveManagedRepoLayout(projectRoot, repoId);
8413
- mkdirSync13(layout.metadataRoot, { recursive: true });
8467
+ mkdirSync14(layout.metadataRoot, { recursive: true });
8414
8468
  const remoteUrl = resolveMirrorRemoteUrl(layout);
8415
- if (!existsSync25(resolve28(layout.mirrorRoot, "HEAD"))) {
8469
+ if (!existsSync26(resolve29(layout.mirrorRoot, "HEAD"))) {
8416
8470
  ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
8417
8471
  }
8418
8472
  const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8432,8 +8486,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
8432
8486
  return layout;
8433
8487
  }
8434
8488
  // packages/runtime/src/control-plane/repos/mirror/refresh.ts
8435
- import { existsSync as existsSync26, mkdirSync as mkdirSync14, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8436
- import { resolve as resolve29 } from "path";
8489
+ import { existsSync as existsSync27, mkdirSync as mkdirSync15, realpathSync as realpathSync3, rmSync as rmSync7 } from "fs";
8490
+ import { resolve as resolve30 } from "path";
8437
8491
  function nowIso3() {
8438
8492
  return new Date().toISOString();
8439
8493
  }
@@ -8460,7 +8514,7 @@ function sameExistingPath2(left, right) {
8460
8514
  try {
8461
8515
  return realpathSync3(left) === realpathSync3(right);
8462
8516
  } catch {
8463
- return resolve29(left) === resolve29(right);
8517
+ return resolve30(left) === resolve30(right);
8464
8518
  }
8465
8519
  }
8466
8520
  function ensureMirrorHead(layout) {
@@ -8506,12 +8560,12 @@ function checkoutLooksUsable2(layout) {
8506
8560
  return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
8507
8561
  }
8508
8562
  function ensureCheckoutFromMirror(layout) {
8509
- mkdirSync14(resolve29(layout.checkoutRoot, ".."), { recursive: true });
8510
- const gitPath = resolve29(layout.checkoutRoot, ".git");
8511
- if (existsSync26(layout.checkoutRoot) && (!existsSync26(gitPath) || !checkoutLooksUsable2(layout))) {
8512
- rmSync6(layout.checkoutRoot, { recursive: true, force: true });
8563
+ mkdirSync15(resolve30(layout.checkoutRoot, ".."), { recursive: true });
8564
+ const gitPath = resolve30(layout.checkoutRoot, ".git");
8565
+ if (existsSync27(layout.checkoutRoot) && (!existsSync27(gitPath) || !checkoutLooksUsable2(layout))) {
8566
+ rmSync7(layout.checkoutRoot, { recursive: true, force: true });
8513
8567
  }
8514
- if (!existsSync26(gitPath)) {
8568
+ if (!existsSync27(gitPath)) {
8515
8569
  ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
8516
8570
  }
8517
8571
  const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8612,7 +8666,7 @@ function repoDiscover(projectRoot, taskId) {
8612
8666
  }
8613
8667
  function repoBaseline(projectRoot, refresh = false) {
8614
8668
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8615
- if (!refresh && existsSync27(paths.baseRepoPinsPath)) {
8669
+ if (!refresh && existsSync28(paths.baseRepoPinsPath)) {
8616
8670
  const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
8617
8671
  return baseline.repos || {};
8618
8672
  }
@@ -8636,8 +8690,8 @@ function ensureMonorepoReady(projectRoot) {
8636
8690
  }
8637
8691
  function persistBaselinePins(projectRoot, repos) {
8638
8692
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8639
- mkdirSync15(resolve30(paths.baseRepoPinsPath, ".."), { recursive: true });
8640
- writeFileSync13(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8693
+ mkdirSync16(resolve31(paths.baseRepoPinsPath, ".."), { recursive: true });
8694
+ writeFileSync14(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8641
8695
  `, "utf-8");
8642
8696
  return repos;
8643
8697
  }
@@ -8716,28 +8770,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
8716
8770
  function resolveRepoDiscoveryPaths(projectRoot) {
8717
8771
  const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
8718
8772
  const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
8719
- const normalizedProjectRoot = resolve30(projectRoot);
8773
+ const normalizedProjectRoot = resolve31(projectRoot);
8720
8774
  const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
8721
- const stateDir = resolve30(hostProjectRoot, ".rig", "state");
8775
+ const stateDir = resolve31(hostProjectRoot, ".rig", "state");
8722
8776
  return {
8723
8777
  monorepoRoot,
8724
- taskRepoCommitsPath: resolve30(stateDir, "task-repo-commits.json"),
8725
- baseRepoPinsPath: resolve30(stateDir, "base-repo-pins.json")
8778
+ taskRepoCommitsPath: resolve31(stateDir, "task-repo-commits.json"),
8779
+ baseRepoPinsPath: resolve31(stateDir, "base-repo-pins.json")
8726
8780
  };
8727
8781
  }
8728
8782
  function shouldUseHostProjectStateRoot(projectRoot) {
8729
8783
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
8730
- if (runtimeWorkspace && resolve30(runtimeWorkspace) === projectRoot) {
8784
+ if (runtimeWorkspace && resolve31(runtimeWorkspace) === projectRoot) {
8731
8785
  return true;
8732
8786
  }
8733
8787
  return basename8(dirname16(projectRoot)) === ".worktrees";
8734
8788
  }
8735
8789
  function readPinFromArtifact(projectRoot, depTask, repoKey) {
8736
- const snapshot = resolve30(artifactDirForId(projectRoot, depTask), "git-state.txt");
8737
- if (!existsSync27(snapshot)) {
8790
+ const snapshot = resolve31(artifactDirForId(projectRoot, depTask), "git-state.txt");
8791
+ if (!existsSync28(snapshot)) {
8738
8792
  return "";
8739
8793
  }
8740
- const content = readFileSync15(snapshot, "utf-8");
8794
+ const content = readFileSync16(snapshot, "utf-8");
8741
8795
  const chunk = content.split(/\r?\n/);
8742
8796
  let inSection = false;
8743
8797
  for (const line of chunk) {
@@ -8759,12 +8813,12 @@ function repoPath(projectRoot, key) {
8759
8813
  if (managed) {
8760
8814
  return managed.checkoutRoot;
8761
8815
  }
8762
- return key.startsWith("/") ? key : resolve30(projectRoot, key);
8816
+ return key.startsWith("/") ? key : resolve31(projectRoot, key);
8763
8817
  }
8764
8818
  function applyPins(projectRoot, pins) {
8765
8819
  for (const [key, commit] of Object.entries(pins)) {
8766
8820
  const path = repoPath(projectRoot, key);
8767
- if (!existsSync27(resolve30(path, ".git"))) {
8821
+ if (!existsSync28(resolve31(path, ".git"))) {
8768
8822
  throw new Error(`Repo for pin not available: ${key} (${path})`);
8769
8823
  }
8770
8824
  let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
@@ -8793,7 +8847,7 @@ function verifyPins(projectRoot, pins) {
8793
8847
  let ok = true;
8794
8848
  for (const [key, expected] of Object.entries(pins)) {
8795
8849
  const path = repoPath(projectRoot, key);
8796
- if (!existsSync27(resolve30(path, ".git"))) {
8850
+ if (!existsSync28(resolve31(path, ".git"))) {
8797
8851
  console.error(`ERROR: repo missing during pin verification: ${key}`);
8798
8852
  ok = false;
8799
8853
  continue;
@@ -8818,23 +8872,23 @@ function resolveRuntimeGitEnv() {
8818
8872
  GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
8819
8873
  };
8820
8874
  }
8821
- const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve30(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
8822
- const runtimeHome = runtimeRoot ? resolve30(runtimeRoot, "home") : process.env.HOME?.trim() || "";
8875
+ const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve31(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
8876
+ const runtimeHome = runtimeRoot ? resolve31(runtimeRoot, "home") : process.env.HOME?.trim() || "";
8823
8877
  if (!runtimeHome) {
8824
8878
  return;
8825
8879
  }
8826
- const knownHostsPath = resolve30(runtimeHome, ".ssh", "known_hosts");
8827
- if (!existsSync27(knownHostsPath)) {
8880
+ const knownHostsPath = resolve31(runtimeHome, ".ssh", "known_hosts");
8881
+ if (!existsSync28(knownHostsPath)) {
8828
8882
  return { HOME: runtimeHome };
8829
8883
  }
8830
- const agentSshKey = resolve30(runtimeHome, ".ssh", "rig-agent-key");
8884
+ const agentSshKey = resolve31(runtimeHome, ".ssh", "rig-agent-key");
8831
8885
  const sshParts = [
8832
8886
  "ssh",
8833
8887
  `-o UserKnownHostsFile="${knownHostsPath}"`,
8834
8888
  "-o StrictHostKeyChecking=yes",
8835
8889
  "-F /dev/null"
8836
8890
  ];
8837
- if (existsSync27(agentSshKey)) {
8891
+ if (existsSync28(agentSshKey)) {
8838
8892
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
8839
8893
  }
8840
8894
  return {
@@ -8844,24 +8898,24 @@ function resolveRuntimeGitEnv() {
8844
8898
  }
8845
8899
  function inferRuntimeRootFromWorkspace(cwd) {
8846
8900
  const contextPath = findRuntimeContextFile3(cwd);
8847
- if (!contextPath || !existsSync27(contextPath)) {
8901
+ if (!contextPath || !existsSync28(contextPath)) {
8848
8902
  return "";
8849
8903
  }
8850
8904
  try {
8851
8905
  loadRuntimeContext(contextPath);
8852
- return resolve30(contextPath, "..");
8906
+ return resolve31(contextPath, "..");
8853
8907
  } catch {
8854
8908
  return "";
8855
8909
  }
8856
8910
  }
8857
8911
  function findRuntimeContextFile3(startPath) {
8858
- let current = resolve30(startPath);
8912
+ let current = resolve31(startPath);
8859
8913
  while (true) {
8860
- const candidate = resolve30(current, "runtime-context.json");
8861
- if (existsSync27(candidate)) {
8914
+ const candidate = resolve31(current, "runtime-context.json");
8915
+ if (existsSync28(candidate)) {
8862
8916
  return candidate;
8863
8917
  }
8864
- const parent = resolve30(current, "..");
8918
+ const parent = resolve31(current, "..");
8865
8919
  if (parent === current) {
8866
8920
  return "";
8867
8921
  }
@@ -8915,7 +8969,7 @@ function getEventBus() {
8915
8969
  }
8916
8970
  function inferRuntimeContext() {
8917
8971
  for (const candidate of runtimeContextCandidates()) {
8918
- if (!candidate || !existsSync28(candidate)) {
8972
+ if (!candidate || !existsSync29(candidate)) {
8919
8973
  continue;
8920
8974
  }
8921
8975
  try {
@@ -8928,15 +8982,15 @@ function inferRuntimeContext() {
8928
8982
  function runtimeContextCandidates() {
8929
8983
  const cwd = process.cwd();
8930
8984
  const candidates = [
8931
- resolve31(cwd, "..", "runtime-context.json"),
8932
- resolve31(cwd, ".rig", "runtime-context.json")
8985
+ resolve32(cwd, "..", "runtime-context.json"),
8986
+ resolve32(cwd, ".rig", "runtime-context.json")
8933
8987
  ];
8934
8988
  const argv1 = process.argv[1]?.trim();
8935
8989
  if (argv1) {
8936
- candidates.push(resolve31(argv1, "..", "..", "runtime-context.json"));
8990
+ candidates.push(resolve32(argv1, "..", "..", "runtime-context.json"));
8937
8991
  }
8938
8992
  if (BAKED_BINARY_PATH) {
8939
- candidates.push(resolve31(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
8993
+ candidates.push(resolve32(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
8940
8994
  }
8941
8995
  return Array.from(new Set(candidates));
8942
8996
  }
@@ -8951,12 +9005,12 @@ var GITHUB_KNOWN_HOSTS = [
8951
9005
  "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
8952
9006
  ];
8953
9007
  function ensureRuntimeKnownHosts(runtimeHome) {
8954
- const sshDir = resolve31(runtimeHome, ".ssh");
8955
- const knownHostsPath = resolve31(sshDir, "known_hosts");
8956
- if (!existsSync28(sshDir)) {
8957
- mkdirSync16(sshDir, { recursive: true });
9008
+ const sshDir = resolve32(runtimeHome, ".ssh");
9009
+ const knownHostsPath = resolve32(sshDir, "known_hosts");
9010
+ if (!existsSync29(sshDir)) {
9011
+ mkdirSync17(sshDir, { recursive: true });
8958
9012
  }
8959
- const existing = existsSync28(knownHostsPath) ? readFileSync16(knownHostsPath, "utf-8") : "";
9013
+ const existing = existsSync29(knownHostsPath) ? readFileSync17(knownHostsPath, "utf-8") : "";
8960
9014
  const existingLines = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
8961
9015
  const missing = GITHUB_KNOWN_HOSTS.filter((line) => !existingLines.has(line));
8962
9016
  if (missing.length === 0) {
@@ -8966,11 +9020,11 @@ function ensureRuntimeKnownHosts(runtimeHome) {
8966
9020
  for (const line of missing) {
8967
9021
  existingLines.add(line);
8968
9022
  }
8969
- writeFileSync14(knownHostsPath, `${Array.from(existingLines).join(`
9023
+ writeFileSync15(knownHostsPath, `${Array.from(existingLines).join(`
8970
9024
  `)}
8971
9025
  `, { mode: 420 });
8972
9026
  } catch (err) {
8973
- const hint = existsSync28(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
9027
+ const hint = existsSync29(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
8974
9028
  console.warn(`[rig-agent] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
8975
9029
  }
8976
9030
  return knownHostsPath;
@@ -8984,13 +9038,13 @@ function hydrateRuntimeProcessEnv(ctx) {
8984
9038
  return;
8985
9039
  }
8986
9040
  process.env.RIG_RUNTIME_CONTEXT_FILE = contextFile;
8987
- const runtimeRoot = dirname17(resolve31(contextFile));
8988
- const runtimeHome = resolve31(runtimeRoot, "home");
8989
- const runtimeTmp = resolve31(runtimeRoot, "tmp");
8990
- const runtimeCache = resolve31(runtimeRoot, "cache");
8991
- const runtimeBin = resolve31(runtimeRoot, "bin");
8992
- const runtimeWorkspaceBin = resolve31(ctx.workspaceDir, ".rig", "bin");
8993
- const runtimeTools = resolve31(ctx.workspaceDir, "rig", "tools");
9041
+ const runtimeRoot = dirname17(resolve32(contextFile));
9042
+ const runtimeHome = resolve32(runtimeRoot, "home");
9043
+ const runtimeTmp = resolve32(runtimeRoot, "tmp");
9044
+ const runtimeCache = resolve32(runtimeRoot, "cache");
9045
+ const runtimeBin = resolve32(runtimeRoot, "bin");
9046
+ const runtimeWorkspaceBin = resolve32(ctx.workspaceDir, ".rig", "bin");
9047
+ const runtimeTools = resolve32(ctx.workspaceDir, "rig", "tools");
8994
9048
  if (ctx.hostProjectRoot) {
8995
9049
  process.env.PROJECT_RIG_ROOT = ctx.hostProjectRoot;
8996
9050
  }
@@ -9006,13 +9060,13 @@ function hydrateRuntimeProcessEnv(ctx) {
9006
9060
  for (const [key, value] of Object.entries(browserEnvFromContext(ctx.browser))) {
9007
9061
  process.env[key] = value;
9008
9062
  }
9009
- if (existsSync28(runtimeHome)) {
9063
+ if (existsSync29(runtimeHome)) {
9010
9064
  process.env.HOME = runtimeHome;
9011
9065
  }
9012
- if (existsSync28(runtimeTmp)) {
9066
+ if (existsSync29(runtimeTmp)) {
9013
9067
  process.env.TMPDIR = runtimeTmp;
9014
9068
  }
9015
- if (existsSync28(runtimeCache)) {
9069
+ if (existsSync29(runtimeCache)) {
9016
9070
  process.env.XDG_CACHE_HOME = runtimeCache;
9017
9071
  }
9018
9072
  const workspaceSecrets = loadDotEnvSecrets(ctx.workspaceDir, process.env);
@@ -9038,31 +9092,31 @@ function hydrateRuntimeProcessEnv(ctx) {
9038
9092
  const currentPath = process.env.PATH || "";
9039
9093
  const pathEntries = currentPath.split(":").filter(Boolean);
9040
9094
  for (const entry of [runtimeBin, runtimeWorkspaceBin, runtimeTools, "/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
9041
- if (existsSync28(entry) && !pathEntries.includes(entry)) {
9095
+ if (existsSync29(entry) && !pathEntries.includes(entry)) {
9042
9096
  pathEntries.unshift(entry);
9043
9097
  }
9044
9098
  }
9045
9099
  process.env.PATH = pathEntries.join(":");
9046
9100
  if (!process.env.RIG_GIT_BIN) {
9047
- const runtimeGit = resolve31(runtimeBin, "git");
9048
- process.env.RIG_GIT_BIN = existsSync28(runtimeGit) ? runtimeGit : Bun.which("git") || "/usr/bin/git";
9101
+ const runtimeGit = resolve32(runtimeBin, "git");
9102
+ process.env.RIG_GIT_BIN = existsSync29(runtimeGit) ? runtimeGit : Bun.which("git") || "/usr/bin/git";
9049
9103
  }
9050
9104
  const knownHosts = ensureRuntimeKnownHosts(runtimeHome);
9051
- const agentKey = resolve31(runtimeHome, ".ssh", "rig-agent-key");
9105
+ const agentKey = resolve32(runtimeHome, ".ssh", "rig-agent-key");
9052
9106
  const sshParts = [
9053
9107
  "ssh",
9054
9108
  `-o UserKnownHostsFile="${knownHosts}"`,
9055
9109
  "-o StrictHostKeyChecking=yes",
9056
9110
  "-F /dev/null"
9057
9111
  ];
9058
- if (existsSync28(agentKey)) {
9112
+ if (existsSync29(agentKey)) {
9059
9113
  sshParts.splice(1, 0, `-i "${agentKey}"`, "-o IdentitiesOnly=yes");
9060
9114
  }
9061
9115
  process.env.GIT_SSH_COMMAND = sshParts.join(" ");
9062
9116
  }
9063
9117
  function inferRuntimeContextFileFromWorkspace(workspaceDir) {
9064
- const candidate = resolve31(workspaceDir, "..", "runtime-context.json");
9065
- return existsSync28(candidate) ? candidate : "";
9118
+ const candidate = resolve32(workspaceDir, "..", "runtime-context.json");
9119
+ return existsSync29(candidate) ? candidate : "";
9066
9120
  }
9067
9121
  async function main() {
9068
9122
  const args = process.argv.slice(2);
@@ -9187,7 +9241,7 @@ async function runAgentCommand(args) {
9187
9241
  const fileIdx = rest.indexOf("--file");
9188
9242
  const inputFile = fileIdx !== -1 ? rest[fileIdx + 1] : undefined;
9189
9243
  if (inputFile) {
9190
- content = readFileSync16(resolve31(projectRoot, inputFile), "utf-8");
9244
+ content = readFileSync17(resolve32(projectRoot, inputFile), "utf-8");
9191
9245
  } else {
9192
9246
  const chunks = [];
9193
9247
  for await (const chunk of process.stdin) {
@@ -9490,8 +9544,8 @@ WORKFLOW:
9490
9544
  `);
9491
9545
  }
9492
9546
  async function runCompletionVerification(projectRoot) {
9493
- const hookPath = resolve31(projectRoot, ".rig/bin/hooks/completion-verification");
9494
- if (!existsSync28(hookPath)) {
9547
+ const hookPath = resolve32(projectRoot, ".rig/bin/hooks/completion-verification");
9548
+ if (!existsSync29(hookPath)) {
9495
9549
  console.error(`[rig-agent] completion-verification hook binary not found: ${hookPath}`);
9496
9550
  return 1;
9497
9551
  }
@@ -9525,7 +9579,7 @@ async function verifyRuntimeManifest() {
9525
9579
  if (!manifestPath) {
9526
9580
  return;
9527
9581
  }
9528
- if (!existsSync28(manifestPath)) {
9582
+ if (!existsSync29(manifestPath)) {
9529
9583
  throw new Error(`[rig-agent] Runtime manifest missing: ${manifestPath}`);
9530
9584
  }
9531
9585
  let manifest;
@@ -9542,10 +9596,10 @@ async function verifyRuntimeManifest() {
9542
9596
  if (!manifestBinaryPath || !expectedHash) {
9543
9597
  throw new Error(`[rig-agent] Runtime manifest is missing binary hash data (${manifestPath}).`);
9544
9598
  }
9545
- if (!existsSync28(manifestBinaryPath)) {
9599
+ if (!existsSync29(manifestBinaryPath)) {
9546
9600
  throw new Error(`[rig-agent] Runtime binary not found at ${manifestBinaryPath}.`);
9547
9601
  }
9548
- const actualHash = sha256Hex(readFileSync16(resolve31(manifestBinaryPath)));
9602
+ const actualHash = sha256Hex(readFileSync17(resolve32(manifestBinaryPath)));
9549
9603
  if (actualHash !== expectedHash) {
9550
9604
  throw new Error(`[rig-agent] Runtime manifest mismatch for binary hash.
9551
9605
  ` + `expected=${expectedHash}