@h-rig/runtime 0.0.6-alpha.33 → 0.0.6-alpha.35

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 (25) hide show
  1. package/dist/bin/rig-agent-dispatch.js +518 -459
  2. package/dist/bin/rig-agent.js +431 -362
  3. package/dist/src/control-plane/agent-wrapper.js +523 -464
  4. package/dist/src/control-plane/harness-main.js +529 -459
  5. package/dist/src/control-plane/hooks/completion-verification.js +353 -283
  6. package/dist/src/control-plane/hooks/inject-context.js +158 -99
  7. package/dist/src/control-plane/hooks/submodule-branch.js +538 -479
  8. package/dist/src/control-plane/hooks/task-runtime-start.js +538 -479
  9. package/dist/src/control-plane/materialize-task-config.js +68 -8
  10. package/dist/src/control-plane/native/git-ops.js +11 -1
  11. package/dist/src/control-plane/native/harness-cli.js +514 -444
  12. package/dist/src/control-plane/native/task-ops.js +392 -322
  13. package/dist/src/control-plane/native/validator.js +159 -100
  14. package/dist/src/control-plane/native/verifier.js +227 -166
  15. package/dist/src/control-plane/pi-sessiond/bin.js +62 -0
  16. package/dist/src/control-plane/pi-sessiond/server.js +62 -0
  17. package/dist/src/control-plane/pi-sessiond/session-service.js +62 -0
  18. package/dist/src/control-plane/pi-settings-materializer.js +52 -0
  19. package/dist/src/control-plane/plugin-host-context.js +59 -0
  20. package/dist/src/control-plane/runtime/index.js +469 -410
  21. package/dist/src/control-plane/runtime/isolation/index.js +493 -434
  22. package/dist/src/control-plane/runtime/isolation.js +493 -434
  23. package/dist/src/control-plane/runtime/queue.js +411 -352
  24. package/dist/src/control-plane/tasks/source-lifecycle.js +87 -28
  25. package/package.json +8 -8
@@ -2,8 +2,8 @@
2
2
  // @bun
3
3
 
4
4
  // packages/runtime/bin/rig-agent.ts
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";
5
+ import { existsSync as existsSync31, mkdirSync as mkdirSync18, readFileSync as readFileSync18, writeFileSync as writeFileSync16 } from "fs";
6
+ import { dirname as dirname18, resolve as resolve33 } 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 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";
3619
+ import { existsSync as existsSync25, lstatSync, mkdirSync as mkdirSync12, readFileSync as readFileSync15, writeFileSync as writeFileSync12 } from "fs";
3620
+ import { dirname as dirname15, isAbsolute as isAbsolute2, resolve as resolve28 } 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 existsSync22, mkdirSync as mkdirSync10, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "fs";
3625
- import { resolve as resolve26 } from "path";
3624
+ import { appendFileSync, existsSync as existsSync24, mkdirSync as mkdirSync11, readFileSync as readFileSync14, writeFileSync as writeFileSync11 } from "fs";
3625
+ import { resolve as resolve27 } from "path";
3626
3626
 
3627
3627
  // packages/runtime/src/control-plane/runtime/tooling/shell.ts
3628
3628
  import { tmpdir as tmpdir4 } from "os";
@@ -3688,6 +3688,8 @@ function runtimeGatewayToolNames() {
3688
3688
  return runtimeToolGatewayNames();
3689
3689
  }
3690
3690
  // packages/runtime/src/control-plane/plugin-host-context.ts
3691
+ import { existsSync as existsSync13 } from "fs";
3692
+ import { resolve as resolvePath } from "path";
3691
3693
  import { createPluginHost } from "@rig/core";
3692
3694
  import { loadConfig } from "@rig/core/load-config";
3693
3695
 
@@ -4026,6 +4028,55 @@ async function materializeSkills(projectRoot, entries) {
4026
4028
  return written;
4027
4029
  }
4028
4030
 
