@osfactory/har 0.43.2 → 0.44.0

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.
package/dist/index.js CHANGED
@@ -553,8 +553,8 @@ var init_parseUtil = __esm({
553
553
  init_errors();
554
554
  init_en();
555
555
  makeIssue = (params) => {
556
- const { data, path: path63, errorMaps, issueData } = params;
557
- const fullPath = [...path63, ...issueData.path || []];
556
+ const { data, path: path64, errorMaps, issueData } = params;
557
+ const fullPath = [...path64, ...issueData.path || []];
558
558
  const fullIssue = {
559
559
  ...issueData,
560
560
  path: fullPath
@@ -862,11 +862,11 @@ var init_types = __esm({
862
862
  init_parseUtil();
863
863
  init_util();
864
864
  ParseInputLazyPath = class {
865
- constructor(parent, value, path63, key) {
865
+ constructor(parent, value, path64, key) {
866
866
  this._cachedPath = [];
867
867
  this.parent = parent;
868
868
  this.data = value;
869
- this._path = path63;
869
+ this._path = path64;
870
870
  this._key = key;
871
871
  }
872
872
  get path() {
@@ -28236,11 +28236,13 @@ var init_manifest = __esm({
28236
28236
  path4 = __toESM(require("path"));
28237
28237
  init_schema2();
28238
28238
  init_file_ops();
28239
- GENERATOR_VERSION = "0.4.0";
28239
+ GENERATOR_VERSION = "0.5.0";
28240
28240
  MANIFEST_VERSION = "1";
28241
28241
  DEFAULT_HAR_DIR = ".har";
28242
28242
  CHECKSUM_SKIP = /* @__PURE__ */ new Set([
28243
28243
  "manifest.json",
28244
+ "AGENTS.md.proposed",
28245
+ "AGENTS.md.proposed.meta.json",
28244
28246
  "AGENT.md.proposed",
28245
28247
  "AGENT.md.proposed.meta.json",
28246
28248
  "ADAPT-PROMPT.md"
@@ -33266,14 +33268,14 @@ var require_url_state_machine = __commonJS({
33266
33268
  return url.replace(/\u0009|\u000A|\u000D/g, "");
33267
33269
  }
33268
33270
  function shortenPath(url) {
33269
- const path63 = url.path;
33270
- if (path63.length === 0) {
33271
+ const path64 = url.path;
33272
+ if (path64.length === 0) {
33271
33273
  return;
33272
33274
  }
33273
- if (url.scheme === "file" && path63.length === 1 && isNormalizedWindowsDriveLetter(path63[0])) {
33275
+ if (url.scheme === "file" && path64.length === 1 && isNormalizedWindowsDriveLetter(path64[0])) {
33274
33276
  return;
33275
33277
  }
33276
- path63.pop();
33278
+ path64.pop();
33277
33279
  }
33278
33280
  function includesCredentials(url) {
33279
33281
  return url.username !== "" || url.password !== "";
@@ -38852,14 +38854,14 @@ __export(fileFromPath_exports, {
38852
38854
  fileFromPathSync: () => fileFromPathSync,
38853
38855
  isFile: () => isFile
38854
38856
  });
38855
- function createFileFromPath(path63, { mtimeMs, size }, filenameOrOptions, options = {}) {
38857
+ function createFileFromPath(path64, { mtimeMs, size }, filenameOrOptions, options = {}) {
38856
38858
  let filename;
38857
38859
  if (isPlainObject_default2(filenameOrOptions)) {
38858
38860
  [options, filename] = [filenameOrOptions, void 0];
38859
38861
  } else {
38860
38862
  filename = filenameOrOptions;
38861
38863
  }
38862
- const file = new FileFromPath({ path: path63, size, lastModified: mtimeMs });
38864
+ const file = new FileFromPath({ path: path64, size, lastModified: mtimeMs });
38863
38865
  if (!filename) {
38864
38866
  filename = file.name;
38865
38867
  }
@@ -38868,13 +38870,13 @@ function createFileFromPath(path63, { mtimeMs, size }, filenameOrOptions, option
38868
38870
  lastModified: file.lastModified
38869
38871
  });
38870
38872
  }
38871
- function fileFromPathSync(path63, filenameOrOptions, options = {}) {
38872
- const stats = (0, import_fs5.statSync)(path63);
38873
- return createFileFromPath(path63, stats, filenameOrOptions, options);
38873
+ function fileFromPathSync(path64, filenameOrOptions, options = {}) {
38874
+ const stats = (0, import_fs5.statSync)(path64);
38875
+ return createFileFromPath(path64, stats, filenameOrOptions, options);
38874
38876
  }
38875
- async function fileFromPath2(path63, filenameOrOptions, options) {
38876
- const stats = await import_fs5.promises.stat(path63);
38877
- return createFileFromPath(path63, stats, filenameOrOptions, options);
38877
+ async function fileFromPath2(path64, filenameOrOptions, options) {
38878
+ const stats = await import_fs5.promises.stat(path64);
38879
+ return createFileFromPath(path64, stats, filenameOrOptions, options);
38878
38880
  }
38879
38881
  var import_fs5, import_path5, import_node_domexception, __classPrivateFieldSet5, __classPrivateFieldGet6, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
38880
38882
  var init_fileFromPath = __esm({
@@ -38956,32 +38958,32 @@ __export(otel_hooks_exports, {
38956
38958
  });
38957
38959
  function getOtelHooksHome() {
38958
38960
  if (process.env.HAR_OTEL_HOOKS_HOME) {
38959
- return path48.resolve(process.env.HAR_OTEL_HOOKS_HOME);
38961
+ return path49.resolve(process.env.HAR_OTEL_HOOKS_HOME);
38960
38962
  }
38961
- return path48.join(os14.homedir(), ".har", "otel-hooks");
38963
+ return path49.join(os15.homedir(), ".har", "otel-hooks");
38962
38964
  }
38963
38965
  function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
38964
- return path48.join(hooksHome, "otel_config.json");
38966
+ return path49.join(hooksHome, "otel_config.json");
38965
38967
  }
38966
38968
  function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
38967
- return path48.join(hooksHome, "run-otel-hook.sh");
38969
+ return path49.join(hooksHome, "run-otel-hook.sh");
38968
38970
  }
38969
38971
  function getOtelHooksStateDir(hooksHome = getOtelHooksHome()) {
38970
- return path48.join(hooksHome, "state");
38972
+ return path49.join(hooksHome, "state");
38971
38973
  }
38972
38974
  function localOtelHookBin(hooksHome) {
38973
- return path48.join(hooksHome, "node_modules", ".bin", "otel-hook");
38975
+ return path49.join(hooksHome, "node_modules", ".bin", "otel-hook");
38974
38976
  }
38975
38977
  function installedPackageVersion(hooksHome) {
38976
38978
  try {
38977
- const pkgPath = path48.join(
38979
+ const pkgPath = path49.join(
38978
38980
  hooksHome,
38979
38981
  "node_modules",
38980
38982
  "@osfactory",
38981
38983
  "otel-hook",
38982
38984
  "package.json"
38983
38985
  );
38984
- const pkg = JSON.parse(fs43.readFileSync(pkgPath, "utf8"));
38986
+ const pkg = JSON.parse(fs44.readFileSync(pkgPath, "utf8"));
38985
38987
  return typeof pkg.version === "string" ? pkg.version : null;
38986
38988
  } catch {
38987
38989
  return null;
@@ -39032,15 +39034,15 @@ function buildOtelHooksConfig(options) {
39032
39034
  };
39033
39035
  }
39034
39036
  function writeOtelHooksConfig(config2, hooksHome = getOtelHooksHome()) {
39035
- fs43.mkdirSync(hooksHome, { recursive: true });
39037
+ fs44.mkdirSync(hooksHome, { recursive: true });
39036
39038
  const configPath = getOtelHooksConfigPath(hooksHome);
39037
- fs43.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
39039
+ fs44.writeFileSync(configPath, `${JSON.stringify(config2, null, 2)}
39038
39040
  `);
39039
39041
  return configPath;
39040
39042
  }
39041
39043
  function writeOtelHooksWrapper(otelHookCommand, hooksHome = getOtelHooksHome()) {
39042
- fs43.mkdirSync(hooksHome, { recursive: true });
39043
- fs43.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
39044
+ fs44.mkdirSync(hooksHome, { recursive: true });
39045
+ fs44.mkdirSync(getOtelHooksStateDir(hooksHome), { recursive: true });
39044
39046
  const wrapperPath = getOtelHooksWrapperPath(hooksHome);
39045
39047
  const configPath = getOtelHooksConfigPath(hooksHome);
39046
39048
  const stateDir = getOtelHooksStateDir(hooksHome);
@@ -39052,9 +39054,9 @@ exec "${otelHookCommand}" run \\
39052
39054
  --state-dir "${stateDir}" \\
39053
39055
  "$@"
39054
39056
  `;
39055
- fs43.writeFileSync(wrapperPath, script, { mode: 493 });
39057
+ fs44.writeFileSync(wrapperPath, script, { mode: 493 });
39056
39058
  try {
39057
- fs43.chmodSync(wrapperPath, 493);
39059
+ fs44.chmodSync(wrapperPath, 493);
39058
39060
  } catch {
39059
39061
  }
39060
39062
  return wrapperPath;
@@ -39067,11 +39069,11 @@ function commandExists2(command2) {
39067
39069
  }
39068
39070
  function resolveOtelHookCommand(hooksHome) {
39069
39071
  const local = localOtelHookBin(hooksHome);
39070
- if (fs43.existsSync(local)) return local;
39072
+ if (fs44.existsSync(local)) return local;
39071
39073
  return null;
39072
39074
  }
39073
39075
  function tryInstallPackage(hooksHome) {
39074
- fs43.mkdirSync(hooksHome, { recursive: true });
39076
+ fs44.mkdirSync(hooksHome, { recursive: true });
39075
39077
  if (!commandExists2("npm")) {
39076
39078
  return {
39077
39079
  ok: false,
@@ -39083,7 +39085,7 @@ function tryInstallPackage(hooksHome) {
39083
39085
  ["install", "--prefix", hooksHome, "--no-fund", "--no-audit", OTEL_HOOKS_PACKAGE],
39084
39086
  { encoding: "utf8", timeout: 18e4 }
39085
39087
  );
39086
- if (result.status === 0 && fs43.existsSync(localOtelHookBin(hooksHome))) {
39088
+ if (result.status === 0 && fs44.existsSync(localOtelHookBin(hooksHome))) {
39087
39089
  return { ok: true, detail: `npm install --prefix ${hooksHome} ${OTEL_HOOKS_PACKAGE}` };
39088
39090
  }
39089
39091
  return {
@@ -39109,14 +39111,14 @@ function uninstallLegacyPythonHooks(hooksHome) {
39109
39111
  }
39110
39112
  function removeLegacyPythonArtifacts(hooksHome) {
39111
39113
  const legacyPaths = [
39112
- path48.join(hooksHome, ".venv"),
39113
- path48.join(hooksHome, "otel_config.yaml"),
39114
- path48.join(hooksHome, "venv")
39114
+ path49.join(hooksHome, ".venv"),
39115
+ path49.join(hooksHome, "otel_config.yaml"),
39116
+ path49.join(hooksHome, "venv")
39115
39117
  ];
39116
39118
  for (const target of legacyPaths) {
39117
39119
  try {
39118
- if (fs43.existsSync(target)) {
39119
- fs43.rmSync(target, { recursive: true, force: true });
39120
+ if (fs44.existsSync(target)) {
39121
+ fs44.rmSync(target, { recursive: true, force: true });
39120
39122
  }
39121
39123
  } catch {
39122
39124
  }
@@ -39157,10 +39159,10 @@ function runSetupProvider(providerId, otelHookCommand, wrapperPath) {
39157
39159
  };
39158
39160
  }
39159
39161
  function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
39160
- if (!fs43.existsSync(filePath)) return false;
39162
+ if (!fs44.existsSync(filePath)) return false;
39161
39163
  let raw;
39162
39164
  try {
39163
- raw = fs43.readFileSync(filePath, "utf8");
39165
+ raw = fs44.readFileSync(filePath, "utf8");
39164
39166
  } catch {
39165
39167
  return false;
39166
39168
  }
@@ -39207,15 +39209,15 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
39207
39209
  return changed;
39208
39210
  };
39209
39211
  if (!walk(parsed)) return false;
39210
- fs43.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
39212
+ fs44.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
39211
39213
  `);
39212
39214
  return true;
39213
39215
  }
39214
39216
  function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
39215
- if (!fs43.existsSync(filePath)) return false;
39217
+ if (!fs44.existsSync(filePath)) return false;
39216
39218
  let raw;
39217
39219
  try {
39218
- raw = fs43.readFileSync(filePath, "utf8");
39220
+ raw = fs44.readFileSync(filePath, "utf8");
39219
39221
  } catch {
39220
39222
  return false;
39221
39223
  }
@@ -39250,21 +39252,21 @@ function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
39250
39252
  }
39251
39253
  }
39252
39254
  if (!changed) return false;
39253
- fs43.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
39255
+ fs44.writeFileSync(filePath, `${JSON.stringify(parsed, null, 2)}
39254
39256
  `);
39255
39257
  return true;
39256
39258
  }
39257
39259
  function rewriteKnownHookRegistrations(wrapperPath) {
39258
- const home = os14.homedir();
39260
+ const home = os15.homedir();
39259
39261
  const candidates = [
39260
- path48.join(home, ".cursor", "hooks.json"),
39261
- path48.join(home, ".claude", "settings.json"),
39262
- path48.join(home, ".codex", "hooks.json")
39262
+ path49.join(home, ".cursor", "hooks.json"),
39263
+ path49.join(home, ".claude", "settings.json"),
39264
+ path49.join(home, ".codex", "hooks.json")
39263
39265
  ];
39264
39266
  for (const filePath of candidates) {
39265
39267
  try {
39266
39268
  rewriteHookCommandsToWrapper(filePath, wrapperPath);
39267
- if (filePath.endsWith(`${path48.sep}.cursor${path48.sep}hooks.json`)) {
39269
+ if (filePath.endsWith(`${path49.sep}.cursor${path49.sep}hooks.json`)) {
39268
39270
  pruneLegacyCursorHookEvents(filePath, wrapperPath);
39269
39271
  }
39270
39272
  } catch {
@@ -39280,7 +39282,7 @@ function ensureOtelHooks(options) {
39280
39282
  const hooksHome = getOtelHooksHome();
39281
39283
  const errors = [];
39282
39284
  const providersSetup = [];
39283
- fs43.mkdirSync(hooksHome, { recursive: true });
39285
+ fs44.mkdirSync(hooksHome, { recursive: true });
39284
39286
  let otelHookCommand = resolveOtelHookCommand(hooksHome);
39285
39287
  const needsInstall = !otelHookCommand || installedPackageVersion(hooksHome) !== pinnedVersion();
39286
39288
  if (needsInstall) {
@@ -39374,14 +39376,14 @@ function ensureOtelHooks(options) {
39374
39376
  function disableOtelHooksExport() {
39375
39377
  return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
39376
39378
  }
39377
- var import_child_process10, fs43, os14, path48, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
39379
+ var import_child_process10, fs44, os15, path49, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
39378
39380
  var init_otel_hooks = __esm({
39379
39381
  "src/core/otel-hooks.ts"() {
39380
39382
  "use strict";
39381
39383
  import_child_process10 = require("child_process");
39382
- fs43 = __toESM(require("fs"));
39383
- os14 = __toESM(require("os"));
39384
- path48 = __toESM(require("path"));
39384
+ fs44 = __toESM(require("fs"));
39385
+ os15 = __toESM(require("os"));
39386
+ path49 = __toESM(require("path"));
39385
39387
  init_control_config();
39386
39388
  init_telemetry_config();
39387
39389
  OTEL_HOOKS_PACKAGE = "@osfactory/otel-hook@0.1.2";
@@ -40497,15 +40499,15 @@ var require_route = __commonJS({
40497
40499
  };
40498
40500
  }
40499
40501
  function wrapConversion(toModel, graph) {
40500
- const path63 = [graph[toModel].parent, toModel];
40502
+ const path64 = [graph[toModel].parent, toModel];
40501
40503
  let fn = conversions[graph[toModel].parent][toModel];
40502
40504
  let cur = graph[toModel].parent;
40503
40505
  while (graph[cur].parent) {
40504
- path63.unshift(graph[cur].parent);
40506
+ path64.unshift(graph[cur].parent);
40505
40507
  fn = link(conversions[graph[cur].parent][cur], fn);
40506
40508
  cur = graph[cur].parent;
40507
40509
  }
40508
- fn.conversion = path63;
40510
+ fn.conversion = path64;
40509
40511
  return fn;
40510
40512
  }
40511
40513
  module2.exports = function(fromModel) {
@@ -46435,7 +46437,7 @@ var require_iso2022 = __commonJS({
46435
46437
  // node_modules/chardet/index.js
46436
46438
  var require_chardet = __commonJS({
46437
46439
  "node_modules/chardet/index.js"(exports2, module2) {
46438
- var fs50 = require("fs");
46440
+ var fs51 = require("fs");
46439
46441
  var utf8 = require_utf8();
46440
46442
  var unicode = require_unicode();
46441
46443
  var mbcs = require_mbcs();
@@ -46509,28 +46511,28 @@ var require_chardet = __commonJS({
46509
46511
  var fd;
46510
46512
  var handler = function(err, buffer) {
46511
46513
  if (fd) {
46512
- fs50.closeSync(fd);
46514
+ fs51.closeSync(fd);
46513
46515
  }
46514
46516
  if (err) return cb(err, null);
46515
46517
  cb(null, self.detect(buffer, opts));
46516
46518
  };
46517
46519
  if (opts && opts.sampleSize) {
46518
- fd = fs50.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
46519
- fs50.read(fd, sample, 0, opts.sampleSize, null, function(err) {
46520
+ fd = fs51.openSync(filepath, "r"), sample = Buffer.allocUnsafe(opts.sampleSize);
46521
+ fs51.read(fd, sample, 0, opts.sampleSize, null, function(err) {
46520
46522
  handler(err, sample);
46521
46523
  });
46522
46524
  return;
46523
46525
  }
46524
- fs50.readFile(filepath, handler);
46526
+ fs51.readFile(filepath, handler);
46525
46527
  };
46526
46528
  module2.exports.detectFileSync = function(filepath, opts) {
46527
46529
  if (opts && opts.sampleSize) {
46528
- var fd = fs50.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
46529
- fs50.readSync(fd, sample2, 0, opts.sampleSize);
46530
- fs50.closeSync(fd);
46530
+ var fd = fs51.openSync(filepath, "r"), sample2 = Buffer.allocUnsafe(opts.sampleSize);
46531
+ fs51.readSync(fd, sample2, 0, opts.sampleSize);
46532
+ fs51.closeSync(fd);
46531
46533
  return self.detect(sample2, opts);
46532
46534
  }
46533
- return self.detect(fs50.readFileSync(filepath), opts);
46535
+ return self.detect(fs51.readFileSync(filepath), opts);
46534
46536
  };
46535
46537
  module2.exports.detectAll = function(buffer, opts) {
46536
46538
  if (typeof opts !== "object") {
@@ -49995,16 +49997,16 @@ var require_os_tmpdir = __commonJS({
49995
49997
  var isWindows = process.platform === "win32";
49996
49998
  var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
49997
49999
  module2.exports = function() {
49998
- var path63;
50000
+ var path64;
49999
50001
  if (isWindows) {
50000
- path63 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
50002
+ path64 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
50001
50003
  } else {
50002
- path63 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
50004
+ path64 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
50003
50005
  }
50004
- if (trailingSlashRe.test(path63)) {
50005
- path63 = path63.slice(0, -1);
50006
+ if (trailingSlashRe.test(path64)) {
50007
+ path64 = path64.slice(0, -1);
50006
50008
  }
50007
- return path63;
50009
+ return path64;
50008
50010
  };
50009
50011
  }
50010
50012
  });
@@ -50012,8 +50014,8 @@ var require_os_tmpdir = __commonJS({
50012
50014
  // node_modules/tmp/lib/tmp.js
50013
50015
  var require_tmp = __commonJS({
50014
50016
  "node_modules/tmp/lib/tmp.js"(exports2, module2) {
50015
- var fs50 = require("fs");
50016
- var path63 = require("path");
50017
+ var fs51 = require("fs");
50018
+ var path64 = require("path");
50017
50019
  var crypto6 = require("crypto");
50018
50020
  var osTmpDir = require_os_tmpdir();
50019
50021
  var _c2 = process.binding("constants");
@@ -50055,7 +50057,7 @@ var require_tmp = __commonJS({
50055
50057
  }
50056
50058
  function _generateTmpName(opts) {
50057
50059
  if (opts.name) {
50058
- return path63.join(opts.dir || tmpDir, opts.name);
50060
+ return path64.join(opts.dir || tmpDir, opts.name);
50059
50061
  }
50060
50062
  if (opts.template) {
50061
50063
  return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
@@ -50066,7 +50068,7 @@ var require_tmp = __commonJS({
50066
50068
  _randomChars(12),
50067
50069
  opts.postfix || ""
50068
50070
  ].join("");
50069
- return path63.join(opts.dir || tmpDir, name);
50071
+ return path64.join(opts.dir || tmpDir, name);
50070
50072
  }
50071
50073
  function tmpName(options, callback) {
50072
50074
  var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
@@ -50076,7 +50078,7 @@ var require_tmp = __commonJS({
50076
50078
  return cb(new Error("Invalid template provided"));
50077
50079
  (function _getUniqueName() {
50078
50080
  const name = _generateTmpName(opts);
50079
- fs50.stat(name, function(err) {
50081
+ fs51.stat(name, function(err) {
50080
50082
  if (!err) {
50081
50083
  if (tries-- > 0) return _getUniqueName();
50082
50084
  return cb(new Error("Could not get a unique tmp filename, max tries reached " + name));
@@ -50094,7 +50096,7 @@ var require_tmp = __commonJS({
50094
50096
  do {
50095
50097
  const name = _generateTmpName(opts);
50096
50098
  try {
50097
- fs50.statSync(name);
50099
+ fs51.statSync(name);
50098
50100
  } catch (e2) {
50099
50101
  return name;
50100
50102
  }
@@ -50106,13 +50108,13 @@ var require_tmp = __commonJS({
50106
50108
  opts.postfix = _isUndefined(opts.postfix) ? ".tmp" : opts.postfix;
50107
50109
  tmpName(opts, function _tmpNameCreated(err, name) {
50108
50110
  if (err) return cb(err);
50109
- fs50.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
50111
+ fs51.open(name, CREATE_FLAGS, opts.mode || FILE_MODE, function _fileCreated(err2, fd) {
50110
50112
  if (err2) return cb(err2);
50111
50113
  if (opts.discardDescriptor) {
50112
- return fs50.close(fd, function _discardCallback(err3) {
50114
+ return fs51.close(fd, function _discardCallback(err3) {
50113
50115
  if (err3) {
50114
50116
  try {
50115
- fs50.unlinkSync(name);
50117
+ fs51.unlinkSync(name);
50116
50118
  } catch (e2) {
50117
50119
  if (!isENOENT(e2)) {
50118
50120
  err3 = e2;
@@ -50135,9 +50137,9 @@ var require_tmp = __commonJS({
50135
50137
  opts.postfix = opts.postfix || ".tmp";
50136
50138
  const discardOrDetachDescriptor = opts.discardDescriptor || opts.detachDescriptor;
50137
50139
  const name = tmpNameSync(opts);
50138
- var fd = fs50.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
50140
+ var fd = fs51.openSync(name, CREATE_FLAGS, opts.mode || FILE_MODE);
50139
50141
  if (opts.discardDescriptor) {
50140
- fs50.closeSync(fd);
50142
+ fs51.closeSync(fd);
50141
50143
  fd = void 0;
50142
50144
  }
50143
50145
  return {
@@ -50149,9 +50151,9 @@ var require_tmp = __commonJS({
50149
50151
  function _rmdirRecursiveSync(root) {
50150
50152
  const dirs = [root];
50151
50153
  do {
50152
- var dir2 = dirs.pop(), deferred = false, files = fs50.readdirSync(dir2);
50154
+ var dir2 = dirs.pop(), deferred = false, files = fs51.readdirSync(dir2);
50153
50155
  for (var i2 = 0, length = files.length; i2 < length; i2++) {
50154
- var file2 = path63.join(dir2, files[i2]), stat = fs50.lstatSync(file2);
50156
+ var file2 = path64.join(dir2, files[i2]), stat = fs51.lstatSync(file2);
50155
50157
  if (stat.isDirectory()) {
50156
50158
  if (!deferred) {
50157
50159
  deferred = true;
@@ -50159,11 +50161,11 @@ var require_tmp = __commonJS({
50159
50161
  }
50160
50162
  dirs.push(file2);
50161
50163
  } else {
50162
- fs50.unlinkSync(file2);
50164
+ fs51.unlinkSync(file2);
50163
50165
  }
50164
50166
  }
50165
50167
  if (!deferred) {
50166
- fs50.rmdirSync(dir2);
50168
+ fs51.rmdirSync(dir2);
50167
50169
  }
50168
50170
  } while (dirs.length !== 0);
50169
50171
  }
@@ -50171,7 +50173,7 @@ var require_tmp = __commonJS({
50171
50173
  var args = _parseArguments(options, callback), opts = args[0], cb = args[1];
50172
50174
  tmpName(opts, function _tmpNameCreated(err, name) {
50173
50175
  if (err) return cb(err);
50174
- fs50.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
50176
+ fs51.mkdir(name, opts.mode || DIR_MODE, function _dirCreated(err2) {
50175
50177
  if (err2) return cb(err2);
50176
50178
  cb(null, name, _prepareTmpDirRemoveCallback(name, opts));
50177
50179
  });
@@ -50180,7 +50182,7 @@ var require_tmp = __commonJS({
50180
50182
  function dirSync(options) {
50181
50183
  var args = _parseArguments(options), opts = args[0];
50182
50184
  const name = tmpNameSync(opts);
50183
- fs50.mkdirSync(name, opts.mode || DIR_MODE);
50185
+ fs51.mkdirSync(name, opts.mode || DIR_MODE);
50184
50186
  return {
50185
50187
  name,
50186
50188
  removeCallback: _prepareTmpDirRemoveCallback(name, opts)
@@ -50190,7 +50192,7 @@ var require_tmp = __commonJS({
50190
50192
  const removeCallback = _prepareRemoveCallback(function _removeCallback(fdPath) {
50191
50193
  try {
50192
50194
  if (0 <= fdPath[0]) {
50193
- fs50.closeSync(fdPath[0]);
50195
+ fs51.closeSync(fdPath[0]);
50194
50196
  }
50195
50197
  } catch (e2) {
50196
50198
  if (!isEBADF(e2) && !isENOENT(e2)) {
@@ -50198,7 +50200,7 @@ var require_tmp = __commonJS({
50198
50200
  }
50199
50201
  }
50200
50202
  try {
50201
- fs50.unlinkSync(fdPath[1]);
50203
+ fs51.unlinkSync(fdPath[1]);
50202
50204
  } catch (e2) {
50203
50205
  if (!isENOENT(e2)) {
50204
50206
  throw e2;
@@ -50211,7 +50213,7 @@ var require_tmp = __commonJS({
50211
50213
  return removeCallback;
50212
50214
  }
50213
50215
  function _prepareTmpDirRemoveCallback(name, opts) {
50214
- const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs50.rmdirSync.bind(fs50);
50216
+ const removeFunction = opts.unsafeCleanup ? _rmdirRecursiveSync : fs51.rmdirSync.bind(fs51);
50215
50217
  const removeCallback = _prepareRemoveCallback(removeFunction, name);
50216
50218
  if (!opts.keep) {
50217
50219
  _removeObjects.unshift(removeCallback);
@@ -63344,8 +63346,8 @@ var require_utils2 = __commonJS({
63344
63346
  }
63345
63347
  return ind;
63346
63348
  }
63347
- function removeDotSegments(path63) {
63348
- let input = path63;
63349
+ function removeDotSegments(path64) {
63350
+ let input = path64;
63349
63351
  const output = [];
63350
63352
  let nextSlash = -1;
63351
63353
  let len = 0;
@@ -63597,8 +63599,8 @@ var require_schemes = __commonJS({
63597
63599
  wsComponent.secure = void 0;
63598
63600
  }
63599
63601
  if (wsComponent.resourceName) {
63600
- const [path63, query] = wsComponent.resourceName.split("?");
63601
- wsComponent.path = path63 && path63 !== "/" ? path63 : void 0;
63602
+ const [path64, query] = wsComponent.resourceName.split("?");
63603
+ wsComponent.path = path64 && path64 !== "/" ? path64 : void 0;
63602
63604
  wsComponent.query = query;
63603
63605
  wsComponent.resourceName = void 0;
63604
63606
  }
@@ -66991,12 +66993,12 @@ var require_dist = __commonJS({
66991
66993
  throw new Error(`Unknown format "${name}"`);
66992
66994
  return f2;
66993
66995
  };
66994
- function addFormats(ajv, list, fs50, exportName) {
66996
+ function addFormats(ajv, list, fs51, exportName) {
66995
66997
  var _a3;
66996
66998
  var _b2;
66997
66999
  (_a3 = (_b2 = ajv.opts.code).formats) !== null && _a3 !== void 0 ? _a3 : _b2.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
66998
67000
  for (const f2 of list)
66999
- ajv.addFormat(f2, fs50[f2]);
67001
+ ajv.addFormat(f2, fs51[f2]);
67000
67002
  }
67001
67003
  module2.exports = exports2 = formatsPlugin;
67002
67004
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -68280,11 +68282,11 @@ var parser = new YargsParser({
68280
68282
  resolve: import_path2.resolve,
68281
68283
  // TODO: figure out a way to combine ESM and CJS coverage, such that
68282
68284
  // we can exercise all the lines below:
68283
- require: (path63) => {
68285
+ require: (path64) => {
68284
68286
  if (typeof require !== "undefined") {
68285
- return require(path63);
68286
- } else if (path63.match(/\.json$/)) {
68287
- return JSON.parse((0, import_fs2.readFileSync)(path63, "utf8"));
68287
+ return require(path64);
68288
+ } else if (path64.match(/\.json$/)) {
68289
+ return JSON.parse((0, import_fs2.readFileSync)(path64, "utf8"));
68288
68290
  } else {
68289
68291
  throw Error("only .json config files are supported in ESM");
68290
68292
  }
@@ -72203,7 +72205,7 @@ function handleRemove(argv) {
72203
72205
  }
72204
72206
 
72205
72207
  // src/cli/commands/env.ts
72206
- var path52 = __toESM(require("path"));
72208
+ var path53 = __toESM(require("path"));
72207
72209
 
72208
72210
  // src/cli/finish-command.ts
72209
72211
  init_sync_context();
@@ -72213,8 +72215,8 @@ async function finishCommand(code) {
72213
72215
  }
72214
72216
 
72215
72217
  // src/core/harness.ts
72216
- var fs39 = __toESM(require("fs"));
72217
- var path43 = __toESM(require("path"));
72218
+ var fs40 = __toESM(require("fs"));
72219
+ var path44 = __toESM(require("path"));
72218
72220
 
72219
72221
  // src/harness/generator.ts
72220
72222
  var fs28 = __toESM(require("fs"));
@@ -72291,15 +72293,6 @@ function pruneCliProfile(harnessDir) {
72291
72293
  }
72292
72294
  }
72293
72295
  }
72294
- function scaffoldClaudeMd(repoPath, projectName, force) {
72295
- const templatePath = resolveTemplateFile("CLAUDE.md.template");
72296
- if (!templatePath) return;
72297
- const dest = path34.join(repoPath, "CLAUDE.md");
72298
- if (fs28.existsSync(dest) && !force) return;
72299
- const displayName = projectName.replace(/_/g, " ");
72300
- const content = fs28.readFileSync(templatePath, "utf8").replace(/__PROJECT_DISPLAY_NAME__/g, displayName);
72301
- fs28.writeFileSync(dest, content);
72302
- }
72303
72296
  function scaffoldHarnessBoilerplate(repoPath, options = {}) {
72304
72297
  const harnessDir = path34.join(repoPath, DEFAULT_HAR_DIR);
72305
72298
  const projectName = path34.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
@@ -72335,7 +72328,6 @@ function scaffoldHarnessBoilerplate(repoPath, options = {}) {
72335
72328
  profile
72336
72329
  );
72337
72330
  writeManifest(repoPath, manifest);
72338
- scaffoldClaudeMd(repoPath, projectName, options.force ?? false);
72339
72331
  ensureRootGitignorePatterns(repoPath);
72340
72332
  success(`Copied harness boilerplate to .har/ (profile: ${profile})`);
72341
72333
  info(`Project name: ${projectName}`);
@@ -72349,8 +72341,8 @@ function finalizeHarness(repoPath, adaptationSummary, stack) {
72349
72341
  }
72350
72342
 
72351
72343
  // src/llm/authoring-agent.ts
72352
- var fs32 = __toESM(require("fs"));
72353
- var path37 = __toESM(require("path"));
72344
+ var fs33 = __toESM(require("fs"));
72345
+ var path38 = __toESM(require("path"));
72354
72346
 
72355
72347
  // node_modules/@anthropic-ai/sdk/error.mjs
72356
72348
  var error_exports = {};
@@ -72749,13 +72741,13 @@ var MultipartBody = class {
72749
72741
  // node_modules/@anthropic-ai/sdk/_shims/node-runtime.mjs
72750
72742
  var import_web = require("node:stream/web");
72751
72743
  var fileFromPathWarned = false;
72752
- async function fileFromPath3(path63, ...args) {
72744
+ async function fileFromPath3(path64, ...args) {
72753
72745
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
72754
72746
  if (!fileFromPathWarned) {
72755
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path63)}) instead`);
72747
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path64)}) instead`);
72756
72748
  fileFromPathWarned = true;
72757
72749
  }
72758
- return await _fileFromPath(path63, ...args);
72750
+ return await _fileFromPath(path64, ...args);
72759
72751
  }
72760
72752
  var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
72761
72753
  var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
@@ -73352,29 +73344,29 @@ var APIClient = class {
73352
73344
  defaultIdempotencyKey() {
73353
73345
  return `stainless-node-retry-${uuid4()}`;
73354
73346
  }
73355
- get(path63, opts) {
73356
- return this.methodRequest("get", path63, opts);
73347
+ get(path64, opts) {
73348
+ return this.methodRequest("get", path64, opts);
73357
73349
  }
73358
- post(path63, opts) {
73359
- return this.methodRequest("post", path63, opts);
73350
+ post(path64, opts) {
73351
+ return this.methodRequest("post", path64, opts);
73360
73352
  }
73361
- patch(path63, opts) {
73362
- return this.methodRequest("patch", path63, opts);
73353
+ patch(path64, opts) {
73354
+ return this.methodRequest("patch", path64, opts);
73363
73355
  }
73364
- put(path63, opts) {
73365
- return this.methodRequest("put", path63, opts);
73356
+ put(path64, opts) {
73357
+ return this.methodRequest("put", path64, opts);
73366
73358
  }
73367
- delete(path63, opts) {
73368
- return this.methodRequest("delete", path63, opts);
73359
+ delete(path64, opts) {
73360
+ return this.methodRequest("delete", path64, opts);
73369
73361
  }
73370
- methodRequest(method, path63, opts) {
73362
+ methodRequest(method, path64, opts) {
73371
73363
  return this.request(Promise.resolve(opts).then(async (opts2) => {
73372
73364
  const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
73373
- return { method, path: path63, ...opts2, body };
73365
+ return { method, path: path64, ...opts2, body };
73374
73366
  }));
73375
73367
  }
73376
- getAPIList(path63, Page, opts) {
73377
- return this.requestAPIList(Page, { method: "get", path: path63, ...opts });
73368
+ getAPIList(path64, Page, opts) {
73369
+ return this.requestAPIList(Page, { method: "get", path: path64, ...opts });
73378
73370
  }
73379
73371
  calculateContentLength(body) {
73380
73372
  if (typeof body === "string") {
@@ -73392,10 +73384,10 @@ var APIClient = class {
73392
73384
  return null;
73393
73385
  }
73394
73386
  buildRequest(options) {
73395
- const { method, path: path63, query, headers = {} } = options;
73387
+ const { method, path: path64, query, headers = {} } = options;
73396
73388
  const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
73397
73389
  const contentLength = this.calculateContentLength(body);
73398
- const url = this.buildURL(path63, query);
73390
+ const url = this.buildURL(path64, query);
73399
73391
  if ("timeout" in options)
73400
73392
  validatePositiveInteger("timeout", options.timeout);
73401
73393
  const timeout = options.timeout ?? this.timeout;
@@ -73504,8 +73496,8 @@ var APIClient = class {
73504
73496
  const request = this.makeRequest(options, null);
73505
73497
  return new PagePromise(this, request, Page);
73506
73498
  }
73507
- buildURL(path63, query) {
73508
- const url = isAbsoluteURL(path63) ? new URL(path63) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path63.startsWith("/") ? path63.slice(1) : path63));
73499
+ buildURL(path64, query) {
73500
+ const url = isAbsoluteURL(path64) ? new URL(path64) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path64.startsWith("/") ? path64.slice(1) : path64));
73509
73501
  const defaultQuery = this.defaultQuery();
73510
73502
  if (!isEmptyObj(defaultQuery)) {
73511
73503
  query = { ...defaultQuery, ...query };
@@ -75328,64 +75320,368 @@ var { AnthropicError: AnthropicError2, APIError: APIError2, APIConnectionError:
75328
75320
  var sdk_default = Anthropic;
75329
75321
 
75330
75322
  // src/llm/tools.ts
75323
+ var fs32 = __toESM(require("fs"));
75324
+ var path37 = __toESM(require("path"));
75325
+ var readline4 = __toESM(require("readline"));
75326
+ init_file_ops();
75327
+ init_logging();
75328
+
75329
+ // src/harness/agent-md.ts
75331
75330
  var fs31 = __toESM(require("fs"));
75332
75331
  var path36 = __toESM(require("path"));
75333
75332
  var readline3 = __toESM(require("readline"));
75334
75333
  init_file_ops();
75335
75334
  init_logging();
75335
+ init_manifest();
75336
75336
 
75337
- // src/harness/agent-md.ts
75337
+ // src/harness/instruction-files.ts
75338
75338
  var fs30 = __toESM(require("fs"));
75339
+ var os13 = __toESM(require("os"));
75339
75340
  var path35 = __toESM(require("path"));
75340
75341
  var readline2 = __toESM(require("readline"));
75341
75342
  init_file_ops();
75342
75343
  init_logging();
75343
- init_manifest();
75344
+ var AGENTS_MD = "AGENTS.md";
75345
+ var LEGACY_AGENT_MD = "AGENT.md";
75346
+ var CLAUDE_MD = "CLAUDE.md";
75347
+ var HAR_SECTION_START = "<!-- har:agent-environment:start -->";
75348
+ var HAR_SECTION_END = "<!-- har:agent-environment:end -->";
75349
+ var CLAUDE_HAR_SECTION_START = "<!-- har:claude-pointer:start -->";
75350
+ var CLAUDE_HAR_SECTION_END = "<!-- har:claude-pointer:end -->";
75351
+ function escapeRegExp(value) {
75352
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
75353
+ }
75354
+ function detectInstructionFiles(repoPath) {
75355
+ return {
75356
+ agentsMd: fs30.existsSync(path35.join(repoPath, AGENTS_MD)),
75357
+ agentMd: fs30.existsSync(path35.join(repoPath, LEGACY_AGENT_MD)),
75358
+ claudeMd: fs30.existsSync(path35.join(repoPath, CLAUDE_MD)),
75359
+ cursorDir: fs30.existsSync(path35.join(repoPath, ".cursor")),
75360
+ claudeDir: fs30.existsSync(path35.join(repoPath, ".claude")),
75361
+ codexHome: fs30.existsSync(path35.join(os13.homedir(), ".codex"))
75362
+ };
75363
+ }
75364
+ function formatDetectionReport(detection) {
75365
+ const lines2 = ["Detected:"];
75366
+ lines2.push(` - ${AGENTS_MD} (${detection.agentsMd ? "exists" : "missing"})`);
75367
+ if (detection.agentMd) {
75368
+ lines2.push(` - ${LEGACY_AGENT_MD} (legacy \u2014 will migrate into ${AGENTS_MD})`);
75369
+ }
75370
+ lines2.push(` - ${CLAUDE_MD} (${detection.claudeMd ? "exists" : "missing"})`);
75371
+ lines2.push(` - .cursor/ (${detection.cursorDir ? "exists" : "missing"})`);
75372
+ lines2.push(` - .claude/ (${detection.claudeDir ? "exists" : "missing"})`);
75373
+ lines2.push(` - ~/.codex (${detection.codexHome ? "exists" : "missing"})`);
75374
+ return lines2.join("\n");
75375
+ }
75376
+ function buildInstallPlan(detection, targets, options = {}) {
75377
+ const writeAgentsMd = options.writeAgentsMd !== false;
75378
+ const skillsEnabled = options.skillsEnabled !== false;
75379
+ const cursorExplicit = options.cursorRule;
75380
+ const wantsCursor = cursorExplicit === true || cursorExplicit !== false && (targets.includes("cursor") || detection.cursorDir);
75381
+ return {
75382
+ agentsMd: writeAgentsMd,
75383
+ migrateLegacyAgentMd: writeAgentsMd && detection.agentMd,
75384
+ claudeMd: skillsEnabled && targets.includes("claude"),
75385
+ cursorRule: wantsCursor,
75386
+ skills: skillsEnabled ? targets : []
75387
+ };
75388
+ }
75389
+ function formatInstallPlan(plan, detection) {
75390
+ const mark = (on) => on ? "[x]" : "[ ]";
75391
+ const lines2 = ["After you confirm, HAR will:"];
75392
+ const agentsAction = detection.agentsMd ? `Update ${AGENTS_MD} \u2014 refresh HAR / agent environment section` : `Create ${AGENTS_MD} \u2014 shared HAR workflow (Codex + cross-tool)`;
75393
+ lines2.push(` ${mark(plan.agentsMd)} ${agentsAction}`);
75394
+ if (plan.migrateLegacyAgentMd) {
75395
+ lines2.push(` ${mark(true)} Migrate ${LEGACY_AGENT_MD} \u2192 ${AGENTS_MD}, then remove legacy file`);
75396
+ }
75397
+ lines2.push(
75398
+ ` ${mark(plan.claudeMd)} Claude \u2014 ensure ${CLAUDE_MD} points at ${AGENTS_MD}; install .claude/skills if confirmed`
75399
+ );
75400
+ lines2.push(
75401
+ ` ${mark(plan.cursorRule)} Cursor \u2014 install/refresh .cursor/rules/har-workflow.mdc + commands if confirmed`
75402
+ );
75403
+ lines2.push(
75404
+ ` ${mark(plan.skills.includes("codex"))} Codex \u2014 global ~/.codex/prompts (skills); project contract is ${AGENTS_MD}`
75405
+ );
75406
+ return lines2.join("\n");
75407
+ }
75408
+ function loadHarAgentsSectionFromTemplate() {
75409
+ const templatePath = resolveTemplateFile("AGENTS.md.template");
75410
+ if (!templatePath) {
75411
+ throw new Error("AGENTS.md.template not found. Run npm run build.");
75412
+ }
75413
+ const content = fs30.readFileSync(templatePath, "utf8");
75414
+ const start = content.indexOf(HAR_SECTION_START);
75415
+ const end = content.indexOf(HAR_SECTION_END);
75416
+ if (start === -1 || end === -1 || end < start) {
75417
+ throw new Error("AGENTS.md.template is missing har:agent-environment markers.");
75418
+ }
75419
+ return content.slice(start, end + HAR_SECTION_END.length);
75420
+ }
75421
+ function loadAgentsMdTemplate() {
75422
+ const templatePath = resolveTemplateFile("AGENTS.md.template");
75423
+ if (!templatePath) {
75424
+ throw new Error("AGENTS.md.template not found. Run npm run build.");
75425
+ }
75426
+ return fs30.readFileSync(templatePath, "utf8");
75427
+ }
75428
+ function upsertMarkedBlock(content, block, startMarker, endMarker) {
75429
+ if (content.includes(startMarker)) {
75430
+ const pattern = new RegExp(
75431
+ `${escapeRegExp(startMarker)}[\\s\\S]*?${escapeRegExp(endMarker)}`
75432
+ );
75433
+ return { content: content.replace(pattern, block), action: "updated" };
75434
+ }
75435
+ const suffix = content.endsWith("\n") ? "" : "\n";
75436
+ return { content: `${content}${suffix}
75437
+ ${block}
75438
+ `, action: "appended" };
75439
+ }
75440
+ function upsertAgentsMdHarSection(repoPath) {
75441
+ const dest = path35.join(repoPath, AGENTS_MD);
75442
+ const section = loadHarAgentsSectionFromTemplate();
75443
+ if (!fs30.existsSync(dest)) {
75444
+ writeFileSafe(dest, loadAgentsMdTemplate());
75445
+ return "created";
75446
+ }
75447
+ const existing = fs30.readFileSync(dest, "utf8");
75448
+ const { content, action } = upsertMarkedBlock(
75449
+ existing,
75450
+ section,
75451
+ HAR_SECTION_START,
75452
+ HAR_SECTION_END
75453
+ );
75454
+ writeFileSafe(dest, content);
75455
+ return action;
75456
+ }
75457
+ function migrateLegacyAgentMd(repoPath) {
75458
+ const legacyPath = path35.join(repoPath, LEGACY_AGENT_MD);
75459
+ const agentsPath = path35.join(repoPath, AGENTS_MD);
75460
+ if (!fs30.existsSync(legacyPath)) return false;
75461
+ const legacy = fs30.readFileSync(legacyPath, "utf8");
75462
+ if (!fs30.existsSync(agentsPath)) {
75463
+ writeFileSafe(agentsPath, legacy);
75464
+ upsertAgentsMdHarSection(repoPath);
75465
+ } else {
75466
+ upsertAgentsMdHarSection(repoPath);
75467
+ }
75468
+ fs30.unlinkSync(legacyPath);
75469
+ info(`Migrated ${LEGACY_AGENT_MD} \u2192 ${AGENTS_MD} (removed legacy file)`);
75470
+ return true;
75471
+ }
75472
+ function loadClaudeMdTemplate(projectName) {
75473
+ const templatePath = resolveTemplateFile("CLAUDE.md.template");
75474
+ if (!templatePath) {
75475
+ throw new Error("CLAUDE.md.template not found. Run npm run build.");
75476
+ }
75477
+ const displayName = projectName.replace(/_/g, " ");
75478
+ return fs30.readFileSync(templatePath, "utf8").replace(/__PROJECT_DISPLAY_NAME__/g, displayName);
75479
+ }
75480
+ function isThinClaudePointer(content) {
75481
+ const trimmed = content.trim();
75482
+ if (trimmed.length > 600) return false;
75483
+ return /AGENTS\.md|AGENT\.md/.test(trimmed) && (trimmed.includes(".har/README.md") || trimmed.includes("har-workflow"));
75484
+ }
75485
+ var CLAUDE_POINTER_BLOCK = `${CLAUDE_HAR_SECTION_START}
75486
+ ## HAR
75487
+
75488
+ This repository uses a \`.har/\` harness. Read [AGENTS.md](./AGENTS.md) and
75489
+ [\`.har/README.md\`](./.har/README.md) before making changes.
75490
+ ${CLAUDE_HAR_SECTION_END}`;
75491
+ function ensureClaudeMdPointer(repoPath, options = {}) {
75492
+ const dest = path35.join(repoPath, CLAUDE_MD);
75493
+ const projectName = path35.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
75494
+ const thin = loadClaudeMdTemplate(projectName);
75495
+ if (!fs30.existsSync(dest)) {
75496
+ writeFileSafe(dest, thin);
75497
+ return "created";
75498
+ }
75499
+ const existing = fs30.readFileSync(dest, "utf8");
75500
+ if (isThinClaudePointer(existing) || options.force) {
75501
+ writeFileSafe(dest, thin);
75502
+ return "updated";
75503
+ }
75504
+ if (existing.includes(CLAUDE_HAR_SECTION_START) || /\[AGENTS\.md\]/.test(existing)) {
75505
+ if (existing.includes(CLAUDE_HAR_SECTION_START)) {
75506
+ const { content: content2, action: action2 } = upsertMarkedBlock(
75507
+ existing,
75508
+ CLAUDE_POINTER_BLOCK,
75509
+ CLAUDE_HAR_SECTION_START,
75510
+ CLAUDE_HAR_SECTION_END
75511
+ );
75512
+ writeFileSafe(dest, content2);
75513
+ return action2;
75514
+ }
75515
+ return "skipped";
75516
+ }
75517
+ const { content, action } = upsertMarkedBlock(
75518
+ existing,
75519
+ CLAUDE_POINTER_BLOCK,
75520
+ CLAUDE_HAR_SECTION_START,
75521
+ CLAUDE_HAR_SECTION_END
75522
+ );
75523
+ writeFileSafe(dest, content);
75524
+ return action;
75525
+ }
75526
+ async function askYesNo2(question, defaultYes = true) {
75527
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
75528
+ return new Promise((resolve47) => {
75529
+ process.stderr.write(`${question} `);
75530
+ rl.once("line", (answer) => {
75531
+ rl.close();
75532
+ const trimmed = answer.trim();
75533
+ if (trimmed === "") {
75534
+ resolve47(defaultYes);
75535
+ return;
75536
+ }
75537
+ resolve47(/^y(es)?$/i.test(trimmed));
75538
+ });
75539
+ });
75540
+ }
75541
+ async function handleInstructionFiles(options) {
75542
+ const { repoPath, mode } = options;
75543
+ const writeAgentsMd = options.writeAgentsMd !== false;
75544
+ const skillsEnabled = options.enabled !== false;
75545
+ const detection = detectInstructionFiles(repoPath);
75546
+ let targets;
75547
+ if (!skillsEnabled) {
75548
+ targets = [];
75549
+ } else if (typeof options.agents === "string") {
75550
+ targets = parseAgentTargets(options.agents);
75551
+ } else {
75552
+ targets = detectAgentTargets(repoPath);
75553
+ }
75554
+ if (skillsEnabled && targets.length === 0 && mode === "init" && typeof options.agents !== "string" && !options.autoYes) {
75555
+ targets = [...AGENT_SKILL_TARGETS];
75556
+ }
75557
+ let plan = buildInstallPlan(detection, targets, {
75558
+ writeAgentsMd,
75559
+ cursorRule: options.cursorRule,
75560
+ skillsEnabled
75561
+ });
75562
+ divider();
75563
+ process.stderr.write(`${formatDetectionReport(detection)}
75564
+
75565
+ `);
75566
+ process.stderr.write(`${formatInstallPlan(plan, detection)}
75567
+ `);
75568
+ divider();
75569
+ const shouldPrompt = !options.autoYes && skillsEnabled && typeof options.agents !== "string" && !(mode === "maintain" && targets.length > 0 && !detection.agentMd);
75570
+ if (shouldPrompt && targets.length > 0) {
75571
+ const accepted = await askYesNo2(
75572
+ `Install HAR agent instructions for: ${targets.join(", ")}? [Y/n]`
75573
+ );
75574
+ if (!accepted) {
75575
+ info("Skipped agent instruction adapters (AGENTS.md will still be updated)");
75576
+ targets = [];
75577
+ plan = buildInstallPlan(detection, targets, {
75578
+ writeAgentsMd,
75579
+ cursorRule: options.cursorRule === true ? true : false,
75580
+ skillsEnabled: false
75581
+ });
75582
+ }
75583
+ }
75584
+ let migratedLegacy = false;
75585
+ let agentsMdAction = null;
75586
+ let claudeMdAction = null;
75587
+ if (writeAgentsMd) {
75588
+ if (detection.agentMd) {
75589
+ migratedLegacy = migrateLegacyAgentMd(repoPath);
75590
+ }
75591
+ agentsMdAction = upsertAgentsMdHarSection(repoPath);
75592
+ if (agentsMdAction === "created") {
75593
+ success(`Wrote ${AGENTS_MD}`);
75594
+ } else if (agentsMdAction === "updated" || agentsMdAction === "appended") {
75595
+ info(
75596
+ `${agentsMdAction === "updated" ? "Refreshed" : "Appended"} HAR section in ${AGENTS_MD}`
75597
+ );
75598
+ }
75599
+ } else {
75600
+ agentsMdAction = "skipped";
75601
+ }
75602
+ if (plan.claudeMd) {
75603
+ claudeMdAction = ensureClaudeMdPointer(repoPath);
75604
+ if (claudeMdAction === "created") {
75605
+ success(`Wrote ${CLAUDE_MD} (pointer \u2192 ${AGENTS_MD})`);
75606
+ } else if (claudeMdAction === "updated" || claudeMdAction === "appended") {
75607
+ info(
75608
+ `${claudeMdAction === "updated" ? "Updated" : "Appended"} ${CLAUDE_MD} pointer \u2192 ${AGENTS_MD}`
75609
+ );
75610
+ }
75611
+ } else {
75612
+ claudeMdAction = "skipped";
75613
+ }
75614
+ return {
75615
+ detection,
75616
+ plan,
75617
+ targets,
75618
+ agentsMdAction,
75619
+ migratedLegacy,
75620
+ claudeMdAction
75621
+ };
75622
+ }
75623
+
75624
+ // src/harness/agent-md.ts
75625
+ var AGENTS_MD_PROPOSAL = "AGENTS.md.proposed";
75626
+ var AGENTS_MD_PROPOSAL_META = "AGENTS.md.proposed.meta.json";
75344
75627
  var AGENT_MD_PROPOSAL = "AGENT.md.proposed";
75345
75628
  var AGENT_MD_PROPOSAL_META = "AGENT.md.proposed.meta.json";
75346
75629
  function writeAgentMdProposal(repoPath, content, rationale) {
75347
75630
  const harnessDir = getHarnessDir(repoPath);
75348
- writeFileSafe(path35.join(harnessDir, AGENT_MD_PROPOSAL), content);
75631
+ writeFileSafe(path36.join(harnessDir, AGENTS_MD_PROPOSAL), content);
75349
75632
  writeFileSafe(
75350
- path35.join(harnessDir, AGENT_MD_PROPOSAL_META),
75633
+ path36.join(harnessDir, AGENTS_MD_PROPOSAL_META),
75351
75634
  JSON.stringify({ rationale, createdAt: (/* @__PURE__ */ new Date()).toISOString() }, null, 2) + "\n"
75352
75635
  );
75636
+ for (const file of [AGENT_MD_PROPOSAL, AGENT_MD_PROPOSAL_META]) {
75637
+ const p2 = path36.join(harnessDir, file);
75638
+ if (fs31.existsSync(p2)) fs31.unlinkSync(p2);
75639
+ }
75353
75640
  }
75354
75641
  function readAgentMdProposal(repoPath) {
75355
75642
  const harnessDir = getHarnessDir(repoPath);
75356
- const proposalPath = path35.join(harnessDir, AGENT_MD_PROPOSAL);
75357
- const metaPath = path35.join(harnessDir, AGENT_MD_PROPOSAL_META);
75358
- if (!fs30.existsSync(proposalPath)) return null;
75359
- const content = fs30.readFileSync(proposalPath, "utf8");
75643
+ const proposalPath = path36.join(harnessDir, AGENTS_MD_PROPOSAL);
75644
+ const metaPath = path36.join(harnessDir, AGENTS_MD_PROPOSAL_META);
75645
+ const legacyProposalPath = path36.join(harnessDir, AGENT_MD_PROPOSAL);
75646
+ const legacyMetaPath = path36.join(harnessDir, AGENT_MD_PROPOSAL_META);
75647
+ const resolvedProposal = fs31.existsSync(proposalPath) ? proposalPath : fs31.existsSync(legacyProposalPath) ? legacyProposalPath : null;
75648
+ if (!resolvedProposal) return null;
75649
+ const resolvedMeta = resolvedProposal === proposalPath ? metaPath : legacyMetaPath;
75650
+ const content = fs31.readFileSync(resolvedProposal, "utf8");
75360
75651
  let rationale = "";
75361
- if (fs30.existsSync(metaPath)) {
75652
+ let createdAt = (/* @__PURE__ */ new Date()).toISOString();
75653
+ if (fs31.existsSync(resolvedMeta)) {
75362
75654
  try {
75363
- rationale = JSON.parse(fs30.readFileSync(metaPath, "utf8")).rationale ?? "";
75655
+ const meta = JSON.parse(fs31.readFileSync(resolvedMeta, "utf8"));
75656
+ rationale = meta.rationale ?? "";
75657
+ createdAt = meta.createdAt ?? createdAt;
75364
75658
  } catch {
75365
75659
  rationale = "";
75366
75660
  }
75367
75661
  }
75368
- return {
75369
- content,
75370
- rationale,
75371
- createdAt: fs30.existsSync(metaPath) ? JSON.parse(fs30.readFileSync(metaPath, "utf8")).createdAt : (/* @__PURE__ */ new Date()).toISOString()
75372
- };
75662
+ return { content, rationale, createdAt };
75373
75663
  }
75374
75664
  function clearAgentMdProposal(repoPath) {
75375
75665
  const harnessDir = getHarnessDir(repoPath);
75376
- for (const file of [AGENT_MD_PROPOSAL, AGENT_MD_PROPOSAL_META]) {
75377
- const p2 = path35.join(harnessDir, file);
75378
- if (fs30.existsSync(p2)) fs30.unlinkSync(p2);
75666
+ for (const file of [
75667
+ AGENTS_MD_PROPOSAL,
75668
+ AGENTS_MD_PROPOSAL_META,
75669
+ AGENT_MD_PROPOSAL,
75670
+ AGENT_MD_PROPOSAL_META
75671
+ ]) {
75672
+ const p2 = path36.join(harnessDir, file);
75673
+ if (fs31.existsSync(p2)) fs31.unlinkSync(p2);
75379
75674
  }
75380
75675
  }
75381
75676
  async function promptApplyAgentMdProposal(repoPath) {
75382
75677
  const proposal = readAgentMdProposal(repoPath);
75383
75678
  if (!proposal) return false;
75384
- const agentMdPath = path35.join(repoPath, "AGENT.md");
75385
- const exists = fs30.existsSync(agentMdPath);
75679
+ const agentsMdPath = path36.join(repoPath, AGENTS_MD);
75680
+ const exists = fs31.existsSync(agentsMdPath);
75386
75681
  process.stderr.write("\n");
75387
75682
  process.stderr.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
75388
- process.stderr.write("Proposed AGENT.md (repo root)\n");
75683
+ process.stderr.write(`Proposed ${AGENTS_MD} (repo root)
75684
+ `);
75389
75685
  process.stderr.write("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n");
75390
75686
  if (proposal.rationale) {
75391
75687
  process.stderr.write(`Why: ${proposal.rationale}
@@ -75401,29 +75697,29 @@ async function promptApplyAgentMdProposal(repoPath) {
75401
75697
  process.stderr.write(" ...\n");
75402
75698
  }
75403
75699
  process.stderr.write("\n");
75404
- process.stderr.write(`Full proposal: .har/${AGENT_MD_PROPOSAL}
75700
+ process.stderr.write(`Full proposal: .har/${AGENTS_MD_PROPOSAL}
75405
75701
  `);
75406
75702
  if (exists) {
75407
- warn("AGENT.md already exists at repo root.");
75408
- const answer = await askYesNo2("Replace AGENT.md with this proposal? (y/n)");
75703
+ warn(`${AGENTS_MD} already exists at repo root.`);
75704
+ const answer = await askYesNo3(`Replace ${AGENTS_MD} with this proposal? (y/n)`);
75409
75705
  if (!answer) {
75410
- info("Skipped \u2014 proposal kept at .har/AGENT.md.proposed");
75706
+ info(`Skipped \u2014 proposal kept at .har/${AGENTS_MD_PROPOSAL}`);
75411
75707
  return false;
75412
75708
  }
75413
75709
  } else {
75414
- const answer = await askYesNo2("Create AGENT.md at repo root? (y/n)");
75710
+ const answer = await askYesNo3(`Create ${AGENTS_MD} at repo root? (y/n)`);
75415
75711
  if (!answer) {
75416
- info("Skipped \u2014 proposal kept at .har/AGENT.md.proposed");
75712
+ info(`Skipped \u2014 proposal kept at .har/${AGENTS_MD_PROPOSAL}`);
75417
75713
  return false;
75418
75714
  }
75419
75715
  }
75420
- writeFileSafe(agentMdPath, proposal.content);
75716
+ writeFileSafe(agentsMdPath, proposal.content);
75421
75717
  clearAgentMdProposal(repoPath);
75422
- info("Wrote AGENT.md");
75718
+ info(`Wrote ${AGENTS_MD}`);
75423
75719
  return true;
75424
75720
  }
75425
- async function askYesNo2(question) {
75426
- const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
75721
+ async function askYesNo3(question) {
75722
+ const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
75427
75723
  return new Promise((resolve47) => {
75428
75724
  process.stderr.write(`${question} `);
75429
75725
  rl.once("line", (answer) => {
@@ -75520,12 +75816,12 @@ function buildAuthoringTools() {
75520
75816
  }
75521
75817
  },
75522
75818
  {
75523
- name: "proposeAgentMd",
75524
- description: "Propose content for AGENT.md at the repo root. Does NOT write the file \u2014 the user approves after init/maintain. Include project-specific notes and pointer to .har/.",
75819
+ name: "proposeAgentsMd",
75820
+ description: "Propose content for AGENTS.md at the repo root. Does NOT write the file \u2014 the user approves after init/maintain. Include project-specific notes and pointer to .har/.",
75525
75821
  input_schema: {
75526
75822
  type: "object",
75527
75823
  properties: {
75528
- content: { type: "string", description: "Full proposed AGENT.md content" },
75824
+ content: { type: "string", description: "Full proposed AGENTS.md content" },
75529
75825
  rationale: { type: "string", description: "Why these changes (shown to user)" }
75530
75826
  },
75531
75827
  required: ["content", "rationale"]
@@ -75570,13 +75866,13 @@ async function handleAuthoringToolCall(toolName, input, repoPath, harnessDir, ca
75570
75866
  async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, callbacks) {
75571
75867
  switch (toolName) {
75572
75868
  case "readRepoFile": {
75573
- const filePath = path36.join(repoPath, input.path);
75869
+ const filePath = path37.join(repoPath, input.path);
75574
75870
  const content = readFile(filePath, input.maxChars ?? 8e3);
75575
75871
  info(`Read repo: ${input.path}`);
75576
75872
  return content;
75577
75873
  }
75578
75874
  case "listRepoDir": {
75579
- const dirPath = path36.join(repoPath, input.path ?? ".");
75875
+ const dirPath = path37.join(repoPath, input.path ?? ".");
75580
75876
  const entries = listDir(dirPath, input.maxFiles ?? 60);
75581
75877
  info(`List repo: ${input.path} \u2192 ${entries.length} entries`);
75582
75878
  return entries.length > 0 ? entries.join("\n") : "(empty directory)";
@@ -75601,17 +75897,17 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
75601
75897
  const filePath = resolveSafePath(harnessDir, relPath);
75602
75898
  writeFileSafe(filePath, input.content);
75603
75899
  if (relPath.endsWith(".sh")) {
75604
- fs31.chmodSync(filePath, 493);
75900
+ fs32.chmodSync(filePath, 493);
75605
75901
  }
75606
75902
  info(`Wrote harness: ${relPath}`);
75607
75903
  return `Written ${relPath} (${input.content.length} bytes)`;
75608
75904
  }
75609
75905
  case "editHarnessFile": {
75610
75906
  const filePath = resolveSafePath(harnessDir, input.path);
75611
- if (!fs31.existsSync(filePath)) {
75907
+ if (!fs32.existsSync(filePath)) {
75612
75908
  return `Error: file not found: ${input.path}`;
75613
75909
  }
75614
- const content = fs31.readFileSync(filePath, "utf8");
75910
+ const content = fs32.readFileSync(filePath, "utf8");
75615
75911
  const oldStr = input.old_string;
75616
75912
  const newStr = input.new_string;
75617
75913
  const count = content.split(oldStr).length - 1;
@@ -75628,17 +75924,17 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
75628
75924
  }
75629
75925
  case "deleteHarnessFile": {
75630
75926
  const filePath = resolveSafePath(harnessDir, input.path);
75631
- if (!fs31.existsSync(filePath)) {
75927
+ if (!fs32.existsSync(filePath)) {
75632
75928
  return `File not found (already deleted): ${input.path}`;
75633
75929
  }
75634
- fs31.unlinkSync(filePath);
75930
+ fs32.unlinkSync(filePath);
75635
75931
  info(`Deleted harness: ${input.path}`);
75636
75932
  return `Deleted ${input.path}`;
75637
75933
  }
75638
- case "proposeAgentMd": {
75934
+ case "proposeAgentsMd": {
75639
75935
  writeAgentMdProposal(repoPath, input.content, input.rationale);
75640
- info("Proposed AGENT.md (awaiting user approval)");
75641
- return "AGENT.md proposal saved to .har/AGENT.md.proposed \u2014 user will be prompted to apply.";
75936
+ info("Proposed AGENTS.md (awaiting user approval)");
75937
+ return "AGENTS.md proposal saved to .har/AGENTS.md.proposed \u2014 user will be prompted to apply.";
75642
75938
  }
75643
75939
  case "ask": {
75644
75940
  return askUser(input.question, input.options ?? []);
@@ -75657,7 +75953,7 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
75657
75953
  }
75658
75954
  }
75659
75955
  async function askUser(question, options) {
75660
- const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
75956
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
75661
75957
  return new Promise((resolve47) => {
75662
75958
  process.stderr.write("\n");
75663
75959
  process.stderr.write(`\u2753 ${question}
@@ -75683,30 +75979,30 @@ async function authorHarness(repoPath, apiKey, options = {}) {
75683
75979
  const harnessDir = getHarnessDir(repoPath);
75684
75980
  const mode = options.mode ?? "init";
75685
75981
  const systemPromptPath = resolvePromptPath("system-authoring.md");
75686
- const agentMdTemplatePath = resolveTemplateFile("AGENT.md.template");
75687
- let systemPrompt = fs32.existsSync(systemPromptPath) ? fs32.readFileSync(systemPromptPath, "utf8") : "Adapt the .har/ boilerplate to match the repository. Edit files directly. Call finishAuthoring when done.";
75982
+ const agentMdTemplatePath = resolveTemplateFile("AGENTS.md.template");
75983
+ let systemPrompt = fs33.existsSync(systemPromptPath) ? fs33.readFileSync(systemPromptPath, "utf8") : "Adapt the .har/ boilerplate to match the repository. Edit files directly. Call finishAuthoring when done.";
75688
75984
  if (agentMdTemplatePath) {
75689
75985
  systemPrompt += `
75690
75986
 
75691
- ## AGENT.md template (starting point for proposeAgentMd)
75987
+ ## AGENTS.md template (starting point for proposeAgentsMd)
75692
75988
 
75693
- ${fs32.readFileSync(agentMdTemplatePath, "utf8")}`;
75989
+ ${fs33.readFileSync(agentMdTemplatePath, "utf8")}`;
75694
75990
  }
75695
75991
  const tools = buildAuthoringTools();
75696
75992
  const messages = [];
75697
75993
  let rootListing;
75698
75994
  try {
75699
- rootListing = fs32.readdirSync(repoPath).slice(0, 50).join("\n");
75995
+ rootListing = fs33.readdirSync(repoPath).slice(0, 50).join("\n");
75700
75996
  } catch {
75701
75997
  throw new Error(`Cannot read repo at path: ${repoPath}`);
75702
75998
  }
75703
75999
  let harnessListing;
75704
76000
  try {
75705
- harnessListing = fs32.readdirSync(harnessDir).join("\n");
76001
+ harnessListing = fs33.readdirSync(harnessDir).join("\n");
75706
76002
  } catch {
75707
76003
  throw new Error(`Cannot read harness dir at: ${harnessDir}`);
75708
76004
  }
75709
- const existingAgentMd = fs32.existsSync(path37.join(repoPath, "AGENT.md")) ? "AGENT.md exists at repo root \u2014 read it before proposing changes via proposeAgentMd." : "No AGENT.md at repo root yet \u2014 propose one via proposeAgentMd.";
76005
+ const existingAgentMd = fs33.existsSync(path38.join(repoPath, "AGENTS.md")) ? "AGENTS.md exists at repo root \u2014 read it before proposing changes via proposeAgentsMd." : "No AGENTS.md at repo root yet \u2014 propose one via proposeAgentsMd.";
75710
76006
  const modeInstructions = mode === "maintain" ? `This is a MAINTENANCE run. .har/ already exists and may have been edited by humans.
75711
76007
  Update it to reflect current repo changes. Prefer editHarnessFile over writeHarnessFile.
75712
76008
  Keep README.md accurate \u2014 it is the index of the harness. ${existingAgentMd}` : `This is an INITIAL setup. A fresh boilerplate has been copied to .har/.
@@ -75786,8 +76082,8 @@ Try running with --verbose to see what the agent is doing.`
75786
76082
  }
75787
76083
 
75788
76084
  // src/harness/validator.ts
75789
- var fs33 = __toESM(require("fs"));
75790
- var path38 = __toESM(require("path"));
76085
+ var fs34 = __toESM(require("fs"));
76086
+ var path39 = __toESM(require("path"));
75791
76087
  init_shell();
75792
76088
  init_manifest();
75793
76089
  init_stages();
@@ -75842,22 +76138,22 @@ var SHELL_SCRIPTS = [
75842
76138
  function validateHarness(repoPath) {
75843
76139
  const harnessDir = getHarnessDir(repoPath);
75844
76140
  const issues = [];
75845
- if (!fs33.existsSync(harnessDir)) {
76141
+ if (!fs34.existsSync(harnessDir)) {
75846
76142
  return {
75847
76143
  pass: false,
75848
76144
  issues: [{ file: ".har", message: "Harness directory not found", severity: "error" }]
75849
76145
  };
75850
76146
  }
75851
76147
  for (const file of getRequiredFiles(repoPath)) {
75852
- const filePath = path38.join(harnessDir, file);
75853
- if (!fs33.existsSync(filePath)) {
76148
+ const filePath = path39.join(harnessDir, file);
76149
+ if (!fs34.existsSync(filePath)) {
75854
76150
  issues.push({ file, message: "Required file missing", severity: "error" });
75855
76151
  }
75856
76152
  }
75857
76153
  for (const script of SHELL_SCRIPTS) {
75858
- const scriptPath = path38.join(harnessDir, script);
75859
- if (!fs33.existsSync(scriptPath)) continue;
75860
- const stat = fs33.statSync(scriptPath);
76154
+ const scriptPath = path39.join(harnessDir, script);
76155
+ if (!fs34.existsSync(scriptPath)) continue;
76156
+ const stat = fs34.statSync(scriptPath);
75861
76157
  if (!(stat.mode & 73)) {
75862
76158
  issues.push({ file: script, message: "Script is not executable", severity: "warning" });
75863
76159
  }
@@ -75872,9 +76168,9 @@ function validateHarness(repoPath) {
75872
76168
  }
75873
76169
  const manifest = readManifest(repoPath);
75874
76170
  const profile = manifest?.profile ?? "default";
75875
- const ecosystemPath = path38.join(harnessDir, "ecosystem.agent.template.cjs");
75876
- if (profile !== "cli" && fs33.existsSync(ecosystemPath)) {
75877
- const content = fs33.readFileSync(ecosystemPath, "utf8");
76171
+ const ecosystemPath = path39.join(harnessDir, "ecosystem.agent.template.cjs");
76172
+ if (profile !== "cli" && fs34.existsSync(ecosystemPath)) {
76173
+ const content = fs34.readFileSync(ecosystemPath, "utf8");
75878
76174
  if (!content.includes("module.exports")) {
75879
76175
  issues.push({
75880
76176
  file: "ecosystem.agent.template.cjs",
@@ -75883,9 +76179,9 @@ function validateHarness(repoPath) {
75883
76179
  });
75884
76180
  }
75885
76181
  }
75886
- const harnessEnvPath = path38.join(harnessDir, "harness.env");
75887
- if (fs33.existsSync(harnessEnvPath)) {
75888
- const content = fs33.readFileSync(harnessEnvPath, "utf8");
76182
+ const harnessEnvPath = path39.join(harnessDir, "harness.env");
76183
+ if (fs34.existsSync(harnessEnvPath)) {
76184
+ const content = fs34.readFileSync(harnessEnvPath, "utf8");
75889
76185
  if (content.includes("TODO: set migrate command")) {
75890
76186
  issues.push({ file: "harness.env", message: "Migrate command still has TODO", severity: "warning" });
75891
76187
  }
@@ -75893,17 +76189,17 @@ function validateHarness(repoPath) {
75893
76189
  issues.push({ file: "harness.env", message: "Seed command still has TODO", severity: "warning" });
75894
76190
  }
75895
76191
  }
75896
- const verifyPath = path38.join(harnessDir, "verify.sh");
75897
- if (fs33.existsSync(verifyPath)) {
75898
- const content = fs33.readFileSync(verifyPath, "utf8");
76192
+ const verifyPath = path39.join(harnessDir, "verify.sh");
76193
+ if (fs34.existsSync(verifyPath)) {
76194
+ const content = fs34.readFileSync(verifyPath, "utf8");
75899
76195
  if (content.includes("echo 'TODO:")) {
75900
76196
  issues.push({ file: "verify.sh", message: "Verification steps still have TODO placeholders", severity: "warning" });
75901
76197
  }
75902
76198
  }
75903
- const stagesPath = path38.join(harnessDir, "stages.json");
75904
- if (fs33.existsSync(stagesPath)) {
76199
+ const stagesPath = path39.join(harnessDir, "stages.json");
76200
+ if (fs34.existsSync(stagesPath)) {
75905
76201
  try {
75906
- JSON.parse(fs33.readFileSync(stagesPath, "utf8"));
76202
+ JSON.parse(fs34.readFileSync(stagesPath, "utf8"));
75907
76203
  const registry2 = readStageRegistry(repoPath);
75908
76204
  if (registry2.stages.length === 0) {
75909
76205
  issues.push({ file: "stages.json", message: "No harness stages declared", severity: "warning" });
@@ -75918,9 +76214,9 @@ function validateHarness(repoPath) {
75918
76214
  } else {
75919
76215
  issues.push({ file: "stages.json", message: "Stage registry missing", severity: "warning" });
75920
76216
  }
75921
- const readmePath = path38.join(harnessDir, "README.md");
75922
- if (fs33.existsSync(readmePath)) {
75923
- const content = fs33.readFileSync(readmePath, "utf8");
76217
+ const readmePath = path39.join(harnessDir, "README.md");
76218
+ if (fs34.existsSync(readmePath)) {
76219
+ const content = fs34.readFileSync(readmePath, "utf8");
75924
76220
  if (!content.includes(".har")) {
75925
76221
  issues.push({ file: "README.md", message: "README should document .har/ paths", severity: "warning" });
75926
76222
  }
@@ -75934,8 +76230,8 @@ function validateHarness(repoPath) {
75934
76230
  async function smokeTestHarness(repoPath) {
75935
76231
  const harnessDir = getHarnessDir(repoPath);
75936
76232
  const issues = [];
75937
- const setupScript = path38.join(harnessDir, "setup-infra.sh");
75938
- if (fs33.existsSync(setupScript)) {
76233
+ const setupScript = path39.join(harnessDir, "setup-infra.sh");
76234
+ if (fs34.existsSync(setupScript)) {
75939
76235
  const result = run(`bash "${setupScript}"`, { cwd: repoPath });
75940
76236
  if (result.code !== 0) {
75941
76237
  issues.push({
@@ -75950,8 +76246,8 @@ async function smokeTestHarness(repoPath) {
75950
76246
  }
75951
76247
 
75952
76248
  // src/harness/drift.ts
75953
- var fs34 = __toESM(require("fs"));
75954
- var path39 = __toESM(require("path"));
76249
+ var fs35 = __toESM(require("fs"));
76250
+ var path40 = __toESM(require("path"));
75955
76251
  init_env();
75956
76252
  init_manifest();
75957
76253
  init_stages();
@@ -76022,16 +76318,16 @@ function substituteProjectName(content, projectName) {
76022
76318
  return content.replace(/__PROJECT_NAME__/g, projectName).replace(/template___PROJECT_NAME__/g, `template_${projectName}`);
76023
76319
  }
76024
76320
  function listBoilerplateFiles(boilerplateDir) {
76025
- if (!fs34.existsSync(boilerplateDir)) return [];
76026
- return fs34.readdirSync(boilerplateDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
76321
+ if (!fs35.existsSync(boilerplateDir)) return [];
76322
+ return fs35.readdirSync(boilerplateDir, { withFileTypes: true }).filter((entry) => entry.isFile()).map((entry) => entry.name).sort();
76027
76323
  }
76028
76324
  function compareHarnessToTemplate(repoPath) {
76029
- const resolved = path39.resolve(repoPath);
76325
+ const resolved = path40.resolve(repoPath);
76030
76326
  const manifest = readManifest(resolved);
76031
76327
  const profile = manifest?.profile ?? "default";
76032
76328
  const harnessDir = getHarnessDir(resolved);
76033
- const projectName = path39.basename(resolved).toLowerCase().replace(/[^a-z0-9]/g, "_");
76034
- const boilerplateDir = path39.join(resolveTemplatesDir(), PROFILE_DIRS2[profile]);
76329
+ const projectName = path40.basename(resolved).toLowerCase().replace(/[^a-z0-9]/g, "_");
76330
+ const boilerplateDir = path40.join(resolveTemplatesDir(), PROFILE_DIRS2[profile]);
76035
76331
  const templateFiles = listBoilerplateFiles(boilerplateDir);
76036
76332
  const missing = [];
76037
76333
  const checksumMismatch = [];
@@ -76039,17 +76335,17 @@ function compareHarnessToTemplate(repoPath) {
76039
76335
  const unchanged = [];
76040
76336
  for (const file of templateFiles) {
76041
76337
  const harnessFile = harnessFileForTemplate(file);
76042
- const templatePath = path39.join(boilerplateDir, file);
76043
- const harnessPath = path39.join(harnessDir, harnessFile);
76044
- let templateContent = fs34.readFileSync(templatePath, "utf8");
76338
+ const templatePath = path40.join(boilerplateDir, file);
76339
+ const harnessPath = path40.join(harnessDir, harnessFile);
76340
+ let templateContent = fs35.readFileSync(templatePath, "utf8");
76045
76341
  if (file === "harness.env") {
76046
76342
  templateContent = substituteProjectName(templateContent, projectName);
76047
76343
  }
76048
- if (!fs34.existsSync(harnessPath)) {
76344
+ if (!fs35.existsSync(harnessPath)) {
76049
76345
  missing.push(harnessFile);
76050
76346
  continue;
76051
76347
  }
76052
- const harnessChecksum = computeFileChecksum(fs34.readFileSync(harnessPath, "utf8"));
76348
+ const harnessChecksum = computeFileChecksum(fs35.readFileSync(harnessPath, "utf8"));
76053
76349
  const templateChecksum = computeFileChecksum(templateContent);
76054
76350
  if (harnessChecksum === templateChecksum) {
76055
76351
  unchanged.push(harnessFile);
@@ -76057,10 +76353,10 @@ function compareHarnessToTemplate(repoPath) {
76057
76353
  checksumMismatch.push(harnessFile);
76058
76354
  }
76059
76355
  }
76060
- if (fs34.existsSync(harnessDir)) {
76061
- for (const file of fs34.readdirSync(harnessDir)) {
76062
- const full = path39.join(harnessDir, file);
76063
- if (!fs34.statSync(full).isFile()) continue;
76356
+ if (fs35.existsSync(harnessDir)) {
76357
+ for (const file of fs35.readdirSync(harnessDir)) {
76358
+ const full = path40.join(harnessDir, file);
76359
+ if (!fs35.statSync(full).isFile()) continue;
76064
76360
  if (file === "manifest.json" || file.startsWith("ADAPT-PROMPT")) continue;
76065
76361
  if (profile === "cli" && CLI_EXPECTED_ABSENT.has(file)) {
76066
76362
  extra.push(file);
@@ -76091,29 +76387,29 @@ function compareHarnessToTemplate(repoPath) {
76091
76387
  }
76092
76388
 
76093
76389
  // src/harness/maintain-bundle.ts
76094
- var fs38 = __toESM(require("fs"));
76095
- var os13 = __toESM(require("os"));
76096
- var path42 = __toESM(require("path"));
76390
+ var fs39 = __toESM(require("fs"));
76391
+ var os14 = __toESM(require("os"));
76392
+ var path43 = __toESM(require("path"));
76097
76393
  init_file_ops();
76098
76394
  init_shell();
76099
76395
  init_manifest();
76100
76396
 
76101
76397
  // src/harness/plugin-drift.ts
76102
- var fs37 = __toESM(require("fs"));
76103
- var path41 = __toESM(require("path"));
76398
+ var fs38 = __toESM(require("fs"));
76399
+ var path42 = __toESM(require("path"));
76104
76400
  init_manifest();
76105
76401
 
76106
76402
  // src/harness/plugins.ts
76107
- var fs36 = __toESM(require("fs"));
76108
- var path40 = __toESM(require("path"));
76403
+ var fs37 = __toESM(require("fs"));
76404
+ var path41 = __toESM(require("path"));
76109
76405
  init_zod();
76110
76406
  init_logging();
76111
76407
 
76112
76408
  // src/harness/parser.ts
76113
- var fs35 = __toESM(require("fs"));
76409
+ var fs36 = __toESM(require("fs"));
76114
76410
  init_manifest();
76115
76411
  function harnessExists(repoPath) {
76116
- return fs35.existsSync(`${repoPath}/.har/setup-infra.sh`);
76412
+ return fs36.existsSync(`${repoPath}/.har/setup-infra.sh`);
76117
76413
  }
76118
76414
 
76119
76415
  // src/harness/plugins.ts
@@ -76138,16 +76434,16 @@ var PluginManifestSchema = external_exports.object({
76138
76434
  docsPath: external_exports.string().min(1)
76139
76435
  });
76140
76436
  function resolvePluginDir(pluginId) {
76141
- const dir = path40.join(resolveTemplatesDir(), "plugins", pluginId);
76142
- if (!fs36.existsSync(dir)) {
76437
+ const dir = path41.join(resolveTemplatesDir(), "plugins", pluginId);
76438
+ if (!fs37.existsSync(dir)) {
76143
76439
  throw new Error(`Plugin not found: ${pluginId}. Run npm run build.`);
76144
76440
  }
76145
76441
  return dir;
76146
76442
  }
76147
76443
  function readPluginManifest(pluginId) {
76148
- const manifestPath = path40.join(resolvePluginDir(pluginId), "template.manifest.json");
76444
+ const manifestPath = path41.join(resolvePluginDir(pluginId), "template.manifest.json");
76149
76445
  const parsed = PluginManifestSchema.safeParse(
76150
- JSON.parse(fs36.readFileSync(manifestPath, "utf8"))
76446
+ JSON.parse(fs37.readFileSync(manifestPath, "utf8"))
76151
76447
  );
76152
76448
  if (!parsed.success) {
76153
76449
  throw new Error(`Invalid plugin manifest for ${pluginId}: ${parsed.error.message}`);
@@ -76158,40 +76454,40 @@ function readPluginManifest(pluginId) {
76158
76454
  return parsed.data;
76159
76455
  }
76160
76456
  function ensureParentDir(filePath) {
76161
- const parent = path40.dirname(filePath);
76162
- if (!fs36.existsSync(parent)) {
76163
- fs36.mkdirSync(parent, { recursive: true });
76457
+ const parent = path41.dirname(filePath);
76458
+ if (!fs37.existsSync(parent)) {
76459
+ fs37.mkdirSync(parent, { recursive: true });
76164
76460
  }
76165
76461
  }
76166
76462
  function copyPluginFile(pluginDir, file, repoPath, force) {
76167
- const srcPath = path40.join(pluginDir, file.src);
76168
- const destPath = path40.join(repoPath, file.dest);
76169
- if (!fs36.existsSync(srcPath)) {
76463
+ const srcPath = path41.join(pluginDir, file.src);
76464
+ const destPath = path41.join(repoPath, file.dest);
76465
+ if (!fs37.existsSync(srcPath)) {
76170
76466
  throw new Error(`Plugin file missing: ${file.src}`);
76171
76467
  }
76172
- if (fs36.existsSync(destPath) && !force) {
76468
+ if (fs37.existsSync(destPath) && !force) {
76173
76469
  throw new Error(
76174
76470
  `File already exists: ${file.dest}. Use --force to overwrite or remove it first.`
76175
76471
  );
76176
76472
  }
76177
76473
  ensureParentDir(destPath);
76178
- fs36.copyFileSync(srcPath, destPath);
76474
+ fs37.copyFileSync(srcPath, destPath);
76179
76475
  if (file.executable) {
76180
- fs36.chmodSync(destPath, 493);
76476
+ fs37.chmodSync(destPath, 493);
76181
76477
  }
76182
76478
  return { written: true, path: file.dest };
76183
76479
  }
76184
76480
  function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
76185
- const packagePath = path40.join(repoPath, "package.json");
76186
- if (!fs36.existsSync(packagePath)) {
76481
+ const packagePath = path41.join(repoPath, "package.json");
76482
+ if (!fs37.existsSync(packagePath)) {
76187
76483
  throw new Error("No package.json in repo root. Add one before applying this plugin.");
76188
76484
  }
76189
- const fragmentPath = path40.join(pluginDir, fragmentRelPath);
76190
- if (!fs36.existsSync(fragmentPath)) {
76485
+ const fragmentPath = path41.join(pluginDir, fragmentRelPath);
76486
+ if (!fs37.existsSync(fragmentPath)) {
76191
76487
  throw new Error(`Package fragment missing: ${fragmentRelPath}`);
76192
76488
  }
76193
- const pkg = JSON.parse(fs36.readFileSync(packagePath, "utf8"));
76194
- const fragment = JSON.parse(fs36.readFileSync(fragmentPath, "utf8"));
76489
+ const pkg = JSON.parse(fs37.readFileSync(packagePath, "utf8"));
76490
+ const fragment = JSON.parse(fs37.readFileSync(fragmentPath, "utf8"));
76195
76491
  for (const section of ["scripts", "devDependencies"]) {
76196
76492
  const existing = pkg[section] ?? {};
76197
76493
  const incoming = fragment[section] ?? {};
@@ -76204,7 +76500,7 @@ function mergePackageJson(repoPath, pluginDir, fragmentRelPath, warnings) {
76204
76500
  }
76205
76501
  pkg[section] = existing;
76206
76502
  }
76207
- fs36.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
76503
+ fs37.writeFileSync(packagePath, JSON.stringify(pkg, null, 2) + "\n");
76208
76504
  }
76209
76505
  function patchStageRegistry(repoPath, manifest, force) {
76210
76506
  const registry2 = readStageRegistry(repoPath);
@@ -76244,8 +76540,8 @@ function assertHarnessPresent(repoPath) {
76244
76540
  }
76245
76541
  function assertStageNotPresent(repoPath, stageId, force) {
76246
76542
  if (force) return;
76247
- const scriptPath = path40.join(repoPath, ".har", "stages", `${stageId}.sh`);
76248
- if (fs36.existsSync(scriptPath)) {
76543
+ const scriptPath = path41.join(repoPath, ".har", "stages", `${stageId}.sh`);
76544
+ if (fs37.existsSync(scriptPath)) {
76249
76545
  throw new Error(
76250
76546
  `Stage script already exists: .har/stages/${stageId}.sh. Use --force to overwrite.`
76251
76547
  );
@@ -76258,7 +76554,7 @@ function assertStageNotPresent(repoPath, stageId, force) {
76258
76554
  }
76259
76555
  }
76260
76556
  function applyPlugin(repoPath, pluginId, options = {}) {
76261
- const resolved = path40.resolve(repoPath);
76557
+ const resolved = path41.resolve(repoPath);
76262
76558
  const force = options.force ?? false;
76263
76559
  const warnings = [];
76264
76560
  const filesWritten = [];
@@ -76277,7 +76573,7 @@ function applyPlugin(repoPath, pluginId, options = {}) {
76277
76573
  if (file.skipFlag === "skipCi" && options.skipCi) {
76278
76574
  continue;
76279
76575
  }
76280
- if (fs36.existsSync(path40.join(resolved, file.dest)) && !force) {
76576
+ if (fs37.existsSync(path41.join(resolved, file.dest)) && !force) {
76281
76577
  warnings.push(`Skipped optional file (exists): ${file.dest}`);
76282
76578
  continue;
76283
76579
  }
@@ -76312,18 +76608,18 @@ function applyPlugin(repoPath, pluginId, options = {}) {
76312
76608
  };
76313
76609
  }
76314
76610
  function listPluginIds() {
76315
- const root = path40.join(resolveTemplatesDir(), "plugins");
76316
- if (!fs36.existsSync(root)) return [...PLUGIN_IDS];
76317
- return fs36.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => PLUGIN_IDS.includes(name));
76611
+ const root = path41.join(resolveTemplatesDir(), "plugins");
76612
+ if (!fs37.existsSync(root)) return [...PLUGIN_IDS];
76613
+ return fs37.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name).filter((name) => PLUGIN_IDS.includes(name));
76318
76614
  }
76319
76615
 
76320
76616
  // src/harness/plugin-drift.ts
76321
76617
  init_stages();
76322
76618
  var PACKAGE_SECTIONS = ["scripts", "devDependencies"];
76323
76619
  function detectInstalledPlugins(repoPath) {
76324
- const resolved = path41.resolve(repoPath);
76325
- const registryPath = path41.join(resolved, ".har", "stages.json");
76326
- if (!fs37.existsSync(registryPath)) return [];
76620
+ const resolved = path42.resolve(repoPath);
76621
+ const registryPath = path42.join(resolved, ".har", "stages.json");
76622
+ if (!fs38.existsSync(registryPath)) return [];
76327
76623
  const registry2 = readStageRegistry(resolved);
76328
76624
  const stageIds = new Set(registry2.stages.map((stage) => stage.id));
76329
76625
  const installed = [];
@@ -76336,17 +76632,17 @@ function detectInstalledPlugins(repoPath) {
76336
76632
  return installed;
76337
76633
  }
76338
76634
  function pluginTemplatePath(pluginId, srcRel) {
76339
- return path41.join(resolveTemplatesDir(), "plugins", pluginId, srcRel);
76635
+ return path42.join(resolveTemplatesDir(), "plugins", pluginId, srcRel);
76340
76636
  }
76341
76637
  function readBundledPluginFile(pluginId, srcRel) {
76342
- return fs37.readFileSync(pluginTemplatePath(pluginId, srcRel), "utf8");
76638
+ return fs38.readFileSync(pluginTemplatePath(pluginId, srcRel), "utf8");
76343
76639
  }
76344
76640
  function listPluginDestPaths(pluginId, repoPath) {
76345
76641
  const manifest = readPluginManifest(pluginId);
76346
76642
  const paths = manifest.files.map((file) => file.dest);
76347
76643
  if (manifest.optionalFiles) {
76348
76644
  for (const file of manifest.optionalFiles) {
76349
- if (fs37.existsSync(path41.join(repoPath, file.dest))) {
76645
+ if (fs38.existsSync(path42.join(repoPath, file.dest))) {
76350
76646
  paths.push(file.dest);
76351
76647
  }
76352
76648
  }
@@ -76405,9 +76701,9 @@ function readTemplatePluginFile(pluginId, dest) {
76405
76701
  return null;
76406
76702
  }
76407
76703
  function readInstalledPluginFile(repoPath, pluginId, dest) {
76408
- const installedPath = path41.join(path41.resolve(repoPath), dest);
76409
- if (!fs37.existsSync(installedPath)) return null;
76410
- const content = fs37.readFileSync(installedPath, "utf8");
76704
+ const installedPath = path42.join(path42.resolve(repoPath), dest);
76705
+ if (!fs38.existsSync(installedPath)) return null;
76706
+ const content = fs38.readFileSync(installedPath, "utf8");
76411
76707
  const manifest = readPluginManifest(pluginId);
76412
76708
  const fragmentRel = manifest.merge?.[dest];
76413
76709
  if (fragmentRel) {
@@ -76426,7 +76722,7 @@ function pluginActionHint(pluginId, dest, kind2) {
76426
76722
  }
76427
76723
  function comparePluginToTemplate(repoPath, pluginId) {
76428
76724
  const manifest = readPluginManifest(pluginId);
76429
- const resolved = path41.resolve(repoPath);
76725
+ const resolved = path42.resolve(repoPath);
76430
76726
  const destPaths = listPluginDestPaths(pluginId, resolved);
76431
76727
  const missing = [];
76432
76728
  const checksumMismatch = [];
@@ -76441,8 +76737,8 @@ function comparePluginToTemplate(repoPath, pluginId) {
76441
76737
  }
76442
76738
  if (dest === "package.json") {
76443
76739
  const fragmentRel = manifest.merge?.[dest];
76444
- const installedPath = path41.join(resolved, dest);
76445
- const installedRaw = fs37.readFileSync(installedPath, "utf8");
76740
+ const installedPath = path42.join(resolved, dest);
76741
+ const installedRaw = fs38.readFileSync(installedPath, "utf8");
76446
76742
  if (fragmentRel && pluginKeysMatch(installedRaw, readBundledPluginFile(pluginId, fragmentRel))) {
76447
76743
  unchanged.push(dest);
76448
76744
  } else if (computeFileChecksum(installedContent) === computeFileChecksum(templateContent)) {
@@ -76511,14 +76807,14 @@ function substituteProjectName2(content, projectName) {
76511
76807
  return content.replace(/__PROJECT_NAME__/g, projectName).replace(/template___PROJECT_NAME__/g, `template_${projectName}`);
76512
76808
  }
76513
76809
  function projectNameFromRepo(repoPath) {
76514
- return path42.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
76810
+ return path43.basename(repoPath).toLowerCase().replace(/[^a-z0-9]/g, "_");
76515
76811
  }
76516
76812
  function boilerplateDirForProfile(profile) {
76517
- return path42.join(resolveTemplatesDir(), PROFILE_DIRS3[profile]);
76813
+ return path43.join(resolveTemplatesDir(), PROFILE_DIRS3[profile]);
76518
76814
  }
76519
76815
  function readBundledTemplateContent(repoPath, profile, file) {
76520
- const templatePath = path42.join(boilerplateDirForProfile(profile), templateFileForHarness(file));
76521
- let content = fs38.readFileSync(templatePath, "utf8");
76816
+ const templatePath = path43.join(boilerplateDirForProfile(profile), templateFileForHarness(file));
76817
+ let content = fs39.readFileSync(templatePath, "utf8");
76522
76818
  if (file === "harness.env") {
76523
76819
  content = substituteProjectName2(content, projectNameFromRepo(repoPath));
76524
76820
  }
@@ -76549,12 +76845,12 @@ function actionHint(file, kind2) {
76549
76845
  return `Read maintain/diffs/${file}.diff and merge into .har/${file}.`;
76550
76846
  }
76551
76847
  function createUnifiedDiff(installedContent, templateContent, installedLabel, templateLabel) {
76552
- const tmpDir = fs38.mkdtempSync(path42.join(os13.tmpdir(), "har-maintain-diff-"));
76848
+ const tmpDir = fs39.mkdtempSync(path43.join(os14.tmpdir(), "har-maintain-diff-"));
76553
76849
  try {
76554
- const installedPath = path42.join(tmpDir, "installed");
76555
- const templatePath = path42.join(tmpDir, "template");
76556
- fs38.writeFileSync(installedPath, installedContent);
76557
- fs38.writeFileSync(templatePath, templateContent);
76850
+ const installedPath = path43.join(tmpDir, "installed");
76851
+ const templatePath = path43.join(tmpDir, "template");
76852
+ fs39.writeFileSync(installedPath, installedContent);
76853
+ fs39.writeFileSync(templatePath, templateContent);
76558
76854
  const result = run(`diff -u "${installedPath}" "${templatePath}"`);
76559
76855
  const body = result.stdout.trim();
76560
76856
  if (!body) return "";
@@ -76563,7 +76859,7 @@ function createUnifiedDiff(installedContent, templateContent, installedLabel, te
76563
76859
  ${body.split("\n").slice(2).join("\n")}
76564
76860
  `;
76565
76861
  } finally {
76566
- fs38.rmSync(tmpDir, { recursive: true, force: true });
76862
+ fs39.rmSync(tmpDir, { recursive: true, force: true });
76567
76863
  }
76568
76864
  }
76569
76865
  function buildActions(repoPath, profile, drift) {
@@ -76578,7 +76874,7 @@ function buildActions(repoPath, profile, drift) {
76578
76874
  });
76579
76875
  }
76580
76876
  for (const file of drift.checksumMismatch) {
76581
- const installedPath = path42.join(harnessDir, file);
76877
+ const installedPath = path43.join(harnessDir, file);
76582
76878
  const installedRel = `maintain/installed/${file}`;
76583
76879
  const templateRel = `maintain/templates/${file}`;
76584
76880
  const diffRel = `maintain/diffs/${file}.diff`;
@@ -76586,7 +76882,7 @@ function buildActions(repoPath, profile, drift) {
76586
76882
  file,
76587
76883
  kind: "drift",
76588
76884
  template: templateRel,
76589
- installed: fs38.existsSync(installedPath) ? installedRel : void 0,
76885
+ installed: fs39.existsSync(installedPath) ? installedRel : void 0,
76590
76886
  diff: diffRel,
76591
76887
  hint: actionHint(file, "drift")
76592
76888
  });
@@ -76596,6 +76892,44 @@ function buildActions(repoPath, profile, drift) {
76596
76892
  function buildStale(drift) {
76597
76893
  return drift.extra.map((file) => ({ file, hint: staleFileHint(file) })).sort((a2, b3) => a2.file.localeCompare(b3.file));
76598
76894
  }
76895
+ function buildInstructionFileNotes(repoPath) {
76896
+ const detection = detectInstructionFiles(repoPath);
76897
+ const notes = [];
76898
+ if (detection.agentMd) {
76899
+ notes.push({
76900
+ kind: "migrate_legacy_agent_md",
76901
+ path: "AGENT.md",
76902
+ message: "Legacy AGENT.md (singular) found \u2014 merge unique notes into AGENTS.md, then delete AGENT.md. Codex auto-loads AGENTS.md only."
76903
+ });
76904
+ }
76905
+ if (!detection.agentsMd) {
76906
+ notes.push({
76907
+ kind: "create_agents_md",
76908
+ path: "AGENTS.md",
76909
+ message: "AGENTS.md missing \u2014 create it with a HAR / agent environment section (or let maintain\u2019s instruction-files step scaffold it, then fill project-specific notes)."
76910
+ });
76911
+ } else {
76912
+ notes.push({
76913
+ kind: "refresh_agents_md_har_section",
76914
+ path: "AGENTS.md",
76915
+ message: "Refresh the managed HAR / agent environment section in AGENTS.md if workflow/commands changed \u2014 do not wipe unrelated project guidance."
76916
+ });
76917
+ }
76918
+ if (detection.claudeMd) {
76919
+ notes.push({
76920
+ kind: "claude_md_pointer",
76921
+ path: "CLAUDE.md",
76922
+ message: "Keep CLAUDE.md as a thin pointer to AGENTS.md (do not duplicate the full HAR workflow)."
76923
+ });
76924
+ } else {
76925
+ notes.push({
76926
+ kind: "claude_md_pointer",
76927
+ path: "CLAUDE.md",
76928
+ message: "Optional: add a thin CLAUDE.md pointer \u2192 AGENTS.md when Claude Code is used on this repo."
76929
+ });
76930
+ }
76931
+ return notes;
76932
+ }
76599
76933
  function buildReadme(report) {
76600
76934
  const lines2 = [
76601
76935
  "# Harness maintenance bundle",
@@ -76663,6 +76997,16 @@ function buildReadme(report) {
76663
76997
  ""
76664
76998
  );
76665
76999
  }
77000
+ if (report.instructionFiles.length > 0) {
77001
+ lines2.push("", "## Agent instruction files (generator 0.5.0)", "");
77002
+ lines2.push(
77003
+ "Repo-root agent docs are **outside** `.har/` checksum drift. Apply while adapting:",
77004
+ ""
77005
+ );
77006
+ for (const note of report.instructionFiles) {
77007
+ lines2.push(`- **\`${note.path}\`** (${note.kind}): ${note.message}`);
77008
+ }
77009
+ }
76666
77010
  lines2.push("", "## Stale files (review)", "");
76667
77011
  if (report.stale.length === 0) {
76668
77012
  lines2.push("None detected.");
@@ -76686,28 +77030,28 @@ function buildReadme(report) {
76686
77030
  }
76687
77031
  function writeBundleArtifacts(repoPath, profile, drift, report) {
76688
77032
  const harnessDir = getHarnessDir(repoPath);
76689
- const bundleDir = path42.join(harnessDir, MAINTAIN_DIR);
76690
- if (fs38.existsSync(bundleDir)) {
76691
- fs38.rmSync(bundleDir, { recursive: true, force: true });
77033
+ const bundleDir = path43.join(harnessDir, MAINTAIN_DIR);
77034
+ if (fs39.existsSync(bundleDir)) {
77035
+ fs39.rmSync(bundleDir, { recursive: true, force: true });
76692
77036
  }
76693
77037
  const dirs = [
76694
77038
  bundleDir,
76695
- path42.join(bundleDir, "templates"),
76696
- path42.join(bundleDir, "installed"),
76697
- path42.join(bundleDir, "diffs"),
76698
- path42.join(bundleDir, "stale")
77039
+ path43.join(bundleDir, "templates"),
77040
+ path43.join(bundleDir, "installed"),
77041
+ path43.join(bundleDir, "diffs"),
77042
+ path43.join(bundleDir, "stale")
76699
77043
  ];
76700
77044
  for (const dir of dirs) {
76701
- fs38.mkdirSync(dir, { recursive: true });
77045
+ fs39.mkdirSync(dir, { recursive: true });
76702
77046
  }
76703
77047
  const affectedFiles = [...drift.missing, ...drift.checksumMismatch];
76704
77048
  for (const file of affectedFiles) {
76705
77049
  const templateContent = readBundledTemplateContent(repoPath, profile, file);
76706
- writeFileSafe(path42.join(bundleDir, "templates", file), templateContent);
76707
- const harnessPath = path42.join(harnessDir, file);
76708
- if (fs38.existsSync(harnessPath)) {
76709
- const installedContent = fs38.readFileSync(harnessPath, "utf8");
76710
- writeFileSafe(path42.join(bundleDir, "installed", file), installedContent);
77050
+ writeFileSafe(path43.join(bundleDir, "templates", file), templateContent);
77051
+ const harnessPath = path43.join(harnessDir, file);
77052
+ if (fs39.existsSync(harnessPath)) {
77053
+ const installedContent = fs39.readFileSync(harnessPath, "utf8");
77054
+ writeFileSafe(path43.join(bundleDir, "installed", file), installedContent);
76711
77055
  const diff = createUnifiedDiff(
76712
77056
  installedContent,
76713
77057
  templateContent,
@@ -76715,14 +77059,14 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
76715
77059
  `templates/${file}`
76716
77060
  );
76717
77061
  if (diff) {
76718
- writeFileSafe(path42.join(bundleDir, "diffs", `${file}.diff`), diff);
77062
+ writeFileSafe(path43.join(bundleDir, "diffs", `${file}.diff`), diff);
76719
77063
  }
76720
77064
  }
76721
77065
  }
76722
- writeFileSafe(path42.join(bundleDir, "README.md"), buildReadme(report));
76723
- writeFileSafe(path42.join(bundleDir, "drift-report.json"), JSON.stringify(report, null, 2) + "\n");
77066
+ writeFileSafe(path43.join(bundleDir, "README.md"), buildReadme(report));
77067
+ writeFileSafe(path43.join(bundleDir, "drift-report.json"), JSON.stringify(report, null, 2) + "\n");
76724
77068
  writeFileSafe(
76725
- path42.join(bundleDir, "validation.json"),
77069
+ path43.join(bundleDir, "validation.json"),
76726
77070
  JSON.stringify(report.validation, null, 2) + "\n"
76727
77071
  );
76728
77072
  if (report.stale.length > 0) {
@@ -76734,34 +77078,34 @@ function writeBundleArtifacts(repoPath, profile, drift, report) {
76734
77078
  ...report.stale.map((s2) => `- **${s2.file}** \u2014 ${s2.hint}`),
76735
77079
  ""
76736
77080
  ];
76737
- writeFileSafe(path42.join(bundleDir, "stale", "MANIFEST.md"), staleLines.join("\n"));
77081
+ writeFileSafe(path43.join(bundleDir, "stale", "MANIFEST.md"), staleLines.join("\n"));
76738
77082
  }
76739
77083
  return bundleDir;
76740
77084
  }
76741
77085
  function ensureParentDir2(filePath) {
76742
- const parent = path42.dirname(filePath);
76743
- if (!fs38.existsSync(parent)) {
76744
- fs38.mkdirSync(parent, { recursive: true });
77086
+ const parent = path43.dirname(filePath);
77087
+ if (!fs39.existsSync(parent)) {
77088
+ fs39.mkdirSync(parent, { recursive: true });
76745
77089
  }
76746
77090
  }
76747
77091
  function writePluginBundleArtifacts(repoPath, bundleDir, report) {
76748
77092
  if (report.pluginActions.length === 0) return;
76749
77093
  for (const action of report.pluginActions) {
76750
- const pluginRoot = path42.join(bundleDir, "plugins", action.pluginId);
76751
- const templatesDir = path42.join(pluginRoot, "templates");
76752
- const installedDir = path42.join(pluginRoot, "installed");
76753
- const diffsDir = path42.join(pluginRoot, "diffs");
77094
+ const pluginRoot = path43.join(bundleDir, "plugins", action.pluginId);
77095
+ const templatesDir = path43.join(pluginRoot, "templates");
77096
+ const installedDir = path43.join(pluginRoot, "installed");
77097
+ const diffsDir = path43.join(pluginRoot, "diffs");
76754
77098
  for (const dir of [templatesDir, installedDir, diffsDir]) {
76755
- fs38.mkdirSync(dir, { recursive: true });
77099
+ fs39.mkdirSync(dir, { recursive: true });
76756
77100
  }
76757
77101
  const templateContent = readTemplatePluginFile(action.pluginId, action.file);
76758
77102
  if (templateContent === null) continue;
76759
- const templatePath = path42.join(templatesDir, action.file);
77103
+ const templatePath = path43.join(templatesDir, action.file);
76760
77104
  ensureParentDir2(templatePath);
76761
77105
  writeFileSafe(templatePath, templateContent);
76762
77106
  const installedContent = readInstalledPluginFile(repoPath, action.pluginId, action.file);
76763
77107
  if (installedContent !== null) {
76764
- const installedPath = path42.join(installedDir, action.file);
77108
+ const installedPath = path43.join(installedDir, action.file);
76765
77109
  ensureParentDir2(installedPath);
76766
77110
  writeFileSafe(installedPath, installedContent);
76767
77111
  const diff = createUnifiedDiff(
@@ -76771,7 +77115,7 @@ function writePluginBundleArtifacts(repoPath, bundleDir, report) {
76771
77115
  `templates/${action.file}`
76772
77116
  );
76773
77117
  if (diff) {
76774
- const diffPath = path42.join(diffsDir, `${action.file}.diff`);
77118
+ const diffPath = path43.join(diffsDir, `${action.file}.diff`);
76775
77119
  ensureParentDir2(diffPath);
76776
77120
  writeFileSafe(diffPath, diff);
76777
77121
  }
@@ -76795,6 +77139,7 @@ function buildMaintainBundle(repoPath, validation2, drift) {
76795
77139
  stale: buildStale(drift),
76796
77140
  missingPortVars: drift.missingPortVars,
76797
77141
  agentSlotMismatch: drift.agentSlotMismatch,
77142
+ instructionFiles: buildInstructionFileNotes(repoPath),
76798
77143
  validation: {
76799
77144
  pass: validation2.pass,
76800
77145
  errors,
@@ -76806,9 +77151,9 @@ function buildMaintainBundle(repoPath, validation2, drift) {
76806
77151
  return { bundleDir, report };
76807
77152
  }
76808
77153
  function removeMaintainBundle(repoPath) {
76809
- const bundleDir = path42.join(getHarnessDir(repoPath), MAINTAIN_DIR);
76810
- if (fs38.existsSync(bundleDir)) {
76811
- fs38.rmSync(bundleDir, { recursive: true, force: true });
77154
+ const bundleDir = path43.join(getHarnessDir(repoPath), MAINTAIN_DIR);
77155
+ if (fs39.existsSync(bundleDir)) {
77156
+ fs39.rmSync(bundleDir, { recursive: true, force: true });
76812
77157
  }
76813
77158
  }
76814
77159
  function formatMaintainBundlePromptSection(report) {
@@ -76874,7 +77219,19 @@ function formatMaintainBundlePromptSection(report) {
76874
77219
  ""
76875
77220
  );
76876
77221
  }
76877
- if (report.actions.length === 0 && report.pluginActions.length === 0 && report.stale.length === 0 && report.missingPortVars.length === 0 && !report.agentSlotMismatch && report.validation.errors.length === 0) {
77222
+ if (report.instructionFiles.length > 0) {
77223
+ lines2.push(
77224
+ "### Agent instruction files (generator 0.5.0 \u2014 outside `.har/` drift)",
77225
+ "",
77226
+ "These are **not** checksum drift rows. Apply them while adapting (HAR also migrates/scaffolds on maintain):",
77227
+ ""
77228
+ );
77229
+ for (const note of report.instructionFiles) {
77230
+ lines2.push(`- **\`${note.path}\`** (${note.kind}): ${note.message}`);
77231
+ }
77232
+ lines2.push("");
77233
+ }
77234
+ if (report.actions.length === 0 && report.pluginActions.length === 0 && report.stale.length === 0 && report.missingPortVars.length === 0 && !report.agentSlotMismatch && report.validation.errors.length === 0 && report.instructionFiles.length === 0) {
76878
77235
  lines2.push("No template drift detected. Review repo stack changes manually if needed.", "");
76879
77236
  }
76880
77237
  return lines2.join("\n");
@@ -76886,11 +77243,11 @@ init_stages();
76886
77243
  init_validation();
76887
77244
  function listHarnessScripts(repoPath) {
76888
77245
  const harnessDir = getHarnessDir(repoPath);
76889
- if (!fs39.existsSync(harnessDir)) return [];
76890
- return fs39.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
77246
+ if (!fs40.existsSync(harnessDir)) return [];
77247
+ return fs40.readdirSync(harnessDir).filter((name) => name.endsWith(".sh")).sort();
76891
77248
  }
76892
77249
  function describeProject(repoPath) {
76893
- const resolved = path43.resolve(repoPath);
77250
+ const resolved = path44.resolve(repoPath);
76894
77251
  const manifest = readManifest(resolved);
76895
77252
  const present = harnessExists(resolved);
76896
77253
  return {
@@ -76910,8 +77267,8 @@ function describeProject(repoPath) {
76910
77267
  };
76911
77268
  }
76912
77269
  async function initHarness(options) {
76913
- const repoPath = path43.resolve(options.repoPath);
76914
- if (!fs39.existsSync(repoPath)) {
77270
+ const repoPath = path44.resolve(options.repoPath);
77271
+ if (!fs40.existsSync(repoPath)) {
76915
77272
  throw new Error(`Path not found: ${repoPath}`);
76916
77273
  }
76917
77274
  const scaffold = scaffoldHarnessBoilerplate(repoPath, {
@@ -76943,9 +77300,9 @@ async function initHarness(options) {
76943
77300
  };
76944
77301
  }
76945
77302
  async function maintainHarness(options) {
76946
- const repoPath = path43.resolve(options.repoPath);
77303
+ const repoPath = path44.resolve(options.repoPath);
76947
77304
  const harnessDir = getHarnessDir(repoPath);
76948
- if (!fs39.existsSync(harnessDir)) {
77305
+ if (!fs40.existsSync(harnessDir)) {
76949
77306
  throw new Error('No .har/ found. Run "har env init" first.');
76950
77307
  }
76951
77308
  if (options.auto) {
@@ -76997,13 +77354,13 @@ function addPlugin(repoPath, pluginId, options = {}) {
76997
77354
  }
76998
77355
 
76999
77356
  // src/harness/custom-stage.ts
77000
- var fs40 = __toESM(require("fs"));
77001
- var path44 = __toESM(require("path"));
77357
+ var fs41 = __toESM(require("fs"));
77358
+ var path45 = __toESM(require("path"));
77002
77359
  init_schema2();
77003
77360
  init_stages();
77004
77361
  var STAGE_ID_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
77005
77362
  function addCustomStage(repoPath, options) {
77006
- const resolved = path44.resolve(repoPath);
77363
+ const resolved = path45.resolve(repoPath);
77007
77364
  if (!harnessExists(resolved)) {
77008
77365
  throw new Error('No .har/ harness found. Run "har env init" first.');
77009
77366
  }
@@ -77040,20 +77397,20 @@ function addCustomStage(repoPath, options) {
77040
77397
  if (options.command) {
77041
77398
  stage.command = options.command;
77042
77399
  } else {
77043
- const scriptRel = path44.join("stages", `${id}.sh`);
77044
- const scriptAbs = path44.join(resolved, ".har", scriptRel);
77045
- if (fs40.existsSync(scriptAbs) && !options.force) {
77400
+ const scriptRel = path45.join("stages", `${id}.sh`);
77401
+ const scriptAbs = path45.join(resolved, ".har", scriptRel);
77402
+ if (fs41.existsSync(scriptAbs) && !options.force) {
77046
77403
  throw new Error(`Stage script already exists: .har/${scriptRel}. Use --force to overwrite.`);
77047
77404
  }
77048
- const skeletonPath = path44.join(
77405
+ const skeletonPath = path45.join(
77049
77406
  resolveTemplatesDir(),
77050
77407
  "plugins",
77051
77408
  "custom-stage-skeleton.sh"
77052
77409
  );
77053
- const skeleton = fs40.readFileSync(skeletonPath, "utf8").replace(/__STAGE_ID__/g, id).replace(/__STAGE_KIND__/g, kind2).replace(/__STAGE_DESCRIPTION__/g, stage.description);
77054
- fs40.mkdirSync(path44.dirname(scriptAbs), { recursive: true });
77055
- fs40.writeFileSync(scriptAbs, skeleton);
77056
- fs40.chmodSync(scriptAbs, 493);
77410
+ const skeleton = fs41.readFileSync(skeletonPath, "utf8").replace(/__STAGE_ID__/g, id).replace(/__STAGE_KIND__/g, kind2).replace(/__STAGE_DESCRIPTION__/g, stage.description);
77411
+ fs41.mkdirSync(path45.dirname(scriptAbs), { recursive: true });
77412
+ fs41.writeFileSync(scriptAbs, skeleton);
77413
+ fs41.chmodSync(scriptAbs, 493);
77057
77414
  filesWritten.push(`.har/${scriptRel}`);
77058
77415
  stage.script = scriptRel;
77059
77416
  stage.artifacts = [
@@ -77101,9 +77458,9 @@ function addCustomStage(repoPath, options) {
77101
77458
  }
77102
77459
 
77103
77460
  // src/harness/adaptation-prompt.ts
77104
- var fs41 = __toESM(require("fs"));
77105
- var path45 = __toESM(require("path"));
77106
- var readline4 = __toESM(require("readline"));
77461
+ var fs42 = __toESM(require("fs"));
77462
+ var path46 = __toESM(require("path"));
77463
+ var readline5 = __toESM(require("readline"));
77107
77464
 
77108
77465
  // src/utils/clipboard.ts
77109
77466
  var import_child_process8 = require("child_process");
@@ -77192,7 +77549,7 @@ function loadTemplate(name) {
77192
77549
  if (!filePath) {
77193
77550
  throw new Error(`Adaptation prompt template not found: ${name}. Run npm run build.`);
77194
77551
  }
77195
- return fs41.readFileSync(filePath, "utf8");
77552
+ return fs42.readFileSync(filePath, "utf8");
77196
77553
  }
77197
77554
  function applyProfilePlaceholders(content, profile) {
77198
77555
  return content.replace(/\{\{PROFILE\}\}/g, profile).replace(/\{\{PROFILE_HINT\}\}/g, PROFILE_HINTS[profile]);
@@ -77214,7 +77571,7 @@ function buildMaintainAdaptationPrompt(_repoPath, bundleReport) {
77214
77571
  }
77215
77572
  function writeAdaptationPrompt(repoPath, content) {
77216
77573
  const harnessDir = getHarnessDir(repoPath);
77217
- const filePath = path45.join(harnessDir, ADAPTATION_PROMPT_FILE);
77574
+ const filePath = path46.join(harnessDir, ADAPTATION_PROMPT_FILE);
77218
77575
  writeFileSafe(filePath, content);
77219
77576
  return filePath;
77220
77577
  }
@@ -77231,8 +77588,8 @@ function printAdaptationPrompt(content) {
77231
77588
  `);
77232
77589
  process.stderr.write("\n");
77233
77590
  }
77234
- function askYesNo3(question) {
77235
- const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
77591
+ function askYesNo4(question) {
77592
+ const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
77236
77593
  return new Promise((resolve47) => {
77237
77594
  process.stderr.write(`${question} `);
77238
77595
  rl.once("line", (answer) => {
@@ -77250,7 +77607,7 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
77250
77607
  }
77251
77608
  let shouldCopy = options.autoYes === true;
77252
77609
  if (!shouldCopy && interactive) {
77253
- shouldCopy = await askYesNo3("Copy adaptation prompt to clipboard for your coding agent? [Y/n]");
77610
+ shouldCopy = await askYesNo4("Copy adaptation prompt to clipboard for your coding agent? [Y/n]");
77254
77611
  }
77255
77612
  if (!shouldCopy) {
77256
77613
  info("Skipped clipboard copy \u2014 prompt is in .har/ADAPT-PROMPT.md");
@@ -77269,27 +77626,27 @@ async function offerAdaptationPromptClipboard(content, options = {}) {
77269
77626
  }
77270
77627
 
77271
77628
  // src/harness/cursor-rule.ts
77272
- var fs42 = __toESM(require("fs"));
77273
- var path46 = __toESM(require("path"));
77274
- var readline5 = __toESM(require("readline"));
77629
+ var fs43 = __toESM(require("fs"));
77630
+ var path47 = __toESM(require("path"));
77631
+ var readline6 = __toESM(require("readline"));
77275
77632
  init_file_ops();
77276
77633
  init_logging();
77277
77634
  var CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/har-workflow.mdc";
77278
77635
  function getCursorRulePath(repoPath) {
77279
- return path46.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
77636
+ return path47.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
77280
77637
  }
77281
77638
  function isCursorWorkspace(repoPath) {
77282
- return fs42.existsSync(path46.join(repoPath, ".cursor"));
77639
+ return fs43.existsSync(path47.join(repoPath, ".cursor"));
77283
77640
  }
77284
77641
  function cursorRuleExists(repoPath) {
77285
- return fs42.existsSync(getCursorRulePath(repoPath));
77642
+ return fs43.existsSync(getCursorRulePath(repoPath));
77286
77643
  }
77287
77644
  function scaffoldCursorRule(repoPath) {
77288
77645
  const templatePath = resolveTemplateFile("cursor-rule.mdc.template");
77289
77646
  if (!templatePath) {
77290
77647
  throw new Error("Cursor rule template not found (cursor-rule.mdc.template). Run npm run build.");
77291
77648
  }
77292
- const content = fs42.readFileSync(templatePath, "utf8");
77649
+ const content = fs43.readFileSync(templatePath, "utf8");
77293
77650
  writeFileSafe(getCursorRulePath(repoPath), content);
77294
77651
  }
77295
77652
  async function handleCursorRule(options) {
@@ -77323,10 +77680,10 @@ async function handleCursorRule(options) {
77323
77680
  }
77324
77681
  async function promptScaffoldCursorRule(exists) {
77325
77682
  const action = exists ? "Update" : "Create";
77326
- return askYesNo4(`${action} ${CURSOR_RULE_RELATIVE_PATH}? [Y/n]`);
77683
+ return askYesNo5(`${action} ${CURSOR_RULE_RELATIVE_PATH}? [Y/n]`);
77327
77684
  }
77328
- async function askYesNo4(question) {
77329
- const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
77685
+ async function askYesNo5(question) {
77686
+ const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
77330
77687
  return new Promise((resolve47) => {
77331
77688
  process.stderr.write(`${question} `);
77332
77689
  rl.once("line", (answer) => {
@@ -77379,7 +77736,7 @@ init_control_config();
77379
77736
 
77380
77737
  // src/core/control-lifecycle.ts
77381
77738
  var import_child_process9 = require("child_process");
77382
- var path47 = __toESM(require("path"));
77739
+ var path48 = __toESM(require("path"));
77383
77740
 
77384
77741
  // src/core/control-image.ts
77385
77742
  var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
@@ -77405,10 +77762,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
77405
77762
  var CONTROL_CONTAINER_PORT = 3847;
77406
77763
  var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
77407
77764
  function resolveControlDir() {
77408
- return path47.resolve(__dirname, "..", "control");
77765
+ return path48.resolve(__dirname, "..", "control");
77409
77766
  }
77410
77767
  function resolveControlBuildContext() {
77411
- return path47.resolve(resolveControlDir(), "..");
77768
+ return path48.resolve(resolveControlDir(), "..");
77412
77769
  }
77413
77770
  function buildDockerRunArgs(options) {
77414
77771
  const name = options.containerName ?? CONTROL_CONTAINER_NAME;
@@ -77464,7 +77821,7 @@ async function startMissionControl(options) {
77464
77821
  "-t",
77465
77822
  imageRef,
77466
77823
  "-f",
77467
- path47.join(resolveControlDir(), "Dockerfile"),
77824
+ path48.join(resolveControlDir(), "Dockerfile"),
77468
77825
  resolveControlBuildContext()
77469
77826
  ]);
77470
77827
  if (buildCode !== 0) {
@@ -77611,7 +77968,7 @@ async function ensureTelemetryInfrastructure(options) {
77611
77968
  // src/core/run-service.ts
77612
77969
  init_telemetry_config();
77613
77970
  init_telemetry_env();
77614
- var path49 = __toESM(require("path"));
77971
+ var path50 = __toESM(require("path"));
77615
77972
  init_local_executor();
77616
77973
  function extractShellOutput(result) {
77617
77974
  const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
@@ -77814,12 +78171,12 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
77814
78171
  suffix: session.suffix,
77815
78172
  createdAt: session.createdAt
77816
78173
  });
77817
- const envFile = path49.join(session.workDir, `.env.agent.${options.agentId}`);
78174
+ const envFile = path50.join(session.workDir, `.env.agent.${options.agentId}`);
77818
78175
  try {
77819
78176
  appendTelemetryEnvToFile(envFile, {
77820
78177
  sessionKey,
77821
78178
  agentId: options.agentId,
77822
- repoPath: path49.resolve(options.repoPath),
78179
+ repoPath: path50.resolve(options.repoPath),
77823
78180
  workDir: session.workDir,
77824
78181
  branch: session.branch,
77825
78182
  suffix: session.suffix,
@@ -78054,12 +78411,12 @@ init_runs();
78054
78411
  init_slot_status();
78055
78412
 
78056
78413
  // src/core/commit-gate-onboarding.ts
78057
- var readline6 = __toESM(require("readline"));
78414
+ var readline7 = __toESM(require("readline"));
78058
78415
 
78059
78416
  // src/core/hooks.ts
78060
- var fs44 = __toESM(require("fs"));
78061
- var os15 = __toESM(require("os"));
78062
- var path50 = __toESM(require("path"));
78417
+ var fs45 = __toESM(require("fs"));
78418
+ var os16 = __toESM(require("os"));
78419
+ var path51 = __toESM(require("path"));
78063
78420
  init_shell();
78064
78421
  init_schema2();
78065
78422
  init_stages();
@@ -78090,7 +78447,7 @@ function resolveCheckoutRoot(cwd) {
78090
78447
  function resolveHooksDir(checkoutDir) {
78091
78448
  const hooksPath = tryGit3(checkoutDir, "rev-parse --git-path hooks");
78092
78449
  if (!hooksPath) throw new Error(`Not a git checkout: ${checkoutDir}`);
78093
- return path50.resolve(checkoutDir, hooksPath);
78450
+ return path51.resolve(checkoutDir, hooksPath);
78094
78451
  }
78095
78452
  function getConfiguredHooksPath(checkoutDir) {
78096
78453
  return tryGit3(checkoutDir, "config core.hooksPath") || void 0;
@@ -78098,9 +78455,9 @@ function getConfiguredHooksPath(checkoutDir) {
78098
78455
  function defaultHarInvocation() {
78099
78456
  const entry = process.argv[1];
78100
78457
  if (entry && entry.endsWith(".js")) {
78101
- return `"${process.execPath}" "${path50.resolve(entry)}"`;
78458
+ return `"${process.execPath}" "${path51.resolve(entry)}"`;
78102
78459
  }
78103
- if (entry) return `"${path50.resolve(entry)}"`;
78460
+ if (entry) return `"${path51.resolve(entry)}"`;
78104
78461
  return "har";
78105
78462
  }
78106
78463
  function buildHookScript(harInvocation, subcommand, failOpenNotice) {
@@ -78120,45 +78477,45 @@ echo "${failOpenNotice}" >&2
78120
78477
  exit 0
78121
78478
  `;
78122
78479
  }
78123
- function upsertMarkedBlock(filePath, block) {
78124
- if (!fs44.existsSync(filePath)) {
78125
- fs44.writeFileSync(filePath, `#!/bin/sh
78480
+ function upsertMarkedBlock2(filePath, block) {
78481
+ if (!fs45.existsSync(filePath)) {
78482
+ fs45.writeFileSync(filePath, `#!/bin/sh
78126
78483
  ${block}
78127
78484
  `, { mode: 493 });
78128
78485
  return "created";
78129
78486
  }
78130
- const content = fs44.readFileSync(filePath, "utf8");
78487
+ const content = fs45.readFileSync(filePath, "utf8");
78131
78488
  if (content.includes(MARKER_START)) {
78132
78489
  const pattern = new RegExp(
78133
- `${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}`
78490
+ `${escapeRegExp2(MARKER_START)}[\\s\\S]*?${escapeRegExp2(MARKER_END)}`
78134
78491
  );
78135
- fs44.writeFileSync(filePath, content.replace(pattern, block));
78136
- fs44.chmodSync(filePath, 493);
78492
+ fs45.writeFileSync(filePath, content.replace(pattern, block));
78493
+ fs45.chmodSync(filePath, 493);
78137
78494
  return "updated";
78138
78495
  }
78139
78496
  const suffix = content.endsWith("\n") ? "" : "\n";
78140
- fs44.writeFileSync(filePath, `${content}${suffix}
78497
+ fs45.writeFileSync(filePath, `${content}${suffix}
78141
78498
  ${block}
78142
78499
  `);
78143
- fs44.chmodSync(filePath, 493);
78500
+ fs45.chmodSync(filePath, 493);
78144
78501
  return "appended";
78145
78502
  }
78146
78503
  function removeMarkedBlock(filePath) {
78147
- if (!fs44.existsSync(filePath)) return false;
78148
- const content = fs44.readFileSync(filePath, "utf8");
78504
+ if (!fs45.existsSync(filePath)) return false;
78505
+ const content = fs45.readFileSync(filePath, "utf8");
78149
78506
  if (!content.includes(MARKER_START)) return false;
78150
78507
  const pattern = new RegExp(
78151
- `\\n?${escapeRegExp(MARKER_START)}[\\s\\S]*?${escapeRegExp(MARKER_END)}\\n?`
78508
+ `\\n?${escapeRegExp2(MARKER_START)}[\\s\\S]*?${escapeRegExp2(MARKER_END)}\\n?`
78152
78509
  );
78153
78510
  const stripped = content.replace(pattern, "\n");
78154
78511
  if (stripped.replace(/^#!\/bin\/sh\n?/, "").trim() === "") {
78155
- fs44.rmSync(filePath);
78512
+ fs45.rmSync(filePath);
78156
78513
  } else {
78157
- fs44.writeFileSync(filePath, stripped);
78514
+ fs45.writeFileSync(filePath, stripped);
78158
78515
  }
78159
78516
  return true;
78160
78517
  }
78161
- function escapeRegExp(value) {
78518
+ function escapeRegExp2(value) {
78162
78519
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
78163
78520
  }
78164
78521
  function installHooks(options) {
@@ -78176,20 +78533,20 @@ Or re-run with --force to write into that directory anyway.`
78176
78533
  );
78177
78534
  }
78178
78535
  const hooksDir = resolveHooksDir(checkout);
78179
- fs44.mkdirSync(hooksDir, { recursive: true });
78536
+ fs45.mkdirSync(hooksDir, { recursive: true });
78180
78537
  const invocation = options.harInvocation ?? defaultHarInvocation();
78181
- fs44.writeFileSync(
78182
- path50.join(hooksDir, "har-pre-commit"),
78538
+ fs45.writeFileSync(
78539
+ path51.join(hooksDir, "har-pre-commit"),
78183
78540
  buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
78184
78541
  { mode: 493 }
78185
78542
  );
78186
- fs44.writeFileSync(
78187
- path50.join(hooksDir, "har-post-commit"),
78543
+ fs45.writeFileSync(
78544
+ path51.join(hooksDir, "har-post-commit"),
78188
78545
  buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
78189
78546
  { mode: 493 }
78190
78547
  );
78191
- const preCommit = upsertMarkedBlock(path50.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
78192
- const postCommit = upsertMarkedBlock(path50.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
78548
+ const preCommit = upsertMarkedBlock2(path51.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
78549
+ const postCommit = upsertMarkedBlock2(path51.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
78193
78550
  ensureValidationsIgnored(checkout);
78194
78551
  return { hooksDir, preCommit, postCommit };
78195
78552
  }
@@ -78198,12 +78555,12 @@ function uninstallHooks(repoPath) {
78198
78555
  if (!checkout) throw new Error(`Not a git repository: ${repoPath}`);
78199
78556
  const hooksDir = resolveHooksDir(checkout);
78200
78557
  let removed = false;
78201
- removed = removeMarkedBlock(path50.join(hooksDir, "pre-commit")) || removed;
78202
- removed = removeMarkedBlock(path50.join(hooksDir, "post-commit")) || removed;
78558
+ removed = removeMarkedBlock(path51.join(hooksDir, "pre-commit")) || removed;
78559
+ removed = removeMarkedBlock(path51.join(hooksDir, "post-commit")) || removed;
78203
78560
  for (const file of ["har-pre-commit", "har-post-commit"]) {
78204
- const full = path50.join(hooksDir, file);
78205
- if (fs44.existsSync(full)) {
78206
- fs44.rmSync(full);
78561
+ const full = path51.join(hooksDir, file);
78562
+ if (fs45.existsSync(full)) {
78563
+ fs45.rmSync(full);
78207
78564
  removed = true;
78208
78565
  }
78209
78566
  }
@@ -78222,10 +78579,10 @@ function isAgentWorktree(checkoutDir) {
78222
78579
  if (branch && (/^har-agent-\d+$/.test(branch) || /-har-agent-\d+-[a-z0-9]+$/.test(branch))) {
78223
78580
  return true;
78224
78581
  }
78225
- const worktreesRoot = path50.join(os15.homedir(), "worktrees");
78226
- const resolved = path50.resolve(checkoutDir);
78227
- const name = path50.basename(resolved);
78228
- return resolved.startsWith(`${worktreesRoot}${path50.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
78582
+ const worktreesRoot = path51.join(os16.homedir(), "worktrees");
78583
+ const resolved = path51.resolve(checkoutDir);
78584
+ const name = path51.basename(resolved);
78585
+ return resolved.startsWith(`${worktreesRoot}${path51.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
78229
78586
  }
78230
78587
  function resolveEffectiveMode(checkoutDir, gate) {
78231
78588
  if (!gate.enabled) return "off";
@@ -78238,15 +78595,15 @@ function getHooksStatus(repoPath) {
78238
78595
  const hooksDir = resolveHooksDir(checkout);
78239
78596
  const gate = getCommitGateConfig(checkout);
78240
78597
  const hasBlock = (name) => {
78241
- const file = path50.join(hooksDir, name);
78242
- return fs44.existsSync(file) && fs44.readFileSync(file, "utf8").includes(MARKER_START);
78598
+ const file = path51.join(hooksDir, name);
78599
+ return fs45.existsSync(file) && fs45.readFileSync(file, "utf8").includes(MARKER_START);
78243
78600
  };
78244
78601
  return {
78245
78602
  checkout,
78246
78603
  hooksDir,
78247
78604
  configuredHooksPath: getConfiguredHooksPath(checkout),
78248
- preCommitInstalled: hasBlock("pre-commit") && fs44.existsSync(path50.join(hooksDir, "har-pre-commit")),
78249
- postCommitInstalled: hasBlock("post-commit") && fs44.existsSync(path50.join(hooksDir, "har-post-commit")),
78605
+ preCommitInstalled: hasBlock("pre-commit") && fs45.existsSync(path51.join(hooksDir, "har-pre-commit")),
78606
+ postCommitInstalled: hasBlock("post-commit") && fs45.existsSync(path51.join(hooksDir, "har-post-commit")),
78250
78607
  gate,
78251
78608
  effectiveMode: resolveEffectiveMode(checkout, gate)
78252
78609
  };
@@ -78257,7 +78614,7 @@ function checkCommitGate(cwd) {
78257
78614
  }
78258
78615
  const checkout = resolveCheckoutRoot(cwd);
78259
78616
  if (!checkout) return { exitCode: 0, messages: [] };
78260
- if (!fs44.existsSync(path50.join(checkout, ".har", "stages.json"))) {
78617
+ if (!fs45.existsSync(path51.join(checkout, ".har", "stages.json"))) {
78261
78618
  return { exitCode: 0, messages: [] };
78262
78619
  }
78263
78620
  const gate = getCommitGateConfig(checkout);
@@ -78330,8 +78687,8 @@ async function recordCommitAssociation(cwd) {
78330
78687
  // src/core/commit-gate-onboarding.ts
78331
78688
  init_stages();
78332
78689
  init_logging();
78333
- function askYesNo5(question) {
78334
- const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
78690
+ function askYesNo6(question) {
78691
+ const rl = readline7.createInterface({ input: process.stdin, output: process.stderr });
78335
78692
  return new Promise((resolve47) => {
78336
78693
  process.stderr.write(`${question} `);
78337
78694
  rl.once("line", (answer) => {
@@ -78362,7 +78719,7 @@ async function handleCommitGateOnboarding(options) {
78362
78719
  const status = getHooksStatus(options.repoPath);
78363
78720
  let shouldInstall = status.preCommitInstalled || status.postCommitInstalled || options.install === "always" || options.autoYes === true;
78364
78721
  if (!shouldInstall && options.install === "prompt" && process.stdin.isTTY && process.stdout.isTTY) {
78365
- shouldInstall = await askYesNo5("Install the HAR commit gate for this repository? [Y/n]");
78722
+ shouldInstall = await askYesNo6("Install the HAR commit gate for this repository? [Y/n]");
78366
78723
  }
78367
78724
  if (!shouldInstall) {
78368
78725
  info("Commit gate is not installed; run `har hooks install` when ready.");
@@ -78379,21 +78736,21 @@ async function handleCommitGateOnboarding(options) {
78379
78736
  }
78380
78737
 
78381
78738
  // src/core/onboarding-preferences.ts
78382
- var fs45 = __toESM(require("fs"));
78383
- var os16 = __toESM(require("os"));
78384
- var path51 = __toESM(require("path"));
78739
+ var fs46 = __toESM(require("fs"));
78740
+ var os17 = __toESM(require("os"));
78741
+ var path52 = __toESM(require("path"));
78385
78742
  init_schema2();
78386
78743
  function getOnboardingPreferencesPath() {
78387
78744
  if (process.env.HAR_PREFERENCES_PATH) {
78388
- return path51.resolve(process.env.HAR_PREFERENCES_PATH);
78745
+ return path52.resolve(process.env.HAR_PREFERENCES_PATH);
78389
78746
  }
78390
- return path51.join(os16.homedir(), ".har", "preferences.json");
78747
+ return path52.join(os17.homedir(), ".har", "preferences.json");
78391
78748
  }
78392
78749
  function readOnboardingPreferences() {
78393
78750
  const preferencePath = getOnboardingPreferencesPath();
78394
78751
  try {
78395
- if (!fs45.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
78396
- return OnboardingPreferencesSchema.parse(JSON.parse(fs45.readFileSync(preferencePath, "utf8")));
78752
+ if (!fs46.existsSync(preferencePath)) return OnboardingPreferencesSchema.parse({});
78753
+ return OnboardingPreferencesSchema.parse(JSON.parse(fs46.readFileSync(preferencePath, "utf8")));
78397
78754
  } catch {
78398
78755
  return OnboardingPreferencesSchema.parse({});
78399
78756
  }
@@ -78418,8 +78775,8 @@ function writeOnboardingPreferences(overrides) {
78418
78775
  };
78419
78776
  const parsed = OnboardingPreferencesSchema.parse(preference);
78420
78777
  const preferencePath = getOnboardingPreferencesPath();
78421
- fs45.mkdirSync(path51.dirname(preferencePath), { recursive: true });
78422
- fs45.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
78778
+ fs46.mkdirSync(path52.dirname(preferencePath), { recursive: true });
78779
+ fs46.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
78423
78780
  `);
78424
78781
  return parsed;
78425
78782
  }
@@ -78713,7 +79070,7 @@ var envCommand = {
78713
79070
  }
78714
79071
  };
78715
79072
  async function handleInit(argv) {
78716
- const repoPath = path52.resolve(argv.repo);
79073
+ const repoPath = path53.resolve(argv.repo);
78717
79074
  const onboarding = resolveOnboardingOptions(argv);
78718
79075
  header("har env init");
78719
79076
  info(`Repository: ${repoPath}`);
@@ -78756,18 +79113,13 @@ async function handleInit(argv) {
78756
79113
  ...onboarding.commitGate,
78757
79114
  autoYes: argv.yes
78758
79115
  });
78759
- await handleCursorRule({
79116
+ await applyAgentIntegrations({
78760
79117
  repoPath,
78761
- cursorRule: onboarding.cursorRule,
78762
- autoYes: argv.yes,
78763
- mode: "init"
78764
- });
78765
- await handleAgentSkills({
78766
- repoPath,
78767
- ...onboarding.agentSkills,
79118
+ mode: "init",
78768
79119
  autoYes: argv.yes,
78769
79120
  force: argv.force,
78770
- mode: "init"
79121
+ cursorRule: onboarding.cursorRule,
79122
+ ...onboarding.agentSkills
78771
79123
  });
78772
79124
  printNextSteps(argv.auto);
78773
79125
  } catch (err) {
@@ -78776,7 +79128,7 @@ async function handleInit(argv) {
78776
79128
  }
78777
79129
  }
78778
79130
  async function handleMaintain(argv) {
78779
- const repoPath = path52.resolve(argv.repo);
79131
+ const repoPath = path53.resolve(argv.repo);
78780
79132
  const onboarding = resolveOnboardingOptions(argv);
78781
79133
  header("har env maintain");
78782
79134
  info(`Repository: ${repoPath}`);
@@ -78840,17 +79192,12 @@ async function handleMaintain(argv) {
78840
79192
  ...onboarding.commitGate,
78841
79193
  autoYes: argv.yes
78842
79194
  });
78843
- await handleCursorRule({
79195
+ await applyAgentIntegrations({
78844
79196
  repoPath,
78845
- cursorRule: onboarding.cursorRule,
79197
+ mode: "maintain",
78846
79198
  autoYes: argv.yes,
78847
- mode: "maintain"
78848
- });
78849
- await handleAgentSkills({
78850
- repoPath,
78851
- ...onboarding.agentSkills,
78852
- autoYes: argv.yes,
78853
- mode: "maintain"
79199
+ cursorRule: onboarding.cursorRule,
79200
+ ...onboarding.agentSkills
78854
79201
  });
78855
79202
  } catch (err) {
78856
79203
  error(err.message);
@@ -78898,16 +79245,43 @@ async function handleAgentMdProposal(repoPath, autoYes) {
78898
79245
  if (autoYes) {
78899
79246
  const proposal = readAgentMdProposal(repoPath);
78900
79247
  if (proposal) {
78901
- writeFileSafe(path52.join(repoPath, "AGENT.md"), proposal.content);
79248
+ writeFileSafe(path53.join(repoPath, AGENTS_MD), proposal.content);
78902
79249
  clearAgentMdProposal(repoPath);
78903
- info("Applied AGENT.md proposal (--yes)");
79250
+ info(`Applied ${AGENTS_MD} proposal (--yes)`);
78904
79251
  }
78905
79252
  return;
78906
79253
  }
78907
79254
  await promptApplyAgentMdProposal(repoPath);
78908
79255
  }
79256
+ async function applyAgentIntegrations(options) {
79257
+ const instruction = await handleInstructionFiles({
79258
+ repoPath: options.repoPath,
79259
+ agents: options.agents,
79260
+ enabled: options.enabled,
79261
+ cursorRule: options.cursorRule,
79262
+ autoYes: options.autoYes,
79263
+ mode: options.mode
79264
+ });
79265
+ const cursorRuleFlag = options.cursorRule === false ? false : options.cursorRule === true || instruction.plan.cursorRule ? true : false;
79266
+ await handleCursorRule({
79267
+ repoPath: options.repoPath,
79268
+ cursorRule: cursorRuleFlag,
79269
+ autoYes: options.autoYes,
79270
+ mode: options.mode
79271
+ });
79272
+ if (instruction.plan.skills.length > 0) {
79273
+ await handleAgentSkills({
79274
+ repoPath: options.repoPath,
79275
+ agents: instruction.plan.skills.join(","),
79276
+ autoYes: options.autoYes,
79277
+ force: options.force,
79278
+ mode: options.mode
79279
+ });
79280
+ } else if (options.enabled === false) {
79281
+ }
79282
+ }
78909
79283
  async function handleAddPlugin(argv) {
78910
- const repoPath = path52.resolve(argv.repo);
79284
+ const repoPath = path53.resolve(argv.repo);
78911
79285
  const available = listPluginIds();
78912
79286
  if (argv.list) {
78913
79287
  for (const id of available) {
@@ -78945,7 +79319,7 @@ async function handleAddPlugin(argv) {
78945
79319
  }
78946
79320
  }
78947
79321
  async function handleAddStage(argv) {
78948
- const repoPath = path52.resolve(argv.repo);
79322
+ const repoPath = path53.resolve(argv.repo);
78949
79323
  const available = listPluginIds();
78950
79324
  if (argv.list) {
78951
79325
  warn("har env add-stage --list is deprecated; prefer: har env add-plugin --list");
@@ -79011,7 +79385,7 @@ async function handleAddStage(argv) {
79011
79385
  });
79012
79386
  }
79013
79387
  async function handlePreflight(argv) {
79014
- const repo = path52.resolve(argv.repo);
79388
+ const repo = path53.resolve(argv.repo);
79015
79389
  const agentId = validateAgentId(argv.id, repo);
79016
79390
  const result = await preflightEnvironment({
79017
79391
  repoPath: repo,
@@ -79027,7 +79401,7 @@ async function handlePreflight(argv) {
79027
79401
  return finishCommand(result.code);
79028
79402
  }
79029
79403
  async function handleLaunch(argv) {
79030
- const repo = path52.resolve(argv.repo);
79404
+ const repo = path53.resolve(argv.repo);
79031
79405
  const agentId = validateAgentId(argv.id, repo);
79032
79406
  if (!argv.resume) {
79033
79407
  const guard = checkLaunchGuard2(repo, agentId, {});
@@ -79082,7 +79456,7 @@ async function handleRecover(argv) {
79082
79456
  });
79083
79457
  }
79084
79458
  async function handleVerify(argv) {
79085
- const repo = path52.resolve(argv.repo);
79459
+ const repo = path53.resolve(argv.repo);
79086
79460
  const agentId = validateAgentId(argv.id, repo);
79087
79461
  const result = await runVerification({
79088
79462
  repoPath: repo,
@@ -79094,7 +79468,7 @@ async function handleVerify(argv) {
79094
79468
  return finishCommand(result.code);
79095
79469
  }
79096
79470
  async function handleTeardown(argv) {
79097
- const repo = path52.resolve(argv.repo);
79471
+ const repo = path53.resolve(argv.repo);
79098
79472
  const agentId = validateAgentId(argv.id, repo);
79099
79473
  const result = await teardownEnvironment({
79100
79474
  repoPath: repo,
@@ -79105,7 +79479,7 @@ async function handleTeardown(argv) {
79105
79479
  return finishCommand(result.code);
79106
79480
  }
79107
79481
  async function handleComplete(argv) {
79108
- const repo = path52.resolve(argv.repo);
79482
+ const repo = path53.resolve(argv.repo);
79109
79483
  const agentId = validateAgentId(argv.id, repo);
79110
79484
  const result = await completeEnvironment({
79111
79485
  repoPath: repo,
@@ -79126,7 +79500,7 @@ async function handleComplete(argv) {
79126
79500
  return finishCommand(result.code);
79127
79501
  }
79128
79502
  async function handleStatus(argv) {
79129
- const repoPath = path52.resolve(argv.repo);
79503
+ const repoPath = path53.resolve(argv.repo);
79130
79504
  if (argv.json) {
79131
79505
  const status = collectEnvironmentStatus(repoPath);
79132
79506
  const output = EnvironmentStatusSchema.parse(status);
@@ -79139,7 +79513,7 @@ async function handleStatus(argv) {
79139
79513
  });
79140
79514
  }
79141
79515
  async function handleRunsList(argv) {
79142
- const repoPath = path52.resolve(argv.repo);
79516
+ const repoPath = path53.resolve(argv.repo);
79143
79517
  const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
79144
79518
  if (argv.json) {
79145
79519
  process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
@@ -79156,7 +79530,7 @@ async function handleRunsList(argv) {
79156
79530
  }
79157
79531
  }
79158
79532
  async function handleRunsGet(argv) {
79159
- const run2 = getRun(path52.resolve(argv.repo), argv.runId);
79533
+ const run2 = getRun(path53.resolve(argv.repo), argv.runId);
79160
79534
  if (!run2) {
79161
79535
  error(`Run not found: ${argv.runId}`);
79162
79536
  return finishCommand(1);
@@ -79231,7 +79605,7 @@ function printNextSteps(auto2) {
79231
79605
  console.error(" Adapt: paste clipboard / prompt above into your coding agent");
79232
79606
  console.error(" Prompt file: .har/ADAPT-PROMPT.md");
79233
79607
  } else {
79234
- console.error(" Agent guide: AGENT.md (repo root, if applied)");
79608
+ console.error(" Agent guide: AGENTS.md (repo root, if applied)");
79235
79609
  }
79236
79610
  console.error(" Setup infra: ./.har/setup-infra.sh # when Docker infra is enabled");
79237
79611
  console.error(" Launch: har env launch 1 # preferred; or ./.har/launch.sh 1");
@@ -79242,7 +79616,7 @@ function printNextSteps(auto2) {
79242
79616
  }
79243
79617
 
79244
79618
  // src/cli/commands/control.ts
79245
- var path56 = __toESM(require("path"));
79619
+ var path57 = __toESM(require("path"));
79246
79620
 
79247
79621
  // node_modules/@inquirer/core/dist/esm/lib/key.mjs
79248
79622
  var isUpKey = (key) => (
@@ -79323,7 +79697,7 @@ function getStore() {
79323
79697
  }
79324
79698
  return store;
79325
79699
  }
79326
- function readline7() {
79700
+ function readline8() {
79327
79701
  return getStore().rl;
79328
79702
  }
79329
79703
  function withUpdates(fn) {
@@ -79368,7 +79742,7 @@ var effectScheduler = {
79368
79742
  const { index } = store;
79369
79743
  store.hooksEffect.push(() => {
79370
79744
  store.hooksCleanup[index]?.();
79371
- const cleanFn = cb(readline7());
79745
+ const cleanFn = cb(readline8());
79372
79746
  if (cleanFn != null && typeof cleanFn !== "function") {
79373
79747
  throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
79374
79748
  }
@@ -79844,7 +80218,7 @@ function breakLines(content, width) {
79844
80218
  return content.split("\n").flatMap((line) => (0, import_wrap_ansi.default)(line, width, { trim: false, hard: true }).split("\n").map((str) => str.trimEnd())).join("\n");
79845
80219
  }
79846
80220
  function readlineWidth() {
79847
- return (0, import_cli_width.default)({ defaultWidth: 80, output: readline7().output });
80221
+ return (0, import_cli_width.default)({ defaultWidth: 80, output: readline8().output });
79848
80222
  }
79849
80223
 
79850
80224
  // node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
@@ -79936,7 +80310,7 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
79936
80310
  }
79937
80311
 
79938
80312
  // node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
79939
- var readline8 = __toESM(require("node:readline"), 1);
80313
+ var readline9 = __toESM(require("node:readline"), 1);
79940
80314
  var import_node_async_hooks3 = require("node:async_hooks");
79941
80315
  var import_mute_stream = __toESM(require_lib3(), 1);
79942
80316
 
@@ -80279,7 +80653,7 @@ function createPrompt(view) {
80279
80653
  const cleanups = /* @__PURE__ */ new Set();
80280
80654
  const output = new import_mute_stream.default();
80281
80655
  output.pipe(context.output ?? process.stdout);
80282
- const rl = readline8.createInterface({
80656
+ const rl = readline9.createInterface({
80283
80657
  terminal: true,
80284
80658
  input,
80285
80659
  output
@@ -81296,9 +81670,9 @@ var import_run_async = __toESM(require_run_async(), 1);
81296
81670
  var import_mute_stream2 = __toESM(require_lib3(), 1);
81297
81671
  var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
81298
81672
  var _2 = {
81299
- set: (obj, path63 = "", value) => {
81673
+ set: (obj, path64 = "", value) => {
81300
81674
  let pointer = obj;
81301
- path63.split(".").forEach((key, index, arr) => {
81675
+ path64.split(".").forEach((key, index, arr) => {
81302
81676
  if (key === "__proto__" || key === "constructor")
81303
81677
  return;
81304
81678
  if (index === arr.length - 1) {
@@ -81309,8 +81683,8 @@ var _2 = {
81309
81683
  pointer = pointer[key];
81310
81684
  });
81311
81685
  },
81312
- get: (obj, path63 = "", defaultValue) => {
81313
- const travel = (regexp) => String.prototype.split.call(path63, regexp).filter(Boolean).reduce(
81686
+ get: (obj, path64 = "", defaultValue) => {
81687
+ const travel = (regexp) => String.prototype.split.call(path64, regexp).filter(Boolean).reduce(
81314
81688
  // @ts-expect-error implicit any on res[key]
81315
81689
  (res, key) => res !== null && res !== void 0 ? res[key] : res,
81316
81690
  obj
@@ -81564,21 +81938,21 @@ init_control_port();
81564
81938
  init_control_sync();
81565
81939
 
81566
81940
  // src/core/control-sync-selection.ts
81567
- var fs46 = __toESM(require("fs"));
81568
- var os17 = __toESM(require("os"));
81569
- var path53 = __toESM(require("path"));
81941
+ var fs47 = __toESM(require("fs"));
81942
+ var os18 = __toESM(require("os"));
81943
+ var path54 = __toESM(require("path"));
81570
81944
  init_control_repo_path();
81571
81945
  function getSelectionPath() {
81572
81946
  if (process.env.HAR_CONTROL_SYNC_SELECTION_PATH) {
81573
- return path53.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
81947
+ return path54.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
81574
81948
  }
81575
- return path53.join(os17.homedir(), ".har", "sync-selection.json");
81949
+ return path54.join(os18.homedir(), ".har", "sync-selection.json");
81576
81950
  }
81577
81951
  function readSyncSelection() {
81578
81952
  const selectionPath = getSelectionPath();
81579
81953
  try {
81580
- if (!fs46.existsSync(selectionPath)) return null;
81581
- const parsed = JSON.parse(fs46.readFileSync(selectionPath, "utf8"));
81954
+ if (!fs47.existsSync(selectionPath)) return null;
81955
+ const parsed = JSON.parse(fs47.readFileSync(selectionPath, "utf8"));
81582
81956
  if (!Array.isArray(parsed.repos)) return null;
81583
81957
  return parsed.repos.map((repoPath) => canonicalizeControlRepoPath(repoPath));
81584
81958
  } catch {
@@ -81588,8 +81962,8 @@ function readSyncSelection() {
81588
81962
  function writeSyncSelection(repos) {
81589
81963
  const selectionPath = getSelectionPath();
81590
81964
  const canonical = Array.from(new Set(repos.map((repoPath) => canonicalizeControlRepoPath(repoPath))));
81591
- fs46.mkdirSync(path53.dirname(selectionPath), { recursive: true });
81592
- fs46.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
81965
+ fs47.mkdirSync(path54.dirname(selectionPath), { recursive: true });
81966
+ fs47.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
81593
81967
  }
81594
81968
  function resolveSyncSelection(input) {
81595
81969
  const { discovered, stored, forceSelect, isTTY } = input;
@@ -81696,8 +82070,8 @@ If your browser did not open, paste that URL.
81696
82070
  }
81697
82071
 
81698
82072
  // src/core/control-unregister.ts
81699
- var fs47 = __toESM(require("fs"));
81700
- var path54 = __toESM(require("path"));
82073
+ var fs48 = __toESM(require("fs"));
82074
+ var path55 = __toESM(require("path"));
81701
82075
  init_control_repo_path();
81702
82076
  init_control_registry();
81703
82077
  init_control_config();
@@ -81707,9 +82081,9 @@ function listUnregisterWorktreeCandidates(repoPath) {
81707
82081
  const harnessRoot = canonicalizeControlRepoPath(repoPath);
81708
82082
  const byPath = /* @__PURE__ */ new Map();
81709
82083
  const add = (partial2) => {
81710
- const resolved = path54.resolve(partial2.worktreePath);
82084
+ const resolved = path55.resolve(partial2.worktreePath);
81711
82085
  if (!resolved || resolved === harnessRoot) return;
81712
- const exists = partial2.exists ?? fs47.existsSync(resolved);
82086
+ const exists = partial2.exists ?? fs48.existsSync(resolved);
81713
82087
  const prev = byPath.get(resolved);
81714
82088
  if (prev) {
81715
82089
  byPath.set(resolved, {
@@ -81756,10 +82130,10 @@ function listUnregisterWorktreeCandidates(repoPath) {
81756
82130
  }
81757
82131
  return [...byPath.values()].sort((a2, b3) => a2.agentId - b3.agentId);
81758
82132
  }
81759
- async function askYesNo6(question) {
82133
+ async function askYesNo7(question) {
81760
82134
  if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
81761
- const readline10 = await import("readline");
81762
- const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
82135
+ const readline11 = await import("readline");
82136
+ const rl = readline11.createInterface({ input: process.stdin, output: process.stderr });
81763
82137
  const answer = await new Promise((resolve47) => {
81764
82138
  rl.question(question, resolve47);
81765
82139
  });
@@ -81773,7 +82147,7 @@ async function confirmUnregister(options) {
81773
82147
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
81774
82148
  throw new Error("Non-interactive terminal \u2014 pass --yes (and optionally --delete-worktrees)");
81775
82149
  }
81776
- const proceed = await askYesNo6("Unregister this repository from Mission Control? [y/N] ");
82150
+ const proceed = await askYesNo7("Unregister this repository from Mission Control? [y/N] ");
81777
82151
  if (!proceed) return { proceed: false, deleteWorktrees: false };
81778
82152
  const existing = options.worktrees.filter((w3) => w3.exists);
81779
82153
  if (existing.length === 0) {
@@ -81785,7 +82159,7 @@ async function confirmUnregister(options) {
81785
82159
  process.stderr.write(` agent-${wt2.agentId}: ${wt2.worktreePath}${dirty}
81786
82160
  `);
81787
82161
  }
81788
- const deleteWorktrees = await askYesNo6(
82162
+ const deleteWorktrees = await askYesNo7(
81789
82163
  `Also delete ${existing.length} session worktree(s) on disk? [y/N] `
81790
82164
  );
81791
82165
  return { proceed: true, deleteWorktrees };
@@ -81823,28 +82197,28 @@ async function teardownWorktrees(repoPath, candidates, dryRun) {
81823
82197
  trigger: "cli"
81824
82198
  });
81825
82199
  if (result.code !== 0) {
81826
- if (fs47.existsSync(candidate.worktreePath)) {
81827
- fs47.rmSync(candidate.worktreePath, { recursive: true, force: true });
82200
+ if (fs48.existsSync(candidate.worktreePath)) {
82201
+ fs48.rmSync(candidate.worktreePath, { recursive: true, force: true });
81828
82202
  }
81829
82203
  }
81830
82204
  outcomes.push({
81831
82205
  path: candidate.worktreePath,
81832
82206
  agentId: candidate.agentId,
81833
- deleted: !fs47.existsSync(candidate.worktreePath),
81834
- error: result.code !== 0 && fs47.existsSync(candidate.worktreePath) ? result.stderr : void 0
82207
+ deleted: !fs48.existsSync(candidate.worktreePath),
82208
+ error: result.code !== 0 && fs48.existsSync(candidate.worktreePath) ? result.stderr : void 0
81835
82209
  });
81836
82210
  } catch (err) {
81837
82211
  const message = err instanceof Error ? err.message : String(err);
81838
82212
  try {
81839
- if (fs47.existsSync(candidate.worktreePath)) {
81840
- fs47.rmSync(candidate.worktreePath, { recursive: true, force: true });
82213
+ if (fs48.existsSync(candidate.worktreePath)) {
82214
+ fs48.rmSync(candidate.worktreePath, { recursive: true, force: true });
81841
82215
  }
81842
82216
  } catch {
81843
82217
  }
81844
82218
  outcomes.push({
81845
82219
  path: candidate.worktreePath,
81846
82220
  agentId: candidate.agentId,
81847
- deleted: !fs47.existsSync(candidate.worktreePath),
82221
+ deleted: !fs48.existsSync(candidate.worktreePath),
81848
82222
  error: message
81849
82223
  });
81850
82224
  }
@@ -81907,16 +82281,16 @@ init_control_config();
81907
82281
  init_control_registry();
81908
82282
 
81909
82283
  // src/core/harness-scrub.ts
81910
- var fs48 = __toESM(require("fs"));
81911
- var path55 = __toESM(require("path"));
82284
+ var fs49 = __toESM(require("fs"));
82285
+ var path56 = __toESM(require("path"));
81912
82286
  var HARNESS_SCRUB_DIRS = ["runs", "validations", "state", "slots"];
81913
82287
  function scrubLocalHarnessDirs(repoPath) {
81914
82288
  const results = [];
81915
- const resolved = path55.resolve(repoPath);
81916
- if (!fs48.existsSync(resolved)) {
82289
+ const resolved = path56.resolve(repoPath);
82290
+ if (!fs49.existsSync(resolved)) {
81917
82291
  for (const directory of HARNESS_SCRUB_DIRS) {
81918
82292
  results.push({
81919
- path: path55.join(resolved, ".har", directory),
82293
+ path: path56.join(resolved, ".har", directory),
81920
82294
  directory,
81921
82295
  deleted: false,
81922
82296
  error: "repository path does not exist"
@@ -81925,24 +82299,24 @@ function scrubLocalHarnessDirs(repoPath) {
81925
82299
  return results;
81926
82300
  }
81927
82301
  for (const directory of HARNESS_SCRUB_DIRS) {
81928
- const target = path55.join(resolved, ".har", directory);
81929
- if (!fs48.existsSync(target)) {
82302
+ const target = path56.join(resolved, ".har", directory);
82303
+ if (!fs49.existsSync(target)) {
81930
82304
  results.push({ path: target, directory, deleted: true });
81931
82305
  continue;
81932
82306
  }
81933
82307
  try {
81934
- fs48.rmSync(target, { recursive: true, force: true });
82308
+ fs49.rmSync(target, { recursive: true, force: true });
81935
82309
  results.push({
81936
82310
  path: target,
81937
82311
  directory,
81938
- deleted: !fs48.existsSync(target),
81939
- error: fs48.existsSync(target) ? "failed to remove directory" : void 0
82312
+ deleted: !fs49.existsSync(target),
82313
+ error: fs49.existsSync(target) ? "failed to remove directory" : void 0
81940
82314
  });
81941
82315
  } catch (err) {
81942
82316
  results.push({
81943
82317
  path: target,
81944
82318
  directory,
81945
- deleted: !fs48.existsSync(target),
82319
+ deleted: !fs49.existsSync(target),
81946
82320
  error: err instanceof Error ? err.message : String(err)
81947
82321
  });
81948
82322
  }
@@ -81953,7 +82327,7 @@ function scrubLocalHarnessForRepos(repoPaths) {
81953
82327
  const results = [];
81954
82328
  const seen = /* @__PURE__ */ new Set();
81955
82329
  for (const repoPath of repoPaths) {
81956
- const key = path55.resolve(repoPath);
82330
+ const key = path56.resolve(repoPath);
81957
82331
  if (seen.has(key)) continue;
81958
82332
  seen.add(key);
81959
82333
  results.push(...scrubLocalHarnessDirs(key));
@@ -81962,10 +82336,10 @@ function scrubLocalHarnessForRepos(repoPaths) {
81962
82336
  }
81963
82337
 
81964
82338
  // src/core/control-reset.ts
81965
- async function askYesNo7(question) {
82339
+ async function askYesNo8(question) {
81966
82340
  if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
81967
- const readline10 = await import("readline");
81968
- const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
82341
+ const readline11 = await import("readline");
82342
+ const rl = readline11.createInterface({ input: process.stdin, output: process.stderr });
81969
82343
  const answer = await new Promise((resolve47) => {
81970
82344
  rl.question(question, resolve47);
81971
82345
  });
@@ -81977,7 +82351,7 @@ async function confirmControlReset(options) {
81977
82351
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
81978
82352
  throw new Error("Non-interactive terminal \u2014 pass --yes");
81979
82353
  }
81980
- return askYesNo7(
82354
+ return askYesNo8(
81981
82355
  `Clear Mission Control data for ${options.repoCount} registered repositor${options.repoCount === 1 ? "y" : "ies"} (and scrub local .har history)? [y/N] `
81982
82356
  );
81983
82357
  }
@@ -82209,7 +82583,7 @@ async function handleDown() {
82209
82583
  return finishCommand(code);
82210
82584
  }
82211
82585
  async function handleRegister(argv) {
82212
- const repoPath = path56.resolve(argv.repo);
82586
+ const repoPath = path57.resolve(argv.repo);
82213
82587
  header("har control register");
82214
82588
  info(`Repository: ${repoPath}`);
82215
82589
  try {
@@ -82301,7 +82675,7 @@ async function handleReset(argv) {
82301
82675
  }
82302
82676
  }
82303
82677
  async function handleUnregister(argv) {
82304
- const repoPath = path56.resolve(argv.repo);
82678
+ const repoPath = path57.resolve(argv.repo);
82305
82679
  const worktrees = listUnregisterWorktreeCandidates(repoPath);
82306
82680
  try {
82307
82681
  let deleteWorktrees = argv.deleteWorktrees;
@@ -82480,11 +82854,11 @@ async function handleLogin(argv) {
82480
82854
  }
82481
82855
 
82482
82856
  // src/cli/commands/hooks.ts
82483
- var path58 = __toESM(require("path"));
82857
+ var path59 = __toESM(require("path"));
82484
82858
 
82485
82859
  // src/core/claude-hooks.ts
82486
- var fs49 = __toESM(require("fs"));
82487
- var path57 = __toESM(require("path"));
82860
+ var fs50 = __toESM(require("fs"));
82861
+ var path58 = __toESM(require("path"));
82488
82862
  var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
82489
82863
  var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
82490
82864
  var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
@@ -82495,8 +82869,8 @@ function isHarGuardEntry(entry) {
82495
82869
  );
82496
82870
  }
82497
82871
  function readSettings(settingsPath) {
82498
- if (!fs49.existsSync(settingsPath)) return {};
82499
- const raw = fs49.readFileSync(settingsPath, "utf8").trim();
82872
+ if (!fs50.existsSync(settingsPath)) return {};
82873
+ const raw = fs50.readFileSync(settingsPath, "utf8").trim();
82500
82874
  if (raw === "") return {};
82501
82875
  const parsed = JSON.parse(raw);
82502
82876
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
@@ -82505,19 +82879,19 @@ function readSettings(settingsPath) {
82505
82879
  return parsed;
82506
82880
  }
82507
82881
  function writeSettings(settingsPath, settings) {
82508
- fs49.mkdirSync(path57.dirname(settingsPath), { recursive: true });
82509
- fs49.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
82882
+ fs50.mkdirSync(path58.dirname(settingsPath), { recursive: true });
82883
+ fs50.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
82510
82884
  }
82511
82885
  function installClaudeGuard(repoPath) {
82512
82886
  const templatePath = resolveTemplateFile("claude-worktree-guard.sh.template");
82513
82887
  if (!templatePath) {
82514
82888
  throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
82515
82889
  }
82516
- const guardScript = path57.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
82517
- fs49.mkdirSync(path57.dirname(guardScript), { recursive: true });
82518
- fs49.copyFileSync(templatePath, guardScript);
82519
- fs49.chmodSync(guardScript, 493);
82520
- const settingsPath = path57.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
82890
+ const guardScript = path58.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
82891
+ fs50.mkdirSync(path58.dirname(guardScript), { recursive: true });
82892
+ fs50.copyFileSync(templatePath, guardScript);
82893
+ fs50.chmodSync(guardScript, 493);
82894
+ const settingsPath = path58.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
82521
82895
  const settings = readSettings(settingsPath);
82522
82896
  const hooks = settings.hooks ?? {};
82523
82897
  const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
@@ -82531,15 +82905,15 @@ function installClaudeGuard(repoPath) {
82531
82905
  }
82532
82906
  function uninstallClaudeGuard(repoPath) {
82533
82907
  let removed = false;
82534
- const guardScript = path57.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
82535
- if (fs49.existsSync(guardScript)) {
82536
- fs49.rmSync(guardScript);
82908
+ const guardScript = path58.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
82909
+ if (fs50.existsSync(guardScript)) {
82910
+ fs50.rmSync(guardScript);
82537
82911
  removed = true;
82538
- const parent = path57.dirname(guardScript);
82539
- if (fs49.existsSync(parent) && fs49.readdirSync(parent).length === 0) fs49.rmdirSync(parent);
82912
+ const parent = path58.dirname(guardScript);
82913
+ if (fs50.existsSync(parent) && fs50.readdirSync(parent).length === 0) fs50.rmdirSync(parent);
82540
82914
  }
82541
- const settingsPath = path57.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
82542
- if (fs49.existsSync(settingsPath)) {
82915
+ const settingsPath = path58.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
82916
+ if (fs50.existsSync(settingsPath)) {
82543
82917
  const settings = readSettings(settingsPath);
82544
82918
  const preToolUse = settings.hooks?.PreToolUse;
82545
82919
  if (preToolUse) {
@@ -82564,8 +82938,8 @@ function uninstallClaudeGuard(repoPath) {
82564
82938
  return { removed };
82565
82939
  }
82566
82940
  function claudeGuardInstalled(repoPath) {
82567
- const settingsPath = path57.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
82568
- if (!fs49.existsSync(settingsPath)) return false;
82941
+ const settingsPath = path58.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
82942
+ if (!fs50.existsSync(settingsPath)) return false;
82569
82943
  try {
82570
82944
  const settings = readSettings(settingsPath);
82571
82945
  return (settings.hooks?.PreToolUse ?? []).some(isHarGuardEntry);
@@ -82582,7 +82956,7 @@ function repoOption(y2) {
82582
82956
  function handleInstall2(argv) {
82583
82957
  try {
82584
82958
  if (argv.claude) {
82585
- const result2 = installClaudeGuard(path58.resolve(argv.repo));
82959
+ const result2 = installClaudeGuard(path59.resolve(argv.repo));
82586
82960
  success("Claude Code worktree guard installed.");
82587
82961
  info(`Guard script: ${result2.guardScript}`);
82588
82962
  info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
@@ -82590,7 +82964,7 @@ function handleInstall2(argv) {
82590
82964
  info("Commit both files so the guard travels with the repo.");
82591
82965
  return;
82592
82966
  }
82593
- const result = installHooks({ repoPath: path58.resolve(argv.repo), force: argv.force });
82967
+ const result = installHooks({ repoPath: path59.resolve(argv.repo), force: argv.force });
82594
82968
  success(`Commit gate installed in ${result.hooksDir}`);
82595
82969
  info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
82596
82970
  info("Commits of unverified change batches will be blocked in agent worktrees.");
@@ -82603,7 +82977,7 @@ function handleInstall2(argv) {
82603
82977
  function handleUninstall(argv) {
82604
82978
  try {
82605
82979
  if (argv.claude) {
82606
- const result2 = uninstallClaudeGuard(path58.resolve(argv.repo));
82980
+ const result2 = uninstallClaudeGuard(path59.resolve(argv.repo));
82607
82981
  if (result2.removed) {
82608
82982
  success("Claude Code worktree guard removed.");
82609
82983
  } else {
@@ -82611,7 +82985,7 @@ function handleUninstall(argv) {
82611
82985
  }
82612
82986
  return;
82613
82987
  }
82614
- const result = uninstallHooks(path58.resolve(argv.repo));
82988
+ const result = uninstallHooks(path59.resolve(argv.repo));
82615
82989
  if (result.removed) {
82616
82990
  success(`Commit gate removed from ${result.hooksDir}`);
82617
82991
  } else {
@@ -82624,7 +82998,7 @@ function handleUninstall(argv) {
82624
82998
  }
82625
82999
  function handleStatus2(argv) {
82626
83000
  try {
82627
- const status = getHooksStatus(path58.resolve(argv.repo));
83001
+ const status = getHooksStatus(path59.resolve(argv.repo));
82628
83002
  if (argv.json) {
82629
83003
  process.stdout.write(`${JSON.stringify(status, null, 2)}
82630
83004
  `);
@@ -82642,7 +83016,7 @@ function handleStatus2(argv) {
82642
83016
  );
82643
83017
  info(`Effective: ${status.effectiveMode} (in this checkout)`);
82644
83018
  info(
82645
- `Claude guard: ${claudeGuardInstalled(path58.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
83019
+ `Claude guard: ${claudeGuardInstalled(path59.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
82646
83020
  );
82647
83021
  } catch (err) {
82648
83022
  error(err instanceof Error ? err.message : String(err));
@@ -82903,10 +83277,10 @@ function assignProp(target, prop, value) {
82903
83277
  configurable: true
82904
83278
  });
82905
83279
  }
82906
- function getElementAtPath(obj, path63) {
82907
- if (!path63)
83280
+ function getElementAtPath(obj, path64) {
83281
+ if (!path64)
82908
83282
  return obj;
82909
- return path63.reduce((acc, key) => acc?.[key], obj);
83283
+ return path64.reduce((acc, key) => acc?.[key], obj);
82910
83284
  }
82911
83285
  function promiseAllObject(promisesObj) {
82912
83286
  const keys = Object.keys(promisesObj);
@@ -83226,11 +83600,11 @@ function aborted(x2, startIndex = 0) {
83226
83600
  }
83227
83601
  return false;
83228
83602
  }
83229
- function prefixIssues(path63, issues) {
83603
+ function prefixIssues(path64, issues) {
83230
83604
  return issues.map((iss) => {
83231
83605
  var _a3;
83232
83606
  (_a3 = iss).path ?? (_a3.path = []);
83233
- iss.path.unshift(path63);
83607
+ iss.path.unshift(path64);
83234
83608
  return iss;
83235
83609
  });
83236
83610
  }
@@ -89704,7 +90078,7 @@ var Server = class extends Protocol {
89704
90078
  };
89705
90079
 
89706
90080
  // src/mcp/server.ts
89707
- var path59 = __toESM(require("path"));
90081
+ var path60 = __toESM(require("path"));
89708
90082
 
89709
90083
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
89710
90084
  var import_node_process3 = __toESM(require("node:process"), 1);
@@ -90345,7 +90719,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
90345
90719
  const input = ControlUpInputSchema.parse({ ...args, repo });
90346
90720
  const result = await startControlAndSync({
90347
90721
  detach: input.detach,
90348
- cwd: path59.resolve(input.repo)
90722
+ cwd: path60.resolve(input.repo)
90349
90723
  });
90350
90724
  if (result.code !== 0) {
90351
90725
  return {
@@ -90409,11 +90783,11 @@ var mcpCommand = {
90409
90783
  };
90410
90784
 
90411
90785
  // src/cli/commands/onboard.ts
90412
- var path61 = __toESM(require("path"));
90786
+ var path62 = __toESM(require("path"));
90413
90787
  init_stages();
90414
90788
 
90415
90789
  // src/core/onboarding.ts
90416
- var path60 = __toESM(require("path"));
90790
+ var path61 = __toESM(require("path"));
90417
90791
  init_control_config();
90418
90792
  init_control_sync();
90419
90793
  init_otel_hooks();
@@ -90548,7 +90922,7 @@ async function defaultEnsureControl(options) {
90548
90922
  return { started: true, apiUrl: result.apiUrl };
90549
90923
  }
90550
90924
  async function runOnboarding(options, deps = {}) {
90551
- const repoPath = path60.resolve(options.repoPath);
90925
+ const repoPath = path61.resolve(options.repoPath);
90552
90926
  const applyTelemetry = deps.applyTelemetry ?? applyOnboardingTelemetry;
90553
90927
  const ensureControl = deps.ensureControl ?? defaultEnsureControl;
90554
90928
  const init = deps.initHarness ?? initHarness;
@@ -90737,7 +91111,7 @@ async function promptChoices(args) {
90737
91111
  };
90738
91112
  }
90739
91113
  const pluginChoices = listPluginChoices();
90740
- const repoPath = path61.resolve(args.repo);
91114
+ const repoPath = path62.resolve(args.repo);
90741
91115
  const alreadyPresent = harnessExists(repoPath);
90742
91116
  const needProfile = !alreadyPresent && !args.skipInit && args.profile === void 0;
90743
91117
  const needAgentSlots = shouldConfigureSlots && flaggedSlots === void 0;
@@ -90854,7 +91228,7 @@ function printSummary(result) {
90854
91228
  console.error("");
90855
91229
  }
90856
91230
  async function handleOnboard(argv) {
90857
- const repoPath = path61.resolve(argv.repo);
91231
+ const repoPath = path62.resolve(argv.repo);
90858
91232
  header("har onboard");
90859
91233
  info(`Repository: ${repoPath}`);
90860
91234
  try {
@@ -90884,18 +91258,13 @@ async function handleOnboard(argv) {
90884
91258
  ...onboarding.commitGate,
90885
91259
  autoYes: argv.yes
90886
91260
  });
90887
- await handleCursorRule({
91261
+ await applyAgentIntegrations({
90888
91262
  repoPath,
90889
- cursorRule: onboarding.cursorRule,
90890
- autoYes: argv.yes,
90891
- mode: result.harnessInitialized ? "init" : "maintain"
90892
- });
90893
- await handleAgentSkills({
90894
- repoPath,
90895
- ...onboarding.agentSkills,
91263
+ mode: result.harnessInitialized ? "init" : "maintain",
90896
91264
  autoYes: argv.yes,
90897
91265
  force: argv.force,
90898
- mode: result.harnessInitialized ? "init" : "maintain"
91266
+ cursorRule: onboarding.cursorRule,
91267
+ ...onboarding.agentSkills
90899
91268
  });
90900
91269
  }
90901
91270
  if (harnessExists(repoPath)) {
@@ -91090,7 +91459,7 @@ var preferencesCommand = {
91090
91459
  };
91091
91460
 
91092
91461
  // src/cli/commands/telemetry.ts
91093
- var path62 = __toESM(require("path"));
91462
+ var path63 = __toESM(require("path"));
91094
91463
  init_control_config();
91095
91464
  init_control_sync();
91096
91465
  init_manifest();
@@ -91183,7 +91552,7 @@ async function handleOff() {
91183
91552
  info("Mission Control will not auto-start. Existing usage rows are kept.");
91184
91553
  }
91185
91554
  async function handleWriteEnv(argv) {
91186
- const repoPath = path62.resolve(argv.repo);
91555
+ const repoPath = path63.resolve(argv.repo);
91187
91556
  const harnessRoot = resolveHarnessRoot(repoPath);
91188
91557
  const session = readSlotRegistry(harnessRoot, argv.agentId);
91189
91558
  const workDir = argv.workDir ?? session?.workDir ?? repoPath;
@@ -91195,7 +91564,7 @@ async function handleWriteEnv(argv) {
91195
91564
  suffix,
91196
91565
  createdAt: session?.createdAt
91197
91566
  });
91198
- const envFile = argv.envFile ?? path62.join(workDir, `.env.agent.${argv.agentId}`);
91567
+ const envFile = argv.envFile ?? path63.join(workDir, `.env.agent.${argv.agentId}`);
91199
91568
  const attrs = {
91200
91569
  sessionKey,
91201
91570
  agentId: argv.agentId,
@@ -91211,7 +91580,7 @@ async function handleWriteEnv(argv) {
91211
91580
  success(`Wrote session attribution to ${envFile}`);
91212
91581
  }
91213
91582
  function handlePrintEnv(argv) {
91214
- const repoPath = path62.resolve(argv.repo);
91583
+ const repoPath = path63.resolve(argv.repo);
91215
91584
  const workDir = argv.workDir ?? repoPath;
91216
91585
  const sessionKey = buildSessionKey({
91217
91586
  branch: argv.branch,