@osfactory/har 1.14.1 → 1.14.2

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 (2) hide show
  1. package/dist/index.js +658 -583
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -35872,6 +35872,20 @@ function resolveMainWorkingTree(cwd) {
35872
35872
  }
35873
35873
  return path7.resolve(toplevel);
35874
35874
  }
35875
+ function listLinkedWorktrees(cwd) {
35876
+ const porcelain = tryGit(cwd, "worktree list --porcelain");
35877
+ if (!porcelain) return [];
35878
+ const main = resolveMainWorkingTree(cwd);
35879
+ const mainResolved = main ? path7.resolve(main) : void 0;
35880
+ const paths = [];
35881
+ for (const line of porcelain.split("\n")) {
35882
+ if (!line.startsWith("worktree ")) continue;
35883
+ const worktree = path7.resolve(line.slice("worktree ".length));
35884
+ if (mainResolved && worktree === mainResolved) continue;
35885
+ paths.push(worktree);
35886
+ }
35887
+ return paths;
35888
+ }
35875
35889
  function canonicalizeControlRepoPath(repoPath) {
35876
35890
  const resolved = path7.resolve(repoPath);
35877
35891
  const toplevel = tryGit(resolved, "rev-parse --show-toplevel");
@@ -37467,13 +37481,55 @@ var init_work_units = __esm({
37467
37481
  // src/core/sync-sources.ts
37468
37482
  function resolveSyncSourcePaths(canonicalPath, workspacePath) {
37469
37483
  const canonical = path18.resolve(canonicalPath);
37470
- if (!workspacePath) return [canonical];
37471
- const workspace = path18.resolve(workspacePath);
37472
- if (workspace === canonical) return [canonical];
37473
- const canonicalRoot = resolveHarnessRoot(canonical);
37474
- const workspaceRoot = resolveHarnessRoot(workspace);
37475
- if (path18.resolve(canonicalRoot) === path18.resolve(workspaceRoot)) return [canonical];
37476
- return [canonical, workspace];
37484
+ const paths = [canonical];
37485
+ const seenRoots = /* @__PURE__ */ new Set([path18.resolve(resolveHarnessRoot(canonical))]);
37486
+ const add = (candidate) => {
37487
+ const resolved = path18.resolve(candidate);
37488
+ const root = path18.resolve(resolveHarnessRoot(resolved));
37489
+ if (seenRoots.has(root)) return;
37490
+ seenRoots.add(root);
37491
+ paths.push(resolved);
37492
+ };
37493
+ if (workspacePath) add(workspacePath);
37494
+ for (const worktree of listLinkedWorktrees(canonical)) {
37495
+ if (hasHarnessEvidence(worktree)) add(worktree);
37496
+ }
37497
+ return paths;
37498
+ }
37499
+ function hasHarnessEvidence(repoPath) {
37500
+ const root = resolveHarnessRoot(repoPath);
37501
+ const harDir = path18.join(root, DEFAULT_HAR_DIR);
37502
+ if (!fs18.existsSync(harDir)) return false;
37503
+ for (const sub of EVIDENCE_SUBDIRS) {
37504
+ const dir = path18.join(harDir, sub);
37505
+ if (!fs18.existsSync(dir)) continue;
37506
+ try {
37507
+ if (fs18.readdirSync(dir).length > 0) return true;
37508
+ } catch {
37509
+ continue;
37510
+ }
37511
+ }
37512
+ return false;
37513
+ }
37514
+ function mergeSlotStatuses(groups) {
37515
+ const byId = /* @__PURE__ */ new Map();
37516
+ for (const group of groups) {
37517
+ for (const slot of group) {
37518
+ const existing = byId.get(slot.agentId);
37519
+ byId.set(slot.agentId, existing ? preferSlotStatus(existing, slot) : slot);
37520
+ }
37521
+ }
37522
+ return [...byId.values()].sort((a, b2) => a.agentId - b2.agentId);
37523
+ }
37524
+ function preferSlotStatus(a, b2) {
37525
+ if (a.active !== b2.active) return a.active ? a : b2;
37526
+ const aCreated = a.sessionCreatedAt ?? "";
37527
+ const bCreated = b2.sessionCreatedAt ?? "";
37528
+ if (aCreated !== bCreated) return aCreated >= bCreated ? a : b2;
37529
+ const aRun = a.lastRunAt ?? "";
37530
+ const bRun = b2.lastRunAt ?? "";
37531
+ if (aRun !== bRun) return aRun >= bRun ? a : b2;
37532
+ return a;
37477
37533
  }
37478
37534
  function mergeById(groups, id) {
37479
37535
  const seen = /* @__PURE__ */ new Map();
@@ -37537,16 +37593,19 @@ function collectCommitBindingsForSync(sourcePaths) {
37537
37593
  (record2) => record2.bindingId
37538
37594
  );
37539
37595
  }
37540
- var path18;
37596
+ var fs18, path18, EVIDENCE_SUBDIRS;
37541
37597
  var init_sync_sources = __esm({
37542
37598
  "src/core/sync-sources.ts"() {
37543
37599
  "use strict";
37600
+ fs18 = __toESM(require("fs"));
37544
37601
  path18 = __toESM(require("path"));
37545
37602
  init_manifest();
37546
37603
  init_commit_bindings();
37604
+ init_control_repo_path();
37547
37605
  init_runs();
37548
37606
  init_validations();
37549
37607
  init_work_units();
37608
+ EVIDENCE_SUBDIRS = ["slots", "runs", "work-units", "validations"];
37550
37609
  }
37551
37610
  });
37552
37611
 
@@ -37689,18 +37748,18 @@ function spawnResult(cmd, args, opts, shell) {
37689
37748
  proc.on("close", (code) => resolve70({ code: code ?? 1, stdout, stderr }));
37690
37749
  });
37691
37750
  }
37692
- var import_child_process4, fs18, path19, realSystemOps, defaultExec, stderrLog, realSleep;
37751
+ var import_child_process4, fs19, path19, realSystemOps, defaultExec, stderrLog, realSleep;
37693
37752
  var init_exec = __esm({
37694
37753
  "src/runtime/exec.ts"() {
37695
37754
  "use strict";
37696
37755
  import_child_process4 = require("child_process");
37697
- fs18 = __toESM(require("fs"));
37756
+ fs19 = __toESM(require("fs"));
37698
37757
  path19 = __toESM(require("path"));
37699
37758
  realSystemOps = {
37700
37759
  which(cmd) {
37701
37760
  if (cmd.includes("/")) {
37702
37761
  try {
37703
- fs18.accessSync(cmd, fs18.constants.X_OK);
37762
+ fs19.accessSync(cmd, fs19.constants.X_OK);
37704
37763
  return cmd;
37705
37764
  } catch {
37706
37765
  return null;
@@ -37710,8 +37769,8 @@ var init_exec = __esm({
37710
37769
  if (!dir) continue;
37711
37770
  const candidate = path19.join(dir, cmd);
37712
37771
  try {
37713
- fs18.accessSync(candidate, fs18.constants.X_OK);
37714
- if (fs18.statSync(candidate).isFile()) return candidate;
37772
+ fs19.accessSync(candidate, fs19.constants.X_OK);
37773
+ if (fs19.statSync(candidate).isFile()) return candidate;
37715
37774
  } catch {
37716
37775
  }
37717
37776
  }
@@ -37758,15 +37817,15 @@ function declaredNodePackageManager(dir, env3 = {}, _ops = realSystemOps) {
37758
37817
  const explicit = env3.HARNESS_NODE_PACKAGE_MANAGER;
37759
37818
  if (explicit) return explicit;
37760
37819
  const pkgPath = path20.join(dir, "package.json");
37761
- if (fs19.existsSync(pkgPath)) {
37762
- const raw = fs19.readFileSync(pkgPath, "utf8");
37820
+ if (fs20.existsSync(pkgPath)) {
37821
+ const raw = fs20.readFileSync(pkgPath, "utf8");
37763
37822
  const match = raw.match(/"packageManager"\s*:\s*"([a-z]*)@/);
37764
37823
  if (match && match[1]) return match[1];
37765
37824
  }
37766
- if (fs19.existsSync(path20.join(dir, "bun.lock")) || fs19.existsSync(path20.join(dir, "bun.lockb"))) return "bun";
37767
- if (fs19.existsSync(path20.join(dir, "pnpm-lock.yaml"))) return "pnpm";
37768
- if (fs19.existsSync(path20.join(dir, "yarn.lock"))) return "yarn";
37769
- if (fs19.existsSync(path20.join(dir, "package-lock.json"))) return "npm";
37825
+ if (fs20.existsSync(path20.join(dir, "bun.lock")) || fs20.existsSync(path20.join(dir, "bun.lockb"))) return "bun";
37826
+ if (fs20.existsSync(path20.join(dir, "pnpm-lock.yaml"))) return "pnpm";
37827
+ if (fs20.existsSync(path20.join(dir, "yarn.lock"))) return "yarn";
37828
+ if (fs20.existsSync(path20.join(dir, "package-lock.json"))) return "npm";
37770
37829
  return "";
37771
37830
  }
37772
37831
  function nodePackageManager(dir, env3 = {}, ops = realSystemOps) {
@@ -37794,11 +37853,11 @@ function nodeLockfile(manager) {
37794
37853
  async function nodeInstall(dir, manager, declared = "", ops = realSystemOps) {
37795
37854
  const substituting = declared !== "" && declared !== manager;
37796
37855
  const lockfile = substituting ? nodeLockfile(manager) : "";
37797
- const hadLockfile = lockfile !== "" && fs19.existsSync(path20.join(dir, lockfile));
37856
+ const hadLockfile = lockfile !== "" && fs20.existsSync(path20.join(dir, lockfile));
37798
37857
  const result = await ops.run(manager, ["install", "--silent"], { cwd: dir, stream: true });
37799
37858
  if (substituting && !hadLockfile && lockfile !== "") {
37800
- fs19.rmSync(path20.join(dir, lockfile), { force: true });
37801
- if (manager === "bun") fs19.rmSync(path20.join(dir, "bun.lockb"), { force: true });
37859
+ fs20.rmSync(path20.join(dir, lockfile), { force: true });
37860
+ if (manager === "bun") fs20.rmSync(path20.join(dir, "bun.lockb"), { force: true });
37802
37861
  }
37803
37862
  return result.code;
37804
37863
  }
@@ -37818,11 +37877,11 @@ function pkgExec(manager, env3 = {}, ops = realSystemOps) {
37818
37877
  if (ops.which("pnpm")) return "pnpm dlx";
37819
37878
  return "npx --yes";
37820
37879
  }
37821
- var fs19, path20, NODE_PACKAGE_MANAGERS;
37880
+ var fs20, path20, NODE_PACKAGE_MANAGERS;
37822
37881
  var init_node_pm = __esm({
37823
37882
  "src/runtime/node-pm.ts"() {
37824
37883
  "use strict";
37825
- fs19 = __toESM(require("fs"));
37884
+ fs20 = __toESM(require("fs"));
37826
37885
  path20 = __toESM(require("path"));
37827
37886
  init_exec();
37828
37887
  NODE_PACKAGE_MANAGERS = ["npm", "bun", "pnpm", "yarn"];
@@ -37836,15 +37895,15 @@ function quoteEnvValue(value) {
37836
37895
  return `'${value.replace(/'/g, `'\\''`)}'`;
37837
37896
  }
37838
37897
  function toolchainReady(workDir) {
37839
- if (fs20.existsSync(path21.join(workDir, "package.json")) && fs20.existsSync(path21.join(workDir, "node_modules"))) {
37898
+ if (fs21.existsSync(path21.join(workDir, "package.json")) && fs21.existsSync(path21.join(workDir, "node_modules"))) {
37840
37899
  return true;
37841
37900
  }
37842
- return fs20.existsSync(path21.join(workDir, ".har", "venv"));
37901
+ return fs21.existsSync(path21.join(workDir, ".har", "venv"));
37843
37902
  }
37844
37903
  function detectEcosystem(dir, env3 = {}) {
37845
37904
  const configured = env3.HARNESS_ECOSYSTEM ?? "auto";
37846
37905
  if (configured && configured !== "auto") return configured;
37847
- const has = (name) => fs20.existsSync(path21.join(dir, name));
37906
+ const has = (name) => fs21.existsSync(path21.join(dir, name));
37848
37907
  if (has("package.json")) return "node";
37849
37908
  if (has("pyproject.toml") || has("setup.py") || has("setup.cfg") || has("requirements.txt") || has("Pipfile")) {
37850
37909
  return "python";
@@ -37877,22 +37936,22 @@ function pythonRequiresMinimum(spec) {
37877
37936
  }
37878
37937
  function pythonReadDotVersion(dir) {
37879
37938
  const file = path21.join(dir, ".python-version");
37880
- if (!fs20.existsSync(file)) return null;
37881
- const first = fs20.readFileSync(file, "utf8").split("\n")[0].replace(/\s/g, "");
37939
+ if (!fs21.existsSync(file)) return null;
37940
+ const first = fs21.readFileSync(file, "utf8").split("\n")[0].replace(/\s/g, "");
37882
37941
  return first || null;
37883
37942
  }
37884
37943
  function pythonReadRequiresSpec(dir) {
37885
37944
  const pyproject = path21.join(dir, "pyproject.toml");
37886
- if (fs20.existsSync(pyproject)) {
37887
- for (const line of fs20.readFileSync(pyproject, "utf8").split("\n")) {
37945
+ if (fs21.existsSync(pyproject)) {
37946
+ for (const line of fs21.readFileSync(pyproject, "utf8").split("\n")) {
37888
37947
  const m = line.match(/^\s*requires-python\s*=\s*"([^"]*)"/);
37889
37948
  if (m) return m[1];
37890
37949
  }
37891
37950
  }
37892
37951
  const setupCfg = path21.join(dir, "setup.cfg");
37893
- if (fs20.existsSync(setupCfg)) {
37952
+ if (fs21.existsSync(setupCfg)) {
37894
37953
  let inOptions = false;
37895
- for (const line of fs20.readFileSync(setupCfg, "utf8").split("\n")) {
37954
+ for (const line of fs21.readFileSync(setupCfg, "utf8").split("\n")) {
37896
37955
  if (/^\[options\]/.test(line)) {
37897
37956
  inOptions = true;
37898
37957
  continue;
@@ -37916,10 +37975,10 @@ function pythonProjectMinimum(dir) {
37916
37975
  return reqMin ?? dotVer;
37917
37976
  }
37918
37977
  function pythonIsUvProject(dir) {
37919
- if (fs20.existsSync(path21.join(dir, "uv.lock"))) return true;
37978
+ if (fs21.existsSync(path21.join(dir, "uv.lock"))) return true;
37920
37979
  const pyproject = path21.join(dir, "pyproject.toml");
37921
- if (!fs20.existsSync(pyproject)) return false;
37922
- return /^\[tool\.uv\]/m.test(fs20.readFileSync(pyproject, "utf8"));
37980
+ if (!fs21.existsSync(pyproject)) return false;
37981
+ return /^\[tool\.uv\]/m.test(fs21.readFileSync(pyproject, "utf8"));
37923
37982
  }
37924
37983
  function iosFindProjectFile(dir, suffix) {
37925
37984
  const matches = [];
@@ -37927,7 +37986,7 @@ function iosFindProjectFile(dir, suffix) {
37927
37986
  const abs = rel ? path21.join(dir, rel) : dir;
37928
37987
  let entries;
37929
37988
  try {
37930
- entries = fs20.readdirSync(abs, { withFileTypes: true });
37989
+ entries = fs21.readdirSync(abs, { withFileTypes: true });
37931
37990
  } catch {
37932
37991
  return;
37933
37992
  }
@@ -37950,15 +38009,15 @@ function iosHasProject(dir, env3) {
37950
38009
  const workspace = env3.HARNESS_XCODE_WORKSPACE;
37951
38010
  const project = env3.HARNESS_XCODE_PROJECT;
37952
38011
  if (workspace || project) {
37953
- if (workspace && fs20.existsSync(path21.join(dir, workspace))) return true;
37954
- if (project && fs20.existsSync(path21.join(dir, project))) return true;
38012
+ if (workspace && fs21.existsSync(path21.join(dir, workspace))) return true;
38013
+ if (project && fs21.existsSync(path21.join(dir, project))) return true;
37955
38014
  return false;
37956
38015
  }
37957
38016
  if (iosFindProjectFile(dir, ".xcworkspace")) return true;
37958
38017
  return iosFindProjectFile(dir, ".xcodeproj") !== null;
37959
38018
  }
37960
38019
  function iosProjectGenerator(dir) {
37961
- const has = (name) => fs20.existsSync(path21.join(dir, name));
38020
+ const has = (name) => fs21.existsSync(path21.join(dir, name));
37962
38021
  if (has("Project.swift") || has("Workspace.swift")) return "tuist";
37963
38022
  if (has("project.yml") || has("project.yaml")) return "xcodegen";
37964
38023
  if (has("Podfile")) return "pod";
@@ -37967,11 +38026,11 @@ function iosProjectGenerator(dir) {
37967
38026
  async function provisionToolchain(options) {
37968
38027
  return new Provisioner(options).provision();
37969
38028
  }
37970
- var fs20, path21, ProvisionError, Provisioner;
38029
+ var fs21, path21, ProvisionError, Provisioner;
37971
38030
  var init_provision = __esm({
37972
38031
  "src/runtime/provision.ts"() {
37973
38032
  "use strict";
37974
- fs20 = __toESM(require("fs"));
38033
+ fs21 = __toESM(require("fs"));
37975
38034
  path21 = __toESM(require("path"));
37976
38035
  init_exec();
37977
38036
  init_node_pm();
@@ -38003,11 +38062,11 @@ var init_provision = __esm({
38003
38062
  this.logFn(message);
38004
38063
  }
38005
38064
  appendEnv(key, value) {
38006
- fs20.appendFileSync(this.envFile, `${key}=${quoteEnvValue(value)}
38065
+ fs21.appendFileSync(this.envFile, `${key}=${quoteEnvValue(value)}
38007
38066
  `);
38008
38067
  }
38009
38068
  appendPathPrefix(prefix) {
38010
- if (!prefix || !fs20.existsSync(prefix)) return;
38069
+ if (!prefix || !fs21.existsSync(prefix)) return;
38011
38070
  this.appendEnv("PATH", `${prefix}:${process.env.PATH ?? ""}`);
38012
38071
  }
38013
38072
  /** Extra process env for subprocesses (venv activation is PATH + VIRTUAL_ENV). */
@@ -38075,7 +38134,7 @@ var init_provision = __esm({
38075
38134
  const found = await this.pythonUvFind(dir, minimum);
38076
38135
  if (executable(found)) return found;
38077
38136
  }
38078
- if (fs20.existsSync(path21.join(dir, ".python-version"))) {
38137
+ if (fs21.existsSync(path21.join(dir, ".python-version"))) {
38079
38138
  const found = await this.pythonUvFind(dir, pythonReadDotVersion(dir));
38080
38139
  if (executable(found)) return found;
38081
38140
  if (this.ops.which("pyenv")) {
@@ -38142,23 +38201,23 @@ var init_provision = __esm({
38142
38201
  }
38143
38202
  await this.pythonWarnIfBelowMinimum(interpreter, projectMin);
38144
38203
  const venvPython = path21.join(venvDir, "bin", "python");
38145
- if (fs20.existsSync(venvDir) && fs20.existsSync(venvPython) && projectMin) {
38204
+ if (fs21.existsSync(venvDir) && fs21.existsSync(venvPython) && projectMin) {
38146
38205
  const venvVer = await this.pythonVersionFromBin(venvPython);
38147
38206
  if (venvVer && !pythonVersionGe(venvVer, projectMin)) {
38148
38207
  this.log(`Existing venv Python ${venvVer} is older than required ${projectMin} \u2014 recreating...`);
38149
- fs20.rmSync(venvDir, { recursive: true, force: true });
38208
+ fs21.rmSync(venvDir, { recursive: true, force: true });
38150
38209
  }
38151
38210
  }
38152
- if (!fs20.existsSync(venvDir)) {
38211
+ if (!fs21.existsSync(venvDir)) {
38153
38212
  if (!await this.pythonCreateVenv(dir, venvDir, interpreter)) {
38154
- fs20.rmSync(venvDir, { recursive: true, force: true });
38213
+ fs21.rmSync(venvDir, { recursive: true, force: true });
38155
38214
  this.log("venv creation failed (on Debian/Ubuntu install python3-venv) \u2014 using resolved interpreter");
38156
38215
  this.appendEnv("HARNESS_ECOSYSTEM", "python");
38157
38216
  this.appendEnv("PYTHON_BIN", interpreter);
38158
38217
  return;
38159
38218
  }
38160
38219
  }
38161
- if (!fs20.existsSync(venvPython)) {
38220
+ if (!fs21.existsSync(venvPython)) {
38162
38221
  this.log(`Python venv at ${venvRel} is missing or broken \u2014 using resolved interpreter`);
38163
38222
  this.appendEnv("HARNESS_ECOSYSTEM", "python");
38164
38223
  this.appendEnv("PYTHON_BIN", interpreter);
@@ -38178,19 +38237,19 @@ var init_provision = __esm({
38178
38237
  quietStderr: quiet,
38179
38238
  stream: !quiet
38180
38239
  });
38181
- if (fs20.existsSync(path21.join(dir, "pyproject.toml"))) {
38240
+ if (fs21.existsSync(path21.join(dir, "pyproject.toml"))) {
38182
38241
  const dev = await pip(["install", "-q", "-e", ".[dev]"], true);
38183
38242
  if (dev.code !== 0) {
38184
38243
  const plain = await pip(["install", "-q", "-e", "."], false);
38185
38244
  if (plain.code !== 0) throw new ProvisionError("pip install -e . failed");
38186
38245
  }
38187
- } else if (fs20.existsSync(path21.join(dir, "requirements.txt"))) {
38246
+ } else if (fs21.existsSync(path21.join(dir, "requirements.txt"))) {
38188
38247
  const result = await pip(["install", "-q", "-r", "requirements.txt"], false);
38189
38248
  if (result.code !== 0) throw new ProvisionError("pip install -r requirements.txt failed");
38190
- } else if (fs20.existsSync(path21.join(dir, "setup.py")) || fs20.existsSync(path21.join(dir, "setup.cfg"))) {
38249
+ } else if (fs21.existsSync(path21.join(dir, "setup.py")) || fs21.existsSync(path21.join(dir, "setup.cfg"))) {
38191
38250
  const result = await pip(["install", "-q", "-e", "."], false);
38192
38251
  if (result.code !== 0) throw new ProvisionError("pip install -e . failed");
38193
- } else if (fs20.existsSync(path21.join(dir, "Pipfile")) && this.ops.which("pipenv")) {
38252
+ } else if (fs21.existsSync(path21.join(dir, "Pipfile")) && this.ops.which("pipenv")) {
38194
38253
  const result = await this.ops.run("pipenv", ["install", "--dev"], {
38195
38254
  cwd: dir,
38196
38255
  stream: true,
@@ -38250,7 +38309,7 @@ var init_provision = __esm({
38250
38309
  const mvn = this.ops.which("mvn");
38251
38310
  if (mvn) {
38252
38311
  this.appendEnv("MVN_BIN", mvn);
38253
- } else if (fs20.existsSync(path21.join(dir, "gradlew"))) {
38312
+ } else if (fs21.existsSync(path21.join(dir, "gradlew"))) {
38254
38313
  this.appendEnv("GRADLE_BIN", path21.join(dir, "gradlew"));
38255
38314
  } else {
38256
38315
  const gradle = this.ops.which("gradle");
@@ -38303,8 +38362,8 @@ var init_provision = __esm({
38303
38362
  }
38304
38363
  }
38305
38364
  async iosPodInstall(dir) {
38306
- if (!fs20.existsSync(path21.join(dir, "Podfile"))) return;
38307
- if (fs20.existsSync(path21.join(dir, "Pods"))) return;
38365
+ if (!fs21.existsSync(path21.join(dir, "Podfile"))) return;
38366
+ if (fs21.existsSync(path21.join(dir, "Pods"))) return;
38308
38367
  if (!this.ops.which("pod")) {
38309
38368
  this.log("ERROR: this repo uses CocoaPods (Podfile, no Pods/) and pod is not on PATH.");
38310
38369
  this.log(" Install CocoaPods, or set HARNESS_INSTALL_CMD in harness.env to provision the project another way.");
@@ -38330,8 +38389,8 @@ var init_provision = __esm({
38330
38389
  // ── monorepo root ──
38331
38390
  async provisionMonorepoRoot() {
38332
38391
  if (!this.relPrefix || !this.worktreeDir) return;
38333
- if (!fs20.existsSync(path21.join(this.worktreeDir, "package.json"))) return;
38334
- if (fs20.existsSync(path21.join(this.worktreeDir, "node_modules"))) return;
38392
+ if (!fs21.existsSync(path21.join(this.worktreeDir, "package.json"))) return;
38393
+ if (fs21.existsSync(path21.join(this.worktreeDir, "node_modules"))) return;
38335
38394
  const manager = nodePackageManager(this.worktreeDir, this.env, this.ops);
38336
38395
  this.log(`Installing monorepo root dependencies in ${this.worktreeDir} with ${manager}...`);
38337
38396
  const code = await nodeInstall(
@@ -38454,8 +38513,8 @@ function seedGitExclude(repoRoot, git2 = defaultGit) {
38454
38513
  if (!commonDir) return;
38455
38514
  const resolved = path22.isAbsolute(commonDir) ? commonDir : path22.resolve(repoRoot, commonDir);
38456
38515
  const excludeFile = path22.join(resolved, "info", "exclude");
38457
- if (!fs21.existsSync(path22.dirname(excludeFile))) return;
38458
- const existing = fs21.existsSync(excludeFile) ? fs21.readFileSync(excludeFile, "utf8") : "";
38516
+ if (!fs22.existsSync(path22.dirname(excludeFile))) return;
38517
+ const existing = fs22.existsSync(excludeFile) ? fs22.readFileSync(excludeFile, "utf8") : "";
38459
38518
  const lines = new Set(existing.split("\n"));
38460
38519
  let appended = "";
38461
38520
  for (const pattern of GIT_EXCLUDE_PATTERNS) {
@@ -38464,7 +38523,7 @@ function seedGitExclude(repoRoot, git2 = defaultGit) {
38464
38523
  }
38465
38524
  if (!appended) return;
38466
38525
  const prefix = existing && !existing.endsWith("\n") ? "\n" : "";
38467
- fs21.appendFileSync(excludeFile, prefix + appended);
38526
+ fs22.appendFileSync(excludeFile, prefix + appended);
38468
38527
  }
38469
38528
  function resolveResumeSession(repoPath, agentId) {
38470
38529
  const session = readSlotRegistry(repoPath, agentId);
@@ -38477,7 +38536,7 @@ function resolveResumeSession(repoPath, agentId) {
38477
38536
  };
38478
38537
  }
38479
38538
  const workDir = session?.workDir ?? "";
38480
- if (!workDir || !fs21.existsSync(workDir) || !fs21.statSync(workDir).isDirectory()) {
38539
+ if (!workDir || !fs22.existsSync(workDir) || !fs22.statSync(workDir).isDirectory()) {
38481
38540
  return {
38482
38541
  ok: false,
38483
38542
  code: "missing-work-dir",
@@ -38485,7 +38544,7 @@ function resolveResumeSession(repoPath, agentId) {
38485
38544
  };
38486
38545
  }
38487
38546
  const envFile = path22.join(workDir, `.env.agent.${agentId}`);
38488
- if (!fs21.existsSync(envFile)) {
38547
+ if (!fs22.existsSync(envFile)) {
38489
38548
  return {
38490
38549
  ok: false,
38491
38550
  code: "missing-env-file",
@@ -38517,7 +38576,7 @@ function removeSessionWorktree(options) {
38517
38576
  }
38518
38577
  const owned = options.mode === void 0 || options.mode === "worktree";
38519
38578
  if (!owned) {
38520
- if (worktreePath && fs21.existsSync(worktreePath) && options.mode === "external") {
38579
+ if (worktreePath && fs22.existsSync(worktreePath) && options.mode === "external") {
38521
38580
  result.preservedWorktree = worktreePath;
38522
38581
  }
38523
38582
  tryGit3(git2, ["worktree", "prune"], options.repoRoot);
@@ -38531,17 +38590,17 @@ function removeSessionWorktree(options) {
38531
38590
  }
38532
38591
  return result;
38533
38592
  }
38534
- if (worktreePath && fs21.existsSync(worktreePath)) {
38593
+ if (worktreePath && fs22.existsSync(worktreePath)) {
38535
38594
  for (const name of [
38536
38595
  `.env.agent.${options.agentId}`,
38537
38596
  `ecosystem.agent.${options.agentId}.config.cjs`
38538
38597
  ]) {
38539
- fs21.rmSync(path22.join(worktreePath, name), { force: true });
38598
+ fs22.rmSync(path22.join(worktreePath, name), { force: true });
38540
38599
  }
38541
38600
  try {
38542
38601
  git2(["worktree", "remove", worktreePath, "--force"], options.repoRoot);
38543
38602
  } catch {
38544
- fs21.rmSync(worktreePath, { recursive: true, force: true });
38603
+ fs22.rmSync(worktreePath, { recursive: true, force: true });
38545
38604
  }
38546
38605
  result.removedWorktree = worktreePath;
38547
38606
  }
@@ -38556,12 +38615,12 @@ function removeSessionWorktree(options) {
38556
38615
  }
38557
38616
  return result;
38558
38617
  }
38559
- var import_child_process5, fs21, os8, path22, crypto6, defaultGit, GIT_EXCLUDE_PATTERNS;
38618
+ var import_child_process5, fs22, os8, path22, crypto6, defaultGit, GIT_EXCLUDE_PATTERNS;
38560
38619
  var init_worktree = __esm({
38561
38620
  "src/runtime/worktree.ts"() {
38562
38621
  "use strict";
38563
38622
  import_child_process5 = require("child_process");
38564
- fs21 = __toESM(require("fs"));
38623
+ fs22 = __toESM(require("fs"));
38565
38624
  os8 = __toESM(require("os"));
38566
38625
  path22 = __toESM(require("path"));
38567
38626
  crypto6 = __toESM(require("crypto"));
@@ -38621,8 +38680,8 @@ function appendTelemetryEnvToFile(envFilePath, attrs) {
38621
38680
  ${TELEMETRY_MARKER_END}
38622
38681
  `;
38623
38682
  let existing = "";
38624
- if (fs22.existsSync(envFilePath)) {
38625
- existing = fs22.readFileSync(envFilePath, "utf8");
38683
+ if (fs23.existsSync(envFilePath)) {
38684
+ existing = fs23.readFileSync(envFilePath, "utf8");
38626
38685
  const start = existing.indexOf(TELEMETRY_MARKER_START);
38627
38686
  if (start >= 0) {
38628
38687
  const end = existing.indexOf(TELEMETRY_MARKER_END, start);
@@ -38633,15 +38692,15 @@ ${TELEMETRY_MARKER_END}
38633
38692
  }
38634
38693
  }
38635
38694
  }
38636
- fs22.mkdirSync(path23.dirname(envFilePath), { recursive: true });
38695
+ fs23.mkdirSync(path23.dirname(envFilePath), { recursive: true });
38637
38696
  const combined = (existing.replace(/\n+$/, "\n") + block).replace(/^\n+/, "");
38638
- fs22.writeFileSync(envFilePath, combined.endsWith("\n") ? combined : combined + "\n");
38697
+ fs23.writeFileSync(envFilePath, combined.endsWith("\n") ? combined : combined + "\n");
38639
38698
  }
38640
- var fs22, path23, TELEMETRY_MARKER_START, TELEMETRY_MARKER_END;
38699
+ var fs23, path23, TELEMETRY_MARKER_START, TELEMETRY_MARKER_END;
38641
38700
  var init_telemetry_env = __esm({
38642
38701
  "src/core/telemetry-env.ts"() {
38643
38702
  "use strict";
38644
- fs22 = __toESM(require("fs"));
38703
+ fs23 = __toESM(require("fs"));
38645
38704
  path23 = __toESM(require("path"));
38646
38705
  init_control_config();
38647
38706
  init_shell();
@@ -38665,8 +38724,8 @@ function substituteEnvTemplate(template, values) {
38665
38724
  }
38666
38725
  function generateAgentEnvFile(options) {
38667
38726
  const templatePath = options.templatePath ?? path24.join(options.harnessDir, "env.template");
38668
- if (!fs23.existsSync(templatePath)) return false;
38669
- const template = fs23.readFileSync(templatePath, "utf8");
38727
+ if (!fs24.existsSync(templatePath)) return false;
38728
+ const template = fs24.readFileSync(templatePath, "utf8");
38670
38729
  const v2 = options.values;
38671
38730
  const rendered = substituteEnvTemplate(template, {
38672
38731
  AGENT_ID: v2.agentId,
@@ -38678,8 +38737,8 @@ function generateAgentEnvFile(options) {
38678
38737
  BROWSER_PORT: v2.browserPort,
38679
38738
  REPO_ROOT: v2.repoRoot
38680
38739
  });
38681
- fs23.mkdirSync(path24.dirname(options.envFile), { recursive: true });
38682
- fs23.writeFileSync(options.envFile, rendered);
38740
+ fs24.mkdirSync(path24.dirname(options.envFile), { recursive: true });
38741
+ fs24.writeFileSync(options.envFile, rendered);
38683
38742
  return true;
38684
38743
  }
38685
38744
  function appendSessionTelemetry(options) {
@@ -38707,11 +38766,11 @@ function appendSessionTelemetry(options) {
38707
38766
  appendTelemetryEnvToFile(envFile, attrs);
38708
38767
  return envFile;
38709
38768
  }
38710
- var fs23, path24, AGENT_ENV_TEMPLATE_VARS;
38769
+ var fs24, path24, AGENT_ENV_TEMPLATE_VARS;
38711
38770
  var init_agent_env = __esm({
38712
38771
  "src/runtime/agent-env.ts"() {
38713
38772
  "use strict";
38714
- fs23 = __toESM(require("fs"));
38773
+ fs24 = __toESM(require("fs"));
38715
38774
  path24 = __toESM(require("path"));
38716
38775
  init_telemetry_env();
38717
38776
  init_slot_registry();
@@ -38736,20 +38795,20 @@ function resolveTemplatesDir() {
38736
38795
  path25.join(__dirname, "..", "harness", "templates")
38737
38796
  ];
38738
38797
  for (const dir of candidates) {
38739
- if (fs24.existsSync(path25.join(dir, "har-boilerplate"))) return dir;
38798
+ if (fs25.existsSync(path25.join(dir, "har-boilerplate"))) return dir;
38740
38799
  }
38741
38800
  throw new Error("Templates directory not found. Run npm run build.");
38742
38801
  }
38743
38802
  function resolveTemplateFile(name) {
38744
38803
  const dir = resolveTemplatesDir();
38745
38804
  const filePath = path25.join(dir, name);
38746
- return fs24.existsSync(filePath) ? filePath : null;
38805
+ return fs25.existsSync(filePath) ? filePath : null;
38747
38806
  }
38748
- var fs24, path25;
38807
+ var fs25, path25;
38749
38808
  var init_paths = __esm({
38750
38809
  "src/utils/paths.ts"() {
38751
38810
  "use strict";
38752
- fs24 = __toESM(require("fs"));
38811
+ fs25 = __toESM(require("fs"));
38753
38812
  path25 = __toESM(require("path"));
38754
38813
  }
38755
38814
  });
@@ -38761,10 +38820,10 @@ function templatesDirFor(options) {
38761
38820
  function readProfileManifest(profile, options) {
38762
38821
  const templates = templatesDirFor(options);
38763
38822
  const manifestPath = path26.join(templates, "profiles", profile, "profile.manifest.json");
38764
- if (!fs25.existsSync(manifestPath)) {
38823
+ if (!fs26.existsSync(manifestPath)) {
38765
38824
  throw new Error(`Profile manifest not found: ${manifestPath}. Run npm run build.`);
38766
38825
  }
38767
- const parsed = ProfileManifestSchema.safeParse(JSON.parse(fs25.readFileSync(manifestPath, "utf8")));
38826
+ const parsed = ProfileManifestSchema.safeParse(JSON.parse(fs26.readFileSync(manifestPath, "utf8")));
38768
38827
  if (!parsed.success) {
38769
38828
  throw new Error(`Invalid profile manifest for ${profile}: ${parsed.error.message}`);
38770
38829
  }
@@ -38782,7 +38841,7 @@ function readProfileCapabilities(profile, options) {
38782
38841
  }
38783
38842
  function resolveProfileBundleDir(bundle, options) {
38784
38843
  const dir = path26.join(templatesDirFor(options), bundle.path);
38785
- if (!fs25.existsSync(dir)) {
38844
+ if (!fs26.existsSync(dir)) {
38786
38845
  throw new Error(`Profile bundle not found: ${bundle.id} (${bundle.path}). Run npm run build.`);
38787
38846
  }
38788
38847
  return dir;
@@ -38801,21 +38860,21 @@ function renderProfileDoc(profile, docName, options) {
38801
38860
  const parts = sections.map((name) => {
38802
38861
  const profilePath = path26.join(templates, "profiles", profile, "docs", dir, `${name}.md`);
38803
38862
  const sharedPath = path26.join(templates, "shared-docs", dir, `${name}.md`);
38804
- const sectionPath = fs25.existsSync(profilePath) ? profilePath : sharedPath;
38805
- if (!fs25.existsSync(sectionPath)) {
38863
+ const sectionPath = fs26.existsSync(profilePath) ? profilePath : sharedPath;
38864
+ if (!fs26.existsSync(sectionPath)) {
38806
38865
  throw new Error(`Doc section not found for ${profile}/${docName}: ${name} (${sectionPath})`);
38807
38866
  }
38808
- return fs25.readFileSync(sectionPath, "utf8");
38867
+ return fs26.readFileSync(sectionPath, "utf8");
38809
38868
  });
38810
38869
  return parts.join("\n");
38811
38870
  }
38812
38871
  function readComposedTemplateContent(entry) {
38813
38872
  if (entry.content !== void 0) return entry.content;
38814
- return fs25.readFileSync(entry.sourcePath, "utf8");
38873
+ return fs26.readFileSync(entry.sourcePath, "utf8");
38815
38874
  }
38816
38875
  function walkTemplateFiles(dir, prefix = "") {
38817
38876
  const out = [];
38818
- for (const entry of fs25.readdirSync(dir, { withFileTypes: true })) {
38877
+ for (const entry of fs26.readdirSync(dir, { withFileTypes: true })) {
38819
38878
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
38820
38879
  if (entry.isDirectory()) {
38821
38880
  out.push(...walkTemplateFiles(path26.join(dir, entry.name), rel));
@@ -38844,11 +38903,11 @@ function composeProfileTemplateMap(profile, options) {
38844
38903
  }
38845
38904
  return map;
38846
38905
  }
38847
- var fs25, path26, ProfileBundleRefSchema, ProfileCapabilitiesSchema, ProfileManifestSchema;
38906
+ var fs26, path26, ProfileBundleRefSchema, ProfileCapabilitiesSchema, ProfileManifestSchema;
38848
38907
  var init_profiles = __esm({
38849
38908
  "src/harness/profiles.ts"() {
38850
38909
  "use strict";
38851
- fs25 = __toESM(require("fs"));
38910
+ fs26 = __toESM(require("fs"));
38852
38911
  path26 = __toESM(require("path"));
38853
38912
  init_zod();
38854
38913
  init_paths();
@@ -38905,13 +38964,13 @@ function harnessUsesPm2(repoPath) {
38905
38964
  const capabilities = harnessCapabilities(repoPath);
38906
38965
  if (capabilities) return capabilities.processManager === "pm2";
38907
38966
  const harnessRoot = resolveHarnessRoot(repoPath);
38908
- return fs26.existsSync(path27.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
38967
+ return fs27.existsSync(path27.join(harnessRoot, ".har", "ecosystem.agent.template.cjs"));
38909
38968
  }
38910
- var fs26, path27;
38969
+ var fs27, path27;
38911
38970
  var init_capabilities = __esm({
38912
38971
  "src/harness/capabilities.ts"() {
38913
38972
  "use strict";
38914
- fs26 = __toESM(require("fs"));
38973
+ fs27 = __toESM(require("fs"));
38915
38974
  path27 = __toESM(require("path"));
38916
38975
  init_manifest();
38917
38976
  init_env();
@@ -38922,7 +38981,7 @@ var init_capabilities = __esm({
38922
38981
  // src/core/slot-ports.ts
38923
38982
  function loadInfraState(harnessRoot, repoRoot) {
38924
38983
  let statePath = path28.join(harnessRoot, ".har", "state", "infra.env");
38925
- if (!fs27.existsSync(statePath) && repoRoot) {
38984
+ if (!fs28.existsSync(statePath) && repoRoot) {
38926
38985
  try {
38927
38986
  const commonDir = (0, import_child_process6.execSync)("git rev-parse --git-common-dir", {
38928
38987
  cwd: repoRoot,
@@ -38940,8 +38999,8 @@ function loadInfraState(harnessRoot, repoRoot) {
38940
38999
  } catch {
38941
39000
  }
38942
39001
  }
38943
- if (!fs27.existsSync(statePath)) return {};
38944
- return parseHarnessEnvSource(fs27.readFileSync(statePath, "utf8")).values;
39002
+ if (!fs28.existsSync(statePath)) return {};
39003
+ return parseHarnessEnvSource(fs28.readFileSync(statePath, "utf8")).values;
38945
39004
  }
38946
39005
  function portStep(env3) {
38947
39006
  return Number(env3.HARNESS_PORT_STEP ?? 10);
@@ -39008,12 +39067,12 @@ function allocateAppPorts(repoPath, agentId) {
39008
39067
  allocated: frontend !== feDefault || api !== apiDefault || debug !== debugDefault
39009
39068
  };
39010
39069
  }
39011
- var import_child_process6, fs27, path28;
39070
+ var import_child_process6, fs28, path28;
39012
39071
  var init_slot_ports = __esm({
39013
39072
  "src/core/slot-ports.ts"() {
39014
39073
  "use strict";
39015
39074
  import_child_process6 = require("child_process");
39016
- fs27 = __toESM(require("fs"));
39075
+ fs28 = __toESM(require("fs"));
39017
39076
  path28 = __toESM(require("path"));
39018
39077
  init_env();
39019
39078
  init_manifest();
@@ -39082,9 +39141,9 @@ function infraStatePath(harnessDir) {
39082
39141
  }
39083
39142
  function readInfraState(harnessDir) {
39084
39143
  const statePath = infraStatePath(harnessDir);
39085
- if (!fs28.existsSync(statePath)) return {};
39144
+ if (!fs29.existsSync(statePath)) return {};
39086
39145
  const ports = {};
39087
- for (const line of fs28.readFileSync(statePath, "utf8").split("\n")) {
39146
+ for (const line of fs29.readFileSync(statePath, "utf8").split("\n")) {
39088
39147
  const match = line.match(/^export\s+([A-Z_]+)=(\d+)\s*$/);
39089
39148
  if (match) ports[match[1]] = Number(match[2]);
39090
39149
  }
@@ -39092,8 +39151,8 @@ function readInfraState(harnessDir) {
39092
39151
  }
39093
39152
  function writeInfraState(harnessDir, ports) {
39094
39153
  const statePath = infraStatePath(harnessDir);
39095
- fs28.mkdirSync(path29.dirname(statePath), { recursive: true });
39096
- fs28.writeFileSync(
39154
+ fs29.mkdirSync(path29.dirname(statePath), { recursive: true });
39155
+ fs29.writeFileSync(
39097
39156
  statePath,
39098
39157
  `# Persisted by setup-infra.sh \u2014 host ports for shared docker compose services.
39099
39158
  export AGENT_DB_PORT=${ports.AGENT_DB_PORT}
@@ -39254,7 +39313,7 @@ async function setupInfra(options) {
39254
39313
  }
39255
39314
  }
39256
39315
  const sharedEcosystem = path29.join(harnessDir, "ecosystem.shared.config.cjs");
39257
- if (fs28.existsSync(sharedEcosystem)) {
39316
+ if (fs29.existsSync(sharedEcosystem)) {
39258
39317
  log("Starting shared app services from ecosystem.shared.config.cjs...");
39259
39318
  const [pkgCmd, ...pkgArgs] = pkgExecPrefix;
39260
39319
  exec(pkgCmd, [...pkgArgs, "pm2", "startOrReload", sharedEcosystem], { cwd: repoRoot });
@@ -39317,11 +39376,11 @@ async function removeMinioBucket(agentId, options) {
39317
39376
  const port = options.minioPort ?? 19e3;
39318
39377
  await request("DELETE", `http://localhost:${port}/agent-${agentId}?force=true`, "minioadmin:minioadmin");
39319
39378
  }
39320
- var fs28, path29, INFRA_LANES, defaultHttpRequest;
39379
+ var fs29, path29, INFRA_LANES, defaultHttpRequest;
39321
39380
  var init_infra = __esm({
39322
39381
  "src/runtime/infra.ts"() {
39323
39382
  "use strict";
39324
- fs28 = __toESM(require("fs"));
39383
+ fs29 = __toESM(require("fs"));
39325
39384
  path29 = __toESM(require("path"));
39326
39385
  init_slot_ports();
39327
39386
  init_exec();
@@ -39366,7 +39425,7 @@ function renderTemplate(template, vars) {
39366
39425
  );
39367
39426
  }
39368
39427
  function generateEcosystemConfig(options) {
39369
- const template = fs29.readFileSync(options.templatePath, "utf8");
39428
+ const template = fs30.readFileSync(options.templatePath, "utf8");
39370
39429
  const rendered = renderTemplate(template, {
39371
39430
  AGENT_ID: String(options.agentId),
39372
39431
  HARNESS_PROJECT_NAME: options.projectName,
@@ -39374,7 +39433,7 @@ function generateEcosystemConfig(options) {
39374
39433
  DEBUG_PORT: String(options.debugPort)
39375
39434
  });
39376
39435
  const configPath = path30.join(options.workDir, `ecosystem.agent.${options.agentId}.config.cjs`);
39377
- fs29.writeFileSync(configPath, rendered);
39436
+ fs30.writeFileSync(configPath, rendered);
39378
39437
  return configPath;
39379
39438
  }
39380
39439
  function pm2(args, options, cwd) {
@@ -39420,11 +39479,11 @@ async function waitForHealthCheck(options) {
39420
39479
  log(`Check logs: ./.har/agent-cli.sh ${agentId} logs`);
39421
39480
  return false;
39422
39481
  }
39423
- var fs29, path30, defaultHttpStatus;
39482
+ var fs30, path30, defaultHttpStatus;
39424
39483
  var init_process = __esm({
39425
39484
  "src/runtime/process.ts"() {
39426
39485
  "use strict";
39427
- fs29 = __toESM(require("fs"));
39486
+ fs30 = __toESM(require("fs"));
39428
39487
  path30 = __toESM(require("path"));
39429
39488
  init_exec();
39430
39489
  defaultHttpStatus = async (url) => {
@@ -39452,7 +39511,7 @@ function simSlug(value) {
39452
39511
  function repoDigest(repoRoot) {
39453
39512
  let resolved = repoRoot;
39454
39513
  try {
39455
- resolved = fs30.realpathSync(repoRoot);
39514
+ resolved = fs31.realpathSync(repoRoot);
39456
39515
  } catch {
39457
39516
  }
39458
39517
  return crypto7.createHash("sha1").update(resolved).digest("hex").slice(0, 6);
@@ -39473,7 +39532,7 @@ function claimFile(harnessDir, agentId) {
39473
39532
  }
39474
39533
  function writeClaim(harnessDir, agentId, udid, name, createdByHar, now = () => /* @__PURE__ */ new Date()) {
39475
39534
  const file = claimFile(harnessDir, agentId);
39476
- fs30.mkdirSync(path31.dirname(file), { recursive: true });
39535
+ fs31.mkdirSync(path31.dirname(file), { recursive: true });
39477
39536
  const claim = {
39478
39537
  agentId,
39479
39538
  udid,
@@ -39481,21 +39540,21 @@ function writeClaim(harnessDir, agentId, udid, name, createdByHar, now = () => /
39481
39540
  createdByHar,
39482
39541
  claimedAt: now().toISOString()
39483
39542
  };
39484
- fs30.writeFileSync(file, JSON.stringify(claim, null, 2) + "\n");
39543
+ fs31.writeFileSync(file, JSON.stringify(claim, null, 2) + "\n");
39485
39544
  }
39486
39545
  function readClaim(harnessDir, agentId) {
39487
39546
  const file = claimFile(harnessDir, agentId);
39488
- if (!fs30.existsSync(file)) return void 0;
39547
+ if (!fs31.existsSync(file)) return void 0;
39489
39548
  try {
39490
- return JSON.parse(fs30.readFileSync(file, "utf8"));
39549
+ return JSON.parse(fs31.readFileSync(file, "utf8"));
39491
39550
  } catch {
39492
39551
  return void 0;
39493
39552
  }
39494
39553
  }
39495
39554
  function claimOwnerOf(harnessDir, udid, selfAgentId, slotIsLive) {
39496
39555
  const dir = claimsDir(harnessDir);
39497
- if (!fs30.existsSync(dir)) return void 0;
39498
- for (const entry of fs30.readdirSync(dir)) {
39556
+ if (!fs31.existsSync(dir)) return void 0;
39557
+ for (const entry of fs31.readdirSync(dir)) {
39499
39558
  const match = entry.match(/^agent-(\d+)\.json$/);
39500
39559
  if (!match) continue;
39501
39560
  const id = Number(match[1]);
@@ -39697,7 +39756,7 @@ function releaseSimulator(ctx, stdout = (message) => process.stdout.write(`${mes
39697
39756
  const log = ctx.log ?? simLog;
39698
39757
  const claim = readClaim(ctx.harnessDir, ctx.agentId);
39699
39758
  if (claim) {
39700
- fs30.rmSync(claimFile(ctx.harnessDir, ctx.agentId), { force: true });
39759
+ fs31.rmSync(claimFile(ctx.harnessDir, ctx.agentId), { force: true });
39701
39760
  if (claim.createdByHar === true && claim.udid) {
39702
39761
  simctl.tryCall(["shutdown", claim.udid]);
39703
39762
  if (simctl.tryCall(["delete", claim.udid])) {
@@ -39710,12 +39769,12 @@ function releaseSimulator(ctx, stdout = (message) => process.stdout.write(`${mes
39710
39769
  }
39711
39770
  deleteDevicesWithPrefix(simctl, deviceLabelPrefix(ctx.env, ctx.repoRoot, ctx.agentId), log);
39712
39771
  }
39713
- var crypto7, fs30, path31, simLog, Simctl;
39772
+ var crypto7, fs31, path31, simLog, Simctl;
39714
39773
  var init_xcode_sim = __esm({
39715
39774
  "src/runtime/xcode-sim.ts"() {
39716
39775
  "use strict";
39717
39776
  crypto7 = __toESM(require("crypto"));
39718
- fs30 = __toESM(require("fs"));
39777
+ fs31 = __toESM(require("fs"));
39719
39778
  path31 = __toESM(require("path"));
39720
39779
  init_exec();
39721
39780
  simLog = (message) => process.stderr.write(`==> simulator: ${message}
@@ -39853,7 +39912,7 @@ function inspectControlUpReadiness(repoPath) {
39853
39912
  const control = controlContainerOnPort(containers, port);
39854
39913
  const warnings = [];
39855
39914
  const controlHarnessDir = path32.join(resolved, "control", ".har");
39856
- const harnessSlot1Active = fs31.existsSync(controlHarnessDir) && readSlotRegistry(path32.join(resolved, "control"), 1)?.status === "active";
39915
+ const harnessSlot1Active = fs32.existsSync(controlHarnessDir) && readSlotRegistry(path32.join(resolved, "control"), 1)?.status === "active";
39857
39916
  if (control) {
39858
39917
  return {
39859
39918
  warnings,
@@ -39882,12 +39941,12 @@ function inspectControlUpReadiness(repoPath) {
39882
39941
  harnessSlot1Active
39883
39942
  };
39884
39943
  }
39885
- var import_child_process7, fs31, path32;
39944
+ var import_child_process7, fs32, path32;
39886
39945
  var init_control_port = __esm({
39887
39946
  "src/core/control-port.ts"() {
39888
39947
  "use strict";
39889
39948
  import_child_process7 = require("child_process");
39890
- fs31 = __toESM(require("fs"));
39949
+ fs32 = __toESM(require("fs"));
39891
39950
  path32 = __toESM(require("path"));
39892
39951
  init_control_config();
39893
39952
  init_slot_registry();
@@ -39922,20 +39981,20 @@ function sameGitCheckout2(a, b2) {
39922
39981
  }
39923
39982
  function discoverWorktree(harnessRoot, agentId, projectName) {
39924
39983
  const session = readSlotRegistry(harnessRoot, agentId);
39925
- if (session?.worktreePath && fs32.existsSync(session.worktreePath)) {
39984
+ if (session?.worktreePath && fs33.existsSync(session.worktreePath)) {
39926
39985
  return session.worktreePath;
39927
39986
  }
39928
39987
  const legacy = path33.join(os9.homedir(), "worktrees", `${projectName}-agent-${agentId}`);
39929
- if (fs32.existsSync(legacy) && sameGitCheckout2(harnessRoot, legacy)) return legacy;
39988
+ if (fs33.existsSync(legacy) && sameGitCheckout2(harnessRoot, legacy)) return legacy;
39930
39989
  const worktreesRoot = path33.join(os9.homedir(), "worktrees");
39931
- if (!fs32.existsSync(worktreesRoot)) return void 0;
39990
+ if (!fs33.existsSync(worktreesRoot)) return void 0;
39932
39991
  const suffix = `-har-agent-${agentId}-`;
39933
39992
  const relPrefix = runGit(harnessRoot, "rev-parse --show-prefix") ?? "";
39934
- for (const name of fs32.readdirSync(worktreesRoot)) {
39993
+ for (const name of fs33.readdirSync(worktreesRoot)) {
39935
39994
  if (!name.includes(suffix)) continue;
39936
39995
  const candidate = path33.join(worktreesRoot, name);
39937
39996
  if (!sameGitCheckout2(harnessRoot, candidate)) continue;
39938
- if (!fs32.existsSync(path33.join(candidate, relPrefix, `.env.agent.${agentId}`))) continue;
39997
+ if (!fs33.existsSync(path33.join(candidate, relPrefix, `.env.agent.${agentId}`))) continue;
39939
39998
  return candidate;
39940
39999
  }
39941
40000
  return void 0;
@@ -39947,9 +40006,9 @@ function collectOccupiedSlot(repoPath, agentId) {
39947
40006
  const session = readSlotRegistry(harnessRoot, agentId);
39948
40007
  const worktreePath = discoverWorktree(harnessRoot, agentId, projectName);
39949
40008
  const workDir = session?.workDir;
39950
- const envInWorkDir = workDir ? fs32.existsSync(path33.join(workDir, `.env.agent.${agentId}`)) : false;
39951
- const envInRoot = fs32.existsSync(path33.join(harnessRoot, `.env.agent.${agentId}`));
39952
- const envInWorktree = worktreePath ? fs32.existsSync(path33.join(worktreePath, `.env.agent.${agentId}`)) : false;
40009
+ const envInWorkDir = workDir ? fs33.existsSync(path33.join(workDir, `.env.agent.${agentId}`)) : false;
40010
+ const envInRoot = fs33.existsSync(path33.join(harnessRoot, `.env.agent.${agentId}`));
40011
+ const envInWorktree = worktreePath ? fs33.existsSync(path33.join(worktreePath, `.env.agent.${agentId}`)) : false;
39953
40012
  const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
39954
40013
  if (!active) return void 0;
39955
40014
  const dirty = worktreePath ? worktreeDirty(worktreePath) : void 0;
@@ -40040,11 +40099,11 @@ function checkLaunchGuard(repoPath, agentId, options = {}) {
40040
40099
  reason: formatOccupiedSlot(slot, repoPath)
40041
40100
  };
40042
40101
  }
40043
- var fs32, os9, path33, import_child_process8;
40102
+ var fs33, os9, path33, import_child_process8;
40044
40103
  var init_slot_launch_guard_occupied = __esm({
40045
40104
  "src/core/slot-launch-guard-occupied.ts"() {
40046
40105
  "use strict";
40047
- fs32 = __toESM(require("fs"));
40106
+ fs33 = __toESM(require("fs"));
40048
40107
  os9 = __toESM(require("os"));
40049
40108
  path33 = __toESM(require("path"));
40050
40109
  import_child_process8 = require("child_process");
@@ -40096,40 +40155,40 @@ exit 0
40096
40155
  `;
40097
40156
  }
40098
40157
  function upsertMarkedBlock(filePath, block) {
40099
- if (!fs33.existsSync(filePath)) {
40100
- fs33.writeFileSync(filePath, `#!/bin/sh
40158
+ if (!fs34.existsSync(filePath)) {
40159
+ fs34.writeFileSync(filePath, `#!/bin/sh
40101
40160
  ${block}
40102
40161
  `, { mode: 493 });
40103
40162
  return "created";
40104
40163
  }
40105
- const content = fs33.readFileSync(filePath, "utf8");
40164
+ const content = fs34.readFileSync(filePath, "utf8");
40106
40165
  if (content.includes(MARKER_START)) {
40107
40166
  const pattern = new RegExp(
40108
40167
  `${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}`
40109
40168
  );
40110
- fs33.writeFileSync(filePath, content.replace(pattern, block));
40111
- fs33.chmodSync(filePath, 493);
40169
+ fs34.writeFileSync(filePath, content.replace(pattern, block));
40170
+ fs34.chmodSync(filePath, 493);
40112
40171
  return "updated";
40113
40172
  }
40114
40173
  const suffix = content.endsWith("\n") ? "" : "\n";
40115
- fs33.writeFileSync(filePath, `${content}${suffix}
40174
+ fs34.writeFileSync(filePath, `${content}${suffix}
40116
40175
  ${block}
40117
40176
  `);
40118
- fs33.chmodSync(filePath, 493);
40177
+ fs34.chmodSync(filePath, 493);
40119
40178
  return "appended";
40120
40179
  }
40121
40180
  function removeMarkedBlock(filePath) {
40122
- if (!fs33.existsSync(filePath)) return false;
40123
- const content = fs33.readFileSync(filePath, "utf8");
40181
+ if (!fs34.existsSync(filePath)) return false;
40182
+ const content = fs34.readFileSync(filePath, "utf8");
40124
40183
  if (!content.includes(MARKER_START)) return false;
40125
40184
  const pattern = new RegExp(
40126
40185
  `\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`
40127
40186
  );
40128
40187
  const stripped = content.replace(pattern, "\n");
40129
40188
  if (stripped.replace(/^#!\/bin\/sh\n?/, "").trim() === "") {
40130
- fs33.rmSync(filePath);
40189
+ fs34.rmSync(filePath);
40131
40190
  } else {
40132
- fs33.writeFileSync(filePath, stripped);
40191
+ fs34.writeFileSync(filePath, stripped);
40133
40192
  }
40134
40193
  return true;
40135
40194
  }
@@ -40151,14 +40210,14 @@ Or re-run with --force to write into that directory anyway.`
40151
40210
  );
40152
40211
  }
40153
40212
  const hooksDir = resolveHooksDir(checkout);
40154
- fs33.mkdirSync(hooksDir, { recursive: true });
40213
+ fs34.mkdirSync(hooksDir, { recursive: true });
40155
40214
  const invocation = options.harInvocation ?? defaultHarInvocation();
40156
- fs33.writeFileSync(
40215
+ fs34.writeFileSync(
40157
40216
  path34.join(hooksDir, "har-pre-commit"),
40158
40217
  buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
40159
40218
  { mode: 493 }
40160
40219
  );
40161
- fs33.writeFileSync(
40220
+ fs34.writeFileSync(
40162
40221
  path34.join(hooksDir, "har-post-commit"),
40163
40222
  buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
40164
40223
  { mode: 493 }
@@ -40177,8 +40236,8 @@ function uninstallHooks(repoPath) {
40177
40236
  removed = removeMarkedBlock(path34.join(hooksDir, "post-commit")) || removed;
40178
40237
  for (const file of ["har-pre-commit", "har-post-commit"]) {
40179
40238
  const full = path34.join(hooksDir, file);
40180
- if (fs33.existsSync(full)) {
40181
- fs33.rmSync(full);
40239
+ if (fs34.existsSync(full)) {
40240
+ fs34.rmSync(full);
40182
40241
  removed = true;
40183
40242
  }
40184
40243
  }
@@ -40214,14 +40273,14 @@ function getHooksStatus(repoPath) {
40214
40273
  const gate = getCommitGateConfig(checkout);
40215
40274
  const hasBlock = (name) => {
40216
40275
  const file = path34.join(hooksDir, name);
40217
- return fs33.existsSync(file) && fs33.readFileSync(file, "utf8").includes(MARKER_START);
40276
+ return fs34.existsSync(file) && fs34.readFileSync(file, "utf8").includes(MARKER_START);
40218
40277
  };
40219
40278
  return {
40220
40279
  checkout,
40221
40280
  hooksDir,
40222
40281
  configuredHooksPath: getConfiguredHooksPath(checkout),
40223
- preCommitInstalled: hasBlock("pre-commit") && fs33.existsSync(path34.join(hooksDir, "har-pre-commit")),
40224
- postCommitInstalled: hasBlock("post-commit") && fs33.existsSync(path34.join(hooksDir, "har-post-commit")),
40282
+ preCommitInstalled: hasBlock("pre-commit") && fs34.existsSync(path34.join(hooksDir, "har-pre-commit")),
40283
+ postCommitInstalled: hasBlock("post-commit") && fs34.existsSync(path34.join(hooksDir, "har-post-commit")),
40225
40284
  gate,
40226
40285
  effectiveMode: resolveEffectiveMode(checkout, gate)
40227
40286
  };
@@ -40232,7 +40291,7 @@ function checkCommitGate(cwd) {
40232
40291
  }
40233
40292
  const checkout = resolveCheckoutRoot(cwd);
40234
40293
  if (!checkout) return { exitCode: 0, messages: [] };
40235
- if (!fs33.existsSync(path34.join(checkout, ".har", "stages.json"))) {
40294
+ if (!fs34.existsSync(path34.join(checkout, ".har", "stages.json"))) {
40236
40295
  return { exitCode: 0, messages: [] };
40237
40296
  }
40238
40297
  const gate = getCommitGateConfig(checkout);
@@ -40308,11 +40367,11 @@ async function recordCommitAssociation(cwd) {
40308
40367
  return { attached: false };
40309
40368
  }
40310
40369
  }
40311
- var fs33, os10, path34, MARKER_START, MARKER_END, PRE_COMMIT_BLOCK, POST_COMMIT_BLOCK;
40370
+ var fs34, os10, path34, MARKER_START, MARKER_END, PRE_COMMIT_BLOCK, POST_COMMIT_BLOCK;
40312
40371
  var init_hooks = __esm({
40313
40372
  "src/core/hooks.ts"() {
40314
40373
  "use strict";
40315
- fs33 = __toESM(require("fs"));
40374
+ fs34 = __toESM(require("fs"));
40316
40375
  os10 = __toESM(require("os"));
40317
40376
  path34 = __toESM(require("path"));
40318
40377
  init_shell();
@@ -40813,9 +40872,9 @@ var init_slot_database = __esm({
40813
40872
  // src/runtime/hooks.ts
40814
40873
  function readHookHarnessEnv(harnessDir) {
40815
40874
  const envPath = path37.join(harnessDir, "harness.env");
40816
- if (!fs34.existsSync(envPath)) return {};
40875
+ if (!fs35.existsSync(envPath)) return {};
40817
40876
  try {
40818
- return parseHarnessEnvSource(fs34.readFileSync(envPath, "utf8")).values;
40877
+ return parseHarnessEnvSource(fs35.readFileSync(envPath, "utf8")).values;
40819
40878
  } catch {
40820
40879
  return {};
40821
40880
  }
@@ -40844,7 +40903,7 @@ function hookDisplayPath(hook) {
40844
40903
  }
40845
40904
  function runLifecycleHook(hook, context) {
40846
40905
  const file = lifecycleHookPath(context.harnessDir, hook);
40847
- if (!fs34.existsSync(file)) return { ran: false, code: 0 };
40906
+ if (!fs35.existsSync(file)) return { ran: false, code: 0 };
40848
40907
  context.log?.(`Running ${hookDisplayPath(hook)}...`);
40849
40908
  const env3 = hookEnv(hook, context);
40850
40909
  const cwd = context.workDir ?? path37.dirname(context.harnessDir);
@@ -40862,11 +40921,11 @@ function runLifecycleHook(hook, context) {
40862
40921
  function postHookFailureMode(env3) {
40863
40922
  return env3.HARNESS_HOOK_POST_FAILURE === "fail" ? "fail" : "warn";
40864
40923
  }
40865
- var fs34, path37, import_child_process12, LIFECYCLE_HOOKS, HOOK_CONTRACT_VERSION, HOOKS_DIR;
40924
+ var fs35, path37, import_child_process12, LIFECYCLE_HOOKS, HOOK_CONTRACT_VERSION, HOOKS_DIR;
40866
40925
  var init_hooks2 = __esm({
40867
40926
  "src/runtime/hooks.ts"() {
40868
40927
  "use strict";
40869
- fs34 = __toESM(require("fs"));
40928
+ fs35 = __toESM(require("fs"));
40870
40929
  path37 = __toESM(require("path"));
40871
40930
  import_child_process12 = require("child_process");
40872
40931
  init_schema2();
@@ -41009,7 +41068,7 @@ function detectProcessManager(repoPath) {
41009
41068
  const harnessRoot = resolveHarnessRoot(repoPath);
41010
41069
  const manifest = readManifest(harnessRoot);
41011
41070
  if (manifest?.profile === "ios") return "simulator";
41012
- if (fs35.existsSync(path38.join(getHarnessDir(harnessRoot), "simulator.sh"))) return "simulator";
41071
+ if (fs36.existsSync(path38.join(getHarnessDir(harnessRoot), "simulator.sh"))) return "simulator";
41013
41072
  return "none";
41014
41073
  }
41015
41074
  function heredocEnvFile(envFile, agentId, workDir, worktreeDir) {
@@ -41021,8 +41080,8 @@ function heredocEnvFile(envFile, agentId, workDir, worktreeDir) {
41021
41080
  "NODE_ENV=test",
41022
41081
  ""
41023
41082
  ].join("\n");
41024
- fs35.mkdirSync(path38.dirname(envFile), { recursive: true });
41025
- fs35.writeFileSync(envFile, content);
41083
+ fs36.mkdirSync(path38.dirname(envFile), { recursive: true });
41084
+ fs36.writeFileSync(envFile, content);
41026
41085
  }
41027
41086
  async function launchSession(options) {
41028
41087
  const repoRoot = resolveHarnessRoot(options.repoPath);
@@ -41283,7 +41342,7 @@ async function launchSession(options) {
41283
41342
  throw new Error("simulator acquisition failed");
41284
41343
  }
41285
41344
  ({ udid: simUdid, name: simName } = sim);
41286
- fs35.appendFileSync(
41345
+ fs36.appendFileSync(
41287
41346
  session.envFile,
41288
41347
  [
41289
41348
  `HARNESS_SIMULATOR_UDID=${quoteEnvValue(simUdid)}`,
@@ -41391,20 +41450,20 @@ function seedExtraExcludePattern(repoRoot, pattern, exec) {
41391
41450
  if (commonDir.code !== 0) return;
41392
41451
  const resolved = path38.isAbsolute(commonDir.stdout.trim()) ? commonDir.stdout.trim() : path38.resolve(repoRoot, commonDir.stdout.trim());
41393
41452
  const excludeFile = path38.join(resolved, "info", "exclude");
41394
- if (!fs35.existsSync(path38.dirname(excludeFile))) return;
41395
- const existing = fs35.existsSync(excludeFile) ? fs35.readFileSync(excludeFile, "utf8") : "";
41453
+ if (!fs36.existsSync(path38.dirname(excludeFile))) return;
41454
+ const existing = fs36.existsSync(excludeFile) ? fs36.readFileSync(excludeFile, "utf8") : "";
41396
41455
  if (existing.split("\n").includes(pattern)) return;
41397
- fs35.appendFileSync(excludeFile, `${pattern}
41456
+ fs36.appendFileSync(excludeFile, `${pattern}
41398
41457
  `);
41399
41458
  }
41400
41459
  function repoRooted(requested, resolved) {
41401
41460
  return path38.resolve(requested) === resolved ? requested : resolved;
41402
41461
  }
41403
- var fs35, path38, stderrLine;
41462
+ var fs36, path38, stderrLine;
41404
41463
  var init_launch = __esm({
41405
41464
  "src/runtime/launch.ts"() {
41406
41465
  "use strict";
41407
- fs35 = __toESM(require("fs"));
41466
+ fs36 = __toESM(require("fs"));
41408
41467
  path38 = __toESM(require("path"));
41409
41468
  init_env();
41410
41469
  init_manifest();
@@ -41484,7 +41543,7 @@ async function teardownSession(options) {
41484
41543
  ];
41485
41544
  for (const dir of [repoRoot, workDir]) {
41486
41545
  if (!dir) continue;
41487
- for (const file of generated(dir)) fs36.rmSync(file, { force: true });
41546
+ for (const file of generated(dir)) fs37.rmSync(file, { force: true });
41488
41547
  }
41489
41548
  const removed = removeSessionWorktree({
41490
41549
  repoRoot,
@@ -41528,11 +41587,11 @@ async function teardownSession(options) {
41528
41587
  out(`\u2713 Agent ${agentId} torn down`);
41529
41588
  return { code: 0 };
41530
41589
  }
41531
- var fs36, path39, os11;
41590
+ var fs37, path39, os11;
41532
41591
  var init_teardown = __esm({
41533
41592
  "src/runtime/teardown.ts"() {
41534
41593
  "use strict";
41535
- fs36 = __toESM(require("fs"));
41594
+ fs37 = __toESM(require("fs"));
41536
41595
  path39 = __toESM(require("path"));
41537
41596
  os11 = __toESM(require("os"));
41538
41597
  init_env();
@@ -41554,7 +41613,7 @@ var init_teardown = __esm({
41554
41613
  // src/runtime/verify.ts
41555
41614
  function resolveVerifyRunner(harnessDir) {
41556
41615
  const installed = path40.join(harnessDir, "lib", "verify-runner.mjs");
41557
- if (fs37.existsSync(installed)) return installed;
41616
+ if (fs38.existsSync(installed)) return installed;
41558
41617
  return path40.join(
41559
41618
  resolveTemplatesDir(),
41560
41619
  "runtime-bundles",
@@ -41615,11 +41674,11 @@ exec node ${JSON.stringify(resolveVerifyRunner(harnessDir))} --agent ${agentId}$
41615
41674
  env: baseEnv
41616
41675
  };
41617
41676
  }
41618
- var fs37, path40, XC_TARGET_FLAGS_FUNCTION, XC_BLOCK, API_PORT_BLOCK, VerifyPlanError;
41677
+ var fs38, path40, XC_TARGET_FLAGS_FUNCTION, XC_BLOCK, API_PORT_BLOCK, VerifyPlanError;
41619
41678
  var init_verify = __esm({
41620
41679
  "src/runtime/verify.ts"() {
41621
41680
  "use strict";
41622
- fs37 = __toESM(require("fs"));
41681
+ fs38 = __toESM(require("fs"));
41623
41682
  path40 = __toESM(require("path"));
41624
41683
  init_paths();
41625
41684
  init_manifest();
@@ -41949,13 +42008,13 @@ function resolveStageScriptPath(repoPath, stage) {
41949
42008
  return path41.join(harnessDir, scriptName);
41950
42009
  }
41951
42010
  const stageScript = path41.join(harnessDir, "stages", `${stage.id}.sh`);
41952
- if (fs38.existsSync(stageScript)) {
42011
+ if (fs39.existsSync(stageScript)) {
41953
42012
  return stageScript;
41954
42013
  }
41955
42014
  const fallback = stage.kind === "inspect" ? "agent-cli.sh" : RUNTIME_SCRIPT_FOR_KIND[stage.kind];
41956
42015
  if (fallback) {
41957
42016
  const fallbackPath = path41.join(harnessDir, fallback);
41958
- if (fs38.existsSync(fallbackPath)) return fallbackPath;
42017
+ if (fs39.existsSync(fallbackPath)) return fallbackPath;
41959
42018
  }
41960
42019
  throw new Error(
41961
42020
  `Stage "${stage.id}" has no runnable script. Add script to stages.json, create .har/stages/${stage.id}.sh, or run verification via har_run_verification.`
@@ -42036,8 +42095,8 @@ function inspectOp(stage) {
42036
42095
  }
42037
42096
  function harnessScriptIsLegacy(repoPath, scriptName) {
42038
42097
  const file = path41.join(getHarnessDir(resolveHarnessRoot(repoPath)), scriptName);
42039
- if (!fs38.existsSync(file)) return false;
42040
- return !fs38.readFileSync(file, "utf8").includes("exec har env");
42098
+ if (!fs39.existsSync(file)) return false;
42099
+ return !fs39.readFileSync(file, "utf8").includes("exec har env");
42041
42100
  }
42042
42101
  function warnLegacyRuntimeScript(repoPath, scriptName) {
42043
42102
  const key = `${path41.resolve(repoPath)}:${scriptName}`;
@@ -42149,11 +42208,11 @@ async function runPackageRuntimeStage(repoPath, stage, options, capture) {
42149
42208
  }
42150
42209
  return void 0;
42151
42210
  }
42152
- var fs38, path41, RUNTIME_SCRIPT_FOR_KIND, warnedLegacyScripts, LocalScriptExecutor, localScriptExecutor;
42211
+ var fs39, path41, RUNTIME_SCRIPT_FOR_KIND, warnedLegacyScripts, LocalScriptExecutor, localScriptExecutor;
42153
42212
  var init_local_executor = __esm({
42154
42213
  "src/core/local-executor.ts"() {
42155
42214
  "use strict";
42156
- fs38 = __toESM(require("fs"));
42215
+ fs39 = __toESM(require("fs"));
42157
42216
  path41 = __toESM(require("path"));
42158
42217
  init_manifest();
42159
42218
  init_env();
@@ -42211,10 +42270,10 @@ var init_local_executor = __esm({
42211
42270
  const harnessDir = getHarnessDir(repoPath);
42212
42271
  const artifactsDirName = getArtifactsDir(repoPath);
42213
42272
  const artifactsDir = path41.join(harnessDir, artifactsDirName);
42214
- if (!fs38.existsSync(artifactsDir)) return [];
42273
+ if (!fs39.existsSync(artifactsDir)) return [];
42215
42274
  const entries = [];
42216
42275
  const walk = (dir, prefix) => {
42217
- for (const entry of fs38.readdirSync(dir, { withFileTypes: true })) {
42276
+ for (const entry of fs39.readdirSync(dir, { withFileTypes: true })) {
42218
42277
  const full = path41.join(dir, entry.name);
42219
42278
  const relative6 = path41.join(prefix, entry.name);
42220
42279
  if (entry.isDirectory()) {
@@ -42222,7 +42281,7 @@ var init_local_executor = __esm({
42222
42281
  continue;
42223
42282
  }
42224
42283
  if (filter2?.stageId && !relative6.includes(filter2.stageId)) continue;
42225
- const stat = fs38.statSync(full);
42284
+ const stat = fs39.statSync(full);
42226
42285
  entries.push({
42227
42286
  path: full,
42228
42287
  relativePath: relative6,
@@ -42281,11 +42340,11 @@ function gitPrefix2(cwd) {
42281
42340
  }
42282
42341
  function discoverSessionWorktreePath(harnessRoot, agentId) {
42283
42342
  const worktreesRoot = path42.join(os12.homedir(), "worktrees");
42284
- if (!fs39.existsSync(worktreesRoot)) return void 0;
42343
+ if (!fs40.existsSync(worktreesRoot)) return void 0;
42285
42344
  const suffix = `-har-agent-${agentId}-`;
42286
42345
  const relPrefix = gitPrefix2(harnessRoot);
42287
- const matches = fs39.readdirSync(worktreesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.includes(suffix)).map((entry) => path42.join(worktreesRoot, entry.name)).filter(
42288
- (candidate) => sameGitCheckout3(harnessRoot, candidate) && fs39.existsSync(path42.join(candidate, relPrefix, `.env.agent.${agentId}`))
42346
+ const matches = fs40.readdirSync(worktreesRoot, { withFileTypes: true }).filter((entry) => entry.isDirectory() && entry.name.includes(suffix)).map((entry) => path42.join(worktreesRoot, entry.name)).filter(
42347
+ (candidate) => sameGitCheckout3(harnessRoot, candidate) && fs40.existsSync(path42.join(candidate, relPrefix, `.env.agent.${agentId}`))
42289
42348
  );
42290
42349
  return matches.sort()[0];
42291
42350
  }
@@ -42293,7 +42352,7 @@ function resolveAgentEnvFile(harnessRoot, agentId) {
42293
42352
  const session = readSlotRegistry(harnessRoot, agentId);
42294
42353
  if (session?.workDir) {
42295
42354
  const inWorkDir = path42.join(session.workDir, `.env.agent.${agentId}`);
42296
- if (fs39.existsSync(inWorkDir)) return inWorkDir;
42355
+ if (fs40.existsSync(inWorkDir)) return inWorkDir;
42297
42356
  }
42298
42357
  const env3 = readHarnessEnv(harnessRoot);
42299
42358
  const projectName = env3.HARNESS_PROJECT_NAME ?? path42.basename(harnessRoot);
@@ -42302,16 +42361,16 @@ function resolveAgentEnvFile(harnessRoot, agentId) {
42302
42361
  path42.join(harnessRoot, `.env.agent.${agentId}`),
42303
42362
  path42.join(os12.homedir(), "worktrees", `${projectName}-agent-${agentId}`, relPrefix, `.env.agent.${agentId}`)
42304
42363
  ]) {
42305
- if (fs39.existsSync(candidate)) return candidate;
42364
+ if (fs40.existsSync(candidate)) return candidate;
42306
42365
  }
42307
42366
  const worktreesRoot = path42.join(os12.homedir(), "worktrees");
42308
- if (!fs39.existsSync(worktreesRoot)) return void 0;
42367
+ if (!fs40.existsSync(worktreesRoot)) return void 0;
42309
42368
  const suffix = `-har-agent-${agentId}-`;
42310
- for (const name of fs39.readdirSync(worktreesRoot).sort()) {
42369
+ for (const name of fs40.readdirSync(worktreesRoot).sort()) {
42311
42370
  if (!name.includes(suffix)) continue;
42312
42371
  const candidateDir = path42.join(worktreesRoot, name);
42313
42372
  const candidate = path42.join(candidateDir, relPrefix, `.env.agent.${agentId}`);
42314
- if (!fs39.existsSync(candidate)) continue;
42373
+ if (!fs40.existsSync(candidate)) continue;
42315
42374
  if (!sameGitCheckout3(harnessRoot, candidateDir)) continue;
42316
42375
  return candidate;
42317
42376
  }
@@ -42319,7 +42378,7 @@ function resolveAgentEnvFile(harnessRoot, agentId) {
42319
42378
  }
42320
42379
  function parseEnvFilePorts(envFile) {
42321
42380
  const values = {};
42322
- for (const line of fs39.readFileSync(envFile, "utf8").split("\n")) {
42381
+ for (const line of fs40.readFileSync(envFile, "utf8").split("\n")) {
42323
42382
  const match = line.match(/^(?:export\s+)?([A-Z_][A-Z0-9_]*)=(.*)$/);
42324
42383
  if (!match) continue;
42325
42384
  values[match[1]] = match[2].replace(/^["']|["']$/g, "");
@@ -42347,8 +42406,8 @@ function loadAgentPorts(harnessRoot, agentId) {
42347
42406
  const allocated = allocateAppPorts(harnessRoot, agentId);
42348
42407
  const infraEnv = path42.join(getHarnessDir(harnessRoot), "state", "infra.env");
42349
42408
  const infraState = {};
42350
- if (fs39.existsSync(infraEnv)) {
42351
- for (const line of fs39.readFileSync(infraEnv, "utf8").split("\n")) {
42409
+ if (fs40.existsSync(infraEnv)) {
42410
+ for (const line of fs40.readFileSync(infraEnv, "utf8").split("\n")) {
42352
42411
  const match = line.match(/^(?:export\s+)?([A-Z_][A-Z0-9_]*)=(.*)$/);
42353
42412
  if (match) infraState[match[1]] = match[2].replace(/^["']|["']$/g, "");
42354
42413
  }
@@ -42437,11 +42496,11 @@ function collectSlotStatus(harnessRoot, agentId, runs, pm2Procs, untrackedPaths)
42437
42496
  "worktrees",
42438
42497
  `${projectName}-agent-${agentId}`
42439
42498
  );
42440
- const worktreePath = session?.worktreePath && fs39.existsSync(session.worktreePath) ? session.worktreePath : fs39.existsSync(legacyWorktreePath) ? legacyWorktreePath : discoverSessionWorktreePath(harnessRoot, agentId);
42499
+ const worktreePath = session?.worktreePath && fs40.existsSync(session.worktreePath) ? session.worktreePath : fs40.existsSync(legacyWorktreePath) ? legacyWorktreePath : discoverSessionWorktreePath(harnessRoot, agentId);
42441
42500
  const workDir = resolveAgentWorkDir(harnessRoot, agentId);
42442
- const envInWorkDir = workDir ? fs39.existsSync(path42.join(workDir, `.env.agent.${agentId}`)) : false;
42443
- const envInRoot = fs39.existsSync(path42.join(harnessRoot, `.env.agent.${agentId}`));
42444
- const envInWorktree = worktreePath ? fs39.existsSync(path42.join(worktreePath, `.env.agent.${agentId}`)) : false;
42501
+ const envInWorkDir = workDir ? fs40.existsSync(path42.join(workDir, `.env.agent.${agentId}`)) : false;
42502
+ const envInRoot = fs40.existsSync(path42.join(harnessRoot, `.env.agent.${agentId}`));
42503
+ const envInWorktree = worktreePath ? fs40.existsSync(path42.join(worktreePath, `.env.agent.${agentId}`)) : false;
42445
42504
  const active = session !== void 0 && session.status !== "completed" || envInWorkDir || envInRoot || envInWorktree;
42446
42505
  const latest = latestRunForAgent(runs, agentId);
42447
42506
  const verifyRun = runs.find((r) => r.agentId === agentId && r.stageId === "verify");
@@ -42549,11 +42608,11 @@ function collectEnvironmentStatus(repoPath) {
42549
42608
  generatedAt: (/* @__PURE__ */ new Date()).toISOString()
42550
42609
  };
42551
42610
  }
42552
- var fs39, os12, path42, import_child_process14, BYPASS_WARNING_MS;
42611
+ var fs40, os12, path42, import_child_process14, BYPASS_WARNING_MS;
42553
42612
  var init_slot_status = __esm({
42554
42613
  "src/core/slot-status.ts"() {
42555
42614
  "use strict";
42556
- fs39 = __toESM(require("fs"));
42615
+ fs40 = __toESM(require("fs"));
42557
42616
  os12 = __toESM(require("os"));
42558
42617
  path42 = __toESM(require("path"));
42559
42618
  import_child_process14 = require("child_process");
@@ -43196,8 +43255,8 @@ function encodeClaudeProjectDir(cwd) {
43196
43255
  return cwd.replace(/[^a-zA-Z0-9]/g, "-");
43197
43256
  }
43198
43257
  function readJsonlRecords(filePath) {
43199
- if (!fs40.existsSync(filePath)) return [];
43200
- const lines = fs40.readFileSync(filePath, "utf8").split(/\r?\n/);
43258
+ if (!fs41.existsSync(filePath)) return [];
43259
+ const lines = fs41.readFileSync(filePath, "utf8").split(/\r?\n/);
43201
43260
  const out = [];
43202
43261
  for (const line of lines) {
43203
43262
  const trimmed = line.trim();
@@ -43289,18 +43348,18 @@ function findMatchingClaudeTranscripts(slot) {
43289
43348
  const fallbackTargets = slot.includeRepoPathFallback && slot.repoPath && !primaryTargets.includes(slot.repoPath) ? [slot.repoPath] : [];
43290
43349
  if (primaryTargets.length === 0 && fallbackTargets.length === 0) return [];
43291
43350
  const root = claudeProjectsRoot();
43292
- if (!fs40.existsSync(root)) return [];
43351
+ if (!fs41.existsSync(root)) return [];
43293
43352
  const primary = [];
43294
43353
  const fallback = [];
43295
- for (const entry of fs40.readdirSync(root, { withFileTypes: true })) {
43354
+ for (const entry of fs41.readdirSync(root, { withFileTypes: true })) {
43296
43355
  if (!entry.isDirectory()) continue;
43297
43356
  const projectDir = path44.join(root, entry.name);
43298
43357
  const primaryEncoded = primaryTargets.some((t) => entry.name === encodeClaudeProjectDir(t));
43299
43358
  const fallbackEncoded = fallbackTargets.some((t) => entry.name === encodeClaudeProjectDir(t));
43300
- for (const file of fs40.readdirSync(projectDir)) {
43359
+ for (const file of fs41.readdirSync(projectDir)) {
43301
43360
  if (!file.endsWith(".jsonl")) continue;
43302
43361
  const filePath = path44.join(projectDir, file);
43303
- const stat = fs40.statSync(filePath);
43362
+ const stat = fs41.statSync(filePath);
43304
43363
  const records = readJsonlRecords(filePath);
43305
43364
  let primaryHit = primaryEncoded;
43306
43365
  let fallbackHit = fallbackEncoded;
@@ -43443,11 +43502,11 @@ function harvestClaudeEvents(slot) {
43443
43502
  ).flatMap((entry) => entry.match.records);
43444
43503
  return capHarvestedEvents(extractPromptEvents(records, sessionKey, slot));
43445
43504
  }
43446
- var fs40, os14, path44, MAX_HARVESTED_SESSION_EVENTS;
43505
+ var fs41, os14, path44, MAX_HARVESTED_SESSION_EVENTS;
43447
43506
  var init_claude = __esm({
43448
43507
  "src/core/usage-harvest/claude.ts"() {
43449
43508
  "use strict";
43450
- fs40 = __toESM(require("fs"));
43509
+ fs41 = __toESM(require("fs"));
43451
43510
  os14 = __toESM(require("os"));
43452
43511
  path44 = __toESM(require("path"));
43453
43512
  init_schema2();
@@ -43464,8 +43523,8 @@ function codexSessionsRoot() {
43464
43523
  return process.env.HAR_CODEX_SESSIONS_DIR ? path45.resolve(process.env.HAR_CODEX_SESSIONS_DIR) : path45.join(os15.homedir(), ".codex", "sessions");
43465
43524
  }
43466
43525
  function walkJsonlFiles(dir, out = []) {
43467
- if (!fs41.existsSync(dir)) return out;
43468
- for (const entry of fs41.readdirSync(dir, { withFileTypes: true })) {
43526
+ if (!fs42.existsSync(dir)) return out;
43527
+ for (const entry of fs42.readdirSync(dir, { withFileTypes: true })) {
43469
43528
  const full = path45.join(dir, entry.name);
43470
43529
  if (entry.isDirectory()) walkJsonlFiles(full, out);
43471
43530
  else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
@@ -43473,7 +43532,7 @@ function walkJsonlFiles(dir, out = []) {
43473
43532
  return out;
43474
43533
  }
43475
43534
  function readJsonl(filePath) {
43476
- const lines = fs41.readFileSync(filePath, "utf8").split(/\r?\n/);
43535
+ const lines = fs42.readFileSync(filePath, "utf8").split(/\r?\n/);
43477
43536
  const out = [];
43478
43537
  for (const line of lines) {
43479
43538
  const trimmed = line.trim();
@@ -43540,7 +43599,7 @@ function harvestCodexUsage(slot) {
43540
43599
  const extracted = extractCodexTokens(records);
43541
43600
  if (!extracted.cwd) continue;
43542
43601
  if (extracted.tokensInput + extracted.tokensOutput + extracted.tokensCacheRead === 0) continue;
43543
- const mtime = fs41.statSync(file).mtimeMs;
43602
+ const mtime = fs42.statSync(file).mtimeMs;
43544
43603
  if (workspaceMatchesTarget(extracted.cwd, primaryTargets)) {
43545
43604
  if (mtime >= bestPrimaryMtime) {
43546
43605
  bestPrimaryMtime = mtime;
@@ -43576,11 +43635,11 @@ function harvestCodexUsage(slot) {
43576
43635
  lastSeenAt: best.seen?.lastAt ?? now
43577
43636
  };
43578
43637
  }
43579
- var fs41, os15, path45;
43638
+ var fs42, os15, path45;
43580
43639
  var init_codex = __esm({
43581
43640
  "src/core/usage-harvest/codex.ts"() {
43582
43641
  "use strict";
43583
- fs41 = __toESM(require("fs"));
43642
+ fs42 = __toESM(require("fs"));
43584
43643
  os15 = __toESM(require("os"));
43585
43644
  path45 = __toESM(require("path"));
43586
43645
  init_schema2();
@@ -43639,8 +43698,8 @@ function getStatePath() {
43639
43698
  function readState() {
43640
43699
  const statePath = getStatePath();
43641
43700
  try {
43642
- if (!fs42.existsSync(statePath)) return { states: [] };
43643
- const parsed = JSON.parse(fs42.readFileSync(statePath, "utf8"));
43701
+ if (!fs43.existsSync(statePath)) return { states: [] };
43702
+ const parsed = JSON.parse(fs43.readFileSync(statePath, "utf8"));
43644
43703
  return Array.isArray(parsed.states) ? parsed : { states: [] };
43645
43704
  } catch {
43646
43705
  return { states: [] };
@@ -43648,8 +43707,8 @@ function readState() {
43648
43707
  }
43649
43708
  function writeState(state) {
43650
43709
  const statePath = getStatePath();
43651
- fs42.mkdirSync(path46.dirname(statePath), { recursive: true });
43652
- fs42.writeFileSync(statePath, JSON.stringify(state, null, 2) + "\n");
43710
+ fs43.mkdirSync(path46.dirname(statePath), { recursive: true });
43711
+ fs43.writeFileSync(statePath, JSON.stringify(state, null, 2) + "\n");
43653
43712
  }
43654
43713
  function readPortalWatermark(repoPath, portalUrl) {
43655
43714
  const canonical = canonicalizeControlRepoPath(repoPath);
@@ -43714,11 +43773,11 @@ function selectSince(rows, since, getTimestamp) {
43714
43773
  }
43715
43774
  return { selected, maxSyncedAt };
43716
43775
  }
43717
- var fs42, os16, path46;
43776
+ var fs43, os16, path46;
43718
43777
  var init_portal_watermark = __esm({
43719
43778
  "src/core/portal-watermark.ts"() {
43720
43779
  "use strict";
43721
- fs42 = __toESM(require("fs"));
43780
+ fs43 = __toESM(require("fs"));
43722
43781
  os16 = __toESM(require("os"));
43723
43782
  path46 = __toESM(require("path"));
43724
43783
  init_control_repo_path();
@@ -44427,10 +44486,26 @@ async function collectPortalTelemetry(repoPath, slots, controlApiUrl, since, por
44427
44486
  };
44428
44487
  }
44429
44488
  }
44489
+ function collectEnvironmentStatusForSync(canonicalPath, sourcePaths) {
44490
+ const collected = /* @__PURE__ */ new Map();
44491
+ const groups = [];
44492
+ for (const source of sourcePaths) {
44493
+ const key = path48.resolve(source);
44494
+ let status = collected.get(key);
44495
+ if (!status) {
44496
+ status = collectEnvironmentStatus(source);
44497
+ collected.set(key, status);
44498
+ }
44499
+ groups.push(status.slots);
44500
+ }
44501
+ const canonicalKey = path48.resolve(canonicalPath);
44502
+ const canonical = collected.get(canonicalKey) ?? collectEnvironmentStatus(canonicalPath);
44503
+ return { ...canonical, slots: mergeSlotStatuses(groups) };
44504
+ }
44430
44505
  async function buildPortalPayload(repoPath, sourcePaths, controlApiUrl, since, full = false, portal) {
44431
44506
  const rawRunsBySource = collectRunsBySource(sourcePaths);
44432
44507
  const runs = mergeRunsBySource(rawRunsBySource);
44433
- const status = collectEnvironmentStatus(repoPath);
44508
+ const status = collectEnvironmentStatusForSync(repoPath, sourcePaths);
44434
44509
  const manifest = readManifest(repoPath);
44435
44510
  const stagesRegistry = readStageRegistry(repoPath);
44436
44511
  const validations = collectValidationsForSync(sourcePaths);
@@ -44787,7 +44862,7 @@ async function syncRepoWithControl(options) {
44787
44862
  }
44788
44863
  const sourcePaths = resolveSyncSourcePaths(repoPath, workspacePath);
44789
44864
  const runs = collectRunsForSync(sourcePaths);
44790
- const status = collectEnvironmentStatus(repoPath);
44865
+ const status = collectEnvironmentStatusForSync(repoPath, sourcePaths);
44791
44866
  const cloudWork = collectWorkUnitsForSync(sourcePaths);
44792
44867
  const harnessRoot = resolveHarnessRoot(repoPath);
44793
44868
  const response = await fetch(`${process.env.HAR_CLOUD_API_URL}/api/sync`, {
@@ -44862,7 +44937,7 @@ async function syncRepoRunsAndSlots(apiUrl, repoId, repoPath, workspacePath, dry
44862
44937
  },
44863
44938
  sourcePaths
44864
44939
  );
44865
- const status = collectEnvironmentStatus(repoPath);
44940
+ const status = collectEnvironmentStatusForSync(repoPath, sourcePaths);
44866
44941
  const slotsBody = SyncSlotsInputSchema.parse({
44867
44942
  slots: status.slots,
44868
44943
  generatedAt: status.generatedAt
@@ -52696,10 +52771,10 @@ var require_lib2 = __commonJS({
52696
52771
  exports2.analyse = analyse;
52697
52772
  var detectFile = (filepath, opts = {}) => new Promise((resolve70, reject) => {
52698
52773
  let fd;
52699
- const fs81 = (0, node_1.default)();
52774
+ const fs82 = (0, node_1.default)();
52700
52775
  const handler = (err, buffer) => {
52701
52776
  if (fd) {
52702
- fs81.closeSync(fd);
52777
+ fs82.closeSync(fd);
52703
52778
  }
52704
52779
  if (err) {
52705
52780
  reject(err);
@@ -52711,9 +52786,9 @@ var require_lib2 = __commonJS({
52711
52786
  };
52712
52787
  const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
52713
52788
  if (sampleSize > 0) {
52714
- fd = fs81.openSync(filepath, "r");
52789
+ fd = fs82.openSync(filepath, "r");
52715
52790
  let sample = Buffer.allocUnsafe(sampleSize);
52716
- fs81.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
52791
+ fs82.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
52717
52792
  if (err) {
52718
52793
  handler(err, null);
52719
52794
  } else {
@@ -52725,22 +52800,22 @@ var require_lib2 = __commonJS({
52725
52800
  });
52726
52801
  return;
52727
52802
  }
52728
- fs81.readFile(filepath, handler);
52803
+ fs82.readFile(filepath, handler);
52729
52804
  });
52730
52805
  exports2.detectFile = detectFile;
52731
52806
  var detectFileSync = (filepath, opts = {}) => {
52732
- const fs81 = (0, node_1.default)();
52807
+ const fs82 = (0, node_1.default)();
52733
52808
  if (opts && opts.sampleSize) {
52734
- const fd = fs81.openSync(filepath, "r");
52809
+ const fd = fs82.openSync(filepath, "r");
52735
52810
  let sample = Buffer.allocUnsafe(opts.sampleSize);
52736
- const bytesRead = fs81.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
52811
+ const bytesRead = fs82.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
52737
52812
  if (bytesRead < opts.sampleSize) {
52738
52813
  sample = sample.subarray(0, bytesRead);
52739
52814
  }
52740
- fs81.closeSync(fd);
52815
+ fs82.closeSync(fd);
52741
52816
  return (0, exports2.detect)(sample);
52742
52817
  }
52743
- return (0, exports2.detect)(fs81.readFileSync(filepath));
52818
+ return (0, exports2.detect)(fs82.readFileSync(filepath));
52744
52819
  };
52745
52820
  exports2.detectFileSync = detectFileSync;
52746
52821
  exports2.default = {
@@ -66095,7 +66170,7 @@ function installedPackageVersion(hooksHome) {
66095
66170
  "otel-hook",
66096
66171
  "package.json"
66097
66172
  );
66098
- const pkg = JSON.parse(fs69.readFileSync(pkgPath, "utf8"));
66173
+ const pkg = JSON.parse(fs70.readFileSync(pkgPath, "utf8"));
66099
66174
  return typeof pkg.version === "string" ? pkg.version : null;
66100
66175
  } catch {
66101
66176
  return null;
@@ -66146,15 +66221,15 @@ function buildOtelHooksConfig(options) {
66146
66221
  };
66147
66222
  }
66148
66223
  function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
66149
- fs69.mkdirSync(hooksHome, { recursive: true });
66224
+ fs70.mkdirSync(hooksHome, { recursive: true });
66150
66225
  const configPath = getOtelHooksConfigPath(hooksHome);
66151
- fs69.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
66226
+ fs70.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
66152
66227
  `);
66153
66228
  return configPath;
66154
66229
  }
66155
66230
  function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
66156
- fs69.mkdirSync(hooksHome, { recursive: true });
66157
- fs69.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
66231
+ fs70.mkdirSync(hooksHome, { recursive: true });
66232
+ fs70.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
66158
66233
  const wrapperPath = getOtelHooksWrapperPath(hooksHome);
66159
66234
  const configPath = getOtelHooksConfigPath(hooksHome);
66160
66235
  const stateDir = getOtelHooksStateDir(hooksHome);
@@ -66177,9 +66252,9 @@ set -uo pipefail
66177
66252
  "$@" || true
66178
66253
  exit 0
66179
66254
  `;
66180
- fs69.writeFileSync(wrapperPath, script, { mode: 493 });
66255
+ fs70.writeFileSync(wrapperPath, script, { mode: 493 });
66181
66256
  try {
66182
- fs69.chmodSync(wrapperPath, 493);
66257
+ fs70.chmodSync(wrapperPath, 493);
66183
66258
  } catch {
66184
66259
  }
66185
66260
  return wrapperPath;
@@ -66192,7 +66267,7 @@ function commandExists3(command2) {
66192
66267
  }
66193
66268
  function resolveOtelHookCommand(hooksHome) {
66194
66269
  const local = localOtelHookBin(hooksHome);
66195
- if (fs69.existsSync(local)) return local;
66270
+ if (fs70.existsSync(local)) return local;
66196
66271
  return null;
66197
66272
  }
66198
66273
  function resolveHooksInstaller(hooksHome) {
@@ -66207,7 +66282,7 @@ function resolveHooksInstaller(hooksHome) {
66207
66282
  return candidates.find((candidate) => commandExists3(candidate.command)) ?? null;
66208
66283
  }
66209
66284
  function tryInstallPackage(hooksHome) {
66210
- fs69.mkdirSync(hooksHome, { recursive: true });
66285
+ fs70.mkdirSync(hooksHome, { recursive: true });
66211
66286
  const installer = resolveHooksInstaller(hooksHome);
66212
66287
  if (!installer) {
66213
66288
  return {
@@ -66220,7 +66295,7 @@ function tryInstallPackage(hooksHome) {
66220
66295
  encoding: "utf8",
66221
66296
  timeout: 18e4
66222
66297
  });
66223
- if (result.status === 0 && fs69.existsSync(localOtelHookBin(hooksHome))) {
66298
+ if (result.status === 0 && fs70.existsSync(localOtelHookBin(hooksHome))) {
66224
66299
  return { ok: true, detail: described };
66225
66300
  }
66226
66301
  return {
@@ -66252,8 +66327,8 @@ function removeLegacyPythonArtifacts(hooksHome) {
66252
66327
  ];
66253
66328
  for (const target of legacyPaths) {
66254
66329
  try {
66255
- if (fs69.existsSync(target)) {
66256
- fs69.rmSync(target, { recursive: true, force: true });
66330
+ if (fs70.existsSync(target)) {
66331
+ fs70.rmSync(target, { recursive: true, force: true });
66257
66332
  }
66258
66333
  } catch {
66259
66334
  }
@@ -66301,10 +66376,10 @@ function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
66301
66376
  };
66302
66377
  }
66303
66378
  function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
66304
- if (!fs69.existsSync(filePath)) return false;
66379
+ if (!fs70.existsSync(filePath)) return false;
66305
66380
  let raw;
66306
66381
  try {
66307
- raw = fs69.readFileSync(filePath, "utf8");
66382
+ raw = fs70.readFileSync(filePath, "utf8");
66308
66383
  } catch {
66309
66384
  return false;
66310
66385
  }
@@ -66351,15 +66426,15 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
66351
66426
  return changed;
66352
66427
  };
66353
66428
  if (!walk(parsed)) return false;
66354
- fs69.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
66429
+ fs70.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
66355
66430
  `);
66356
66431
  return true;
66357
66432
  }
66358
66433
  function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
66359
- if (!fs69.existsSync(filePath)) return false;
66434
+ if (!fs70.existsSync(filePath)) return false;
66360
66435
  let raw;
66361
66436
  try {
66362
- raw = fs69.readFileSync(filePath, "utf8");
66437
+ raw = fs70.readFileSync(filePath, "utf8");
66363
66438
  } catch {
66364
66439
  return false;
66365
66440
  }
@@ -66394,7 +66469,7 @@ function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
66394
66469
  }
66395
66470
  }
66396
66471
  if (!changed) return false;
66397
- fs69.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
66472
+ fs70.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
66398
66473
  `);
66399
66474
  return true;
66400
66475
  }
@@ -66424,7 +66499,7 @@ function ensureOtelHooks(options) {
66424
66499
  const hooksHome = getOtelHooksHome();
66425
66500
  const errors = [];
66426
66501
  const providersSetup = [];
66427
- fs69.mkdirSync(hooksHome, { recursive: true });
66502
+ fs70.mkdirSync(hooksHome, { recursive: true });
66428
66503
  let otelHookCommand = resolveOtelHookCommand(hooksHome);
66429
66504
  const needsInstall = !otelHookCommand || installedPackageVersion(hooksHome) !== pinnedVersion();
66430
66505
  if (needsInstall) {
@@ -66518,12 +66593,12 @@ function ensureOtelHooks(options) {
66518
66593
  function disableOtelHooksExport() {
66519
66594
  return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
66520
66595
  }
66521
- var import_child_process19, fs69, os22, path79, OTEL_HOOKS_PACKAGE, HOOK_TIMEOUT_SECONDS, HOOK_EXPORT_TIMEOUT_MS, HOOK_FLUSH_TIMEOUT_MS, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
66596
+ var import_child_process19, fs70, os22, path79, OTEL_HOOKS_PACKAGE, HOOK_TIMEOUT_SECONDS, HOOK_EXPORT_TIMEOUT_MS, HOOK_FLUSH_TIMEOUT_MS, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
66522
66597
  var init_otel_hooks = __esm({
66523
66598
  "src/core/otel-hooks.ts"() {
66524
66599
  "use strict";
66525
66600
  import_child_process19 = require("child_process");
66526
- fs69 = __toESM(require("fs"));
66601
+ fs70 = __toESM(require("fs"));
66527
66602
  os22 = __toESM(require("os"));
66528
66603
  path79 = __toESM(require("path"));
66529
66604
  init_control_config();
@@ -73395,12 +73470,12 @@ var require_dist = __commonJS({
73395
73470
  throw new Error(`Unknown format "${name}"`);
73396
73471
  return f2;
73397
73472
  };
73398
- function addFormats(ajv, list, fs81, exportName) {
73473
+ function addFormats(ajv, list, fs82, exportName) {
73399
73474
  var _a2;
73400
73475
  var _b2;
73401
73476
  (_a2 = (_b2 = ajv.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
73402
73477
  for (const f2 of list)
73403
- ajv.addFormat(f2, fs81[f2]);
73478
+ ajv.addFormat(f2, fs82[f2]);
73404
73479
  }
73405
73480
  module2.exports = exports2 = formatsPlugin;
73406
73481
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -78267,7 +78342,7 @@ init_sync_context();
78267
78342
  var path51 = __toESM(require("path"));
78268
78343
 
78269
78344
  // src/harness/agent-skills.ts
78270
- var fs43 = __toESM(require("fs"));
78345
+ var fs44 = __toESM(require("fs"));
78271
78346
  var os17 = __toESM(require("os"));
78272
78347
  var path50 = __toESM(require("path"));
78273
78348
  var readline = __toESM(require("readline"));
@@ -78279,17 +78354,17 @@ var AGENT_SKILL_TARGETS = ["claude", "cursor", "codex"];
78279
78354
  var MANAGED_HEADER = "<!-- managed by har \u2014 regenerated by `har agents install` / `har env maintain`; edit at your own risk -->";
78280
78355
  function agentSkillsTemplateDir() {
78281
78356
  const dir = path50.join(resolveTemplatesDir(), "agent-skills");
78282
- if (!fs43.existsSync(dir)) {
78357
+ if (!fs44.existsSync(dir)) {
78283
78358
  throw new Error("Agent skills templates not found (templates/agent-skills). Run npm run build.");
78284
78359
  }
78285
78360
  return dir;
78286
78361
  }
78287
78362
  function readSkillsManifest() {
78288
78363
  const manifestPath = path50.join(agentSkillsTemplateDir(), "skills.manifest.json");
78289
- return JSON.parse(fs43.readFileSync(manifestPath, "utf8"));
78364
+ return JSON.parse(fs44.readFileSync(manifestPath, "utf8"));
78290
78365
  }
78291
78366
  function readSkillBody(entry) {
78292
- return fs43.readFileSync(path50.join(agentSkillsTemplateDir(), entry.body), "utf8");
78367
+ return fs44.readFileSync(path50.join(agentSkillsTemplateDir(), entry.body), "utf8");
78293
78368
  }
78294
78369
  function renderYamlValue(value) {
78295
78370
  if (typeof value === "string") return JSON.stringify(value);
@@ -78353,7 +78428,7 @@ function resolveScaffoldPath(repoPath, file) {
78353
78428
  return path50.join(repoPath, file.relPath);
78354
78429
  }
78355
78430
  function isHarManaged(filePath) {
78356
- return fs43.readFileSync(filePath, "utf8").includes(MANAGED_HEADER);
78431
+ return fs44.readFileSync(filePath, "utf8").includes(MANAGED_HEADER);
78357
78432
  }
78358
78433
  function scaffoldAgentSkills(repoPath, agents, options = {}) {
78359
78434
  const written = [];
@@ -78361,7 +78436,7 @@ function scaffoldAgentSkills(repoPath, agents, options = {}) {
78361
78436
  const records = [];
78362
78437
  for (const file of renderSkillFiles(agents)) {
78363
78438
  const destPath = resolveScaffoldPath(repoPath, file);
78364
- if (fs43.existsSync(destPath) && !options.force && !isHarManaged(destPath)) {
78439
+ if (fs44.existsSync(destPath) && !options.force && !isHarManaged(destPath)) {
78365
78440
  warn(`Skipped ${file.relPath} \u2014 exists with user modifications (use --force to overwrite)`);
78366
78441
  skipped.push(file.relPath);
78367
78442
  continue;
@@ -78395,16 +78470,16 @@ function removeAgentSkills(repoPath, agents) {
78395
78470
  const removed = [];
78396
78471
  for (const file of renderSkillFiles(agents)) {
78397
78472
  const destPath = resolveScaffoldPath(repoPath, file);
78398
- if (!fs43.existsSync(destPath)) continue;
78473
+ if (!fs44.existsSync(destPath)) continue;
78399
78474
  if (!isHarManaged(destPath)) {
78400
78475
  warn(`Kept ${file.relPath} \u2014 has user modifications`);
78401
78476
  continue;
78402
78477
  }
78403
- fs43.rmSync(destPath);
78478
+ fs44.rmSync(destPath);
78404
78479
  removed.push(file.relPath);
78405
78480
  const parent = path50.dirname(destPath);
78406
- if (fs43.existsSync(parent) && fs43.readdirSync(parent).length === 0) {
78407
- fs43.rmdirSync(parent);
78481
+ if (fs44.existsSync(parent) && fs44.readdirSync(parent).length === 0) {
78482
+ fs44.rmdirSync(parent);
78408
78483
  }
78409
78484
  }
78410
78485
  const manifest = readManifest(repoPath);
@@ -78423,9 +78498,9 @@ function detectAgentTargets(repoPath) {
78423
78498
  const manifest = readManifest(repoPath);
78424
78499
  const scaffolded = new Set((manifest?.scaffoldedAgentFiles ?? []).map((entry) => entry.agent));
78425
78500
  const detected = new Set(scaffolded);
78426
- if (fs43.existsSync(path50.join(repoPath, ".claude"))) detected.add("claude");
78427
- if (fs43.existsSync(path50.join(repoPath, ".cursor"))) detected.add("cursor");
78428
- if (fs43.existsSync(path50.join(os17.homedir(), ".codex"))) detected.add("codex");
78501
+ if (fs44.existsSync(path50.join(repoPath, ".claude"))) detected.add("claude");
78502
+ if (fs44.existsSync(path50.join(repoPath, ".cursor"))) detected.add("cursor");
78503
+ if (fs44.existsSync(path50.join(os17.homedir(), ".codex"))) detected.add("codex");
78429
78504
  return AGENT_SKILL_TARGETS.filter((agent) => detected.has(agent));
78430
78505
  }
78431
78506
  function parseAgentTargets(raw) {
@@ -78558,7 +78633,7 @@ function handleRemove(argv) {
78558
78633
  }
78559
78634
 
78560
78635
  // src/cli/commands/env.ts
78561
- var fs72 = __toESM(require("fs"));
78636
+ var fs73 = __toESM(require("fs"));
78562
78637
  var path83 = __toESM(require("path"));
78563
78638
 
78564
78639
  // src/cli/finish-command.ts
@@ -78569,17 +78644,17 @@ async function finishCommand(code) {
78569
78644
  }
78570
78645
 
78571
78646
  // src/core/harness.ts
78572
- var fs66 = __toESM(require("fs"));
78647
+ var fs67 = __toESM(require("fs"));
78573
78648
  var path75 = __toESM(require("path"));
78574
78649
 
78575
78650
  // src/harness/generator.ts
78576
- var fs49 = __toESM(require("fs"));
78651
+ var fs50 = __toESM(require("fs"));
78577
78652
  var path57 = __toESM(require("path"));
78578
78653
  init_file_ops();
78579
78654
  init_logging();
78580
78655
 
78581
78656
  // src/core/gitignore.ts
78582
- var fs44 = __toESM(require("fs"));
78657
+ var fs45 = __toESM(require("fs"));
78583
78658
  var path52 = __toESM(require("path"));
78584
78659
  var HARNESS_ROOT_GITIGNORE_PATTERNS = [
78585
78660
  ".env.agent.*",
@@ -78587,7 +78662,7 @@ var HARNESS_ROOT_GITIGNORE_PATTERNS = [
78587
78662
  ];
78588
78663
  function ensureRootGitignorePatterns(checkoutDir) {
78589
78664
  const gitignorePath = path52.join(checkoutDir, ".gitignore");
78590
- const content = fs44.existsSync(gitignorePath) ? fs44.readFileSync(gitignorePath, "utf8") : "";
78665
+ const content = fs45.existsSync(gitignorePath) ? fs45.readFileSync(gitignorePath, "utf8") : "";
78591
78666
  const lines = content.split("\n").map((line) => line.trim());
78592
78667
  const missing = HARNESS_ROOT_GITIGNORE_PATTERNS.filter((pattern) => !lines.includes(pattern));
78593
78668
  if (missing.length === 0) return;
@@ -78596,11 +78671,11 @@ function ensureRootGitignorePatterns(checkoutDir) {
78596
78671
  const block = lines.some((line) => line.includes("HAR agent slot artifacts")) || header2.length === 0 ? `${missing.join("\n")}
78597
78672
  ` : `${header2}${missing.join("\n")}
78598
78673
  `;
78599
- fs44.writeFileSync(gitignorePath, `${content}${suffix}${block}`);
78674
+ fs45.writeFileSync(gitignorePath, `${content}${suffix}${block}`);
78600
78675
  }
78601
78676
 
78602
78677
  // src/harness/gitignore-template.ts
78603
- var fs45 = __toESM(require("fs"));
78678
+ var fs46 = __toESM(require("fs"));
78604
78679
  var path53 = __toESM(require("path"));
78605
78680
  var HARNESS_GITIGNORE_TEMPLATE = "gitignore.template";
78606
78681
  var HARNESS_GITIGNORE_FILE = ".gitignore";
@@ -78612,22 +78687,22 @@ function templateFileForHarness(harnessFile) {
78612
78687
  }
78613
78688
  function resolveGitignoreTemplateSource(boilerplateDir) {
78614
78689
  const primary = path53.join(boilerplateDir, HARNESS_GITIGNORE_TEMPLATE);
78615
- if (fs45.existsSync(primary)) return primary;
78690
+ if (fs46.existsSync(primary)) return primary;
78616
78691
  const legacy = path53.join(boilerplateDir, HARNESS_GITIGNORE_FILE);
78617
- if (fs45.existsSync(legacy)) return legacy;
78692
+ if (fs46.existsSync(legacy)) return legacy;
78618
78693
  return null;
78619
78694
  }
78620
78695
  function writeHarnessGitignore(harnessDir, boilerplateDir) {
78621
78696
  const src = resolveGitignoreTemplateSource(boilerplateDir);
78622
78697
  if (!src) return;
78623
- fs45.writeFileSync(path53.join(harnessDir, HARNESS_GITIGNORE_FILE), fs45.readFileSync(src, "utf8"));
78698
+ fs46.writeFileSync(path53.join(harnessDir, HARNESS_GITIGNORE_FILE), fs46.readFileSync(src, "utf8"));
78624
78699
  }
78625
78700
  function isExpectedHarnessOnlyFile(harnessFile, templateFiles) {
78626
78701
  return harnessFile === HARNESS_GITIGNORE_FILE && templateFiles.includes(HARNESS_GITIGNORE_TEMPLATE);
78627
78702
  }
78628
78703
 
78629
78704
  // src/harness/drift.ts
78630
- var fs46 = __toESM(require("fs"));
78705
+ var fs47 = __toESM(require("fs"));
78631
78706
  var path54 = __toESM(require("path"));
78632
78707
  init_env();
78633
78708
  init_manifest();
@@ -78757,7 +78832,7 @@ function compareHarnessToTemplate(repoPath) {
78757
78832
  for (const file of templateFiles) {
78758
78833
  const harnessFile = harnessFileForTemplate(file);
78759
78834
  const harnessPath = path54.join(harnessDir, harnessFile);
78760
- if (userOwnedFiles.has(harnessFile) && fs46.existsSync(harnessPath)) {
78835
+ if (userOwnedFiles.has(harnessFile) && fs47.existsSync(harnessPath)) {
78761
78836
  ownedByUser.push(harnessFile);
78762
78837
  continue;
78763
78838
  }
@@ -78765,11 +78840,11 @@ function compareHarnessToTemplate(repoPath) {
78765
78840
  readComposedTemplateContent(composed.get(file)),
78766
78841
  projectName
78767
78842
  );
78768
- if (!fs46.existsSync(harnessPath)) {
78843
+ if (!fs47.existsSync(harnessPath)) {
78769
78844
  missing.push(harnessFile);
78770
78845
  continue;
78771
78846
  }
78772
- const installedChecksum = computeFileChecksum(fs46.readFileSync(harnessPath, "utf8"));
78847
+ const installedChecksum = computeFileChecksum(fs47.readFileSync(harnessPath, "utf8"));
78773
78848
  const templateChecksum = computeFileChecksum(templateContent);
78774
78849
  const recordedFile = fileBaseline?.[harnessFile];
78775
78850
  const recordedTemplate = templateBaseline?.[harnessFile];
@@ -78782,10 +78857,10 @@ function compareHarnessToTemplate(repoPath) {
78782
78857
  else if (status === "upstream-updated") upstreamUpdated.push(harnessFile);
78783
78858
  else conflict.push(harnessFile);
78784
78859
  }
78785
- if (fs46.existsSync(harnessDir)) {
78786
- for (const file of fs46.readdirSync(harnessDir)) {
78860
+ if (fs47.existsSync(harnessDir)) {
78861
+ for (const file of fs47.readdirSync(harnessDir)) {
78787
78862
  const full = path54.join(harnessDir, file);
78788
- if (!fs46.statSync(full).isFile()) continue;
78863
+ if (!fs47.statSync(full).isFile()) continue;
78789
78864
  if (file === "manifest.json" || file === "plugins.json" || file.startsWith("ADAPT-PROMPT") || file.startsWith("MIGRATE-PROMPT")) {
78790
78865
  continue;
78791
78866
  }
@@ -78819,7 +78894,7 @@ function compareHarnessToTemplate(repoPath) {
78819
78894
  init_manifest();
78820
78895
 
78821
78896
  // src/harness/plugin-ledger.ts
78822
- var fs47 = __toESM(require("fs"));
78897
+ var fs48 = __toESM(require("fs"));
78823
78898
  var path55 = __toESM(require("path"));
78824
78899
  init_zod();
78825
78900
  init_file_ops();
@@ -78847,9 +78922,9 @@ function getPluginLedgerPath(repoPath) {
78847
78922
  }
78848
78923
  function readPluginLedger(repoPath) {
78849
78924
  const ledgerPath = getPluginLedgerPath(repoPath);
78850
- if (!fs47.existsSync(ledgerPath)) return null;
78925
+ if (!fs48.existsSync(ledgerPath)) return null;
78851
78926
  try {
78852
- const raw = JSON.parse(fs47.readFileSync(ledgerPath, "utf8"));
78927
+ const raw = JSON.parse(fs48.readFileSync(ledgerPath, "utf8"));
78853
78928
  const parsed = PluginLedgerSchema.safeParse(raw);
78854
78929
  return parsed.success ? parsed.data : null;
78855
78930
  } catch {
@@ -78859,8 +78934,8 @@ function readPluginLedger(repoPath) {
78859
78934
  function writePluginLedger(repoPath, ledger) {
78860
78935
  const ledgerPath = getPluginLedgerPath(repoPath);
78861
78936
  const harnessDir = path55.dirname(ledgerPath);
78862
- if (!fs47.existsSync(harnessDir)) {
78863
- fs47.mkdirSync(harnessDir, { recursive: true });
78937
+ if (!fs48.existsSync(harnessDir)) {
78938
+ fs48.mkdirSync(harnessDir, { recursive: true });
78864
78939
  }
78865
78940
  writeFileSafe(ledgerPath, `${JSON.stringify(ledger, null, 2)}
78866
78941
  `);
@@ -78900,7 +78975,7 @@ init_schema2();
78900
78975
  init_stages();
78901
78976
 
78902
78977
  // src/harness/lifecycle-shims.ts
78903
- var fs48 = __toESM(require("fs"));
78978
+ var fs49 = __toESM(require("fs"));
78904
78979
  var path56 = __toESM(require("path"));
78905
78980
  init_manifest();
78906
78981
  init_stages();
@@ -78933,10 +79008,10 @@ function retireLifecycleShims(repoPath) {
78933
79008
  const pruned = [];
78934
79009
  for (const shim3 of LIFECYCLE_SHIM_FILES) {
78935
79010
  const file = path56.join(harnessDir, shim3);
78936
- if (!fs48.existsSync(file) || !fs48.statSync(file).isFile()) continue;
78937
- const content = fs48.readFileSync(file, "utf8");
79011
+ if (!fs49.existsSync(file) || !fs49.statSync(file).isFile()) continue;
79012
+ const content = fs49.readFileSync(file, "utf8");
78938
79013
  if (!isManagedShimContent(content)) continue;
78939
- fs48.rmSync(file);
79014
+ fs49.rmSync(file);
78940
79015
  pruned.push(shim3);
78941
79016
  }
78942
79017
  const stagesRewritten = stripLifecycleShimCommands(repoPath);
@@ -78972,21 +79047,21 @@ function scaffoldHarnessBoilerplate(repoPath, options = {}) {
78972
79047
  const profile = options.profile ?? "default";
78973
79048
  const profileManifest = readProfileManifest(profile);
78974
79049
  const bundleIds = profileManifest.bundles.map((b2) => b2.id);
78975
- if (fs49.existsSync(harnessDir) && !options.force) {
79050
+ if (fs50.existsSync(harnessDir) && !options.force) {
78976
79051
  throw new Error(
78977
79052
  '.har/ already exists. Use --force to overwrite or run "har env maintain" to update in place.'
78978
79053
  );
78979
79054
  }
78980
- if (options.force && fs49.existsSync(harnessDir)) {
78981
- fs49.rmSync(harnessDir, { recursive: true, force: true });
79055
+ if (options.force && fs50.existsSync(harnessDir)) {
79056
+ fs50.rmSync(harnessDir, { recursive: true, force: true });
78982
79057
  }
78983
- fs49.mkdirSync(harnessDir, { recursive: true });
79058
+ fs50.mkdirSync(harnessDir, { recursive: true });
78984
79059
  for (const bundle of profileManifest.bundles) {
78985
79060
  const bundleDir = resolveProfileBundleDir(bundle);
78986
79061
  copyDirRecursive(bundleDir, harnessDir);
78987
79062
  }
78988
79063
  for (const docName of Object.keys(profileManifest.docs)) {
78989
- fs49.writeFileSync(path57.join(harnessDir, docName), renderProfileDoc(profile, docName));
79064
+ fs50.writeFileSync(path57.join(harnessDir, docName), renderProfileDoc(profile, docName));
78990
79065
  }
78991
79066
  const gitignoreSource = composeProfileTemplateMap(profile).get(HARNESS_GITIGNORE_TEMPLATE);
78992
79067
  if (gitignoreSource) {
@@ -78995,10 +79070,10 @@ function scaffoldHarnessBoilerplate(repoPath, options = {}) {
78995
79070
  syncAgentSlotsToHarnessEnv(repoPath);
78996
79071
  retireLifecycleShims(repoPath);
78997
79072
  const harnessEnvPath = path57.join(harnessDir, "harness.env");
78998
- if (fs49.existsSync(harnessEnvPath)) {
78999
- let content = fs49.readFileSync(harnessEnvPath, "utf8");
79073
+ if (fs50.existsSync(harnessEnvPath)) {
79074
+ let content = fs50.readFileSync(harnessEnvPath, "utf8");
79000
79075
  content = substituteTemplateTokens(content, projectName);
79001
- fs49.writeFileSync(harnessEnvPath, content);
79076
+ fs50.writeFileSync(harnessEnvPath, content);
79002
79077
  const validation2 = validateHarnessEnvSource(content);
79003
79078
  if (!validation2.ok) {
79004
79079
  const details = validation2.issues.filter((i) => i.severity === "error").map((i) => i.line !== void 0 ? `line ${i.line}: ${i.message}` : i.message).join("\n ");
@@ -79036,14 +79111,14 @@ function finalizeHarness(repoPath, adaptationSummary, stack) {
79036
79111
  }
79037
79112
 
79038
79113
  // src/harness/agent-md.ts
79039
- var fs51 = __toESM(require("fs"));
79114
+ var fs52 = __toESM(require("fs"));
79040
79115
  var path60 = __toESM(require("path"));
79041
79116
  init_file_ops();
79042
79117
  init_logging();
79043
79118
  init_manifest();
79044
79119
 
79045
79120
  // src/harness/instruction-files.ts
79046
- var fs50 = __toESM(require("fs"));
79121
+ var fs51 = __toESM(require("fs"));
79047
79122
  var os19 = __toESM(require("os"));
79048
79123
  var path59 = __toESM(require("path"));
79049
79124
 
@@ -81795,12 +81870,12 @@ function outsideContentShrinkMessage(beforeLines, afterLines) {
81795
81870
  }
81796
81871
  function detectInstructionFiles(repoPath) {
81797
81872
  return {
81798
- agentsMd: fs50.existsSync(path59.join(repoPath, AGENTS_MD)),
81799
- agentMd: fs50.existsSync(path59.join(repoPath, LEGACY_AGENT_MD)),
81800
- claudeMd: fs50.existsSync(path59.join(repoPath, CLAUDE_MD)),
81801
- cursorDir: fs50.existsSync(path59.join(repoPath, ".cursor")),
81802
- claudeDir: fs50.existsSync(path59.join(repoPath, ".claude")),
81803
- codexHome: fs50.existsSync(path59.join(os19.homedir(), ".codex"))
81873
+ agentsMd: fs51.existsSync(path59.join(repoPath, AGENTS_MD)),
81874
+ agentMd: fs51.existsSync(path59.join(repoPath, LEGACY_AGENT_MD)),
81875
+ claudeMd: fs51.existsSync(path59.join(repoPath, CLAUDE_MD)),
81876
+ cursorDir: fs51.existsSync(path59.join(repoPath, ".cursor")),
81877
+ claudeDir: fs51.existsSync(path59.join(repoPath, ".claude")),
81878
+ codexHome: fs51.existsSync(path59.join(os19.homedir(), ".codex"))
81804
81879
  };
81805
81880
  }
81806
81881
  function formatDetectionReport(detection) {
@@ -81865,7 +81940,7 @@ function loadHarAgentsSectionFromTemplate(options = {}) {
81865
81940
  if (!templatePath) {
81866
81941
  throw new Error("AGENTS.md.template not found. Run npm run build.");
81867
81942
  }
81868
- const content = fs50.readFileSync(templatePath, "utf8");
81943
+ const content = fs51.readFileSync(templatePath, "utf8");
81869
81944
  const start = content.indexOf(HAR_SECTION_START);
81870
81945
  const end = content.indexOf(HAR_SECTION_END);
81871
81946
  if (start === -1 || end === -1 || end < start) {
@@ -81883,7 +81958,7 @@ function loadAgentsMdTemplate() {
81883
81958
  if (!templatePath) {
81884
81959
  throw new Error("AGENTS.md.template not found. Run npm run build.");
81885
81960
  }
81886
- return fs50.readFileSync(templatePath, "utf8");
81961
+ return fs51.readFileSync(templatePath, "utf8");
81887
81962
  }
81888
81963
  function upsertMarkedBlock2(content, block, startMarker, endMarker) {
81889
81964
  const existingBlock = findLastCompleteMarkedBlock(content, startMarker, endMarker);
@@ -81919,11 +81994,11 @@ function upsertAgentsMdHarSection(repoPath, options = {}) {
81919
81994
  const dest = path59.join(repoPath, AGENTS_MD);
81920
81995
  const ejected = readManifest(repoPath)?.ejected === true;
81921
81996
  const section = loadHarAgentsSectionFromTemplate({ ejected });
81922
- if (!fs50.existsSync(dest)) {
81997
+ if (!fs51.existsSync(dest)) {
81923
81998
  writeFileSafe(dest, loadAgentsMdTemplate());
81924
81999
  return "created";
81925
82000
  }
81926
- const existing = fs50.readFileSync(dest, "utf8");
82001
+ const existing = fs51.readFileSync(dest, "utf8");
81927
82002
  const sanitized = stripClaudePointerFromAgentsMd(existing);
81928
82003
  const { content, action } = upsertMarkedBlock2(
81929
82004
  sanitized,
@@ -81950,13 +82025,13 @@ function upsertAgentsMdHarSection(repoPath, options = {}) {
81950
82025
  function migrateLegacyAgentMd(repoPath) {
81951
82026
  const legacyPath = path59.join(repoPath, LEGACY_AGENT_MD);
81952
82027
  const agentsPath = path59.join(repoPath, AGENTS_MD);
81953
- if (!fs50.existsSync(legacyPath)) return false;
81954
- const legacy = fs50.readFileSync(legacyPath, "utf8");
81955
- if (!fs50.existsSync(agentsPath)) {
82028
+ if (!fs51.existsSync(legacyPath)) return false;
82029
+ const legacy = fs51.readFileSync(legacyPath, "utf8");
82030
+ if (!fs51.existsSync(agentsPath)) {
81956
82031
  writeFileSafe(agentsPath, legacy);
81957
82032
  upsertAgentsMdHarSection(repoPath);
81958
82033
  } else {
81959
- const agents = fs50.readFileSync(agentsPath, "utf8");
82034
+ const agents = fs51.readFileSync(agentsPath, "utf8");
81960
82035
  const legacyTrimmed = legacy.trim();
81961
82036
  if (legacyTrimmed.length > 0 && !agents.includes(legacyTrimmed)) {
81962
82037
  const suffix = agents.endsWith("\n") ? "" : "\n";
@@ -81966,7 +82041,7 @@ ${legacyTrimmed}
81966
82041
  }
81967
82042
  upsertAgentsMdHarSection(repoPath);
81968
82043
  }
81969
- fs50.unlinkSync(legacyPath);
82044
+ fs51.unlinkSync(legacyPath);
81970
82045
  info(`Migrated ${LEGACY_AGENT_MD} \u2192 ${AGENTS_MD} (removed legacy file)`);
81971
82046
  return true;
81972
82047
  }
@@ -81976,7 +82051,7 @@ function loadClaudeMdTemplate() {
81976
82051
  if (!templatePath) {
81977
82052
  throw new Error("CLAUDE.md.template not found. Run npm run build.");
81978
82053
  }
81979
- return fs50.readFileSync(templatePath, "utf8");
82054
+ return fs51.readFileSync(templatePath, "utf8");
81980
82055
  }
81981
82056
  function isHarOwnedClaudeMd(content) {
81982
82057
  const trimmed = content.trim();
@@ -81990,11 +82065,11 @@ function hasAgentsImport(content) {
81990
82065
  function ensureClaudeMdPointer(repoPath, options = {}) {
81991
82066
  const dest = path59.join(repoPath, CLAUDE_MD);
81992
82067
  const thin = loadClaudeMdTemplate();
81993
- if (!fs50.existsSync(dest)) {
82068
+ if (!fs51.existsSync(dest)) {
81994
82069
  writeFileSafe(dest, thin);
81995
82070
  return "created";
81996
82071
  }
81997
- const existing = fs50.readFileSync(dest, "utf8");
82072
+ const existing = fs51.readFileSync(dest, "utf8");
81998
82073
  if (isHarOwnedClaudeMd(existing) || options.force) {
81999
82074
  if (existing.trim() === CLAUDE_MD_IMPORT) return "skipped";
82000
82075
  writeFileSafe(dest, thin);
@@ -82132,15 +82207,15 @@ function readAgentMdProposal(repoPath) {
82132
82207
  const metaPath = path60.join(harnessDir, AGENTS_MD_PROPOSAL_META);
82133
82208
  const legacyProposalPath = path60.join(harnessDir, AGENT_MD_PROPOSAL);
82134
82209
  const legacyMetaPath = path60.join(harnessDir, AGENT_MD_PROPOSAL_META);
82135
- const resolvedProposal = fs51.existsSync(proposalPath) ? proposalPath : fs51.existsSync(legacyProposalPath) ? legacyProposalPath : null;
82210
+ const resolvedProposal = fs52.existsSync(proposalPath) ? proposalPath : fs52.existsSync(legacyProposalPath) ? legacyProposalPath : null;
82136
82211
  if (!resolvedProposal) return null;
82137
82212
  const resolvedMeta = resolvedProposal === proposalPath ? metaPath : legacyMetaPath;
82138
- const content = fs51.readFileSync(resolvedProposal, "utf8");
82213
+ const content = fs52.readFileSync(resolvedProposal, "utf8");
82139
82214
  let rationale = "";
82140
82215
  let createdAt = (/* @__PURE__ */ new Date()).toISOString();
82141
- if (fs51.existsSync(resolvedMeta)) {
82216
+ if (fs52.existsSync(resolvedMeta)) {
82142
82217
  try {
82143
- const meta = JSON.parse(fs51.readFileSync(resolvedMeta, "utf8"));
82218
+ const meta = JSON.parse(fs52.readFileSync(resolvedMeta, "utf8"));
82144
82219
  rationale = meta.rationale ?? "";
82145
82220
  createdAt = meta.createdAt ?? createdAt;
82146
82221
  } catch {
@@ -82158,7 +82233,7 @@ function clearAgentMdProposal(repoPath) {
82158
82233
  AGENT_MD_PROPOSAL_META
82159
82234
  ]) {
82160
82235
  const p = path60.join(harnessDir, file);
82161
- if (fs51.existsSync(p)) fs51.unlinkSync(p);
82236
+ if (fs52.existsSync(p)) fs52.unlinkSync(p);
82162
82237
  }
82163
82238
  }
82164
82239
  function wouldProposalShrinkExisting(existing, proposal) {
@@ -82172,8 +82247,8 @@ function applyAgentMdProposalMerge(repoPath, options = {}) {
82172
82247
  const proposal = readAgentMdProposal(repoPath);
82173
82248
  if (!proposal) return false;
82174
82249
  const agentsMdPath = path60.join(repoPath, AGENTS_MD);
82175
- if (fs51.existsSync(agentsMdPath)) {
82176
- const existing = fs51.readFileSync(agentsMdPath, "utf8");
82250
+ if (fs52.existsSync(agentsMdPath)) {
82251
+ const existing = fs52.readFileSync(agentsMdPath, "utf8");
82177
82252
  if (wouldProposalShrinkExisting(existing, proposal.content)) {
82178
82253
  const message = `${AGENTS_MD} proposal would drop project-specific content outside har:agent-environment markers \u2014 merge custom sections from .har/${AGENTS_MD_PROPOSAL} manually, then delete the proposal.`;
82179
82254
  if (options.rejectSignificantShrink) {
@@ -82196,7 +82271,7 @@ function finalizeAgentsMdInstructionFiles(repoPath) {
82196
82271
  }
82197
82272
 
82198
82273
  // src/harness/validator.ts
82199
- var fs53 = __toESM(require("fs"));
82274
+ var fs54 = __toESM(require("fs"));
82200
82275
  var path62 = __toESM(require("path"));
82201
82276
  init_shell();
82202
82277
  init_env();
@@ -82204,7 +82279,7 @@ init_manifest();
82204
82279
  init_stages();
82205
82280
 
82206
82281
  // src/harness/verification.ts
82207
- var fs52 = __toESM(require("fs"));
82282
+ var fs53 = __toESM(require("fs"));
82208
82283
  var path61 = __toESM(require("path"));
82209
82284
  init_env();
82210
82285
  init_provision();
@@ -82233,7 +82308,7 @@ function nodeSmokeCommand(repoPath) {
82233
82308
  const pkgPath = path61.join(repoPath, "package.json");
82234
82309
  let scripts = {};
82235
82310
  try {
82236
- scripts = JSON.parse(fs52.readFileSync(pkgPath, "utf8")).scripts ?? {};
82311
+ scripts = JSON.parse(fs53.readFileSync(pkgPath, "utf8")).scripts ?? {};
82237
82312
  } catch {
82238
82313
  scripts = {};
82239
82314
  }
@@ -82264,7 +82339,7 @@ function nodeSmokeCommand(repoPath) {
82264
82339
  function nodeScriptOrSkip(repoPath, script) {
82265
82340
  const pkgPath = path61.join(repoPath, "package.json");
82266
82341
  try {
82267
- const scripts = JSON.parse(fs52.readFileSync(pkgPath, "utf8")).scripts ?? {};
82342
+ const scripts = JSON.parse(fs53.readFileSync(pkgPath, "utf8")).scripts ?? {};
82268
82343
  if (scripts[script]) {
82269
82344
  return script === "test" ? "${NPM_BIN:-npm} test" : `\${NPM_BIN:-npm} run ${script}`;
82270
82345
  }
@@ -82389,7 +82464,7 @@ function ensureEcosystemVerificationStages(repoPath) {
82389
82464
  const skipped = /* @__PURE__ */ new Set();
82390
82465
  for (const stage of defaults.stages) {
82391
82466
  if (stages.some((s) => s.id === stage.id)) continue;
82392
- if (stage.script && !fs52.existsSync(path61.join(harnessDir, stage.script))) {
82467
+ if (stage.script && !fs53.existsSync(path61.join(harnessDir, stage.script))) {
82393
82468
  skipped.add(stage.id);
82394
82469
  continue;
82395
82470
  }
@@ -82447,7 +82522,7 @@ var SHELL_SCRIPTS = [
82447
82522
  function validateHarness(repoPath) {
82448
82523
  const harnessDir = getHarnessDir(repoPath);
82449
82524
  const issues = [];
82450
- if (!fs53.existsSync(harnessDir)) {
82525
+ if (!fs54.existsSync(harnessDir)) {
82451
82526
  return {
82452
82527
  pass: false,
82453
82528
  issues: [{ file: ".har", message: "Harness directory not found", severity: "error" }]
@@ -82455,14 +82530,14 @@ function validateHarness(repoPath) {
82455
82530
  }
82456
82531
  for (const file of getRequiredFiles(repoPath)) {
82457
82532
  const filePath = path62.join(harnessDir, file);
82458
- if (!fs53.existsSync(filePath)) {
82533
+ if (!fs54.existsSync(filePath)) {
82459
82534
  issues.push({ file, message: "Required file missing", severity: "error" });
82460
82535
  }
82461
82536
  }
82462
82537
  for (const script of SHELL_SCRIPTS) {
82463
82538
  const scriptPath = path62.join(harnessDir, script);
82464
- if (!fs53.existsSync(scriptPath)) continue;
82465
- const stat = fs53.statSync(scriptPath);
82539
+ if (!fs54.existsSync(scriptPath)) continue;
82540
+ const stat = fs54.statSync(scriptPath);
82466
82541
  if (!(stat.mode & 73)) {
82467
82542
  issues.push({ file: script, message: "Script is not executable", severity: "warning" });
82468
82543
  }
@@ -82478,8 +82553,8 @@ function validateHarness(repoPath) {
82478
82553
  const manifest = readManifest(repoPath);
82479
82554
  const profile = manifest?.profile ?? "default";
82480
82555
  const ecosystemPath = path62.join(harnessDir, "ecosystem.agent.template.cjs");
82481
- if (profile !== "cli" && fs53.existsSync(ecosystemPath)) {
82482
- const content = fs53.readFileSync(ecosystemPath, "utf8");
82556
+ if (profile !== "cli" && fs54.existsSync(ecosystemPath)) {
82557
+ const content = fs54.readFileSync(ecosystemPath, "utf8");
82483
82558
  if (!content.includes("module.exports")) {
82484
82559
  issues.push({
82485
82560
  file: "ecosystem.agent.template.cjs",
@@ -82489,8 +82564,8 @@ function validateHarness(repoPath) {
82489
82564
  }
82490
82565
  }
82491
82566
  const harnessEnvPath = path62.join(harnessDir, "harness.env");
82492
- if (fs53.existsSync(harnessEnvPath)) {
82493
- const content = fs53.readFileSync(harnessEnvPath, "utf8");
82567
+ if (fs54.existsSync(harnessEnvPath)) {
82568
+ const content = fs54.readFileSync(harnessEnvPath, "utf8");
82494
82569
  if (content.includes("TODO: set migrate command")) {
82495
82570
  issues.push({ file: "harness.env", message: "Migrate command still has TODO", severity: "warning" });
82496
82571
  }
@@ -82507,16 +82582,16 @@ function validateHarness(repoPath) {
82507
82582
  }
82508
82583
  }
82509
82584
  const verifyPath = path62.join(harnessDir, "verify.sh");
82510
- if (fs53.existsSync(verifyPath)) {
82511
- const content = fs53.readFileSync(verifyPath, "utf8");
82585
+ if (fs54.existsSync(verifyPath)) {
82586
+ const content = fs54.readFileSync(verifyPath, "utf8");
82512
82587
  if (content.includes("echo 'TODO:")) {
82513
82588
  issues.push({ file: "verify.sh", message: "Verification steps still have TODO placeholders", severity: "warning" });
82514
82589
  }
82515
82590
  }
82516
82591
  const stagesPath = path62.join(harnessDir, "stages.json");
82517
- if (fs53.existsSync(stagesPath)) {
82592
+ if (fs54.existsSync(stagesPath)) {
82518
82593
  try {
82519
- JSON.parse(fs53.readFileSync(stagesPath, "utf8"));
82594
+ JSON.parse(fs54.readFileSync(stagesPath, "utf8"));
82520
82595
  const registry2 = readStageRegistry(repoPath);
82521
82596
  if (registry2.stages.length === 0) {
82522
82597
  issues.push({ file: "stages.json", message: "No harness stages declared", severity: "warning" });
@@ -82539,8 +82614,8 @@ function validateHarness(repoPath) {
82539
82614
  issues.push({ file: "stages.json", message: "Stage registry missing", severity: "warning" });
82540
82615
  }
82541
82616
  const readmePath = path62.join(harnessDir, "README.md");
82542
- if (fs53.existsSync(readmePath)) {
82543
- const content = fs53.readFileSync(readmePath, "utf8");
82617
+ if (fs54.existsSync(readmePath)) {
82618
+ const content = fs54.readFileSync(readmePath, "utf8");
82544
82619
  if (!content.includes(".har")) {
82545
82620
  issues.push({ file: "README.md", message: "README should document .har/ paths", severity: "warning" });
82546
82621
  }
@@ -82555,7 +82630,7 @@ async function smokeTestHarness(repoPath) {
82555
82630
  const harnessDir = getHarnessDir(repoPath);
82556
82631
  const issues = [];
82557
82632
  const setupScript = path62.join(harnessDir, "setup-infra.sh");
82558
- if (fs53.existsSync(setupScript)) {
82633
+ if (fs54.existsSync(setupScript)) {
82559
82634
  const result = run(`bash "${setupScript}"`, { cwd: repoPath });
82560
82635
  if (result.code !== 0) {
82561
82636
  issues.push({
@@ -82570,7 +82645,7 @@ async function smokeTestHarness(repoPath) {
82570
82645
  }
82571
82646
 
82572
82647
  // src/harness/maintain-bundle.ts
82573
- var fs59 = __toESM(require("fs"));
82648
+ var fs60 = __toESM(require("fs"));
82574
82649
  var os21 = __toESM(require("os"));
82575
82650
  var path67 = __toESM(require("path"));
82576
82651
  init_file_ops();
@@ -82578,34 +82653,34 @@ init_shell();
82578
82653
  init_manifest();
82579
82654
 
82580
82655
  // src/harness/plugin-drift.ts
82581
- var fs58 = __toESM(require("fs"));
82656
+ var fs59 = __toESM(require("fs"));
82582
82657
  var path66 = __toESM(require("path"));
82583
82658
  init_manifest();
82584
82659
 
82585
82660
  // src/harness/plugins.ts
82586
- var fs57 = __toESM(require("fs"));
82661
+ var fs58 = __toESM(require("fs"));
82587
82662
  var path65 = __toESM(require("path"));
82588
82663
  init_zod();
82589
82664
  init_logging();
82590
82665
  init_paths();
82591
82666
 
82592
82667
  // src/harness/parser.ts
82593
- var fs54 = __toESM(require("fs"));
82668
+ var fs55 = __toESM(require("fs"));
82594
82669
  init_manifest();
82595
82670
  function harnessExists(repoPath) {
82596
- return fs54.existsSync(`${repoPath}/.har/stages.json`);
82671
+ return fs55.existsSync(`${repoPath}/.har/stages.json`);
82597
82672
  }
82598
82673
 
82599
82674
  // src/harness/bundle-resolve.ts
82600
82675
  var import_child_process16 = require("child_process");
82601
- var fs55 = __toESM(require("fs"));
82676
+ var fs56 = __toESM(require("fs"));
82602
82677
  var os20 = __toESM(require("os"));
82603
82678
  var path63 = __toESM(require("path"));
82604
82679
  init_paths();
82605
82680
  function findManifestPath(dir, config2) {
82606
82681
  for (const name of config2.manifestFiles) {
82607
82682
  const candidate = path63.join(dir, name);
82608
- if (fs55.existsSync(candidate)) return candidate;
82683
+ if (fs56.existsSync(candidate)) return candidate;
82609
82684
  }
82610
82685
  return null;
82611
82686
  }
@@ -82614,9 +82689,9 @@ function hasManifest(dir, config2) {
82614
82689
  }
82615
82690
  function readPackageVersion(dir) {
82616
82691
  const pkgPath = path63.join(dir, "package.json");
82617
- if (!fs55.existsSync(pkgPath)) return void 0;
82692
+ if (!fs56.existsSync(pkgPath)) return void 0;
82618
82693
  try {
82619
- const pkg = JSON.parse(fs55.readFileSync(pkgPath, "utf8"));
82694
+ const pkg = JSON.parse(fs56.readFileSync(pkgPath, "utf8"));
82620
82695
  return typeof pkg.version === "string" ? pkg.version : void 0;
82621
82696
  } catch {
82622
82697
  return void 0;
@@ -82626,7 +82701,7 @@ function readManifestId(dir, config2) {
82626
82701
  const manifestPath = findManifestPath(dir, config2);
82627
82702
  if (!manifestPath) return void 0;
82628
82703
  try {
82629
- const raw = JSON.parse(fs55.readFileSync(manifestPath, "utf8"));
82704
+ const raw = JSON.parse(fs56.readFileSync(manifestPath, "utf8"));
82630
82705
  return typeof raw.id === "string" ? raw.id : void 0;
82631
82706
  } catch {
82632
82707
  return void 0;
@@ -82649,7 +82724,7 @@ function expandHome(p) {
82649
82724
  return p;
82650
82725
  }
82651
82726
  function makeTempDir(prefix) {
82652
- return fs55.mkdtempSync(path63.join(os20.tmpdir(), prefix));
82727
+ return fs56.mkdtempSync(path63.join(os20.tmpdir(), prefix));
82653
82728
  }
82654
82729
  function manifestNames(config2) {
82655
82730
  return config2.manifestFiles.join(" or ");
@@ -82668,7 +82743,7 @@ function isLocalBundleDir(dir, repoPath, config2) {
82668
82743
  function resolvePathSpec(spec, repoPath, config2) {
82669
82744
  const raw = spec.startsWith("file:") ? spec.slice("file:".length) : spec;
82670
82745
  const dir = path63.resolve(expandHome(raw));
82671
- if (!fs55.existsSync(dir) || !fs55.statSync(dir).isDirectory()) {
82746
+ if (!fs56.existsSync(dir) || !fs56.statSync(dir).isDirectory()) {
82672
82747
  throw new Error(`${config2.label} path not found: ${spec}`);
82673
82748
  }
82674
82749
  if (!hasManifest(dir, config2)) {
@@ -82692,19 +82767,19 @@ function resolveNpmSpec(spec, config2) {
82692
82767
  stdio: ["ignore", "pipe", "pipe"],
82693
82768
  timeout: 12e4
82694
82769
  });
82695
- const tarballs = fs55.readdirSync(tmp).filter((f2) => f2.endsWith(".tgz"));
82770
+ const tarballs = fs56.readdirSync(tmp).filter((f2) => f2.endsWith(".tgz"));
82696
82771
  if (tarballs.length === 0) {
82697
82772
  throw new Error(`npm pack produced no tarball for ${spec}`);
82698
82773
  }
82699
82774
  const extractDir = path63.join(tmp, "extract");
82700
- fs55.mkdirSync(extractDir);
82775
+ fs56.mkdirSync(extractDir);
82701
82776
  (0, import_child_process16.execFileSync)("tar", ["-xzf", path63.join(tmp, tarballs[0]), "-C", extractDir], {
82702
82777
  encoding: "utf8",
82703
82778
  stdio: ["ignore", "pipe", "pipe"]
82704
82779
  });
82705
82780
  let dir = path63.join(extractDir, "package");
82706
82781
  if (!hasManifest(dir, config2)) {
82707
- const nested = fs55.readdirSync(extractDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path63.join(extractDir, e.name)).find((d) => hasManifest(d, config2));
82782
+ const nested = fs56.readdirSync(extractDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path63.join(extractDir, e.name)).find((d) => hasManifest(d, config2));
82708
82783
  if (!nested) {
82709
82784
  throw new Error(
82710
82785
  `npm package ${spec} has no ${manifestNames(config2)} (not a HAR ${config2.label} bundle)`
@@ -82722,7 +82797,7 @@ function resolveNpmSpec(spec, config2) {
82722
82797
  };
82723
82798
  } catch (err) {
82724
82799
  for (const d of cleanupDirs) {
82725
- fs55.rmSync(d, { recursive: true, force: true });
82800
+ fs56.rmSync(d, { recursive: true, force: true });
82726
82801
  }
82727
82802
  const message = err instanceof Error ? err.message : String(err);
82728
82803
  throw new Error(`Failed to install ${config2.label} from npm (${spec}): ${message}`);
@@ -82751,8 +82826,8 @@ function resolveGitSpec(spec, config2) {
82751
82826
  let dir = cloneDir;
82752
82827
  if (!hasManifest(dir, config2)) {
82753
82828
  const nestedRoot = path63.join(cloneDir, config2.gitNestedDir);
82754
- if (fs55.existsSync(nestedRoot)) {
82755
- const child = fs55.readdirSync(nestedRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path63.join(nestedRoot, e.name)).find((d) => hasManifest(d, config2));
82829
+ if (fs56.existsSync(nestedRoot)) {
82830
+ const child = fs56.readdirSync(nestedRoot, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path63.join(nestedRoot, e.name)).find((d) => hasManifest(d, config2));
82756
82831
  if (child) dir = child;
82757
82832
  }
82758
82833
  }
@@ -82771,7 +82846,7 @@ function resolveGitSpec(spec, config2) {
82771
82846
  };
82772
82847
  } catch (err) {
82773
82848
  for (const d of cleanupDirs) {
82774
- fs55.rmSync(d, { recursive: true, force: true });
82849
+ fs56.rmSync(d, { recursive: true, force: true });
82775
82850
  }
82776
82851
  const message = err instanceof Error ? err.message : String(err);
82777
82852
  throw new Error(`Failed to install ${config2.label} from git (${spec}): ${message}`);
@@ -82828,17 +82903,17 @@ function resolveBundleSource(spec, repoPath, config2) {
82828
82903
  }
82829
82904
  function listTemplateBundleIds(config2) {
82830
82905
  const root = path63.join(resolveTemplatesDir(), config2.templatesSubdir);
82831
- if (!fs55.existsSync(root)) return [];
82832
- return fs55.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => hasManifest(path63.join(root, name), config2)).sort();
82906
+ if (!fs56.existsSync(root)) return [];
82907
+ return fs56.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => hasManifest(path63.join(root, name), config2)).sort();
82833
82908
  }
82834
82909
  function listLocalBundleIds(repoPath, config2) {
82835
82910
  const root = path63.resolve(repoPath, config2.localDir);
82836
- if (!fs55.existsSync(root)) return [];
82837
- return fs55.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => hasManifest(path63.join(root, name), config2)).sort();
82911
+ if (!fs56.existsSync(root)) return [];
82912
+ return fs56.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => hasManifest(path63.join(root, name), config2)).sort();
82838
82913
  }
82839
82914
  function cleanupResolvedBundle(source) {
82840
82915
  for (const dir of source.cleanupDirs) {
82841
- fs55.rmSync(dir, { recursive: true, force: true });
82916
+ fs56.rmSync(dir, { recursive: true, force: true });
82842
82917
  }
82843
82918
  }
82844
82919
 
@@ -82880,7 +82955,7 @@ function cleanupResolvedPlugin(source) {
82880
82955
  }
82881
82956
 
82882
82957
  // src/harness/plugin-prompt.ts
82883
- var fs56 = __toESM(require("fs"));
82958
+ var fs57 = __toESM(require("fs"));
82884
82959
  var path64 = __toESM(require("path"));
82885
82960
  init_paths();
82886
82961
  init_file_ops();
@@ -82897,7 +82972,7 @@ function loadTemplate() {
82897
82972
  "Plugin adaptation prompt template not found: adaptation-prompt-plugin.md. Run npm run build."
82898
82973
  );
82899
82974
  }
82900
- return fs56.readFileSync(filePath, "utf8");
82975
+ return fs57.readFileSync(filePath, "utf8");
82901
82976
  }
82902
82977
  function resolveInstallCommand(repoPath) {
82903
82978
  const env3 = readHarnessEnv(repoPath);
@@ -82978,7 +83053,7 @@ function primaryStageId(manifest) {
82978
83053
  }
82979
83054
  function resolveBundledPluginDir(pluginId) {
82980
83055
  const dir = path65.join(resolveTemplatesDir(), "plugins", pluginId);
82981
- if (!fs57.existsSync(dir)) {
83056
+ if (!fs58.existsSync(dir)) {
82982
83057
  throw new Error(`Plugin not found: ${pluginId}. Run npm run build.`);
82983
83058
  }
82984
83059
  return dir;
@@ -82988,7 +83063,7 @@ function readPluginManifestFromDir(pluginDir, expectedId) {
82988
83063
  if (!manifestPath) {
82989
83064
  throw new Error(`No template.manifest.json in ${pluginDir}`);
82990
83065
  }
82991
- const raw = JSON.parse(fs57.readFileSync(manifestPath, "utf8"));
83066
+ const raw = JSON.parse(fs58.readFileSync(manifestPath, "utf8"));
82992
83067
  if (raw.kind === LINE_BUNDLE_KIND || path65.basename(manifestPath) === "line.manifest.json") {
82993
83068
  throw new Error(
82994
83069
  `${path65.basename(manifestPath)} declares "kind": "line" \u2014 this is a factory line bundle, not a verification plugin. Install it with: har line add <spec>`
@@ -83008,39 +83083,39 @@ function readPluginManifest(pluginId) {
83008
83083
  }
83009
83084
  function ensureParentDir(filePath) {
83010
83085
  const parent = path65.dirname(filePath);
83011
- if (!fs57.existsSync(parent)) {
83012
- fs57.mkdirSync(parent, { recursive: true });
83086
+ if (!fs58.existsSync(parent)) {
83087
+ fs58.mkdirSync(parent, { recursive: true });
83013
83088
  }
83014
83089
  }
83015
83090
  function copyPluginFile(pluginDir, file, repoPath, force) {
83016
83091
  const srcPath = path65.join(pluginDir, file.src);
83017
83092
  const destPath = path65.join(repoPath, file.dest);
83018
- if (!fs57.existsSync(srcPath)) {
83093
+ if (!fs58.existsSync(srcPath)) {
83019
83094
  throw new Error(`Plugin file missing: ${file.src}`);
83020
83095
  }
83021
- if (fs57.existsSync(destPath) && !force) {
83096
+ if (fs58.existsSync(destPath) && !force) {
83022
83097
  throw new Error(
83023
83098
  `File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
83024
83099
  );
83025
83100
  }
83026
83101
  ensureParentDir(destPath);
83027
- fs57.copyFileSync(srcPath, destPath);
83102
+ fs58.copyFileSync(srcPath, destPath);
83028
83103
  if (file.executable) {
83029
- fs57.chmodSync(destPath, 493);
83104
+ fs58.chmodSync(destPath, 493);
83030
83105
  }
83031
83106
  return { written: true, path: file.dest };
83032
83107
  }
83033
83108
  function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
83034
83109
  const packagePath = path65.join(repoPath, "package.json");
83035
- if (!fs57.existsSync(packagePath)) {
83110
+ if (!fs58.existsSync(packagePath)) {
83036
83111
  throw new Error("No package.json in repo root. Add one before applying this plugin.");
83037
83112
  }
83038
83113
  const fragmentPath = path65.join(pluginDir, fragmentRelPath);
83039
- if (!fs57.existsSync(fragmentPath)) {
83114
+ if (!fs58.existsSync(fragmentPath)) {
83040
83115
  throw new Error(`Package fragment missing: ${fragmentRelPath}`);
83041
83116
  }
83042
- const pkg = JSON.parse(fs57.readFileSync(packagePath, "utf8"));
83043
- const fragment = JSON.parse(fs57.readFileSync(fragmentPath, "utf8"));
83117
+ const pkg = JSON.parse(fs58.readFileSync(packagePath, "utf8"));
83118
+ const fragment = JSON.parse(fs58.readFileSync(fragmentPath, "utf8"));
83044
83119
  for (const section of ["scripts", "devDependencies"]) {
83045
83120
  const existing = pkg[section] ?? {};
83046
83121
  const incoming = fragment[section] ?? {};
@@ -83053,7 +83128,7 @@ function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
83053
83128
  }
83054
83129
  pkg[section] = existing;
83055
83130
  }
83056
- fs57.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
83131
+ fs58.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
83057
83132
  }
83058
83133
  function patchStageRegistry(repoPath, stages, verificationStageIds, force) {
83059
83134
  const registry2 = readStageRegistry(repoPath);
@@ -83090,7 +83165,7 @@ function assertStagesNotPresent(repoPath, stageIds, force) {
83090
83165
  const registry2 = readStageRegistry(repoPath);
83091
83166
  for (const stageId of stageIds) {
83092
83167
  const scriptPath = path65.join(repoPath, ".har", "stages", `${stageId}.sh`);
83093
- if (fs57.existsSync(scriptPath)) {
83168
+ if (fs58.existsSync(scriptPath)) {
83094
83169
  throw new Error(
83095
83170
  `Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
83096
83171
  );
@@ -83123,7 +83198,7 @@ function applyPluginFromDir(repoPath, pluginDir, options, meta) {
83123
83198
  if (file.skipFlag === "skipCi" && options.skipCi) {
83124
83199
  continue;
83125
83200
  }
83126
- if (fs57.existsSync(path65.join(resolved, file.dest)) && !force) {
83201
+ if (fs58.existsSync(path65.join(resolved, file.dest)) && !force) {
83127
83202
  warnings.push(`Skipped optional file (exists): ${file.dest}`);
83128
83203
  continue;
83129
83204
  }
@@ -83205,7 +83280,7 @@ function detectInstalledPlugins(repoPath) {
83205
83280
  return ledger.plugins.map((p) => p.id).sort();
83206
83281
  }
83207
83282
  const registryPath = path66.join(resolved, ".har", "stages.json");
83208
- if (!fs58.existsSync(registryPath)) return [];
83283
+ if (!fs59.existsSync(registryPath)) return [];
83209
83284
  const registry2 = readStageRegistry(resolved);
83210
83285
  const stageIds = new Set(registry2.stages.map((stage) => stage.id));
83211
83286
  const installed = [];
@@ -83227,13 +83302,13 @@ function resolvePluginBaseline(repoPath, pluginId) {
83227
83302
  const entry = ledger?.plugins.find((p) => p.id === pluginId);
83228
83303
  if (entry?.source === "local") {
83229
83304
  const localDir = path66.join(resolved, LOCAL_PLUGINS_DIR, pluginId);
83230
- if (fs58.existsSync(path66.join(localDir, "template.manifest.json"))) {
83305
+ if (fs59.existsSync(path66.join(localDir, "template.manifest.json"))) {
83231
83306
  return { kind: "local", dir: localDir, manifest: readPluginManifestFromDir(localDir) };
83232
83307
  }
83233
83308
  return null;
83234
83309
  }
83235
83310
  const bundled = path66.join(resolveTemplatesDir(), "plugins", pluginId);
83236
- if (fs58.existsSync(path66.join(bundled, "template.manifest.json"))) {
83311
+ if (fs59.existsSync(path66.join(bundled, "template.manifest.json"))) {
83237
83312
  return { kind: "bundled", dir: bundled, manifest: readPluginManifestFromDir(bundled) };
83238
83313
  }
83239
83314
  return null;
@@ -83246,14 +83321,14 @@ function requireBaseline(repoPath, pluginId) {
83246
83321
  return baseline;
83247
83322
  }
83248
83323
  function readBaselineFile(baseline, srcRel) {
83249
- return fs58.readFileSync(path66.join(baseline.dir, srcRel), "utf8");
83324
+ return fs59.readFileSync(path66.join(baseline.dir, srcRel), "utf8");
83250
83325
  }
83251
83326
  function listPluginDestPaths(baseline, repoPath) {
83252
83327
  const manifest = baseline.manifest;
83253
83328
  const paths = manifest.files.map((file) => file.dest);
83254
83329
  if (manifest.optionalFiles) {
83255
83330
  for (const file of manifest.optionalFiles) {
83256
- if (fs58.existsSync(path66.join(repoPath, file.dest))) {
83331
+ if (fs59.existsSync(path66.join(repoPath, file.dest))) {
83257
83332
  paths.push(file.dest);
83258
83333
  }
83259
83334
  }
@@ -83313,8 +83388,8 @@ function readTemplatePluginFile(repoPath, pluginId, dest) {
83313
83388
  }
83314
83389
  function readInstalledPluginFile(repoPath, pluginId, dest) {
83315
83390
  const installedPath = path66.join(path66.resolve(repoPath), dest);
83316
- if (!fs58.existsSync(installedPath)) return null;
83317
- const content = fs58.readFileSync(installedPath, "utf8");
83391
+ if (!fs59.existsSync(installedPath)) return null;
83392
+ const content = fs59.readFileSync(installedPath, "utf8");
83318
83393
  const baseline = requireBaseline(repoPath, pluginId);
83319
83394
  const fragmentRel = baseline.manifest.merge?.[dest];
83320
83395
  if (fragmentRel) {
@@ -83356,7 +83431,7 @@ function comparePluginToTemplate(repoPath, pluginId) {
83356
83431
  if (dest === "package.json") {
83357
83432
  const fragmentRel = manifest.merge?.[dest];
83358
83433
  const installedPath = path66.join(resolved, dest);
83359
- const installedRaw = fs58.readFileSync(installedPath, "utf8");
83434
+ const installedRaw = fs59.readFileSync(installedPath, "utf8");
83360
83435
  if (fragmentRel && pluginKeysMatch(installedRaw, readBaselineFile(baseline, fragmentRel))) {
83361
83436
  unchanged.push(dest);
83362
83437
  } else if (computeFileChecksum(installedContent) === computeFileChecksum(templateContent)) {
@@ -83456,12 +83531,12 @@ function actionHint(file, kind) {
83456
83531
  return `Upstream template updated since your last finalize \u2014 read maintain/diffs/${file}.diff and apply into .har/${file}.`;
83457
83532
  }
83458
83533
  function createUnifiedDiff(installedContent, templateContent, installedLabel, templateLabel) {
83459
- const tmpDir = fs59.mkdtempSync(path67.join(os21.tmpdir(), "har-maintain-diff-"));
83534
+ const tmpDir = fs60.mkdtempSync(path67.join(os21.tmpdir(), "har-maintain-diff-"));
83460
83535
  try {
83461
83536
  const installedPath = path67.join(tmpDir, "installed");
83462
83537
  const templatePath = path67.join(tmpDir, "template");
83463
- fs59.writeFileSync(installedPath, installedContent);
83464
- fs59.writeFileSync(templatePath, templateContent);
83538
+ fs60.writeFileSync(installedPath, installedContent);
83539
+ fs60.writeFileSync(templatePath, templateContent);
83465
83540
  const result = run(`diff -u "${installedPath}" "${templatePath}"`);
83466
83541
  const body = result.stdout.trim();
83467
83542
  if (!body) return "";
@@ -83470,7 +83545,7 @@ function createUnifiedDiff(installedContent, templateContent, installedLabel, te
83470
83545
  ${body.split("\n").slice(2).join("\n")}
83471
83546
  `;
83472
83547
  } finally {
83473
- fs59.rmSync(tmpDir, { recursive: true, force: true });
83548
+ fs60.rmSync(tmpDir, { recursive: true, force: true });
83474
83549
  }
83475
83550
  }
83476
83551
  function buildActions(repoPath, profile, drift) {
@@ -83494,7 +83569,7 @@ function buildActions(repoPath, profile, drift) {
83494
83569
  file,
83495
83570
  kind,
83496
83571
  template: `maintain/templates/${file}`,
83497
- installed: fs59.existsSync(installedPath) ? `maintain/installed/${file}` : void 0,
83572
+ installed: fs60.existsSync(installedPath) ? `maintain/installed/${file}` : void 0,
83498
83573
  diff: `maintain/diffs/${file}.diff`,
83499
83574
  hint: actionHint(file, kind)
83500
83575
  });
@@ -83666,8 +83741,8 @@ function buildReadme(report) {
83666
83741
  function writeBundleArtifacts(repoPath, profile, drift, report) {
83667
83742
  const harnessDir = getHarnessDir(repoPath);
83668
83743
  const bundleDir = path67.join(harnessDir, MAINTAIN_DIR);
83669
- if (fs59.existsSync(bundleDir)) {
83670
- fs59.rmSync(bundleDir, { recursive: true, force: true });
83744
+ if (fs60.existsSync(bundleDir)) {
83745
+ fs60.rmSync(bundleDir, { recursive: true, force: true });
83671
83746
  }
83672
83747
  const dirs = [
83673
83748
  bundleDir,
@@ -83677,15 +83752,15 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
83677
83752
  path67.join(bundleDir, "stale")
83678
83753
  ];
83679
83754
  for (const dir of dirs) {
83680
- fs59.mkdirSync(dir, { recursive: true });
83755
+ fs60.mkdirSync(dir, { recursive: true });
83681
83756
  }
83682
83757
  const affectedFiles = [...drift.missing, ...drift.upstreamUpdated, ...drift.conflict];
83683
83758
  for (const file of affectedFiles) {
83684
83759
  const templateContent = readBundledTemplateContent(repoPath, profile, file);
83685
83760
  writeFileSafe(path67.join(bundleDir, "templates", file), templateContent);
83686
83761
  const harnessPath = path67.join(harnessDir, file);
83687
- if (fs59.existsSync(harnessPath)) {
83688
- const installedContent = fs59.readFileSync(harnessPath, "utf8");
83762
+ if (fs60.existsSync(harnessPath)) {
83763
+ const installedContent = fs60.readFileSync(harnessPath, "utf8");
83689
83764
  writeFileSafe(path67.join(bundleDir, "installed", file), installedContent);
83690
83765
  const diff = createUnifiedDiff(
83691
83766
  installedContent,
@@ -83719,8 +83794,8 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
83719
83794
  }
83720
83795
  function ensureParentDir2(filePath) {
83721
83796
  const parent = path67.dirname(filePath);
83722
- if (!fs59.existsSync(parent)) {
83723
- fs59.mkdirSync(parent, { recursive: true });
83797
+ if (!fs60.existsSync(parent)) {
83798
+ fs60.mkdirSync(parent, { recursive: true });
83724
83799
  }
83725
83800
  }
83726
83801
  function writePluginBundleArtifacts(repoPath, bundleDir, report) {
@@ -83731,7 +83806,7 @@ function writePluginBundleArtifacts(repoPath, bundleDir, report) {
83731
83806
  const installedDir = path67.join(pluginRoot, "installed");
83732
83807
  const diffsDir = path67.join(pluginRoot, "diffs");
83733
83808
  for (const dir of [templatesDir, installedDir, diffsDir]) {
83734
- fs59.mkdirSync(dir, { recursive: true });
83809
+ fs60.mkdirSync(dir, { recursive: true });
83735
83810
  }
83736
83811
  const templateContent = readTemplatePluginFile(repoPath, action.pluginId, action.file);
83737
83812
  if (templateContent === null) continue;
@@ -83787,8 +83862,8 @@ function buildMaintainBundle(repoPath, validation2, drift) {
83787
83862
  }
83788
83863
  function removeMaintainBundle(repoPath) {
83789
83864
  const bundleDir = path67.join(getHarnessDir(repoPath), MAINTAIN_DIR);
83790
- if (fs59.existsSync(bundleDir)) {
83791
- fs59.rmSync(bundleDir, { recursive: true, force: true });
83865
+ if (fs60.existsSync(bundleDir)) {
83866
+ fs60.rmSync(bundleDir, { recursive: true, force: true });
83792
83867
  }
83793
83868
  }
83794
83869
  function formatMaintainBundlePromptSection(report) {
@@ -83897,7 +83972,7 @@ init_manifest();
83897
83972
  init_stages();
83898
83973
 
83899
83974
  // src/harness/doctor.ts
83900
- var fs64 = __toESM(require("fs"));
83975
+ var fs65 = __toESM(require("fs"));
83901
83976
  var path73 = __toESM(require("path"));
83902
83977
  init_package_version();
83903
83978
  init_slot_registry();
@@ -83914,7 +83989,7 @@ function compareSemver(a, b2) {
83914
83989
  }
83915
83990
 
83916
83991
  // src/harness/eject.ts
83917
- var fs60 = __toESM(require("fs"));
83992
+ var fs61 = __toESM(require("fs"));
83918
83993
  var path68 = __toESM(require("path"));
83919
83994
  init_package_version();
83920
83995
  init_manifest();
@@ -83922,7 +83997,7 @@ var EJECTED_RUNTIME_DIR = "runtime";
83922
83997
  var EJECTED_RUNTIME_BUNDLE = "har.cjs";
83923
83998
  function resolveRuntimeBundleSource() {
83924
83999
  if (process.env.HAR_EJECT_RUNTIME_SOURCE) {
83925
- return fs60.existsSync(process.env.HAR_EJECT_RUNTIME_SOURCE) ? process.env.HAR_EJECT_RUNTIME_SOURCE : null;
84000
+ return fs61.existsSync(process.env.HAR_EJECT_RUNTIME_SOURCE) ? process.env.HAR_EJECT_RUNTIME_SOURCE : null;
83926
84001
  }
83927
84002
  const candidates = [
83928
84003
  // Bundled CLI: __dirname is dist/ and index.js is the self-contained runtime.
@@ -83931,7 +84006,7 @@ function resolveRuntimeBundleSource() {
83931
84006
  path68.resolve(__dirname, "..", "..", "dist", "index.js")
83932
84007
  ];
83933
84008
  for (const candidate of candidates) {
83934
- if (fs60.existsSync(candidate)) return candidate;
84009
+ if (fs61.existsSync(candidate)) return candidate;
83935
84010
  }
83936
84011
  return null;
83937
84012
  }
@@ -83973,11 +84048,11 @@ function ejectHarness(repoPath) {
83973
84048
  }
83974
84049
  const version2 = getHarPackageVersion();
83975
84050
  const runtimeDir = path68.join(harnessDir, EJECTED_RUNTIME_DIR);
83976
- fs60.mkdirSync(runtimeDir, { recursive: true });
84051
+ fs61.mkdirSync(runtimeDir, { recursive: true });
83977
84052
  const runtimeFile = path68.join(runtimeDir, EJECTED_RUNTIME_BUNDLE);
83978
- fs60.copyFileSync(bundleSource, runtimeFile);
83979
- fs60.chmodSync(runtimeFile, 493);
83980
- fs60.writeFileSync(path68.join(runtimeDir, "README.md"), RUNTIME_README(version2));
84053
+ fs61.copyFileSync(bundleSource, runtimeFile);
84054
+ fs61.chmodSync(runtimeFile, 493);
84055
+ fs61.writeFileSync(path68.join(runtimeDir, "README.md"), RUNTIME_README(version2));
83981
84056
  retireLifecycleShims(resolved);
83982
84057
  writeManifest(resolved, {
83983
84058
  ...manifest,
@@ -83998,7 +84073,7 @@ function adoptHarness(repoPath) {
83998
84073
  if (!manifest.ejected) {
83999
84074
  throw new Error("Harness is not ejected \u2014 the packaged runtime is already in use.");
84000
84075
  }
84001
- fs60.rmSync(path68.join(harnessDir, EJECTED_RUNTIME_DIR), { recursive: true, force: true });
84076
+ fs61.rmSync(path68.join(harnessDir, EJECTED_RUNTIME_DIR), { recursive: true, force: true });
84002
84077
  const retired = retireLifecycleShims(resolved);
84003
84078
  const rest = { ...manifest };
84004
84079
  delete rest.ejected;
@@ -84016,7 +84091,7 @@ init_env();
84016
84091
  init_manifest();
84017
84092
 
84018
84093
  // src/harness/line-ledger.ts
84019
- var fs61 = __toESM(require("fs"));
84094
+ var fs62 = __toESM(require("fs"));
84020
84095
  var path69 = __toESM(require("path"));
84021
84096
  init_file_ops();
84022
84097
  init_manifest();
@@ -84026,9 +84101,9 @@ function getLineLedgerPath(repoPath) {
84026
84101
  }
84027
84102
  function readLineLedger(repoPath) {
84028
84103
  const ledgerPath = getLineLedgerPath(repoPath);
84029
- if (!fs61.existsSync(ledgerPath)) return null;
84104
+ if (!fs62.existsSync(ledgerPath)) return null;
84030
84105
  try {
84031
- const parsed = LineLedgerSchema.safeParse(JSON.parse(fs61.readFileSync(ledgerPath, "utf8")));
84106
+ const parsed = LineLedgerSchema.safeParse(JSON.parse(fs62.readFileSync(ledgerPath, "utf8")));
84032
84107
  return parsed.success ? parsed.data : null;
84033
84108
  } catch {
84034
84109
  return null;
@@ -84037,8 +84112,8 @@ function readLineLedger(repoPath) {
84037
84112
  function writeLineLedger(repoPath, ledger) {
84038
84113
  const ledgerPath = getLineLedgerPath(repoPath);
84039
84114
  const harnessDir = path69.dirname(ledgerPath);
84040
- if (!fs61.existsSync(harnessDir)) {
84041
- fs61.mkdirSync(harnessDir, { recursive: true });
84115
+ if (!fs62.existsSync(harnessDir)) {
84116
+ fs62.mkdirSync(harnessDir, { recursive: true });
84042
84117
  }
84043
84118
  writeFileSafe(ledgerPath, `${JSON.stringify(ledger, null, 2)}
84044
84119
  `);
@@ -84054,7 +84129,7 @@ function upsertLineLedgerEntry(repoPath, entry) {
84054
84129
  }
84055
84130
 
84056
84131
  // src/harness/lines.ts
84057
- var fs62 = __toESM(require("fs"));
84132
+ var fs63 = __toESM(require("fs"));
84058
84133
  var path71 = __toESM(require("path"));
84059
84134
  init_logging();
84060
84135
 
@@ -84198,7 +84273,7 @@ function readLineManifestFromDir(bundleDir, expectedId) {
84198
84273
  if (!manifestPath) {
84199
84274
  throw new Error(`No ${LINE_MANIFEST_FILES.join(" or ")} in ${bundleDir}`);
84200
84275
  }
84201
- const raw = JSON.parse(fs62.readFileSync(manifestPath, "utf8"));
84276
+ const raw = JSON.parse(fs63.readFileSync(manifestPath, "utf8"));
84202
84277
  if (raw.kind !== LINE_BUNDLE_KIND) {
84203
84278
  throw new Error(
84204
84279
  `${path71.basename(manifestPath)} is not a factory line bundle (missing "kind": "line"). Verification plugins install with: har env add-plugin <spec>`
@@ -84215,10 +84290,10 @@ function readLineManifestFromDir(bundleDir, expectedId) {
84215
84290
  }
84216
84291
  function readLineProgramFromDir(bundleDir, manifest) {
84217
84292
  const programPath = path71.join(bundleDir, manifest.program);
84218
- if (!fs62.existsSync(programPath)) {
84293
+ if (!fs63.existsSync(programPath)) {
84219
84294
  throw new Error(`Line program missing: ${manifest.program} (referenced by line.manifest.json)`);
84220
84295
  }
84221
- const parsed = LineProgramSchema.safeParse(JSON.parse(fs62.readFileSync(programPath, "utf8")));
84296
+ const parsed = LineProgramSchema.safeParse(JSON.parse(fs63.readFileSync(programPath, "utf8")));
84222
84297
  if (!parsed.success) {
84223
84298
  throw new Error(`Invalid line program (${manifest.program}): ${parsed.error.message}`);
84224
84299
  }
@@ -84231,31 +84306,31 @@ function readLineProgramFromDir(bundleDir, manifest) {
84231
84306
  }
84232
84307
  function readInstalledLineProgram(repoPath, lineId) {
84233
84308
  const programPath = path71.join(path71.resolve(repoPath), lineProgramPathRel(lineId));
84234
- if (!fs62.existsSync(programPath)) return null;
84235
- const parsed = LineProgramSchema.safeParse(JSON.parse(fs62.readFileSync(programPath, "utf8")));
84309
+ if (!fs63.existsSync(programPath)) return null;
84310
+ const parsed = LineProgramSchema.safeParse(JSON.parse(fs63.readFileSync(programPath, "utf8")));
84236
84311
  return parsed.success ? parsed.data : null;
84237
84312
  }
84238
84313
  function ensureParentDir3(filePath) {
84239
- fs62.mkdirSync(path71.dirname(filePath), { recursive: true });
84314
+ fs63.mkdirSync(path71.dirname(filePath), { recursive: true });
84240
84315
  }
84241
84316
  function copyBundleFile(bundleDir, file, repoPath, force) {
84242
84317
  const srcPath = path71.join(bundleDir, file.src);
84243
84318
  const destPath = path71.join(repoPath, file.dest);
84244
- if (!fs62.existsSync(srcPath)) {
84319
+ if (!fs63.existsSync(srcPath)) {
84245
84320
  throw new Error(`Line file missing: ${file.src}`);
84246
84321
  }
84247
84322
  if (path71.resolve(srcPath) === path71.resolve(destPath)) {
84248
84323
  return file.dest;
84249
84324
  }
84250
- if (fs62.existsSync(destPath) && !force) {
84325
+ if (fs63.existsSync(destPath) && !force) {
84251
84326
  throw new Error(
84252
84327
  `File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
84253
84328
  );
84254
84329
  }
84255
84330
  ensureParentDir3(destPath);
84256
- fs62.copyFileSync(srcPath, destPath);
84331
+ fs63.copyFileSync(srcPath, destPath);
84257
84332
  if (file.executable) {
84258
- fs62.chmodSync(destPath, 493);
84333
+ fs63.chmodSync(destPath, 493);
84259
84334
  }
84260
84335
  return file.dest;
84261
84336
  }
@@ -84314,20 +84389,20 @@ function applyLineFromDir(repoPath, bundleDir, options, meta) {
84314
84389
  const programDest = path71.join(resolved, lineProgramPathRel(manifest.id));
84315
84390
  const programSrc = path71.join(bundleDir, manifest.program);
84316
84391
  if (path71.resolve(programSrc) !== path71.resolve(programDest)) {
84317
- if (fs62.existsSync(programDest) && !force) {
84392
+ if (fs63.existsSync(programDest) && !force) {
84318
84393
  throw new Error(
84319
84394
  `Line already installed: ${lineProgramPathRel(manifest.id)}. Use --force to replace.`
84320
84395
  );
84321
84396
  }
84322
84397
  ensureParentDir3(programDest);
84323
- fs62.copyFileSync(programSrc, programDest);
84398
+ fs63.copyFileSync(programSrc, programDest);
84324
84399
  }
84325
84400
  filesWritten.push(lineProgramPathRel(manifest.id));
84326
84401
  const manifestDest = path71.join(resolved, lineDirRel(manifest.id), "line.manifest.json");
84327
84402
  const manifestSrc = findManifestPath(bundleDir, LINE_BUNDLE_CONFIG);
84328
84403
  if (path71.resolve(manifestSrc) !== path71.resolve(manifestDest)) {
84329
84404
  ensureParentDir3(manifestDest);
84330
- fs62.copyFileSync(manifestSrc, manifestDest);
84405
+ fs63.copyFileSync(manifestSrc, manifestDest);
84331
84406
  filesWritten.push(`${lineDirRel(manifest.id)}/line.manifest.json`);
84332
84407
  }
84333
84408
  registerStagesOnly(resolved, stages, force);
@@ -84408,7 +84483,7 @@ init_stages();
84408
84483
  init_hooks2();
84409
84484
 
84410
84485
  // src/harness/migrations.ts
84411
- var fs63 = __toESM(require("fs"));
84486
+ var fs64 = __toESM(require("fs"));
84412
84487
  var path72 = __toESM(require("path"));
84413
84488
  init_schema2();
84414
84489
  init_manifest();
@@ -84459,24 +84534,24 @@ function harnessEnvIsPre10(content) {
84459
84534
  }
84460
84535
  function scriptIsVendored(harnessDir, script) {
84461
84536
  const file = path72.join(harnessDir, script);
84462
- if (!fs63.existsSync(file)) return false;
84463
- const content = fs63.readFileSync(file, "utf8");
84537
+ if (!fs64.existsSync(file)) return false;
84538
+ const content = fs64.readFileSync(file, "utf8");
84464
84539
  return !content.includes("exec har env") && !content.includes("runtime/har.cjs");
84465
84540
  }
84466
84541
  function isPre10Harness(repoPath) {
84467
84542
  const resolved = path72.resolve(repoPath);
84468
84543
  const harnessDir = getHarnessDir(resolved);
84469
- if (!fs63.existsSync(harnessDir)) return false;
84544
+ if (!fs64.existsSync(harnessDir)) return false;
84470
84545
  const manifest = readManifest(resolved);
84471
84546
  if (manifest?.ejected) return false;
84472
84547
  for (const file of LEGACY_MACHINERY_FILES) {
84473
- if (fs63.existsSync(path72.join(harnessDir, file))) return true;
84548
+ if (fs64.existsSync(path72.join(harnessDir, file))) return true;
84474
84549
  }
84475
84550
  for (const script of MANAGED_SHIM_FILES) {
84476
84551
  if (scriptIsVendored(harnessDir, script)) return true;
84477
84552
  }
84478
84553
  const envPath = path72.join(harnessDir, "harness.env");
84479
- if (fs63.existsSync(envPath) && harnessEnvIsPre10(fs63.readFileSync(envPath, "utf8"))) {
84554
+ if (fs64.existsSync(envPath) && harnessEnvIsPre10(fs64.readFileSync(envPath, "utf8"))) {
84480
84555
  return true;
84481
84556
  }
84482
84557
  return false;
@@ -84621,7 +84696,7 @@ function buildPre10Plan(repoPath) {
84621
84696
  const deleteLifecycleScripts = [];
84622
84697
  const residue = [];
84623
84698
  for (const script of MANAGED_SHIM_FILES) {
84624
- if (!fs63.existsSync(path72.join(harnessDir, script))) continue;
84699
+ if (!fs64.existsSync(path72.join(harnessDir, script))) continue;
84625
84700
  deleteLifecycleScripts.push(script);
84626
84701
  if (scriptIsVendored(harnessDir, script)) {
84627
84702
  const target = SCRIPT_RESIDUE_TARGET[script] ?? "review";
@@ -84636,16 +84711,16 @@ function buildPre10Plan(repoPath) {
84636
84711
  const survivingScripts = [];
84637
84712
  for (const dir of ["stages", "hooks"]) {
84638
84713
  const full = path72.join(harnessDir, dir);
84639
- if (!fs63.existsSync(full)) continue;
84640
- for (const entry of fs63.readdirSync(full)) {
84714
+ if (!fs64.existsSync(full)) continue;
84715
+ for (const entry of fs64.readdirSync(full)) {
84641
84716
  if (entry.endsWith(".sh") || entry.endsWith(".mjs")) survivingScripts.push(path72.join(dir, entry));
84642
84717
  }
84643
84718
  }
84644
- for (const entry of fs63.readdirSync(harnessDir)) {
84719
+ for (const entry of fs64.readdirSync(harnessDir)) {
84645
84720
  if (!entry.endsWith(".sh")) continue;
84646
84721
  if (MANAGED_SHIM_FILES.includes(entry)) continue;
84647
84722
  if (LEGACY_MACHINERY_FILES.includes(entry)) continue;
84648
- if (!fs63.statSync(path72.join(harnessDir, entry)).isFile()) continue;
84723
+ if (!fs64.statSync(path72.join(harnessDir, entry)).isFile()) continue;
84649
84724
  survivingScripts.push(entry);
84650
84725
  }
84651
84726
  const referencedBy = (machineryFile) => {
@@ -84654,12 +84729,12 @@ function buildPre10Plan(repoPath) {
84654
84729
  `(?:\\bsource\\b|\\bbash\\b|\\bexec\\b|(?:^|[;&|(])\\s*\\.\\s)[^\\n#]*${base}`
84655
84730
  );
84656
84731
  return survivingScripts.filter(
84657
- (script) => fs63.readFileSync(path72.join(harnessDir, script), "utf8").split("\n").some((line) => !/^\s*#/.test(line) && loadRe.test(line))
84732
+ (script) => fs64.readFileSync(path72.join(harnessDir, script), "utf8").split("\n").some((line) => !/^\s*#/.test(line) && loadRe.test(line))
84658
84733
  );
84659
84734
  };
84660
84735
  const retireDocs = [];
84661
84736
  for (const doc of RETIRED_DOC_FILES) {
84662
- if (!fs63.existsSync(path72.join(harnessDir, doc))) continue;
84737
+ if (!fs64.existsSync(path72.join(harnessDir, doc))) continue;
84663
84738
  retireDocs.push(doc);
84664
84739
  residue.push({
84665
84740
  source: doc,
@@ -84673,7 +84748,7 @@ function buildPre10Plan(repoPath) {
84673
84748
  const retainMachinery = [];
84674
84749
  for (const file of LEGACY_MACHINERY_FILES) {
84675
84750
  const full = path72.join(harnessDir, file);
84676
- if (!fs63.existsSync(full)) continue;
84751
+ if (!fs64.existsSync(full)) continue;
84677
84752
  const refs = referencedBy(file);
84678
84753
  if (refs.length > 0) {
84679
84754
  retainMachinery.push(file);
@@ -84687,7 +84762,7 @@ function buildPre10Plan(repoPath) {
84687
84762
  }
84688
84763
  deleteMachinery.push(file);
84689
84764
  const recorded = fileBaseline[file];
84690
- const installed = computeFileChecksum(fs63.readFileSync(full, "utf8"));
84765
+ const installed = computeFileChecksum(fs64.readFileSync(full, "utf8"));
84691
84766
  if (recorded !== void 0 && installed !== recorded) {
84692
84767
  editedMachinery.push(file);
84693
84768
  residue.push({
@@ -84700,8 +84775,8 @@ function buildPre10Plan(repoPath) {
84700
84775
  }
84701
84776
  let env3 = null;
84702
84777
  const envPath = path72.join(harnessDir, "harness.env");
84703
- if (fs63.existsSync(envPath)) {
84704
- const content = fs63.readFileSync(envPath, "utf8");
84778
+ if (fs64.existsSync(envPath)) {
84779
+ const content = fs64.readFileSync(envPath, "utf8");
84705
84780
  if (harnessEnvIsPre10(content) || migrateHarnessEnvContent(content).commentedKeys.length > 0) {
84706
84781
  env3 = migrateHarnessEnvContent(content);
84707
84782
  for (const fn of env3.customFunctions) {
@@ -84726,7 +84801,7 @@ function buildPre10Plan(repoPath) {
84726
84801
  for (const file of composed.keys()) {
84727
84802
  if (MANAGED_SHIM_FILES.includes(file)) continue;
84728
84803
  if (file === "gitignore.template") continue;
84729
- if (!fs63.existsSync(path72.join(harnessDir, file))) installMissing.push(file);
84804
+ if (!fs64.existsSync(path72.join(harnessDir, file))) installMissing.push(file);
84730
84805
  }
84731
84806
  let phantomVerificationIds = [];
84732
84807
  try {
@@ -84761,13 +84836,13 @@ function applyPre10Plan(repoPath, plan) {
84761
84836
  const harnessDir = getHarnessDir(resolved);
84762
84837
  const effective = plan ?? buildPre10Plan(resolved);
84763
84838
  const backupDir = path72.join(harnessDir, MIGRATE_BACKUP_DIR);
84764
- fs63.mkdirSync(backupDir, { recursive: true });
84839
+ fs64.mkdirSync(backupDir, { recursive: true });
84765
84840
  const backup = (file) => {
84766
84841
  const src = path72.join(harnessDir, file);
84767
- if (!fs63.existsSync(src)) return;
84842
+ if (!fs64.existsSync(src)) return;
84768
84843
  const dest = path72.join(backupDir, file);
84769
- fs63.mkdirSync(path72.dirname(dest), { recursive: true });
84770
- fs63.copyFileSync(src, dest);
84844
+ fs64.mkdirSync(path72.dirname(dest), { recursive: true });
84845
+ fs64.copyFileSync(src, dest);
84771
84846
  };
84772
84847
  const written = [];
84773
84848
  const deleted = [];
@@ -84775,7 +84850,7 @@ function applyPre10Plan(repoPath, plan) {
84775
84850
  const composed = composeProfileTemplateMap(effective.profile);
84776
84851
  for (const script of effective.deleteLifecycleScripts) {
84777
84852
  backup(script);
84778
- fs63.rmSync(path72.join(harnessDir, script), { force: true });
84853
+ fs64.rmSync(path72.join(harnessDir, script), { force: true });
84779
84854
  deleted.push(script);
84780
84855
  }
84781
84856
  if (stripLifecycleShimCommands(resolved)) {
@@ -84783,26 +84858,26 @@ function applyPre10Plan(repoPath, plan) {
84783
84858
  }
84784
84859
  for (const file of effective.deleteMachinery) {
84785
84860
  backup(file);
84786
- fs63.rmSync(path72.join(harnessDir, file), { force: true });
84861
+ fs64.rmSync(path72.join(harnessDir, file), { force: true });
84787
84862
  deleted.push(file);
84788
84863
  }
84789
84864
  for (const doc of effective.retireDocs ?? []) {
84790
84865
  backup(doc);
84791
84866
  }
84792
84867
  const libDir = path72.join(harnessDir, "lib");
84793
- if (fs63.existsSync(libDir) && fs63.readdirSync(libDir).length === 0) {
84794
- fs63.rmdirSync(libDir);
84868
+ if (fs64.existsSync(libDir) && fs64.readdirSync(libDir).length === 0) {
84869
+ fs64.rmdirSync(libDir);
84795
84870
  deleted.push("lib/");
84796
84871
  }
84797
84872
  for (const file of effective.installMissing ?? []) {
84798
84873
  const source = composed.get(file);
84799
84874
  if (!source) continue;
84800
84875
  const dest = path72.join(harnessDir, file);
84801
- if (fs63.existsSync(dest)) continue;
84876
+ if (fs64.existsSync(dest)) continue;
84802
84877
  const rendered = substituteTemplateTokens(readComposedTemplateContent(source), projectName);
84803
- fs63.mkdirSync(path72.dirname(dest), { recursive: true });
84804
- fs63.writeFileSync(dest, rendered);
84805
- if (/\.(sh|mjs)$/.test(file)) fs63.chmodSync(dest, 493);
84878
+ fs64.mkdirSync(path72.dirname(dest), { recursive: true });
84879
+ fs64.writeFileSync(dest, rendered);
84880
+ if (/\.(sh|mjs)$/.test(file)) fs64.chmodSync(dest, 493);
84806
84881
  written.push(file);
84807
84882
  }
84808
84883
  if (effective.phantomVerificationIds.length > 0) {
@@ -84817,7 +84892,7 @@ function applyPre10Plan(repoPath, plan) {
84817
84892
  }
84818
84893
  if (effective.env) {
84819
84894
  backup("harness.env");
84820
- fs63.writeFileSync(path72.join(harnessDir, "harness.env"), effective.env.content);
84895
+ fs64.writeFileSync(path72.join(harnessDir, "harness.env"), effective.env.content);
84821
84896
  written.push("harness.env");
84822
84897
  }
84823
84898
  const manifest = readManifest(resolved);
@@ -84832,7 +84907,7 @@ function applyPre10Plan(repoPath, plan) {
84832
84907
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
84833
84908
  });
84834
84909
  }
84835
- fs63.writeFileSync(
84910
+ fs64.writeFileSync(
84836
84911
  path72.join(harnessDir, MIGRATE_PLAN_FILE),
84837
84912
  JSON.stringify({ ...effective, appliedAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2) + "\n"
84838
84913
  );
@@ -84855,25 +84930,25 @@ function pendingMigrations(repoPath) {
84855
84930
  function writeMigrationPlan(repoPath, plan) {
84856
84931
  const harnessDir = getHarnessDir(path72.resolve(repoPath));
84857
84932
  const planPath = path72.join(harnessDir, MIGRATE_PLAN_FILE);
84858
- fs63.mkdirSync(path72.dirname(planPath), { recursive: true });
84859
- fs63.writeFileSync(planPath, JSON.stringify(plan, null, 2) + "\n");
84933
+ fs64.mkdirSync(path72.dirname(planPath), { recursive: true });
84934
+ fs64.writeFileSync(planPath, JSON.stringify(plan, null, 2) + "\n");
84860
84935
  return planPath;
84861
84936
  }
84862
84937
  function removeMigrationArtifacts(repoPath) {
84863
84938
  const harnessDir = getHarnessDir(path72.resolve(repoPath));
84864
- fs63.rmSync(path72.join(harnessDir, MIGRATE_DIR), { recursive: true, force: true });
84865
- fs63.rmSync(path72.join(harnessDir, "MIGRATE-PROMPT.md"), { force: true });
84939
+ fs64.rmSync(path72.join(harnessDir, MIGRATE_DIR), { recursive: true, force: true });
84940
+ fs64.rmSync(path72.join(harnessDir, "MIGRATE-PROMPT.md"), { force: true });
84866
84941
  }
84867
84942
 
84868
84943
  // src/harness/doctor.ts
84869
84944
  function listHarnessShellScripts(harnessDir) {
84870
84945
  const out = [];
84871
84946
  const push = (dir, prefix) => {
84872
- if (!fs64.existsSync(dir)) return;
84873
- for (const entry of fs64.readdirSync(dir).sort()) {
84947
+ if (!fs65.existsSync(dir)) return;
84948
+ for (const entry of fs65.readdirSync(dir).sort()) {
84874
84949
  if (!entry.endsWith(".sh")) continue;
84875
84950
  const full = path73.join(dir, entry);
84876
- if (!fs64.statSync(full).isFile()) continue;
84951
+ if (!fs65.statSync(full).isFile()) continue;
84877
84952
  out.push(prefix ? `${prefix}/${entry}` : entry);
84878
84953
  }
84879
84954
  };
@@ -84900,8 +84975,8 @@ var PRE_1_0_FUNCTION_RE = /^\s*(har_infra_enabled|har_pg|har_node_[a-z_]+|har_pk
84900
84975
  var LEGACY_TRIPLET_RE = /^export\s+HARNESS_[A-Z0-9_]+_PORT_(DEFAULT|SCAN_START|SCAN_END)=/m;
84901
84976
  function detectContract(harnessDir) {
84902
84977
  const envPath = path73.join(harnessDir, "harness.env");
84903
- if (!fs64.existsSync(envPath)) return "none";
84904
- const content = fs64.readFileSync(envPath, "utf8");
84978
+ if (!fs65.existsSync(envPath)) return "none";
84979
+ const content = fs65.readFileSync(envPath, "utf8");
84905
84980
  if (PRE_1_0_FUNCTION_RE.test(content) || LEGACY_TRIPLET_RE.test(content)) {
84906
84981
  return "pre-1.0";
84907
84982
  }
@@ -84934,7 +85009,7 @@ function runDoctor(repoPath) {
84934
85009
  const harnessDir = getHarnessDir(repoPath);
84935
85010
  const findings = [];
84936
85011
  const skipped = /* @__PURE__ */ new Set();
84937
- if (!fs64.existsSync(harnessDir)) {
85012
+ if (!fs65.existsSync(harnessDir)) {
84938
85013
  return {
84939
85014
  ok: false,
84940
85015
  contract: "none",
@@ -85004,8 +85079,8 @@ function runDoctor(repoPath) {
85004
85079
  let registry2 = null;
85005
85080
  try {
85006
85081
  const stagesPath = path73.join(harnessDir, "stages.json");
85007
- if (fs64.existsSync(stagesPath)) {
85008
- const raw = JSON.parse(fs64.readFileSync(stagesPath, "utf8"));
85082
+ if (fs65.existsSync(stagesPath)) {
85083
+ const raw = JSON.parse(fs65.readFileSync(stagesPath, "utf8"));
85009
85084
  if (typeof raw !== "object" || raw === null || !Array.isArray(raw.stages)) {
85010
85085
  throw new Error("stages.json has no `stages` array \u2014 the registry is structurally invalid");
85011
85086
  }
@@ -85037,7 +85112,7 @@ function runDoctor(repoPath) {
85037
85112
  const file = resolveStageFile(harnessDir, stage);
85038
85113
  if (!file) continue;
85039
85114
  const rel = path73.relative(harnessDir, file);
85040
- if (!fs64.existsSync(file)) {
85115
+ if (!fs65.existsSync(file)) {
85041
85116
  findings.push({
85042
85117
  check: "stage-files",
85043
85118
  severity: contractSeverity,
@@ -85047,7 +85122,7 @@ function runDoctor(repoPath) {
85047
85122
  });
85048
85123
  continue;
85049
85124
  }
85050
- if (rel.endsWith(".sh") && !(fs64.statSync(file).mode & 73)) {
85125
+ if (rel.endsWith(".sh") && !(fs65.statSync(file).mode & 73)) {
85051
85126
  findings.push({
85052
85127
  check: "stage-files",
85053
85128
  severity: "warning",
@@ -85070,7 +85145,7 @@ function runDoctor(repoPath) {
85070
85145
  continue;
85071
85146
  }
85072
85147
  const file = resolveStageFile(harnessDir, stage);
85073
- if (file && !fs64.existsSync(file)) {
85148
+ if (file && !fs65.existsSync(file)) {
85074
85149
  findings.push({
85075
85150
  check: "lifecycle-stages",
85076
85151
  severity: contractSeverity,
@@ -85123,7 +85198,7 @@ function runDoctor(repoPath) {
85123
85198
  } else {
85124
85199
  const runtimeRel = path73.join(EJECTED_RUNTIME_DIR, EJECTED_RUNTIME_BUNDLE);
85125
85200
  const runtimePath = path73.join(harnessDir, runtimeRel);
85126
- if (!fs64.existsSync(runtimePath)) {
85201
+ if (!fs65.existsSync(runtimePath)) {
85127
85202
  findings.push({
85128
85203
  check: "ejected-runtime",
85129
85204
  severity: "error",
@@ -85136,7 +85211,7 @@ function runDoctor(repoPath) {
85136
85211
  for (const entry of listSlotRegistryEntries(repoPath)) {
85137
85212
  if (entry.status === "completed") continue;
85138
85213
  const dir = entry.worktreePath ?? entry.workDir;
85139
- if (dir && !fs64.existsSync(dir)) {
85214
+ if (dir && !fs65.existsSync(dir)) {
85140
85215
  findings.push({
85141
85216
  check: "slot-registry",
85142
85217
  severity: "warning",
@@ -85147,10 +85222,10 @@ function runDoctor(repoPath) {
85147
85222
  }
85148
85223
  }
85149
85224
  const hooksDir = path73.join(harnessDir, "hooks");
85150
- if (fs64.existsSync(hooksDir)) {
85151
- for (const file of fs64.readdirSync(hooksDir).sort()) {
85225
+ if (fs65.existsSync(hooksDir)) {
85226
+ for (const file of fs65.readdirSync(hooksDir).sort()) {
85152
85227
  const full = path73.join(hooksDir, file);
85153
- if (!fs64.statSync(full).isFile() || !file.endsWith(".sh")) continue;
85228
+ if (!fs65.statSync(full).isFile() || !file.endsWith(".sh")) continue;
85154
85229
  if (!LIFECYCLE_HOOKS.includes(file.replace(/\.sh$/, ""))) {
85155
85230
  findings.push({
85156
85231
  check: "hooks",
@@ -85161,7 +85236,7 @@ function runDoctor(repoPath) {
85161
85236
  });
85162
85237
  continue;
85163
85238
  }
85164
- if (!(fs64.statSync(full).mode & 73)) {
85239
+ if (!(fs65.statSync(full).mode & 73)) {
85165
85240
  findings.push({
85166
85241
  check: "hooks",
85167
85242
  severity: "warning",
@@ -85176,12 +85251,12 @@ function runDoctor(repoPath) {
85176
85251
  const full = path73.join(harnessDir, rel);
85177
85252
  let content;
85178
85253
  try {
85179
- content = fs64.readFileSync(full, "utf8");
85254
+ content = fs65.readFileSync(full, "utf8");
85180
85255
  } catch {
85181
85256
  continue;
85182
85257
  }
85183
85258
  for (const machinery of LEGACY_MACHINERY_FILES) {
85184
- if (fs64.existsSync(path73.join(harnessDir, machinery))) continue;
85259
+ if (fs65.existsSync(path73.join(harnessDir, machinery))) continue;
85185
85260
  const base = machinery.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
85186
85261
  const loadRe = new RegExp(
85187
85262
  `(?:\\bsource\\b|\\bbash\\b|\\bexec\\b|(?:^|[;&|(])\\s*\\.\\s)[^\\n#]*${base}`
@@ -85285,7 +85360,7 @@ function summarizeDoctorReport(report) {
85285
85360
  }
85286
85361
 
85287
85362
  // src/harness/migrate-prompt.ts
85288
- var fs65 = __toESM(require("fs"));
85363
+ var fs66 = __toESM(require("fs"));
85289
85364
  var path74 = __toESM(require("path"));
85290
85365
  init_paths();
85291
85366
  init_file_ops();
@@ -85400,7 +85475,7 @@ function loadTemplate2() {
85400
85475
  if (!filePath) {
85401
85476
  throw new Error("Migration prompt template not found: migration-prompt.md. Run npm run build.");
85402
85477
  }
85403
- return fs65.readFileSync(filePath, "utf8");
85478
+ return fs66.readFileSync(filePath, "utf8");
85404
85479
  }
85405
85480
  function buildMigrationPrompt(plan, applied) {
85406
85481
  return loadTemplate2().replace("{{MIGRATION_SECTION}}", buildMigrationSection(plan, applied));
@@ -85414,8 +85489,8 @@ function writeMigrationPrompt(repoPath, content) {
85414
85489
  // src/core/harness.ts
85415
85490
  function listHarnessScripts(repoPath) {
85416
85491
  const harnessDir = getHarnessDir(repoPath);
85417
- if (!fs66.existsSync(harnessDir)) return [];
85418
- return fs66.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
85492
+ if (!fs67.existsSync(harnessDir)) return [];
85493
+ return fs67.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
85419
85494
  }
85420
85495
  function describeProject(repoPath) {
85421
85496
  const resolved = path75.resolve(repoPath);
@@ -85439,7 +85514,7 @@ function describeProject(repoPath) {
85439
85514
  }
85440
85515
  async function initHarness(options) {
85441
85516
  const repoPath = path75.resolve(options.repoPath);
85442
- if (!fs66.existsSync(repoPath)) {
85517
+ if (!fs67.existsSync(repoPath)) {
85443
85518
  throw new Error(`Path not found: ${repoPath}`);
85444
85519
  }
85445
85520
  const scaffold = scaffoldHarnessBoilerplate(repoPath, {
@@ -85462,7 +85537,7 @@ async function initHarness(options) {
85462
85537
  async function maintainHarness(options) {
85463
85538
  const repoPath = path75.resolve(options.repoPath);
85464
85539
  const harnessDir = getHarnessDir(repoPath);
85465
- if (!fs66.existsSync(harnessDir)) {
85540
+ if (!fs67.existsSync(harnessDir)) {
85466
85541
  throw new Error('No .har/ found. Run "har onboard" first.');
85467
85542
  }
85468
85543
  let migration;
@@ -85540,7 +85615,7 @@ function addPlugin(repoPath, pluginId, options = {}) {
85540
85615
  }
85541
85616
 
85542
85617
  // src/harness/adaptation-prompt.ts
85543
- var fs67 = __toESM(require("fs"));
85618
+ var fs68 = __toESM(require("fs"));
85544
85619
  var path76 = __toESM(require("path"));
85545
85620
  var readline5 = __toESM(require("readline"));
85546
85621
 
@@ -85632,7 +85707,7 @@ function loadTemplate3(name) {
85632
85707
  if (!filePath) {
85633
85708
  throw new Error(`Adaptation prompt template not found: ${name}. Run npm run build.`);
85634
85709
  }
85635
- return fs67.readFileSync(filePath, "utf8");
85710
+ return fs68.readFileSync(filePath, "utf8");
85636
85711
  }
85637
85712
  function applyProfilePlaceholders(content, profile) {
85638
85713
  return content.replace(/\{\{PROFILE\}\}/g, profile).replace(/\{\{PROFILE_HINT\}\}/g, PROFILE_HINTS[profile]);
@@ -85710,7 +85785,7 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
85710
85785
  }
85711
85786
 
85712
85787
  // src/harness/cursor-rule.ts
85713
- var fs68 = __toESM(require("fs"));
85788
+ var fs69 = __toESM(require("fs"));
85714
85789
  var path77 = __toESM(require("path"));
85715
85790
  var readline6 = __toESM(require("readline"));
85716
85791
  init_file_ops();
@@ -85721,17 +85796,17 @@ function getCursorRulePath(repoPath) {
85721
85796
  return path77.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
85722
85797
  }
85723
85798
  function isCursorWorkspace(repoPath) {
85724
- return fs68.existsSync(path77.join(repoPath, ".cursor"));
85799
+ return fs69.existsSync(path77.join(repoPath, ".cursor"));
85725
85800
  }
85726
85801
  function cursorRuleExists(repoPath) {
85727
- return fs68.existsSync(getCursorRulePath(repoPath));
85802
+ return fs69.existsSync(getCursorRulePath(repoPath));
85728
85803
  }
85729
85804
  function scaffoldCursorRule(repoPath) {
85730
85805
  const templatePath = resolveTemplateFile("cursor-rule.mdc.template");
85731
85806
  if (!templatePath) {
85732
85807
  throw new Error("Cursor rule template not found (cursor-rule.mdc.template). Run npm run build.");
85733
85808
  }
85734
- const content = fs68.readFileSync(templatePath, "utf8");
85809
+ const content = fs69.readFileSync(templatePath, "utf8");
85735
85810
  writeFileSafe(getCursorRulePath(repoPath), content);
85736
85811
  }
85737
85812
  async function handleCursorRule(options) {
@@ -86564,7 +86639,7 @@ init_work_units();
86564
86639
  init_manifest();
86565
86640
 
86566
86641
  // src/core/cleanup-service.ts
86567
- var fs70 = __toESM(require("fs"));
86642
+ var fs71 = __toESM(require("fs"));
86568
86643
  var os23 = __toESM(require("os"));
86569
86644
  var path81 = __toESM(require("path"));
86570
86645
  var import_child_process20 = require("child_process");
@@ -86663,7 +86738,7 @@ function classifySlotCandidate(repoPath, projectName, slot, options) {
86663
86738
  return candidate;
86664
86739
  }
86665
86740
  function resolveRepoForWorktree(worktreePath) {
86666
- if (!fs70.existsSync(worktreePath)) return void 0;
86741
+ if (!fs71.existsSync(worktreePath)) return void 0;
86667
86742
  const commonDir = runGit3(worktreePath, "rev-parse --git-common-dir");
86668
86743
  if (!commonDir) return void 0;
86669
86744
  const gitRoot = path81.resolve(worktreePath, commonDir, "..");
@@ -86672,9 +86747,9 @@ function resolveRepoForWorktree(worktreePath) {
86672
86747
  }
86673
86748
  function discoverOrphanWorktrees(knownPaths) {
86674
86749
  const worktreesRoot = getWorktreesRoot();
86675
- if (!fs70.existsSync(worktreesRoot)) return [];
86750
+ if (!fs71.existsSync(worktreesRoot)) return [];
86676
86751
  const orphans = [];
86677
- for (const entry of fs70.readdirSync(worktreesRoot, { withFileTypes: true })) {
86752
+ for (const entry of fs71.readdirSync(worktreesRoot, { withFileTypes: true })) {
86678
86753
  if (!entry.isDirectory() || !entry.name.includes("-har-agent-")) continue;
86679
86754
  const worktreePath = path81.resolve(path81.join(worktreesRoot, entry.name));
86680
86755
  if (knownPaths.has(worktreePath)) continue;
@@ -86701,7 +86776,7 @@ async function discoverCleanupCandidates(options = {}) {
86701
86776
  const candidates = [];
86702
86777
  const knownWorktreePaths = /* @__PURE__ */ new Set();
86703
86778
  for (const repoPath of repoPaths) {
86704
- if (!fs70.existsSync(repoPath) || !readManifest(repoPath)) continue;
86779
+ if (!fs71.existsSync(repoPath) || !readManifest(repoPath)) continue;
86705
86780
  const harnessRoot = resolveHarnessRoot(repoPath);
86706
86781
  const canonicalRepo = canonicalizeControlRepoPath(harnessRoot);
86707
86782
  const status = collectEnvironmentStatus(harnessRoot);
@@ -86814,7 +86889,7 @@ async function executeCleanupCandidates(candidates, options = {}) {
86814
86889
  continue;
86815
86890
  }
86816
86891
  if (candidate.kind === "orphan_worktree" && candidate.worktreePath) {
86817
- if (fs70.existsSync(candidate.worktreePath)) {
86892
+ if (fs71.existsSync(candidate.worktreePath)) {
86818
86893
  const repoRoot = candidate.repoPath !== getWorktreesRoot() ? candidate.repoPath : resolveRepoForWorktree(candidate.worktreePath);
86819
86894
  if (repoRoot) {
86820
86895
  try {
@@ -86825,8 +86900,8 @@ async function executeCleanupCandidates(candidates, options = {}) {
86825
86900
  } catch {
86826
86901
  }
86827
86902
  }
86828
- if (fs70.existsSync(candidate.worktreePath)) {
86829
- fs70.rmSync(candidate.worktreePath, { recursive: true, force: true });
86903
+ if (fs71.existsSync(candidate.worktreePath)) {
86904
+ fs71.rmSync(candidate.worktreePath, { recursive: true, force: true });
86830
86905
  }
86831
86906
  }
86832
86907
  outcomes.push({ candidate, ok: true });
@@ -86972,7 +87047,7 @@ function warnIfDockerUnavailable(status = detectDockerStatus()) {
86972
87047
  }
86973
87048
 
86974
87049
  // src/core/onboarding-preferences.ts
86975
- var fs71 = __toESM(require("fs"));
87050
+ var fs72 = __toESM(require("fs"));
86976
87051
  var os24 = __toESM(require("os"));
86977
87052
  var path82 = __toESM(require("path"));
86978
87053
  init_schema2();
@@ -86985,8 +87060,8 @@ function getOnboardingPreferencesPath() {
86985
87060
  function readOnboardingPreferences() {
86986
87061
  const preferencePath = getOnboardingPreferencesPath();
86987
87062
  try {
86988
- if (!fs71.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
86989
- return OnboardingPreferencesSchema.parse(JSON.parse(fs71.readFileSync(preferencePath, "utf8")));
87063
+ if (!fs72.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
87064
+ return OnboardingPreferencesSchema.parse(JSON.parse(fs72.readFileSync(preferencePath, "utf8")));
86990
87065
  } catch {
86991
87066
  return OnboardingPreferencesSchema.parse({});
86992
87067
  }
@@ -87011,8 +87086,8 @@ function writeOnboardingPreferences(overrides) {
87011
87086
  };
87012
87087
  const parsed = OnboardingPreferencesSchema.parse(preference);
87013
87088
  const preferencePath = getOnboardingPreferencesPath();
87014
- fs71.mkdirSync(path82.dirname(preferencePath), { recursive: true });
87015
- fs71.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
87089
+ fs72.mkdirSync(path82.dirname(preferencePath), { recursive: true });
87090
+ fs72.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
87016
87091
  `);
87017
87092
  return parsed;
87018
87093
  }
@@ -87640,7 +87715,7 @@ async function handleAddPlugin(argv) {
87640
87715
  console.error(` Docs: ${result.docsPath}`);
87641
87716
  console.error("");
87642
87717
  info(`Adaptation prompt saved to ${result.adaptPromptPath}`);
87643
- const promptContent = fs72.readFileSync(path83.join(repoPath, result.adaptPromptPath), "utf8");
87718
+ const promptContent = fs73.readFileSync(path83.join(repoPath, result.adaptPromptPath), "utf8");
87644
87719
  await offerAdaptationPromptClipboard(promptContent, { fileLabel: result.adaptPromptPath });
87645
87720
  } catch (err) {
87646
87721
  error(err.message);
@@ -88185,7 +88260,7 @@ init_portal_targets();
88185
88260
  init_control_config();
88186
88261
 
88187
88262
  // src/core/portal-connect.ts
88188
- var fs73 = __toESM(require("fs"));
88263
+ var fs74 = __toESM(require("fs"));
88189
88264
  var path84 = __toESM(require("path"));
88190
88265
  var import_crypto2 = require("crypto");
88191
88266
  init_control_repo_path();
@@ -88356,7 +88431,7 @@ function remainingConnections(connections, usedAliases) {
88356
88431
  init_portal_targets();
88357
88432
  function attachRepoIfPresent(alias, repoPath) {
88358
88433
  const resolved = path84.resolve(repoPath ?? ".");
88359
- if (!fs73.existsSync(resolved)) return null;
88434
+ if (!fs74.existsSync(resolved)) return null;
88360
88435
  const canonical = canonicalizeControlRepoPath(resolved);
88361
88436
  attachRepoPortalTarget(canonical, alias);
88362
88437
  recordRepoForControlSync(canonical);
@@ -88424,7 +88499,7 @@ async function runPortalConnect(input) {
88424
88499
  }
88425
88500
  function listRegisteredReposForConnect(repoPath) {
88426
88501
  const resolved = repoPath ? path84.resolve(repoPath) : null;
88427
- const current = resolved && fs73.existsSync(resolved) ? canonicalizeControlRepoPath(resolved) : null;
88502
+ const current = resolved && fs74.existsSync(resolved) ? canonicalizeControlRepoPath(resolved) : null;
88428
88503
  return [.../* @__PURE__ */ new Set([...current ? [current] : [], ...listRegisteredRepos()])];
88429
88504
  }
88430
88505
 
@@ -88740,7 +88815,7 @@ init_control_port();
88740
88815
  init_control_sync();
88741
88816
 
88742
88817
  // src/core/control-sync-selection.ts
88743
- var fs74 = __toESM(require("fs"));
88818
+ var fs75 = __toESM(require("fs"));
88744
88819
  var os25 = __toESM(require("os"));
88745
88820
  var path85 = __toESM(require("path"));
88746
88821
  init_control_repo_path();
@@ -88753,8 +88828,8 @@ function getSelectionPath() {
88753
88828
  function readSyncSelection() {
88754
88829
  const selectionPath = getSelectionPath();
88755
88830
  try {
88756
- if (!fs74.existsSync(selectionPath)) return null;
88757
- const parsed = JSON.parse(fs74.readFileSync(selectionPath, "utf8"));
88831
+ if (!fs75.existsSync(selectionPath)) return null;
88832
+ const parsed = JSON.parse(fs75.readFileSync(selectionPath, "utf8"));
88758
88833
  if (!Array.isArray(parsed.repos)) return null;
88759
88834
  return parsed.repos.map((repoPath) => canonicalizeControlRepoPath(repoPath));
88760
88835
  } catch {
@@ -88764,8 +88839,8 @@ function readSyncSelection() {
88764
88839
  function writeSyncSelection(repos) {
88765
88840
  const selectionPath = getSelectionPath();
88766
88841
  const canonical = Array.from(new Set(repos.map((repoPath) => canonicalizeControlRepoPath(repoPath))));
88767
- fs74.mkdirSync(path85.dirname(selectionPath), { recursive: true });
88768
- fs74.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
88842
+ fs75.mkdirSync(path85.dirname(selectionPath), { recursive: true });
88843
+ fs75.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
88769
88844
  }
88770
88845
  function resolveSyncSelection(input) {
88771
88846
  const { discovered, stored, forceSelect, isTTY } = input;
@@ -88792,7 +88867,7 @@ function resolveSyncSelection(input) {
88792
88867
  }
88793
88868
 
88794
88869
  // src/core/control-unregister.ts
88795
- var fs75 = __toESM(require("fs"));
88870
+ var fs76 = __toESM(require("fs"));
88796
88871
  var path86 = __toESM(require("path"));
88797
88872
  init_control_repo_path();
88798
88873
  init_control_registry();
@@ -88805,7 +88880,7 @@ function listUnregisterWorktreeCandidates(repoPath) {
88805
88880
  const add = (partial2) => {
88806
88881
  const resolved = path86.resolve(partial2.worktreePath);
88807
88882
  if (!resolved || resolved === harnessRoot) return;
88808
- const exists = partial2.exists ?? fs75.existsSync(resolved);
88883
+ const exists = partial2.exists ?? fs76.existsSync(resolved);
88809
88884
  const prev = byPath.get(resolved);
88810
88885
  if (prev) {
88811
88886
  byPath.set(resolved, {
@@ -88919,28 +88994,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
88919
88994
  trigger: "cli"
88920
88995
  });
88921
88996
  if (result.code !== 0) {
88922
- if (fs75.existsSync(candidate.worktreePath)) {
88923
- fs75.rmSync(candidate.worktreePath, { recursive: true, force: true });
88997
+ if (fs76.existsSync(candidate.worktreePath)) {
88998
+ fs76.rmSync(candidate.worktreePath, { recursive: true, force: true });
88924
88999
  }
88925
89000
  }
88926
89001
  outcomes.push({
88927
89002
  path: candidate.worktreePath,
88928
89003
  agentId: candidate.agentId,
88929
- deleted: !fs75.existsSync(candidate.worktreePath),
88930
- error: result.code !== 0 && fs75.existsSync(candidate.worktreePath) ? result.stderr : void 0
89004
+ deleted: !fs76.existsSync(candidate.worktreePath),
89005
+ error: result.code !== 0 && fs76.existsSync(candidate.worktreePath) ? result.stderr : void 0
88931
89006
  });
88932
89007
  } catch (err) {
88933
89008
  const message = err instanceof Error ? err.message : String(err);
88934
89009
  try {
88935
- if (fs75.existsSync(candidate.worktreePath)) {
88936
- fs75.rmSync(candidate.worktreePath, { recursive: true, force: true });
89010
+ if (fs76.existsSync(candidate.worktreePath)) {
89011
+ fs76.rmSync(candidate.worktreePath, { recursive: true, force: true });
88937
89012
  }
88938
89013
  } catch {
88939
89014
  }
88940
89015
  outcomes.push({
88941
89016
  path: candidate.worktreePath,
88942
89017
  agentId: candidate.agentId,
88943
- deleted: !fs75.existsSync(candidate.worktreePath),
89018
+ deleted: !fs76.existsSync(candidate.worktreePath),
88944
89019
  error: message
88945
89020
  });
88946
89021
  }
@@ -89003,13 +89078,13 @@ init_control_config();
89003
89078
  init_control_registry();
89004
89079
 
89005
89080
  // src/core/harness-scrub.ts
89006
- var fs76 = __toESM(require("fs"));
89081
+ var fs77 = __toESM(require("fs"));
89007
89082
  var path87 = __toESM(require("path"));
89008
89083
  var HARNESS_SCRUB_DIRS = ["runs", "validations", "commit-bindings", "state", "slots"];
89009
89084
  function scrubLocalHarnessDirs(repoPath) {
89010
89085
  const results = [];
89011
89086
  const resolved = path87.resolve(repoPath);
89012
- if (!fs76.existsSync(resolved)) {
89087
+ if (!fs77.existsSync(resolved)) {
89013
89088
  for (const directory of HARNESS_SCRUB_DIRS) {
89014
89089
  results.push({
89015
89090
  path: path87.join(resolved, ".har", directory),
@@ -89022,23 +89097,23 @@ function scrubLocalHarnessDirs(repoPath) {
89022
89097
  }
89023
89098
  for (const directory of HARNESS_SCRUB_DIRS) {
89024
89099
  const target = path87.join(resolved, ".har", directory);
89025
- if (!fs76.existsSync(target)) {
89100
+ if (!fs77.existsSync(target)) {
89026
89101
  results.push({ path: target, directory, deleted: true });
89027
89102
  continue;
89028
89103
  }
89029
89104
  try {
89030
- fs76.rmSync(target, { recursive: true, force: true });
89105
+ fs77.rmSync(target, { recursive: true, force: true });
89031
89106
  results.push({
89032
89107
  path: target,
89033
89108
  directory,
89034
- deleted: !fs76.existsSync(target),
89035
- error: fs76.existsSync(target) ? "failed to remove directory" : void 0
89109
+ deleted: !fs77.existsSync(target),
89110
+ error: fs77.existsSync(target) ? "failed to remove directory" : void 0
89036
89111
  });
89037
89112
  } catch (err) {
89038
89113
  results.push({
89039
89114
  path: target,
89040
89115
  directory,
89041
- deleted: !fs76.existsSync(target),
89116
+ deleted: !fs77.existsSync(target),
89042
89117
  error: err instanceof Error ? err.message : String(err)
89043
89118
  });
89044
89119
  }
@@ -89725,7 +89800,7 @@ var path90 = __toESM(require("path"));
89725
89800
  init_hooks();
89726
89801
 
89727
89802
  // src/core/claude-hooks.ts
89728
- var fs77 = __toESM(require("fs"));
89803
+ var fs78 = __toESM(require("fs"));
89729
89804
  var path89 = __toESM(require("path"));
89730
89805
  init_paths();
89731
89806
  var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
@@ -89738,8 +89813,8 @@ function isHarGuardEntry(entry) {
89738
89813
  );
89739
89814
  }
89740
89815
  function readSettings(settingsPath) {
89741
- if (!fs77.existsSync(settingsPath)) return {};
89742
- const raw = fs77.readFileSync(settingsPath, "utf8").trim();
89816
+ if (!fs78.existsSync(settingsPath)) return {};
89817
+ const raw = fs78.readFileSync(settingsPath, "utf8").trim();
89743
89818
  if (raw === "") return {};
89744
89819
  const parsed = JSON.parse(raw);
89745
89820
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -89748,8 +89823,8 @@ function readSettings(settingsPath) {
89748
89823
  return parsed;
89749
89824
  }
89750
89825
  function writeSettings(settingsPath, settings) {
89751
- fs77.mkdirSync(path89.dirname(settingsPath), { recursive: true });
89752
- fs77.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
89826
+ fs78.mkdirSync(path89.dirname(settingsPath), { recursive: true });
89827
+ fs78.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
89753
89828
  }
89754
89829
  function installClaudeGuard(repoPath) {
89755
89830
  const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
@@ -89757,9 +89832,9 @@ function installClaudeGuard(repoPath) {
89757
89832
  throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
89758
89833
  }
89759
89834
  const guardScript = path89.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
89760
- fs77.mkdirSync(path89.dirname(guardScript), { recursive: true });
89761
- fs77.copyFileSync(templatePath, guardScript);
89762
- fs77.chmodSync(guardScript, 493);
89835
+ fs78.mkdirSync(path89.dirname(guardScript), { recursive: true });
89836
+ fs78.copyFileSync(templatePath, guardScript);
89837
+ fs78.chmodSync(guardScript, 493);
89763
89838
  const settingsPath = path89.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
89764
89839
  const settings = readSettings(settingsPath);
89765
89840
  const hooks = settings.hooks ?? {};
@@ -89775,14 +89850,14 @@ function installClaudeGuard(repoPath) {
89775
89850
  function uninstallClaudeGuard(repoPath) {
89776
89851
  let removed = false;
89777
89852
  const guardScript = path89.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
89778
- if (fs77.existsSync(guardScript)) {
89779
- fs77.rmSync(guardScript);
89853
+ if (fs78.existsSync(guardScript)) {
89854
+ fs78.rmSync(guardScript);
89780
89855
  removed = true;
89781
89856
  const parent = path89.dirname(guardScript);
89782
- if (fs77.existsSync(parent) && fs77.readdirSync(parent).length === 0) fs77.rmdirSync(parent);
89857
+ if (fs78.existsSync(parent) && fs78.readdirSync(parent).length === 0) fs78.rmdirSync(parent);
89783
89858
  }
89784
89859
  const settingsPath = path89.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
89785
- if (fs77.existsSync(settingsPath)) {
89860
+ if (fs78.existsSync(settingsPath)) {
89786
89861
  const settings = readSettings(settingsPath);
89787
89862
  const preToolUse = settings.hooks?.PreToolUse;
89788
89863
  if (preToolUse) {
@@ -89808,7 +89883,7 @@ function uninstallClaudeGuard(repoPath) {
89808
89883
  }
89809
89884
  function claudeGuardInstalled(repoPath) {
89810
89885
  const settingsPath = path89.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
89811
- if (!fs77.existsSync(settingsPath)) return false;
89886
+ if (!fs78.existsSync(settingsPath)) return false;
89812
89887
  try {
89813
89888
  const settings = readSettings(settingsPath);
89814
89889
  return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
@@ -97050,13 +97125,13 @@ init_runs();
97050
97125
  var path92 = __toESM(require("path"));
97051
97126
 
97052
97127
  // src/harness/line-create.ts
97053
- var fs78 = __toESM(require("fs"));
97128
+ var fs79 = __toESM(require("fs"));
97054
97129
  var path91 = __toESM(require("path"));
97055
97130
  init_paths();
97056
97131
  init_schema2();
97057
97132
  var LINE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
97058
97133
  function renderSkeleton(templatePath, tokens) {
97059
- let content = fs78.readFileSync(templatePath, "utf8");
97134
+ let content = fs79.readFileSync(templatePath, "utf8");
97060
97135
  for (const [token, value] of Object.entries(tokens)) {
97061
97136
  content = content.replace(new RegExp(token, "g"), value);
97062
97137
  }
@@ -97075,7 +97150,7 @@ function createLine(repoPath, options) {
97075
97150
  }
97076
97151
  const lineDir = path91.join(resolved, LOCAL_LINES_DIR, id);
97077
97152
  const lineDirRel2 = `${LOCAL_LINES_DIR}/${id}`;
97078
- if (fs78.existsSync(lineDir) && !options.force) {
97153
+ if (fs79.existsSync(lineDir) && !options.force) {
97079
97154
  throw new Error(`Line already exists: ${lineDirRel2}/. Use --force to overwrite.`);
97080
97155
  }
97081
97156
  const stationIds = options.stations?.length ? options.stations : ["S1", "S2"];
@@ -97149,9 +97224,9 @@ function createLine(repoPath, options) {
97149
97224
  const filesWritten = [];
97150
97225
  const write = (rel, content, executable = false) => {
97151
97226
  const abs = path91.join(lineDir, rel);
97152
- fs78.mkdirSync(path91.dirname(abs), { recursive: true });
97153
- fs78.writeFileSync(abs, content);
97154
- if (executable) fs78.chmodSync(abs, 493);
97227
+ fs79.mkdirSync(path91.dirname(abs), { recursive: true });
97228
+ fs79.writeFileSync(abs, content);
97229
+ if (executable) fs79.chmodSync(abs, 493);
97155
97230
  filesWritten.push(`${lineDirRel2}/${rel}`);
97156
97231
  };
97157
97232
  write("line.manifest.json", `${JSON.stringify(manifest, null, 2)}
@@ -99224,13 +99299,13 @@ var lineCommand = {
99224
99299
  var path98 = __toESM(require("path"));
99225
99300
 
99226
99301
  // src/harness/plugin-create.ts
99227
- var fs79 = __toESM(require("fs"));
99302
+ var fs80 = __toESM(require("fs"));
99228
99303
  var path97 = __toESM(require("path"));
99229
99304
  init_paths();
99230
99305
  init_schema2();
99231
99306
  var PLUGIN_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
99232
99307
  function renderSkeleton2(templatePath, tokens) {
99233
- let content = fs79.readFileSync(templatePath, "utf8");
99308
+ let content = fs80.readFileSync(templatePath, "utf8");
99234
99309
  for (const [token, value] of Object.entries(tokens)) {
99235
99310
  content = content.replace(new RegExp(token, "g"), value);
99236
99311
  }
@@ -99255,7 +99330,7 @@ function createLocalPlugin(repoPath, options) {
99255
99330
  }
99256
99331
  const pluginDir = path97.join(resolved, LOCAL_PLUGINS_DIR, id);
99257
99332
  const pluginDirRel = `${LOCAL_PLUGINS_DIR}/${id}`;
99258
- if (fs79.existsSync(pluginDir) && !options.force) {
99333
+ if (fs80.existsSync(pluginDir) && !options.force) {
99259
99334
  throw new Error(`Plugin already exists: ${pluginDirRel}/. Use --force to overwrite.`);
99260
99335
  }
99261
99336
  const description = options.description ?? `Custom ${kind} stage (local plugin: ${id})`;
@@ -99298,9 +99373,9 @@ function createLocalPlugin(repoPath, options) {
99298
99373
  const filesWritten = [];
99299
99374
  const write = (rel, content, executable = false) => {
99300
99375
  const abs = path97.join(pluginDir, rel);
99301
- fs79.mkdirSync(path97.dirname(abs), { recursive: true });
99302
- fs79.writeFileSync(abs, content);
99303
- if (executable) fs79.chmodSync(abs, 493);
99376
+ fs80.mkdirSync(path97.dirname(abs), { recursive: true });
99377
+ fs80.writeFileSync(abs, content);
99378
+ if (executable) fs80.chmodSync(abs, 493);
99304
99379
  filesWritten.push(`${pluginDirRel}/${rel}`);
99305
99380
  };
99306
99381
  write("template.manifest.json", `${JSON.stringify(manifest, null, 2)}
@@ -99800,16 +99875,16 @@ async function runCli() {
99800
99875
  }
99801
99876
 
99802
99877
  // src/core/prefer-local-runtime.ts
99803
- var fs80 = __toESM(require("fs"));
99878
+ var fs81 = __toESM(require("fs"));
99804
99879
  var path100 = __toESM(require("path"));
99805
99880
  var import_child_process22 = require("child_process");
99806
99881
  init_package_version();
99807
99882
  var PACKAGE_NAME = "@osfactory/har";
99808
99883
  function readPackageJson(dir) {
99809
99884
  const pkgPath = path100.join(dir, "package.json");
99810
- if (!fs80.existsSync(pkgPath)) return null;
99885
+ if (!fs81.existsSync(pkgPath)) return null;
99811
99886
  try {
99812
- return JSON.parse(fs80.readFileSync(pkgPath, "utf8"));
99887
+ return JSON.parse(fs81.readFileSync(pkgPath, "utf8"));
99813
99888
  } catch {
99814
99889
  return null;
99815
99890
  }
@@ -99823,11 +99898,11 @@ function resolveHarEntry(pkgDir, pkg) {
99823
99898
  rel = pkg.bin;
99824
99899
  }
99825
99900
  const entry = path100.resolve(pkgDir, rel);
99826
- return fs80.existsSync(entry) ? entry : null;
99901
+ return fs81.existsSync(entry) ? entry : null;
99827
99902
  }
99828
99903
  function sameFile(a, b2) {
99829
99904
  try {
99830
- return fs80.realpathSync(a) === fs80.realpathSync(b2);
99905
+ return fs81.realpathSync(a) === fs81.realpathSync(b2);
99831
99906
  } catch {
99832
99907
  return path100.resolve(a) === path100.resolve(b2);
99833
99908
  }