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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/bin/rig-agent-dispatch.js +1165 -785
  2. package/dist/bin/rig-agent.js +458 -389
  3. package/dist/src/control-plane/agent-wrapper.js +1191 -504
  4. package/dist/src/control-plane/authority-files.js +12 -6
  5. package/dist/src/control-plane/harness-main.js +2186 -1786
  6. package/dist/src/control-plane/hooks/completion-verification.js +2084 -1019
  7. package/dist/src/control-plane/hooks/inject-context.js +193 -139
  8. package/dist/src/control-plane/hooks/submodule-branch.js +603 -545
  9. package/dist/src/control-plane/hooks/task-runtime-start.js +603 -545
  10. package/dist/src/control-plane/materialize-task-config.js +64 -8
  11. package/dist/src/control-plane/native/git-ops.js +90 -64
  12. package/dist/src/control-plane/native/harness-cli.js +1989 -682
  13. package/dist/src/control-plane/native/pr-automation.js +1657 -54
  14. package/dist/src/control-plane/native/pr-review-gate.js +1455 -0
  15. package/dist/src/control-plane/native/repo-ops.js +3 -0
  16. package/dist/src/control-plane/native/run-ops.js +39 -13
  17. package/dist/src/control-plane/native/task-ops.js +1819 -527
  18. package/dist/src/control-plane/native/validator.js +163 -109
  19. package/dist/src/control-plane/native/verifier.js +1616 -323
  20. package/dist/src/control-plane/native/workspace-ops.js +12 -6
  21. package/dist/src/control-plane/pi-sessiond/bin.js +793 -0
  22. package/dist/src/control-plane/pi-sessiond/client.js +41 -0
  23. package/dist/src/control-plane/pi-sessiond/event-hub.js +59 -0
  24. package/dist/src/control-plane/pi-sessiond/extension-ui-context.js +198 -0
  25. package/dist/src/control-plane/pi-sessiond/launcher.js +173 -0
  26. package/dist/src/control-plane/pi-sessiond/server.js +802 -0
  27. package/dist/src/control-plane/pi-sessiond/session-service.js +540 -0
  28. package/dist/src/control-plane/pi-sessiond/types.js +1 -0
  29. package/dist/src/control-plane/plugin-host-context.js +54 -0
  30. package/dist/src/control-plane/runtime/image/fingerprint-sidecar.js +3 -0
  31. package/dist/src/control-plane/runtime/image/index.js +3 -0
  32. package/dist/src/control-plane/runtime/image-fingerprint-sidecar.js +3 -0
  33. package/dist/src/control-plane/runtime/image.js +3 -0
  34. package/dist/src/control-plane/runtime/index.js +517 -722
  35. package/dist/src/control-plane/runtime/isolation/home.js +28 -6
  36. package/dist/src/control-plane/runtime/isolation/index.js +541 -461
  37. package/dist/src/control-plane/runtime/isolation/runner.js +28 -6
  38. package/dist/src/control-plane/runtime/isolation/shared.js +9 -6
  39. package/dist/src/control-plane/runtime/isolation.js +541 -461
  40. package/dist/src/control-plane/runtime/plugin-mode.js +3 -27
  41. package/dist/src/control-plane/runtime/queue.js +458 -385
  42. package/dist/src/control-plane/runtime/snapshot/task-run.js +3 -0
  43. package/dist/src/control-plane/runtime/task-run-snapshot.js +3 -0
  44. package/dist/src/control-plane/skill-materializer.js +46 -0
  45. package/dist/src/control-plane/tasks/source-aware-task-config-source.js +14 -2
  46. package/dist/src/control-plane/tasks/source-lifecycle.js +86 -32
  47. package/dist/src/index.js +27 -298
  48. package/dist/src/layout.js +12 -7
  49. package/dist/src/local-server.js +20 -14
  50. package/native/darwin-arm64/rig-git +0 -0
  51. package/native/darwin-arm64/rig-git.build-manifest.json +1 -1
  52. package/native/darwin-arm64/rig-shell +0 -0
  53. package/native/darwin-arm64/rig-shell.build-manifest.json +1 -1
  54. package/native/darwin-arm64/rig-tools +0 -0
  55. package/native/darwin-arm64/rig-tools.build-manifest.json +1 -1
  56. package/native/darwin-arm64/runtime-native.dylib +0 -0
  57. package/package.json +8 -6
  58. package/dist/src/control-plane/runtime/plugins.js +0 -1131
  59. package/dist/src/plugins.js +0 -329
