@osfactory/har 0.37.0 → 0.38.1

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
@@ -873,14 +873,14 @@ var require_url_state_machine = __commonJS({
873
873
  return url.replace(/\u0009|\u000A|\u000D/g, "");
874
874
  }
875
875
  function shortenPath(url) {
876
- const path61 = url.path;
877
- if (path61.length === 0) {
876
+ const path62 = url.path;
877
+ if (path62.length === 0) {
878
878
  return;
879
879
  }
880
- if (url.scheme === "file" && path61.length === 1 && isNormalizedWindowsDriveLetter(path61[0])) {
880
+ if (url.scheme === "file" && path62.length === 1 && isNormalizedWindowsDriveLetter(path62[0])) {
881
881
  return;
882
882
  }
883
- path61.pop();
883
+ path62.pop();
884
884
  }
885
885
  function includesCredentials(url) {
886
886
  return url.username !== "" || url.password !== "";
@@ -2200,7 +2200,7 @@ var require_lib2 = __commonJS({
2200
2200
  let accum = [];
2201
2201
  let accumBytes = 0;
2202
2202
  let abort = false;
2203
- return new Body.Promise(function(resolve45, reject) {
2203
+ return new Body.Promise(function(resolve46, reject) {
2204
2204
  let resTimeout;
2205
2205
  if (_this4.timeout) {
2206
2206
  resTimeout = setTimeout(function() {
@@ -2234,7 +2234,7 @@ var require_lib2 = __commonJS({
2234
2234
  }
2235
2235
  clearTimeout(resTimeout);
2236
2236
  try {
2237
- resolve45(Buffer.concat(accum, accumBytes));
2237
+ resolve46(Buffer.concat(accum, accumBytes));
2238
2238
  } catch (err) {
2239
2239
  reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
2240
2240
  }
@@ -2909,7 +2909,7 @@ var require_lib2 = __commonJS({
2909
2909
  throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
2910
2910
  }
2911
2911
  Body.Promise = fetch3.Promise;
2912
- return new fetch3.Promise(function(resolve45, reject) {
2912
+ return new fetch3.Promise(function(resolve46, reject) {
2913
2913
  const request = new Request3(url, opts);
2914
2914
  const options = getNodeRequestOptions(request);
2915
2915
  const send = (options.protocol === "https:" ? https : http2).request;
@@ -3042,7 +3042,7 @@ var require_lib2 = __commonJS({
3042
3042
  requestOpts.body = void 0;
3043
3043
  requestOpts.headers.delete("content-length");
3044
3044
  }
3045
- resolve45(fetch3(new Request3(locationURL, requestOpts)));
3045
+ resolve46(fetch3(new Request3(locationURL, requestOpts)));
3046
3046
  finalize();
3047
3047
  return;
3048
3048
  }
@@ -3063,7 +3063,7 @@ var require_lib2 = __commonJS({
3063
3063
  const codings = headers.get("Content-Encoding");
3064
3064
  if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
3065
3065
  response = new Response3(body, response_options);
3066
- resolve45(response);
3066
+ resolve46(response);
3067
3067
  return;
3068
3068
  }
3069
3069
  const zlibOptions = {
@@ -3073,7 +3073,7 @@ var require_lib2 = __commonJS({
3073
3073
  if (codings == "gzip" || codings == "x-gzip") {
3074
3074
  body = body.pipe(zlib.createGunzip(zlibOptions));
3075
3075
  response = new Response3(body, response_options);
3076
- resolve45(response);
3076
+ resolve46(response);
3077
3077
  return;
3078
3078
  }
3079
3079
  if (codings == "deflate" || codings == "x-deflate") {
@@ -3085,12 +3085,12 @@ var require_lib2 = __commonJS({
3085
3085
  body = body.pipe(zlib.createInflateRaw());
3086
3086
  }
3087
3087
  response = new Response3(body, response_options);
3088
- resolve45(response);
3088
+ resolve46(response);
3089
3089
  });
3090
3090
  raw.on("end", function() {
3091
3091
  if (!response) {
3092
3092
  response = new Response3(body, response_options);
3093
- resolve45(response);
3093
+ resolve46(response);
3094
3094
  }
3095
3095
  });
3096
3096
  return;
@@ -3098,11 +3098,11 @@ var require_lib2 = __commonJS({
3098
3098
  if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
3099
3099
  body = body.pipe(zlib.createBrotliDecompress());
3100
3100
  response = new Response3(body, response_options);
3101
- resolve45(response);
3101
+ resolve46(response);
3102
3102
  return;
3103
3103
  }
3104
3104
  response = new Response3(body, response_options);
3105
- resolve45(response);
3105
+ resolve46(response);
3106
3106
  });
3107
3107
  writeToStream(req, request);
3108
3108
  });
@@ -6459,14 +6459,14 @@ __export(fileFromPath_exports, {
6459
6459
  fileFromPathSync: () => fileFromPathSync,
6460
6460
  isFile: () => isFile
6461
6461
  });
6462
- function createFileFromPath(path61, { mtimeMs, size }, filenameOrOptions, options = {}) {
6462
+ function createFileFromPath(path62, { mtimeMs, size }, filenameOrOptions, options = {}) {
6463
6463
  let filename;
6464
6464
  if (isPlainObject_default2(filenameOrOptions)) {
6465
6465
  [options, filename] = [filenameOrOptions, void 0];
6466
6466
  } else {
6467
6467
  filename = filenameOrOptions;
6468
6468
  }
6469
- const file = new FileFromPath({ path: path61, size, lastModified: mtimeMs });
6469
+ const file = new FileFromPath({ path: path62, size, lastModified: mtimeMs });
6470
6470
  if (!filename) {
6471
6471
  filename = file.name;
6472
6472
  }
@@ -6475,13 +6475,13 @@ function createFileFromPath(path61, { mtimeMs, size }, filenameOrOptions, option
6475
6475
  lastModified: file.lastModified
6476
6476
  });
6477
6477
  }
6478
- function fileFromPathSync(path61, filenameOrOptions, options = {}) {
6479
- const stats = (0, import_fs5.statSync)(path61);
6480
- return createFileFromPath(path61, stats, filenameOrOptions, options);
6478
+ function fileFromPathSync(path62, filenameOrOptions, options = {}) {
6479
+ const stats = (0, import_fs5.statSync)(path62);
6480
+ return createFileFromPath(path62, stats, filenameOrOptions, options);
6481
6481
  }
6482
- async function fileFromPath2(path61, filenameOrOptions, options) {
6483
- const stats = await import_fs5.promises.stat(path61);
6484
- return createFileFromPath(path61, stats, filenameOrOptions, options);
6482
+ async function fileFromPath2(path62, filenameOrOptions, options) {
6483
+ const stats = await import_fs5.promises.stat(path62);
6484
+ return createFileFromPath(path62, stats, filenameOrOptions, options);
6485
6485
  }
6486
6486
  var import_fs5, import_path5, import_node_domexception, __classPrivateFieldSet5, __classPrivateFieldGet6, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
6487
6487
  var init_fileFromPath = __esm({
@@ -6640,25 +6640,25 @@ __export(otel_hooks_exports, {
6640
6640
  });
6641
6641
  function getOtelHooksHome() {
6642
6642
  if (process.env.HAR_OTEL_HOOKS_HOME) {
6643
- return path46.resolve(process.env.HAR_OTEL_HOOKS_HOME);
6643
+ return path47.resolve(process.env.HAR_OTEL_HOOKS_HOME);
6644
6644
  }
6645
- return path46.join(os14.homedir(), ".har", "otel-hooks");
6645
+ return path47.join(os14.homedir(), ".har", "otel-hooks");
6646
6646
  }
6647
6647
  function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
6648
- return path46.join(hooksHome, "otel_config.json");
6648
+ return path47.join(hooksHome, "otel_config.json");
6649
6649
  }
6650
6650
  function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
6651
- return path46.join(hooksHome, "run-otel-hook.sh");
6651
+ return path47.join(hooksHome, "run-otel-hook.sh");
6652
6652
  }
6653
6653
  function getOtelHooksStateDir(hooksHome = getOtelHooksHome()) {
6654
- return path46.join(hooksHome, "state");
6654
+ return path47.join(hooksHome, "state");
6655
6655
  }
6656
6656
  function localOtelHookBin(hooksHome) {
6657
- return path46.join(hooksHome, "node_modules", ".bin", "otel-hook");
6657
+ return path47.join(hooksHome, "node_modules", ".bin", "otel-hook");
6658
6658
  }
6659
6659
  function installedPackageVersion(hooksHome) {
6660
6660
  try {
6661
- const pkgPath = path46.join(
6661
+ const pkgPath = path47.join(
6662
6662
  hooksHome,
6663
6663
  "node_modules",
6664
6664
  "@osfactory",
@@ -6793,9 +6793,9 @@ function uninstallLegacyPythonHooks(hooksHome) {
6793
6793
  }
6794
6794
  function removeLegacyPythonArtifacts(hooksHome) {
6795
6795
  const legacyPaths = [
6796
- path46.join(hooksHome, ".venv"),
6797
- path46.join(hooksHome, "otel_config.yaml"),
6798
- path46.join(hooksHome, "venv")
6796
+ path47.join(hooksHome, ".venv"),
6797
+ path47.join(hooksHome, "otel_config.yaml"),
6798
+ path47.join(hooksHome, "venv")
6799
6799
  ];
6800
6800
  for (const target of legacyPaths) {
6801
6801
  try {
@@ -6941,14 +6941,14 @@ function pruneLegacyCursorHookEvents(filePath, wrapperPath) {
6941
6941
  function rewriteKnownHookRegistrations(wrapperPath) {
6942
6942
  const home = os14.homedir();
6943
6943
  const candidates = [
6944
- path46.join(home, ".cursor", "hooks.json"),
6945
- path46.join(home, ".claude", "settings.json"),
6946
- path46.join(home, ".codex", "hooks.json")
6944
+ path47.join(home, ".cursor", "hooks.json"),
6945
+ path47.join(home, ".claude", "settings.json"),
6946
+ path47.join(home, ".codex", "hooks.json")
6947
6947
  ];
6948
6948
  for (const filePath of candidates) {
6949
6949
  try {
6950
6950
  rewriteHookCommandsToWrapper(filePath, wrapperPath);
6951
- if (filePath.endsWith(`${path46.sep}.cursor${path46.sep}hooks.json`)) {
6951
+ if (filePath.endsWith(`${path47.sep}.cursor${path47.sep}hooks.json`)) {
6952
6952
  pruneLegacyCursorHookEvents(filePath, wrapperPath);
6953
6953
  }
6954
6954
  } catch {
@@ -7058,14 +7058,14 @@ function ensureOtelHooks(options) {
7058
7058
  function disableOtelHooksExport() {
7059
7059
  return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
7060
7060
  }
7061
- var import_child_process10, fs43, os14, path46, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
7061
+ var import_child_process10, fs43, os14, path47, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_PROVIDERS, OTEL_HOOKS_AGENTS, LEGACY_CURSOR_ONLY_HOOK_EVENTS;
7062
7062
  var init_otel_hooks = __esm({
7063
7063
  "src/core/otel-hooks.ts"() {
7064
7064
  "use strict";
7065
7065
  import_child_process10 = require("child_process");
7066
7066
  fs43 = __toESM(require("fs"));
7067
7067
  os14 = __toESM(require("os"));
7068
- path46 = __toESM(require("path"));
7068
+ path47 = __toESM(require("path"));
7069
7069
  init_control_config();
7070
7070
  init_telemetry_config();
7071
7071
  OTEL_HOOKS_PACKAGE = "@osfactory/otel-hook@0.1.2";
@@ -8181,15 +8181,15 @@ var require_route = __commonJS({
8181
8181
  };
8182
8182
  }
8183
8183
  function wrapConversion(toModel, graph) {
8184
- const path61 = [graph[toModel].parent, toModel];
8184
+ const path62 = [graph[toModel].parent, toModel];
8185
8185
  let fn = conversions[graph[toModel].parent][toModel];
8186
8186
  let cur = graph[toModel].parent;
8187
8187
  while (graph[cur].parent) {
8188
- path61.unshift(graph[cur].parent);
8188
+ path62.unshift(graph[cur].parent);
8189
8189
  fn = link(conversions[graph[cur].parent][cur], fn);
8190
8190
  cur = graph[cur].parent;
8191
8191
  }
8192
- fn.conversion = path61;
8192
+ fn.conversion = path62;
8193
8193
  return fn;
8194
8194
  }
8195
8195
  module2.exports = function(fromModel) {
@@ -17679,16 +17679,16 @@ var require_os_tmpdir = __commonJS({
17679
17679
  var isWindows = process.platform === "win32";
17680
17680
  var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
17681
17681
  module2.exports = function() {
17682
- var path61;
17682
+ var path62;
17683
17683
  if (isWindows) {
17684
- path61 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
17684
+ path62 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
17685
17685
  } else {
17686
- path61 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
17686
+ path62 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
17687
17687
  }
17688
- if (trailingSlashRe.test(path61)) {
17689
- path61 = path61.slice(0, -1);
17688
+ if (trailingSlashRe.test(path62)) {
17689
+ path62 = path62.slice(0, -1);
17690
17690
  }
17691
- return path61;
17691
+ return path62;
17692
17692
  };
17693
17693
  }
17694
17694
  });
@@ -17697,7 +17697,7 @@ var require_os_tmpdir = __commonJS({
17697
17697
  var require_tmp = __commonJS({
17698
17698
  "node_modules/tmp/lib/tmp.js"(exports2, module2) {
17699
17699
  var fs50 = require("fs");
17700
- var path61 = require("path");
17700
+ var path62 = require("path");
17701
17701
  var crypto6 = require("crypto");
17702
17702
  var osTmpDir = require_os_tmpdir();
17703
17703
  var _c2 = process.binding("constants");
@@ -17739,7 +17739,7 @@ var require_tmp = __commonJS({
17739
17739
  }
17740
17740
  function _generateTmpName(opts) {
17741
17741
  if (opts.name) {
17742
- return path61.join(opts.dir || tmpDir, opts.name);
17742
+ return path62.join(opts.dir || tmpDir, opts.name);
17743
17743
  }
17744
17744
  if (opts.template) {
17745
17745
  return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
@@ -17750,7 +17750,7 @@ var require_tmp = __commonJS({
17750
17750
  _randomChars(12),
17751
17751
  opts.postfix || ""
17752
17752
  ].join("");
17753
- return path61.join(opts.dir || tmpDir, name);
17753
+ return path62.join(opts.dir || tmpDir, name);
17754
17754
  }
17755
17755
  function tmpName(options, callback) {
17756
17756
  var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
@@ -17835,7 +17835,7 @@ var require_tmp = __commonJS({
17835
17835
  do {
17836
17836
  var dir2 = dirs.pop(), deferred = false, files = fs50.readdirSync(dir2);
17837
17837
  for (var i2 = 0, length = files.length; i2 < length; i2++) {
17838
- var file2 = path61.join(dir2, files[i2]), stat = fs50.lstatSync(file2);
17838
+ var file2 = path62.join(dir2, files[i2]), stat = fs50.lstatSync(file2);
17839
17839
  if (stat.isDirectory()) {
17840
17840
  if (!deferred) {
17841
17841
  deferred = true;
@@ -19046,7 +19046,7 @@ var require_Observable = __commonJS({
19046
19046
  Observable2.prototype.forEach = function(next, promiseCtor) {
19047
19047
  var _this = this;
19048
19048
  promiseCtor = getPromiseCtor(promiseCtor);
19049
- return new promiseCtor(function(resolve45, reject) {
19049
+ return new promiseCtor(function(resolve46, reject) {
19050
19050
  var subscriber = new Subscriber_1.SafeSubscriber({
19051
19051
  next: function(value) {
19052
19052
  try {
@@ -19057,7 +19057,7 @@ var require_Observable = __commonJS({
19057
19057
  }
19058
19058
  },
19059
19059
  error: reject,
19060
- complete: resolve45
19060
+ complete: resolve46
19061
19061
  });
19062
19062
  _this.subscribe(subscriber);
19063
19063
  });
@@ -19079,14 +19079,14 @@ var require_Observable = __commonJS({
19079
19079
  Observable2.prototype.toPromise = function(promiseCtor) {
19080
19080
  var _this = this;
19081
19081
  promiseCtor = getPromiseCtor(promiseCtor);
19082
- return new promiseCtor(function(resolve45, reject) {
19082
+ return new promiseCtor(function(resolve46, reject) {
19083
19083
  var value;
19084
19084
  _this.subscribe(function(x2) {
19085
19085
  return value = x2;
19086
19086
  }, function(err) {
19087
19087
  return reject(err);
19088
19088
  }, function() {
19089
- return resolve45(value);
19089
+ return resolve46(value);
19090
19090
  });
19091
19091
  });
19092
19092
  };
@@ -21182,11 +21182,11 @@ var require_innerFrom = __commonJS({
21182
21182
  "use strict";
21183
21183
  var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P3, generator) {
21184
21184
  function adopt(value) {
21185
- return value instanceof P3 ? value : new P3(function(resolve45) {
21186
- resolve45(value);
21185
+ return value instanceof P3 ? value : new P3(function(resolve46) {
21186
+ resolve46(value);
21187
21187
  });
21188
21188
  }
21189
- return new (P3 || (P3 = Promise))(function(resolve45, reject) {
21189
+ return new (P3 || (P3 = Promise))(function(resolve46, reject) {
21190
21190
  function fulfilled(value) {
21191
21191
  try {
21192
21192
  step(generator.next(value));
@@ -21202,7 +21202,7 @@ var require_innerFrom = __commonJS({
21202
21202
  }
21203
21203
  }
21204
21204
  function step(result) {
21205
- result.done ? resolve45(result.value) : adopt(result.value).then(fulfilled, rejected);
21205
+ result.done ? resolve46(result.value) : adopt(result.value).then(fulfilled, rejected);
21206
21206
  }
21207
21207
  step((generator = generator.apply(thisArg, _arguments || [])).next());
21208
21208
  });
@@ -21284,14 +21284,14 @@ var require_innerFrom = __commonJS({
21284
21284
  }, i2);
21285
21285
  function verb(n2) {
21286
21286
  i2[n2] = o2[n2] && function(v3) {
21287
- return new Promise(function(resolve45, reject) {
21288
- v3 = o2[n2](v3), settle(resolve45, reject, v3.done, v3.value);
21287
+ return new Promise(function(resolve46, reject) {
21288
+ v3 = o2[n2](v3), settle(resolve46, reject, v3.done, v3.value);
21289
21289
  });
21290
21290
  };
21291
21291
  }
21292
- function settle(resolve45, reject, d2, v3) {
21292
+ function settle(resolve46, reject, d2, v3) {
21293
21293
  Promise.resolve(v3).then(function(v4) {
21294
- resolve45({ value: v4, done: d2 });
21294
+ resolve46({ value: v4, done: d2 });
21295
21295
  }, reject);
21296
21296
  }
21297
21297
  };
@@ -21910,7 +21910,7 @@ var require_lastValueFrom = __commonJS({
21910
21910
  var EmptyError_1 = require_EmptyError();
21911
21911
  function lastValueFrom2(source, config2) {
21912
21912
  var hasConfig = typeof config2 === "object";
21913
- return new Promise(function(resolve45, reject) {
21913
+ return new Promise(function(resolve46, reject) {
21914
21914
  var _hasValue = false;
21915
21915
  var _value;
21916
21916
  source.subscribe({
@@ -21921,9 +21921,9 @@ var require_lastValueFrom = __commonJS({
21921
21921
  error: reject,
21922
21922
  complete: function() {
21923
21923
  if (_hasValue) {
21924
- resolve45(_value);
21924
+ resolve46(_value);
21925
21925
  } else if (hasConfig) {
21926
- resolve45(config2.defaultValue);
21926
+ resolve46(config2.defaultValue);
21927
21927
  } else {
21928
21928
  reject(new EmptyError_1.EmptyError());
21929
21929
  }
@@ -21945,16 +21945,16 @@ var require_firstValueFrom = __commonJS({
21945
21945
  var Subscriber_1 = require_Subscriber();
21946
21946
  function firstValueFrom(source, config2) {
21947
21947
  var hasConfig = typeof config2 === "object";
21948
- return new Promise(function(resolve45, reject) {
21948
+ return new Promise(function(resolve46, reject) {
21949
21949
  var subscriber = new Subscriber_1.SafeSubscriber({
21950
21950
  next: function(value) {
21951
- resolve45(value);
21951
+ resolve46(value);
21952
21952
  subscriber.unsubscribe();
21953
21953
  },
21954
21954
  error: reject,
21955
21955
  complete: function() {
21956
21956
  if (hasConfig) {
21957
- resolve45(config2.defaultValue);
21957
+ resolve46(config2.defaultValue);
21958
21958
  } else {
21959
21959
  reject(new EmptyError_1.EmptyError());
21960
21960
  }
@@ -27747,14 +27747,14 @@ var require_run_async = __commonJS({
27747
27747
  return function() {
27748
27748
  var args = arguments;
27749
27749
  var originalThis = this;
27750
- var promise = new Promise(function(resolve45, reject) {
27750
+ var promise = new Promise(function(resolve46, reject) {
27751
27751
  var resolved = false;
27752
27752
  const wrappedResolve = function(value) {
27753
27753
  if (resolved) {
27754
27754
  console.warn("Run-async promise already resolved.");
27755
27755
  }
27756
27756
  resolved = true;
27757
- resolve45(value);
27757
+ resolve46(value);
27758
27758
  };
27759
27759
  var rejected = false;
27760
27760
  const wrappedReject = function(value) {
@@ -30783,7 +30783,7 @@ var require_compile = __commonJS({
30783
30783
  const schOrFunc = root.refs[ref];
30784
30784
  if (schOrFunc)
30785
30785
  return schOrFunc;
30786
- let _sch = resolve45.call(this, root, ref);
30786
+ let _sch = resolve46.call(this, root, ref);
30787
30787
  if (_sch === void 0) {
30788
30788
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
30789
30789
  const { schemaId } = this.opts;
@@ -30810,7 +30810,7 @@ var require_compile = __commonJS({
30810
30810
  function sameSchemaEnv(s1, s2) {
30811
30811
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
30812
30812
  }
30813
- function resolve45(root, ref) {
30813
+ function resolve46(root, ref) {
30814
30814
  let sch;
30815
30815
  while (typeof (sch = this.refs[ref]) == "string")
30816
30816
  ref = sch;
@@ -31028,8 +31028,8 @@ var require_utils2 = __commonJS({
31028
31028
  }
31029
31029
  return ind;
31030
31030
  }
31031
- function removeDotSegments(path61) {
31032
- let input = path61;
31031
+ function removeDotSegments(path62) {
31032
+ let input = path62;
31033
31033
  const output = [];
31034
31034
  let nextSlash = -1;
31035
31035
  let len = 0;
@@ -31281,8 +31281,8 @@ var require_schemes = __commonJS({
31281
31281
  wsComponent.secure = void 0;
31282
31282
  }
31283
31283
  if (wsComponent.resourceName) {
31284
- const [path61, query] = wsComponent.resourceName.split("?");
31285
- wsComponent.path = path61 && path61 !== "/" ? path61 : void 0;
31284
+ const [path62, query] = wsComponent.resourceName.split("?");
31285
+ wsComponent.path = path62 && path62 !== "/" ? path62 : void 0;
31286
31286
  wsComponent.query = query;
31287
31287
  wsComponent.resourceName = void 0;
31288
31288
  }
@@ -31441,7 +31441,7 @@ var require_fast_uri = __commonJS({
31441
31441
  }
31442
31442
  return uri;
31443
31443
  }
31444
- function resolve45(baseURI, relativeURI, options) {
31444
+ function resolve46(baseURI, relativeURI, options) {
31445
31445
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
31446
31446
  const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
31447
31447
  schemelessOptions.skipEscape = true;
@@ -31699,7 +31699,7 @@ var require_fast_uri = __commonJS({
31699
31699
  var fastUri = {
31700
31700
  SCHEMES,
31701
31701
  normalize: normalize3,
31702
- resolve: resolve45,
31702
+ resolve: resolve46,
31703
31703
  resolveComponent,
31704
31704
  equal,
31705
31705
  serialize,
@@ -35964,11 +35964,11 @@ var parser = new YargsParser({
35964
35964
  resolve: import_path2.resolve,
35965
35965
  // TODO: figure out a way to combine ESM and CJS coverage, such that
35966
35966
  // we can exercise all the lines below:
35967
- require: (path61) => {
35967
+ require: (path62) => {
35968
35968
  if (typeof require !== "undefined") {
35969
- return require(path61);
35970
- } else if (path61.match(/\.json$/)) {
35971
- return JSON.parse((0, import_fs2.readFileSync)(path61, "utf8"));
35969
+ return require(path62);
35970
+ } else if (path62.match(/\.json$/)) {
35971
+ return JSON.parse((0, import_fs2.readFileSync)(path62, "utf8"));
35972
35972
  } else {
35973
35973
  throw Error("only .json config files are supported in ESM");
35974
35974
  }
@@ -37311,13 +37311,13 @@ function usage(yargs, shim3) {
37311
37311
  };
37312
37312
  self.stringifiedValues = function stringifiedValues(values, separator) {
37313
37313
  let string3 = "";
37314
- const sep7 = separator || ", ";
37314
+ const sep6 = separator || ", ";
37315
37315
  const array2 = [].concat(values);
37316
37316
  if (!values || !array2.length)
37317
37317
  return string3;
37318
37318
  array2.forEach((value) => {
37319
37319
  if (string3.length)
37320
- string3 += sep7;
37320
+ string3 += sep6;
37321
37321
  string3 += JSON.stringify(value);
37322
37322
  });
37323
37323
  return string3;
@@ -38494,12 +38494,12 @@ var YargsInstance = class {
38494
38494
  async getCompletion(args, done) {
38495
38495
  argsert("<array> [function]", [args, done], arguments.length);
38496
38496
  if (!done) {
38497
- return new Promise((resolve45, reject) => {
38497
+ return new Promise((resolve46, reject) => {
38498
38498
  __classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
38499
38499
  if (err)
38500
38500
  reject(err);
38501
38501
  else
38502
- resolve45(completions);
38502
+ resolve46(completions);
38503
38503
  });
38504
38504
  });
38505
38505
  } else {
@@ -40652,8 +40652,8 @@ function getErrorMap() {
40652
40652
 
40653
40653
  // node_modules/zod/v3/helpers/parseUtil.js
40654
40654
  var makeIssue = (params) => {
40655
- const { data, path: path61, errorMaps, issueData } = params;
40656
- const fullPath = [...path61, ...issueData.path || []];
40655
+ const { data, path: path62, errorMaps, issueData } = params;
40656
+ const fullPath = [...path62, ...issueData.path || []];
40657
40657
  const fullIssue = {
40658
40658
  ...issueData,
40659
40659
  path: fullPath
@@ -40769,11 +40769,11 @@ var errorUtil;
40769
40769
 
40770
40770
  // node_modules/zod/v3/types.js
40771
40771
  var ParseInputLazyPath = class {
40772
- constructor(parent, value, path61, key) {
40772
+ constructor(parent, value, path62, key) {
40773
40773
  this._cachedPath = [];
40774
40774
  this.parent = parent;
40775
40775
  this.data = value;
40776
- this._path = path61;
40776
+ this._path = path62;
40777
40777
  this._key = key;
40778
40778
  }
40779
40779
  get path() {
@@ -44506,7 +44506,7 @@ var AgentSlotStatusSchema = external_exports.object({
44506
44506
  attemptId: WorkAttemptIdSchema.optional(),
44507
44507
  sessionStatus: external_exports.enum(["starting", "active", "failed", "completed"]).optional(),
44508
44508
  lastError: external_exports.string().optional(),
44509
- /** Set when a failed/starting session can be resumed without --replace. */
44509
+ /** Set when a failed/starting session can be resumed with --resume instead of a fresh launch. */
44510
44510
  resumeHint: external_exports.string().optional(),
44511
44511
  /** Worktree checked out to no branch (legacy failure mode; should not happen with sessions). */
44512
44512
  detachedHead: external_exports.boolean().optional(),
@@ -68312,16 +68312,16 @@ async function handleAgentSkills(options) {
68312
68312
  }
68313
68313
  async function askYesNo(question) {
68314
68314
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
68315
- return new Promise((resolve45) => {
68315
+ return new Promise((resolve46) => {
68316
68316
  process.stderr.write(`${question} `);
68317
68317
  rl.once("line", (answer) => {
68318
68318
  rl.close();
68319
68319
  const trimmed = answer.trim();
68320
68320
  if (trimmed === "") {
68321
- resolve45(true);
68321
+ resolve46(true);
68322
68322
  return;
68323
68323
  }
68324
- resolve45(/^y(es)?$/i.test(trimmed));
68324
+ resolve46(/^y(es)?$/i.test(trimmed));
68325
68325
  });
68326
68326
  });
68327
68327
  }
@@ -68400,7 +68400,7 @@ function handleRemove(argv) {
68400
68400
  }
68401
68401
 
68402
68402
  // src/cli/commands/env.ts
68403
- var path50 = __toESM(require("path"));
68403
+ var path51 = __toESM(require("path"));
68404
68404
 
68405
68405
  // src/core/harness.ts
68406
68406
  var fs22 = __toESM(require("fs"));
@@ -68486,6 +68486,7 @@ function parseHarnessEnvInt(env3, key) {
68486
68486
 
68487
68487
  // src/harness/stages.ts
68488
68488
  var STAGE_REGISTRY_FILE = "stages.json";
68489
+ var HAR_AGENT_SLOT_ONBOARD_MAX = 10;
68489
68490
  var AGENT_REQUIRED_KINDS = /* @__PURE__ */ new Set([
68490
68491
  "launch",
68491
68492
  "verify",
@@ -68672,6 +68673,15 @@ ${maxLine}
68672
68673
  fs10.writeFileSync(envPath, content);
68673
68674
  return true;
68674
68675
  }
68676
+ function applyAgentSlotMax(repoPath, max) {
68677
+ const slots = HarnessAgentSlotsSchema.parse({ min: HAR_AGENT_SLOT_MIN, max });
68678
+ const registry2 = readStageRegistry(repoPath);
68679
+ writeStageRegistry(repoPath, {
68680
+ ...registry2,
68681
+ agentSlots: slots
68682
+ });
68683
+ syncAgentSlotsToHarnessEnv(repoPath);
68684
+ }
68675
68685
  function stageRequiresAgentId(stage) {
68676
68686
  if (typeof stage.requiresAgentId === "boolean") return stage.requiresAgentId;
68677
68687
  return AGENT_REQUIRED_KINDS.has(stage.kind);
@@ -69179,13 +69189,13 @@ var MultipartBody = class {
69179
69189
  // node_modules/@anthropic-ai/sdk/_shims/node-runtime.mjs
69180
69190
  var import_web = require("node:stream/web");
69181
69191
  var fileFromPathWarned = false;
69182
- async function fileFromPath3(path61, ...args) {
69192
+ async function fileFromPath3(path62, ...args) {
69183
69193
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
69184
69194
  if (!fileFromPathWarned) {
69185
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path61)}) instead`);
69195
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path62)}) instead`);
69186
69196
  fileFromPathWarned = true;
69187
69197
  }
69188
- return await _fileFromPath(path61, ...args);
69198
+ return await _fileFromPath(path62, ...args);
69189
69199
  }
69190
69200
  var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
69191
69201
  var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
@@ -69681,8 +69691,8 @@ async function defaultParseResponse(props) {
69681
69691
  }
69682
69692
  var APIPromise = class _APIPromise extends Promise {
69683
69693
  constructor(responsePromise, parseResponse = defaultParseResponse) {
69684
- super((resolve45) => {
69685
- resolve45(null);
69694
+ super((resolve46) => {
69695
+ resolve46(null);
69686
69696
  });
69687
69697
  this.responsePromise = responsePromise;
69688
69698
  this.parseResponse = parseResponse;
@@ -69782,29 +69792,29 @@ var APIClient = class {
69782
69792
  defaultIdempotencyKey() {
69783
69793
  return `stainless-node-retry-${uuid4()}`;
69784
69794
  }
69785
- get(path61, opts) {
69786
- return this.methodRequest("get", path61, opts);
69795
+ get(path62, opts) {
69796
+ return this.methodRequest("get", path62, opts);
69787
69797
  }
69788
- post(path61, opts) {
69789
- return this.methodRequest("post", path61, opts);
69798
+ post(path62, opts) {
69799
+ return this.methodRequest("post", path62, opts);
69790
69800
  }
69791
- patch(path61, opts) {
69792
- return this.methodRequest("patch", path61, opts);
69801
+ patch(path62, opts) {
69802
+ return this.methodRequest("patch", path62, opts);
69793
69803
  }
69794
- put(path61, opts) {
69795
- return this.methodRequest("put", path61, opts);
69804
+ put(path62, opts) {
69805
+ return this.methodRequest("put", path62, opts);
69796
69806
  }
69797
- delete(path61, opts) {
69798
- return this.methodRequest("delete", path61, opts);
69807
+ delete(path62, opts) {
69808
+ return this.methodRequest("delete", path62, opts);
69799
69809
  }
69800
- methodRequest(method, path61, opts) {
69810
+ methodRequest(method, path62, opts) {
69801
69811
  return this.request(Promise.resolve(opts).then(async (opts2) => {
69802
69812
  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;
69803
- return { method, path: path61, ...opts2, body };
69813
+ return { method, path: path62, ...opts2, body };
69804
69814
  }));
69805
69815
  }
69806
- getAPIList(path61, Page, opts) {
69807
- return this.requestAPIList(Page, { method: "get", path: path61, ...opts });
69816
+ getAPIList(path62, Page, opts) {
69817
+ return this.requestAPIList(Page, { method: "get", path: path62, ...opts });
69808
69818
  }
69809
69819
  calculateContentLength(body) {
69810
69820
  if (typeof body === "string") {
@@ -69822,10 +69832,10 @@ var APIClient = class {
69822
69832
  return null;
69823
69833
  }
69824
69834
  buildRequest(options) {
69825
- const { method, path: path61, query, headers = {} } = options;
69835
+ const { method, path: path62, query, headers = {} } = options;
69826
69836
  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;
69827
69837
  const contentLength = this.calculateContentLength(body);
69828
- const url = this.buildURL(path61, query);
69838
+ const url = this.buildURL(path62, query);
69829
69839
  if ("timeout" in options)
69830
69840
  validatePositiveInteger("timeout", options.timeout);
69831
69841
  const timeout = options.timeout ?? this.timeout;
@@ -69934,8 +69944,8 @@ var APIClient = class {
69934
69944
  const request = this.makeRequest(options, null);
69935
69945
  return new PagePromise(this, request, Page);
69936
69946
  }
69937
- buildURL(path61, query) {
69938
- const url = isAbsoluteURL(path61) ? new URL(path61) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path61.startsWith("/") ? path61.slice(1) : path61));
69947
+ buildURL(path62, query) {
69948
+ const url = isAbsoluteURL(path62) ? new URL(path62) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path62.startsWith("/") ? path62.slice(1) : path62));
69939
69949
  const defaultQuery = this.defaultQuery();
69940
69950
  if (!isEmptyObj(defaultQuery)) {
69941
69951
  query = { ...defaultQuery, ...query };
@@ -70220,7 +70230,7 @@ var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
70220
70230
  var isAbsoluteURL = (url) => {
70221
70231
  return startsWithSchemeRegexp.test(url);
70222
70232
  };
70223
- var sleep = (ms) => new Promise((resolve45) => setTimeout(resolve45, ms));
70233
+ var sleep = (ms) => new Promise((resolve46) => setTimeout(resolve46, ms));
70224
70234
  var validatePositiveInteger = (name, n2) => {
70225
70235
  if (typeof n2 !== "number" || !Number.isInteger(n2)) {
70226
70236
  throw new AnthropicError(`${name} must be an integer`);
@@ -70711,12 +70721,12 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
70711
70721
  }
70712
70722
  return this._emit("error", new AnthropicError(String(error3)));
70713
70723
  });
70714
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve45, reject) => {
70715
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve45, "f");
70724
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve46, reject) => {
70725
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve46, "f");
70716
70726
  __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectConnectedPromise, reject, "f");
70717
70727
  }), "f");
70718
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve45, reject) => {
70719
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve45, "f");
70728
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve46, reject) => {
70729
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve46, "f");
70720
70730
  __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectEndPromise, reject, "f");
70721
70731
  }), "f");
70722
70732
  __classPrivateFieldGet8(this, _PromptCachingBetaMessageStream_connectedPromise, "f").catch(() => {
@@ -70845,11 +70855,11 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
70845
70855
  * const message = await stream.emitted('message') // rejects if the stream errors
70846
70856
  */
70847
70857
  emitted(event) {
70848
- return new Promise((resolve45, reject) => {
70858
+ return new Promise((resolve46, reject) => {
70849
70859
  __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_catchingPromiseCreated, true, "f");
70850
70860
  if (event !== "error")
70851
70861
  this.once("error", reject);
70852
- this.once(event, resolve45);
70862
+ this.once(event, resolve46);
70853
70863
  });
70854
70864
  }
70855
70865
  async done() {
@@ -71076,7 +71086,7 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
71076
71086
  if (done) {
71077
71087
  return { value: void 0, done: true };
71078
71088
  }
71079
- return new Promise((resolve45, reject) => readQueue.push({ resolve: resolve45, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
71089
+ return new Promise((resolve46, reject) => readQueue.push({ resolve: resolve46, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
71080
71090
  }
71081
71091
  const chunk = pushQueue.shift();
71082
71092
  return { value: chunk, done: false };
@@ -71224,12 +71234,12 @@ var MessageStream = class _MessageStream {
71224
71234
  }
71225
71235
  return this._emit("error", new AnthropicError(String(error3)));
71226
71236
  });
71227
- __classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve45, reject) => {
71228
- __classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve45, "f");
71237
+ __classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve46, reject) => {
71238
+ __classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve46, "f");
71229
71239
  __classPrivateFieldSet8(this, _MessageStream_rejectConnectedPromise, reject, "f");
71230
71240
  }), "f");
71231
- __classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve45, reject) => {
71232
- __classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve45, "f");
71241
+ __classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve46, reject) => {
71242
+ __classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve46, "f");
71233
71243
  __classPrivateFieldSet8(this, _MessageStream_rejectEndPromise, reject, "f");
71234
71244
  }), "f");
71235
71245
  __classPrivateFieldGet9(this, _MessageStream_connectedPromise, "f").catch(() => {
@@ -71358,11 +71368,11 @@ var MessageStream = class _MessageStream {
71358
71368
  * const message = await stream.emitted('message') // rejects if the stream errors
71359
71369
  */
71360
71370
  emitted(event) {
71361
- return new Promise((resolve45, reject) => {
71371
+ return new Promise((resolve46, reject) => {
71362
71372
  __classPrivateFieldSet8(this, _MessageStream_catchingPromiseCreated, true, "f");
71363
71373
  if (event !== "error")
71364
71374
  this.once("error", reject);
71365
- this.once(event, resolve45);
71375
+ this.once(event, resolve46);
71366
71376
  });
71367
71377
  }
71368
71378
  async done() {
@@ -71589,7 +71599,7 @@ var MessageStream = class _MessageStream {
71589
71599
  if (done) {
71590
71600
  return { value: void 0, done: true };
71591
71601
  }
71592
- return new Promise((resolve45, reject) => readQueue.push({ resolve: resolve45, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
71602
+ return new Promise((resolve46, reject) => readQueue.push({ resolve: resolve46, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
71593
71603
  }
71594
71604
  const chunk = pushQueue.shift();
71595
71605
  return { value: chunk, done: false };
@@ -71849,11 +71859,11 @@ async function promptApplyAgentMdProposal(repoPath) {
71849
71859
  }
71850
71860
  async function askYesNo2(question) {
71851
71861
  const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
71852
- return new Promise((resolve45) => {
71862
+ return new Promise((resolve46) => {
71853
71863
  process.stderr.write(`${question} `);
71854
71864
  rl.once("line", (answer) => {
71855
71865
  rl.close();
71856
- resolve45(/^y(es)?$/i.test(answer.trim()));
71866
+ resolve46(/^y(es)?$/i.test(answer.trim()));
71857
71867
  });
71858
71868
  });
71859
71869
  }
@@ -72083,7 +72093,7 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
72083
72093
  }
72084
72094
  async function askUser(question, options) {
72085
72095
  const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
72086
- return new Promise((resolve45) => {
72096
+ return new Promise((resolve46) => {
72087
72097
  process.stderr.write("\n");
72088
72098
  process.stderr.write(`\u2753 ${question}
72089
72099
  `);
@@ -72094,7 +72104,7 @@ async function askUser(question, options) {
72094
72104
  process.stderr.write("> ");
72095
72105
  rl.once("line", (answer) => {
72096
72106
  rl.close();
72097
- resolve45(answer.trim());
72107
+ resolve46(answer.trim());
72098
72108
  });
72099
72109
  });
72100
72110
  }
@@ -72238,7 +72248,7 @@ function runScript(scriptPath, args = [], options = {}) {
72238
72248
  function runScriptCapture(scriptPath, args = [], options = {}) {
72239
72249
  const stream = options.stream ?? false;
72240
72250
  const { stream: _stream, ...spawnOptions } = options;
72241
- return new Promise((resolve45) => {
72251
+ return new Promise((resolve46) => {
72242
72252
  const proc = (0, import_child_process.spawn)("bash", [scriptPath, ...args], {
72243
72253
  ...spawnOptions,
72244
72254
  stdio: ["inherit", "pipe", "pipe"]
@@ -72253,13 +72263,13 @@ function runScriptCapture(scriptPath, args = [], options = {}) {
72253
72263
  stderr += d2;
72254
72264
  if (stream) process.stderr.write(d2);
72255
72265
  });
72256
- proc.on("close", (code) => resolve45({ stdout, stderr, code: code ?? 0 }));
72266
+ proc.on("close", (code) => resolve46({ stdout, stderr, code: code ?? 0 }));
72257
72267
  });
72258
72268
  }
72259
72269
  function runShellCommand(command2, options = {}) {
72260
72270
  const stream = options.stream ?? false;
72261
72271
  const { stream: _stream, ...spawnOptions } = options;
72262
- return new Promise((resolve45) => {
72272
+ return new Promise((resolve46) => {
72263
72273
  const proc = (0, import_child_process.spawn)("bash", ["-lc", command2], {
72264
72274
  ...spawnOptions,
72265
72275
  stdio: ["inherit", "pipe", "pipe"]
@@ -72274,7 +72284,7 @@ function runShellCommand(command2, options = {}) {
72274
72284
  stderr += d2;
72275
72285
  if (stream) process.stderr.write(d2);
72276
72286
  });
72277
- proc.on("close", (code) => resolve45({ stdout, stderr, code: code ?? 0 }));
72287
+ proc.on("close", (code) => resolve46({ stdout, stderr, code: code ?? 0 }));
72278
72288
  });
72279
72289
  }
72280
72290
 
@@ -73732,12 +73742,12 @@ function printAdaptationPrompt(content) {
73732
73742
  }
73733
73743
  function askYesNo3(question) {
73734
73744
  const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
73735
- return new Promise((resolve45) => {
73745
+ return new Promise((resolve46) => {
73736
73746
  process.stderr.write(`${question} `);
73737
73747
  rl.once("line", (answer) => {
73738
73748
  rl.close();
73739
73749
  const trimmed = answer.trim();
73740
- resolve45(trimmed === "" || /^y(es)?$/i.test(trimmed));
73750
+ resolve46(trimmed === "" || /^y(es)?$/i.test(trimmed));
73741
73751
  });
73742
73752
  });
73743
73753
  }
@@ -73824,16 +73834,16 @@ async function promptScaffoldCursorRule(exists) {
73824
73834
  }
73825
73835
  async function askYesNo4(question) {
73826
73836
  const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
73827
- return new Promise((resolve45) => {
73837
+ return new Promise((resolve46) => {
73828
73838
  process.stderr.write(`${question} `);
73829
73839
  rl.once("line", (answer) => {
73830
73840
  rl.close();
73831
73841
  const trimmed = answer.trim();
73832
73842
  if (trimmed === "") {
73833
- resolve45(true);
73843
+ resolve46(true);
73834
73844
  return;
73835
73845
  }
73836
- resolve45(/^y(es)?$/i.test(trimmed));
73846
+ resolve46(/^y(es)?$/i.test(trimmed));
73837
73847
  });
73838
73848
  });
73839
73849
  }
@@ -73963,8 +73973,6 @@ function buildLaunchFlagArgs(flags) {
73963
73973
  const args = [];
73964
73974
  if (flags.worktree === false) args.push("--no-worktree");
73965
73975
  if (flags.claude) args.push("--claude");
73966
- if (flags.confirmReplace) args.push("--replace");
73967
- if (flags.force) args.push("--force");
73968
73976
  if (flags.resume) args.push("--resume");
73969
73977
  if (flags.workUnitId) args.push(`--work-id=${flags.workUnitId}`);
73970
73978
  if (flags.attemptId) args.push(`--attempt-id=${flags.attemptId}`);
@@ -74143,7 +74151,7 @@ var LocalScriptExecutor = class {
74143
74151
  var localScriptExecutor = new LocalScriptExecutor();
74144
74152
 
74145
74153
  // src/core/control-sync.ts
74146
- var path44 = __toESM(require("path"));
74154
+ var path45 = __toESM(require("path"));
74147
74155
  init_control_config();
74148
74156
 
74149
74157
  // src/core/control-registry.ts
@@ -74223,6 +74231,7 @@ function registryChanged(before, after) {
74223
74231
  function recordRepoForControlSync(repoPath) {
74224
74232
  if (process.env.HAR_CONTROL_DISABLED === "true") return;
74225
74233
  const resolved = canonicalizeControlRepoPath(repoPath);
74234
+ if (!resolveMainWorkingTree(resolved)) return;
74226
74235
  if (!readManifest(resolved)) return;
74227
74236
  const registry2 = readRegistry();
74228
74237
  if (registry2.repos.includes(resolved)) return;
@@ -74709,7 +74718,7 @@ function describeLaunchBase(repoPath) {
74709
74718
  return [
74710
74719
  `New session will be based on: ${branch}${sha ? ` @ ${sha}` : ""}`,
74711
74720
  ` (HEAD of ${harnessRoot})`,
74712
- " --replace does not choose this base \u2014 switch the main checkout first for a new unrelated task."
74721
+ " Switch the main checkout to your intended base before launching a new session."
74713
74722
  ];
74714
74723
  }
74715
74724
  function formatOccupiedSlot(slot, repoPath, resume) {
@@ -74721,27 +74730,30 @@ function formatOccupiedSlot(slot, repoPath, resume) {
74721
74730
  slot.sessionStatus ? ` Status: ${slot.sessionStatus}` : void 0,
74722
74731
  slot.lastError ? ` Error: ${slot.lastError}` : void 0,
74723
74732
  slot.sessionCreatedAt ? ` Since: ${slot.sessionCreatedAt}` : void 0,
74724
- slot.dirty ? " Git: dirty (uncommitted changes \u2014 commit or use force to discard)" : " Git: clean",
74733
+ slot.dirty ? " Git: dirty (uncommitted changes \u2014 commit or discard them in the worktree)" : " Git: clean",
74725
74734
  "",
74726
74735
  ...describeLaunchBase(repoPath),
74727
74736
  ""
74728
74737
  ];
74729
74738
  if (resume || slot.sessionStatus === "failed" || slot.sessionStatus === "starting") {
74730
74739
  lines2.push(
74731
- "This session failed partway through launch. Resume without replacing:",
74740
+ "This session failed partway through launch. Resume without a new launch:",
74732
74741
  ` har env launch ${slot.agentId} --resume`,
74733
74742
  ` har env recover ${slot.agentId}`,
74734
74743
  ` ./.har/launch.sh ${slot.agentId} --resume`,
74735
74744
  ""
74736
74745
  );
74746
+ } else {
74747
+ lines2.push(
74748
+ "Free the slot before starting a new session:",
74749
+ slot.dirty ? ` Commit or discard changes in the worktree, then: har env teardown ${slot.agentId} (or complete ${slot.agentId})` : ` har env complete ${slot.agentId} # or: har env teardown ${slot.agentId}`,
74750
+ ` har env launch ${slot.agentId}`,
74751
+ ""
74752
+ );
74737
74753
  }
74738
74754
  lines2.push(
74739
- "Prefer complete/teardown when the previous task is finished, then launch.",
74740
- "Replacing removes the worktree. The session branch is kept only if you committed.",
74741
- "Gitignored paths (state/, runs/, local clones) are NOT preserved.",
74742
- "",
74743
- "To replace: pass confirmReplace=true (MCP), --replace (CLI), or answer y at the prompt.",
74744
- "If the worktree is dirty, also pass force=true / --force after explicit user approval."
74755
+ "complete/teardown remove the worktree. The session branch is kept only if you committed.",
74756
+ "Gitignored paths (state/, runs/, local clones) are NOT preserved."
74745
74757
  );
74746
74758
  return lines2.filter(Boolean).join("\n");
74747
74759
  }
@@ -74761,42 +74773,18 @@ function checkLaunchGuard(repoPath, agentId, options = {}) {
74761
74773
  reason: [
74762
74774
  `Slot ${agentId} is not resumable (status=${session?.status ?? "none"}).`,
74763
74775
  "Only failed or starting sessions can be resumed.",
74764
- "Use a normal launch with --replace to start fresh."
74776
+ `Free the slot first: har env teardown ${agentId} (or complete ${agentId}), then har env launch ${agentId}.`
74765
74777
  ].join("\n")
74766
74778
  };
74767
74779
  }
74768
74780
  return { allowed: true, slot };
74769
74781
  }
74770
- if (isSlotResumable(session) && !options.confirmReplace) {
74771
- return {
74772
- allowed: false,
74773
- blocked: true,
74774
- slot,
74775
- reason: formatOccupiedSlot(slot, repoPath)
74776
- };
74777
- }
74778
- if (!options.confirmReplace) {
74779
- return {
74780
- allowed: false,
74781
- blocked: true,
74782
- slot,
74783
- reason: formatOccupiedSlot(slot, repoPath)
74784
- };
74785
- }
74786
- if (slot.dirty && !options.force) {
74787
- return {
74788
- allowed: false,
74789
- blocked: true,
74790
- slot,
74791
- reason: [
74792
- formatOccupiedSlot(slot, repoPath),
74793
- "",
74794
- "The occupied worktree has uncommitted changes.",
74795
- "Pass force=true / --force to discard them (only after explicit user approval)."
74796
- ].join("\n")
74797
- };
74798
- }
74799
- return { allowed: true, slot };
74782
+ return {
74783
+ allowed: false,
74784
+ blocked: true,
74785
+ slot,
74786
+ reason: formatOccupiedSlot(slot, repoPath)
74787
+ };
74800
74788
  }
74801
74789
 
74802
74790
  // src/core/slot-preflight.ts
@@ -74858,24 +74846,20 @@ function inspectSlotReadiness(repoPath, agentId, options = {}) {
74858
74846
  const warnings = [];
74859
74847
  const ports = {};
74860
74848
  const session = readSlotRegistry(harnessRoot, agentId);
74861
- const guard = options.occupied !== void 0 ? options.occupied.active ? options.resume && isSlotResumable(session) ? { allowed: true } : !options.confirmReplace ? {
74849
+ const guard = options.occupied !== void 0 ? options.occupied.active ? options.resume && isSlotResumable(session) ? { allowed: true } : {
74862
74850
  allowed: false,
74863
74851
  blocked: true,
74864
74852
  reason: `Slot ${agentId} is already in use.`
74865
- } : options.occupied.dirty && !options.force ? {
74866
- allowed: false,
74867
- blocked: true,
74868
- reason: `Slot ${agentId} worktree has uncommitted changes.`
74869
- } : { allowed: true } : { allowed: true } : checkLaunchGuard(repoPath, agentId, options);
74853
+ } : { allowed: true } : checkLaunchGuard(repoPath, agentId, options);
74870
74854
  if (!guard.allowed) {
74871
74855
  const resumable = isSlotResumable(session);
74872
74856
  blockers.push({
74873
74857
  code: options.occupied?.dirty ? "slot_dirty" : resumable ? "slot_resumable" : "slot_occupied",
74874
74858
  message: guard.reason ?? `Slot ${agentId} is occupied.`,
74875
- remediation: resumable ? `Resume the partial launch: har env launch ${agentId} --resume (or har env recover ${agentId})` : guard.slot?.dirty ? "Commit changes in the worktree, or pass --force after explicit user approval." : "Pass --replace (CLI), confirmReplace=true (MCP), or answer y at the launch prompt."
74859
+ remediation: resumable ? `Resume the partial launch: har env launch ${agentId} --resume (or har env recover ${agentId})` : `Free the slot: har env teardown ${agentId} (or complete ${agentId}), then har env launch ${agentId}.`
74876
74860
  });
74877
74861
  remediations.push(
74878
- resumable ? `har env launch ${agentId} --resume` : guard.slot?.dirty ? "har env preflight <id> --replace --force" : "har env preflight <id> --replace"
74862
+ resumable ? `har env launch ${agentId} --resume` : `har env teardown ${agentId}`
74879
74863
  );
74880
74864
  }
74881
74865
  const pm2Procs = usesPm2 ? options.pm2Processes !== void 0 ? options.pm2Processes : listPm2Processes() : void 0;
@@ -74904,7 +74888,7 @@ function inspectSlotReadiness(repoPath, agentId, options = {}) {
74904
74888
  blockers.push({
74905
74889
  code: "project_mismatch",
74906
74890
  message: `Slot registry projectName=${session.projectName} does not match harness ${projectName}.`,
74907
- remediation: "Teardown the stale session and relaunch with --replace."
74891
+ remediation: "Teardown the stale session, then relaunch."
74908
74892
  });
74909
74893
  }
74910
74894
  }
@@ -75614,7 +75598,7 @@ init_telemetry_config();
75614
75598
  // src/core/usage-harvest/claude.ts
75615
75599
  var fs40 = __toESM(require("fs"));
75616
75600
  var os11 = __toESM(require("os"));
75617
- var path40 = __toESM(require("path"));
75601
+ var path41 = __toESM(require("path"));
75618
75602
  init_telemetry_config();
75619
75603
 
75620
75604
  // src/core/telemetry-env.ts
@@ -75682,16 +75666,24 @@ ${TELEMETRY_MARKER_END}
75682
75666
  fs39.writeFileSync(envFilePath, combined.endsWith("\n") ? combined : combined + "\n");
75683
75667
  }
75684
75668
 
75685
- // src/core/usage-harvest/claude.ts
75686
- function pathsMatch(candidate, targets) {
75687
- const norm = path40.resolve(candidate);
75688
- return targets.some((t2) => {
75689
- const target = path40.resolve(t2);
75690
- return norm === target || norm.startsWith(target + path40.sep) || target.startsWith(norm + path40.sep);
75691
- });
75669
+ // src/core/workspace-path-match.ts
75670
+ var path40 = __toESM(require("path"));
75671
+ function stripTrailingSeparators(value) {
75672
+ return value.replace(/[/\\]+$/, "");
75673
+ }
75674
+ function isWorkspaceUnderPath(workspace, basePath) {
75675
+ const workspaceNorm = stripTrailingSeparators(path40.resolve(workspace));
75676
+ const baseNorm = stripTrailingSeparators(path40.resolve(basePath));
75677
+ if (!workspaceNorm || !baseNorm) return false;
75678
+ return workspaceNorm === baseNorm || workspaceNorm.startsWith(`${baseNorm}${path40.sep}`);
75692
75679
  }
75680
+ function workspaceMatchesTarget(workspace, targets) {
75681
+ return targets.some((target) => isWorkspaceUnderPath(workspace, target));
75682
+ }
75683
+
75684
+ // src/core/usage-harvest/claude.ts
75693
75685
  function claudeProjectsRoot() {
75694
- return process.env.HAR_CLAUDE_PROJECTS_DIR ? path40.resolve(process.env.HAR_CLAUDE_PROJECTS_DIR) : path40.join(os11.homedir(), ".claude", "projects");
75686
+ return process.env.HAR_CLAUDE_PROJECTS_DIR ? path41.resolve(process.env.HAR_CLAUDE_PROJECTS_DIR) : path41.join(os11.homedir(), ".claude", "projects");
75695
75687
  }
75696
75688
  function encodeClaudeProjectDir(cwd) {
75697
75689
  return cwd.replace(/[^a-zA-Z0-9]/g, "-");
@@ -75766,18 +75758,18 @@ function findMatchingClaudeTranscripts(slot) {
75766
75758
  const matches = [];
75767
75759
  for (const entry of fs40.readdirSync(root, { withFileTypes: true })) {
75768
75760
  if (!entry.isDirectory()) continue;
75769
- const projectDir = path40.join(root, entry.name);
75770
- const encodedHit = targets.some((t2) => entry.name.includes(encodeClaudeProjectDir(t2).slice(0, 40)));
75761
+ const projectDir = path41.join(root, entry.name);
75762
+ const encodedHit = targets.some((t2) => entry.name === encodeClaudeProjectDir(t2));
75771
75763
  for (const file of fs40.readdirSync(projectDir)) {
75772
75764
  if (!file.endsWith(".jsonl")) continue;
75773
- const filePath = path40.join(projectDir, file);
75765
+ const filePath = path41.join(projectDir, file);
75774
75766
  const stat = fs40.statSync(filePath);
75775
75767
  const records = readJsonlRecords(filePath);
75776
75768
  let cwdHit = encodedHit;
75777
75769
  for (const record2 of records) {
75778
75770
  if (!record2 || typeof record2 !== "object") continue;
75779
75771
  const cwd = String(record2.cwd ?? "");
75780
- if (cwd && pathsMatch(cwd, targets)) {
75772
+ if (cwd && workspaceMatchesTarget(cwd, targets)) {
75781
75773
  cwdHit = true;
75782
75774
  break;
75783
75775
  }
@@ -75885,21 +75877,14 @@ function harvestClaudeEvents(slot) {
75885
75877
  // src/core/usage-harvest/codex.ts
75886
75878
  var fs41 = __toESM(require("fs"));
75887
75879
  var os12 = __toESM(require("os"));
75888
- var path41 = __toESM(require("path"));
75889
- function pathsMatch2(candidate, targets) {
75890
- const norm = path41.resolve(candidate);
75891
- return targets.some((t2) => {
75892
- const target = path41.resolve(t2);
75893
- return norm === target || norm.startsWith(target + path41.sep) || target.startsWith(norm + path41.sep);
75894
- });
75895
- }
75880
+ var path42 = __toESM(require("path"));
75896
75881
  function codexSessionsRoot() {
75897
- return process.env.HAR_CODEX_SESSIONS_DIR ? path41.resolve(process.env.HAR_CODEX_SESSIONS_DIR) : path41.join(os12.homedir(), ".codex", "sessions");
75882
+ return process.env.HAR_CODEX_SESSIONS_DIR ? path42.resolve(process.env.HAR_CODEX_SESSIONS_DIR) : path42.join(os12.homedir(), ".codex", "sessions");
75898
75883
  }
75899
75884
  function walkJsonlFiles(dir, out = []) {
75900
75885
  if (!fs41.existsSync(dir)) return out;
75901
75886
  for (const entry of fs41.readdirSync(dir, { withFileTypes: true })) {
75902
- const full = path41.join(dir, entry.name);
75887
+ const full = path42.join(dir, entry.name);
75903
75888
  if (entry.isDirectory()) walkJsonlFiles(full, out);
75904
75889
  else if (entry.isFile() && entry.name.endsWith(".jsonl")) out.push(full);
75905
75890
  }
@@ -75968,7 +75953,7 @@ function harvestCodexUsage(slot) {
75968
75953
  for (const file of files) {
75969
75954
  const records = readJsonl(file);
75970
75955
  const extracted = extractCodexTokens(records);
75971
- if (!extracted.cwd || !pathsMatch2(extracted.cwd, targets)) continue;
75956
+ if (!extracted.cwd || !workspaceMatchesTarget(extracted.cwd, targets)) continue;
75972
75957
  if (extracted.tokensInput + extracted.tokensOutput + extracted.tokensCacheRead === 0) continue;
75973
75958
  const mtime = fs41.statSync(file).mtimeMs;
75974
75959
  if (mtime >= bestMtime) {
@@ -76012,17 +75997,17 @@ function harvestEventsForSlot(slot) {
76012
75997
  }
76013
75998
 
76014
75999
  // src/core/control-persisted-usage.ts
76015
- var path43 = __toESM(require("path"));
76000
+ var path44 = __toESM(require("path"));
76016
76001
 
76017
76002
  // src/core/portal-watermark.ts
76018
76003
  var fs42 = __toESM(require("fs"));
76019
76004
  var os13 = __toESM(require("os"));
76020
- var path42 = __toESM(require("path"));
76005
+ var path43 = __toESM(require("path"));
76021
76006
  function getStatePath() {
76022
76007
  if (process.env.HAR_PORTAL_SYNC_STATE_PATH) {
76023
- return path42.resolve(process.env.HAR_PORTAL_SYNC_STATE_PATH);
76008
+ return path43.resolve(process.env.HAR_PORTAL_SYNC_STATE_PATH);
76024
76009
  }
76025
- return path42.join(os13.homedir(), ".har", "portal-sync-state.json");
76010
+ return path43.join(os13.homedir(), ".har", "portal-sync-state.json");
76026
76011
  }
76027
76012
  function readState() {
76028
76013
  const statePath = getStatePath();
@@ -76036,7 +76021,7 @@ function readState() {
76036
76021
  }
76037
76022
  function writeState(state) {
76038
76023
  const statePath = getStatePath();
76039
- fs42.mkdirSync(path42.dirname(statePath), { recursive: true });
76024
+ fs42.mkdirSync(path43.dirname(statePath), { recursive: true });
76040
76025
  fs42.writeFileSync(statePath, JSON.stringify(state, null, 2) + "\n");
76041
76026
  }
76042
76027
  function readPortalWatermark(repoPath, portalUrl) {
@@ -76088,8 +76073,8 @@ async function getJson(url) {
76088
76073
  async function resolveControlRepoId(apiUrl, repoPath) {
76089
76074
  const repos = await getJson(`${apiUrl}/api/repos`);
76090
76075
  if (!Array.isArray(repos)) return null;
76091
- const target = path43.resolve(repoPath);
76092
- return repos.find((repo) => path43.resolve(repo.path) === target)?.id ?? null;
76076
+ const target = path44.resolve(repoPath);
76077
+ return repos.find((repo) => path44.resolve(repo.path) === target)?.id ?? null;
76093
76078
  }
76094
76079
  function optionalString(value) {
76095
76080
  return value == null ? void 0 : value;
@@ -76392,28 +76377,16 @@ async function waitForControlApi(apiUrl = getControlApiUrl(), timeoutMs = 6e4, i
76392
76377
  const deadline = Date.now() + timeoutMs;
76393
76378
  while (Date.now() < deadline) {
76394
76379
  if (await isControlApiReachable(apiUrl)) return true;
76395
- await new Promise((resolve45) => setTimeout(resolve45, intervalMs));
76380
+ await new Promise((resolve46) => setTimeout(resolve46, intervalMs));
76396
76381
  }
76397
76382
  return false;
76398
76383
  }
76399
76384
  async function discoverHarRepos(options) {
76400
- const apiUrl = options?.apiUrl ?? getControlApiUrl();
76401
76385
  const repoPaths = new Set(listRegisteredRepos());
76402
76386
  if (options?.cwd) {
76403
76387
  const cwd = canonicalizeControlRepoPath(options.cwd);
76404
76388
  if (readManifest(cwd)) repoPaths.add(cwd);
76405
76389
  }
76406
- try {
76407
- const listResponse = await fetch(`${apiUrl}/api/repos`);
76408
- if (listResponse.ok) {
76409
- const repos = await listResponse.json();
76410
- for (const repo of repos) {
76411
- const resolved = canonicalizeControlRepoPath(repo.path);
76412
- if (readManifest(resolved)) repoPaths.add(resolved);
76413
- }
76414
- }
76415
- } catch {
76416
- }
76417
76390
  return [...repoPaths];
76418
76391
  }
76419
76392
  async function syncReposWithControl(options) {
@@ -76495,7 +76468,7 @@ async function syncRepoWithLocalControl(options) {
76495
76468
  const listResponse = await fetch(`${apiUrl}/api/repos`);
76496
76469
  if (!listResponse.ok) throw new Error("Failed to list repos from Control API");
76497
76470
  const repos = await listResponse.json();
76498
- const existing = repos.find((r2) => path44.resolve(r2.path) === repoPath);
76471
+ const existing = repos.find((r2) => path45.resolve(r2.path) === repoPath);
76499
76472
  if (!existing) {
76500
76473
  return;
76501
76474
  }
@@ -76654,6 +76627,7 @@ async function syncRepoWithControlAsync(repoPath) {
76654
76627
  if (process.env.HAR_CONTROL_DISABLED === "true" || process.env.NODE_ENV === "test") return;
76655
76628
  const verbose = process.env.HAR_CONTROL_VERBOSE === "true";
76656
76629
  try {
76630
+ recordRepoForControlSync(repoPath);
76657
76631
  const apiUrl = getControlApiUrl();
76658
76632
  if (!await isControlApiReachable(apiUrl)) {
76659
76633
  if (verbose) {
@@ -76698,7 +76672,7 @@ init_control_config();
76698
76672
 
76699
76673
  // src/core/control-lifecycle.ts
76700
76674
  var import_child_process9 = require("child_process");
76701
- var path45 = __toESM(require("path"));
76675
+ var path46 = __toESM(require("path"));
76702
76676
 
76703
76677
  // src/core/control-image.ts
76704
76678
  var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
@@ -76722,10 +76696,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
76722
76696
  var CONTROL_CONTAINER_PORT = 3847;
76723
76697
  var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
76724
76698
  function resolveControlDir() {
76725
- return path45.resolve(__dirname, "..", "control");
76699
+ return path46.resolve(__dirname, "..", "control");
76726
76700
  }
76727
76701
  function resolveControlBuildContext() {
76728
- return path45.resolve(resolveControlDir(), "..");
76702
+ return path46.resolve(resolveControlDir(), "..");
76729
76703
  }
76730
76704
  function buildDockerRunArgs(options) {
76731
76705
  const name = options.containerName ?? CONTROL_CONTAINER_NAME;
@@ -76781,7 +76755,7 @@ async function startMissionControl(options) {
76781
76755
  "-t",
76782
76756
  imageRef,
76783
76757
  "-f",
76784
- path45.join(resolveControlDir(), "Dockerfile"),
76758
+ path46.join(resolveControlDir(), "Dockerfile"),
76785
76759
  resolveControlBuildContext()
76786
76760
  ]);
76787
76761
  if (buildCode !== 0) {
@@ -76926,7 +76900,7 @@ async function ensureTelemetryInfrastructure(options) {
76926
76900
 
76927
76901
  // src/core/run-service.ts
76928
76902
  init_telemetry_config();
76929
- var path47 = __toESM(require("path"));
76903
+ var path48 = __toESM(require("path"));
76930
76904
  function extractShellOutput(result) {
76931
76905
  const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
76932
76906
  const stderr = result.logs?.find((log) => log.stream === "stderr")?.content ?? "";
@@ -77013,10 +76987,7 @@ var RunService = class {
77013
76987
  return this.executor.listArtifacts({ repoPath: options.repoPath }, { stageId: options.stageId });
77014
76988
  }
77015
76989
  async preflightEnvironment(options) {
77016
- const readiness = inspectSlotReadiness(options.repoPath, options.agentId, {
77017
- confirmReplace: options.confirmReplace,
77018
- force: options.force
77019
- });
76990
+ const readiness = inspectSlotReadiness(options.repoPath, options.agentId, {});
77020
76991
  const report = formatPreflightReport(options.agentId, readiness);
77021
76992
  return {
77022
76993
  code: readiness.canLaunch ? 0 : 1,
@@ -77028,8 +76999,6 @@ var RunService = class {
77028
76999
  }
77029
77000
  async launchEnvironment(options) {
77030
77001
  const guard = checkLaunchGuard2(options.repoPath, options.agentId, {
77031
- confirmReplace: options.confirmReplace,
77032
- force: options.force,
77033
77002
  resume: options.resume
77034
77003
  });
77035
77004
  if (!guard.allowed) {
@@ -77079,7 +77048,7 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
77079
77048
  const attemptId = workUnitId ? resumableSession?.attemptId ?? crypto5.randomUUID() : void 0;
77080
77049
  if (workUnitId && attemptId) {
77081
77050
  const conflictingSession = listSlotRegistryEntries(harnessRoot).find(
77082
- (entry) => entry.workUnitId === workUnitId && !(entry.agentId === options.agentId && (options.resume || options.confirmReplace))
77051
+ (entry) => entry.workUnitId === workUnitId && !(entry.agentId === options.agentId && options.resume)
77083
77052
  );
77084
77053
  if (conflictingSession) {
77085
77054
  return {
@@ -77112,8 +77081,6 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
77112
77081
  launchFlags: {
77113
77082
  worktree: options.worktree,
77114
77083
  claude: options.claude,
77115
- confirmReplace: options.confirmReplace,
77116
- force: options.force,
77117
77084
  resume: options.resume,
77118
77085
  workUnitId,
77119
77086
  attemptId
@@ -77136,12 +77103,12 @@ Usage from Cursor / Claude / Codex (@osfactory/otel-hook) will appear under Work
77136
77103
  suffix: session.suffix,
77137
77104
  createdAt: session.createdAt
77138
77105
  });
77139
- const envFile = path47.join(session.workDir, `.env.agent.${options.agentId}`);
77106
+ const envFile = path48.join(session.workDir, `.env.agent.${options.agentId}`);
77140
77107
  try {
77141
77108
  appendTelemetryEnvToFile(envFile, {
77142
77109
  sessionKey,
77143
77110
  agentId: options.agentId,
77144
- repoPath: path47.resolve(options.repoPath),
77111
+ repoPath: path48.resolve(options.repoPath),
77145
77112
  workDir: session.workDir,
77146
77113
  branch: session.branch,
77147
77114
  suffix: session.suffix,
@@ -77379,7 +77346,7 @@ var readline6 = __toESM(require("readline"));
77379
77346
  // src/core/hooks.ts
77380
77347
  var fs44 = __toESM(require("fs"));
77381
77348
  var os15 = __toESM(require("os"));
77382
- var path48 = __toESM(require("path"));
77349
+ var path49 = __toESM(require("path"));
77383
77350
  var MARKER_START = "# >>> har commit gate (managed by `har hooks`) >>>";
77384
77351
  var MARKER_END = "# <<< har commit gate <<<";
77385
77352
  var PRE_COMMIT_BLOCK = [
@@ -77404,7 +77371,7 @@ function resolveCheckoutRoot(cwd) {
77404
77371
  function resolveHooksDir(checkoutDir) {
77405
77372
  const hooksPath = tryGit3(checkoutDir, "rev-parse --git-path hooks");
77406
77373
  if (!hooksPath) throw new Error(`Not a git checkout: ${checkoutDir}`);
77407
- return path48.resolve(checkoutDir, hooksPath);
77374
+ return path49.resolve(checkoutDir, hooksPath);
77408
77375
  }
77409
77376
  function getConfiguredHooksPath(checkoutDir) {
77410
77377
  return tryGit3(checkoutDir, "config core.hooksPath") || void 0;
@@ -77412,9 +77379,9 @@ function getConfiguredHooksPath(checkoutDir) {
77412
77379
  function defaultHarInvocation() {
77413
77380
  const entry = process.argv[1];
77414
77381
  if (entry && entry.endsWith(".js")) {
77415
- return `"${process.execPath}" "${path48.resolve(entry)}"`;
77382
+ return `"${process.execPath}" "${path49.resolve(entry)}"`;
77416
77383
  }
77417
- if (entry) return `"${path48.resolve(entry)}"`;
77384
+ if (entry) return `"${path49.resolve(entry)}"`;
77418
77385
  return "har";
77419
77386
  }
77420
77387
  function buildHookScript(harInvocation, subcommand, failOpenNotice) {
@@ -77493,17 +77460,17 @@ Or re-run with --force to write into that directory anyway.`
77493
77460
  fs44.mkdirSync(hooksDir, { recursive: true });
77494
77461
  const invocation = options.harInvocation ?? defaultHarInvocation();
77495
77462
  fs44.writeFileSync(
77496
- path48.join(hooksDir, "har-pre-commit"),
77463
+ path49.join(hooksDir, "har-pre-commit"),
77497
77464
  buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
77498
77465
  { mode: 493 }
77499
77466
  );
77500
77467
  fs44.writeFileSync(
77501
- path48.join(hooksDir, "har-post-commit"),
77468
+ path49.join(hooksDir, "har-post-commit"),
77502
77469
  buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
77503
77470
  { mode: 493 }
77504
77471
  );
77505
- const preCommit = upsertMarkedBlock(path48.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
77506
- const postCommit = upsertMarkedBlock(path48.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
77472
+ const preCommit = upsertMarkedBlock(path49.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
77473
+ const postCommit = upsertMarkedBlock(path49.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
77507
77474
  ensureValidationsIgnored(checkout);
77508
77475
  return { hooksDir, preCommit, postCommit };
77509
77476
  }
@@ -77512,10 +77479,10 @@ function uninstallHooks(repoPath) {
77512
77479
  if (!checkout) throw new Error(`Not a git repository: ${repoPath}`);
77513
77480
  const hooksDir = resolveHooksDir(checkout);
77514
77481
  let removed = false;
77515
- removed = removeMarkedBlock(path48.join(hooksDir, "pre-commit")) || removed;
77516
- removed = removeMarkedBlock(path48.join(hooksDir, "post-commit")) || removed;
77482
+ removed = removeMarkedBlock(path49.join(hooksDir, "pre-commit")) || removed;
77483
+ removed = removeMarkedBlock(path49.join(hooksDir, "post-commit")) || removed;
77517
77484
  for (const file of ["har-pre-commit", "har-post-commit"]) {
77518
- const full = path48.join(hooksDir, file);
77485
+ const full = path49.join(hooksDir, file);
77519
77486
  if (fs44.existsSync(full)) {
77520
77487
  fs44.rmSync(full);
77521
77488
  removed = true;
@@ -77536,10 +77503,10 @@ function isAgentWorktree(checkoutDir) {
77536
77503
  if (branch && (/^har-agent-\d+$/.test(branch) || /-har-agent-\d+-[a-z0-9]+$/.test(branch))) {
77537
77504
  return true;
77538
77505
  }
77539
- const worktreesRoot = path48.join(os15.homedir(), "worktrees");
77540
- const resolved = path48.resolve(checkoutDir);
77541
- const name = path48.basename(resolved);
77542
- return resolved.startsWith(`${worktreesRoot}${path48.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
77506
+ const worktreesRoot = path49.join(os15.homedir(), "worktrees");
77507
+ const resolved = path49.resolve(checkoutDir);
77508
+ const name = path49.basename(resolved);
77509
+ return resolved.startsWith(`${worktreesRoot}${path49.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
77543
77510
  }
77544
77511
  function resolveEffectiveMode(checkoutDir, gate) {
77545
77512
  if (!gate.enabled) return "off";
@@ -77552,15 +77519,15 @@ function getHooksStatus(repoPath) {
77552
77519
  const hooksDir = resolveHooksDir(checkout);
77553
77520
  const gate = getCommitGateConfig(checkout);
77554
77521
  const hasBlock = (name) => {
77555
- const file = path48.join(hooksDir, name);
77522
+ const file = path49.join(hooksDir, name);
77556
77523
  return fs44.existsSync(file) && fs44.readFileSync(file, "utf8").includes(MARKER_START);
77557
77524
  };
77558
77525
  return {
77559
77526
  checkout,
77560
77527
  hooksDir,
77561
77528
  configuredHooksPath: getConfiguredHooksPath(checkout),
77562
- preCommitInstalled: hasBlock("pre-commit") && fs44.existsSync(path48.join(hooksDir, "har-pre-commit")),
77563
- postCommitInstalled: hasBlock("post-commit") && fs44.existsSync(path48.join(hooksDir, "har-post-commit")),
77529
+ preCommitInstalled: hasBlock("pre-commit") && fs44.existsSync(path49.join(hooksDir, "har-pre-commit")),
77530
+ postCommitInstalled: hasBlock("post-commit") && fs44.existsSync(path49.join(hooksDir, "har-post-commit")),
77564
77531
  gate,
77565
77532
  effectiveMode: resolveEffectiveMode(checkout, gate)
77566
77533
  };
@@ -77571,7 +77538,7 @@ function checkCommitGate(cwd) {
77571
77538
  }
77572
77539
  const checkout = resolveCheckoutRoot(cwd);
77573
77540
  if (!checkout) return { exitCode: 0, messages: [] };
77574
- if (!fs44.existsSync(path48.join(checkout, ".har", "stages.json"))) {
77541
+ if (!fs44.existsSync(path49.join(checkout, ".har", "stages.json"))) {
77575
77542
  return { exitCode: 0, messages: [] };
77576
77543
  }
77577
77544
  const gate = getCommitGateConfig(checkout);
@@ -77644,12 +77611,12 @@ async function recordCommitAssociation(cwd) {
77644
77611
  // src/core/commit-gate-onboarding.ts
77645
77612
  function askYesNo5(question) {
77646
77613
  const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
77647
- return new Promise((resolve45) => {
77614
+ return new Promise((resolve46) => {
77648
77615
  process.stderr.write(`${question} `);
77649
77616
  rl.once("line", (answer) => {
77650
77617
  rl.close();
77651
77618
  const trimmed = answer.trim();
77652
- resolve45(trimmed === "" || /^y(es)?$/i.test(trimmed));
77619
+ resolve46(trimmed === "" || /^y(es)?$/i.test(trimmed));
77653
77620
  });
77654
77621
  });
77655
77622
  }
@@ -77693,12 +77660,12 @@ async function handleCommitGateOnboarding(options) {
77693
77660
  // src/core/onboarding-preferences.ts
77694
77661
  var fs45 = __toESM(require("fs"));
77695
77662
  var os16 = __toESM(require("os"));
77696
- var path49 = __toESM(require("path"));
77663
+ var path50 = __toESM(require("path"));
77697
77664
  function getOnboardingPreferencesPath() {
77698
77665
  if (process.env.HAR_PREFERENCES_PATH) {
77699
- return path49.resolve(process.env.HAR_PREFERENCES_PATH);
77666
+ return path50.resolve(process.env.HAR_PREFERENCES_PATH);
77700
77667
  }
77701
- return path49.join(os16.homedir(), ".har", "preferences.json");
77668
+ return path50.join(os16.homedir(), ".har", "preferences.json");
77702
77669
  }
77703
77670
  function readOnboardingPreferences() {
77704
77671
  const preferencePath = getOnboardingPreferencesPath();
@@ -77729,7 +77696,7 @@ function writeOnboardingPreferences(overrides) {
77729
77696
  };
77730
77697
  const parsed = OnboardingPreferencesSchema.parse(preference);
77731
77698
  const preferencePath = getOnboardingPreferencesPath();
77732
- fs45.mkdirSync(path49.dirname(preferencePath), { recursive: true });
77699
+ fs45.mkdirSync(path50.dirname(preferencePath), { recursive: true });
77733
77700
  fs45.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
77734
77701
  `);
77735
77702
  return parsed;
@@ -77752,10 +77719,11 @@ Slot lifecycle (do not confuse these):
77752
77719
  complete finish successfully: full verify, then teardown (frees the slot)
77753
77720
  teardown abandon / free the slot without a completion validation
77754
77721
 
77755
- --replace only confirms destroying a previous session on that slot id
77756
- it does NOT choose main \u2014 new session still uses current HEAD
77757
- --force additionally discard dirty uncommitted work (user approval only)
77758
- --resume recover failed/starting; never use --replace for that
77722
+ Occupied slots always block a new launch:
77723
+ har env complete <id> # or: har env teardown <id>
77724
+ har env launch <id> # then start the new session
77725
+
77726
+ --resume recover a failed/starting session; never needed for a fresh launch
77759
77727
 
77760
77728
  For a new unrelated task: checkout main (or your intended base) on the main
77761
77729
  repo checkout, free the slot (complete/teardown), then launch.`;
@@ -77768,23 +77736,23 @@ var HAR_ENV_EPILOG = `Environment lifecycle:
77768
77736
  teardown <id> free the slot without recording a completion validation
77769
77737
 
77770
77738
  Occupied slots:
77771
- Prefer complete/teardown when the previous task is finished, then launch.
77772
- Use --replace only to reuse the same slot id immediately (destroys old worktree).
77773
- --replace does not select the base branch \u2014 HEAD of --repo does.
77774
- Dirty previous worktree also needs --force after explicit user approval.`;
77739
+ Always blocked for a fresh launch \u2014 free the slot first, then launch again:
77740
+ har env complete <id> # or: har env teardown <id>
77741
+ har env launch <id>
77742
+ A new launch uses the main checkout's current HEAD \u2014 switch that checkout to
77743
+ your intended base first.
77744
+ Failed/starting sessions can be resumed instead: har env launch <id> --resume
77745
+ (or har env recover <id>).`;
77775
77746
  var LAUNCH_COMMAND_DESCRIBE = "Start a fresh agent session (new worktree from the main checkout HEAD)";
77776
- var LAUNCH_REPLACE_DESCRIBE = "Destroy the previous session on this slot and start another (does not choose main; still uses --repo HEAD)";
77777
- var LAUNCH_FORCE_DESCRIBE = "With --replace: discard uncommitted changes in the old worktree (only after explicit user approval)";
77778
- var LAUNCH_RESUME_DESCRIBE = "Continue a failed or starting launch without creating a new worktree (prefer over --replace)";
77747
+ var LAUNCH_RESUME_DESCRIBE = "Continue a failed or starting launch without creating a new worktree";
77779
77748
  var LAUNCH_EPILOG = `Every launch creates a NEW session from the current HEAD of --repo (the main
77780
77749
  checkout). The worktree path encodes that base branch \u2014 switch --repo to main
77781
77750
  before launch for a new unrelated task unless you intentionally stack on a
77782
77751
  feature branch.
77783
77752
 
77784
77753
  Free slot: har env launch 1
77785
- Occupied: har env complete 1 # or teardown \u2014 then launch
77786
- har env launch 1 --replace # reuse slot id now
77787
- har env launch 1 --replace --force # + discard dirty work
77754
+ Occupied: har env complete 1 # or teardown
77755
+ har env launch 1 # then start the new session
77788
77756
  Failed launch: har env recover 1 # or: har env launch 1 --resume`;
77789
77757
 
77790
77758
  // src/cli/commands/env.ts
@@ -77936,15 +77904,7 @@ var envCommand = {
77936
77904
  type: "boolean",
77937
77905
  default: true,
77938
77906
  describe: "Use an isolated git worktree (default)"
77939
- }).option("claude", { type: "boolean", default: false }).option("replace", {
77940
- type: "boolean",
77941
- default: false,
77942
- describe: LAUNCH_REPLACE_DESCRIBE
77943
- }).option("force", {
77944
- type: "boolean",
77945
- default: false,
77946
- describe: LAUNCH_FORCE_DESCRIBE
77947
- }).option("resume", {
77907
+ }).option("claude", { type: "boolean", default: false }).option("resume", {
77948
77908
  type: "boolean",
77949
77909
  default: false,
77950
77910
  describe: LAUNCH_RESUME_DESCRIBE
@@ -77967,15 +77927,7 @@ var envCommand = {
77967
77927
  ).command(
77968
77928
  "preflight <id>",
77969
77929
  "Check whether a slot can launch now (ports, PM2, Docker, occupied slot)",
77970
- (y2) => y2.positional("id", { type: "number", describe: "Agent slot id (see .har/stages.json agentSlots)" }).option("repo", { type: "string", default: "." }).option("json", { type: "boolean", default: false, describe: "Structured JSON output" }).option("replace", {
77971
- type: "boolean",
77972
- default: false,
77973
- describe: "Treat an occupied slot as replaceable (same as launch --replace)"
77974
- }).option("force", {
77975
- type: "boolean",
77976
- default: false,
77977
- describe: "Allow replacing a dirty worktree (only after explicit approval)"
77978
- }),
77930
+ (y2) => y2.positional("id", { type: "number", describe: "Agent slot id (see .har/stages.json agentSlots)" }).option("repo", { type: "string", default: "." }).option("json", { type: "boolean", default: false, describe: "Structured JSON output" }),
77979
77931
  handlePreflight
77980
77932
  ).command(
77981
77933
  "verify <id>",
@@ -78033,7 +77985,7 @@ var envCommand = {
78033
77985
  }
78034
77986
  };
78035
77987
  async function handleInit(argv) {
78036
- const repoPath = path50.resolve(argv.repo);
77988
+ const repoPath = path51.resolve(argv.repo);
78037
77989
  const onboarding = resolveOnboardingOptions(argv);
78038
77990
  header("har env init");
78039
77991
  info(`Repository: ${repoPath}`);
@@ -78071,7 +78023,6 @@ async function handleInit(argv) {
78071
78023
  }
78072
78024
  divider();
78073
78025
  success("Harness initialized!");
78074
- recordRepoForControlSync(repoPath);
78075
78026
  await handleCommitGateOnboarding({
78076
78027
  repoPath,
78077
78028
  ...onboarding.commitGate,
@@ -78097,7 +78048,7 @@ async function handleInit(argv) {
78097
78048
  }
78098
78049
  }
78099
78050
  async function handleMaintain(argv) {
78100
- const repoPath = path50.resolve(argv.repo);
78051
+ const repoPath = path51.resolve(argv.repo);
78101
78052
  const onboarding = resolveOnboardingOptions(argv);
78102
78053
  header("har env maintain");
78103
78054
  info(`Repository: ${repoPath}`);
@@ -78219,7 +78170,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
78219
78170
  if (autoYes) {
78220
78171
  const proposal = readAgentMdProposal(repoPath);
78221
78172
  if (proposal) {
78222
- writeFileSafe(path50.join(repoPath, "AGENT.md"), proposal.content);
78173
+ writeFileSafe(path51.join(repoPath, "AGENT.md"), proposal.content);
78223
78174
  clearAgentMdProposal(repoPath);
78224
78175
  info("Applied AGENT.md proposal (--yes)");
78225
78176
  }
@@ -78228,7 +78179,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
78228
78179
  await promptApplyAgentMdProposal(repoPath);
78229
78180
  }
78230
78181
  async function handleAddPlugin(argv) {
78231
- const repoPath = path50.resolve(argv.repo);
78182
+ const repoPath = path51.resolve(argv.repo);
78232
78183
  const available = listPluginIds();
78233
78184
  if (argv.list) {
78234
78185
  for (const id of available) {
@@ -78266,7 +78217,7 @@ async function handleAddPlugin(argv) {
78266
78217
  }
78267
78218
  }
78268
78219
  async function handleAddStage(argv) {
78269
- const repoPath = path50.resolve(argv.repo);
78220
+ const repoPath = path51.resolve(argv.repo);
78270
78221
  const available = listPluginIds();
78271
78222
  if (argv.list) {
78272
78223
  warn("har env add-stage --list is deprecated; prefer: har env add-plugin --list");
@@ -78332,13 +78283,11 @@ async function handleAddStage(argv) {
78332
78283
  });
78333
78284
  }
78334
78285
  async function handlePreflight(argv) {
78335
- const repo = path50.resolve(argv.repo);
78286
+ const repo = path51.resolve(argv.repo);
78336
78287
  const agentId = validateAgentId(argv.id, repo);
78337
78288
  const result = await preflightEnvironment({
78338
78289
  repoPath: repo,
78339
- agentId,
78340
- confirmReplace: argv.replace,
78341
- force: argv.force
78290
+ agentId
78342
78291
  });
78343
78292
  if (argv.json) {
78344
78293
  const output = SlotReadinessSchema.parse(result.readiness);
@@ -78350,48 +78299,13 @@ async function handlePreflight(argv) {
78350
78299
  process.exit(result.code);
78351
78300
  }
78352
78301
  async function handleLaunch(argv) {
78353
- const repo = path50.resolve(argv.repo);
78302
+ const repo = path51.resolve(argv.repo);
78354
78303
  const agentId = validateAgentId(argv.id, repo);
78355
- let confirmReplace = argv.replace;
78356
- let force = argv.force;
78357
78304
  if (!argv.resume) {
78358
- const guard = checkLaunchGuard2(repo, agentId, { confirmReplace, force });
78305
+ const guard = checkLaunchGuard2(repo, agentId, {});
78359
78306
  if (!guard.allowed && guard.blocked) {
78360
- if (!confirmReplace && process.stdin.isTTY && process.stdout.isTTY) {
78361
- warn("Occupied slot \u2014 review before replacing:");
78362
- console.error(guard.reason ?? "");
78363
- const readline10 = await import("readline");
78364
- const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
78365
- const answer = await new Promise((resolve45) => {
78366
- rl.question("Replace this slot? [y/N] ", resolve45);
78367
- });
78368
- rl.close();
78369
- if (!/^[Yy]$/.test(answer.trim())) {
78370
- error("Aborted \u2014 slot left unchanged.");
78371
- process.exit(2);
78372
- }
78373
- confirmReplace = true;
78374
- }
78375
- }
78376
- const guardAfterConfirm = checkLaunchGuard2(repo, agentId, { confirmReplace, force });
78377
- if (!guardAfterConfirm.allowed && guardAfterConfirm.blocked && guardAfterConfirm.slot?.dirty) {
78378
- if (!force && process.stdin.isTTY && process.stdout.isTTY) {
78379
- warn("Worktree has uncommitted changes.");
78380
- const readline10 = await import("readline");
78381
- const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
78382
- const answer = await new Promise((resolve45) => {
78383
- rl.question("Discard uncommitted changes? [y/N] ", resolve45);
78384
- });
78385
- rl.close();
78386
- if (!/^[Yy]$/.test(answer.trim())) {
78387
- error("Aborted \u2014 uncommitted work preserved.");
78388
- process.exit(2);
78389
- }
78390
- force = true;
78391
- } else if (!force) {
78392
- error(guardAfterConfirm.reason ?? "Dirty worktree requires --force.");
78393
- process.exit(2);
78394
- }
78307
+ error(guard.reason ?? `Slot ${agentId} is occupied.`);
78308
+ process.exit(2);
78395
78309
  }
78396
78310
  }
78397
78311
  const result = await launchEnvironment({
@@ -78399,8 +78313,6 @@ async function handleLaunch(argv) {
78399
78313
  agentId,
78400
78314
  worktree: argv.worktree,
78401
78315
  claude: argv.claude,
78402
- confirmReplace,
78403
- force,
78404
78316
  resume: argv.resume,
78405
78317
  workUnitId: argv.workId,
78406
78318
  source: argv.workSource,
@@ -78433,8 +78345,6 @@ async function handleRecover(argv) {
78433
78345
  repo: argv.repo,
78434
78346
  worktree: true,
78435
78347
  claude: false,
78436
- replace: false,
78437
- force: false,
78438
78348
  resume: true,
78439
78349
  workId: void 0,
78440
78350
  workSource: void 0,
@@ -78444,7 +78354,7 @@ async function handleRecover(argv) {
78444
78354
  });
78445
78355
  }
78446
78356
  async function handleVerify(argv) {
78447
- const repo = path50.resolve(argv.repo);
78357
+ const repo = path51.resolve(argv.repo);
78448
78358
  const agentId = validateAgentId(argv.id, repo);
78449
78359
  const result = await runVerification({
78450
78360
  repoPath: repo,
@@ -78456,7 +78366,7 @@ async function handleVerify(argv) {
78456
78366
  process.exit(result.code);
78457
78367
  }
78458
78368
  async function handleTeardown(argv) {
78459
- const repo = path50.resolve(argv.repo);
78369
+ const repo = path51.resolve(argv.repo);
78460
78370
  const agentId = validateAgentId(argv.id, repo);
78461
78371
  const result = await teardownEnvironment({
78462
78372
  repoPath: repo,
@@ -78467,7 +78377,7 @@ async function handleTeardown(argv) {
78467
78377
  process.exit(result.code);
78468
78378
  }
78469
78379
  async function handleComplete(argv) {
78470
- const repo = path50.resolve(argv.repo);
78380
+ const repo = path51.resolve(argv.repo);
78471
78381
  const agentId = validateAgentId(argv.id, repo);
78472
78382
  const result = await completeEnvironment({
78473
78383
  repoPath: repo,
@@ -78488,7 +78398,7 @@ async function handleComplete(argv) {
78488
78398
  process.exit(result.code);
78489
78399
  }
78490
78400
  async function handleStatus(argv) {
78491
- const repoPath = path50.resolve(argv.repo);
78401
+ const repoPath = path51.resolve(argv.repo);
78492
78402
  if (argv.json) {
78493
78403
  const status = collectEnvironmentStatus(repoPath);
78494
78404
  const output = EnvironmentStatusSchema.parse(status);
@@ -78501,7 +78411,7 @@ async function handleStatus(argv) {
78501
78411
  });
78502
78412
  }
78503
78413
  async function handleRunsList(argv) {
78504
- const repoPath = path50.resolve(argv.repo);
78414
+ const repoPath = path51.resolve(argv.repo);
78505
78415
  const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
78506
78416
  if (argv.json) {
78507
78417
  process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
@@ -78518,7 +78428,7 @@ async function handleRunsList(argv) {
78518
78428
  }
78519
78429
  }
78520
78430
  async function handleRunsGet(argv) {
78521
- const run2 = getRun(path50.resolve(argv.repo), argv.runId);
78431
+ const run2 = getRun(path51.resolve(argv.repo), argv.runId);
78522
78432
  if (!run2) {
78523
78433
  error(`Run not found: ${argv.runId}`);
78524
78434
  process.exit(1);
@@ -78604,7 +78514,7 @@ function printNextSteps(auto2) {
78604
78514
  }
78605
78515
 
78606
78516
  // src/cli/commands/control.ts
78607
- var path54 = __toESM(require("path"));
78517
+ var path55 = __toESM(require("path"));
78608
78518
 
78609
78519
  // node_modules/@inquirer/core/dist/esm/lib/key.mjs
78610
78520
  var isUpKey = (key) => (
@@ -79624,13 +79534,13 @@ var PromisePolyfill = class extends Promise {
79624
79534
  // Available starting from Node 22
79625
79535
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
79626
79536
  static withResolver() {
79627
- let resolve45;
79537
+ let resolve46;
79628
79538
  let reject;
79629
79539
  const promise = new Promise((res, rej) => {
79630
- resolve45 = res;
79540
+ resolve46 = res;
79631
79541
  reject = rej;
79632
79542
  });
79633
- return { promise, resolve: resolve45, reject };
79543
+ return { promise, resolve: resolve46, reject };
79634
79544
  }
79635
79545
  };
79636
79546
 
@@ -79647,7 +79557,7 @@ function createPrompt(view) {
79647
79557
  output
79648
79558
  });
79649
79559
  const screen = new ScreenManager(rl);
79650
- const { promise, resolve: resolve45, reject } = PromisePolyfill.withResolver();
79560
+ const { promise, resolve: resolve46, reject } = PromisePolyfill.withResolver();
79651
79561
  const cancel = () => reject(new CancelPromptError());
79652
79562
  if (signal) {
79653
79563
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -79671,7 +79581,7 @@ function createPrompt(view) {
79671
79581
  cycle(() => {
79672
79582
  try {
79673
79583
  const nextView = view(config2, (value) => {
79674
- setImmediate(() => resolve45(value));
79584
+ setImmediate(() => resolve46(value));
79675
79585
  });
79676
79586
  const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
79677
79587
  screen.render(content, bottomContent);
@@ -80658,9 +80568,9 @@ var import_run_async = __toESM(require_run_async(), 1);
80658
80568
  var import_mute_stream2 = __toESM(require_lib3(), 1);
80659
80569
  var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
80660
80570
  var _2 = {
80661
- set: (obj, path61 = "", value) => {
80571
+ set: (obj, path62 = "", value) => {
80662
80572
  let pointer = obj;
80663
- path61.split(".").forEach((key, index, arr) => {
80573
+ path62.split(".").forEach((key, index, arr) => {
80664
80574
  if (key === "__proto__" || key === "constructor")
80665
80575
  return;
80666
80576
  if (index === arr.length - 1) {
@@ -80671,8 +80581,8 @@ var _2 = {
80671
80581
  pointer = pointer[key];
80672
80582
  });
80673
80583
  },
80674
- get: (obj, path61 = "", defaultValue) => {
80675
- const travel = (regexp) => String.prototype.split.call(path61, regexp).filter(Boolean).reduce(
80584
+ get: (obj, path62 = "", defaultValue) => {
80585
+ const travel = (regexp) => String.prototype.split.call(path62, regexp).filter(Boolean).reduce(
80676
80586
  // @ts-expect-error implicit any on res[key]
80677
80587
  (res, key) => res !== null && res !== void 0 ? res[key] : res,
80678
80588
  obj
@@ -80786,7 +80696,7 @@ var PromptsRunner = class {
80786
80696
  throw new Error(`Prompt for type ${question.type} not found`);
80787
80697
  }
80788
80698
  let cleanupSignal;
80789
- const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve45, reject) => {
80699
+ const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve46, reject) => {
80790
80700
  const rl = import_node_readline.default.createInterface(setupReadlineOptions(this.opt));
80791
80701
  rl.resume();
80792
80702
  const onClose = () => {
@@ -80822,7 +80732,7 @@ var PromptsRunner = class {
80822
80732
  cleanupSignal = void 0;
80823
80733
  };
80824
80734
  }
80825
- activePrompt.run().then(resolve45, reject).finally(cleanup);
80735
+ activePrompt.run().then(resolve46, reject).finally(cleanup);
80826
80736
  }) : prompt2;
80827
80737
  const { signal: moduleSignal } = this.opt;
80828
80738
  if (moduleSignal?.aborted) {
@@ -80926,12 +80836,12 @@ init_control_config();
80926
80836
  // src/core/control-sync-selection.ts
80927
80837
  var fs46 = __toESM(require("fs"));
80928
80838
  var os17 = __toESM(require("os"));
80929
- var path51 = __toESM(require("path"));
80839
+ var path52 = __toESM(require("path"));
80930
80840
  function getSelectionPath() {
80931
80841
  if (process.env.HAR_CONTROL_SYNC_SELECTION_PATH) {
80932
- return path51.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
80842
+ return path52.resolve(process.env.HAR_CONTROL_SYNC_SELECTION_PATH);
80933
80843
  }
80934
- return path51.join(os17.homedir(), ".har", "sync-selection.json");
80844
+ return path52.join(os17.homedir(), ".har", "sync-selection.json");
80935
80845
  }
80936
80846
  function readSyncSelection() {
80937
80847
  const selectionPath = getSelectionPath();
@@ -80947,7 +80857,7 @@ function readSyncSelection() {
80947
80857
  function writeSyncSelection(repos) {
80948
80858
  const selectionPath = getSelectionPath();
80949
80859
  const canonical = Array.from(new Set(repos.map((repoPath) => canonicalizeControlRepoPath(repoPath))));
80950
- fs46.mkdirSync(path51.dirname(selectionPath), { recursive: true });
80860
+ fs46.mkdirSync(path52.dirname(selectionPath), { recursive: true });
80951
80861
  fs46.writeFileSync(selectionPath, JSON.stringify({ repos: canonical }, null, 2) + "\n");
80952
80862
  }
80953
80863
  function resolveSyncSelection(input) {
@@ -80995,7 +80905,7 @@ function openBrowser(url) {
80995
80905
  }
80996
80906
  async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
80997
80907
  const state = (0, import_crypto.randomUUID)();
80998
- return new Promise((resolve45, reject) => {
80908
+ return new Promise((resolve46, reject) => {
80999
80909
  let timer;
81000
80910
  const server = http.createServer((req, res) => {
81001
80911
  const requestUrl = new URL(req.url ?? "", "http://127.0.0.1");
@@ -81018,7 +80928,7 @@ async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
81018
80928
  res.writeHead(200, { "Content-Type": "text/html" });
81019
80929
  res.end("<h1>Logged in</h1><p>You can close this tab and return to the terminal.</p>");
81020
80930
  cleanup();
81021
- resolve45({ portalUrl, token, workspace, email: email2, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
80931
+ resolve46({ portalUrl, token, workspace, email: email2, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
81022
80932
  });
81023
80933
  const cleanup = () => {
81024
80934
  clearTimeout(timer);
@@ -81046,13 +80956,13 @@ If your browser did not open, paste that URL.
81046
80956
 
81047
80957
  // src/core/control-unregister.ts
81048
80958
  var fs47 = __toESM(require("fs"));
81049
- var path52 = __toESM(require("path"));
80959
+ var path53 = __toESM(require("path"));
81050
80960
  init_control_config();
81051
80961
  function listUnregisterWorktreeCandidates(repoPath) {
81052
80962
  const harnessRoot = canonicalizeControlRepoPath(repoPath);
81053
80963
  const byPath = /* @__PURE__ */ new Map();
81054
80964
  const add = (partial2) => {
81055
- const resolved = path52.resolve(partial2.worktreePath);
80965
+ const resolved = path53.resolve(partial2.worktreePath);
81056
80966
  if (!resolved || resolved === harnessRoot) return;
81057
80967
  const exists = partial2.exists ?? fs47.existsSync(resolved);
81058
80968
  const prev = byPath.get(resolved);
@@ -81105,8 +81015,8 @@ async function askYesNo6(question) {
81105
81015
  if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
81106
81016
  const readline10 = await import("readline");
81107
81017
  const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
81108
- const answer = await new Promise((resolve45) => {
81109
- rl.question(question, resolve45);
81018
+ const answer = await new Promise((resolve46) => {
81019
+ rl.question(question, resolve46);
81110
81020
  });
81111
81021
  rl.close();
81112
81022
  return /^[Yy]$/.test(answer.trim());
@@ -81252,15 +81162,15 @@ init_control_config();
81252
81162
 
81253
81163
  // src/core/harness-scrub.ts
81254
81164
  var fs48 = __toESM(require("fs"));
81255
- var path53 = __toESM(require("path"));
81165
+ var path54 = __toESM(require("path"));
81256
81166
  var HARNESS_SCRUB_DIRS = ["runs", "validations", "state", "slots"];
81257
81167
  function scrubLocalHarnessDirs(repoPath) {
81258
81168
  const results = [];
81259
- const resolved = path53.resolve(repoPath);
81169
+ const resolved = path54.resolve(repoPath);
81260
81170
  if (!fs48.existsSync(resolved)) {
81261
81171
  for (const directory of HARNESS_SCRUB_DIRS) {
81262
81172
  results.push({
81263
- path: path53.join(resolved, ".har", directory),
81173
+ path: path54.join(resolved, ".har", directory),
81264
81174
  directory,
81265
81175
  deleted: false,
81266
81176
  error: "repository path does not exist"
@@ -81269,7 +81179,7 @@ function scrubLocalHarnessDirs(repoPath) {
81269
81179
  return results;
81270
81180
  }
81271
81181
  for (const directory of HARNESS_SCRUB_DIRS) {
81272
- const target = path53.join(resolved, ".har", directory);
81182
+ const target = path54.join(resolved, ".har", directory);
81273
81183
  if (!fs48.existsSync(target)) {
81274
81184
  results.push({ path: target, directory, deleted: true });
81275
81185
  continue;
@@ -81297,7 +81207,7 @@ function scrubLocalHarnessForRepos(repoPaths) {
81297
81207
  const results = [];
81298
81208
  const seen = /* @__PURE__ */ new Set();
81299
81209
  for (const repoPath of repoPaths) {
81300
- const key = path53.resolve(repoPath);
81210
+ const key = path54.resolve(repoPath);
81301
81211
  if (seen.has(key)) continue;
81302
81212
  seen.add(key);
81303
81213
  results.push(...scrubLocalHarnessDirs(key));
@@ -81310,8 +81220,8 @@ async function askYesNo7(question) {
81310
81220
  if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
81311
81221
  const readline10 = await import("readline");
81312
81222
  const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
81313
- const answer = await new Promise((resolve45) => {
81314
- rl.question(question, resolve45);
81223
+ const answer = await new Promise((resolve46) => {
81224
+ rl.question(question, resolve46);
81315
81225
  });
81316
81226
  rl.close();
81317
81227
  return /^[Yy]$/.test(answer.trim());
@@ -81556,7 +81466,7 @@ async function handleDown() {
81556
81466
  process.exit(code);
81557
81467
  }
81558
81468
  async function handleRegister(argv) {
81559
- const repoPath = path54.resolve(argv.repo);
81469
+ const repoPath = path55.resolve(argv.repo);
81560
81470
  header("har control register");
81561
81471
  info(`Repository: ${repoPath}`);
81562
81472
  try {
@@ -81648,7 +81558,7 @@ async function handleReset(argv) {
81648
81558
  }
81649
81559
  }
81650
81560
  async function handleUnregister(argv) {
81651
- const repoPath = path54.resolve(argv.repo);
81561
+ const repoPath = path55.resolve(argv.repo);
81652
81562
  const worktrees = listUnregisterWorktreeCandidates(repoPath);
81653
81563
  try {
81654
81564
  let deleteWorktrees = argv.deleteWorktrees;
@@ -81809,7 +81719,7 @@ async function handleWatch(argv) {
81809
81719
  };
81810
81720
  const tick = async () => {
81811
81721
  if (argv.repo) {
81812
- await syncOne(path54.resolve(argv.repo));
81722
+ await syncOne(path55.resolve(argv.repo));
81813
81723
  return;
81814
81724
  }
81815
81725
  try {
@@ -81859,11 +81769,11 @@ async function handleLogin(argv) {
81859
81769
  }
81860
81770
 
81861
81771
  // src/cli/commands/hooks.ts
81862
- var path56 = __toESM(require("path"));
81772
+ var path57 = __toESM(require("path"));
81863
81773
 
81864
81774
  // src/core/claude-hooks.ts
81865
81775
  var fs49 = __toESM(require("fs"));
81866
- var path55 = __toESM(require("path"));
81776
+ var path56 = __toESM(require("path"));
81867
81777
  var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
81868
81778
  var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
81869
81779
  var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
@@ -81884,7 +81794,7 @@ function readSettings(settingsPath) {
81884
81794
  return parsed;
81885
81795
  }
81886
81796
  function writeSettings(settingsPath, settings) {
81887
- fs49.mkdirSync(path55.dirname(settingsPath), { recursive: true });
81797
+ fs49.mkdirSync(path56.dirname(settingsPath), { recursive: true });
81888
81798
  fs49.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
81889
81799
  }
81890
81800
  function installClaudeGuard(repoPath) {
@@ -81892,11 +81802,11 @@ function installClaudeGuard(repoPath) {
81892
81802
  if (!templatePath) {
81893
81803
  throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
81894
81804
  }
81895
- const guardScript = path55.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
81896
- fs49.mkdirSync(path55.dirname(guardScript), { recursive: true });
81805
+ const guardScript = path56.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
81806
+ fs49.mkdirSync(path56.dirname(guardScript), { recursive: true });
81897
81807
  fs49.copyFileSync(templatePath, guardScript);
81898
81808
  fs49.chmodSync(guardScript, 493);
81899
- const settingsPath = path55.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
81809
+ const settingsPath = path56.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
81900
81810
  const settings = readSettings(settingsPath);
81901
81811
  const hooks = settings.hooks ?? {};
81902
81812
  const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
@@ -81910,14 +81820,14 @@ function installClaudeGuard(repoPath) {
81910
81820
  }
81911
81821
  function uninstallClaudeGuard(repoPath) {
81912
81822
  let removed = false;
81913
- const guardScript = path55.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
81823
+ const guardScript = path56.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
81914
81824
  if (fs49.existsSync(guardScript)) {
81915
81825
  fs49.rmSync(guardScript);
81916
81826
  removed = true;
81917
- const parent = path55.dirname(guardScript);
81827
+ const parent = path56.dirname(guardScript);
81918
81828
  if (fs49.existsSync(parent) && fs49.readdirSync(parent).length === 0) fs49.rmdirSync(parent);
81919
81829
  }
81920
- const settingsPath = path55.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
81830
+ const settingsPath = path56.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
81921
81831
  if (fs49.existsSync(settingsPath)) {
81922
81832
  const settings = readSettings(settingsPath);
81923
81833
  const preToolUse = settings.hooks?.PreToolUse;
@@ -81943,7 +81853,7 @@ function uninstallClaudeGuard(repoPath) {
81943
81853
  return { removed };
81944
81854
  }
81945
81855
  function claudeGuardInstalled(repoPath) {
81946
- const settingsPath = path55.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
81856
+ const settingsPath = path56.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
81947
81857
  if (!fs49.existsSync(settingsPath)) return false;
81948
81858
  try {
81949
81859
  const settings = readSettings(settingsPath);
@@ -81960,7 +81870,7 @@ function repoOption(y2) {
81960
81870
  function handleInstall2(argv) {
81961
81871
  try {
81962
81872
  if (argv.claude) {
81963
- const result2 = installClaudeGuard(path56.resolve(argv.repo));
81873
+ const result2 = installClaudeGuard(path57.resolve(argv.repo));
81964
81874
  success("Claude Code worktree guard installed.");
81965
81875
  info(`Guard script: ${result2.guardScript}`);
81966
81876
  info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
@@ -81968,7 +81878,7 @@ function handleInstall2(argv) {
81968
81878
  info("Commit both files so the guard travels with the repo.");
81969
81879
  return;
81970
81880
  }
81971
- const result = installHooks({ repoPath: path56.resolve(argv.repo), force: argv.force });
81881
+ const result = installHooks({ repoPath: path57.resolve(argv.repo), force: argv.force });
81972
81882
  success(`Commit gate installed in ${result.hooksDir}`);
81973
81883
  info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
81974
81884
  info("Commits of unverified change batches will be blocked in agent worktrees.");
@@ -81981,7 +81891,7 @@ function handleInstall2(argv) {
81981
81891
  function handleUninstall(argv) {
81982
81892
  try {
81983
81893
  if (argv.claude) {
81984
- const result2 = uninstallClaudeGuard(path56.resolve(argv.repo));
81894
+ const result2 = uninstallClaudeGuard(path57.resolve(argv.repo));
81985
81895
  if (result2.removed) {
81986
81896
  success("Claude Code worktree guard removed.");
81987
81897
  } else {
@@ -81989,7 +81899,7 @@ function handleUninstall(argv) {
81989
81899
  }
81990
81900
  return;
81991
81901
  }
81992
- const result = uninstallHooks(path56.resolve(argv.repo));
81902
+ const result = uninstallHooks(path57.resolve(argv.repo));
81993
81903
  if (result.removed) {
81994
81904
  success(`Commit gate removed from ${result.hooksDir}`);
81995
81905
  } else {
@@ -82002,7 +81912,7 @@ function handleUninstall(argv) {
82002
81912
  }
82003
81913
  function handleStatus2(argv) {
82004
81914
  try {
82005
- const status = getHooksStatus(path56.resolve(argv.repo));
81915
+ const status = getHooksStatus(path57.resolve(argv.repo));
82006
81916
  if (argv.json) {
82007
81917
  process.stdout.write(`${JSON.stringify(status, null, 2)}
82008
81918
  `);
@@ -82020,7 +81930,7 @@ function handleStatus2(argv) {
82020
81930
  );
82021
81931
  info(`Effective: ${status.effectiveMode} (in this checkout)`);
82022
81932
  info(
82023
- `Claude guard: ${claudeGuardInstalled(path56.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
81933
+ `Claude guard: ${claudeGuardInstalled(path57.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
82024
81934
  );
82025
81935
  } catch (err) {
82026
81936
  error(err instanceof Error ? err.message : String(err));
@@ -82281,10 +82191,10 @@ function assignProp(target, prop, value) {
82281
82191
  configurable: true
82282
82192
  });
82283
82193
  }
82284
- function getElementAtPath(obj, path61) {
82285
- if (!path61)
82194
+ function getElementAtPath(obj, path62) {
82195
+ if (!path62)
82286
82196
  return obj;
82287
- return path61.reduce((acc, key) => acc?.[key], obj);
82197
+ return path62.reduce((acc, key) => acc?.[key], obj);
82288
82198
  }
82289
82199
  function promiseAllObject(promisesObj) {
82290
82200
  const keys = Object.keys(promisesObj);
@@ -82604,11 +82514,11 @@ function aborted(x2, startIndex = 0) {
82604
82514
  }
82605
82515
  return false;
82606
82516
  }
82607
- function prefixIssues(path61, issues) {
82517
+ function prefixIssues(path62, issues) {
82608
82518
  return issues.map((iss) => {
82609
82519
  var _a3;
82610
82520
  (_a3 = iss).path ?? (_a3.path = []);
82611
- iss.path.unshift(path61);
82521
+ iss.path.unshift(path62);
82612
82522
  return iss;
82613
82523
  });
82614
82524
  }
@@ -87931,7 +87841,7 @@ var Protocol = class {
87931
87841
  return;
87932
87842
  }
87933
87843
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
87934
- await new Promise((resolve45) => setTimeout(resolve45, pollInterval));
87844
+ await new Promise((resolve46) => setTimeout(resolve46, pollInterval));
87935
87845
  options?.signal?.throwIfAborted();
87936
87846
  }
87937
87847
  } catch (error3) {
@@ -87948,7 +87858,7 @@ var Protocol = class {
87948
87858
  */
87949
87859
  request(request, resultSchema, options) {
87950
87860
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
87951
- return new Promise((resolve45, reject) => {
87861
+ return new Promise((resolve46, reject) => {
87952
87862
  const earlyReject = (error3) => {
87953
87863
  reject(error3);
87954
87864
  };
@@ -88026,7 +87936,7 @@ var Protocol = class {
88026
87936
  if (!parseResult.success) {
88027
87937
  reject(parseResult.error);
88028
87938
  } else {
88029
- resolve45(parseResult.data);
87939
+ resolve46(parseResult.data);
88030
87940
  }
88031
87941
  } catch (error3) {
88032
87942
  reject(error3);
@@ -88287,12 +88197,12 @@ var Protocol = class {
88287
88197
  }
88288
88198
  } catch {
88289
88199
  }
88290
- return new Promise((resolve45, reject) => {
88200
+ return new Promise((resolve46, reject) => {
88291
88201
  if (signal.aborted) {
88292
88202
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
88293
88203
  return;
88294
88204
  }
88295
- const timeoutId = setTimeout(resolve45, interval);
88205
+ const timeoutId = setTimeout(resolve46, interval);
88296
88206
  signal.addEventListener("abort", () => {
88297
88207
  clearTimeout(timeoutId);
88298
88208
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -89082,7 +88992,7 @@ var Server = class extends Protocol {
89082
88992
  };
89083
88993
 
89084
88994
  // src/mcp/server.ts
89085
- var path57 = __toESM(require("path"));
88995
+ var path58 = __toESM(require("path"));
89086
88996
 
89087
88997
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
89088
88998
  var import_node_process3 = __toESM(require("node:process"), 1);
@@ -89165,12 +89075,12 @@ var StdioServerTransport = class {
89165
89075
  this.onclose?.();
89166
89076
  }
89167
89077
  send(message) {
89168
- return new Promise((resolve45) => {
89078
+ return new Promise((resolve46) => {
89169
89079
  const json = serializeMessage(message);
89170
89080
  if (this._stdout.write(json)) {
89171
- resolve45();
89081
+ resolve46();
89172
89082
  } else {
89173
- this._stdout.once("drain", resolve45);
89083
+ this._stdout.once("drain", resolve46);
89174
89084
  }
89175
89085
  });
89176
89086
  }
@@ -89250,13 +89160,9 @@ var LaunchEnvironmentInputSchema = external_exports.object({
89250
89160
  agentId: agentIdSchema,
89251
89161
  worktree: external_exports.boolean().default(true),
89252
89162
  claude: external_exports.boolean().default(false),
89253
- confirmReplace: external_exports.boolean().default(false).describe(
89254
- "Destroy the previous session on this slot and start another from main-checkout HEAD. Does not choose main. Prefer complete/teardown when the prior task is finished. Call har_get_status first; get explicit user approval."
89255
- ),
89256
- force: external_exports.boolean().default(false).describe(
89257
- "Discard uncommitted changes in a dirty occupied worktree. Requires confirmReplace=true and explicit user approval \u2014 never set autonomously."
89163
+ resume: external_exports.boolean().default(false).describe(
89164
+ "Resume a failed or partial launch without creating a new worktree. Only valid for failed/starting sessions \u2014 otherwise call har_get_status, then har_complete_environment or har_teardown_environment before launching again."
89258
89165
  ),
89259
- resume: external_exports.boolean().default(false).describe("Resume a failed or partial launch without creating a new worktree."),
89260
89166
  workUnitId: external_exports.string().min(1).max(128).optional(),
89261
89167
  source: external_exports.string().min(1).max(64).optional(),
89262
89168
  sourceUrl: external_exports.string().url().optional(),
@@ -89282,9 +89188,7 @@ var LaunchEnvironmentOutputSchema = ShellRunOutputSchema.extend({
89282
89188
  });
89283
89189
  var PreflightEnvironmentInputSchema = external_exports.object({
89284
89190
  repo: external_exports.string().default("."),
89285
- agentId: agentIdSchema,
89286
- confirmReplace: external_exports.boolean().default(false).describe("Treat an occupied slot as replaceable (same as launch confirmReplace)."),
89287
- force: external_exports.boolean().default(false).describe("Allow replacing a dirty worktree (requires explicit user approval).")
89191
+ agentId: agentIdSchema
89288
89192
  });
89289
89193
  var PreflightEnvironmentOutputSchema = ShellRunOutputSchema.extend({
89290
89194
  readiness: SlotReadinessSchema,
@@ -89384,24 +89288,16 @@ var HAR_MCP_TOOLS = [
89384
89288
  },
89385
89289
  {
89386
89290
  name: "har_launch_environment",
89387
- description: "Start a FRESH agent session from the main checkout HEAD (switch that checkout to main first for a new unrelated task). Run BEFORE editing any file: returns workDir \u2014 ALL edits go there, never the main checkout. Prefer har_complete_environment / har_teardown_environment when a prior task is done. Occupied slots block until confirmReplace=true (does NOT choose main). force=true discards dirty work \u2014 never set without user approval. Failed launches: resume=true / har_recover_environment.",
89291
+ description: "Start a FRESH agent session from the main checkout HEAD (switch that checkout to main first for a new unrelated task). Run BEFORE editing any file: returns workDir \u2014 ALL edits go there, never the main checkout. Occupied slots always block: call har_get_status, then har_complete_environment or har_teardown_environment, then relaunch \u2014 unless the session is failed/starting, in which case pass resume=true (or use har_recover_environment).",
89388
89292
  inputSchema: objectJsonSchema(
89389
89293
  {
89390
89294
  repo: repoJsonProperty,
89391
89295
  agentId: agentIdJsonProperty,
89392
89296
  worktree: { type: "boolean" },
89393
89297
  claude: { type: "boolean" },
89394
- confirmReplace: {
89395
- type: "boolean",
89396
- description: "Destroy the previous session on this slot and start another from main-checkout HEAD. Does not choose main. Prefer complete/teardown when the prior task is finished. Call har_get_status first; get explicit user approval."
89397
- },
89398
- force: {
89399
- type: "boolean",
89400
- description: "Discard uncommitted changes when replacing a dirty worktree. Requires confirmReplace=true and explicit user approval."
89401
- },
89402
89298
  resume: {
89403
89299
  type: "boolean",
89404
- description: "Resume a failed or partial launch (status failed/starting) without confirmReplace. Preserves worktree and env."
89300
+ description: "Resume a failed or partial launch (status failed/starting) without creating a new worktree. Preserves worktree and env. Not usable to replace an active/completed slot \u2014 free it with har_complete_environment or har_teardown_environment first."
89405
89301
  },
89406
89302
  workUnitId: {
89407
89303
  type: "string",
@@ -89435,15 +89331,7 @@ var HAR_MCP_TOOLS = [
89435
89331
  inputSchema: objectJsonSchema(
89436
89332
  {
89437
89333
  repo: repoJsonProperty,
89438
- agentId: agentIdJsonProperty,
89439
- confirmReplace: {
89440
- type: "boolean",
89441
- description: "Treat an occupied slot as replaceable (same as launch confirmReplace)."
89442
- },
89443
- force: {
89444
- type: "boolean",
89445
- description: "Allow replacing a dirty worktree (only after explicit user approval)."
89446
- }
89334
+ agentId: agentIdJsonProperty
89447
89335
  },
89448
89336
  ["agentId"]
89449
89337
  )
@@ -89577,7 +89465,6 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
89577
89465
  smoke: input.smoke,
89578
89466
  profile: input.profile
89579
89467
  });
89580
- recordRepoForControlSync(repo);
89581
89468
  return jsonContent({
89582
89469
  harnessDir: result.harnessDir,
89583
89470
  validation: result.validation,
@@ -89593,8 +89480,6 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
89593
89480
  agentId,
89594
89481
  worktree: input.worktree,
89595
89482
  claude: input.claude,
89596
- confirmReplace: input.confirmReplace,
89597
- force: input.force,
89598
89483
  resume: input.resume,
89599
89484
  workUnitId: input.workUnitId,
89600
89485
  source: input.source,
@@ -89617,8 +89502,6 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
89617
89502
  agentId,
89618
89503
  worktree: input.worktree,
89619
89504
  claude: input.claude,
89620
- confirmReplace: false,
89621
- force: false,
89622
89505
  resume: true,
89623
89506
  workUnitId: input.workUnitId,
89624
89507
  source: input.source,
@@ -89638,9 +89521,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
89638
89521
  const agentId = validateAgentId(input.agentId, repo);
89639
89522
  const result = await preflightEnvironment({
89640
89523
  repoPath: repo,
89641
- agentId,
89642
- confirmReplace: input.confirmReplace,
89643
- force: input.force
89524
+ agentId
89644
89525
  });
89645
89526
  const parsed = PreflightEnvironmentOutputSchema.parse(result);
89646
89527
  return {
@@ -89745,7 +89626,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
89745
89626
  const input = ControlUpInputSchema.parse({ ...args, repo });
89746
89627
  const result = await startControlAndSync({
89747
89628
  detach: input.detach,
89748
- cwd: path57.resolve(input.repo)
89629
+ cwd: path58.resolve(input.repo)
89749
89630
  });
89750
89631
  if (result.code !== 0) {
89751
89632
  return {
@@ -89809,10 +89690,10 @@ var mcpCommand = {
89809
89690
  };
89810
89691
 
89811
89692
  // src/cli/commands/onboard.ts
89812
- var path59 = __toESM(require("path"));
89693
+ var path60 = __toESM(require("path"));
89813
89694
 
89814
89695
  // src/core/onboarding.ts
89815
- var path58 = __toESM(require("path"));
89696
+ var path59 = __toESM(require("path"));
89816
89697
  init_control_config();
89817
89698
  init_otel_hooks();
89818
89699
  init_telemetry_config();
@@ -89944,7 +89825,7 @@ async function defaultEnsureControl(options) {
89944
89825
  return { started: true, apiUrl: result.apiUrl };
89945
89826
  }
89946
89827
  async function runOnboarding(options, deps = {}) {
89947
- const repoPath = path58.resolve(options.repoPath);
89828
+ const repoPath = path59.resolve(options.repoPath);
89948
89829
  const applyTelemetry = deps.applyTelemetry ?? applyOnboardingTelemetry;
89949
89830
  const ensureControl = deps.ensureControl ?? defaultEnsureControl;
89950
89831
  const init = deps.initHarness ?? initHarness;
@@ -89977,9 +89858,20 @@ async function runOnboarding(options, deps = {}) {
89977
89858
  warn("Harness has validation errors \u2014 review .har/ after adaptation.");
89978
89859
  }
89979
89860
  harnessInitialized = true;
89980
- recordRepoForControlSync(repoPath);
89981
89861
  success("Harness scaffolded");
89982
89862
  }
89863
+ let agentSlots = null;
89864
+ if (harnessExists(repoPath)) {
89865
+ if (options.agentSlotsMax !== void 0) {
89866
+ applyAgentSlotMax(repoPath, options.agentSlotsMax);
89867
+ info(`Agent slots: 1\u2013${options.agentSlotsMax} parallel (written to .har/stages.json)`);
89868
+ }
89869
+ try {
89870
+ agentSlots = getAgentSlotRange(repoPath);
89871
+ } catch {
89872
+ agentSlots = null;
89873
+ }
89874
+ }
89983
89875
  const pluginsApplied = [];
89984
89876
  const pluginWarnings = [];
89985
89877
  if (options.plugins.length > 0) {
@@ -90028,7 +89920,8 @@ async function runOnboarding(options, deps = {}) {
90028
89920
  pluginsApplied,
90029
89921
  pluginWarnings,
90030
89922
  adaptationPromptPath,
90031
- adaptationPromptCopied
89923
+ adaptationPromptCopied,
89924
+ agentSlots
90032
89925
  };
90033
89926
  }
90034
89927
  async function finalizeOnboardingAdaptation(options) {
@@ -90059,6 +89952,27 @@ function parsePluginsFlag(raw) {
90059
89952
  }
90060
89953
  return selected;
90061
89954
  }
89955
+ function defaultAgentSlotMaxForProfile(profile) {
89956
+ return profile === "default" ? 5 : 3;
89957
+ }
89958
+ function parseAgentSlotsFlag(raw) {
89959
+ if (raw === void 0) return void 0;
89960
+ if (!Number.isInteger(raw) || raw < HAR_AGENT_SLOT_MIN || raw > HAR_AGENT_SLOT_ONBOARD_MAX) {
89961
+ throw new Error(
89962
+ `--agent-slots must be an integer from ${HAR_AGENT_SLOT_MIN} to ${HAR_AGENT_SLOT_ONBOARD_MAX}`
89963
+ );
89964
+ }
89965
+ return raw;
89966
+ }
89967
+ function resolveDefaultAgentSlotsMax(repoPath, profile, alreadyPresent) {
89968
+ if (alreadyPresent) {
89969
+ try {
89970
+ return getAgentSlotRange(repoPath).max;
89971
+ } catch {
89972
+ }
89973
+ }
89974
+ return defaultAgentSlotMaxForProfile(profile);
89975
+ }
90062
89976
  async function pauseForGuide(autoYes) {
90063
89977
  if (autoYes || !process.stdin.isTTY || !process.stdout.isTTY) return;
90064
89978
  await esm_default13.prompt([
@@ -90070,20 +89984,23 @@ async function pauseForGuide(autoYes) {
90070
89984
  ]);
90071
89985
  }
90072
89986
  async function promptChoices(args) {
89987
+ const flaggedSlots = parseAgentSlotsFlag(args.agentSlots);
89988
+ const shouldConfigureSlots = !args.skipInit;
90073
89989
  if (args.yes) {
90074
89990
  const telemetry2 = args.telemetry ?? "on";
90075
89991
  return {
90076
89992
  profile: args.profile ?? "default",
90077
89993
  telemetry: telemetry2,
90078
89994
  startControl: args.control ?? telemetry2 !== "off",
90079
- plugins: parsePluginsFlag(args.plugins) ?? []
89995
+ plugins: parsePluginsFlag(args.plugins) ?? [],
89996
+ agentSlotsMax: shouldConfigureSlots ? flaggedSlots : void 0
90080
89997
  };
90081
89998
  }
90082
89999
  const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY);
90083
90000
  if (!interactive) {
90084
- if (args.telemetry === void 0 && args.control === void 0 && args.plugins === void 0 && args.profile === void 0) {
90001
+ if (args.telemetry === void 0 && args.control === void 0 && args.plugins === void 0 && args.profile === void 0 && args.agentSlots === void 0) {
90085
90002
  throw new Error(
90086
- "Interactive onboarding requires a TTY. Pass --yes or flags (--profile, --telemetry, --control/--no-control, --plugins)."
90003
+ "Interactive onboarding requires a TTY. Pass --yes or flags (--profile, --telemetry, --control/--no-control, --plugins, --agent-slots)."
90087
90004
  );
90088
90005
  }
90089
90006
  const telemetry2 = args.telemetry ?? "on";
@@ -90091,12 +90008,20 @@ async function promptChoices(args) {
90091
90008
  profile: args.profile ?? "default",
90092
90009
  telemetry: telemetry2,
90093
90010
  startControl: args.control ?? telemetry2 !== "off",
90094
- plugins: parsePluginsFlag(args.plugins) ?? []
90011
+ plugins: parsePluginsFlag(args.plugins) ?? [],
90012
+ agentSlotsMax: shouldConfigureSlots ? flaggedSlots : void 0
90095
90013
  };
90096
90014
  }
90097
90015
  const pluginChoices = listPluginChoices();
90098
- const alreadyPresent = harnessExists(path59.resolve(args.repo));
90016
+ const repoPath = path60.resolve(args.repo);
90017
+ const alreadyPresent = harnessExists(repoPath);
90099
90018
  const needProfile = !alreadyPresent && !args.skipInit && args.profile === void 0;
90019
+ const needAgentSlots = shouldConfigureSlots && flaggedSlots === void 0;
90020
+ if (needAgentSlots) {
90021
+ info(
90022
+ "Each parallel slot runs an isolated copy of the stack. The practical limit depends on your machine resources (RAM/CPU) and how expensive the stack is to run (Docker services, databases, frontends, etc.). You can change this later in .har/stages.json."
90023
+ );
90024
+ }
90100
90025
  const answers = await esm_default13.prompt([
90101
90026
  {
90102
90027
  type: "list",
@@ -90138,14 +90063,37 @@ async function promptChoices(args) {
90138
90063
  name: plugin.label,
90139
90064
  value: plugin.id
90140
90065
  }))
90066
+ },
90067
+ {
90068
+ type: "number",
90069
+ name: "agentSlotsMax",
90070
+ message: `How many agents do you want to run in parallel? (${HAR_AGENT_SLOT_MIN}\u2013${HAR_AGENT_SLOT_ONBOARD_MAX})`,
90071
+ when: () => needAgentSlots,
90072
+ default: (current) => resolveDefaultAgentSlotsMax(
90073
+ repoPath,
90074
+ args.profile ?? current.profile ?? "default",
90075
+ alreadyPresent
90076
+ ),
90077
+ validate: (value) => {
90078
+ if (value === void 0 || !Number.isInteger(value) || value < HAR_AGENT_SLOT_MIN || value > HAR_AGENT_SLOT_ONBOARD_MAX) {
90079
+ return `Enter an integer from ${HAR_AGENT_SLOT_MIN} to ${HAR_AGENT_SLOT_ONBOARD_MAX}`;
90080
+ }
90081
+ return true;
90082
+ }
90141
90083
  }
90142
90084
  ]);
90143
90085
  const telemetry = args.telemetry ?? answers.telemetry ?? "on";
90086
+ const profile = args.profile ?? answers.profile ?? "default";
90087
+ let agentSlotsMax;
90088
+ if (shouldConfigureSlots) {
90089
+ agentSlotsMax = flaggedSlots ?? answers.agentSlotsMax;
90090
+ }
90144
90091
  return {
90145
- profile: args.profile ?? answers.profile ?? "default",
90092
+ profile,
90146
90093
  telemetry,
90147
90094
  startControl: args.control ?? answers.startControl ?? telemetry !== "off",
90148
- plugins: parsePluginsFlag(args.plugins) ?? answers.plugins ?? []
90095
+ plugins: parsePluginsFlag(args.plugins) ?? answers.plugins ?? [],
90096
+ agentSlotsMax
90149
90097
  };
90150
90098
  }
90151
90099
  function printSummary(result) {
@@ -90162,6 +90110,11 @@ function printSummary(result) {
90162
90110
  info(
90163
90111
  `Plugins: ${result.pluginsApplied.length > 0 ? result.pluginsApplied.join(", ") : "none"}`
90164
90112
  );
90113
+ if (result.agentSlots) {
90114
+ info(
90115
+ `Agent slots: ${result.agentSlots.min}\u2013${result.agentSlots.max} parallel (see .har/stages.json)`
90116
+ );
90117
+ }
90165
90118
  if (result.adaptationPromptPath) {
90166
90119
  info(`Adapt prompt: ${result.adaptationPromptPath}`);
90167
90120
  info(
@@ -90177,7 +90130,7 @@ function printSummary(result) {
90177
90130
  console.error("");
90178
90131
  }
90179
90132
  async function handleOnboard(argv) {
90180
- const repoPath = path59.resolve(argv.repo);
90133
+ const repoPath = path60.resolve(argv.repo);
90181
90134
  header("har onboard");
90182
90135
  info(`Repository: ${repoPath}`);
90183
90136
  try {
@@ -90198,7 +90151,8 @@ async function handleOnboard(argv) {
90198
90151
  skipInit: argv.skipInit,
90199
90152
  deferAdaptationPrompt: true,
90200
90153
  autoYes: argv.yes,
90201
- forcePlugins: argv.force
90154
+ forcePlugins: argv.force,
90155
+ agentSlotsMax: choices.agentSlotsMax
90202
90156
  });
90203
90157
  if (result.harnessInitialized || harnessExists(repoPath)) {
90204
90158
  await handleCommitGateOnboarding({
@@ -90261,6 +90215,9 @@ var onboardCommand = {
90261
90215
  }).option("plugins", {
90262
90216
  type: "string",
90263
90217
  describe: "Comma-separated plugins to install (e.g. playwright); --no-plugins to skip; interactive checkbox when omitted"
90218
+ }).option("agent-slots", {
90219
+ type: "number",
90220
+ describe: `Max parallel agent slots to configure in .har/stages.json (${HAR_AGENT_SLOT_MIN}\u2013${HAR_AGENT_SLOT_ONBOARD_MAX})`
90264
90221
  }).option("skip-guide", {
90265
90222
  type: "boolean",
90266
90223
  default: false,
@@ -90408,7 +90365,7 @@ var preferencesCommand = {
90408
90365
  };
90409
90366
 
90410
90367
  // src/cli/commands/telemetry.ts
90411
- var path60 = __toESM(require("path"));
90368
+ var path61 = __toESM(require("path"));
90412
90369
  init_control_config();
90413
90370
  init_otel_hooks();
90414
90371
  init_telemetry_config();
@@ -90496,7 +90453,7 @@ async function handleOff() {
90496
90453
  info("Mission Control will not auto-start. Existing usage rows are kept.");
90497
90454
  }
90498
90455
  async function handleWriteEnv(argv) {
90499
- const repoPath = path60.resolve(argv.repo);
90456
+ const repoPath = path61.resolve(argv.repo);
90500
90457
  const harnessRoot = resolveHarnessRoot(repoPath);
90501
90458
  const session = readSlotRegistry(harnessRoot, argv.agentId);
90502
90459
  const workDir = argv.workDir ?? session?.workDir ?? repoPath;
@@ -90508,7 +90465,7 @@ async function handleWriteEnv(argv) {
90508
90465
  suffix,
90509
90466
  createdAt: session?.createdAt
90510
90467
  });
90511
- const envFile = argv.envFile ?? path60.join(workDir, `.env.agent.${argv.agentId}`);
90468
+ const envFile = argv.envFile ?? path61.join(workDir, `.env.agent.${argv.agentId}`);
90512
90469
  const attrs = {
90513
90470
  sessionKey,
90514
90471
  agentId: argv.agentId,
@@ -90524,7 +90481,7 @@ async function handleWriteEnv(argv) {
90524
90481
  success(`Wrote session attribution to ${envFile}`);
90525
90482
  }
90526
90483
  function handlePrintEnv(argv) {
90527
- const repoPath = path60.resolve(argv.repo);
90484
+ const repoPath = path61.resolve(argv.repo);
90528
90485
  const workDir = argv.workDir ?? repoPath;
90529
90486
  const sessionKey = buildSessionKey({
90530
90487
  branch: argv.branch,