4031
+ // packages/runtime/src/control-plane/pi-settings-materializer.ts
4032
+ import { existsSync as existsSync12, mkdirSync as mkdirSync7, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
4033
+ import { dirname as dirname11, resolve as resolve15 } from "path";
4034
+ var SETTINGS_RELATIVE_PATH = ".pi/settings.json";
4035
+ var MANAGED_RECORD_RELATIVE_PATH = ".rig/state/pi-managed-packages.json";
4036
+ function readJson(path, fallback) {
4037
+ if (!existsSync12(path))
4038
+ return fallback;
4039
+ try {
4040
+ return JSON.parse(readFileSync9(path, "utf-8"));
4041
+ } catch {
4042
+ return fallback;
4043
+ }
4044
+ }
4045
+ function packageKey(entry) {
4046
+ if (typeof entry === "string")
4047
+ return entry;
4048
+ if (entry && typeof entry === "object" && typeof entry.source === "string") {
4049
+ return entry.source;
4050
+ }
4051
+ return JSON.stringify(entry);
4052
+ }
4053
+ function materializePiPackages(projectRoot, declaredPackages) {
4054
+ const settingsPath = resolve15(projectRoot, SETTINGS_RELATIVE_PATH);
4055
+ const managedRecordPath = resolve15(projectRoot, MANAGED_RECORD_RELATIVE_PATH);
4056
+ const settings = readJson(settingsPath, {});
4057
+ const previouslyManaged = new Set(readJson(managedRecordPath, []));
4058
+ const existing = Array.isArray(settings.packages) ? settings.packages : [];
4059
+ const operatorEntries = existing.filter((entry) => !previouslyManaged.has(packageKey(entry)));
4060
+ const operatorKeys = new Set(operatorEntries.map(packageKey));
4061
+ const managedToAdd = declaredPackages.filter((pkg) => !operatorKeys.has(pkg));
4062
+ const nextPackages = [...operatorEntries, ...managedToAdd];
4063
+ if (nextPackages.length > 0 || existsSync12(settingsPath)) {
4064
+ const nextSettings = { ...settings };
4065
+ if (nextPackages.length > 0) {
4066
+ nextSettings.packages = nextPackages;
4067
+ } else {
4068
+ delete nextSettings.packages;
4069
+ }
4070
+ mkdirSync7(dirname11(settingsPath), { recursive: true });
4071
+ writeFileSync6(settingsPath, `${JSON.stringify(nextSettings, null, 2)}
4072
+ `, "utf-8");
4073
+ }
4074
+ mkdirSync7(dirname11(managedRecordPath), { recursive: true });
4075
+ writeFileSync6(managedRecordPath, `${JSON.stringify(managedToAdd, null, 2)}
4076
+ `, "utf-8");
4077
+ return { settingsPath, packages: managedToAdd };
4078
+ }
4079
+
4029
4080
  // packages/runtime/src/control-plane/plugin-host-context.ts
4030
4081
  async function buildPluginHostContext(projectRoot) {
4031
4082
  let config;
@@ -4073,6 +4124,14 @@ async function buildPluginHostContext(projectRoot) {
4073
4124
  } catch (err) {
4074
4125
  console.warn(`[plugin-host] skill materialization failed: ${err instanceof Error ? err.message : err}`);
4075
4126
  }
4127
+ try {
4128
+ const piPackages = config.runtime?.pi?.packages ?? [];
4129
+ if (piPackages.length > 0 || existsSync13(resolvePath(projectRoot, ".rig/state/pi-managed-packages.json"))) {
4130
+ materializePiPackages(projectRoot, piPackages);
4131
+ }
4132
+ } catch (err) {
4133
+ console.warn(`[plugin-host] Pi package materialization failed: ${err instanceof Error ? err.message : err}`);
4134
+ }
4076
4135
  return {
4077
4136
  config,
4078
4137
  pluginHost,
@@ -4086,12 +4145,12 @@ async function buildPluginHostContext(projectRoot) {
4086
4145
 
4087
4146
  // packages/runtime/src/control-plane/tasks/source-aware-task-config-source.ts
4088
4147
  import { spawnSync } from "child_process";
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";
4148
+ import { existsSync as existsSync15, readFileSync as readFileSync11, readdirSync as readdirSync2, statSync as statSync3, writeFileSync as writeFileSync7 } from "fs";
4149
+ import { basename as basename4, join as join3, resolve as resolve17 } from "path";
4091
4150
 
4092
4151
  // packages/runtime/src/control-plane/tasks/legacy-task-config-source.ts
4093
- import { existsSync as existsSync12, readFileSync as readFileSync9 } from "fs";
4094
- import { resolve as resolve15 } from "path";
4152
+ import { existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
4153
+ import { resolve as resolve16 } from "path";
4095
4154
 
4096
4155
  // packages/runtime/src/control-plane/tasks/task-record-reader.ts
4097
4156
  async function findTaskById(reader, id) {
@@ -4114,7 +4173,7 @@ class LegacyTaskConfigReadError extends Error {
4114
4173
  }
4115
4174
  }
4116
4175
  function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
4117
- const configPath = options.configPath ?? resolve15(projectRoot, ".rig", "task-config.json");
4176
+ const configPath = options.configPath ?? resolve16(projectRoot, ".rig", "task-config.json");
4118
4177
  const reader = {
4119
4178
  async listTasks() {
4120
4179
  return readLegacyTaskRecords(projectRoot, configPath);
@@ -4125,8 +4184,8 @@ function createLegacyTaskConfigRecordReader(projectRoot, options = {}) {
4125
4184
  };
4126
4185
  return reader;
4127
4186
  }
4128
- function readLegacyTaskRecords(projectRoot, configPath = resolve15(projectRoot, ".rig", "task-config.json")) {
4129
- if (!existsSync12(configPath)) {
4187
+ function readLegacyTaskRecords(projectRoot, configPath = resolve16(projectRoot, ".rig", "task-config.json")) {
4188
+ if (!existsSync14(configPath)) {
4130
4189
  return [];
4131
4190
  }
4132
4191
  const rawConfig = readLegacyTaskConfigJson(projectRoot, configPath);
@@ -4134,7 +4193,7 @@ function readLegacyTaskRecords(projectRoot, configPath = resolve15(projectRoot,
4134
4193
  }
4135
4194
  function readLegacyTaskConfigJson(projectRoot, configPath) {
4136
4195
  try {
4137
- const parsed = JSON.parse(readFileSync9(configPath, "utf8"));
4196
+ const parsed = JSON.parse(readFileSync10(configPath, "utf8"));
4138
4197
  if (isPlainRecord(parsed)) {
4139
4198
  return parsed;
4140
4199
  }
@@ -4218,7 +4277,7 @@ function isPlainRecord(candidate) {
4218
4277
  var STATUS_LABELS = new Set(["ready", "blocked", "in-progress", "under-review", "failed", "cancelled"]);
4219
4278
  var FILE_TASK_PATTERN = /\.(task\.)?json$/;
4220
4279
  function createSourceAwareTaskConfigRecordReader(projectRoot, options = {}) {
4221
- const configPath = options.configPath ?? resolve16(projectRoot, ".rig", "task-config.json");
4280
+ const configPath = options.configPath ?? resolve17(projectRoot, ".rig", "task-config.json");
4222
4281
  const legacy = createLegacyTaskConfigRecordReader(projectRoot, { configPath });
4223
4282
  const spawnFn = options.spawn ?? spawnSync;
4224
4283
  const ghBinary = options.ghBinary ?? "gh";
@@ -4301,10 +4360,10 @@ function readMaterializedTaskMetadata(entry) {
4301
4360
  return metadata;
4302
4361
  }
4303
4362
  function readConfiguredFilesTaskSourcePath(projectRoot) {
4304
- const jsonPath = resolve16(projectRoot, "rig.config.json");
4305
- if (existsSync13(jsonPath)) {
4363
+ const jsonPath = resolve17(projectRoot, "rig.config.json");
4364
+ if (existsSync15(jsonPath)) {
4306
4365
  try {
4307
- const parsed = JSON.parse(readFileSync10(jsonPath, "utf8"));
4366
+ const parsed = JSON.parse(readFileSync11(jsonPath, "utf8"));
4308
4367
  if (isPlainRecord2(parsed) && isPlainRecord2(parsed.taskSource)) {
4309
4368
  const source = parsed.taskSource;
4310
4369
  return source.kind === "files" && typeof source.path === "string" ? source.path : null;
@@ -4313,12 +4372,12 @@ function readConfiguredFilesTaskSourcePath(projectRoot) {
4313
4372
  return null;
4314
4373
  }
4315
4374
  }
4316
- const tsPath = resolve16(projectRoot, "rig.config.ts");
4317
- if (!existsSync13(tsPath)) {
4375
+ const tsPath = resolve17(projectRoot, "rig.config.ts");
4376
+ if (!existsSync15(tsPath)) {
4318
4377
  return null;
4319
4378
  }
4320
4379
  try {
4321
- const source = readFileSync10(tsPath, "utf8");
4380
+ const source = readFileSync11(tsPath, "utf8");
4322
4381
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
4323
4382
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
4324
4383
  if (kind !== "files") {
@@ -4338,10 +4397,10 @@ function readRawTaskEntry(configPath, taskId) {
4338
4397
  return isPlainRecord2(entry) ? entry : null;
4339
4398
  }
4340
4399
  function readRawTaskConfig(configPath) {
4341
- if (!existsSync13(configPath)) {
4400
+ if (!existsSync15(configPath)) {
4342
4401
  return null;
4343
4402
  }
4344
- const parsed = JSON.parse(readFileSync10(configPath, "utf8"));
4403
+ const parsed = JSON.parse(readFileSync11(configPath, "utf8"));
4345
4404
  return isPlainRecord2(parsed) ? parsed : null;
4346
4405
  }
4347
4406
  function stripLegacyTaskConfigMetadata2(raw) {
@@ -4349,8 +4408,8 @@ function stripLegacyTaskConfigMetadata2(raw) {
4349
4408
  return tasks;
4350
4409
  }
4351
4410
  function listFileBackedTasks(projectRoot, sourcePath) {
4352
- const directory = resolve16(projectRoot, sourcePath);
4353
- if (!existsSync13(directory)) {
4411
+ const directory = resolve17(projectRoot, sourcePath);
4412
+ if (!existsSync15(directory)) {
4354
4413
  return [];
4355
4414
  }
4356
4415
  const tasks = [];
@@ -4365,11 +4424,11 @@ function listFileBackedTasks(projectRoot, sourcePath) {
4365
4424
  return tasks;
4366
4425
  }
4367
4426
  function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
4368
- const file = findFileBackedTaskFile(resolve16(projectRoot, sourcePath), taskId);
4427
+ const file = findFileBackedTaskFile(resolve17(projectRoot, sourcePath), taskId);
4369
4428
  if (!file) {
4370
4429
  return null;
4371
4430
  }
4372
- const raw = JSON.parse(readFileSync10(file, "utf8"));
4431
+ const raw = JSON.parse(readFileSync11(file, "utf8"));
4373
4432
  if (!isPlainRecord2(raw)) {
4374
4433
  return null;
4375
4434
  }
@@ -4382,7 +4441,7 @@ function readFileBackedTask(projectRoot, sourcePath, taskId, rawEntry) {
4382
4441
  };
4383
4442
  }
4384
4443
  function findFileBackedTaskFile(directory, taskId) {
4385
- if (!existsSync13(directory)) {
4444
+ if (!existsSync15(directory)) {
4386
4445
  return null;
4387
4446
  }
4388
4447
  for (const name of readdirSync2(directory)) {
@@ -4392,7 +4451,7 @@ function findFileBackedTaskFile(directory, taskId) {
4392
4451
  try {
4393
4452
  if (!statSync3(file).isFile())
4394
4453
  continue;
4395
- const raw = JSON.parse(readFileSync10(file, "utf8"));
4454
+ const raw = JSON.parse(readFileSync11(file, "utf8"));
4396
4455
  const inferredId = basename4(file).replace(FILE_TASK_PATTERN, "");
4397
4456
  const id = isPlainRecord2(raw) && typeof raw.id === "string" ? raw.id : inferredId;
4398
4457
  if (id === taskId) {
@@ -4552,8 +4611,8 @@ async function readConfiguredTaskSourceTask(projectRoot, taskId) {
4552
4611
  }
4553
4612
 
4554
4613
  // packages/runtime/src/control-plane/native/task-state.ts
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";
4614
+ import { existsSync as existsSync19, readFileSync as readFileSync13, readdirSync as readdirSync3, statSync as statSync4, writeFileSync as writeFileSync8 } from "fs";
4615
+ import { basename as basename6, resolve as resolve21 } from "path";
4557
4616
 
4558
4617
  // packages/runtime/src/control-plane/state-sync/types.ts
4559
4618
  var SUPPORTED_TASK_STATE_SCHEMA_VERSION = 1;
@@ -4661,38 +4720,38 @@ function readTaskStateMetadataEnvelope(raw) {
4661
4720
  };
4662
4721
  }
4663
4722
  // packages/runtime/src/control-plane/state-sync/read.ts
4664
- import { existsSync as existsSync16, readFileSync as readFileSync11 } from "fs";
4665
- import { resolve as resolve19 } from "path";
4723
+ import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
4724
+ import { resolve as resolve20 } from "path";
4666
4725
 
4667
4726
  // packages/runtime/src/control-plane/state-sync/repo.ts
4668
- import { existsSync as existsSync15 } from "fs";
4669
- import { resolve as resolve18 } from "path";
4727
+ import { existsSync as existsSync17 } from "fs";
4728
+ import { resolve as resolve19 } from "path";
4670
4729
 
4671
4730
  // packages/runtime/src/control-plane/repos/layout.ts
4672
- import { existsSync as existsSync14 } from "fs";
4673
- import { basename as basename5, dirname as dirname11, join as join4, resolve as resolve17 } from "path";
4731
+ import { existsSync as existsSync16 } from "fs";
4732
+ import { basename as basename5, dirname as dirname12, join as join4, resolve as resolve18 } from "path";
4674
4733
  function resolveRepoStateDir(projectRoot) {
4675
- const normalizedProjectRoot = resolve17(projectRoot);
4676
- const projectParent = dirname11(normalizedProjectRoot);
4734
+ const normalizedProjectRoot = resolve18(projectRoot);
4735
+ const projectParent = dirname12(normalizedProjectRoot);
4677
4736
  if (basename5(projectParent) === ".worktrees") {
4678
- const ownerRoot = dirname11(projectParent);
4679
- const ownerHasRepoMarkers = existsSync14(resolve17(ownerRoot, ".git")) || existsSync14(resolve17(ownerRoot, ".rig", "state"));
4737
+ const ownerRoot = dirname12(projectParent);
4738
+ const ownerHasRepoMarkers = existsSync16(resolve18(ownerRoot, ".git")) || existsSync16(resolve18(ownerRoot, ".rig", "state"));
4680
4739
  if (ownerHasRepoMarkers) {
4681
- return resolve17(ownerRoot, ".rig", "state");
4740
+ return resolve18(ownerRoot, ".rig", "state");
4682
4741
  }
4683
4742
  }
4684
- return resolve17(projectRoot, ".rig", "state");
4743
+ return resolve18(projectRoot, ".rig", "state");
4685
4744
  }
4686
4745
  function resolveManagedRepoLayout(projectRoot, repoId) {
4687
- const normalizedProjectRoot = resolve17(projectRoot);
4746
+ const normalizedProjectRoot = resolve18(projectRoot);
4688
4747
  const entry = getManagedRepoEntry(repoId);
4689
4748
  const stateDir = resolveRepoStateDir(normalizedProjectRoot);
4690
4749
  const metadataRelativePath = join4("repos", entry.id);
4691
- const metadataRoot = resolve17(stateDir, metadataRelativePath);
4750
+ const metadataRoot = resolve18(stateDir, metadataRelativePath);
4692
4751
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
4693
- const runsInsideTaskWorktree = runtimeWorkspace && resolve17(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname11(normalizedProjectRoot)) === ".worktrees";
4752
+ const runsInsideTaskWorktree = runtimeWorkspace && resolve18(runtimeWorkspace) === normalizedProjectRoot || basename5(dirname12(normalizedProjectRoot)) === ".worktrees";
4694
4753
  const isPrimaryManagedRepo = listManagedRepoEntries()[0]?.id === repoId;
4695
- const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve17(process.env[entry.checkoutEnvVar].trim()) : resolve17(normalizedProjectRoot, entry.alias);
4754
+ const checkoutRoot = isPrimaryManagedRepo && runsInsideTaskWorktree ? resolveMonorepoRoot(normalizedProjectRoot) : entry.checkoutEnvVar && process.env[entry.checkoutEnvVar]?.trim() ? resolve18(process.env[entry.checkoutEnvVar].trim()) : resolve18(normalizedProjectRoot, entry.alias);
4696
4755
  return {
4697
4756
  projectRoot: normalizedProjectRoot,
4698
4757
  repoId: entry.id,
@@ -4700,12 +4759,12 @@ function resolveManagedRepoLayout(projectRoot, repoId) {
4700
4759
  defaultBranch: entry.defaultBranch,
4701
4760
  remoteUrl: entry.remoteEnvVar && process.env[entry.remoteEnvVar]?.trim() ? process.env[entry.remoteEnvVar].trim() : entry.defaultRemoteUrl,
4702
4761
  checkoutRoot,
4703
- worktreesRoot: resolve17(checkoutRoot, ".worktrees"),
4762
+ worktreesRoot: resolve18(checkoutRoot, ".worktrees"),
4704
4763
  stateDir,
4705
4764
  metadataRoot,
4706
4765
  metadataRelativePath,
4707
- mirrorRoot: resolve17(metadataRoot, "mirror.git"),
4708
- mirrorStatePath: resolve17(metadataRoot, "mirror-state.json"),
4766
+ mirrorRoot: resolve18(metadataRoot, "mirror.git"),
4767
+ mirrorStatePath: resolve18(metadataRoot, "mirror-state.json"),
4709
4768
  mirrorStateRelativePath: join4(metadataRelativePath, "mirror-state.json")
4710
4769
  };
4711
4770
  }
@@ -4727,7 +4786,7 @@ function resolveTrackerRepoPath(projectRoot) {
4727
4786
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
4728
4787
  try {
4729
4788
  const layout = resolveMonorepoRepoLayout(projectRoot);
4730
- if (existsSync15(resolve18(layout.mirrorRoot, "HEAD"))) {
4789
+ if (existsSync17(resolve19(layout.mirrorRoot, "HEAD"))) {
4731
4790
  return layout.mirrorRoot;
4732
4791
  }
4733
4792
  } catch {}
@@ -4738,8 +4797,8 @@ function resolveTrackerRepoPath(projectRoot) {
4738
4797
  var DEFAULT_READ_DEPS2 = {
4739
4798
  fetchRef: nativeFetchRef,
4740
4799
  readBlobAtRef: nativeReadBlobAtRef,
4741
- exists: existsSync16,
4742
- readFile: (path) => readFileSync11(path, "utf8")
4800
+ exists: existsSync18,
4801
+ readFile: (path) => readFileSync12(path, "utf8")
4743
4802
  };
4744
4803
  function parseIssueStatus(rawStatus) {
4745
4804
  const normalized = normalizeTaskLifecycleStatus(rawStatus);
@@ -4820,12 +4879,12 @@ function shouldPreferLocalTrackerState(options) {
4820
4879
  if (runtimeContextPath) {
4821
4880
  return true;
4822
4881
  }
4823
- return existsSync16(resolve19(runtimeWorkspace, ".rig", "runtime-context.json"));
4882
+ return existsSync18(resolve20(runtimeWorkspace, ".rig", "runtime-context.json"));
4824
4883
  }
4825
4884
  function readLocalTrackerState(projectRoot, deps) {
4826
4885
  const monorepoRoot = resolveMonorepoRoot2(projectRoot);
4827
- const issuesPath = resolve19(monorepoRoot, ".beads", "issues.jsonl");
4828
- const taskStatePath = resolve19(monorepoRoot, ".beads", "task-state.json");
4886
+ const issuesPath = resolve20(monorepoRoot, ".beads", "issues.jsonl");
4887
+ const taskStatePath = resolve20(monorepoRoot, ".beads", "task-state.json");
4829
4888
  return projectSyncedTrackerSnapshot({
4830
4889
  source: "local",
4831
4890
  issuesBaseOid: null,
@@ -4887,7 +4946,7 @@ function readValidationDescriptions(projectRoot) {
4887
4946
  return readValidationDescriptionMap(raw);
4888
4947
  }
4889
4948
  function readSourceValidationDescriptions(projectRoot) {
4890
- const rootRaw = readJsonFile(resolve20(projectRoot, "rig", "task-config.json"), {});
4949
+ const rootRaw = readJsonFile(resolve21(projectRoot, "rig", "task-config.json"), {});
4891
4950
  const sourcePath = findSourceTaskConfigPath(projectRoot);
4892
4951
  const sourceRaw = sourcePath ? readJsonFile(sourcePath, {}) : {};
4893
4952
  const rootDescriptions = readValidationDescriptionMap(rootRaw);
@@ -4963,15 +5022,15 @@ function readValidationDescriptionsFromMeta(meta) {
4963
5022
  return meta.validation_descriptions;
4964
5023
  }
4965
5024
  function readLocalSourceTaskStateEnvelope(projectRoot) {
4966
- const taskStatePath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
5025
+ const taskStatePath = resolve21(resolveMonorepoRoot2(projectRoot), ".beads", "task-state.json");
4967
5026
  return readTaskStateMetadataEnvelope(readJsonFile(taskStatePath, {}));
4968
5027
  }
4969
5028
  function readLocalSourceTaskLifecycleStatus(projectRoot, taskId) {
4970
- const issuesPath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
4971
- if (!existsSync17(issuesPath)) {
5029
+ const issuesPath = resolve21(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
5030
+ if (!existsSync19(issuesPath)) {
4972
5031
  return null;
4973
5032
  }
4974
- for (const line of readFileSync12(issuesPath, "utf8").split(/\r?\n/)) {
5033
+ for (const line of readFileSync13(issuesPath, "utf8").split(/\r?\n/)) {
4975
5034
  const trimmed = line.trim();
4976
5035
  if (!trimmed) {
4977
5036
  continue;
@@ -5012,25 +5071,25 @@ function lookupTask(projectRoot, input) {
5012
5071
  function artifactDirForId(projectRoot, id) {
5013
5072
  const workspaceDir = process.env.RIG_TASK_WORKSPACE?.trim();
5014
5073
  if (workspaceDir) {
5015
- const worktreeArtifacts = resolve20(workspaceDir, "artifacts", id);
5016
- if (existsSync17(worktreeArtifacts) || existsSync17(resolve20(workspaceDir, "artifacts"))) {
5074
+ const worktreeArtifacts = resolve21(workspaceDir, "artifacts", id);
5075
+ if (existsSync19(worktreeArtifacts) || existsSync19(resolve21(workspaceDir, "artifacts"))) {
5017
5076
  return worktreeArtifacts;
5018
5077
  }
5019
5078
  }
5020
5079
  try {
5021
5080
  const paths = resolveHarnessPaths(projectRoot);
5022
- return resolve20(paths.artifactsDir, id);
5081
+ return resolve21(paths.artifactsDir, id);
5023
5082
  } catch {
5024
- return resolve20(resolveMonorepoRoot2(projectRoot), "artifacts", id);
5083
+ return resolve21(resolveMonorepoRoot2(projectRoot), "artifacts", id);
5025
5084
  }
5026
5085
  }
5027
5086
  function resolveTaskConfigPath(projectRoot) {
5028
5087
  const paths = resolveHarnessPaths(projectRoot);
5029
- if (existsSync17(paths.taskConfigPath)) {
5088
+ if (existsSync19(paths.taskConfigPath)) {
5030
5089
  return paths.taskConfigPath;
5031
5090
  }
5032
5091
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
5033
- if (existsSync17(candidate)) {
5092
+ if (existsSync19(candidate)) {
5034
5093
  return candidate;
5035
5094
  }
5036
5095
  }
@@ -5038,7 +5097,7 @@ function resolveTaskConfigPath(projectRoot) {
5038
5097
  }
5039
5098
  function findSourceTaskConfigPath(projectRoot) {
5040
5099
  for (const candidate of sourceTaskConfigCandidates(projectRoot)) {
5041
- if (existsSync17(candidate)) {
5100
+ if (existsSync19(candidate)) {
5042
5101
  return candidate;
5043
5102
  }
5044
5103
  }
@@ -5051,7 +5110,7 @@ function readAndSyncSourceTaskConfig(projectRoot) {
5051
5110
  const synced = synchronizeTaskConfigWithTracker(projectRoot, raw);
5052
5111
  if (sourcePath && synced.updated) {
5053
5112
  try {
5054
- writeFileSync7(sourcePath, `${JSON.stringify(synced.config, null, 2)}
5113
+ writeFileSync8(sourcePath, `${JSON.stringify(synced.config, null, 2)}
5055
5114
  `, "utf-8");
5056
5115
  } catch {}
5057
5116
  }
@@ -5103,12 +5162,12 @@ function shouldRefreshAutoSyncedTaskConfigEntry(entry) {
5103
5162
  return !candidate.role;
5104
5163
  }
5105
5164
  function readSourceIssueRecords(projectRoot) {
5106
- const issuesPath = resolve20(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
5107
- if (!existsSync17(issuesPath)) {
5165
+ const issuesPath = resolve21(resolveMonorepoRoot2(projectRoot), ".beads", "issues.jsonl");
5166
+ if (!existsSync19(issuesPath)) {
5108
5167
  return [];
5109
5168
  }
5110
5169
  const records = [];
5111
- for (const line of readFileSync12(issuesPath, "utf-8").split(/\r?\n/)) {
5170
+ for (const line of readFileSync13(issuesPath, "utf-8").split(/\r?\n/)) {
5112
5171
  const trimmed = line.trim();
5113
5172
  if (!trimmed) {
5114
5173
  continue;
@@ -5164,19 +5223,19 @@ function readConfiguredFileTaskConfig(projectRoot) {
5164
5223
  if (!sourcePath) {
5165
5224
  return {};
5166
5225
  }
5167
- const directory = resolve20(projectRoot, sourcePath);
5168
- if (!existsSync17(directory)) {
5226
+ const directory = resolve21(projectRoot, sourcePath);
5227
+ if (!existsSync19(directory)) {
5169
5228
  return {};
5170
5229
  }
5171
5230
  const config = {};
5172
5231
  for (const name of readdirSync3(directory)) {
5173
5232
  if (!FILE_TASK_PATTERN2.test(name))
5174
5233
  continue;
5175
- const file = resolve20(directory, name);
5234
+ const file = resolve21(directory, name);
5176
5235
  try {
5177
5236
  if (!statSync4(file).isFile())
5178
5237
  continue;
5179
- const raw = JSON.parse(readFileSync12(file, "utf8"));
5238
+ const raw = JSON.parse(readFileSync13(file, "utf8"));
5180
5239
  if (!raw || typeof raw !== "object" || Array.isArray(raw))
5181
5240
  continue;
5182
5241
  const record = raw;
@@ -5218,10 +5277,10 @@ function firstStringList2(...candidates) {
5218
5277
  return [];
5219
5278
  }
5220
5279
  function readConfiguredFilesTaskSourcePath2(projectRoot) {
5221
- const jsonPath = resolve20(projectRoot, "rig.config.json");
5222
- if (existsSync17(jsonPath)) {
5280
+ const jsonPath = resolve21(projectRoot, "rig.config.json");
5281
+ if (existsSync19(jsonPath)) {
5223
5282
  try {
5224
- const parsed = JSON.parse(readFileSync12(jsonPath, "utf8"));
5283
+ const parsed = JSON.parse(readFileSync13(jsonPath, "utf8"));
5225
5284
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
5226
5285
  const taskSource = parsed.taskSource;
5227
5286
  if (taskSource && typeof taskSource === "object" && !Array.isArray(taskSource)) {
@@ -5233,12 +5292,12 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
5233
5292
  return null;
5234
5293
  }
5235
5294
  }
5236
- const tsPath = resolve20(projectRoot, "rig.config.ts");
5237
- if (!existsSync17(tsPath)) {
5295
+ const tsPath = resolve21(projectRoot, "rig.config.ts");
5296
+ if (!existsSync19(tsPath)) {
5238
5297
  return null;
5239
5298
  }
5240
5299
  try {
5241
- const source = readFileSync12(tsPath, "utf8");
5300
+ const source = readFileSync13(tsPath, "utf8");
5242
5301
  const taskSourceBlock = source.match(/taskSource\s*:\s*\{[\s\S]*?\}/m)?.[0] ?? "";
5243
5302
  const kind = taskSourceBlock.match(/kind\s*:\s*["']([^"']+)["']/)?.[1];
5244
5303
  if (kind !== "files") {
@@ -5252,23 +5311,23 @@ function readConfiguredFilesTaskSourcePath2(projectRoot) {
5252
5311
  function sourceTaskConfigCandidates(projectRoot) {
5253
5312
  const runtimeContext = loadRuntimeContextFromEnv();
5254
5313
  return [
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")
5314
+ runtimeContext?.monorepoMainRoot ? resolve21(runtimeContext.monorepoMainRoot, ".rig", "task-config.json") : "",
5315
+ process.env.MONOREPO_MAIN_ROOT?.trim() ? resolve21(process.env.MONOREPO_MAIN_ROOT.trim(), ".rig", "task-config.json") : "",
5316
+ resolve21(resolveMonorepoRoot2(projectRoot), ".rig", "task-config.json")
5258
5317
  ].filter(Boolean);
5259
5318
  }
5260
5319
 
5261
5320
  // packages/runtime/src/control-plane/native/validator.ts
5262
- import { existsSync as existsSync21, mkdirSync as mkdirSync9, writeFileSync as writeFileSync9 } from "fs";
5263
- import { resolve as resolve25 } from "path";
5321
+ import { existsSync as existsSync23, mkdirSync as mkdirSync10, writeFileSync as writeFileSync10 } from "fs";
5322
+ import { resolve as resolve26 } from "path";
5264
5323
 
5265
5324
  // packages/runtime/src/control-plane/native/validator-binaries.ts
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";
5325
+ import { existsSync as existsSync22, mkdirSync as mkdirSync9, rmSync as rmSync6, statSync as statSync5 } from "fs";
5326
+ import { dirname as dirname14, resolve as resolve25 } from "path";
5268
5327
 
5269
5328
  // packages/runtime/src/binary-run.ts
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";
5329
+ import { chmodSync as chmodSync2, cpSync, existsSync as existsSync20, mkdirSync as mkdirSync8, renameSync as renameSync3, rmSync as rmSync5, writeFileSync as writeFileSync9 } from "fs";
5330
+ import { basename as basename7, dirname as dirname13, resolve as resolve22 } from "path";
5272
5331
  import { fileURLToPath } from "url";
5273
5332
  import { drainMicrotasks, gcAndSweep } from "bun:jsc";
5274
5333
  var runtimeBinaryBuildQueue = Promise.resolve();
@@ -5294,9 +5353,9 @@ async function buildRuntimeBinary(options) {
5294
5353
  });
5295
5354
  }
5296
5355
  async function buildRuntimeBinaryInProcess(options, manifest) {
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 });
5356
+ const tempBuildDir = resolve22(dirname13(options.outputPath), `.bun-build-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`);
5357
+ const tempOutputPath = resolve22(tempBuildDir, basename7(options.outputPath));
5358
+ mkdirSync8(tempBuildDir, { recursive: true });
5300
5359
  await withTemporaryEnv({
5301
5360
  ...options.env,
5302
5361
  ...options.define ? { RIG_BUILD_CONFIG_JSON: JSON.stringify(options.define) } : {}
@@ -5321,7 +5380,7 @@ async function buildRuntimeBinaryInProcess(options, manifest) {
5321
5380
  `);
5322
5381
  throw new Error(`Failed to build ${options.entrypoint}: ${details || "Bun.build() returned errors"}`);
5323
5382
  }
5324
- if (!existsSync18(tempOutputPath)) {
5383
+ if (!existsSync20(tempOutputPath)) {
5325
5384
  const emitted = buildResult.outputs.map((output) => output.path).join(", ") || "(none)";
5326
5385
  throw new Error(`Failed to build ${options.entrypoint}: Bun.build() did not emit ${tempOutputPath}. Emitted: ${emitted}`);
5327
5386
  }
@@ -5353,8 +5412,8 @@ function runtimeBinaryCacheManifestPath(outputPath) {
5353
5412
  function resolveRuntimeBinaryBuildOptions(options) {
5354
5413
  return {
5355
5414
  ...options,
5356
- entrypoint: resolve21(options.cwd, options.sourcePath),
5357
- outputPath: resolve21(options.outputPath)
5415
+ entrypoint: resolve22(options.cwd, options.sourcePath),
5416
+ outputPath: resolve22(options.outputPath)
5358
5417
  };
5359
5418
  }
5360
5419
  function shouldUseRuntimeBinaryBuildWorker() {
@@ -5368,7 +5427,7 @@ function shouldUseRuntimeBinaryBuildWorker() {
5368
5427
  }
5369
5428
  async function buildRuntimeBinaryViaWorker(options) {
5370
5429
  const workerSourcePath = resolveRuntimeBinaryBuildWorkerSourcePath(options);
5371
- if (!workerSourcePath || !existsSync18(workerSourcePath)) {
5430
+ if (!workerSourcePath || !existsSync20(workerSourcePath)) {
5372
5431
  await buildRuntimeBinaryInProcess(options, {
5373
5432
  manifestPath: runtimeBinaryCacheManifestPath(options.outputPath),
5374
5433
  buildKey: createRuntimeBinaryBuildKey({
@@ -5405,7 +5464,7 @@ async function buildRuntimeBinaryViaWorker(options) {
5405
5464
  }
5406
5465
  }
5407
5466
  function createRuntimeBinaryBuildWorkerPayloadPath(outputPath) {
5408
- return resolve21(dirname12(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
5467
+ return resolve22(dirname13(outputPath), `.bun-build-worker-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);
5409
5468
  }
5410
5469
  function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
5411
5470
  const envRoots = [
@@ -5414,13 +5473,13 @@ function resolveRuntimeBinaryBuildWorkerSourcePath(options) {
5414
5473
  process.env.PROJECT_RIG_ROOT?.trim()
5415
5474
  ].filter(Boolean);
5416
5475
  for (const root of envRoots) {
5417
- const candidate = resolve21(root, "packages/runtime/src/binary-build-worker.ts");
5418
- if (existsSync18(candidate)) {
5476
+ const candidate = resolve22(root, "packages/runtime/src/binary-build-worker.ts");
5477
+ if (existsSync20(candidate)) {
5419
5478
  return candidate;
5420
5479
  }
5421
5480
  }
5422
- const localCandidate = resolve21(import.meta.dir, "binary-build-worker.ts");
5423
- return existsSync18(localCandidate) ? localCandidate : null;
5481
+ const localCandidate = resolve22(import.meta.dir, "binary-build-worker.ts");
5482
+ return existsSync20(localCandidate) ? localCandidate : null;
5424
5483
  }
5425
5484
  function resolveRuntimeBinaryBuildWorkerInvocation() {
5426
5485
  const bunPath = Bun.which("bun");
@@ -5456,7 +5515,7 @@ function createRuntimeBinaryBuildKey(input) {
5456
5515
  });
5457
5516
  }
5458
5517
  async function isRuntimeBinaryBuildFresh(input) {
5459
- if (!existsSync18(input.outputPath) || !existsSync18(input.manifestPath)) {
5518
+ if (!existsSync20(input.outputPath) || !existsSync20(input.manifestPath)) {
5460
5519
  return false;
5461
5520
  }
5462
5521
  let manifest = null;
@@ -5469,7 +5528,7 @@ async function isRuntimeBinaryBuildFresh(input) {
5469
5528
  return false;
5470
5529
  }
5471
5530
  for (const [filePath, expectedDigest] of Object.entries(manifest.inputs || {})) {
5472
- if (!existsSync18(filePath)) {
5531
+ if (!existsSync20(filePath)) {
5473
5532
  return false;
5474
5533
  }
5475
5534
  if (await sha256File(filePath) !== expectedDigest) {
@@ -5482,7 +5541,7 @@ async function writeRuntimeBinaryCacheManifest(input) {
5482
5541
  const inputs = {};
5483
5542
  for (const inputPath of Object.keys(input.metafile?.inputs || {}).sort()) {
5484
5543
  const normalized = normalizeBuildInputPath(input.cwd, inputPath);
5485
- if (!normalized || !existsSync18(normalized)) {
5544
+ if (!normalized || !existsSync20(normalized)) {
5486
5545
  continue;
5487
5546
  }
5488
5547
  inputs[normalized] = await sha256File(normalized);
@@ -5505,7 +5564,7 @@ function normalizeBuildInputPath(cwd, inputPath) {
5505
5564
  if (inputPath.startsWith("<")) {
5506
5565
  return null;
5507
5566
  }
5508
- return resolve21(cwd, inputPath);
5567
+ return resolve22(cwd, inputPath);
5509
5568
  }
5510
5569
  async function sha256File(path) {
5511
5570
  const hasher = new Bun.CryptoHasher("sha256");
@@ -5521,8 +5580,8 @@ function sortRecord(value) {
5521
5580
  async function runSerializedRuntimeBinaryBuild(action) {
5522
5581
  const previous = runtimeBinaryBuildQueue;
5523
5582
  let release;
5524
- runtimeBinaryBuildQueue = new Promise((resolve22) => {
5525
- release = resolve22;
5583
+ runtimeBinaryBuildQueue = new Promise((resolve23) => {
5584
+ release = resolve23;
5526
5585
  });
5527
5586
  await previous;
5528
5587
  try {
@@ -5567,11 +5626,11 @@ async function withTemporaryCwd(cwd, action) {
5567
5626
  }
5568
5627
 
5569
5628
  // packages/runtime/src/control-plane/runtime/provisioning-env.ts
5570
- import { delimiter, resolve as resolve23 } from "path";
5629
+ import { delimiter, resolve as resolve24 } from "path";
5571
5630
 
5572
5631
  // packages/runtime/src/control-plane/runtime/runtime-paths.ts
5573
- import { existsSync as existsSync19, readdirSync as readdirSync4, realpathSync } from "fs";
5574
- import { resolve as resolve22 } from "path";
5632
+ import { existsSync as existsSync21, readdirSync as readdirSync4, realpathSync } from "fs";
5633
+ import { resolve as resolve23 } from "path";
5575
5634
 
5576
5635
  // packages/runtime/src/control-plane/runtime/sandbox/utils.ts
5577
5636
  function uniq(values) {
@@ -5589,7 +5648,7 @@ function resolveBunBinaryPath() {
5589
5648
  }
5590
5649
  const home = process.env.HOME?.trim();
5591
5650
  const fallbackCandidates = [
5592
- home ? resolve22(home, ".bun/bin/bun") : "",
5651
+ home ? resolve23(home, ".bun/bin/bun") : "",
5593
5652
  "/opt/homebrew/bin/bun",
5594
5653
  "/usr/local/bin/bun",
5595
5654
  "/usr/bin/bun"
@@ -5617,8 +5676,8 @@ function resolveClaudeBinaryPath() {
5617
5676
  }
5618
5677
  const home = process.env.HOME?.trim();
5619
5678
  const fallbackCandidates = [
5620
- home ? resolve22(home, ".local/bin/claude") : "",
5621
- home ? resolve22(home, ".local/share/claude/local/claude") : "",
5679
+ home ? resolve23(home, ".local/bin/claude") : "",
5680
+ home ? resolve23(home, ".local/share/claude/local/claude") : "",
5622
5681
  "/opt/homebrew/bin/claude",
5623
5682
  "/usr/local/bin/claude",
5624
5683
  "/usr/bin/claude"
@@ -5632,51 +5691,51 @@ function resolveClaudeBinaryPath() {
5632
5691
  throw new Error("claude not found in PATH");
5633
5692
  }
5634
5693
  function resolveBunInstallDir(bunBinaryPath = resolveBunBinaryPath()) {
5635
- return resolve22(bunBinaryPath, "../..");
5694
+ return resolve23(bunBinaryPath, "../..");
5636
5695
  }
5637
5696
  function resolveClaudeInstallDir() {
5638
5697
  const realPath = resolveClaudeBinaryPath();
5639
- return resolve22(realPath, "..");
5698
+ return resolve23(realPath, "..");
5640
5699
  }
5641
5700
  function resolveNodeInstallDir() {
5642
5701
  const preferredNode = resolvePreferredNodeBinary();
5643
5702
  if (!preferredNode)
5644
5703
  return null;
5645
5704
  const explicitNode = process.env.RIG_NODE_BIN?.trim();
5646
- if (explicitNode && resolve22(explicitNode) === resolve22(preferredNode)) {
5647
- return preferredNode.endsWith("/bin/node") ? resolve22(preferredNode, "../..") : resolve22(preferredNode, "..");
5705
+ if (explicitNode && resolve23(explicitNode) === resolve23(preferredNode)) {
5706
+ return preferredNode.endsWith("/bin/node") ? resolve23(preferredNode, "../..") : resolve23(preferredNode, "..");
5648
5707
  }
5649
5708
  try {
5650
5709
  const realPath = realpathSync(preferredNode);
5651
5710
  if (realPath.endsWith("/bin/node")) {
5652
- return resolve22(realPath, "../..");
5711
+ return resolve23(realPath, "../..");
5653
5712
  }
5654
- return resolve22(realPath, "..");
5713
+ return resolve23(realPath, "..");
5655
5714
  } catch {
5656
- return resolve22(preferredNode, "..");
5715
+ return resolve23(preferredNode, "..");
5657
5716
  }
5658
5717
  }
5659
5718
  function resolvePreferredNodeBinary() {
5660
5719
  const candidates = [];
5661
5720
  const envNode = process.env.RIG_NODE_BIN?.trim();
5662
5721
  if (envNode) {
5663
- const explicit = resolve22(envNode);
5664
- if (existsSync19(explicit)) {
5722
+ const explicit = resolve23(envNode);
5723
+ if (existsSync21(explicit)) {
5665
5724
  return explicit;
5666
5725
  }
5667
5726
  }
5668
5727
  const nvmBin = process.env.NVM_BIN?.trim();
5669
5728
  if (nvmBin) {
5670
- candidates.push(resolve22(nvmBin, "node"));
5729
+ candidates.push(resolve23(nvmBin, "node"));
5671
5730
  }
5672
5731
  const home = process.env.HOME?.trim();
5673
5732
  if (home) {
5674
- const nvmVersionsDir = resolve22(home, ".nvm/versions/node");
5675
- if (existsSync19(nvmVersionsDir)) {
5733
+ const nvmVersionsDir = resolve23(home, ".nvm/versions/node");
5734
+ if (existsSync21(nvmVersionsDir)) {
5676
5735
  try {
5677
5736
  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/, "")));
5678
5737
  for (const versionDir of versionDirs) {
5679
- candidates.push(resolve22(nvmVersionsDir, versionDir, "bin/node"));
5738
+ candidates.push(resolve23(nvmVersionsDir, versionDir, "bin/node"));
5680
5739
  }
5681
5740
  } catch {}
5682
5741
  }
@@ -5685,8 +5744,8 @@ function resolvePreferredNodeBinary() {
5685
5744
  if (whichNode) {
5686
5745
  candidates.push(whichNode);
5687
5746
  }
5688
- const deduped = uniq(candidates.map((candidate) => resolve22(candidate)));
5689
- const existing = deduped.filter((candidate) => existsSync19(candidate));
5747
+ const deduped = uniq(candidates.map((candidate) => resolve23(candidate)));
5748
+ const existing = deduped.filter((candidate) => existsSync21(candidate));
5690
5749
  if (existing.length === 0) {
5691
5750
  return null;
5692
5751
  }
@@ -5700,7 +5759,7 @@ function resolvePreferredNodeBinary() {
5700
5759
  return existing[0] ?? null;
5701
5760
  }
5702
5761
  function inferNodeMajor(nodeBinaryPath) {
5703
- const normalized = resolve22(nodeBinaryPath).replace(/\\/g, "/");
5762
+ const normalized = resolve23(nodeBinaryPath).replace(/\\/g, "/");
5704
5763
  const match = normalized.match(/(?:^|\/)(?:node-)?v?(\d+)\.\d+\.\d+(?:\/|$)/);
5705
5764
  if (!match) {
5706
5765
  return null;
@@ -5712,8 +5771,8 @@ function normalizeExecutablePath(candidate) {
5712
5771
  if (!candidate) {
5713
5772
  return "";
5714
5773
  }
5715
- const normalized = resolve22(candidate);
5716
- if (!existsSync19(normalized)) {
5774
+ const normalized = resolve23(candidate);
5775
+ if (!existsSync21(normalized)) {
5717
5776
  return "";
5718
5777
  }
5719
5778
  try {
@@ -5723,7 +5782,7 @@ function normalizeExecutablePath(candidate) {
5723
5782
  }
5724
5783
  }
5725
5784
  function looksLikeRuntimeGateway(candidate) {
5726
- const normalized = resolve22(candidate).replace(/\\/g, "/");
5785
+ const normalized = resolve23(candidate).replace(/\\/g, "/");
5727
5786
  return normalized.includes("/.rig/bin/") || normalized.endsWith("/rig-shell") || normalized.endsWith("/rig-agent");
5728
5787
  }
5729
5788
 
@@ -5744,7 +5803,7 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
5744
5803
  try {
5745
5804
  return resolveClaudeInstallDir();
5746
5805
  } catch {
5747
- return resolve23(claudeBinary, "..");
5806
+ return resolve24(claudeBinary, "..");
5748
5807
  }
5749
5808
  })() : "";
5750
5809
  const nodeDir = resolveNodeInstallDir();
@@ -5754,8 +5813,8 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
5754
5813
  `${bunDir}/bin`,
5755
5814
  claudeDir,
5756
5815
  nodeDir ? `${nodeDir}/bin` : "",
5757
- realHome ? resolve23(realHome, ".local/bin") : "",
5758
- realHome ? resolve23(realHome, ".cargo/bin") : "",
5816
+ realHome ? resolve24(realHome, ".local/bin") : "",
5817
+ realHome ? resolve24(realHome, ".cargo/bin") : "",
5759
5818
  ...inheritedPath,
5760
5819
  "/usr/local/bin",
5761
5820
  "/usr/local/sbin",
@@ -5786,9 +5845,9 @@ function runtimeProvisioningEnv(baseEnv = process.env) {
5786
5845
  // packages/runtime/src/control-plane/native/validator-binaries.ts
5787
5846
  function resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext) {
5788
5847
  if (runtimeContext) {
5789
- return resolve24(runtimeContext.binDir, "validators", binaryName);
5848
+ return resolve25(runtimeContext.binDir, "validators", binaryName);
5790
5849
  }
5791
- return resolve24(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
5850
+ return resolve25(resolveHarnessPaths(projectRoot).binDir, "validators", binaryName);
5792
5851
  }
5793
5852
  async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
5794
5853
  const match = checkId.match(/^([a-z][\w-]*):([a-z][\w-]*)$/);
@@ -5803,19 +5862,19 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
5803
5862
  const binaryName = `${category}-${check}`;
5804
5863
  const binaryPath = resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
5805
5864
  const hostProjectRoot = runtimeContext?.hostProjectRoot?.trim() || projectRoot;
5806
- const sourcePath = resolve24(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
5807
- if (!existsSync20(sourcePath)) {
5865
+ const sourcePath = resolve25(hostProjectRoot, "packages/runtime/src/control-plane/validators", category, `${check}.ts`);
5866
+ if (!existsSync22(sourcePath)) {
5808
5867
  return null;
5809
5868
  }
5810
5869
  const sourceMtime = statSync5(sourcePath).mtimeMs;
5811
- const binaryExists = existsSync20(binaryPath);
5870
+ const binaryExists = existsSync22(binaryPath);
5812
5871
  const binaryMtime = binaryExists ? statSync5(binaryPath).mtimeMs : 0;
5813
5872
  if (!binaryExists || sourceMtime > binaryMtime) {
5814
5873
  if (binaryExists) {
5815
5874
  rmSync6(binaryPath, { force: true });
5816
5875
  rmSync6(`${binaryPath}.build-manifest.json`, { force: true });
5817
5876
  }
5818
- mkdirSync8(dirname13(binaryPath), { recursive: true });
5877
+ mkdirSync9(dirname14(binaryPath), { recursive: true });
5819
5878
  await buildRuntimeBinary({
5820
5879
  sourcePath: `packages/runtime/src/control-plane/validators/${category}/${check}.ts`,
5821
5880
  outputPath: binaryPath,
@@ -5824,7 +5883,7 @@ async function ensureValidatorBinary(projectRoot, checkId, runtimeContext) {
5824
5883
  env: runtimeProvisioningEnv()
5825
5884
  });
5826
5885
  }
5827
- return existsSync20(binaryPath) ? binaryPath : null;
5886
+ return existsSync22(binaryPath) ? binaryPath : null;
5828
5887
  }
5829
5888
 
5830
5889
  // packages/runtime/src/control-plane/native/validator.ts
@@ -5861,20 +5920,20 @@ async function readTaskSourceValidation(projectRoot, taskId) {
5861
5920
  function resolveValidationPaths(projectRoot, taskId, runtimeContext) {
5862
5921
  if (runtimeContext) {
5863
5922
  return {
5864
- taskLogDir: resolve25(runtimeContext.logsDir, taskId),
5865
- artifactDir: resolve25(runtimeContext.workspaceDir, "artifacts", taskId)
5923
+ taskLogDir: resolve26(runtimeContext.logsDir, taskId),
5924
+ artifactDir: resolve26(runtimeContext.workspaceDir, "artifacts", taskId)
5866
5925
  };
5867
5926
  }
5868
5927
  const paths = resolveHarnessPaths(projectRoot);
5869
5928
  return {
5870
- taskLogDir: resolve25(paths.logsDir, taskId),
5871
- artifactDir: resolve25(paths.artifactsDir, taskId)
5929
+ taskLogDir: resolve26(paths.logsDir, taskId),
5930
+ artifactDir: resolve26(paths.artifactsDir, taskId)
5872
5931
  };
5873
5932
  }
5874
5933
  async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext) {
5875
5934
  const binaryName = checkId.replace(":", "-");
5876
5935
  const binaryPath = await ensureValidatorBinary(projectRoot, checkId, runtimeContext) ?? resolveValidatorBinaryPath(projectRoot, binaryName, runtimeContext);
5877
- if (!existsSync21(binaryPath)) {
5936
+ if (!existsSync23(binaryPath)) {
5878
5937
  return {
5879
5938
  result: {
5880
5939
  id: checkId,
@@ -5885,7 +5944,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
5885
5944
  };
5886
5945
  }
5887
5946
  const validatorCwd = runtimeContext?.workspaceDir || resolveMonorepoRoot(projectRoot);
5888
- const runtimeShellPath = runtimeContext ? resolve25(runtimeContext.binDir, "rig-shell") : "";
5947
+ const runtimeShellPath = runtimeContext ? resolve26(runtimeContext.binDir, "rig-shell") : "";
5889
5948
  const monorepoMainRoot = runtimeContext?.monorepoMainRoot || process.env.MONOREPO_MAIN_ROOT?.trim() || resolveMonorepoRoot(projectRoot);
5890
5949
  const validatorEnv = {
5891
5950
  PROJECT_RIG_ROOT: runtimeContext?.hostProjectRoot || projectRoot,
@@ -5900,7 +5959,7 @@ async function runValidatorBinary(projectRoot, taskId, checkId, runtimeContext)
5900
5959
  validatorEnv.RIG_LOGS_DIR = runtimeContext.logsDir;
5901
5960
  validatorEnv.RIG_RUNTIME_BIN_DIR = runtimeContext.binDir;
5902
5961
  }
5903
- const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync21(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
5962
+ const { exitCode, stdout, stderr } = await runCaptureAsync(runtimeShellPath && existsSync23(runtimeShellPath) ? [runtimeShellPath, "run-binary", binaryPath] : [binaryPath], validatorCwd, validatorEnv);
5904
5963
  try {
5905
5964
  const result = JSON.parse(stdout.trim());
5906
5965
  return { result, exitCode };
@@ -5940,8 +5999,8 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
5940
5999
  const configuredValidation = stringArray(taskConfig[taskId]?.validation);
5941
6000
  const commands = resolvedContext?.validation?.length ? resolvedContext.validation : configuredValidation.length > 0 ? configuredValidation : sourceValidation.validation;
5942
6001
  const { taskLogDir, artifactDir } = resolveValidationPaths(projectRoot, taskId, resolvedContext);
5943
- mkdirSync9(taskLogDir, { recursive: true });
5944
- mkdirSync9(artifactDir, { recursive: true });
6002
+ mkdirSync10(taskLogDir, { recursive: true });
6003
+ mkdirSync10(artifactDir, { recursive: true });
5945
6004
  if (commands.length === 0) {
5946
6005
  const skipped = {
5947
6006
  status: "skipped",
@@ -5950,7 +6009,7 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
5950
6009
  failed: 0,
5951
6010
  categories: []
5952
6011
  };
5953
- writeFileSync9(resolve25(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
6012
+ writeFileSync10(resolve26(artifactDir, "validation-summary.json"), `${JSON.stringify(skipped, null, 2)}
5954
6013
  `, "utf-8");
5955
6014
  return skipped;
5956
6015
  }
@@ -5985,18 +6044,18 @@ async function validateTask(projectRoot, taskId, runtimeContext, registry, optio
5985
6044
  exit_code: 2,
5986
6045
  duration_seconds: 0
5987
6046
  });
5988
- const logFile2 = resolve25(taskLogDir, `invalid-entry-validation.log`);
5989
- mkdirSync9(taskLogDir, { recursive: true });
5990
- writeFileSync9(logFile2, `=== ${nowIso()} :: ${cmd} ===
6047
+ const logFile2 = resolve26(taskLogDir, `invalid-entry-validation.log`);
6048
+ mkdirSync10(taskLogDir, { recursive: true });
6049
+ writeFileSync10(logFile2, `=== ${nowIso()} :: ${cmd} ===
5991
6050
  Invalid validation entry: not a check-ID. All entries must use format "category:check-name".
5992
6051
  `, "utf-8");
5993
6052
  continue;
5994
6053
  }
5995
6054
  const { result, exitCode } = await dispatchValidator(cmd, effectiveRegistry, validatorCtx, (id) => runValidatorBinary(projectRoot, taskId, id, resolvedContext));
5996
6055
  const durationSeconds = Math.max(0, Math.round((Date.now() - startedAt) / 1000));
5997
- const logFile = resolve25(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
5998
- mkdirSync9(taskLogDir, { recursive: true });
5999
- writeFileSync9(logFile, `=== ${nowIso()} :: ${cmd} ===
6056
+ const logFile = resolve26(taskLogDir, `${cmd.replace(":", "-")}-validation.log`);
6057
+ mkdirSync10(taskLogDir, { recursive: true });
6058
+ writeFileSync10(logFile, `=== ${nowIso()} :: ${cmd} ===
6000
6059
  ${JSON.stringify(result, null, 2)}
6001
6060
  `, "utf-8");
6002
6061
  if (result.passed) {
@@ -6018,8 +6077,8 @@ ${JSON.stringify(result, null, 2)}
6018
6077
  failed,
6019
6078
  categories
6020
6079
  };
6021
- mkdirSync9(artifactDir, { recursive: true });
6022
- writeFileSync9(resolve25(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
6080
+ mkdirSync10(artifactDir, { recursive: true });
6081
+ writeFileSync10(resolve26(artifactDir, "validation-summary.json"), `${JSON.stringify(summary, null, 2)}
6023
6082
  `, "utf-8");
6024
6083
  return summary;
6025
6084
  }
@@ -6366,16 +6425,16 @@ async function taskDeps(projectRoot, taskId) {
6366
6425
  for (const dep of deps) {
6367
6426
  const artifactDir = artifactDirForId(projectRoot, dep);
6368
6427
  console.log(`=== ${dep} ===`);
6369
- if (!existsSync22(artifactDir)) {
6428
+ if (!existsSync24(artifactDir)) {
6370
6429
  console.log(` (no artifacts yet)
6371
6430
  `);
6372
6431
  continue;
6373
6432
  }
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);
6433
+ printArtifactSection(resolve27(artifactDir, "decision-log.md"), "--- Decisions ---");
6434
+ printArtifactSection(resolve27(artifactDir, "next-actions.md"), "--- Next Actions (for you) ---");
6435
+ const changedFiles = resolve27(artifactDir, "changed-files.txt");
6436
+ if (existsSync24(changedFiles)) {
6437
+ const lines = readFileSync14(changedFiles, "utf-8").split(/\r?\n/).filter(Boolean);
6379
6438
  console.log(`--- Changed Files (${lines.length}) ---`);
6380
6439
  for (const line of lines) {
6381
6440
  console.log(line);
@@ -6420,12 +6479,12 @@ function taskRecord(projectRoot, type, text, taskId) {
6420
6479
  throw new Error("No active task.");
6421
6480
  }
6422
6481
  const paths = resolveHarnessPaths(projectRoot);
6423
- mkdirSync10(paths.stateDir, { recursive: true });
6482
+ mkdirSync11(paths.stateDir, { recursive: true });
6424
6483
  if (type === "decision") {
6425
- const artifactDir = resolve26(paths.artifactsDir, activeTask);
6426
- mkdirSync10(artifactDir, { recursive: true });
6484
+ const artifactDir = resolve27(paths.artifactsDir, activeTask);
6485
+ mkdirSync11(artifactDir, { recursive: true });
6427
6486
  const timestamp = nowIso();
6428
- appendFileSync(resolve26(artifactDir, "decision-log.md"), `
6487
+ appendFileSync(resolve27(artifactDir, "decision-log.md"), `
6429
6488
  ### ${timestamp}
6430
6489
 
6431
6490
  ${text}
@@ -6435,14 +6494,14 @@ ${text}
6435
6494
  return;
6436
6495
  }
6437
6496
  const failedPath = paths.failedApproachesPath;
6438
- if (!existsSync22(failedPath)) {
6439
- writeFileSync10(failedPath, `# Failed Approaches Log
6497
+ if (!existsSync24(failedPath)) {
6498
+ writeFileSync11(failedPath, `# Failed Approaches Log
6440
6499
 
6441
6500
  This file records approaches that did not work.
6442
6501
 
6443
6502
  `, "utf-8");
6444
6503
  }
6445
- const content = readFileSync13(failedPath, "utf-8");
6504
+ const content = readFileSync14(failedPath, "utf-8");
6446
6505
  const attempts = (content.match(new RegExp(`^## ${escapeRegExp(activeTask)}\\b`, "gm")) || []).length + 1;
6447
6506
  appendFileSync(failedPath, `
6448
6507
  ## ${activeTask} - Attempt ${attempts} (${nowIso()})
@@ -6459,40 +6518,40 @@ function taskArtifacts(projectRoot, taskId) {
6459
6518
  throw new Error("No active task.");
6460
6519
  }
6461
6520
  const paths = resolveHarnessPaths(projectRoot);
6462
- const artifactDir = resolve26(paths.artifactsDir, activeTask);
6463
- mkdirSync10(artifactDir, { recursive: true });
6521
+ const artifactDir = resolve27(paths.artifactsDir, activeTask);
6522
+ mkdirSync11(artifactDir, { recursive: true });
6464
6523
  const changed = changedFilesForTask(projectRoot, activeTask, true);
6465
- writeFileSync10(resolve26(artifactDir, "changed-files.txt"), `${changed.join(`
6524
+ writeFileSync11(resolve27(artifactDir, "changed-files.txt"), `${changed.join(`
6466
6525
  `)}
6467
6526
  `, "utf-8");
6468
6527
  console.log(`changed-files.txt: ${changed.length} files`);
6469
- const taskResultPath = resolve26(artifactDir, "task-result.json");
6470
- if (!existsSync22(taskResultPath)) {
6528
+ const taskResultPath = resolve27(artifactDir, "task-result.json");
6529
+ if (!existsSync24(taskResultPath)) {
6471
6530
  const template = {
6472
6531
  task_id: activeTask,
6473
6532
  status: "completed",
6474
6533
  summary: "TODO: Write a one-line summary of what you did",
6475
6534
  completed_at: nowIso()
6476
6535
  };
6477
- writeFileSync10(taskResultPath, `${JSON.stringify(template, null, 2)}
6536
+ writeFileSync11(taskResultPath, `${JSON.stringify(template, null, 2)}
6478
6537
  `, "utf-8");
6479
6538
  console.log("task-result.json: created (update the summary!)");
6480
6539
  } else {
6481
6540
  console.log("task-result.json: already exists");
6482
6541
  }
6483
- const decisionLogPath = resolve26(artifactDir, "decision-log.md");
6484
- if (!existsSync22(decisionLogPath)) {
6542
+ const decisionLogPath = resolve27(artifactDir, "decision-log.md");
6543
+ if (!existsSync24(decisionLogPath)) {
6485
6544
  const content = `# Decision Log: ${activeTask}
6486
6545
 
6487
6546
  Record key decisions here using: rig-agent record decision "..."
6488
6547
  `;
6489
- writeFileSync10(decisionLogPath, content, "utf-8");
6548
+ writeFileSync11(decisionLogPath, content, "utf-8");
6490
6549
  console.log("decision-log.md: created (record your decisions!)");
6491
6550
  } else {
6492
6551
  console.log("decision-log.md: already exists");
6493
6552
  }
6494
- const nextActionsPath = resolve26(artifactDir, "next-actions.md");
6495
- if (!existsSync22(nextActionsPath)) {
6553
+ const nextActionsPath = resolve27(artifactDir, "next-actions.md");
6554
+ if (!existsSync24(nextActionsPath)) {
6496
6555
  const content = [
6497
6556
  `# Next Actions: ${activeTask}`,
6498
6557
  "",
@@ -6509,13 +6568,13 @@ Record key decisions here using: rig-agent record decision "..."
6509
6568
  ""
6510
6569
  ].join(`
6511
6570
  `);
6512
- writeFileSync10(nextActionsPath, content, "utf-8");
6571
+ writeFileSync11(nextActionsPath, content, "utf-8");
6513
6572
  console.log("next-actions.md: created (add recommendations for downstream tasks!)");
6514
6573
  } else {
6515
6574
  console.log("next-actions.md: already exists");
6516
6575
  }
6517
- const validationSummaryPath = resolve26(artifactDir, "validation-summary.json");
6518
- if (existsSync22(validationSummaryPath)) {
6576
+ const validationSummaryPath = resolve27(artifactDir, "validation-summary.json");
6577
+ if (existsSync24(validationSummaryPath)) {
6519
6578
  console.log("validation-summary.json: already exists");
6520
6579
  } else {
6521
6580
  console.log("validation-summary.json: not yet created (run: rig-agent validate)");
@@ -6529,8 +6588,8 @@ function taskArtifactDir(projectRoot, taskId) {
6529
6588
  throw new Error("No active task.");
6530
6589
  }
6531
6590
  const paths = resolveHarnessPaths(projectRoot);
6532
- const artifactDir = resolve26(paths.artifactsDir, activeTask);
6533
- mkdirSync10(artifactDir, { recursive: true });
6591
+ const artifactDir = resolve27(paths.artifactsDir, activeTask);
6592
+ mkdirSync11(artifactDir, { recursive: true });
6534
6593
  return artifactDir;
6535
6594
  }
6536
6595
  function taskArtifactWrite(projectRoot, filename, content, taskId) {
@@ -6539,10 +6598,10 @@ function taskArtifactWrite(projectRoot, filename, content, taskId) {
6539
6598
  throw new Error("No active task.");
6540
6599
  }
6541
6600
  const paths = resolveHarnessPaths(projectRoot);
6542
- const artifactDir = resolve26(paths.artifactsDir, activeTask);
6543
- mkdirSync10(artifactDir, { recursive: true });
6544
- const targetPath = resolve26(artifactDir, filename);
6545
- writeFileSync10(targetPath, content, "utf-8");
6601
+ const artifactDir = resolve27(paths.artifactsDir, activeTask);
6602
+ mkdirSync11(artifactDir, { recursive: true });
6603
+ const targetPath = resolve27(artifactDir, filename);
6604
+ writeFileSync11(targetPath, content, "utf-8");
6546
6605
  console.log(`Wrote: ${targetPath}`);
6547
6606
  }
6548
6607
  async function taskValidate(projectRoot, taskId, validatorRegistry) {
@@ -6603,7 +6662,7 @@ function collectTaskChangedFiles(projectRoot, taskId, includeCommitted) {
6603
6662
  [projectRoot, ""],
6604
6663
  [monorepoRepoRoot, ""]
6605
6664
  ]) {
6606
- if (!existsSync22(resolve26(repo, ".git"))) {
6665
+ if (!existsSync24(resolve27(repo, ".git"))) {
6607
6666
  continue;
6608
6667
  }
6609
6668
  if (includeCommitted && repo === monorepoRepoRoot) {
@@ -6628,12 +6687,22 @@ function filterTaskChangedFiles(projectRoot, taskId, files, scoped) {
6628
6687
  }
6629
6688
  function resolveTaskMonorepoRoot(projectRoot) {
6630
6689
  const runtimeWorkspace = loadRuntimeContextFromEnv()?.workspaceDir || process.env.RIG_TASK_WORKSPACE?.trim();
6631
- if (runtimeWorkspace && existsSync22(resolve26(runtimeWorkspace, ".git"))) {
6632
- return resolve26(runtimeWorkspace);
6690
+ if (runtimeWorkspace && existsSync24(resolve27(runtimeWorkspace, ".git"))) {
6691
+ return resolve27(runtimeWorkspace);
6633
6692
  }
6634
6693
  return resolveHarnessPaths(projectRoot).monorepoRoot;
6635
6694
  }
6636
6695
  function collectCommittedMonorepoFiles(projectRoot, repo) {
6696
+ const defaultRef = runCapture(["git", "-C", repo, "rev-parse", "--abbrev-ref", "origin/HEAD"], projectRoot);
6697
+ if (defaultRef.exitCode === 0 && defaultRef.stdout.trim()) {
6698
+ const mergeBase = runCapture(["git", "-C", repo, "merge-base", "HEAD", defaultRef.stdout.trim()], projectRoot);
6699
+ if (mergeBase.exitCode === 0 && mergeBase.stdout.trim()) {
6700
+ const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${mergeBase.stdout.trim()}..HEAD`], projectRoot);
6701
+ if (result.exitCode === 0) {
6702
+ return result.stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
6703
+ }
6704
+ }
6705
+ }
6637
6706
  const initialHeadCommit = resolveRuntimeInitialHeadCommit(projectRoot, repo);
6638
6707
  if (initialHeadCommit) {
6639
6708
  const result = runCapture(["git", "-C", repo, "diff", "--name-only", `${initialHeadCommit}..HEAD`], projectRoot);
@@ -6657,7 +6726,7 @@ function resolveRuntimeInitialHeadCommit(projectRoot, repo) {
6657
6726
  const runtimeContext = loadRuntimeContextFromEnv();
6658
6727
  if (runtimeContext?.initialHeadCommits?.monorepo?.trim()) {
6659
6728
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6660
- if (resolve26(monorepoRoot) === resolve26(repo)) {
6729
+ if (resolve27(monorepoRoot) === resolve27(repo)) {
6661
6730
  return runtimeContext.initialHeadCommits.monorepo.trim();
6662
6731
  }
6663
6732
  }
@@ -6667,7 +6736,7 @@ function resolveMonorepoBaseCommit(projectRoot, repo) {
6667
6736
  const runtimeContext = loadRuntimeContextFromEnv();
6668
6737
  if (runtimeContext?.monorepoBaseCommit?.trim()) {
6669
6738
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6670
- if (resolve26(monorepoRoot) === resolve26(repo)) {
6739
+ if (resolve27(monorepoRoot) === resolve27(repo)) {
6671
6740
  return runtimeContext.monorepoBaseCommit.trim();
6672
6741
  }
6673
6742
  }
@@ -6712,7 +6781,7 @@ function resolveRuntimeDirtyBaseline(projectRoot, repo) {
6712
6781
  return new Set;
6713
6782
  }
6714
6783
  const monorepoRoot = resolveTaskMonorepoRoot(projectRoot);
6715
- const selected = resolve26(repo) === resolve26(monorepoRoot) ? dirtyFiles.monorepo : resolve26(repo) === resolve26(projectRoot) ? dirtyFiles.project : undefined;
6784
+ const selected = resolve27(repo) === resolve27(monorepoRoot) ? dirtyFiles.monorepo : resolve27(repo) === resolve27(projectRoot) ? dirtyFiles.project : undefined;
6716
6785
  return new Set((selected || []).map((file) => normalizeChangedFilePath(file)).filter(Boolean));
6717
6786
  }
6718
6787
  function normalizeChangedFilePath(file) {
@@ -6812,12 +6881,12 @@ function printIndented(text) {
6812
6881
  }
6813
6882
  }
6814
6883
  function readLocalBeadsTasks(projectRoot) {
6815
- const issuesPath = resolve26(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
6816
- if (!existsSync22(issuesPath)) {
6884
+ const issuesPath = resolve27(resolveMonorepoRoot2(projectRoot), ".beads/issues.jsonl");
6885
+ if (!existsSync24(issuesPath)) {
6817
6886
  return [];
6818
6887
  }
6819
6888
  const tasks = [];
6820
- for (const line of readFileSync13(issuesPath, "utf-8").split(/\r?\n/)) {
6889
+ for (const line of readFileSync14(issuesPath, "utf-8").split(/\r?\n/)) {
6821
6890
  const trimmed = line.trim();
6822
6891
  if (!trimmed) {
6823
6892
  continue;
@@ -6930,11 +6999,11 @@ function taskDependencies(projectRoot, taskId, tracker) {
6930
6999
  return [...ids].sort();
6931
7000
  }
6932
7001
  function printArtifactSection(path, header) {
6933
- if (!existsSync22(path)) {
7002
+ if (!existsSync24(path)) {
6934
7003
  return;
6935
7004
  }
6936
7005
  console.log(header);
6937
- process.stdout.write(readFileSync13(path, "utf-8"));
7006
+ process.stdout.write(readFileSync14(path, "utf-8"));
6938
7007
  console.log("");
6939
7008
  }
6940
7009
  function escapeRegExp(value) {
@@ -6974,8 +7043,8 @@ function isRuntimeGatewayGhPath(candidate) {
6974
7043
  }
6975
7044
  function resolveOptionalMonorepoRoot(projectRoot) {
6976
7045
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
6977
- if (runtimeWorkspace && existsSync23(resolve27(runtimeWorkspace, ".git"))) {
6978
- return resolve27(runtimeWorkspace);
7046
+ if (runtimeWorkspace && existsSync25(resolve28(runtimeWorkspace, ".git"))) {
7047
+ return resolve28(runtimeWorkspace);
6979
7048
  }
6980
7049
  try {
6981
7050
  return resolveMonorepoRoot2(projectRoot);
@@ -7000,7 +7069,7 @@ function resolveGitBinary(projectRoot) {
7000
7069
  if (!candidate || isRuntimeGatewayGitPath(candidate)) {
7001
7070
  continue;
7002
7071
  }
7003
- if (existsSync23(candidate)) {
7072
+ if (existsSync25(candidate)) {
7004
7073
  return candidate;
7005
7074
  }
7006
7075
  }
@@ -7024,7 +7093,7 @@ function shouldScopeGitCommit(args, hasTaskContext) {
7024
7093
  if (!hasTaskContext) {
7025
7094
  return false;
7026
7095
  }
7027
- return !args.includes("--all") && !args.includes("--unscoped");
7096
+ return args.includes("--scoped");
7028
7097
  }
7029
7098
  function gitStatus(projectRoot, taskId) {
7030
7099
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
@@ -7060,11 +7129,11 @@ function gitPreflight(projectRoot, taskId, strict) {
7060
7129
  const expected = resolvedTask ? `rig/${resolveTaskBranchId(projectRoot, resolvedTask)}` : "";
7061
7130
  console.log("=== Git Flow Preflight ===");
7062
7131
  let issues = 0;
7063
- if (!existsSync23(resolve27(projectRoot, ".git"))) {
7132
+ if (!existsSync25(resolve28(projectRoot, ".git"))) {
7064
7133
  console.log(`ERROR: project root is not a git repo (${projectRoot})`);
7065
7134
  issues += 1;
7066
7135
  }
7067
- if (monorepoRoot && existsSync23(resolve27(monorepoRoot, ".git"))) {
7136
+ if (monorepoRoot && existsSync25(resolve28(monorepoRoot, ".git"))) {
7068
7137
  const monoBranch = branchName(projectRoot, monorepoRoot);
7069
7138
  if (expected && monoBranch !== expected) {
7070
7139
  console.log(`WARN: monorepo branch is ${monoBranch}, expected ${expected} for task ${resolvedTask}`);
@@ -7098,7 +7167,7 @@ function gitSyncBranch(projectRoot, taskId, targetRepo = "monorepo") {
7098
7167
  }
7099
7168
  const repoRoot = targetRepo === "monorepo" ? resolveOptionalMonorepoRoot(projectRoot) || resolveMonorepoRoot2(projectRoot) : projectRoot;
7100
7169
  const repoLabel = targetRepo === "monorepo" ? "Monorepo" : "Project";
7101
- if (!existsSync23(resolve27(repoRoot, ".git"))) {
7170
+ if (!existsSync25(resolve28(repoRoot, ".git"))) {
7102
7171
  throw new Error(`${repoLabel} repo not found at ${repoRoot}`);
7103
7172
  }
7104
7173
  const branchId = resolveTaskBranchId(projectRoot, resolvedTask);
@@ -7142,8 +7211,8 @@ function gitCommit(options) {
7142
7211
  function gitSnapshot(projectRoot, taskId, outputPath) {
7143
7212
  const monorepoRoot = resolveOptionalMonorepoRoot(projectRoot);
7144
7213
  const resolvedTask = taskId || safeCurrentTaskId(projectRoot);
7145
- const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve27(resolve27(projectRoot, ".rig", "state"), "git-state.txt"));
7146
- mkdirSync11(dirname14(output), { recursive: true });
7214
+ const output = outputPath || (resolvedTask ? resolveArtifactSnapshot(projectRoot, resolvedTask) : resolve28(resolve28(projectRoot, ".rig", "state"), "git-state.txt"));
7215
+ mkdirSync12(dirname15(output), { recursive: true });
7147
7216
  const lines = ["# Git Snapshot", `timestamp: ${nowIso()}`];
7148
7217
  if (resolvedTask) {
7149
7218
  lines.push(`task: ${resolvedTask}`);
@@ -7153,7 +7222,7 @@ function gitSnapshot(projectRoot, taskId, outputPath) {
7153
7222
  if (monorepoRoot && monorepoRoot !== projectRoot) {
7154
7223
  lines.push(...snapshotRepo(projectRoot, "monorepo", monorepoRoot));
7155
7224
  }
7156
- writeFileSync11(output, `${lines.join(`
7225
+ writeFileSync12(output, `${lines.join(`
7157
7226
  `)}
7158
7227
  `, "utf-8");
7159
7228
  return output;
@@ -7177,7 +7246,7 @@ function gitOpenPr(options) {
7177
7246
  } else if (taskId) {
7178
7247
  gitSyncBranch(options.projectRoot, taskId, "project");
7179
7248
  }
7180
- if (!existsSync23(resolve27(repoRoot, ".git"))) {
7249
+ if (!existsSync25(resolve28(repoRoot, ".git"))) {
7181
7250
  throw new Error(`Repository not available for open-pr target ${target}: ${repoRoot}`);
7182
7251
  }
7183
7252
  const branch = branchName(options.projectRoot, repoRoot);
@@ -7390,12 +7459,12 @@ function assertPrHasNoGitConflicts(prState, repoLabel, baseRef) {
7390
7459
  }
7391
7460
  function writePrMetadata(projectRoot, taskId, result) {
7392
7461
  const dir = artifactDirForId(projectRoot, taskId);
7393
- mkdirSync11(dir, { recursive: true });
7394
- const path = resolve27(dir, "pr-state.json");
7462
+ mkdirSync12(dir, { recursive: true });
7463
+ const path = resolve28(dir, "pr-state.json");
7395
7464
  let prs = {};
7396
- if (existsSync23(path)) {
7465
+ if (existsSync25(path)) {
7397
7466
  try {
7398
- const parsed = JSON.parse(readFileSync14(path, "utf-8"));
7467
+ const parsed = JSON.parse(readFileSync15(path, "utf-8"));
7399
7468
  if (parsed && typeof parsed === "object" && parsed.prs && typeof parsed.prs === "object") {
7400
7469
  prs = parsed.prs;
7401
7470
  }
@@ -7411,12 +7480,12 @@ function writePrMetadata(projectRoot, taskId, result) {
7411
7480
  ...primary || {},
7412
7481
  updated_at: nowIso()
7413
7482
  };
7414
- writeFileSync11(path, `${JSON.stringify(artifact, null, 2)}
7483
+ writeFileSync12(path, `${JSON.stringify(artifact, null, 2)}
7415
7484
  `, "utf-8");
7416
7485
  }
7417
7486
  function resolveArtifactSnapshot(projectRoot, taskId) {
7418
- const artifactDir = resolve27(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7419
- return resolve27(artifactDir, "git-state.txt");
7487
+ const artifactDir = resolve28(resolveHarnessPaths(projectRoot).artifactsDir, taskId);
7488
+ return resolve28(artifactDir, "git-state.txt");
7420
7489
  }
7421
7490
  function ensureFullGitHistory(projectRoot, repoRoot, remoteName = "origin") {
7422
7491
  const shallow = runCapture2(gitCmd(projectRoot, repoRoot, "rev-parse", "--is-shallow-repository"), projectRoot);
@@ -7468,14 +7537,14 @@ function resolveGithubCliBinary(projectRoot) {
7468
7537
  }
7469
7538
  const explicitPathEntries = (process.env.PATH || "").split(":").map((entry) => entry.trim()).filter(Boolean);
7470
7539
  for (const entry of explicitPathEntries) {
7471
- candidates.add(resolve27(entry, "gh"));
7540
+ candidates.add(resolve28(entry, "gh"));
7472
7541
  }
7473
7542
  const bunResolved = Bun.which("gh");
7474
7543
  if (bunResolved) {
7475
7544
  candidates.add(bunResolved);
7476
7545
  }
7477
7546
  for (const candidate of candidates) {
7478
- if (candidate && existsSync23(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7547
+ if (candidate && existsSync25(candidate) && !isRuntimeGatewayGhPath(candidate)) {
7479
7548
  return candidate;
7480
7549
  }
7481
7550
  }
@@ -7505,7 +7574,7 @@ function resolveRepoNameWithOwner(projectRoot, repoRoot) {
7505
7574
  return resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, repoRoot, repoRoot, visited);
7506
7575
  }
7507
7576
  function resolveGithubRepoNameWithOwnerFromGitRoot(projectRoot, gitRoot, cwd, visited) {
7508
- const normalizedGitRoot = resolve27(gitRoot);
7577
+ const normalizedGitRoot = resolve28(gitRoot);
7509
7578
  if (visited.has(normalizedGitRoot)) {
7510
7579
  return "";
7511
7580
  }
@@ -7577,7 +7646,7 @@ function resolveNetworkRemoteName(projectRoot, repoRoot, repoNameWithOwner) {
7577
7646
  return remotes.includes("origin") ? "origin" : remotes[0];
7578
7647
  }
7579
7648
  function gitQuery(projectRoot, gitRoot, cwd, ...args) {
7580
- const gitArgs = existsSync23(resolve27(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7649
+ const gitArgs = existsSync25(resolve28(gitRoot, ".git")) ? gitCmd(projectRoot, gitRoot, ...args) : [resolveGitBinary(projectRoot), "--git-dir", gitRoot, ...args];
7581
7650
  return runCapture2(gitArgs, cwd, projectRoot);
7582
7651
  }
7583
7652
  function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
@@ -7595,9 +7664,9 @@ function resolveLocalGitRemoteRoot(remoteUrl, gitRoot) {
7595
7664
  } else if (/^[a-z][a-z0-9+.-]*:\/\//i.test(normalized) || /^[^@]+@[^:]+:.+$/.test(normalized)) {
7596
7665
  return "";
7597
7666
  } else if (!isAbsolute2(normalized)) {
7598
- candidate = resolve27(gitRoot, normalized);
7667
+ candidate = resolve28(gitRoot, normalized);
7599
7668
  }
7600
- return existsSync23(candidate) ? candidate : "";
7669
+ return existsSync25(candidate) ? candidate : "";
7601
7670
  }
7602
7671
  function normalizeGithubRepoNameWithOwner(value) {
7603
7672
  const normalized = value.trim();
@@ -7724,7 +7793,7 @@ function inferReviewerFromChangedFiles(projectRoot, repoRoot, baseRef, branchRef
7724
7793
  return best;
7725
7794
  }
7726
7795
  function snapshotRepo(projectRoot, label, repo) {
7727
- if (!existsSync23(resolve27(repo, ".git"))) {
7796
+ if (!existsSync25(resolve28(repo, ".git"))) {
7728
7797
  return [`## ${label}`, `repo: ${repo}`, "status: unavailable", ""];
7729
7798
  }
7730
7799
  const status = runCapture2(gitCmd(projectRoot, repo, "status", "--short"), projectRoot).stdout.trim();
@@ -7747,7 +7816,7 @@ function snapshotRepo(projectRoot, label, repo) {
7747
7816
  ];
7748
7817
  }
7749
7818
  function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files, changedFilesManifest) {
7750
- if (!existsSync23(resolve27(repo, ".git"))) {
7819
+ if (!existsSync25(resolve28(repo, ".git"))) {
7751
7820
  console.log(`Skipping ${label}: repo not available (${repo})`);
7752
7821
  return;
7753
7822
  }
@@ -7779,18 +7848,18 @@ function commitRepo(projectRoot, repo, label, message, allowEmpty, scoped, files
7779
7848
  console.log(`Committed ${label}: ${message}`);
7780
7849
  }
7781
7850
  function readChangedFilesManifest(projectRoot, taskId) {
7782
- const manifestPath = resolve27(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7783
- if (!existsSync23(manifestPath)) {
7851
+ const manifestPath = resolve28(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7852
+ if (!existsSync25(manifestPath)) {
7784
7853
  return [];
7785
7854
  }
7786
- const files = readFileSync14(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
7855
+ const files = readFileSync15(manifestPath, "utf-8").split(/\r?\n/).map((line) => normalizeChangedFilePath2(line)).filter(Boolean);
7787
7856
  return [...new Set(files)];
7788
7857
  }
7789
7858
  function refreshChangedFilesManifest(projectRoot, taskId) {
7790
- const manifestPath = resolve27(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7791
- mkdirSync11(dirname14(manifestPath), { recursive: true });
7859
+ const manifestPath = resolve28(artifactDirForId(projectRoot, taskId), "changed-files.txt");
7860
+ mkdirSync12(dirname15(manifestPath), { recursive: true });
7792
7861
  const changedFiles = changedFilesForTask(projectRoot, taskId, true);
7793
- writeFileSync11(manifestPath, `${changedFiles.join(`
7862
+ writeFileSync12(manifestPath, `${changedFiles.join(`
7794
7863
  `)}
7795
7864
  `, "utf-8");
7796
7865
  return manifestPath;
@@ -7903,7 +7972,7 @@ function repoHasPathChange(projectRoot, repoRoot, relativePath) {
7903
7972
  return result.exitCode === 0 && result.stdout.trim().length > 0;
7904
7973
  }
7905
7974
  function stageExcludePathspecs(repoRoot) {
7906
- const patterns = existsSync23(resolve27(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
7975
+ const patterns = existsSync25(resolve28(repoRoot, ".rig", "task-config.json")) ? [...TASK_RUNTIME_STAGE_EXCLUDES, ...GENERATED_STAGE_EXCLUDES] : [".rig/**", ...GENERATED_STAGE_EXCLUDES];
7907
7976
  return patterns.map((pattern) => `:(glob,exclude)${pattern}`);
7908
7977
  }
7909
7978
  function pathResolvesBeyondSymlink(repoRoot, relativePath) {
@@ -7913,7 +7982,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
7913
7982
  }
7914
7983
  let current = repoRoot;
7915
7984
  for (let index = 0;index < parts.length - 1; index += 1) {
7916
- current = resolve27(current, parts[index]);
7985
+ current = resolve28(current, parts[index]);
7917
7986
  try {
7918
7987
  if (lstatSync(current).isSymbolicLink()) {
7919
7988
  return true;
@@ -7925,7 +7994,7 @@ function pathResolvesBeyondSymlink(repoRoot, relativePath) {
7925
7994
  return false;
7926
7995
  }
7927
7996
  function printRepoStatus(projectRoot, label, repo, expectedBranch) {
7928
- if (!existsSync23(resolve27(repo, ".git"))) {
7997
+ if (!existsSync25(resolve28(repo, ".git"))) {
7929
7998
  console.log(`${label}: unavailable (${repo})`);
7930
7999
  return;
7931
8000
  }
@@ -7961,7 +8030,7 @@ function resolveTaskBranchId(projectRoot, taskId) {
7961
8030
  }
7962
8031
  } catch {}
7963
8032
  const artifactDir = artifactDirForId(projectRoot, taskId);
7964
- if (existsSync23(artifactDir)) {
8033
+ if (existsSync25(artifactDir)) {
7965
8034
  return taskId;
7966
8035
  }
7967
8036
  throw new Error(`Unknown task id: ${taskId}`);
@@ -7997,11 +8066,11 @@ function runCapture2(command, cwd, projectRoot = cwd) {
7997
8066
  }
7998
8067
  function runtimeGitEnv(projectRoot) {
7999
8068
  const { ctx, runtimeRoot } = resolveRuntimeMetadata(projectRoot);
8000
- const runtimeHome = runtimeRoot ? resolve27(runtimeRoot, "home") : "";
8001
- const runtimeTmp = runtimeRoot ? resolve27(runtimeRoot, "tmp") : "";
8002
- const runtimeCache = runtimeRoot ? resolve27(runtimeRoot, "cache") : "";
8003
- const runtimeKnownHosts = runtimeHome ? resolve27(runtimeHome, ".ssh", "known_hosts") : "";
8004
- const runtimeKey = runtimeHome ? resolve27(runtimeHome, ".ssh", "rig-agent-key") : "";
8069
+ const runtimeHome = runtimeRoot ? resolve28(runtimeRoot, "home") : "";
8070
+ const runtimeTmp = runtimeRoot ? resolve28(runtimeRoot, "tmp") : "";
8071
+ const runtimeCache = runtimeRoot ? resolve28(runtimeRoot, "cache") : "";
8072
+ const runtimeKnownHosts = runtimeHome ? resolve28(runtimeHome, ".ssh", "known_hosts") : "";
8073
+ const runtimeKey = runtimeHome ? resolve28(runtimeHome, ".ssh", "rig-agent-key") : "";
8005
8074
  const env = {};
8006
8075
  if (ctx?.workspaceDir) {
8007
8076
  env.PROJECT_RIG_ROOT = projectRoot;
@@ -8014,14 +8083,14 @@ function runtimeGitEnv(projectRoot) {
8014
8083
  if (runtimeRoot) {
8015
8084
  env.RIG_RUNTIME_HOME = runtimeRoot;
8016
8085
  }
8017
- if (runtimeHome && existsSync23(runtimeHome)) {
8086
+ if (runtimeHome && existsSync25(runtimeHome)) {
8018
8087
  env.HOME = runtimeHome;
8019
8088
  env.OPENSSL_CONF = ensureRuntimeOpenSslConfig(runtimeHome);
8020
8089
  }
8021
- if (runtimeTmp && existsSync23(runtimeTmp)) {
8090
+ if (runtimeTmp && existsSync25(runtimeTmp)) {
8022
8091
  env.TMPDIR = runtimeTmp;
8023
8092
  }
8024
- if (runtimeCache && existsSync23(runtimeCache)) {
8093
+ if (runtimeCache && existsSync25(runtimeCache)) {
8025
8094
  env.XDG_CACHE_HOME = runtimeCache;
8026
8095
  }
8027
8096
  const workspaceSecrets = loadDotEnvSecrets(ctx?.workspaceDir || projectRoot, process.env);
@@ -8065,14 +8134,14 @@ function runtimeGitEnv(projectRoot) {
8065
8134
  env.GH_TOKEN = env.GH_TOKEN || gitHubToken;
8066
8135
  applyGitHubCredentialHelperEnv(env);
8067
8136
  }
8068
- if (runtimeKnownHosts && existsSync23(runtimeKnownHosts)) {
8137
+ if (runtimeKnownHosts && existsSync25(runtimeKnownHosts)) {
8069
8138
  const sshParts = [
8070
8139
  "ssh",
8071
8140
  `-o UserKnownHostsFile="${runtimeKnownHosts}"`,
8072
8141
  "-o StrictHostKeyChecking=yes",
8073
8142
  "-F /dev/null"
8074
8143
  ];
8075
- if (runtimeKey && existsSync23(runtimeKey)) {
8144
+ if (runtimeKey && existsSync25(runtimeKey)) {
8076
8145
  sshParts.splice(1, 0, `-i "${runtimeKey}"`, "-o IdentitiesOnly=yes");
8077
8146
  }
8078
8147
  env.GIT_SSH_COMMAND = sshParts.join(" ");
@@ -8093,12 +8162,12 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8093
8162
  if (!runtimeRoot) {
8094
8163
  return {};
8095
8164
  }
8096
- const path = resolve27(runtimeRoot, "runtime-secrets.json");
8097
- if (!existsSync23(path)) {
8165
+ const path = resolve28(runtimeRoot, "runtime-secrets.json");
8166
+ if (!existsSync25(path)) {
8098
8167
  return {};
8099
8168
  }
8100
8169
  try {
8101
- const parsed = JSON.parse(readFileSync14(path, "utf-8"));
8170
+ const parsed = JSON.parse(readFileSync15(path, "utf-8"));
8102
8171
  const entries = Object.entries(parsed).filter((entry) => typeof entry[1] === "string");
8103
8172
  return Object.fromEntries(entries);
8104
8173
  } catch {
@@ -8106,13 +8175,13 @@ function loadPersistedRuntimeSecrets(runtimeRoot) {
8106
8175
  }
8107
8176
  }
8108
8177
  function ensureRuntimeOpenSslConfig(runtimeHome) {
8109
- const sslDir = resolve27(runtimeHome, ".ssl");
8110
- const sslConfig = resolve27(sslDir, "openssl.cnf");
8111
- if (!existsSync23(sslDir)) {
8112
- mkdirSync11(sslDir, { recursive: true });
8178
+ const sslDir = resolve28(runtimeHome, ".ssl");
8179
+ const sslConfig = resolve28(sslDir, "openssl.cnf");
8180
+ if (!existsSync25(sslDir)) {
8181
+ mkdirSync12(sslDir, { recursive: true });
8113
8182
  }
8114
- if (!existsSync23(sslConfig)) {
8115
- writeFileSync11(sslConfig, `# Rig runtime OpenSSL config placeholder
8183
+ if (!existsSync25(sslConfig)) {
8184
+ writeFileSync12(sslConfig, `# Rig runtime OpenSSL config placeholder
8116
8185
  `);
8117
8186
  }
8118
8187
  return sslConfig;
@@ -8130,29 +8199,29 @@ function resolveRuntimeMetadata(projectRoot) {
8130
8199
  if (contextFile) {
8131
8200
  return {
8132
8201
  ctx,
8133
- runtimeRoot: dirname14(resolve27(contextFile))
8202
+ runtimeRoot: dirname15(resolve28(contextFile))
8134
8203
  };
8135
8204
  }
8136
8205
  const inferredContextFile = findRuntimeContextFile2(projectRoot);
8137
- if (existsSync23(inferredContextFile)) {
8206
+ if (existsSync25(inferredContextFile)) {
8138
8207
  try {
8139
8208
  ctx = loadRuntimeContext(inferredContextFile);
8140
8209
  } catch {}
8141
8210
  return {
8142
8211
  ctx,
8143
- runtimeRoot: dirname14(inferredContextFile)
8212
+ runtimeRoot: dirname15(inferredContextFile)
8144
8213
  };
8145
8214
  }
8146
8215
  return { ctx, runtimeRoot: "" };
8147
8216
  }
8148
8217
  function findRuntimeContextFile2(startPath) {
8149
- let current = resolve27(startPath);
8218
+ let current = resolve28(startPath);
8150
8219
  while (true) {
8151
- const candidate = resolve27(current, "runtime-context.json");
8152
- if (existsSync23(candidate)) {
8220
+ const candidate = resolve28(current, "runtime-context.json");
8221
+ if (existsSync25(candidate)) {
8153
8222
  return candidate;
8154
8223
  }
8155
- const parent = dirname14(current);
8224
+ const parent = dirname15(current);
8156
8225
  if (parent === current) {
8157
8226
  return "";
8158
8227
  }
@@ -8161,7 +8230,7 @@ function findRuntimeContextFile2(startPath) {
8161
8230
  }
8162
8231
 
8163
8232
  // packages/runtime/src/control-plane/native/profile-ops.ts
8164
- import { existsSync as existsSync24, mkdirSync as mkdirSync12, writeFileSync as writeFileSync12 } from "fs";
8233
+ import { existsSync as existsSync26, mkdirSync as mkdirSync13, writeFileSync as writeFileSync13 } from "fs";
8165
8234
  var DEFAULTS = {
8166
8235
  model: parseEnvOrDefault(process.env.DEFAULT_AGENT_MODEL, ["claude", "gpt-codex", "pi"], "pi"),
8167
8236
  runtime: parseEnvOrDefault(process.env.DEFAULT_AGENT_RUNTIME, ["claude-code", "codex-app-server", "pi"], "pi"),
@@ -8176,7 +8245,7 @@ function parseEnvOrDefault(value, allowed, fallback) {
8176
8245
  return allowed.includes(value) ? value : fallback;
8177
8246
  }
8178
8247
  async function readProfileFile(path) {
8179
- if (!existsSync24(path)) {
8248
+ if (!existsSync26(path)) {
8180
8249
  return null;
8181
8250
  }
8182
8251
  try {
@@ -8229,14 +8298,14 @@ async function setProfile(projectRoot, options) {
8229
8298
  plugin = model === "gpt-codex" ? "codex" : model === "pi" ? "pi" : "claude";
8230
8299
  }
8231
8300
  const paths = resolveHarnessPaths(projectRoot);
8232
- mkdirSync12(paths.stateDir, { recursive: true });
8301
+ mkdirSync13(paths.stateDir, { recursive: true });
8233
8302
  const next = {
8234
8303
  model,
8235
8304
  runtime,
8236
8305
  agent_plugin: plugin,
8237
8306
  updated_at: new Date().toISOString()
8238
8307
  };
8239
- writeFileSync12(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8308
+ writeFileSync13(paths.agentProfilePath, `${JSON.stringify(next, null, 2)}
8240
8309
  `, "utf-8");
8241
8310
  await showProfile(projectRoot, false);
8242
8311
  }
@@ -8272,13 +8341,13 @@ async function setReviewProfile(projectRoot, mode, provider) {
8272
8341
  throw new Error(`Invalid provider: ${resolvedProvider}. Supported: greptile.`);
8273
8342
  }
8274
8343
  const paths = resolveHarnessPaths(projectRoot);
8275
- mkdirSync12(paths.stateDir, { recursive: true });
8344
+ mkdirSync13(paths.stateDir, { recursive: true });
8276
8345
  const next = {
8277
8346
  mode,
8278
8347
  provider: resolvedProvider,
8279
8348
  updated_at: new Date().toISOString()
8280
8349
  };
8281
- writeFileSync12(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8350
+ writeFileSync13(paths.reviewProfilePath, `${JSON.stringify(next, null, 2)}
8282
8351
  `, "utf-8");
8283
8352
  await showReviewProfile(projectRoot);
8284
8353
  }
@@ -8316,44 +8385,44 @@ async function loadReviewProfile(path) {
8316
8385
  }
8317
8386
 
8318
8387
  // packages/runtime/src/control-plane/native/repo-ops.ts
8319
- import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync16, readdirSync as readdirSync6, rmSync as rmSync8, writeFileSync as writeFileSync14 } from "fs";
8320
- import { basename as basename8, dirname as dirname16, resolve as resolve31 } from "path";
8388
+ import { existsSync as existsSync30, mkdirSync as mkdirSync17, readFileSync as readFileSync17, readdirSync as readdirSync6, rmSync as rmSync8, writeFileSync as writeFileSync15 } from "fs";
8389
+ import { basename as basename8, dirname as dirname17, resolve as resolve32 } from "path";
8321
8390
  // packages/runtime/src/control-plane/repos/mirror/bootstrap.ts
8322
- import { existsSync as existsSync26, mkdirSync as mkdirSync14, realpathSync as realpathSync2 } from "fs";
8323
- import { resolve as resolve29 } from "path";
8391
+ import { existsSync as existsSync28, mkdirSync as mkdirSync15, realpathSync as realpathSync2 } from "fs";
8392
+ import { resolve as resolve30 } from "path";
8324
8393
 
8325
8394
  // packages/runtime/src/control-plane/authority-files.ts
8326
- 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";
8327
- import { dirname as dirname15, join as join5, relative, resolve as resolve28 } from "path";
8395
+ import { existsSync as existsSync27, mkdirSync as mkdirSync14, readFileSync as readFileSync16, writeFileSync as writeFileSync14, appendFileSync as appendFileSync2, copyFileSync as copyFileSync3, statSync as statSync6, readdirSync as readdirSync5, chmodSync as chmodSync3 } from "fs";
8396
+ import { dirname as dirname16, join as join5, relative, resolve as resolve29 } from "path";
8328
8397
  import { parse as parseToml, stringify as stringifyToml } from "smol-toml";
8329
8398
  function resolveAuthorityProjectStateDir(projectRoot) {
8330
8399
  const explicit = process.env.RIG_STATE_DIR?.trim();
8331
8400
  if (explicit) {
8332
- return resolve28(explicit);
8401
+ return resolve29(explicit);
8333
8402
  }
8334
- return resolve28(resolve28(projectRoot), ".rig", "state");
8403
+ return resolve29(resolve29(projectRoot), ".rig", "state");
8335
8404
  }
8336
8405
  function readJsonAtPath(path, fallback) {
8337
- if (!existsSync25(path)) {
8406
+ if (!existsSync27(path)) {
8338
8407
  return fallback;
8339
8408
  }
8340
8409
  try {
8341
- return JSON.parse(readFileSync15(path, "utf-8"));
8410
+ return JSON.parse(readFileSync16(path, "utf-8"));
8342
8411
  } catch {
8343
8412
  return fallback;
8344
8413
  }
8345
8414
  }
8346
8415
  function writeJsonAtPath(path, value) {
8347
- mkdirSync13(dirname15(path), { recursive: true });
8348
- writeFileSync13(path, `${JSON.stringify(value, null, 2)}
8416
+ mkdirSync14(dirname16(path), { recursive: true });
8417
+ writeFileSync14(path, `${JSON.stringify(value, null, 2)}
8349
8418
  `, "utf8");
8350
8419
  return path;
8351
8420
  }
8352
8421
  function readAuthorityProjectStateJson(projectRoot, relativePath, fallback) {
8353
- return readJsonAtPath(resolve28(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8422
+ return readJsonAtPath(resolve29(resolveAuthorityProjectStateDir(projectRoot), relativePath), fallback);
8354
8423
  }
8355
8424
  function writeAuthorityProjectStateJson(projectRoot, relativePath, value) {
8356
- return writeJsonAtPath(resolve28(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8425
+ return writeJsonAtPath(resolve29(resolveAuthorityProjectStateDir(projectRoot), relativePath), value);
8357
8426
  }
8358
8427
 
8359
8428
  // packages/runtime/src/control-plane/repos/mirror/state.ts
@@ -8413,7 +8482,7 @@ function sameExistingPath(left, right) {
8413
8482
  try {
8414
8483
  return realpathSync2(left) === realpathSync2(right);
8415
8484
  } catch {
8416
- return resolve29(left) === resolve29(right);
8485
+ return resolve30(left) === resolve30(right);
8417
8486
  }
8418
8487
  }
8419
8488
  function repoLooksUsable(repoRoot, projectRoot) {
@@ -8449,7 +8518,7 @@ function resolveMirrorRemoteUrl(layout) {
8449
8518
  }
8450
8519
  }
8451
8520
  }
8452
- if (existsSync26(resolve29(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8521
+ if (existsSync28(resolve30(layout.checkoutRoot, ".git")) && checkoutLooksUsable(layout)) {
8453
8522
  const checkoutOrigin = runGit(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
8454
8523
  if (checkoutOrigin.exitCode === 0) {
8455
8524
  const currentOrigin = checkoutOrigin.stdout.trim();
@@ -8462,9 +8531,9 @@ function resolveMirrorRemoteUrl(layout) {
8462
8531
  }
8463
8532
  function ensureManagedRepoMirror(projectRoot, repoId) {
8464
8533
  const layout = resolveManagedRepoLayout(projectRoot, repoId);
8465
- mkdirSync14(layout.metadataRoot, { recursive: true });
8534
+ mkdirSync15(layout.metadataRoot, { recursive: true });
8466
8535
  const remoteUrl = resolveMirrorRemoteUrl(layout);
8467
- if (!existsSync26(resolve29(layout.mirrorRoot, "HEAD"))) {
8536
+ if (!existsSync28(resolve30(layout.mirrorRoot, "HEAD"))) {
8468
8537
  ensureGitSuccess(runGit(["git", "init", "--bare", layout.mirrorRoot], layout.projectRoot), ["git", "init", "--bare", layout.mirrorRoot]);
8469
8538
  }
8470
8539
  const getOrigin = runGit(["git", "--git-dir", layout.mirrorRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8484,8 +8553,8 @@ function ensureManagedRepoMirror(projectRoot, repoId) {
8484
8553
  return layout;
8485
8554
  }
8486
8555
  // packages/runtime/src/control-plane/repos/mirror/refresh.ts
8487
- import { existsSync as existsSync27, mkdirSync as mkdirSync15, realpathSync as realpathSync3, rmSync as rmSync7 } from "fs";
8488
- import { resolve as resolve30 } from "path";
8556
+ import { existsSync as existsSync29, mkdirSync as mkdirSync16, realpathSync as realpathSync3, rmSync as rmSync7 } from "fs";
8557
+ import { resolve as resolve31 } from "path";
8489
8558
  function nowIso3() {
8490
8559
  return new Date().toISOString();
8491
8560
  }
@@ -8512,7 +8581,7 @@ function sameExistingPath2(left, right) {
8512
8581
  try {
8513
8582
  return realpathSync3(left) === realpathSync3(right);
8514
8583
  } catch {
8515
- return resolve30(left) === resolve30(right);
8584
+ return resolve31(left) === resolve31(right);
8516
8585
  }
8517
8586
  }
8518
8587
  function ensureMirrorHead(layout) {
@@ -8558,12 +8627,12 @@ function checkoutLooksUsable2(layout) {
8558
8627
  return probe.exitCode === 0 && sameExistingPath2(probe.stdout.trim(), layout.checkoutRoot);
8559
8628
  }
8560
8629
  function ensureCheckoutFromMirror(layout) {
8561
- mkdirSync15(resolve30(layout.checkoutRoot, ".."), { recursive: true });
8562
- const gitPath = resolve30(layout.checkoutRoot, ".git");
8563
- if (existsSync27(layout.checkoutRoot) && (!existsSync27(gitPath) || !checkoutLooksUsable2(layout))) {
8630
+ mkdirSync16(resolve31(layout.checkoutRoot, ".."), { recursive: true });
8631
+ const gitPath = resolve31(layout.checkoutRoot, ".git");
8632
+ if (existsSync29(layout.checkoutRoot) && (!existsSync29(gitPath) || !checkoutLooksUsable2(layout))) {
8564
8633
  rmSync7(layout.checkoutRoot, { recursive: true, force: true });
8565
8634
  }
8566
- if (!existsSync27(gitPath)) {
8635
+ if (!existsSync29(gitPath)) {
8567
8636
  ensureGitSuccess2(runGit2(["git", "clone", layout.mirrorRoot, layout.checkoutRoot], layout.projectRoot), ["git", "clone", layout.mirrorRoot, layout.checkoutRoot]);
8568
8637
  }
8569
8638
  const getOrigin = runGit2(["git", "-C", layout.checkoutRoot, "remote", "get-url", "origin"], layout.projectRoot);
@@ -8664,7 +8733,7 @@ function repoDiscover(projectRoot, taskId) {
8664
8733
  }
8665
8734
  function repoBaseline(projectRoot, refresh = false) {
8666
8735
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8667
- if (!refresh && existsSync28(paths.baseRepoPinsPath)) {
8736
+ if (!refresh && existsSync30(paths.baseRepoPinsPath)) {
8668
8737
  const baseline = readJsonFile(paths.baseRepoPinsPath, { recorded_at: nowIso(), repos: {} });
8669
8738
  return baseline.repos || {};
8670
8739
  }
@@ -8688,8 +8757,8 @@ function ensureMonorepoReady(projectRoot) {
8688
8757
  }
8689
8758
  function persistBaselinePins(projectRoot, repos) {
8690
8759
  const paths = resolveRepoDiscoveryPaths(projectRoot);
8691
- mkdirSync16(resolve31(paths.baseRepoPinsPath, ".."), { recursive: true });
8692
- writeFileSync14(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8760
+ mkdirSync17(resolve32(paths.baseRepoPinsPath, ".."), { recursive: true });
8761
+ writeFileSync15(paths.baseRepoPinsPath, `${JSON.stringify({ recorded_at: nowIso(), repos }, null, 2)}
8693
8762
  `, "utf-8");
8694
8763
  return repos;
8695
8764
  }
@@ -8768,28 +8837,28 @@ function readRepoDiscoveryTaskConfig(projectRoot) {
8768
8837
  function resolveRepoDiscoveryPaths(projectRoot) {
8769
8838
  const monorepoRoot = resolveMonorepoRepoLayout(projectRoot).checkoutRoot;
8770
8839
  const explicitHostProjectRoot = (process.env.RIG_HOST_PROJECT_ROOT || "").trim();
8771
- const normalizedProjectRoot = resolve31(projectRoot);
8840
+ const normalizedProjectRoot = resolve32(projectRoot);
8772
8841
  const hostProjectRoot = explicitHostProjectRoot && shouldUseHostProjectStateRoot(normalizedProjectRoot) ? explicitHostProjectRoot : normalizedProjectRoot;
8773
- const stateDir = resolve31(hostProjectRoot, ".rig", "state");
8842
+ const stateDir = resolve32(hostProjectRoot, ".rig", "state");
8774
8843
  return {
8775
8844
  monorepoRoot,
8776
- taskRepoCommitsPath: resolve31(stateDir, "task-repo-commits.json"),
8777
- baseRepoPinsPath: resolve31(stateDir, "base-repo-pins.json")
8845
+ taskRepoCommitsPath: resolve32(stateDir, "task-repo-commits.json"),
8846
+ baseRepoPinsPath: resolve32(stateDir, "base-repo-pins.json")
8778
8847
  };
8779
8848
  }
8780
8849
  function shouldUseHostProjectStateRoot(projectRoot) {
8781
8850
  const runtimeWorkspace = process.env.RIG_TASK_WORKSPACE?.trim();
8782
- if (runtimeWorkspace && resolve31(runtimeWorkspace) === projectRoot) {
8851
+ if (runtimeWorkspace && resolve32(runtimeWorkspace) === projectRoot) {
8783
8852
  return true;
8784
8853
  }
8785
- return basename8(dirname16(projectRoot)) === ".worktrees";
8854
+ return basename8(dirname17(projectRoot)) === ".worktrees";
8786
8855
  }
8787
8856
  function readPinFromArtifact(projectRoot, depTask, repoKey) {
8788
- const snapshot = resolve31(artifactDirForId(projectRoot, depTask), "git-state.txt");
8789
- if (!existsSync28(snapshot)) {
8857
+ const snapshot = resolve32(artifactDirForId(projectRoot, depTask), "git-state.txt");
8858
+ if (!existsSync30(snapshot)) {
8790
8859
  return "";
8791
8860
  }
8792
- const content = readFileSync16(snapshot, "utf-8");
8861
+ const content = readFileSync17(snapshot, "utf-8");
8793
8862
  const chunk = content.split(/\r?\n/);
8794
8863
  let inSection = false;
8795
8864
  for (const line of chunk) {
@@ -8811,12 +8880,12 @@ function repoPath(projectRoot, key) {
8811
8880
  if (managed) {
8812
8881
  return managed.checkoutRoot;
8813
8882
  }
8814
- return key.startsWith("/") ? key : resolve31(projectRoot, key);
8883
+ return key.startsWith("/") ? key : resolve32(projectRoot, key);
8815
8884
  }
8816
8885
  function applyPins(projectRoot, pins) {
8817
8886
  for (const [key, commit] of Object.entries(pins)) {
8818
8887
  const path = repoPath(projectRoot, key);
8819
- if (!existsSync28(resolve31(path, ".git"))) {
8888
+ if (!existsSync30(resolve32(path, ".git"))) {
8820
8889
  throw new Error(`Repo for pin not available: ${key} (${path})`);
8821
8890
  }
8822
8891
  let hasCommit = runGitCapture(["git", "-C", path, "cat-file", "-e", `${commit}^{commit}`], projectRoot).exitCode === 0;
@@ -8845,7 +8914,7 @@ function verifyPins(projectRoot, pins) {
8845
8914
  let ok = true;
8846
8915
  for (const [key, expected] of Object.entries(pins)) {
8847
8916
  const path = repoPath(projectRoot, key);
8848
- if (!existsSync28(resolve31(path, ".git"))) {
8917
+ if (!existsSync30(resolve32(path, ".git"))) {
8849
8918
  console.error(`ERROR: repo missing during pin verification: ${key}`);
8850
8919
  ok = false;
8851
8920
  continue;
@@ -8870,23 +8939,23 @@ function resolveRuntimeGitEnv() {
8870
8939
  GIT_SSH_COMMAND: process.env.GIT_SSH_COMMAND
8871
8940
  };
8872
8941
  }
8873
- 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()));
8874
- const runtimeHome = runtimeRoot ? resolve31(runtimeRoot, "home") : process.env.HOME?.trim() || "";
8942
+ const runtimeRoot = process.env.RIG_RUNTIME_HOME?.trim() || (process.env.RIG_RUNTIME_CONTEXT_FILE?.trim() ? resolve32(process.env.RIG_RUNTIME_CONTEXT_FILE, "..") : inferRuntimeRootFromWorkspace(process.cwd()));
8943
+ const runtimeHome = runtimeRoot ? resolve32(runtimeRoot, "home") : process.env.HOME?.trim() || "";
8875
8944
  if (!runtimeHome) {
8876
8945
  return;
8877
8946
  }
8878
- const knownHostsPath = resolve31(runtimeHome, ".ssh", "known_hosts");
8879
- if (!existsSync28(knownHostsPath)) {
8947
+ const knownHostsPath = resolve32(runtimeHome, ".ssh", "known_hosts");
8948
+ if (!existsSync30(knownHostsPath)) {
8880
8949
  return { HOME: runtimeHome };
8881
8950
  }
8882
- const agentSshKey = resolve31(runtimeHome, ".ssh", "rig-agent-key");
8951
+ const agentSshKey = resolve32(runtimeHome, ".ssh", "rig-agent-key");
8883
8952
  const sshParts = [
8884
8953
  "ssh",
8885
8954
  `-o UserKnownHostsFile="${knownHostsPath}"`,
8886
8955
  "-o StrictHostKeyChecking=yes",
8887
8956
  "-F /dev/null"
8888
8957
  ];
8889
- if (existsSync28(agentSshKey)) {
8958
+ if (existsSync30(agentSshKey)) {
8890
8959
  sshParts.splice(1, 0, `-i "${agentSshKey}"`, "-o IdentitiesOnly=yes");
8891
8960
  }
8892
8961
  return {
@@ -8896,24 +8965,24 @@ function resolveRuntimeGitEnv() {
8896
8965
  }
8897
8966
  function inferRuntimeRootFromWorkspace(cwd) {
8898
8967
  const contextPath = findRuntimeContextFile3(cwd);
8899
- if (!contextPath || !existsSync28(contextPath)) {
8968
+ if (!contextPath || !existsSync30(contextPath)) {
8900
8969
  return "";
8901
8970
  }
8902
8971
  try {
8903
8972
  loadRuntimeContext(contextPath);
8904
- return resolve31(contextPath, "..");
8973
+ return resolve32(contextPath, "..");
8905
8974
  } catch {
8906
8975
  return "";
8907
8976
  }
8908
8977
  }
8909
8978
  function findRuntimeContextFile3(startPath) {
8910
- let current = resolve31(startPath);
8979
+ let current = resolve32(startPath);
8911
8980
  while (true) {
8912
- const candidate = resolve31(current, "runtime-context.json");
8913
- if (existsSync28(candidate)) {
8981
+ const candidate = resolve32(current, "runtime-context.json");
8982
+ if (existsSync30(candidate)) {
8914
8983
  return candidate;
8915
8984
  }
8916
- const parent = resolve31(current, "..");
8985
+ const parent = resolve32(current, "..");
8917
8986
  if (parent === current) {
8918
8987
  return "";
8919
8988
  }
@@ -8935,7 +9004,7 @@ var BAKED_STATUS_OUTPUT2 = BUILD_CONFIG3.AGENT_STATUS_OUTPUT ?? "";
8935
9004
  var BAKED_GIT_BRANCH = BUILD_CONFIG3.AGENT_GIT_BRANCH ?? "";
8936
9005
  var BAKED_BASE_COMMIT = BUILD_CONFIG3.AGENT_BASE_COMMIT ?? "";
8937
9006
  if (BAKED_BINARY_PATH) {
8938
- const binaryDir = dirname17(BAKED_BINARY_PATH);
9007
+ const binaryDir = dirname18(BAKED_BINARY_PATH);
8939
9008
  const currentPath = process.env.PATH || "";
8940
9009
  const pathEntries = currentPath.split(":").filter(Boolean);
8941
9010
  if (!pathEntries.includes(binaryDir)) {
@@ -8967,7 +9036,7 @@ function getEventBus() {
8967
9036
  }
8968
9037
  function inferRuntimeContext() {
8969
9038
  for (const candidate of runtimeContextCandidates()) {
8970
- if (!candidate || !existsSync29(candidate)) {
9039
+ if (!candidate || !existsSync31(candidate)) {
8971
9040
  continue;
8972
9041
  }
8973
9042
  try {
@@ -8980,15 +9049,15 @@ function inferRuntimeContext() {
8980
9049
  function runtimeContextCandidates() {
8981
9050
  const cwd = process.cwd();
8982
9051
  const candidates = [
8983
- resolve32(cwd, "..", "runtime-context.json"),
8984
- resolve32(cwd, ".rig", "runtime-context.json")
9052
+ resolve33(cwd, "..", "runtime-context.json"),
9053
+ resolve33(cwd, ".rig", "runtime-context.json")
8985
9054
  ];
8986
9055
  const argv1 = process.argv[1]?.trim();
8987
9056
  if (argv1) {
8988
- candidates.push(resolve32(argv1, "..", "..", "runtime-context.json"));
9057
+ candidates.push(resolve33(argv1, "..", "..", "runtime-context.json"));
8989
9058
  }
8990
9059
  if (BAKED_BINARY_PATH) {
8991
- candidates.push(resolve32(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
9060
+ candidates.push(resolve33(BAKED_BINARY_PATH, "..", "..", "runtime-context.json"));
8992
9061
  }
8993
9062
  return Array.from(new Set(candidates));
8994
9063
  }
@@ -9003,12 +9072,12 @@ var GITHUB_KNOWN_HOSTS = [
9003
9072
  "github.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCj7ndNxQowgcQnjshcLrqPEiiphnt+VTTvDP6mHBL9j1aNUkY4Ue1gvwnGLVlOhGeYrnZaMgRK6+PKCUXaDbC7qtbW8gIkhL7aGCsOr/C56SJMy/BCZfxd1nWzAOxSDPgVsmerOBYfNqltV9/hWCqBywINIR+5dIg6JTJ72pcEpEjcYgXkE2YEFXV1JHnsKgbLWNlhScqb2UmyRkQyytRLtL+38TGxkxCflmO+5Z8CSSNY7GidjMIZ7Q4zMjA2n1nGrlTDkzwDCsw+wqFPGQA179cnfGWOWRVruj16z6XyvxvjJwbz0wQZ75XK5tKSb7FNyeIEs4TT4jk+S4dhPeAUC5y+bDYirYgM4GC7uEnztnZyaVWQ7B381AK4Qdrwt51ZqExKbQpTUNn+EjqoTwvqNj4kqx5QUCI0ThS/YkOxJCXmPUWZbhjpCg56i+2aB6CmK2JGhn57K5mj0MNdBXA4/WnwH6XoPWJzK5Nyu2zB3nAZp+S5hpQs+p1vN1/wsjk="
9004
9073
  ];
9005
9074
  function ensureRuntimeKnownHosts(runtimeHome) {
9006
- const sshDir = resolve32(runtimeHome, ".ssh");
9007
- const knownHostsPath = resolve32(sshDir, "known_hosts");
9008
- if (!existsSync29(sshDir)) {
9009
- mkdirSync17(sshDir, { recursive: true });
9075
+ const sshDir = resolve33(runtimeHome, ".ssh");
9076
+ const knownHostsPath = resolve33(sshDir, "known_hosts");
9077
+ if (!existsSync31(sshDir)) {
9078
+ mkdirSync18(sshDir, { recursive: true });
9010
9079
  }
9011
- const existing = existsSync29(knownHostsPath) ? readFileSync17(knownHostsPath, "utf-8") : "";
9080
+ const existing = existsSync31(knownHostsPath) ? readFileSync18(knownHostsPath, "utf-8") : "";
9012
9081
  const existingLines = new Set(existing.split(/\r?\n/).map((line) => line.trim()).filter(Boolean));
9013
9082
  const missing = GITHUB_KNOWN_HOSTS.filter((line) => !existingLines.has(line));
9014
9083
  if (missing.length === 0) {
@@ -9018,11 +9087,11 @@ function ensureRuntimeKnownHosts(runtimeHome) {
9018
9087
  for (const line of missing) {
9019
9088
  existingLines.add(line);
9020
9089
  }
9021
- writeFileSync15(knownHostsPath, `${Array.from(existingLines).join(`
9090
+ writeFileSync16(knownHostsPath, `${Array.from(existingLines).join(`
9022
9091
  `)}
9023
9092
  `, { mode: 420 });
9024
9093
  } catch (err) {
9025
- const hint = existsSync29(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
9094
+ const hint = existsSync31(knownHostsPath) ? "" : " \u2014 known_hosts is missing; git SSH operations may fail";
9026
9095
  console.warn(`[rig-agent] Could not update ${knownHostsPath}: ${err instanceof Error ? err.message : String(err)}${hint}`);
9027
9096
  }
9028
9097
  return knownHostsPath;
@@ -9036,13 +9105,13 @@ function hydrateRuntimeProcessEnv(ctx) {
9036
9105
  return;
9037
9106
  }
9038
9107
  process.env.RIG_RUNTIME_CONTEXT_FILE = contextFile;
9039
- const runtimeRoot = dirname17(resolve32(contextFile));
9040
- const runtimeHome = resolve32(runtimeRoot, "home");
9041
- const runtimeTmp = resolve32(runtimeRoot, "tmp");
9042
- const runtimeCache = resolve32(runtimeRoot, "cache");
9043
- const runtimeBin = resolve32(runtimeRoot, "bin");
9044
- const runtimeWorkspaceBin = resolve32(ctx.workspaceDir, ".rig", "bin");
9045
- const runtimeTools = resolve32(ctx.workspaceDir, "rig", "tools");
9108
+ const runtimeRoot = dirname18(resolve33(contextFile));
9109
+ const runtimeHome = resolve33(runtimeRoot, "home");
9110
+ const runtimeTmp = resolve33(runtimeRoot, "tmp");
9111
+ const runtimeCache = resolve33(runtimeRoot, "cache");
9112
+ const runtimeBin = resolve33(runtimeRoot, "bin");
9113
+ const runtimeWorkspaceBin = resolve33(ctx.workspaceDir, ".rig", "bin");
9114
+ const runtimeTools = resolve33(ctx.workspaceDir, "rig", "tools");
9046
9115
  if (ctx.hostProjectRoot) {
9047
9116
  process.env.PROJECT_RIG_ROOT = ctx.hostProjectRoot;
9048
9117
  }
@@ -9058,13 +9127,13 @@ function hydrateRuntimeProcessEnv(ctx) {
9058
9127
  for (const [key, value] of Object.entries(browserEnvFromContext(ctx.browser))) {
9059
9128
  process.env[key] = value;
9060
9129
  }
9061
- if (existsSync29(runtimeHome)) {
9130
+ if (existsSync31(runtimeHome)) {
9062
9131
  process.env.HOME = runtimeHome;
9063
9132
  }
9064
- if (existsSync29(runtimeTmp)) {
9133
+ if (existsSync31(runtimeTmp)) {
9065
9134
  process.env.TMPDIR = runtimeTmp;
9066
9135
  }
9067
- if (existsSync29(runtimeCache)) {
9136
+ if (existsSync31(runtimeCache)) {
9068
9137
  process.env.XDG_CACHE_HOME = runtimeCache;
9069
9138
  }
9070
9139
  const workspaceSecrets = loadDotEnvSecrets(ctx.workspaceDir, process.env);
@@ -9090,31 +9159,31 @@ function hydrateRuntimeProcessEnv(ctx) {
9090
9159
  const currentPath = process.env.PATH || "";
9091
9160
  const pathEntries = currentPath.split(":").filter(Boolean);
9092
9161
  for (const entry of [runtimeBin, runtimeWorkspaceBin, runtimeTools, "/usr/bin", "/bin", "/usr/sbin", "/sbin"]) {
9093
- if (existsSync29(entry) && !pathEntries.includes(entry)) {
9162
+ if (existsSync31(entry) && !pathEntries.includes(entry)) {
9094
9163
  pathEntries.unshift(entry);
9095
9164
  }
9096
9165
  }
9097
9166
  process.env.PATH = pathEntries.join(":");
9098
9167
  if (!process.env.RIG_GIT_BIN) {
9099
- const runtimeGit = resolve32(runtimeBin, "git");
9100
- process.env.RIG_GIT_BIN = existsSync29(runtimeGit) ? runtimeGit : Bun.which("git") || "/usr/bin/git";
9168
+ const runtimeGit = resolve33(runtimeBin, "git");
9169
+ process.env.RIG_GIT_BIN = existsSync31(runtimeGit) ? runtimeGit : Bun.which("git") || "/usr/bin/git";
9101
9170
  }
9102
9171
  const knownHosts = ensureRuntimeKnownHosts(runtimeHome);
9103
- const agentKey = resolve32(runtimeHome, ".ssh", "rig-agent-key");
9172
+ const agentKey = resolve33(runtimeHome, ".ssh", "rig-agent-key");
9104
9173
  const sshParts = [
9105
9174
  "ssh",
9106
9175
  `-o UserKnownHostsFile="${knownHosts}"`,
9107
9176
  "-o StrictHostKeyChecking=yes",
9108
9177
  "-F /dev/null"
9109
9178
  ];
9110
- if (existsSync29(agentKey)) {
9179
+ if (existsSync31(agentKey)) {
9111
9180
  sshParts.splice(1, 0, `-i "${agentKey}"`, "-o IdentitiesOnly=yes");
9112
9181
  }
9113
9182
  process.env.GIT_SSH_COMMAND = sshParts.join(" ");
9114
9183
  }
9115
9184
  function inferRuntimeContextFileFromWorkspace(workspaceDir) {
9116
- const candidate = resolve32(workspaceDir, "..", "runtime-context.json");
9117
- return existsSync29(candidate) ? candidate : "";
9185
+ const candidate = resolve33(workspaceDir, "..", "runtime-context.json");
9186
+ return existsSync31(candidate) ? candidate : "";
9118
9187
  }
9119
9188
  async function main() {
9120
9189
  const args = process.argv.slice(2);
@@ -9239,7 +9308,7 @@ async function runAgentCommand(args) {
9239
9308
  const fileIdx = rest.indexOf("--file");
9240
9309
  const inputFile = fileIdx !== -1 ? rest[fileIdx + 1] : undefined;
9241
9310
  if (inputFile) {
9242
- content = readFileSync17(resolve32(projectRoot, inputFile), "utf-8");
9311
+ content = readFileSync18(resolve33(projectRoot, inputFile), "utf-8");
9243
9312
  } else {
9244
9313
  const chunks = [];
9245
9314
  for await (const chunk of process.stdin) {
@@ -9542,8 +9611,8 @@ WORKFLOW:
9542
9611
  `);
9543
9612
  }
9544
9613
  async function runCompletionVerification(projectRoot) {
9545
- const hookPath = resolve32(projectRoot, ".rig/bin/hooks/completion-verification");
9546
- if (!existsSync29(hookPath)) {
9614
+ const hookPath = resolve33(projectRoot, ".rig/bin/hooks/completion-verification");
9615
+ if (!existsSync31(hookPath)) {
9547
9616
  console.error(`[rig-agent] completion-verification hook binary not found: ${hookPath}`);
9548
9617
  return 1;
9549
9618
  }
@@ -9577,7 +9646,7 @@ async function verifyRuntimeManifest() {
9577
9646
  if (!manifestPath) {
9578
9647
  return;
9579
9648
  }
9580
- if (!existsSync29(manifestPath)) {
9649
+ if (!existsSync31(manifestPath)) {
9581
9650
  throw new Error(`[rig-agent] Runtime manifest missing: ${manifestPath}`);
9582
9651
  }
9583
9652
  let manifest;
@@ -9594,10 +9663,10 @@ async function verifyRuntimeManifest() {
9594
9663
  if (!manifestBinaryPath || !expectedHash) {
9595
9664
  throw new Error(`[rig-agent] Runtime manifest is missing binary hash data (${manifestPath}).`);
9596
9665
  }
9597
- if (!existsSync29(manifestBinaryPath)) {
9666
+ if (!existsSync31(manifestBinaryPath)) {
9598
9667
  throw new Error(`[rig-agent] Runtime binary not found at ${manifestBinaryPath}.`);
9599
9668
  }
9600
- const actualHash = sha256Hex(readFileSync17(resolve32(manifestBinaryPath)));
9669
+ const actualHash = sha256Hex(readFileSync18(resolve33(manifestBinaryPath)));
9601
9670
  if (actualHash !== expectedHash) {
9602
9671
  throw new Error(`[rig-agent] Runtime manifest mismatch for binary hash.
9603
9672
  ` + `expected=${expectedHash}