@@ -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) {
@@ -4421,8 +4475,8 @@ function githubStatusFor(issue) {
4421
4475
  return "open";
4422
4476
  }
4423
4477
  function selectedGitHubEnv() {
4424
- const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() ?? "";
4425
- return { GH_TOKEN: token, GITHUB_TOKEN: token };
4478
+ const token = process.env.RIG_GITHUB_SELECTED_TOKEN?.trim() || process.env.RIG_GITHUB_TOKEN?.trim() || "";
4479
+ return { GH_TOKEN: token, GITHUB_TOKEN: token, RIG_GITHUB_TOKEN: token };
4426
4480
  }
4427
4481
  function ghSpawnOptions() {
4428
4482
  return { encoding: "utf-8", env: { ...process.env, ...selectedGitHubEnv() } };
@@ -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,15 +6435,15 @@ ${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");
6392
- const attempts = (content.match(new RegExp(`^## ${escapeRegExp2(activeTask)}\\b`, "gm")) || []).length + 1;
6445
+ const content = readFileSync13(failedPath, "utf-8");
6446
+ const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
6393
6447
  appendFileSync(failedPath, `
6394
6448
  ## ${activeTask} - Attempt ${attempts} (${nowIso()})
6395
6449
 
@@ -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,14 +6932,14 @@ 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
- function escapeRegExp2(value) {
6942
+ function escapeRegExp(value) {
6889
6943
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6890
6944
  }
6891
6945
  function changedFilesForTask(projectRoot, taskId, scoped) {
@@ -6914,16 +6968,16 @@ var TASK_ARTIFACT_STAGE_FALLBACK = new Set([
6914
6968
  "task-result.json",
6915
6969
  "validation-summary.json"
6916
6970
  ]);
6917
- function resolveHostRigBinDir(root) {
6918
- return resolve26(root, ".rig", "bin");
6919
- }
6920
6971
  function isRuntimeGatewayGitPath(candidate) {
6921
6972
  return /\/\.rig\/bin\/git$/.test(candidate.replace(/\\/g, "/"));
6922
6973
  }
6974
+ function isRuntimeGatewayGhPath(candidate) {
6975
+ return /\/\.rig\/bin\/gh$/.test(candidate.replace(/\\/g, "/"));
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,12 +7002,15 @@ 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
  }
6955
7009
  return "git";
6956
7010
  }
7011
+ function escapeRegExp2(value) {
7012
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
7013
+ }
6957
7014
  function safeCurrentTaskId(projectRoot) {
6958
7015
  try {
6959
7016
  const taskId = currentTaskId(projectRoot);
@@ -7005,11 +7062,11 @@ function gitPreflight(projectRoot, taskId, strict) {
7005
7062
  const expected = resolvedTask ? `rig/${resolveTaskBranchId(projectRoot, resolvedTask)}` : "";
7006
7063
  console.log("=== Git Flow Preflight ===");
7007
7064
  let issues = 0;
7008
- if (!existsSync22(resolve26(projectRoot, ".git"))) {
7065
+ if (!existsSync23(resolve27(projectRoot, ".git"))) {
7009
7066
  console.log(`ERROR: project root is not a git repo (${projectRoot})`);
7010
7067
  issues += 1;
7011
7068
  }
7012
- if (monorepoRoot && existsSync22(resolve26(monorepoRoot, ".git"))) {
7069
+ if (monorepoRoot && existsSync23(resolve27(monorepoRoot, ".git"))) {
7013
7070
  const monoBranch = branchName(projectRoot, monorepoRoot);
7014
7071
  if (expected && monoBranch !== expected) {
7015
7072
  console.log(`WARN: monorepo branch is ${monoBranch}, expected ${expected} for task ${resolvedTask}`);
@@ -7043,7 +7100,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7043
7100
  }
7044
7101
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7045
7102
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7046
- if (!existsSync22(resolve26(repoRoot, ".git"))) {
7103
+ if (!existsSync23(resolve27(repoRoot, ".git"))) {
7047
7104
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7048
7105
  }
7049
7106
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7087,8 +7144,8 @@ function gitCommit(options) {
7087
7144
  function gitSnapshot(projectRoot, taskId, outputPath) {
7088
7145
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
7089
7146
  const resolvedTask = taskId || safeCurrentTaskId(projectRoot);
7090
- const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve26(resolve26(projectRoot, ".rig", "state"), "git-state.txt"));
7091
- 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 });
7092
7149
  const lines = ["# Git Snapshot", `timestamp: ${nowIso()}`];
7093
7150
  if (resolvedTask) {
7094
7151
  lines.push(`task: ${resolvedTask}`);
@@ -7098,7 +7155,7 @@ function gitSnapshot(projectRoot, taskId, outputPath) {
7098
7155
  if (monorepoRoot && monorepoRoot !== projectRoot) {
7099
7156
  lines.push(...snapshotRepo(projectRoot, "monorepo", monorepoRoot));
7100
7157
  }
7101
- writeFileSync10(output, `${lines.join(`
7158
+ writeFileSync11(output, `${lines.join(`
7102
7159
  `)}
7103
7160
  `, "utf-8");
7104
7161
  return output;
@@ -7122,7 +7179,7 @@ function gitOpenPr(options) {
7122
7179
  } else if (taskId) {
7123
7180
  gitSyncBranch(options.projectRoot, taskId, "project");
7124
7181
  }
7125
- if (!existsSync22(resolve26(repoRoot, ".git"))) {
7182
+ if (!existsSync23(resolve27(repoRoot, ".git"))) {
7126
7183
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7127
7184
  }
7128
7185
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7167,10 +7224,11 @@ function gitOpenPr(options) {
7167
7224
  "",
7168
7225
  "## Task",
7169
7226
  `- beads: ${taskId || "n/a"}`,
7227
+ ...defaultPrRunLines(taskId, repoNameWithOwner),
7170
7228
  "",
7171
7229
  "## Review",
7172
7230
  "- Completion verification will run validation, verifier review, and PR policy checks.",
7173
- "- When repository policy allows it, Rig enables GitHub auto-merge after approval."
7231
+ "- When repository policy allows it, Rig attempts an immediate strict-gated, head-locked merge after approval."
7174
7232
  ].join(`
7175
7233
  `);
7176
7234
  const preCheck = runCapture2(withGhRepo([gh, "pr", "list", "--state", "merged", "--head", branch, "--json", "url,mergedAt", "--jq", ".[0]"], repoNameWithOwner), repoRoot);
@@ -7258,6 +7316,30 @@ function gitOpenPr(options) {
7258
7316
  }
7259
7317
  return result;
7260
7318
  }
7319
+ function defaultPrRunLines(taskId, repoNameWithOwner) {
7320
+ const lines = [];
7321
+ const runId = process.env.RIG_SERVER_RUN_ID?.trim();
7322
+ if (runId) {
7323
+ lines.push(`- Run: ${runId}`);
7324
+ }
7325
+ const closeout = defaultPrCloseoutLine(taskId, repoNameWithOwner);
7326
+ if (closeout) {
7327
+ lines.push(`- ${closeout}`);
7328
+ }
7329
+ return lines;
7330
+ }
7331
+ function defaultPrCloseoutLine(taskId, repoNameWithOwner) {
7332
+ const sourceIssueId = loadRuntimeContextFromEnv()?.sourceTask?.sourceIssueId;
7333
+ if (sourceIssueId) {
7334
+ const match = sourceIssueId.match(/^([^#]+)#(\d+)$/);
7335
+ if (match?.[1] && match[2]) {
7336
+ const sourceRepo = match[1];
7337
+ const issueNumber = match[2];
7338
+ return sourceRepo.toLowerCase() === repoNameWithOwner.toLowerCase() ? `Closes #${issueNumber}` : `Closes ${sourceRepo}#${issueNumber}`;
7339
+ }
7340
+ }
7341
+ return /^\d+$/.test(taskId) ? `Closes #${taskId}` : "";
7342
+ }
7261
7343
  function readPrViewState(gh, repoRoot, repoNameWithOwner, prUrl) {
7262
7344
  const view = runCapture2(withGhRepo([
7263
7345
  gh,
@@ -7310,12 +7392,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7310
7392
  }
7311
7393
  function writePrMetadata(projectRoot, taskId, result) {
7312
7394
  const dir = artifactDirForId(projectRoot, taskId);
7313
- mkdirSync10(dir, { recursive: true });
7314
- const path = resolve26(dir, "pr-state.json");
7395
+ mkdirSync11(dir, { recursive: true });
7396
+ const path = resolve27(dir, "pr-state.json");
7315
7397
  let prs = {};
7316
- if (existsSync22(path)) {
7398
+ if (existsSync23(path)) {
7317
7399
  try {
7318
- const parsed = JSON.parse(readFileSync13(path, "utf-8"));
7400
+ const parsed = JSON.parse(readFileSync14(path, "utf-8"));
7319
7401
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7320
7402
  prs = parsed.prs;
7321
7403
  }
@@ -7331,12 +7413,12 @@ function writePrMetadata(projectRoot, taskId, result) {
7331
7413
  ...primary || {},
7332
7414
  updated_at: nowIso()
7333
7415
  };
7334
- writeFileSync10(path, `${JSON.stringify(artifact, null, 2)}
7416
+ writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7335
7417
  `, "utf-8");
7336
7418
  }
7337
7419
  function resolveArtifactSnapshot(projectRoot, taskId) {
7338
- const artifactDir = resolve26(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7339
- return resolve26(artifactDir, "git-state.txt");
7420
+ const artifactDir = resolve27(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7421
+ return resolve27(artifactDir, "git-state.txt");
7340
7422
  }
7341
7423
  function ensureFullGitHistory(projectRoot, repoRoot, remoteName = "origin") {
7342
7424
  const shallow = runCapture2(gitCmd(projectRoot, repoRoot, "rev-parse", "--is-shallow-repository"), projectRoot);
@@ -7383,32 +7465,19 @@ function resolveGithubCliBinary(projectRoot) {
7383
7465
  if (explicit) {
7384
7466
  candidates.add(explicit);
7385
7467
  }
7468
+ for (const candidate of ["/usr/bin/gh", "/opt/homebrew/bin/gh", "/usr/local/bin/gh"]) {
7469
+ candidates.add(candidate);
7470
+ }
7386
7471
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7387
7472
  for (const entry of explicitPathEntries) {
7388
- candidates.add(resolve26(entry, "gh"));
7389
- }
7390
- const hostProjectRoot = process.env.RIG_HOST_PROJECT_ROOT?.trim();
7391
- if (hostProjectRoot) {
7392
- candidates.add(resolve26(resolveHostRigBinDir(hostProjectRoot), "gh"));
7393
- }
7394
- candidates.add(resolve26(resolveHostRigBinDir(projectRoot), "gh"));
7395
- const runtimeContext = loadRuntimeContextFromEnv();
7396
- if (runtimeContext?.binDir) {
7397
- candidates.add(resolve26(runtimeContext.binDir, "gh"));
7398
- }
7399
- const runtimeHome = process.env.RIG_RUNTIME_HOME?.trim();
7400
- if (runtimeHome) {
7401
- candidates.add(resolve26(runtimeHome, "bin", "gh"));
7402
- }
7403
- for (const candidate of ["/opt/homebrew/bin/gh", "/usr/local/bin/gh", "/usr/bin/gh"]) {
7404
- candidates.add(candidate);
7473
+ candidates.add(resolve27(entry, "gh"));
7405
7474
  }
7406
7475
  const bunResolved = Bun.which("gh");
7407
7476
  if (bunResolved) {
7408
7477
  candidates.add(bunResolved);
7409
7478
  }
7410
7479
  for (const candidate of candidates) {
7411
- if (candidate && existsSync22(candidate)) {
7480
+ if (candidate && existsSync23(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7412
7481
  return candidate;
7413
7482
  }
7414
7483
  }
@@ -7438,7 +7507,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7438
7507
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7439
7508
  }
7440
7509
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7441
- const normalizedGitRoot = resolve26(gitRoot);
7510
+ const normalizedGitRoot = resolve27(gitRoot);
7442
7511
  if (visited.has(normalizedGitRoot)) {
7443
7512
  return "";
7444
7513
  }
@@ -7510,7 +7579,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
7510
7579
  return remotes.includes("origin") ? "origin" : remotes[0];
7511
7580
  }
7512
7581
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
7513
- 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];
7514
7583
  return runCapture2(gitArgs, cwd, projectRoot);
7515
7584
  }
7516
7585
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -7528,9 +7597,9 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
7528
7597
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
7529
7598
  return "";
7530
7599
  } else if (!isAbsolute2(normalized)) {
7531
- candidate = resolve26(gitRoot, normalized);
7600
+ candidate = resolve27(gitRoot, normalized);
7532
7601
  }
7533
- return existsSync22(candidate) ? candidate : "";
7602
+ return existsSync23(candidate) ? candidate : "";
7534
7603
  }
7535
7604
  function normalizeGithubRepoNameWithOwner(value) {
7536
7605
  const normalized = value.trim();
@@ -7561,7 +7630,7 @@ function inferRepositoryDefaultBase(projectRoot, repoRoot, repoNameWithOwner, re
7561
7630
  const remote = remoteName || "origin";
7562
7631
  const symbolic = runCapture2(gitCmd(projectRoot, repoRoot, "symbolic-ref", "--short", `refs/remotes/${remote}/HEAD`), projectRoot);
7563
7632
  if (symbolic.exitCode === 0) {
7564
- const ref = symbolic.stdout.trim().replace(new RegExp(`^${escapeRegExp(remote)}/`), "");
7633
+ const ref = symbolic.stdout.trim().replace(new RegExp(`^${escapeRegExp2(remote)}/`), "");
7565
7634
  if (ref && ref !== "HEAD") {
7566
7635
  return ref;
7567
7636
  }
@@ -7657,7 +7726,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
7657
7726
  return best;
7658
7727
  }
7659
7728
  function snapshotRepo(projectRoot, label, repo) {
7660
- if (!existsSync22(resolve26(repo, ".git"))) {
7729
+ if (!existsSync23(resolve27(repo, ".git"))) {
7661
7730
  return [`## ${label}`, `repo: ${repo}`, "status: unavailable", ""];
7662
7731
  }
7663
7732
  const status = runCapture2(gitCmd(projectRoot, repo, "status", "--short"), projectRoot).stdout.trim();
@@ -7680,7 +7749,7 @@ function snapshotRepo(projectRoot, label, repo) {
7680
7749
  ];
7681
7750
  }
7682
7751
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
7683
- if (!existsSync22(resolve26(repo, ".git"))) {
7752
+ if (!existsSync23(resolve27(repo, ".git"))) {
7684
7753
  console.log(`Skipping ${label}: repo not available (${repo})`);
7685
7754
  return;
7686
7755
  }
@@ -7712,18 +7781,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
7712
7781
  console.log(`Committed ${label}: ${message}`);
7713
7782
  }
7714
7783
  function readChangedFilesManifest(projectRoot, taskId) {
7715
- const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7716
- if (!existsSync22(manifestPath)) {
7784
+ const manifestPath = resolve27(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7785
+ if (!existsSync23(manifestPath)) {
7717
7786
  return [];
7718
7787
  }
7719
- 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);
7720
7789
  return [...new Set(files)];
7721
7790
  }
7722
7791
  function refreshChangedFilesManifest(projectRoot, taskId) {
7723
- const manifestPath = resolve26(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7724
- mkdirSync10(dirname14(manifestPath), { recursive: true });
7792
+ const manifestPath = resolve27(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7793
+ mkdirSync11(dirname14(manifestPath), { recursive: true });
7725
7794
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
7726
- writeFileSync10(manifestPath, `${changedFiles.join(`
7795
+ writeFileSync11(manifestPath, `${changedFiles.join(`
7727
7796
  `)}
7728
7797
  `, "utf-8");
7729
7798
  return manifestPath;
@@ -7836,7 +7905,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
7836
7905
  return result.exitCode === 0 && result.stdout.trim().length > 0;
7837
7906
  }
7838
7907
  function stageExcludePathspecs(repoRoot) {
7839
- 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];
7840
7909
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
7841
7910
  }
7842
7911
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -7846,7 +7915,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
7846
7915
  }
7847
7916
  let current = repoRoot;
7848
7917
  for (let index = 0;index < parts.length - 1; index += 1) {
7849
- current = resolve26(current, parts[index]);
7918
+ current = resolve27(current, parts[index]);
7850
7919
  try {
7851
7920
  if (lstatSync(current).isSymbolicLink()) {
7852
7921
  return true;
@@ -7858,7 +7927,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
7858
7927
  return false;
7859
7928
  }
7860
7929
  function printRepoStatus(projectRoot, label, repo, expectedBranch) {
7861
- if (!existsSync22(resolve26(repo, ".git"))) {
7930
+ if (!existsSync23(resolve27(repo, ".git"))) {
7862
7931
  console.log(`${label}: unavailable (${repo})`);
7863
7932
  return;
7864
7933
  }
@@ -7894,7 +7963,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
7894
7963
  }
7895
7964
  } catch {}
7896
7965
  const artifactDir = artifactDirForId(projectRoot, taskId);
7897
- if (existsSync22(artifactDir)) {
7966
+ if (existsSync23(artifactDir)) {
7898
7967
  return taskId;
7899
7968
  }
7900
7969
  throw new Error(`Unknown task id: ${taskId}`);
@@ -7930,11 +7999,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
7930
7999
  }
7931
8000
  function runtimeGitEnv(projectRoot) {
7932
8001
  const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
7933
- const runtimeHome = runtimeRoot ? resolve26(runtimeRoot, "home") : "";
7934
- const runtimeTmp = runtimeRoot ? resolve26(runtimeRoot, "tmp") : "";
7935
- const runtimeCache = runtimeRoot ? resolve26(runtimeRoot, "cache") : "";
7936
- const runtimeKnownHosts = runtimeHome ? resolve26(runtimeHome, ".ssh", "known_hosts") : "";
7937
- 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") : "";
7938
8007
  const env = {};
7939
8008
  if (ctx?.workspaceDir) {
7940
8009
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -7947,14 +8016,14 @@ function runtimeGitEnv(projectRoot) {
7947
8016
  if (runtimeRoot) {
7948
8017
  env.RIG_RUNTIME_HOME = runtimeRoot;
7949
8018
  }
7950
- if (runtimeHome && existsSync22(runtimeHome)) {
8019
+ if (runtimeHome && existsSync23(runtimeHome)) {
7951
8020
  env.HOME = runtimeHome;
7952
8021
  env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
7953
8022
  }
7954
- if (runtimeTmp && existsSync22(runtimeTmp)) {
8023
+ if (runtimeTmp && existsSync23(runtimeTmp)) {
7955
8024
  env.TMPDIR = runtimeTmp;
7956
8025
  }
7957
- if (runtimeCache && existsSync22(runtimeCache)) {
8026
+ if (runtimeCache && existsSync23(runtimeCache)) {
7958
8027
  env.XDG_CACHE_HOME = runtimeCache;
7959
8028
  }
7960
8029
  const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
@@ -7998,14 +8067,14 @@ function runtimeGitEnv(projectRoot) {
7998
8067
  env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
7999
8068
  applyGitHubCredentialHelperEnv(env);
8000
8069
  }
8001
- if (runtimeKnownHosts && existsSync22(runtimeKnownHosts)) {
8070
+ if (runtimeKnownHosts && existsSync23(runtimeKnownHosts)) {
8002
8071
  const sshParts = [
8003
8072
  "ssh",
8004
8073
  `-o UserKnownHostsFile="${runtimeKnownHosts}"`,
8005
8074
  "-o StrictHostKeyChecking=yes",
8006
8075
  "-F /dev/null"
8007
8076
  ];
8008
- if (runtimeKey && existsSync22(runtimeKey)) {
8077
+ if (runtimeKey && existsSync23(runtimeKey)) {
8009
8078
  sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
8010
8079
  }
8011
8080
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -8026,12 +8095,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8026
8095
  if (!runtimeRoot) {
8027
8096
  return {};
8028
8097
  }
8029
- const path = resolve26(runtimeRoot, "runtime-secrets.json");
8030
- if (!existsSync22(path)) {
8098
+ const path = resolve27(runtimeRoot, "runtime-secrets.json");
8099
+ if (!existsSync23(path)) {
8031
8100
  return {};
8032
8101
  }
8033
8102
  try {
8034
- const parsed = JSON.parse(readFileSync13(path, "utf-8"));
8103
+ const parsed = JSON.parse(readFileSync14(path, "utf-8"));
8035
8104
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8036
8105
  return Object.fromEntries(entries);
8037
8106
  } catch {
@@ -8039,13 +8108,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8039
8108
  }
8040
8109
  }
8041
8110
  function ensureRuntimeOpenSslConfig(runtimeHome) {
8042
- const sslDir = resolve26(runtimeHome, ".ssl");
8043
- const sslConfig = resolve26(sslDir, "openssl.cnf");
8044
- if (!existsSync22(sslDir)) {
8045
- 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 });
8046
8115
  }
8047
- if (!existsSync22(sslConfig)) {
8048
- writeFileSync10(sslConfig, `# Rig runtime OpenSSL config placeholder
8116
+ if (!existsSync23(sslConfig)) {
8117
+ writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8049
8118
  `);
8050
8119
  }
8051
8120
  return sslConfig;
@@ -8063,11 +8132,11 @@ function resolveRuntimeMetadata(projectRoot) {
8063
8132
  if (contextFile) {
8064
8133
  return {
8065
8134
  ctx,
8066
- runtimeRoot: dirname14(resolve26(contextFile))
8135
+ runtimeRoot: dirname14(resolve27(contextFile))
8067
8136
  };
8068
8137
  }
8069
8138
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
8070
- if (existsSync22(inferredContextFile)) {
8139
+ if (existsSync23(inferredContextFile)) {
8071
8140
  try {
8072
8141
  ctx = loadRuntimeContext(inferredContextFile);
8073
8142
  } catch {}
@@ -8079,10 +8148,10 @@ function resolveRuntimeMetadata(projectRoot) {
8079
8148
  return { ctx, runtimeRoot: "" };
8080
8149
  }
8081
8150
  function findRuntimeContextFile2(startPath) {
8082
- let current = resolve26(startPath);
8151
+ let current = resolve27(startPath);
8083
8152
  while (true) {
8084
- const candidate = resolve26(current, "runtime-context.json");
8085
- if (existsSync22(candidate)) {
8153
+ const candidate = resolve27(current, "runtime-context.json");
8154
+ if (existsSync23(candidate)) {
8086
8155
  return candidate;
8087
8156
  }
8088
8157
  const parent = dirname14(current);
@@ -8094,7 +8163,7 @@ function findRuntimeContextFile2(startPath) {
8094
8163
  }
8095
8164
 
8096
8165
  // packages/runtime/src/control-plane/native/profile-ops.ts
8097
- 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";
8098
8167
  var DEFAULTS = {
8099
8168
  model: parseEnvOrDefault(process.env.DEFAULT_AGENT_MODEL, ["claude", "gpt-codex", "pi"], "pi"),
8100
8169
  runtime: parseEnvOrDefault(process.env.DEFAULT_AGENT_RUNTIME, ["claude-code", "codex-app-server", "pi"], "pi"),
@@ -8109,7 +8178,7 @@ function parseEnvOrDefault(value, allowed, fallback) {
8109
8178
  return allowed.includes(value) ? value : fallback;
8110
8179
  }
8111
8180
  async function readProfileFile(path) {
8112
- if (!existsSync23(path)) {
8181
+ if (!existsSync24(path)) {
8113
8182
  return null;
8114
8183
  }
8115
8184
  try {
@@ -8162,14 +8231,14 @@ async function setProfile(projectRoot, options) {
8162
8231
  plugin = model === "gpt-codex" ? "codex" : model === "pi" ? "pi" : "claude";
8163
8232
  }
8164
8233
  const paths = resolveHarnessPaths(projectRoot);
8165
- mkdirSync11(paths.stateDir, { recursive: true });
8234
+ mkdirSync12(paths.stateDir, { recursive: true });
8166
8235
  const next = {
8167
8236
  model,
8168
8237
  runtime,
8169
8238
  agent_plugin: plugin,
8170
8239
  updated_at: new Date().toISOString()
8171
8240
  };
8172
- writeFileSync11(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8241
+ writeFileSync12(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8173
8242
  `, "utf-8");
8174
8243
  await showProfile(projectRoot, false);
8175
8244
  }
@@ -8205,13 +8274,13 @@ async function setReviewProfile(projectRoot, mode, provider) {
8205
8274
  throw new Error(`Invalid provider: ${resolvedProvider}. Supported: greptile.`);
8206
8275
  }
8207
8276
  const paths = resolveHarnessPaths(projectRoot);
8208
- mkdirSync11(paths.stateDir, { recursive: true });
8277
+ mkdirSync12(paths.stateDir, { recursive: true });
8209
8278
  const next = {
8210
8279
  mode,
8211
8280
  provider: resolvedProvider,
8212
8281
  updated_at: new Date().toISOString()
8213
8282
  };
8214
- writeFileSync11(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8283
+ writeFileSync12(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8215
8284
  `, "utf-8");
8216
8285
  await showReviewProfile(projectRoot);
8217
8286
  }
@@ -8249,44 +8318,44 @@ async function loadReviewProfile(path) {
8249
8318
  }
8250
8319
 
8251
8320
  // packages/runtime/src/control-plane/native/repo-ops.ts
8252
- import { existsSync as existsSync27, mkdirSync as mkdirSync15, readFileSync as readFileSync15, readdirSync as readdirSync5, rmSync as rmSync7, writeFileSync as writeFileSync13 } from "fs";
8253
- 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";
8254
8323
  // packages/runtime/src/control-plane/repos/mirror/bootstrap.ts
8255
- import { existsSync as existsSync25, mkdirSync as mkdirSync13, realpathSync as realpathSync2 } from "fs";
8256
- 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";
8257
8326
 
8258
8327
  // packages/runtime/src/control-plane/authority-files.ts
8259
- 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";
8260
- 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";
8261
8330
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8262
8331
  function resolveAuthorityProjectStateDir(projectRoot) {
8263
8332
  const explicit = process.env.RIG_STATE_DIR?.trim();
8264
8333
  if (explicit) {
8265
- return resolve27(explicit);
8334
+ return resolve28(explicit);
8266
8335
  }
8267
- return resolve27(resolve27(projectRoot), ".rig", "state");
8336
+ return resolve28(resolve28(projectRoot), ".rig", "state");
8268
8337
  }
8269
8338
  function readJsonAtPath(path, fallback) {
8270
- if (!existsSync24(path)) {
8339
+ if (!existsSync25(path)) {
8271
8340
  return fallback;
8272
8341
  }
8273
8342
  try {
8274
- return JSON.parse(readFileSync14(path, "utf-8"));
8343
+ return JSON.parse(readFileSync15(path, "utf-8"));
8275
8344
  } catch {
8276
8345
  return fallback;
8277
8346
  }
8278
8347
  }
8279
8348
  function writeJsonAtPath(path, value) {
8280
- mkdirSync12(dirname15(path), { recursive: true });
8281
- writeFileSync12(path, `${JSON.stringify(value, null, 2)}
8349
+ mkdirSync13(dirname15(path), { recursive: true });
8350
+ writeFileSync13(path, `${JSON.stringify(value, null, 2)}
8282
8351
  `, "utf8");
8283
8352
  return path;
8284
8353
  }
8285
8354
  function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
8286
- return readJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8355
+ return readJsonAtPath(resolve28(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8287
8356
  }
8288
8357
  function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
8289
- return writeJsonAtPath(resolve27(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8358
+ return writeJsonAtPath(resolve28(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8290
8359
  }
8291
8360
 
8292
8361
  // packages/runtime/src/control-plane/repos/mirror/state.ts
@@ -8346,7 +8415,7 @@ function sameExistingPath(left, right) {
8346
8415
  try {
8347
8416
  return realpathSync2(left) === realpathSync2(right);
8348
8417
  } catch {
8349
- return resolve28(left) === resolve28(right);
8418
+ return resolve29(left) === resolve29(right);
8350
8419
  }
8351
8420
  }
8352
8421
  function repoLooksUsable(repoRoot, projectRoot) {
@@ -8382,7 +8451,7 @@ function resolveMirrorRemoteUrl(layout) {
8382
8451
  }
8383
8452
  }
8384
8453
  }
8385
- if (existsSync25(resolve28(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8454
+ if (existsSync26(resolve29(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8386
8455
  const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
8387
8456
  if (checkoutOrigin.exitCode === 0) {
8388
8457
  const currentOrigin = checkoutOrigin.stdout.trim();
@@ -8395,9 +8464,9 @@ function resolveMirrorRemoteUrl(layout) {
8395
8464
  }
8396
8465
  function ensureManagedRepoMirror(projectRoot, repoId) {
8397
8466
  const layout = resolveManagedRepoLayout(projectRoot, repoId);
8398
- mkdirSync13(layout.metadataRoot, { recursive: true });
8467
+ mkdirSync14(layout.metadataRoot, { recursive: true });
8399
8468
  const remoteUrl = resolveMirrorRemoteUrl(layout);
8400
- if (!existsSync25(resolve28(layout.mirrorRoot, "HEAD"))) {
8469
+ if (!existsSync26(resolve29(layout.mirrorRoot, "HEAD"))) {
8401
8470
  ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
8402
8471
  }
8403
8472
  const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8417,8 +8486,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
8417
8486
  return layout;
8418
8487
  }
8419
8488
  // packages/runtime/src/control-plane/repos/mirror/refresh.ts
8420
- import { existsSync as existsSync26, mkdirSync as mkdirSync14, realpathSync as realpathSync3, rmSync as rmSync6 } from "fs";
8421
- 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";
8422
8491
  function nowIso3() {
8423
8492
  return new Date().toISOString();
8424
8493
  }
@@ -8445,7 +8514,7 @@ function sameExistingPath2(left, right) {
8445
8514
  try {
8446
8515
  return realpathSync3(left) === realpathSync3(right);
8447
8516
  } catch {
8448
- return resolve29(left) === resolve29(right);
8517
+ return resolve30(left) === resolve30(right);
8449
8518
  }
8450
8519
  }
8451
8520
  function ensureMirrorHead(layout) {
@@ -8491,12 +8560,12 @@ function checkoutLooksUsable2(layout) {
8491
8560
  return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
8492
8561
  }
8493
8562
  function ensureCheckoutFromMirror(layout) {
8494
- mkdirSync14(resolve29(layout.checkoutRoot, ".."), { recursive: true });
8495
- const gitPath = resolve29(layout.checkoutRoot, ".git");
8496
- if (existsSync26(layout.checkoutRoot) && (!existsSync26(gitPath) || !checkoutLooksUsable2(layout))) {
8497
- 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 });
8498
8567
  }
8499
- if (!existsSync26(gitPath)) {
8568
+ if (!existsSync27(gitPath)) {
8500
8569
  ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
8501
8570
  }
8502
8571
  const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8597,7 +8666,7 @@ function repoDiscover(projectRoot, taskId) {
8597
8666
  }
8598
8667
  function repoBaseline(projectRoot, refresh = false) {
8599
8668
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8600
- if (!refresh && existsSync27(paths.baseRepoPinsPath)) {
8669
+ if (!refresh && existsSync28(paths.baseRepoPinsPath)) {
8601
8670
  const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
8602
8671
  return baseline.repos || {};
8603
8672
  }
@@ -8621,8 +8690,8 @@ function ensureMonorepoReady(projectRoot) {
8621
8690
  }
8622
8691
  function persistBaselinePins(projectRoot, repos) {
8623
8692
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8624
- mkdirSync15(resolve30(paths.baseRepoPinsPath, ".."), { recursive: true });
8625
- 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)}
8626
8695
  `, "utf-8");
8627
8696
  return repos;
8628
8697
  }
@@ -8701,28 +8770,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
8701
8770
  function resolveRepoDiscoveryPaths(projectRoot) {
8702
8771
  const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
8703
8772
  const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
8704
- const normalizedProjectRoot = resolve30(projectRoot);
8773
+ const normalizedProjectRoot = resolve31(projectRoot);
8705
8774
  const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
8706
- const stateDir = resolve30(hostProjectRoot, ".rig", "state");
8775
+ const stateDir = resolve31(hostProjectRoot, ".rig", "state");
8707
8776
  return {
8708
8777
  monorepoRoot,
8709
- taskRepoCommitsPath: resolve30(stateDir, "task-repo-commits.json"),
8710
- baseRepoPinsPath: resolve30(stateDir, "base-repo-pins.json")
8778
+ taskRepoCommitsPath: resolve31(stateDir, "task-repo-commits.json"),
8779
+ baseRepoPinsPath: resolve31(stateDir, "base-repo-pins.json")
8711
8780
  };
8712
8781
  }
8713
8782
  function shouldUseHostProjectStateRoot(projectRoot) {
8714
8783
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
8715
- if (runtimeWorkspace && resolve30(runtimeWorkspace) === projectRoot) {
8784
+ if (runtimeWorkspace && resolve31(runtimeWorkspace) === projectRoot) {
8716
8785
  return true;
8717
8786
  }
8718
8787
  return basename8(dirname16(projectRoot)) === ".worktrees";
8719
8788
  }
8720
8789
  function readPinFromArtifact(projectRoot, depTask, repoKey) {
8721
- const snapshot = resolve30(artifactDirForId(projectRoot, depTask), "git-state.txt");
8722
- if (!existsSync27(snapshot)) {
8790
+ const snapshot = resolve31(artifactDirForId(projectRoot, depTask), "git-state.txt");
8791
+ if (!existsSync28(snapshot)) {
8723
8792
  return "";
8724
8793
  }
8725
- const content = readFileSync15(snapshot, "utf-8");
8794
+ const content = readFileSync16(snapshot, "utf-8");
8726
8795
  const chunk = content.split(/\r?\n/);
8727
8796
  let inSection = false;
8728
8797
  for (const line of chunk) {
@@ -8744,12 +8813,12 @@ function repoPath(projectRoot, key) {
8744
8813
  if (managed) {
8745
8814
  return managed.checkoutRoot;
8746
8815
  }
8747
- return key.startsWith("/") ? key : resolve30(projectRoot, key);
8816
+ return key.startsWith("/") ? key : resolve31(projectRoot, key);
8748
8817
  }
8749
8818
  function applyPins(projectRoot, pins) {
8750
8819
  for (const [key, commit] of Object.entries(pins)) {
8751
8820
  const path = repoPath(projectRoot, key);
8752
- if (!existsSync27(resolve30(path, ".git"))) {
8821
+ if (!existsSync28(resolve31(path, ".git"))) {
8753
8822
  throw new Error(`Repo for pin not available: ${key} (${path})`);
8754
8823
  }
8755
8824
  let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
@@ -8778,7 +8847,7 @@ function verifyPins(projectRoot, pins) {
8778
8847
  let ok = true;
8779
8848
  for (const [key, expected] of Object.entries(pins)) {
8780
8849
  const path = repoPath(projectRoot, key);
8781
- if (!existsSync27(resolve30(path, ".git"))) {
8850
+ if (!existsSync28(resolve31(path, ".git"))) {
8782
8851
  console.error(`ERROR: repo missing during pin verification: ${key}`);
8783
8852
  ok = false;
8784
8853
  continue;
@@ -8803,23 +8872,23 @@ function resolveRuntimeGitEnv() {
8803
8872
  GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
8804
8873
  };
8805
8874
  }
8806
- 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()));
8807
- 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() || "";
8808
8877
  if (!runtimeHome) {
8809
8878
  return;
8810
8879
  }
8811
- const knownHostsPath = resolve30(runtimeHome, ".ssh", "known_hosts");
8812
- if (!existsSync27(knownHostsPath)) {
8880
+ const knownHostsPath = resolve31(runtimeHome, ".ssh", "known_hosts");
8881
+ if (!existsSync28(knownHostsPath)) {
8813
8882
  return { HOME: runtimeHome };
8814
8883
  }
8815
- const agentSshKey = resolve30(runtimeHome, ".ssh", "rig-agent-key");
8884
+ const agentSshKey = resolve31(runtimeHome, ".ssh", "rig-agent-key");
8816
8885
  const sshParts = [
8817
8886
  "ssh",
8818
8887
  `-o UserKnownHostsFile="${knownHostsPath}"`,
8819
8888
  "-o StrictHostKeyChecking=yes",
8820
8889
  "-F /dev/null"
8821
8890
  ];
8822
- if (existsSync27(agentSshKey)) {
8891
+ if (existsSync28(agentSshKey)) {
8823
8892
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
8824
8893
  }
8825
8894
  return {
@@ -8829,24 +8898,24 @@ function resolveRuntimeGitEnv() {
8829
8898
  }
8830
8899
  function inferRuntimeRootFromWorkspace(cwd) {
8831
8900
  const contextPath = findRuntimeContextFile3(cwd);
8832
- if (!contextPath || !existsSync27(contextPath)) {
8901
+ if (!contextPath || !existsSync28(contextPath)) {
8833
8902
  return "";
8834
8903
  }
8835
8904
  try {
8836
8905
  loadRuntimeContext(contextPath);
8837
- return resolve30(contextPath, "..");
8906
+ return resolve31(contextPath, "..");
8838
8907
  } catch {
8839
8908
  return "";
8840
8909
  }
8841
8910
  }
8842
8911
  function findRuntimeContextFile3(startPath) {
8843
- let current = resolve30(startPath);
8912
+ let current = resolve31(startPath);
8844
8913
  while (true) {
8845
- const candidate = resolve30(current, "runtime-context.json");
8846
- if (existsSync27(candidate)) {
8914
+ const candidate = resolve31(current, "runtime-context.json");
8915
+ if (existsSync28(candidate)) {
8847
8916
  return candidate;
8848
8917
  }
8849
- const parent = resolve30(current, "..");
8918
+ const parent = resolve31(current, "..");
8850
8919
  if (parent === current) {
8851
8920
  return "";
8852
8921
  }
@@ -8900,7 +8969,7 @@ function getEventBus() {
8900
8969
  }
8901
8970
  function inferRuntimeContext() {
8902
8971
  for (const candidate of runtimeContextCandidates()) {
8903
- if (!candidate || !existsSync28(candidate)) {
8972
+ if (!candidate || !existsSync29(candidate)) {
8904
8973
  continue;
8905
8974
  }
8906
8975
  try {
@@ -8913,15 +8982,15 @@ function inferRuntimeContext() {
8913
8982
  function runtimeContextCandidates() {
8914
8983
  const cwd = process.cwd();
8915
8984
  const candidates = [
8916
- resolve31(cwd, "..", "runtime-context.json"),
8917
- resolve31(cwd, ".rig", "runtime-context.json")
8985
+ resolve32(cwd, "..", "runtime-context.json"),
8986
+ resolve32(cwd, ".rig", "runtime-context.json")
8918
8987
  ];
8919
8988
  const argv1 = process.argv[1]?.trim();
8920
8989
  if (argv1) {
8921
- candidates.push(resolve31(argv1, "..", "..", "runtime-context.json"));
8990
+ candidates.push(resolve32(argv1, "..", "..", "runtime-context.json"));
8922
8991
  }
8923
8992
  if (BAKED_BINARY_PATH) {
8924
- candidates.push(resolve31(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
8993
+ candidates.push(resolve32(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
8925
8994
  }
8926
8995
  return Array.from(new Set(candidates));
8927
8996
  }
@@ -8936,12 +9005,12 @@ var GITHUB_KNOWN_HOSTS = [
8936
9005
  "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
8937
9006
  ];
8938
9007
  function ensureRuntimeKnownHosts(runtimeHome) {
8939
- const sshDir = resolve31(runtimeHome, ".ssh");
8940
- const knownHostsPath = resolve31(sshDir, "known_hosts");
8941
- if (!existsSync28(sshDir)) {
8942
- 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 });
8943
9012
  }
8944
- const existing = existsSync28(knownHostsPath) ? readFileSync16(knownHostsPath, "utf-8") : "";
9013
+ const existing = existsSync29(knownHostsPath) ? readFileSync17(knownHostsPath, "utf-8") : "";
8945
9014
  const existingLines = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
8946
9015
  const missing = GITHUB_KNOWN_HOSTS.filter((line) => !existingLines.has(line));
8947
9016
  if (missing.length === 0) {
@@ -8951,11 +9020,11 @@ function ensureRuntimeKnownHosts(runtimeHome) {
8951
9020
  for (const line of missing) {
8952
9021
  existingLines.add(line);
8953
9022
  }
8954
- writeFileSync14(knownHostsPath, `${Array.from(existingLines).join(`
9023
+ writeFileSync15(knownHostsPath, `${Array.from(existingLines).join(`
8955
9024
  `)}
8956
9025
  `, { mode: 420 });
8957
9026
  } catch (err) {
8958
- 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";
8959
9028
  console.warn(`[rig-agent] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
8960
9029
  }
8961
9030
  return knownHostsPath;
@@ -8969,13 +9038,13 @@ function hydrateRuntimeProcessEnv(ctx) {
8969
9038
  return;
8970
9039
  }
8971
9040
  process.env.RIG_RUNTIME_CONTEXT_FILE = contextFile;
8972
- const runtimeRoot = dirname17(resolve31(contextFile));
8973
- const runtimeHome = resolve31(runtimeRoot, "home");
8974
- const runtimeTmp = resolve31(runtimeRoot, "tmp");
8975
- const runtimeCache = resolve31(runtimeRoot, "cache");
8976
- const runtimeBin = resolve31(runtimeRoot, "bin");
8977
- const runtimeWorkspaceBin = resolve31(ctx.workspaceDir, ".rig", "bin");
8978
- 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");
8979
9048
  if (ctx.hostProjectRoot) {
8980
9049
  process.env.PROJECT_RIG_ROOT = ctx.hostProjectRoot;
8981
9050
  }
@@ -8991,13 +9060,13 @@ function hydrateRuntimeProcessEnv(ctx) {
8991
9060
  for (const [key, value] of Object.entries(browserEnvFromContext(ctx.browser))) {
8992
9061
  process.env[key] = value;
8993
9062
  }
8994
- if (existsSync28(runtimeHome)) {
9063
+ if (existsSync29(runtimeHome)) {
8995
9064
  process.env.HOME = runtimeHome;
8996
9065
  }
8997
- if (existsSync28(runtimeTmp)) {
9066
+ if (existsSync29(runtimeTmp)) {
8998
9067
  process.env.TMPDIR = runtimeTmp;
8999
9068
  }
9000
- if (existsSync28(runtimeCache)) {
9069
+ if (existsSync29(runtimeCache)) {
9001
9070
  process.env.XDG_CACHE_HOME = runtimeCache;
9002
9071
  }
9003
9072
  const workspaceSecrets = loadDotEnvSecrets(ctx.workspaceDir, process.env);
@@ -9023,31 +9092,31 @@ function hydrateRuntimeProcessEnv(ctx) {
9023
9092
  const currentPath = process.env.PATH || "";
9024
9093
  const pathEntries = currentPath.split(":").filter(Boolean);
9025
9094
  for (const entry of [runtimeBin, runtimeWorkspaceBin, runtimeTools, "/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
9026
- if (existsSync28(entry) && !pathEntries.includes(entry)) {
9095
+ if (existsSync29(entry) && !pathEntries.includes(entry)) {
9027
9096
  pathEntries.unshift(entry);
9028
9097
  }
9029
9098
  }
9030
9099
  process.env.PATH = pathEntries.join(":");
9031
9100
  if (!process.env.RIG_GIT_BIN) {
9032
- const runtimeGit = resolve31(runtimeBin, "git");
9033
- 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";
9034
9103
  }
9035
9104
  const knownHosts = ensureRuntimeKnownHosts(runtimeHome);
9036
- const agentKey = resolve31(runtimeHome, ".ssh", "rig-agent-key");
9105
+ const agentKey = resolve32(runtimeHome, ".ssh", "rig-agent-key");
9037
9106
  const sshParts = [
9038
9107
  "ssh",
9039
9108
  `-o UserKnownHostsFile="${knownHosts}"`,
9040
9109
  "-o StrictHostKeyChecking=yes",
9041
9110
  "-F /dev/null"
9042
9111
  ];
9043
- if (existsSync28(agentKey)) {
9112
+ if (existsSync29(agentKey)) {
9044
9113
  sshParts.splice(1, 0, `-i "${agentKey}"`, "-o IdentitiesOnly=yes");
9045
9114
  }
9046
9115
  process.env.GIT_SSH_COMMAND = sshParts.join(" ");
9047
9116
  }
9048
9117
  function inferRuntimeContextFileFromWorkspace(workspaceDir) {
9049
- const candidate = resolve31(workspaceDir, "..", "runtime-context.json");
9050
- return existsSync28(candidate) ? candidate : "";
9118
+ const candidate = resolve32(workspaceDir, "..", "runtime-context.json");
9119
+ return existsSync29(candidate) ? candidate : "";
9051
9120
  }
9052
9121
  async function main() {
9053
9122
  const args = process.argv.slice(2);
@@ -9172,7 +9241,7 @@ async function runAgentCommand(args) {
9172
9241
  const fileIdx = rest.indexOf("--file");
9173
9242
  const inputFile = fileIdx !== -1 ? rest[fileIdx + 1] : undefined;
9174
9243
  if (inputFile) {
9175
- content = readFileSync16(resolve31(projectRoot, inputFile), "utf-8");
9244
+ content = readFileSync17(resolve32(projectRoot, inputFile), "utf-8");
9176
9245
  } else {
9177
9246
  const chunks = [];
9178
9247
  for await (const chunk of process.stdin) {
@@ -9475,8 +9544,8 @@ WORKFLOW:
9475
9544
  `);
9476
9545
  }
9477
9546
  async function runCompletionVerification(projectRoot) {
9478
- const hookPath = resolve31(projectRoot, ".rig/bin/hooks/completion-verification");
9479
- if (!existsSync28(hookPath)) {
9547
+ const hookPath = resolve32(projectRoot, ".rig/bin/hooks/completion-verification");
9548
+ if (!existsSync29(hookPath)) {
9480
9549
  console.error(`[rig-agent] completion-verification hook binary not found: ${hookPath}`);
9481
9550
  return 1;
9482
9551
  }
@@ -9510,7 +9579,7 @@ async function verifyRuntimeManifest() {
9510
9579
  if (!manifestPath) {
9511
9580
  return;
9512
9581
  }
9513
- if (!existsSync28(manifestPath)) {
9582
+ if (!existsSync29(manifestPath)) {
9514
9583
  throw new Error(`[rig-agent] Runtime manifest missing: ${manifestPath}`);
9515
9584
  }
9516
9585
  let manifest;
@@ -9527,10 +9596,10 @@ async function verifyRuntimeManifest() {
9527
9596
  if (!manifestBinaryPath || !expectedHash) {
9528
9597
  throw new Error(`[rig-agent] Runtime manifest is missing binary hash data (${manifestPath}).`);
9529
9598
  }
9530
- if (!existsSync28(manifestBinaryPath)) {
9599
+ if (!existsSync29(manifestBinaryPath)) {
9531
9600
  throw new Error(`[rig-agent] Runtime binary not found at ${manifestBinaryPath}.`);
9532
9601
  }
9533
- const actualHash = sha256Hex(readFileSync16(resolve31(manifestBinaryPath)));
9602
+ const actualHash = sha256Hex(readFileSync17(resolve32(manifestBinaryPath)));
9534
9603
  if (actualHash !== expectedHash) {
9535
9604
  throw new Error(`[rig-agent] Runtime manifest mismatch for binary hash.
9536
9605
  ` + `expected=${expectedHash}