@osfactory/har 0.22.0 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +39 -254
  2. package/dist/index.js +716 -322
  3. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -765,14 +765,14 @@ var require_url_state_machine = __commonJS({
765
765
  return url.replace(/\u0009|\u000A|\u000D/g, "");
766
766
  }
767
767
  function shortenPath(url) {
768
- const path54 = url.path;
769
- if (path54.length === 0) {
768
+ const path55 = url.path;
769
+ if (path55.length === 0) {
770
770
  return;
771
771
  }
772
- if (url.scheme === "file" && path54.length === 1 && isNormalizedWindowsDriveLetter(path54[0])) {
772
+ if (url.scheme === "file" && path55.length === 1 && isNormalizedWindowsDriveLetter(path55[0])) {
773
773
  return;
774
774
  }
775
- path54.pop();
775
+ path55.pop();
776
776
  }
777
777
  function includesCredentials(url) {
778
778
  return url.username !== "" || url.password !== "";
@@ -2092,7 +2092,7 @@ var require_lib2 = __commonJS({
2092
2092
  let accum = [];
2093
2093
  let accumBytes = 0;
2094
2094
  let abort = false;
2095
- return new Body.Promise(function(resolve38, reject) {
2095
+ return new Body.Promise(function(resolve39, reject) {
2096
2096
  let resTimeout;
2097
2097
  if (_this4.timeout) {
2098
2098
  resTimeout = setTimeout(function() {
@@ -2126,7 +2126,7 @@ var require_lib2 = __commonJS({
2126
2126
  }
2127
2127
  clearTimeout(resTimeout);
2128
2128
  try {
2129
- resolve38(Buffer.concat(accum, accumBytes));
2129
+ resolve39(Buffer.concat(accum, accumBytes));
2130
2130
  } catch (err) {
2131
2131
  reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, "system", err));
2132
2132
  }
@@ -2801,7 +2801,7 @@ var require_lib2 = __commonJS({
2801
2801
  throw new Error("native promise missing, set fetch.Promise to your favorite alternative");
2802
2802
  }
2803
2803
  Body.Promise = fetch3.Promise;
2804
- return new fetch3.Promise(function(resolve38, reject) {
2804
+ return new fetch3.Promise(function(resolve39, reject) {
2805
2805
  const request = new Request3(url, opts);
2806
2806
  const options = getNodeRequestOptions(request);
2807
2807
  const send = (options.protocol === "https:" ? https : http2).request;
@@ -2934,7 +2934,7 @@ var require_lib2 = __commonJS({
2934
2934
  requestOpts.body = void 0;
2935
2935
  requestOpts.headers.delete("content-length");
2936
2936
  }
2937
- resolve38(fetch3(new Request3(locationURL, requestOpts)));
2937
+ resolve39(fetch3(new Request3(locationURL, requestOpts)));
2938
2938
  finalize();
2939
2939
  return;
2940
2940
  }
@@ -2955,7 +2955,7 @@ var require_lib2 = __commonJS({
2955
2955
  const codings = headers.get("Content-Encoding");
2956
2956
  if (!request.compress || request.method === "HEAD" || codings === null || res.statusCode === 204 || res.statusCode === 304) {
2957
2957
  response = new Response3(body, response_options);
2958
- resolve38(response);
2958
+ resolve39(response);
2959
2959
  return;
2960
2960
  }
2961
2961
  const zlibOptions = {
@@ -2965,7 +2965,7 @@ var require_lib2 = __commonJS({
2965
2965
  if (codings == "gzip" || codings == "x-gzip") {
2966
2966
  body = body.pipe(zlib.createGunzip(zlibOptions));
2967
2967
  response = new Response3(body, response_options);
2968
- resolve38(response);
2968
+ resolve39(response);
2969
2969
  return;
2970
2970
  }
2971
2971
  if (codings == "deflate" || codings == "x-deflate") {
@@ -2977,12 +2977,12 @@ var require_lib2 = __commonJS({
2977
2977
  body = body.pipe(zlib.createInflateRaw());
2978
2978
  }
2979
2979
  response = new Response3(body, response_options);
2980
- resolve38(response);
2980
+ resolve39(response);
2981
2981
  });
2982
2982
  raw.on("end", function() {
2983
2983
  if (!response) {
2984
2984
  response = new Response3(body, response_options);
2985
- resolve38(response);
2985
+ resolve39(response);
2986
2986
  }
2987
2987
  });
2988
2988
  return;
@@ -2990,11 +2990,11 @@ var require_lib2 = __commonJS({
2990
2990
  if (codings == "br" && typeof zlib.createBrotliDecompress === "function") {
2991
2991
  body = body.pipe(zlib.createBrotliDecompress());
2992
2992
  response = new Response3(body, response_options);
2993
- resolve38(response);
2993
+ resolve39(response);
2994
2994
  return;
2995
2995
  }
2996
2996
  response = new Response3(body, response_options);
2997
- resolve38(response);
2997
+ resolve39(response);
2998
2998
  });
2999
2999
  writeToStream(req, request);
3000
3000
  });
@@ -6351,14 +6351,14 @@ __export(fileFromPath_exports, {
6351
6351
  fileFromPathSync: () => fileFromPathSync,
6352
6352
  isFile: () => isFile
6353
6353
  });
6354
- function createFileFromPath(path54, { mtimeMs, size }, filenameOrOptions, options = {}) {
6354
+ function createFileFromPath(path55, { mtimeMs, size }, filenameOrOptions, options = {}) {
6355
6355
  let filename;
6356
6356
  if (isPlainObject_default2(filenameOrOptions)) {
6357
6357
  [options, filename] = [filenameOrOptions, void 0];
6358
6358
  } else {
6359
6359
  filename = filenameOrOptions;
6360
6360
  }
6361
- const file = new FileFromPath({ path: path54, size, lastModified: mtimeMs });
6361
+ const file = new FileFromPath({ path: path55, size, lastModified: mtimeMs });
6362
6362
  if (!filename) {
6363
6363
  filename = file.name;
6364
6364
  }
@@ -6367,13 +6367,13 @@ function createFileFromPath(path54, { mtimeMs, size }, filenameOrOptions, option
6367
6367
  lastModified: file.lastModified
6368
6368
  });
6369
6369
  }
6370
- function fileFromPathSync(path54, filenameOrOptions, options = {}) {
6371
- const stats = (0, import_fs5.statSync)(path54);
6372
- return createFileFromPath(path54, stats, filenameOrOptions, options);
6370
+ function fileFromPathSync(path55, filenameOrOptions, options = {}) {
6371
+ const stats = (0, import_fs5.statSync)(path55);
6372
+ return createFileFromPath(path55, stats, filenameOrOptions, options);
6373
6373
  }
6374
- async function fileFromPath2(path54, filenameOrOptions, options) {
6375
- const stats = await import_fs5.promises.stat(path54);
6376
- return createFileFromPath(path54, stats, filenameOrOptions, options);
6374
+ async function fileFromPath2(path55, filenameOrOptions, options) {
6375
+ const stats = await import_fs5.promises.stat(path55);
6376
+ return createFileFromPath(path55, stats, filenameOrOptions, options);
6377
6377
  }
6378
6378
  var import_fs5, import_path5, import_node_domexception, __classPrivateFieldSet5, __classPrivateFieldGet6, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
6379
6379
  var init_fileFromPath = __esm({
@@ -6449,6 +6449,7 @@ function readPortalCredentials() {
6449
6449
  portalUrl: parsed.portalUrl,
6450
6450
  token: parsed.token,
6451
6451
  workspace: parsed.workspace,
6452
+ email: parsed.email,
6452
6453
  createdAt: parsed.createdAt ?? ""
6453
6454
  };
6454
6455
  } catch {
@@ -6624,15 +6625,15 @@ __export(otel_hooks_exports, {
6624
6625
  });
6625
6626
  function getOtelHooksHome() {
6626
6627
  if (process.env.HAR_OTEL_HOOKS_HOME) {
6627
- return path43.resolve(process.env.HAR_OTEL_HOOKS_HOME);
6628
+ return path44.resolve(process.env.HAR_OTEL_HOOKS_HOME);
6628
6629
  }
6629
- return path43.join(os13.homedir(), ".har", "otel-hooks");
6630
+ return path44.join(os13.homedir(), ".har", "otel-hooks");
6630
6631
  }
6631
6632
  function getOtelHooksConfigPath(hooksHome = getOtelHooksHome()) {
6632
- return path43.join(hooksHome, "otel_config.json");
6633
+ return path44.join(hooksHome, "otel_config.json");
6633
6634
  }
6634
6635
  function getOtelHooksWrapperPath(hooksHome = getOtelHooksHome()) {
6635
- return path43.join(hooksHome, "run-otel-hook.sh");
6636
+ return path44.join(hooksHome, "run-otel-hook.sh");
6636
6637
  }
6637
6638
  function buildOtelHooksConfig(options) {
6638
6639
  const enabled = options?.enabled ?? isTelemetryEnabled();
@@ -6677,22 +6678,22 @@ exec "${otelHookCommand}" "$@"
6677
6678
  }
6678
6679
  return wrapperPath;
6679
6680
  }
6680
- function commandExists(command2) {
6681
- const result = (0, import_child_process9.spawnSync)("sh", ["-c", `command -v ${JSON.stringify(command2)}`], {
6681
+ function commandExists2(command2) {
6682
+ const result = (0, import_child_process10.spawnSync)("sh", ["-c", `command -v ${JSON.stringify(command2)}`], {
6682
6683
  encoding: "utf8"
6683
6684
  });
6684
6685
  return result.status === 0 && Boolean(result.stdout?.trim());
6685
6686
  }
6686
6687
  function resolveOtelHookCommand() {
6687
- if (commandExists("otel-hook")) {
6688
- const which = (0, import_child_process9.spawnSync)("sh", ["-c", "command -v otel-hook"], { encoding: "utf8" });
6688
+ if (commandExists2("otel-hook")) {
6689
+ const which = (0, import_child_process10.spawnSync)("sh", ["-c", "command -v otel-hook"], { encoding: "utf8" });
6689
6690
  return which.stdout?.trim() || "otel-hook";
6690
6691
  }
6691
6692
  return null;
6692
6693
  }
6693
6694
  function tryInstallPackage() {
6694
- if (commandExists("uv")) {
6695
- const result = (0, import_child_process9.spawnSync)(
6695
+ if (commandExists2("uv")) {
6696
+ const result = (0, import_child_process10.spawnSync)(
6696
6697
  "uv",
6697
6698
  ["tool", "install", "--force", OTEL_HOOKS_PACKAGE],
6698
6699
  { encoding: "utf8", timeout: 18e4 }
@@ -6701,8 +6702,8 @@ function tryInstallPackage() {
6701
6702
  return { ok: true, detail: `uv tool install ${OTEL_HOOKS_PACKAGE}` };
6702
6703
  }
6703
6704
  }
6704
- if (commandExists("pipx")) {
6705
- const result = (0, import_child_process9.spawnSync)("pipx", ["install", "--force", OTEL_HOOKS_PACKAGE], {
6705
+ if (commandExists2("pipx")) {
6706
+ const result = (0, import_child_process10.spawnSync)("pipx", ["install", "--force", OTEL_HOOKS_PACKAGE], {
6706
6707
  encoding: "utf8",
6707
6708
  timeout: 18e4
6708
6709
  });
@@ -6714,9 +6715,9 @@ function tryInstallPackage() {
6714
6715
  detail: `pipx install failed: ${(result.stderr || result.stdout || "").trim().slice(0, 400)}`
6715
6716
  };
6716
6717
  }
6717
- if (commandExists("pip3") || commandExists("pip")) {
6718
- const pip = commandExists("pip3") ? "pip3" : "pip";
6719
- const result = (0, import_child_process9.spawnSync)(
6718
+ if (commandExists2("pip3") || commandExists2("pip")) {
6719
+ const pip = commandExists2("pip3") ? "pip3" : "pip";
6720
+ const result = (0, import_child_process10.spawnSync)(
6720
6721
  pip,
6721
6722
  ["install", "--user", OTEL_HOOKS_PACKAGE],
6722
6723
  { encoding: "utf8", timeout: 18e4 }
@@ -6735,7 +6736,7 @@ function tryInstallPackage() {
6735
6736
  };
6736
6737
  }
6737
6738
  function runSetupAgent(agent, otelHookCommand, hooksHome) {
6738
- const result = (0, import_child_process9.spawnSync)(otelHookCommand, ["setup", "--agent", agent], {
6739
+ const result = (0, import_child_process10.spawnSync)(otelHookCommand, ["setup", "--agent", agent], {
6739
6740
  encoding: "utf8",
6740
6741
  env: {
6741
6742
  ...process.env,
@@ -6801,9 +6802,9 @@ function rewriteHookCommandsToWrapper(filePath, wrapperPath) {
6801
6802
  function rewriteKnownHookRegistrations(wrapperPath) {
6802
6803
  const home = os13.homedir();
6803
6804
  const candidates = [
6804
- path43.join(home, ".cursor", "hooks.json"),
6805
- path43.join(home, ".claude", "settings.json"),
6806
- path43.join(home, ".codex", "hooks.json")
6805
+ path44.join(home, ".cursor", "hooks.json"),
6806
+ path44.join(home, ".claude", "settings.json"),
6807
+ path44.join(home, ".codex", "hooks.json")
6807
6808
  ];
6808
6809
  for (const filePath of candidates) {
6809
6810
  try {
@@ -6885,14 +6886,14 @@ function ensureOtelHooks(options) {
6885
6886
  function disableOtelHooksExport() {
6886
6887
  return writeOtelHooksConfig(buildOtelHooksConfig({ enabled: false }));
6887
6888
  }
6888
- var import_child_process9, fs41, os13, path43, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_AGENTS;
6889
+ var import_child_process10, fs41, os13, path44, OTEL_HOOKS_PACKAGE, OTEL_HOOKS_AGENTS;
6889
6890
  var init_otel_hooks = __esm({
6890
6891
  "src/core/otel-hooks.ts"() {
6891
6892
  "use strict";
6892
- import_child_process9 = require("child_process");
6893
+ import_child_process10 = require("child_process");
6893
6894
  fs41 = __toESM(require("fs"));
6894
6895
  os13 = __toESM(require("os"));
6895
- path43 = __toESM(require("path"));
6896
+ path44 = __toESM(require("path"));
6896
6897
  init_control_config();
6897
6898
  init_telemetry_config();
6898
6899
  OTEL_HOOKS_PACKAGE = "opentelemetry-hooks==0.14.0";
@@ -9851,7 +9852,7 @@ var require_compile = __commonJS({
9851
9852
  const schOrFunc = root.refs[ref];
9852
9853
  if (schOrFunc)
9853
9854
  return schOrFunc;
9854
- let _sch = resolve38.call(this, root, ref);
9855
+ let _sch = resolve39.call(this, root, ref);
9855
9856
  if (_sch === void 0) {
9856
9857
  const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
9857
9858
  const { schemaId } = this.opts;
@@ -9878,7 +9879,7 @@ var require_compile = __commonJS({
9878
9879
  function sameSchemaEnv(s1, s2) {
9879
9880
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
9880
9881
  }
9881
- function resolve38(root, ref) {
9882
+ function resolve39(root, ref) {
9882
9883
  let sch;
9883
9884
  while (typeof (sch = this.refs[ref]) == "string")
9884
9885
  ref = sch;
@@ -10096,8 +10097,8 @@ var require_utils2 = __commonJS({
10096
10097
  }
10097
10098
  return ind;
10098
10099
  }
10099
- function removeDotSegments(path54) {
10100
- let input = path54;
10100
+ function removeDotSegments(path55) {
10101
+ let input = path55;
10101
10102
  const output = [];
10102
10103
  let nextSlash = -1;
10103
10104
  let len = 0;
@@ -10349,8 +10350,8 @@ var require_schemes = __commonJS({
10349
10350
  wsComponent.secure = void 0;
10350
10351
  }
10351
10352
  if (wsComponent.resourceName) {
10352
- const [path54, query] = wsComponent.resourceName.split("?");
10353
- wsComponent.path = path54 && path54 !== "/" ? path54 : void 0;
10353
+ const [path55, query] = wsComponent.resourceName.split("?");
10354
+ wsComponent.path = path55 && path55 !== "/" ? path55 : void 0;
10354
10355
  wsComponent.query = query;
10355
10356
  wsComponent.resourceName = void 0;
10356
10357
  }
@@ -10509,7 +10510,7 @@ var require_fast_uri = __commonJS({
10509
10510
  }
10510
10511
  return uri;
10511
10512
  }
10512
- function resolve38(baseURI, relativeURI, options) {
10513
+ function resolve39(baseURI, relativeURI, options) {
10513
10514
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
10514
10515
  const resolved = resolveComponent(parse4(baseURI, schemelessOptions), parse4(relativeURI, schemelessOptions), schemelessOptions, true);
10515
10516
  schemelessOptions.skipEscape = true;
@@ -10767,7 +10768,7 @@ var require_fast_uri = __commonJS({
10767
10768
  var fastUri = {
10768
10769
  SCHEMES,
10769
10770
  normalize: normalize3,
10770
- resolve: resolve38,
10771
+ resolve: resolve39,
10771
10772
  resolveComponent,
10772
10773
  equal,
10773
10774
  serialize,
@@ -14848,15 +14849,15 @@ var require_route = __commonJS({
14848
14849
  };
14849
14850
  }
14850
14851
  function wrapConversion(toModel, graph) {
14851
- const path54 = [graph[toModel].parent, toModel];
14852
+ const path55 = [graph[toModel].parent, toModel];
14852
14853
  let fn = conversions[graph[toModel].parent][toModel];
14853
14854
  let cur = graph[toModel].parent;
14854
14855
  while (graph[cur].parent) {
14855
- path54.unshift(graph[cur].parent);
14856
+ path55.unshift(graph[cur].parent);
14856
14857
  fn = link(conversions[graph[cur].parent][cur], fn);
14857
14858
  cur = graph[cur].parent;
14858
14859
  }
14859
- fn.conversion = path54;
14860
+ fn.conversion = path55;
14860
14861
  return fn;
14861
14862
  }
14862
14863
  module2.exports = function(fromModel) {
@@ -24346,16 +24347,16 @@ var require_os_tmpdir = __commonJS({
24346
24347
  var isWindows = process.platform === "win32";
24347
24348
  var trailingSlashRe = isWindows ? /[^:]\\$/ : /.\/$/;
24348
24349
  module2.exports = function() {
24349
- var path54;
24350
+ var path55;
24350
24351
  if (isWindows) {
24351
- path54 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
24352
+ path55 = process.env.TEMP || process.env.TMP || (process.env.SystemRoot || process.env.windir) + "\\temp";
24352
24353
  } else {
24353
- path54 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
24354
+ path55 = process.env.TMPDIR || process.env.TMP || process.env.TEMP || "/tmp";
24354
24355
  }
24355
- if (trailingSlashRe.test(path54)) {
24356
- path54 = path54.slice(0, -1);
24356
+ if (trailingSlashRe.test(path55)) {
24357
+ path55 = path55.slice(0, -1);
24357
24358
  }
24358
- return path54;
24359
+ return path55;
24359
24360
  };
24360
24361
  }
24361
24362
  });
@@ -24364,7 +24365,7 @@ var require_os_tmpdir = __commonJS({
24364
24365
  var require_tmp = __commonJS({
24365
24366
  "node_modules/tmp/lib/tmp.js"(exports2, module2) {
24366
24367
  var fs46 = require("fs");
24367
- var path54 = require("path");
24368
+ var path55 = require("path");
24368
24369
  var crypto6 = require("crypto");
24369
24370
  var osTmpDir = require_os_tmpdir();
24370
24371
  var _c2 = process.binding("constants");
@@ -24406,7 +24407,7 @@ var require_tmp = __commonJS({
24406
24407
  }
24407
24408
  function _generateTmpName(opts) {
24408
24409
  if (opts.name) {
24409
- return path54.join(opts.dir || tmpDir, opts.name);
24410
+ return path55.join(opts.dir || tmpDir, opts.name);
24410
24411
  }
24411
24412
  if (opts.template) {
24412
24413
  return opts.template.replace(TEMPLATE_PATTERN, _randomChars(6));
@@ -24417,7 +24418,7 @@ var require_tmp = __commonJS({
24417
24418
  _randomChars(12),
24418
24419
  opts.postfix || ""
24419
24420
  ].join("");
24420
- return path54.join(opts.dir || tmpDir, name);
24421
+ return path55.join(opts.dir || tmpDir, name);
24421
24422
  }
24422
24423
  function tmpName(options, callback) {
24423
24424
  var args = _parseArguments(options, callback), opts = args[0], cb = args[1], tries = opts.name ? 1 : opts.tries || DEFAULT_TRIES;
@@ -24502,7 +24503,7 @@ var require_tmp = __commonJS({
24502
24503
  do {
24503
24504
  var dir2 = dirs.pop(), deferred = false, files = fs46.readdirSync(dir2);
24504
24505
  for (var i2 = 0, length = files.length; i2 < length; i2++) {
24505
- var file2 = path54.join(dir2, files[i2]), stat = fs46.lstatSync(file2);
24506
+ var file2 = path55.join(dir2, files[i2]), stat = fs46.lstatSync(file2);
24506
24507
  if (stat.isDirectory()) {
24507
24508
  if (!deferred) {
24508
24509
  deferred = true;
@@ -25713,7 +25714,7 @@ var require_Observable = __commonJS({
25713
25714
  Observable2.prototype.forEach = function(next, promiseCtor) {
25714
25715
  var _this = this;
25715
25716
  promiseCtor = getPromiseCtor(promiseCtor);
25716
- return new promiseCtor(function(resolve38, reject) {
25717
+ return new promiseCtor(function(resolve39, reject) {
25717
25718
  var subscriber = new Subscriber_1.SafeSubscriber({
25718
25719
  next: function(value) {
25719
25720
  try {
@@ -25724,7 +25725,7 @@ var require_Observable = __commonJS({
25724
25725
  }
25725
25726
  },
25726
25727
  error: reject,
25727
- complete: resolve38
25728
+ complete: resolve39
25728
25729
  });
25729
25730
  _this.subscribe(subscriber);
25730
25731
  });
@@ -25746,14 +25747,14 @@ var require_Observable = __commonJS({
25746
25747
  Observable2.prototype.toPromise = function(promiseCtor) {
25747
25748
  var _this = this;
25748
25749
  promiseCtor = getPromiseCtor(promiseCtor);
25749
- return new promiseCtor(function(resolve38, reject) {
25750
+ return new promiseCtor(function(resolve39, reject) {
25750
25751
  var value;
25751
25752
  _this.subscribe(function(x2) {
25752
25753
  return value = x2;
25753
25754
  }, function(err) {
25754
25755
  return reject(err);
25755
25756
  }, function() {
25756
- return resolve38(value);
25757
+ return resolve39(value);
25757
25758
  });
25758
25759
  });
25759
25760
  };
@@ -27849,11 +27850,11 @@ var require_innerFrom = __commonJS({
27849
27850
  "use strict";
27850
27851
  var __awaiter = exports2 && exports2.__awaiter || function(thisArg, _arguments, P2, generator) {
27851
27852
  function adopt(value) {
27852
- return value instanceof P2 ? value : new P2(function(resolve38) {
27853
- resolve38(value);
27853
+ return value instanceof P2 ? value : new P2(function(resolve39) {
27854
+ resolve39(value);
27854
27855
  });
27855
27856
  }
27856
- return new (P2 || (P2 = Promise))(function(resolve38, reject) {
27857
+ return new (P2 || (P2 = Promise))(function(resolve39, reject) {
27857
27858
  function fulfilled(value) {
27858
27859
  try {
27859
27860
  step(generator.next(value));
@@ -27869,7 +27870,7 @@ var require_innerFrom = __commonJS({
27869
27870
  }
27870
27871
  }
27871
27872
  function step(result) {
27872
- result.done ? resolve38(result.value) : adopt(result.value).then(fulfilled, rejected);
27873
+ result.done ? resolve39(result.value) : adopt(result.value).then(fulfilled, rejected);
27873
27874
  }
27874
27875
  step((generator = generator.apply(thisArg, _arguments || [])).next());
27875
27876
  });
@@ -27951,14 +27952,14 @@ var require_innerFrom = __commonJS({
27951
27952
  }, i2);
27952
27953
  function verb(n2) {
27953
27954
  i2[n2] = o2[n2] && function(v2) {
27954
- return new Promise(function(resolve38, reject) {
27955
- v2 = o2[n2](v2), settle(resolve38, reject, v2.done, v2.value);
27955
+ return new Promise(function(resolve39, reject) {
27956
+ v2 = o2[n2](v2), settle(resolve39, reject, v2.done, v2.value);
27956
27957
  });
27957
27958
  };
27958
27959
  }
27959
- function settle(resolve38, reject, d2, v2) {
27960
+ function settle(resolve39, reject, d2, v2) {
27960
27961
  Promise.resolve(v2).then(function(v3) {
27961
- resolve38({ value: v3, done: d2 });
27962
+ resolve39({ value: v3, done: d2 });
27962
27963
  }, reject);
27963
27964
  }
27964
27965
  };
@@ -28577,7 +28578,7 @@ var require_lastValueFrom = __commonJS({
28577
28578
  var EmptyError_1 = require_EmptyError();
28578
28579
  function lastValueFrom2(source, config2) {
28579
28580
  var hasConfig = typeof config2 === "object";
28580
- return new Promise(function(resolve38, reject) {
28581
+ return new Promise(function(resolve39, reject) {
28581
28582
  var _hasValue = false;
28582
28583
  var _value;
28583
28584
  source.subscribe({
@@ -28588,9 +28589,9 @@ var require_lastValueFrom = __commonJS({
28588
28589
  error: reject,
28589
28590
  complete: function() {
28590
28591
  if (_hasValue) {
28591
- resolve38(_value);
28592
+ resolve39(_value);
28592
28593
  } else if (hasConfig) {
28593
- resolve38(config2.defaultValue);
28594
+ resolve39(config2.defaultValue);
28594
28595
  } else {
28595
28596
  reject(new EmptyError_1.EmptyError());
28596
28597
  }
@@ -28612,16 +28613,16 @@ var require_firstValueFrom = __commonJS({
28612
28613
  var Subscriber_1 = require_Subscriber();
28613
28614
  function firstValueFrom(source, config2) {
28614
28615
  var hasConfig = typeof config2 === "object";
28615
- return new Promise(function(resolve38, reject) {
28616
+ return new Promise(function(resolve39, reject) {
28616
28617
  var subscriber = new Subscriber_1.SafeSubscriber({
28617
28618
  next: function(value) {
28618
- resolve38(value);
28619
+ resolve39(value);
28619
28620
  subscriber.unsubscribe();
28620
28621
  },
28621
28622
  error: reject,
28622
28623
  complete: function() {
28623
28624
  if (hasConfig) {
28624
- resolve38(config2.defaultValue);
28625
+ resolve39(config2.defaultValue);
28625
28626
  } else {
28626
28627
  reject(new EmptyError_1.EmptyError());
28627
28628
  }
@@ -34414,14 +34415,14 @@ var require_run_async = __commonJS({
34414
34415
  return function() {
34415
34416
  var args = arguments;
34416
34417
  var originalThis = this;
34417
- var promise = new Promise(function(resolve38, reject) {
34418
+ var promise = new Promise(function(resolve39, reject) {
34418
34419
  var resolved = false;
34419
34420
  const wrappedResolve = function(value) {
34420
34421
  if (resolved) {
34421
34422
  console.warn("Run-async promise already resolved.");
34422
34423
  }
34423
34424
  resolved = true;
34424
- resolve38(value);
34425
+ resolve39(value);
34425
34426
  };
34426
34427
  var rejected = false;
34427
34428
  const wrappedReject = function(value) {
@@ -35680,8 +35681,8 @@ var YargsParser = class {
35680
35681
  type = DefaultValuesForTypeKey.ARRAY;
35681
35682
  return type;
35682
35683
  }
35683
- function isUndefined(num) {
35684
- return num === void 0;
35684
+ function isUndefined(num2) {
35685
+ return num2 === void 0;
35685
35686
  }
35686
35687
  function checkConfiguration() {
35687
35688
  Object.keys(flags.counts).find((key) => {
@@ -35775,11 +35776,11 @@ var parser = new YargsParser({
35775
35776
  resolve: import_path2.resolve,
35776
35777
  // TODO: figure out a way to combine ESM and CJS coverage, such that
35777
35778
  // we can exercise all the lines below:
35778
- require: (path54) => {
35779
+ require: (path55) => {
35779
35780
  if (typeof require !== "undefined") {
35780
- return require(path54);
35781
- } else if (path54.match(/\.json$/)) {
35782
- return JSON.parse((0, import_fs2.readFileSync)(path54, "utf8"));
35781
+ return require(path55);
35782
+ } else if (path55.match(/\.json$/)) {
35783
+ return JSON.parse((0, import_fs2.readFileSync)(path55, "utf8"));
35783
35784
  } else {
35784
35785
  throw Error("only .json config files are supported in ESM");
35785
35786
  }
@@ -37688,8 +37689,8 @@ ${customMsgs.join("\n")}` : "";
37688
37689
  return implied;
37689
37690
  };
37690
37691
  function keyExists(argv, val) {
37691
- const num = Number(val);
37692
- val = isNaN(num) ? val : num;
37692
+ const num2 = Number(val);
37693
+ val = isNaN(num2) ? val : num2;
37693
37694
  if (typeof val === "number") {
37694
37695
  val = argv._.length >= val;
37695
37696
  } else if (val.match(/^--no-.+/)) {
@@ -38305,12 +38306,12 @@ var YargsInstance = class {
38305
38306
  async getCompletion(args, done) {
38306
38307
  argsert("<array> [function]", [args, done], arguments.length);
38307
38308
  if (!done) {
38308
- return new Promise((resolve38, reject) => {
38309
+ return new Promise((resolve39, reject) => {
38309
38310
  __classPrivateFieldGet(this, _YargsInstance_completion, "f").getCompletion(args, (err, completions) => {
38310
38311
  if (err)
38311
38312
  reject(err);
38312
38313
  else
38313
- resolve38(completions);
38314
+ resolve39(completions);
38314
38315
  });
38315
38316
  });
38316
38317
  } else {
@@ -40460,8 +40461,8 @@ function getErrorMap() {
40460
40461
 
40461
40462
  // node_modules/zod/v3/helpers/parseUtil.js
40462
40463
  var makeIssue = (params) => {
40463
- const { data, path: path54, errorMaps, issueData } = params;
40464
- const fullPath = [...path54, ...issueData.path || []];
40464
+ const { data, path: path55, errorMaps, issueData } = params;
40465
+ const fullPath = [...path55, ...issueData.path || []];
40465
40466
  const fullIssue = {
40466
40467
  ...issueData,
40467
40468
  path: fullPath
@@ -40577,11 +40578,11 @@ var errorUtil;
40577
40578
 
40578
40579
  // node_modules/zod/v3/types.js
40579
40580
  var ParseInputLazyPath = class {
40580
- constructor(parent, value, path54, key) {
40581
+ constructor(parent, value, path55, key) {
40581
40582
  this._cachedPath = [];
40582
40583
  this.parent = parent;
40583
40584
  this.data = value;
40584
- this._path = path54;
40585
+ this._path = path55;
40585
40586
  this._key = key;
40586
40587
  }
40587
40588
  get path() {
@@ -44720,16 +44721,16 @@ async function handleAgentSkills(options) {
44720
44721
  }
44721
44722
  async function askYesNo(question) {
44722
44723
  const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
44723
- return new Promise((resolve38) => {
44724
+ return new Promise((resolve39) => {
44724
44725
  process.stderr.write(`${question} `);
44725
44726
  rl.once("line", (answer) => {
44726
44727
  rl.close();
44727
44728
  const trimmed = answer.trim();
44728
44729
  if (trimmed === "") {
44729
- resolve38(true);
44730
+ resolve39(true);
44730
44731
  return;
44731
44732
  }
44732
- resolve38(/^y(es)?$/i.test(trimmed));
44733
+ resolve39(/^y(es)?$/i.test(trimmed));
44733
44734
  });
44734
44735
  });
44735
44736
  }
@@ -44808,7 +44809,7 @@ function handleRemove(argv) {
44808
44809
  }
44809
44810
 
44810
44811
  // src/cli/commands/env.ts
44811
- var path47 = __toESM(require("path"));
44812
+ var path48 = __toESM(require("path"));
44812
44813
 
44813
44814
  // src/core/harness.ts
44814
44815
  var fs20 = __toESM(require("fs"));
@@ -45587,13 +45588,13 @@ var MultipartBody = class {
45587
45588
  // node_modules/@anthropic-ai/sdk/_shims/node-runtime.mjs
45588
45589
  var import_web = require("node:stream/web");
45589
45590
  var fileFromPathWarned = false;
45590
- async function fileFromPath3(path54, ...args) {
45591
+ async function fileFromPath3(path55, ...args) {
45591
45592
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
45592
45593
  if (!fileFromPathWarned) {
45593
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path54)}) instead`);
45594
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path55)}) instead`);
45594
45595
  fileFromPathWarned = true;
45595
45596
  }
45596
- return await _fileFromPath(path54, ...args);
45597
+ return await _fileFromPath(path55, ...args);
45597
45598
  }
45598
45599
  var defaultHttpAgent = new import_agentkeepalive.default({ keepAlive: true, timeout: 5 * 60 * 1e3 });
45599
45600
  var defaultHttpsAgent = new import_agentkeepalive.default.HttpsAgent({ keepAlive: true, timeout: 5 * 60 * 1e3 });
@@ -46089,8 +46090,8 @@ async function defaultParseResponse(props) {
46089
46090
  }
46090
46091
  var APIPromise = class _APIPromise extends Promise {
46091
46092
  constructor(responsePromise, parseResponse = defaultParseResponse) {
46092
- super((resolve38) => {
46093
- resolve38(null);
46093
+ super((resolve39) => {
46094
+ resolve39(null);
46094
46095
  });
46095
46096
  this.responsePromise = responsePromise;
46096
46097
  this.parseResponse = parseResponse;
@@ -46190,29 +46191,29 @@ var APIClient = class {
46190
46191
  defaultIdempotencyKey() {
46191
46192
  return `stainless-node-retry-${uuid4()}`;
46192
46193
  }
46193
- get(path54, opts) {
46194
- return this.methodRequest("get", path54, opts);
46194
+ get(path55, opts) {
46195
+ return this.methodRequest("get", path55, opts);
46195
46196
  }
46196
- post(path54, opts) {
46197
- return this.methodRequest("post", path54, opts);
46197
+ post(path55, opts) {
46198
+ return this.methodRequest("post", path55, opts);
46198
46199
  }
46199
- patch(path54, opts) {
46200
- return this.methodRequest("patch", path54, opts);
46200
+ patch(path55, opts) {
46201
+ return this.methodRequest("patch", path55, opts);
46201
46202
  }
46202
- put(path54, opts) {
46203
- return this.methodRequest("put", path54, opts);
46203
+ put(path55, opts) {
46204
+ return this.methodRequest("put", path55, opts);
46204
46205
  }
46205
- delete(path54, opts) {
46206
- return this.methodRequest("delete", path54, opts);
46206
+ delete(path55, opts) {
46207
+ return this.methodRequest("delete", path55, opts);
46207
46208
  }
46208
- methodRequest(method, path54, opts) {
46209
+ methodRequest(method, path55, opts) {
46209
46210
  return this.request(Promise.resolve(opts).then(async (opts2) => {
46210
46211
  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;
46211
- return { method, path: path54, ...opts2, body };
46212
+ return { method, path: path55, ...opts2, body };
46212
46213
  }));
46213
46214
  }
46214
- getAPIList(path54, Page, opts) {
46215
- return this.requestAPIList(Page, { method: "get", path: path54, ...opts });
46215
+ getAPIList(path55, Page, opts) {
46216
+ return this.requestAPIList(Page, { method: "get", path: path55, ...opts });
46216
46217
  }
46217
46218
  calculateContentLength(body) {
46218
46219
  if (typeof body === "string") {
@@ -46230,10 +46231,10 @@ var APIClient = class {
46230
46231
  return null;
46231
46232
  }
46232
46233
  buildRequest(options) {
46233
- const { method, path: path54, query, headers = {} } = options;
46234
+ const { method, path: path55, query, headers = {} } = options;
46234
46235
  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;
46235
46236
  const contentLength = this.calculateContentLength(body);
46236
- const url = this.buildURL(path54, query);
46237
+ const url = this.buildURL(path55, query);
46237
46238
  if ("timeout" in options)
46238
46239
  validatePositiveInteger("timeout", options.timeout);
46239
46240
  const timeout = options.timeout ?? this.timeout;
@@ -46342,8 +46343,8 @@ var APIClient = class {
46342
46343
  const request = this.makeRequest(options, null);
46343
46344
  return new PagePromise(this, request, Page);
46344
46345
  }
46345
- buildURL(path54, query) {
46346
- const url = isAbsoluteURL(path54) ? new URL(path54) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path54.startsWith("/") ? path54.slice(1) : path54));
46346
+ buildURL(path55, query) {
46347
+ const url = isAbsoluteURL(path55) ? new URL(path55) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path55.startsWith("/") ? path55.slice(1) : path55));
46347
46348
  const defaultQuery = this.defaultQuery();
46348
46349
  if (!isEmptyObj(defaultQuery)) {
46349
46350
  query = { ...defaultQuery, ...query };
@@ -46628,7 +46629,7 @@ var startsWithSchemeRegexp = new RegExp("^(?:[a-z]+:)?//", "i");
46628
46629
  var isAbsoluteURL = (url) => {
46629
46630
  return startsWithSchemeRegexp.test(url);
46630
46631
  };
46631
- var sleep = (ms) => new Promise((resolve38) => setTimeout(resolve38, ms));
46632
+ var sleep = (ms) => new Promise((resolve39) => setTimeout(resolve39, ms));
46632
46633
  var validatePositiveInteger = (name, n2) => {
46633
46634
  if (typeof n2 !== "number" || !Number.isInteger(n2)) {
46634
46635
  throw new AnthropicError(`${name} must be an integer`);
@@ -47119,12 +47120,12 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
47119
47120
  }
47120
47121
  return this._emit("error", new AnthropicError(String(error3)));
47121
47122
  });
47122
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve38, reject) => {
47123
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve38, "f");
47123
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_connectedPromise, new Promise((resolve39, reject) => {
47124
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveConnectedPromise, resolve39, "f");
47124
47125
  __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectConnectedPromise, reject, "f");
47125
47126
  }), "f");
47126
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve38, reject) => {
47127
- __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve38, "f");
47127
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_endPromise, new Promise((resolve39, reject) => {
47128
+ __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_resolveEndPromise, resolve39, "f");
47128
47129
  __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_rejectEndPromise, reject, "f");
47129
47130
  }), "f");
47130
47131
  __classPrivateFieldGet8(this, _PromptCachingBetaMessageStream_connectedPromise, "f").catch(() => {
@@ -47253,11 +47254,11 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
47253
47254
  * const message = await stream.emitted('message') // rejects if the stream errors
47254
47255
  */
47255
47256
  emitted(event) {
47256
- return new Promise((resolve38, reject) => {
47257
+ return new Promise((resolve39, reject) => {
47257
47258
  __classPrivateFieldSet7(this, _PromptCachingBetaMessageStream_catchingPromiseCreated, true, "f");
47258
47259
  if (event !== "error")
47259
47260
  this.once("error", reject);
47260
- this.once(event, resolve38);
47261
+ this.once(event, resolve39);
47261
47262
  });
47262
47263
  }
47263
47264
  async done() {
@@ -47484,7 +47485,7 @@ var PromptCachingBetaMessageStream = class _PromptCachingBetaMessageStream {
47484
47485
  if (done) {
47485
47486
  return { value: void 0, done: true };
47486
47487
  }
47487
- return new Promise((resolve38, reject) => readQueue.push({ resolve: resolve38, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
47488
+ return new Promise((resolve39, reject) => readQueue.push({ resolve: resolve39, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
47488
47489
  }
47489
47490
  const chunk = pushQueue.shift();
47490
47491
  return { value: chunk, done: false };
@@ -47632,12 +47633,12 @@ var MessageStream = class _MessageStream {
47632
47633
  }
47633
47634
  return this._emit("error", new AnthropicError(String(error3)));
47634
47635
  });
47635
- __classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve38, reject) => {
47636
- __classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve38, "f");
47636
+ __classPrivateFieldSet8(this, _MessageStream_connectedPromise, new Promise((resolve39, reject) => {
47637
+ __classPrivateFieldSet8(this, _MessageStream_resolveConnectedPromise, resolve39, "f");
47637
47638
  __classPrivateFieldSet8(this, _MessageStream_rejectConnectedPromise, reject, "f");
47638
47639
  }), "f");
47639
- __classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve38, reject) => {
47640
- __classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve38, "f");
47640
+ __classPrivateFieldSet8(this, _MessageStream_endPromise, new Promise((resolve39, reject) => {
47641
+ __classPrivateFieldSet8(this, _MessageStream_resolveEndPromise, resolve39, "f");
47641
47642
  __classPrivateFieldSet8(this, _MessageStream_rejectEndPromise, reject, "f");
47642
47643
  }), "f");
47643
47644
  __classPrivateFieldGet9(this, _MessageStream_connectedPromise, "f").catch(() => {
@@ -47766,11 +47767,11 @@ var MessageStream = class _MessageStream {
47766
47767
  * const message = await stream.emitted('message') // rejects if the stream errors
47767
47768
  */
47768
47769
  emitted(event) {
47769
- return new Promise((resolve38, reject) => {
47770
+ return new Promise((resolve39, reject) => {
47770
47771
  __classPrivateFieldSet8(this, _MessageStream_catchingPromiseCreated, true, "f");
47771
47772
  if (event !== "error")
47772
47773
  this.once("error", reject);
47773
- this.once(event, resolve38);
47774
+ this.once(event, resolve39);
47774
47775
  });
47775
47776
  }
47776
47777
  async done() {
@@ -47997,7 +47998,7 @@ var MessageStream = class _MessageStream {
47997
47998
  if (done) {
47998
47999
  return { value: void 0, done: true };
47999
48000
  }
48000
- return new Promise((resolve38, reject) => readQueue.push({ resolve: resolve38, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
48001
+ return new Promise((resolve39, reject) => readQueue.push({ resolve: resolve39, reject })).then((chunk2) => chunk2 ? { value: chunk2, done: false } : { value: void 0, done: true });
48001
48002
  }
48002
48003
  const chunk = pushQueue.shift();
48003
48004
  return { value: chunk, done: false };
@@ -48257,11 +48258,11 @@ async function promptApplyAgentMdProposal(repoPath) {
48257
48258
  }
48258
48259
  async function askYesNo2(question) {
48259
48260
  const rl = readline2.createInterface({ input: process.stdin, output: process.stderr });
48260
- return new Promise((resolve38) => {
48261
+ return new Promise((resolve39) => {
48261
48262
  process.stderr.write(`${question} `);
48262
48263
  rl.once("line", (answer) => {
48263
48264
  rl.close();
48264
- resolve38(/^y(es)?$/i.test(answer.trim()));
48265
+ resolve39(/^y(es)?$/i.test(answer.trim()));
48265
48266
  });
48266
48267
  });
48267
48268
  }
@@ -48491,7 +48492,7 @@ async function executeAuthoringToolCall(toolName, input, repoPath, harnessDir, c
48491
48492
  }
48492
48493
  async function askUser(question, options) {
48493
48494
  const rl = readline3.createInterface({ input: process.stdin, output: process.stderr });
48494
- return new Promise((resolve38) => {
48495
+ return new Promise((resolve39) => {
48495
48496
  process.stderr.write("\n");
48496
48497
  process.stderr.write(`\u2753 ${question}
48497
48498
  `);
@@ -48502,7 +48503,7 @@ async function askUser(question, options) {
48502
48503
  process.stderr.write("> ");
48503
48504
  rl.once("line", (answer) => {
48504
48505
  rl.close();
48505
- resolve38(answer.trim());
48506
+ resolve39(answer.trim());
48506
48507
  });
48507
48508
  });
48508
48509
  }
@@ -48646,7 +48647,7 @@ function runScript(scriptPath, args = [], options = {}) {
48646
48647
  function runScriptCapture(scriptPath, args = [], options = {}) {
48647
48648
  const stream = options.stream ?? false;
48648
48649
  const { stream: _stream, ...spawnOptions } = options;
48649
- return new Promise((resolve38) => {
48650
+ return new Promise((resolve39) => {
48650
48651
  const proc = (0, import_child_process.spawn)("bash", [scriptPath, ...args], {
48651
48652
  ...spawnOptions,
48652
48653
  stdio: ["inherit", "pipe", "pipe"]
@@ -48661,13 +48662,13 @@ function runScriptCapture(scriptPath, args = [], options = {}) {
48661
48662
  stderr += d2;
48662
48663
  if (stream) process.stderr.write(d2);
48663
48664
  });
48664
- proc.on("close", (code) => resolve38({ stdout, stderr, code: code ?? 0 }));
48665
+ proc.on("close", (code) => resolve39({ stdout, stderr, code: code ?? 0 }));
48665
48666
  });
48666
48667
  }
48667
48668
  function runShellCommand(command2, options = {}) {
48668
48669
  const stream = options.stream ?? false;
48669
48670
  const { stream: _stream, ...spawnOptions } = options;
48670
- return new Promise((resolve38) => {
48671
+ return new Promise((resolve39) => {
48671
48672
  const proc = (0, import_child_process.spawn)("bash", ["-lc", command2], {
48672
48673
  ...spawnOptions,
48673
48674
  stdio: ["inherit", "pipe", "pipe"]
@@ -48682,7 +48683,7 @@ function runShellCommand(command2, options = {}) {
48682
48683
  stderr += d2;
48683
48684
  if (stream) process.stderr.write(d2);
48684
48685
  });
48685
- proc.on("close", (code) => resolve38({ stdout, stderr, code: code ?? 0 }));
48686
+ proc.on("close", (code) => resolve39({ stdout, stderr, code: code ?? 0 }));
48686
48687
  });
48687
48688
  }
48688
48689
 
@@ -49512,12 +49513,12 @@ function requireApiKey() {
49512
49513
  return key;
49513
49514
  }
49514
49515
  function validateAgentId(id, repoPath) {
49515
- const num = Number(id);
49516
+ const num2 = Number(id);
49516
49517
  const range = getAgentSlotRange(repoPath);
49517
- if (!Number.isInteger(num) || num < range.min || num > range.max) {
49518
+ if (!Number.isInteger(num2) || num2 < range.min || num2 > range.max) {
49518
49519
  throw new Error(`agent-id must be a number between ${range.min} and ${range.max}`);
49519
49520
  }
49520
- return num;
49521
+ return num2;
49521
49522
  }
49522
49523
 
49523
49524
  // src/core/harness.ts
@@ -49738,6 +49739,81 @@ function addCustomStage(repoPath, options) {
49738
49739
  // src/harness/adaptation-prompt.ts
49739
49740
  var fs22 = __toESM(require("fs"));
49740
49741
  var path21 = __toESM(require("path"));
49742
+ var readline4 = __toESM(require("readline"));
49743
+
49744
+ // src/utils/clipboard.ts
49745
+ var import_child_process2 = require("child_process");
49746
+ function commandExists(command2) {
49747
+ const probe = process.platform === "win32" ? (0, import_child_process2.spawnSync)("where", [command2], { encoding: "utf8", stdio: ["ignore", "ignore", "ignore"] }) : (0, import_child_process2.spawnSync)("which", [command2], { encoding: "utf8", stdio: ["ignore", "ignore", "ignore"] });
49748
+ return probe.status === 0;
49749
+ }
49750
+ function tryPipeCommand(command2, args, text) {
49751
+ const result = (0, import_child_process2.spawnSync)(command2, args, {
49752
+ input: text,
49753
+ encoding: "utf8",
49754
+ stdio: ["pipe", "ignore", "ignore"]
49755
+ });
49756
+ return result.status === 0 && !result.error;
49757
+ }
49758
+ function writeOsc52Clipboard(text, stream = process.stderr) {
49759
+ if (!("isTTY" in stream) || !stream.isTTY) return false;
49760
+ if (Buffer.byteLength(text, "utf8") > 2e5) return false;
49761
+ const b64 = Buffer.from(text, "utf8").toString("base64");
49762
+ stream.write(`\x1B]52;c;${b64}\x07`);
49763
+ return true;
49764
+ }
49765
+ function copyViaPlatformTools(text) {
49766
+ if (process.platform === "darwin" && commandExists("pbcopy")) {
49767
+ if (tryPipeCommand("pbcopy", [], text)) return { ok: true, method: "pbcopy" };
49768
+ }
49769
+ if (process.platform === "win32") {
49770
+ if (commandExists("powershell")) {
49771
+ const result = (0, import_child_process2.spawnSync)(
49772
+ "powershell",
49773
+ [
49774
+ "-NoProfile",
49775
+ "-NonInteractive",
49776
+ "-Command",
49777
+ "$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [Text.UTF8Encoding]::new(); Set-Clipboard -Value ([Console]::In.ReadToEnd())"
49778
+ ],
49779
+ {
49780
+ input: text,
49781
+ encoding: "utf8",
49782
+ stdio: ["pipe", "ignore", "ignore"]
49783
+ }
49784
+ );
49785
+ if (result.status === 0 && !result.error) return { ok: true, method: "powershell" };
49786
+ }
49787
+ if (commandExists("clip") && tryPipeCommand("clip", [], text)) {
49788
+ return { ok: true, method: "clip" };
49789
+ }
49790
+ }
49791
+ if (process.platform === "linux" || process.platform === "freebsd" || process.platform === "openbsd") {
49792
+ if (commandExists("wl-copy") && tryPipeCommand("wl-copy", [], text)) {
49793
+ return { ok: true, method: "wl-copy" };
49794
+ }
49795
+ if (commandExists("xclip") && tryPipeCommand("xclip", ["-selection", "clipboard"], text)) {
49796
+ return { ok: true, method: "xclip" };
49797
+ }
49798
+ if (commandExists("xsel") && tryPipeCommand("xsel", ["--clipboard", "--input"], text)) {
49799
+ return { ok: true, method: "xsel" };
49800
+ }
49801
+ }
49802
+ return {
49803
+ ok: false,
49804
+ detail: "No system clipboard command available (pbcopy, wl-copy/xclip/xsel, or clip)"
49805
+ };
49806
+ }
49807
+ function copyTextToClipboard(text) {
49808
+ const platform = copyViaPlatformTools(text);
49809
+ if (platform.ok) return platform;
49810
+ if (writeOsc52Clipboard(text)) {
49811
+ return { ok: true, method: "osc52" };
49812
+ }
49813
+ return platform;
49814
+ }
49815
+
49816
+ // src/harness/adaptation-prompt.ts
49741
49817
  var ADAPTATION_PROMPT_FILE = "ADAPT-PROMPT.md";
49742
49818
  var PROFILE_HINTS = {
49743
49819
  default: "Web app profile (SaaS/full-stack) \u2014 Docker Compose for shared infra (HARNESS_INFRA_SERVICES), PM2 for the primary application only, git worktree per agent slot by default. Launch provisions toolchain via harness.env (HARNESS_ECOSYSTEM, HARNESS_INSTALL_CMD) and writes paths to .env.agent.<id>. Identify the primary app agents modify; run supporting services shared.",
@@ -49788,11 +49864,47 @@ function printAdaptationPrompt(content) {
49788
49864
  `);
49789
49865
  process.stderr.write("\n");
49790
49866
  }
49867
+ function askYesNo3(question) {
49868
+ const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
49869
+ return new Promise((resolve39) => {
49870
+ process.stderr.write(`${question} `);
49871
+ rl.once("line", (answer) => {
49872
+ rl.close();
49873
+ const trimmed = answer.trim();
49874
+ resolve39(trimmed === "" || /^y(es)?$/i.test(trimmed));
49875
+ });
49876
+ });
49877
+ }
49878
+ async function offerAdaptationPromptClipboard(content, options = {}) {
49879
+ const interactive = Boolean(process.stdin.isTTY && process.stderr.isTTY);
49880
+ if (!interactive && !options.autoYes) {
49881
+ info("Prompt also saved to .har/ADAPT-PROMPT.md (open or copy from there)");
49882
+ return false;
49883
+ }
49884
+ let shouldCopy = options.autoYes === true;
49885
+ if (!shouldCopy && interactive) {
49886
+ shouldCopy = await askYesNo3("Copy adaptation prompt to clipboard for your coding agent? [Y/n]");
49887
+ }
49888
+ if (!shouldCopy) {
49889
+ info("Skipped clipboard copy \u2014 prompt is in .har/ADAPT-PROMPT.md");
49890
+ return false;
49891
+ }
49892
+ const result = copyTextToClipboard(content);
49893
+ if (result.ok) {
49894
+ success(
49895
+ result.method === "osc52" ? "Copied adaptation prompt to clipboard (terminal OSC 52) \u2014 paste into your coding agent" : "Copied adaptation prompt to clipboard \u2014 paste into your coding agent"
49896
+ );
49897
+ return true;
49898
+ }
49899
+ warn(`Could not copy to clipboard: ${result.detail}`);
49900
+ info("Open .har/ADAPT-PROMPT.md and paste that into your coding agent instead");
49901
+ return false;
49902
+ }
49791
49903
 
49792
49904
  // src/harness/cursor-rule.ts
49793
49905
  var fs23 = __toESM(require("fs"));
49794
49906
  var path22 = __toESM(require("path"));
49795
- var readline4 = __toESM(require("readline"));
49907
+ var readline5 = __toESM(require("readline"));
49796
49908
  var CURSOR_RULE_RELATIVE_PATH = ".cursor/rules/har-workflow.mdc";
49797
49909
  function getCursorRulePath(repoPath) {
49798
49910
  return path22.join(repoPath, CURSOR_RULE_RELATIVE_PATH);
@@ -49842,20 +49954,20 @@ async function handleCursorRule(options) {
49842
49954
  }
49843
49955
  async function promptScaffoldCursorRule(exists) {
49844
49956
  const action = exists ? "Update" : "Create";
49845
- return askYesNo3(`${action} ${CURSOR_RULE_RELATIVE_PATH}? [Y/n]`);
49957
+ return askYesNo4(`${action} ${CURSOR_RULE_RELATIVE_PATH}? [Y/n]`);
49846
49958
  }
49847
- async function askYesNo3(question) {
49848
- const rl = readline4.createInterface({ input: process.stdin, output: process.stderr });
49849
- return new Promise((resolve38) => {
49959
+ async function askYesNo4(question) {
49960
+ const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
49961
+ return new Promise((resolve39) => {
49850
49962
  process.stderr.write(`${question} `);
49851
49963
  rl.once("line", (answer) => {
49852
49964
  rl.close();
49853
49965
  const trimmed = answer.trim();
49854
49966
  if (trimmed === "") {
49855
- resolve38(true);
49967
+ resolve39(true);
49856
49968
  return;
49857
49969
  }
49858
- resolve38(/^y(es)?$/i.test(trimmed));
49970
+ resolve39(/^y(es)?$/i.test(trimmed));
49859
49971
  });
49860
49972
  });
49861
49973
  }
@@ -50165,7 +50277,7 @@ var LocalScriptExecutor = class {
50165
50277
  var localScriptExecutor = new LocalScriptExecutor();
50166
50278
 
50167
50279
  // src/core/control-sync.ts
50168
- var path41 = __toESM(require("path"));
50280
+ var path42 = __toESM(require("path"));
50169
50281
  init_control_config();
50170
50282
 
50171
50283
  // src/core/control-registry.ts
@@ -50283,22 +50395,25 @@ function listRegisteredRepos() {
50283
50395
  return kept;
50284
50396
  }
50285
50397
 
50398
+ // src/core/control-sync.ts
50399
+ init_portal_credentials();
50400
+
50286
50401
  // src/core/slot-status.ts
50287
50402
  var fs33 = __toESM(require("fs"));
50288
50403
  var os8 = __toESM(require("os"));
50289
50404
  var path33 = __toESM(require("path"));
50290
- var import_child_process7 = require("child_process");
50405
+ var import_child_process8 = require("child_process");
50291
50406
 
50292
50407
  // src/core/runs.ts
50293
50408
  var crypto2 = __toESM(require("crypto"));
50294
- var import_child_process2 = require("child_process");
50409
+ var import_child_process3 = require("child_process");
50295
50410
  var fs29 = __toESM(require("fs"));
50296
50411
  var os6 = __toESM(require("os"));
50297
50412
  var path28 = __toESM(require("path"));
50298
50413
  var RUNS_DIR = "runs";
50299
50414
  function gitCommonDir(cwd) {
50300
50415
  try {
50301
- const out = (0, import_child_process2.execSync)("git rev-parse --git-common-dir", {
50416
+ const out = (0, import_child_process3.execSync)("git rev-parse --git-common-dir", {
50302
50417
  cwd,
50303
50418
  encoding: "utf8",
50304
50419
  stdio: ["pipe", "pipe", "ignore"]
@@ -50315,7 +50430,7 @@ function sameGitCheckout(a2, b2) {
50315
50430
  }
50316
50431
  function gitPrefix(cwd) {
50317
50432
  try {
50318
- return (0, import_child_process2.execSync)("git rev-parse --show-prefix", {
50433
+ return (0, import_child_process3.execSync)("git rev-parse --show-prefix", {
50319
50434
  cwd,
50320
50435
  encoding: "utf8",
50321
50436
  stdio: ["pipe", "pipe", "ignore"]
@@ -50484,13 +50599,13 @@ function listRuns(repoPath, filter2 = {}) {
50484
50599
  var path32 = __toESM(require("path"));
50485
50600
 
50486
50601
  // src/core/control-port.ts
50487
- var import_child_process4 = require("child_process");
50602
+ var import_child_process5 = require("child_process");
50488
50603
  var fs31 = __toESM(require("fs"));
50489
50604
  var path30 = __toESM(require("path"));
50490
50605
  init_control_config();
50491
50606
 
50492
50607
  // src/core/slot-ports.ts
50493
- var import_child_process3 = require("child_process");
50608
+ var import_child_process4 = require("child_process");
50494
50609
  var fs30 = __toESM(require("fs"));
50495
50610
  var path29 = __toESM(require("path"));
50496
50611
  function portStep(env3) {
@@ -50504,7 +50619,7 @@ function slotPortLaneEnd(defaultPort, step) {
50504
50619
  }
50505
50620
  function isPortInUse(port, host = "127.0.0.1") {
50506
50621
  try {
50507
- (0, import_child_process3.execSync)(`bash -c 'exec 3<>/dev/tcp/${host}/${port}'`, { stdio: "ignore" });
50622
+ (0, import_child_process4.execSync)(`bash -c 'exec 3<>/dev/tcp/${host}/${port}'`, { stdio: "ignore" });
50508
50623
  return true;
50509
50624
  } catch {
50510
50625
  return false;
@@ -50575,7 +50690,7 @@ function controlContainerOnPort(containers, port) {
50575
50690
  }
50576
50691
  function listDockerContainers() {
50577
50692
  try {
50578
- const raw = (0, import_child_process4.execSync)("docker ps --format {{.Names}}\\t{{.Ports}}", {
50693
+ const raw = (0, import_child_process5.execSync)("docker ps --format {{.Names}}\\t{{.Ports}}", {
50579
50694
  encoding: "utf8",
50580
50695
  stdio: ["pipe", "pipe", "ignore"],
50581
50696
  timeout: 3e3
@@ -50643,10 +50758,10 @@ function inspectControlUpReadiness(repoPath) {
50643
50758
  var fs32 = __toESM(require("fs"));
50644
50759
  var os7 = __toESM(require("os"));
50645
50760
  var path31 = __toESM(require("path"));
50646
- var import_child_process5 = require("child_process");
50761
+ var import_child_process6 = require("child_process");
50647
50762
  function runGit(cwd, args) {
50648
50763
  try {
50649
- return (0, import_child_process5.execSync)(`git ${args}`, {
50764
+ return (0, import_child_process6.execSync)(`git ${args}`, {
50650
50765
  cwd,
50651
50766
  encoding: "utf8",
50652
50767
  stdio: ["pipe", "pipe", "ignore"]
@@ -50812,10 +50927,10 @@ function checkLaunchGuard(repoPath, agentId, options = {}) {
50812
50927
  }
50813
50928
 
50814
50929
  // src/core/slot-preflight.ts
50815
- var import_child_process6 = require("child_process");
50930
+ var import_child_process7 = require("child_process");
50816
50931
  function listPm2Processes() {
50817
50932
  try {
50818
- const raw = (0, import_child_process6.execSync)("npx --yes pm2 jlist", {
50933
+ const raw = (0, import_child_process7.execSync)("npx --yes pm2 jlist", {
50819
50934
  encoding: "utf8",
50820
50935
  stdio: ["pipe", "pipe", "ignore"],
50821
50936
  timeout: 3e3
@@ -51039,7 +51154,7 @@ function formatPreflightReport(agentId, readiness) {
51039
51154
  var BYPASS_WARNING_MS = 15 * 60 * 1e3;
51040
51155
  function readGitRemote(repoPath) {
51041
51156
  try {
51042
- const remote = (0, import_child_process7.execSync)("git remote get-url origin", {
51157
+ const remote = (0, import_child_process8.execSync)("git remote get-url origin", {
51043
51158
  cwd: repoPath,
51044
51159
  encoding: "utf8",
51045
51160
  stdio: ["pipe", "pipe", "ignore"]
@@ -51051,7 +51166,7 @@ function readGitRemote(repoPath) {
51051
51166
  }
51052
51167
  function runGit2(cwd, args) {
51053
51168
  try {
51054
- return (0, import_child_process7.execSync)(`git ${args}`, {
51169
+ return (0, import_child_process8.execSync)(`git ${args}`, {
51055
51170
  cwd,
51056
51171
  encoding: "utf8",
51057
51172
  stdio: ["pipe", "pipe", "ignore"]
@@ -51127,7 +51242,7 @@ function lastBuildPass(run2) {
51127
51242
  }
51128
51243
  function listPm2Processes2() {
51129
51244
  try {
51130
- const raw = (0, import_child_process7.execSync)("npx --yes pm2 jlist", {
51245
+ const raw = (0, import_child_process8.execSync)("npx --yes pm2 jlist", {
51131
51246
  encoding: "utf8",
51132
51247
  stdio: ["pipe", "pipe", "ignore"],
51133
51248
  timeout: 3e3
@@ -51722,6 +51837,7 @@ function extractClaudeUsageFromRecords(records) {
51722
51837
  let tokensCacheRead = 0;
51723
51838
  let tokensCacheCreation = 0;
51724
51839
  let costUsd = null;
51840
+ const modelBreakdown = {};
51725
51841
  for (const record2 of records) {
51726
51842
  if (!record2 || typeof record2 !== "object") continue;
51727
51843
  const payload = record2;
@@ -51733,15 +51849,35 @@ function extractClaudeUsageFromRecords(records) {
51733
51849
  tokensCacheCreation = Number(usage2.cache_creation_input_tokens ?? 0);
51734
51850
  if (payload.total_cost_usd != null) costUsd = Number(payload.total_cost_usd);
51735
51851
  }
51736
- const nestedUsage = payload.usage ?? payload.message?.usage;
51852
+ const message = payload.message;
51853
+ const nestedUsage = payload.usage ?? message?.usage;
51737
51854
  if (nestedUsage && payload.type !== "result") {
51738
- tokensInput += Number(nestedUsage.input_tokens ?? 0);
51739
- tokensOutput += Number(nestedUsage.output_tokens ?? 0);
51740
- tokensCacheRead += Number(nestedUsage.cache_read_input_tokens ?? 0);
51741
- tokensCacheCreation += Number(nestedUsage.cache_creation_input_tokens ?? 0);
51855
+ const i2 = Number(nestedUsage.input_tokens ?? 0);
51856
+ const o2 = Number(nestedUsage.output_tokens ?? 0);
51857
+ const cr2 = Number(nestedUsage.cache_read_input_tokens ?? 0);
51858
+ const cc = Number(nestedUsage.cache_creation_input_tokens ?? 0);
51859
+ tokensInput += i2;
51860
+ tokensOutput += o2;
51861
+ tokensCacheRead += cr2;
51862
+ tokensCacheCreation += cc;
51863
+ const model = typeof message?.model === "string" ? message.model : void 0;
51864
+ if (model && model !== "<synthetic>") {
51865
+ const totals = modelBreakdown[model] ??= {
51866
+ tokensInput: 0,
51867
+ tokensOutput: 0,
51868
+ tokensCacheRead: 0,
51869
+ tokensCacheCreation: 0,
51870
+ tokensTotal: 0
51871
+ };
51872
+ totals.tokensInput += i2;
51873
+ totals.tokensOutput += o2;
51874
+ totals.tokensCacheRead += cr2;
51875
+ totals.tokensCacheCreation += cc;
51876
+ totals.tokensTotal += i2 + o2 + cr2 + cc;
51877
+ }
51742
51878
  }
51743
51879
  }
51744
- return { tokensInput, tokensOutput, tokensCacheRead, tokensCacheCreation, costUsd };
51880
+ return { tokensInput, tokensOutput, tokensCacheRead, tokensCacheCreation, costUsd, modelBreakdown };
51745
51881
  }
51746
51882
  function findMatchingClaudeTranscripts(slot) {
51747
51883
  const targets = [slot.workDir, slot.worktreePath].filter(Boolean);
@@ -51848,6 +51984,7 @@ function harvestClaudeUsage(slot) {
51848
51984
  tokensCacheCreation: best.tokensCacheCreation,
51849
51985
  tokensTotal,
51850
51986
  costUsd: best.costUsd,
51987
+ ...Object.keys(best.modelBreakdown).length > 0 ? { modelBreakdown: best.modelBreakdown } : {},
51851
51988
  sources: ["harvest"],
51852
51989
  firstSeenAt: slot.sessionCreatedAt ?? now,
51853
51990
  lastSeenAt: now
@@ -51995,6 +52132,166 @@ function harvestEventsForSlot(slot) {
51995
52132
  return harvestClaudeEvents(slot);
51996
52133
  }
51997
52134
 
52135
+ // src/core/control-persisted-usage.ts
52136
+ var path41 = __toESM(require("path"));
52137
+ var FETCH_TIMEOUT_MS = 3e3;
52138
+ async function getJson(url) {
52139
+ try {
52140
+ const response = await fetch(url, {
52141
+ method: "GET",
52142
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS)
52143
+ });
52144
+ if (!response.ok) return null;
52145
+ return await response.json();
52146
+ } catch {
52147
+ return null;
52148
+ }
52149
+ }
52150
+ async function resolveControlRepoId(apiUrl, repoPath) {
52151
+ const repos = await getJson(`${apiUrl}/api/repos`);
52152
+ if (!Array.isArray(repos)) return null;
52153
+ const target = path41.resolve(repoPath);
52154
+ return repos.find((repo) => path41.resolve(repo.path) === target)?.id ?? null;
52155
+ }
52156
+ function optionalString(value) {
52157
+ return value == null ? void 0 : value;
52158
+ }
52159
+ function toSources(value) {
52160
+ if (!Array.isArray(value)) return [];
52161
+ return value.filter((v2) => v2 === "otel" || v2 === "harvest");
52162
+ }
52163
+ function normalizeUsage(row) {
52164
+ return {
52165
+ sessionKey: row.sessionKey,
52166
+ agentId: row.agentId,
52167
+ agentTool: row.agentTool,
52168
+ ...optionalString(row.workDir) !== void 0 ? { workDir: row.workDir } : {},
52169
+ ...optionalString(row.branch) !== void 0 ? { branch: row.branch } : {},
52170
+ ...optionalString(row.suffix) !== void 0 ? { suffix: row.suffix } : {},
52171
+ ...optionalString(row.workUnitId) !== void 0 ? { workUnitId: row.workUnitId } : {},
52172
+ ...optionalString(row.attemptId) !== void 0 ? { attemptId: row.attemptId } : {},
52173
+ tokensInput: Number(row.tokensInput ?? 0),
52174
+ tokensOutput: Number(row.tokensOutput ?? 0),
52175
+ tokensCacheRead: Number(row.tokensCacheRead ?? 0),
52176
+ tokensCacheCreation: Number(row.tokensCacheCreation ?? 0),
52177
+ tokensTotal: Number(row.tokensTotal ?? 0),
52178
+ costUsd: row.costUsd == null ? null : Number(row.costUsd),
52179
+ ...row.modelBreakdown ? { modelBreakdown: row.modelBreakdown } : {},
52180
+ sources: toSources(row.sources),
52181
+ firstSeenAt: row.firstSeenAt,
52182
+ lastSeenAt: row.lastSeenAt
52183
+ };
52184
+ }
52185
+ function normalizeEvent(row) {
52186
+ return {
52187
+ sessionKey: row.sessionKey,
52188
+ agentId: row.agentId,
52189
+ agentTool: row.agentTool,
52190
+ eventName: row.eventName,
52191
+ sequence: Number(row.sequence ?? 0),
52192
+ timestamp: row.timestamp,
52193
+ ...optionalString(row.workUnitId) !== void 0 ? { workUnitId: row.workUnitId } : {},
52194
+ ...optionalString(row.attemptId) !== void 0 ? { attemptId: row.attemptId } : {},
52195
+ ...row.attributes ? { attributes: row.attributes } : {},
52196
+ promptText: row.promptText ?? null,
52197
+ responseText: row.responseText ?? null,
52198
+ rawTruncated: row.rawTruncated ?? null,
52199
+ source: row.source === "harvest" ? "harvest" : "otel"
52200
+ };
52201
+ }
52202
+ async function fetchPersistedPortalTelemetry(repoPath, apiUrl) {
52203
+ const repoId = await resolveControlRepoId(apiUrl, repoPath);
52204
+ if (!repoId) return { usage: [], events: [] };
52205
+ const [usageResponse, eventsResponse] = await Promise.all([
52206
+ getJson(`${apiUrl}/api/repos/${repoId}/usage`),
52207
+ getJson(`${apiUrl}/api/repos/${repoId}/events`)
52208
+ ]);
52209
+ return {
52210
+ usage: (usageResponse?.usage ?? []).map(normalizeUsage),
52211
+ events: (eventsResponse?.events ?? []).map(normalizeEvent)
52212
+ };
52213
+ }
52214
+
52215
+ // src/core/portal-usage-merge.ts
52216
+ var KEY_SEP = "\0";
52217
+ function usageKey(row) {
52218
+ return `${row.sessionKey}${KEY_SEP}${row.agentTool}`;
52219
+ }
52220
+ function eventKey(event) {
52221
+ return [event.sessionKey, event.agentTool, event.eventName, event.sequence ?? 0].join(KEY_SEP);
52222
+ }
52223
+ function num(value) {
52224
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
52225
+ }
52226
+ function earlier(a2, b2) {
52227
+ return new Date(a2).getTime() <= new Date(b2).getTime() ? a2 : b2;
52228
+ }
52229
+ function later(a2, b2) {
52230
+ return new Date(a2).getTime() >= new Date(b2).getTime() ? a2 : b2;
52231
+ }
52232
+ function mergeModelBreakdown(a2, b2) {
52233
+ if (!a2) return b2;
52234
+ if (!b2) return a2;
52235
+ const out = {};
52236
+ for (const model of /* @__PURE__ */ new Set([...Object.keys(a2), ...Object.keys(b2)])) {
52237
+ const left2 = a2[model];
52238
+ const right2 = b2[model];
52239
+ if (left2 && typeof left2 === "object" && right2 && typeof right2 === "object") {
52240
+ const l2 = left2;
52241
+ const r2 = right2;
52242
+ const totals = {};
52243
+ for (const field of /* @__PURE__ */ new Set([...Object.keys(l2), ...Object.keys(r2)])) {
52244
+ totals[field] = Math.max(num(l2[field]), num(r2[field]));
52245
+ }
52246
+ out[model] = totals;
52247
+ } else {
52248
+ out[model] = right2 ?? left2;
52249
+ }
52250
+ }
52251
+ return out;
52252
+ }
52253
+ function mergeUsageRow(a2, b2) {
52254
+ const costA = a2.costUsd ?? null;
52255
+ const costB = b2.costUsd ?? null;
52256
+ const costUsd = costA != null || costB != null ? Math.max(num(costA), num(costB)) : a2.costUsd ?? b2.costUsd;
52257
+ return {
52258
+ ...a2,
52259
+ ...b2,
52260
+ workDir: b2.workDir ?? a2.workDir,
52261
+ branch: b2.branch ?? a2.branch,
52262
+ suffix: b2.suffix ?? a2.suffix,
52263
+ workUnitId: b2.workUnitId ?? a2.workUnitId,
52264
+ attemptId: b2.attemptId ?? a2.attemptId,
52265
+ tokensInput: Math.max(num(a2.tokensInput), num(b2.tokensInput)),
52266
+ tokensOutput: Math.max(num(a2.tokensOutput), num(b2.tokensOutput)),
52267
+ tokensCacheRead: Math.max(num(a2.tokensCacheRead), num(b2.tokensCacheRead)),
52268
+ tokensCacheCreation: Math.max(num(a2.tokensCacheCreation), num(b2.tokensCacheCreation)),
52269
+ tokensTotal: Math.max(num(a2.tokensTotal), num(b2.tokensTotal)),
52270
+ costUsd,
52271
+ modelBreakdown: mergeModelBreakdown(a2.modelBreakdown, b2.modelBreakdown),
52272
+ sources: [.../* @__PURE__ */ new Set([...a2.sources ?? [], ...b2.sources ?? []])],
52273
+ firstSeenAt: earlier(a2.firstSeenAt, b2.firstSeenAt),
52274
+ lastSeenAt: later(a2.lastSeenAt, b2.lastSeenAt)
52275
+ };
52276
+ }
52277
+ function mergePortalUsage(live, persisted) {
52278
+ const merged = /* @__PURE__ */ new Map();
52279
+ for (const row of [...live, ...persisted]) {
52280
+ const key = usageKey(row);
52281
+ const existing = merged.get(key);
52282
+ merged.set(key, existing ? mergeUsageRow(existing, row) : row);
52283
+ }
52284
+ return [...merged.values()];
52285
+ }
52286
+ function dedupePortalEvents(live, persisted) {
52287
+ const merged = /* @__PURE__ */ new Map();
52288
+ for (const event of [...live, ...persisted]) {
52289
+ const key = eventKey(event);
52290
+ if (!merged.has(key)) merged.set(key, event);
52291
+ }
52292
+ return [...merged.values()];
52293
+ }
52294
+
51998
52295
  // src/core/control-sync.ts
51999
52296
  async function postJson(url, body, dryRun) {
52000
52297
  if (dryRun) return null;
@@ -52009,9 +52306,9 @@ async function postJson(url, body, dryRun) {
52009
52306
  }
52010
52307
  return await response.json();
52011
52308
  }
52012
- async function postPortalSync(target, body, dryRun) {
52309
+ async function postPortal(target, endpoint, body, dryRun) {
52013
52310
  if (dryRun) return;
52014
- const response = await fetch(`${target.url}/api/sync`, {
52311
+ const response = await fetch(`${target.url}${endpoint}`, {
52015
52312
  method: "POST",
52016
52313
  headers: {
52017
52314
  "Content-Type": "application/json",
@@ -52029,21 +52326,101 @@ async function postPortalSync(target, body, dryRun) {
52029
52326
  throw new Error(`har-portal sync failed: HTTP ${response.status}${text ? ` \u2014 ${text}` : ""}`);
52030
52327
  }
52031
52328
  }
52032
- function buildPortalSyncBody(repoPath) {
52329
+ function resolvePortalUserEmail() {
52330
+ return readPortalCredentials()?.email || void 0;
52331
+ }
52332
+ function dropNullFields(record2) {
52333
+ return Object.fromEntries(Object.entries(record2).filter(([, value]) => value !== null));
52334
+ }
52335
+ function modelsFromBreakdown(breakdown) {
52336
+ if (!breakdown) return [];
52337
+ return Object.entries(breakdown).map(([model, totals]) => ({
52338
+ model,
52339
+ ...totals && typeof totals === "object" ? totals : {}
52340
+ }));
52341
+ }
52342
+ async function collectPortalTelemetry(repoPath, slots, controlApiUrl) {
52343
+ if (!isTelemetryEnabled()) return { usage: [], events: [] };
52344
+ try {
52345
+ const userEmail = resolvePortalUserEmail();
52346
+ const liveUsage = slots.flatMap(
52347
+ (slot) => harvestUsageForSlot({
52348
+ agentId: slot.agentId,
52349
+ workDir: slot.workDir,
52350
+ worktreePath: slot.worktreePath,
52351
+ branch: slot.branch,
52352
+ suffix: slot.suffix,
52353
+ sessionCreatedAt: slot.sessionCreatedAt,
52354
+ repoPath
52355
+ }).map((row) => ({
52356
+ ...row,
52357
+ workUnitId: slot.workUnitId ?? row.workUnitId,
52358
+ attemptId: slot.attemptId ?? row.attemptId,
52359
+ sessionKey: row.sessionKey || buildSessionKey({
52360
+ branch: slot.branch,
52361
+ agentId: slot.agentId,
52362
+ suffix: slot.suffix,
52363
+ createdAt: slot.sessionCreatedAt
52364
+ })
52365
+ }))
52366
+ );
52367
+ const liveEvents = slots.flatMap(
52368
+ (slot) => harvestEventsForSlot({
52369
+ agentId: slot.agentId,
52370
+ workDir: slot.workDir,
52371
+ worktreePath: slot.worktreePath,
52372
+ branch: slot.branch,
52373
+ suffix: slot.suffix,
52374
+ sessionCreatedAt: slot.sessionCreatedAt,
52375
+ repoPath
52376
+ }).map((event) => ({
52377
+ ...event,
52378
+ workUnitId: slot.workUnitId ?? event.workUnitId,
52379
+ attemptId: slot.attemptId ?? event.attemptId
52380
+ }))
52381
+ );
52382
+ const persisted = await fetchPersistedPortalTelemetry(repoPath, controlApiUrl);
52383
+ const usage2 = mergePortalUsage(liveUsage, persisted.usage).map((row) => {
52384
+ const models = modelsFromBreakdown(row.modelBreakdown);
52385
+ return {
52386
+ ...row,
52387
+ ...userEmail ? { userEmail } : {},
52388
+ ...models.length > 0 ? { models } : {}
52389
+ };
52390
+ });
52391
+ const events = dedupePortalEvents(liveEvents, persisted.events).map(
52392
+ (event) => dropNullFields({ ...event })
52393
+ );
52394
+ return { usage: usage2, events };
52395
+ } catch {
52396
+ return { usage: [], events: [] };
52397
+ }
52398
+ }
52399
+ async function buildPortalPayload(repoPath, controlApiUrl) {
52033
52400
  const runs = listRuns(repoPath);
52034
52401
  const status = collectEnvironmentStatus(repoPath);
52035
52402
  const manifest = readManifest(repoPath);
52036
52403
  const stagesRegistry = readStageRegistry(repoPath);
52037
- const validations = listValidations(resolveHarnessRoot(repoPath));
52038
- return {
52404
+ const harnessRoot = resolveHarnessRoot(repoPath);
52405
+ const validations = listValidations(harnessRoot);
52406
+ const workUnits = listWorkUnits(harnessRoot);
52407
+ const attempts = listWorkAttempts(harnessRoot);
52408
+ const validationBindings = listValidationBindings(harnessRoot);
52409
+ const { usage: usage2, events } = await collectPortalTelemetry(repoPath, status.slots, controlApiUrl);
52410
+ const syncBody = {
52039
52411
  path: repoPath,
52040
52412
  ...manifest ? { manifest } : {},
52041
52413
  ...stagesRegistry ? { stagesRegistry } : {},
52042
52414
  runs,
52043
52415
  slots: status.slots,
52044
52416
  generatedAt: status.generatedAt,
52045
- ...validations.length > 0 ? { validations } : {}
52417
+ ...validations.length > 0 ? { validations } : {},
52418
+ ...workUnits.length > 0 ? { workUnits } : {},
52419
+ ...attempts.length > 0 ? { attempts } : {},
52420
+ ...validationBindings.length > 0 ? { validationBindings } : {},
52421
+ ...usage2.length > 0 ? { usage: usage2 } : {}
52046
52422
  };
52423
+ return { syncBody, events };
52047
52424
  }
52048
52425
  async function isControlApiReachable(apiUrl = getControlApiUrl()) {
52049
52426
  try {
@@ -52060,7 +52437,7 @@ async function waitForControlApi(apiUrl = getControlApiUrl(), timeoutMs = 6e4, i
52060
52437
  const deadline = Date.now() + timeoutMs;
52061
52438
  while (Date.now() < deadline) {
52062
52439
  if (await isControlApiReachable(apiUrl)) return true;
52063
- await new Promise((resolve38) => setTimeout(resolve38, intervalMs));
52440
+ await new Promise((resolve39) => setTimeout(resolve39, intervalMs));
52064
52441
  }
52065
52442
  return false;
52066
52443
  }
@@ -52161,7 +52538,16 @@ async function syncRepoWithControl(options) {
52161
52538
  }
52162
52539
  const portal = getPortalTarget();
52163
52540
  if (portal) {
52164
- await postPortalSync(portal, buildPortalSyncBody(repoPath), options.dryRun);
52541
+ const { syncBody, events } = await buildPortalPayload(repoPath, apiUrl);
52542
+ await postPortal(portal, "/api/sync", syncBody, options.dryRun);
52543
+ if (events.length > 0) {
52544
+ await postPortal(
52545
+ portal,
52546
+ "/api/otel",
52547
+ { path: repoPath, events, spans: [] },
52548
+ options.dryRun
52549
+ );
52550
+ }
52165
52551
  return;
52166
52552
  }
52167
52553
  const registerResult = await registerRepoWithControl({ ...options, repoPath });
@@ -52170,7 +52556,7 @@ async function syncRepoWithControl(options) {
52170
52556
  const listResponse = await fetch(`${apiUrl}/api/repos`);
52171
52557
  if (!listResponse.ok) throw new Error("Failed to list repos from Control API");
52172
52558
  const repos = await listResponse.json();
52173
- const existing = repos.find((r2) => path41.resolve(r2.path) === repoPath);
52559
+ const existing = repos.find((r2) => path42.resolve(r2.path) === repoPath);
52174
52560
  if (!existing) {
52175
52561
  return;
52176
52562
  }
@@ -52322,8 +52708,8 @@ function checkLaunchGuard2(repoPath, agentId, options = {}) {
52322
52708
  init_control_config();
52323
52709
 
52324
52710
  // src/core/control-lifecycle.ts
52325
- var import_child_process8 = require("child_process");
52326
- var path42 = __toESM(require("path"));
52711
+ var import_child_process9 = require("child_process");
52712
+ var path43 = __toESM(require("path"));
52327
52713
 
52328
52714
  // src/core/control-image.ts
52329
52715
  var DEFAULT_CONTROL_IMAGE = "theosfactory/har-control";
@@ -52347,10 +52733,10 @@ var CONTROL_DATA_VOLUME = "har_control_data";
52347
52733
  var CONTROL_CONTAINER_PORT = 3847;
52348
52734
  var CONTROL_DATA_DB_URL = "file:/data/har_control.db";
52349
52735
  function resolveControlDir() {
52350
- return path42.resolve(__dirname, "..", "control");
52736
+ return path43.resolve(__dirname, "..", "control");
52351
52737
  }
52352
52738
  function resolveControlBuildContext() {
52353
- return path42.resolve(resolveControlDir(), "..");
52739
+ return path43.resolve(resolveControlDir(), "..");
52354
52740
  }
52355
52741
  function buildDockerRunArgs(options) {
52356
52742
  const name = options.containerName ?? CONTROL_CONTAINER_NAME;
@@ -52373,7 +52759,7 @@ function buildDockerRunArgs(options) {
52373
52759
  return args;
52374
52760
  }
52375
52761
  function runDocker(args) {
52376
- const result = (0, import_child_process8.spawnSync)("docker", args, {
52762
+ const result = (0, import_child_process9.spawnSync)("docker", args, {
52377
52763
  stdio: "inherit",
52378
52764
  env: process.env
52379
52765
  });
@@ -52383,7 +52769,7 @@ function runDocker(args) {
52383
52769
  return result.status ?? 1;
52384
52770
  }
52385
52771
  function controlContainerExists(name = CONTROL_CONTAINER_NAME) {
52386
- const result = (0, import_child_process8.spawnSync)("docker", ["ps", "-aq", "-f", `name=^${name}$`], {
52772
+ const result = (0, import_child_process9.spawnSync)("docker", ["ps", "-aq", "-f", `name=^${name}$`], {
52387
52773
  encoding: "utf8",
52388
52774
  stdio: ["pipe", "pipe", "ignore"]
52389
52775
  });
@@ -52406,7 +52792,7 @@ async function startMissionControl(options) {
52406
52792
  "-t",
52407
52793
  imageRef,
52408
52794
  "-f",
52409
- path42.join(resolveControlDir(), "Dockerfile"),
52795
+ path43.join(resolveControlDir(), "Dockerfile"),
52410
52796
  resolveControlBuildContext()
52411
52797
  ]);
52412
52798
  if (buildCode !== 0) {
@@ -52550,7 +52936,7 @@ async function ensureTelemetryInfrastructure(options) {
52550
52936
 
52551
52937
  // src/core/run-service.ts
52552
52938
  init_telemetry_config();
52553
- var path44 = __toESM(require("path"));
52939
+ var path45 = __toESM(require("path"));
52554
52940
  function extractShellOutput(result) {
52555
52941
  const stdout = result.logs?.find((log) => log.stream === "stdout")?.content ?? result.logs?.find((log) => !log.stream)?.content ?? "";
52556
52942
  const stderr = result.logs?.find((log) => log.stream === "stderr")?.content ?? "";
@@ -52760,12 +53146,12 @@ Usage from Cursor / Claude / Codex (opentelemetry-hooks) will appear under Workt
52760
53146
  suffix: session.suffix,
52761
53147
  createdAt: session.createdAt
52762
53148
  });
52763
- const envFile = path44.join(session.workDir, `.env.agent.${options.agentId}`);
53149
+ const envFile = path45.join(session.workDir, `.env.agent.${options.agentId}`);
52764
53150
  try {
52765
53151
  appendTelemetryEnvToFile(envFile, {
52766
53152
  sessionKey,
52767
53153
  agentId: options.agentId,
52768
- repoPath: path44.resolve(options.repoPath),
53154
+ repoPath: path45.resolve(options.repoPath),
52769
53155
  workDir: session.workDir,
52770
53156
  branch: session.branch,
52771
53157
  suffix: session.suffix,
@@ -52994,12 +53380,12 @@ var getEnvironmentStatus = defaultRunService.getEnvironmentStatus.bind(defaultRu
52994
53380
  var getEnvironmentLogs = defaultRunService.getEnvironmentLogs.bind(defaultRunService);
52995
53381
 
52996
53382
  // src/core/commit-gate-onboarding.ts
52997
- var readline5 = __toESM(require("readline"));
53383
+ var readline6 = __toESM(require("readline"));
52998
53384
 
52999
53385
  // src/core/hooks.ts
53000
53386
  var fs42 = __toESM(require("fs"));
53001
53387
  var os14 = __toESM(require("os"));
53002
- var path45 = __toESM(require("path"));
53388
+ var path46 = __toESM(require("path"));
53003
53389
  var MARKER_START = "# >>> har commit gate (managed by `har hooks`) >>>";
53004
53390
  var MARKER_END = "# <<< har commit gate <<<";
53005
53391
  var PRE_COMMIT_BLOCK = [
@@ -53024,7 +53410,7 @@ function resolveCheckoutRoot(cwd) {
53024
53410
  function resolveHooksDir(checkoutDir) {
53025
53411
  const hooksPath = tryGit3(checkoutDir, "rev-parse --git-path hooks");
53026
53412
  if (!hooksPath) throw new Error(`Not a git checkout: ${checkoutDir}`);
53027
- return path45.resolve(checkoutDir, hooksPath);
53413
+ return path46.resolve(checkoutDir, hooksPath);
53028
53414
  }
53029
53415
  function getConfiguredHooksPath(checkoutDir) {
53030
53416
  return tryGit3(checkoutDir, "config core.hooksPath") || void 0;
@@ -53032,9 +53418,9 @@ function getConfiguredHooksPath(checkoutDir) {
53032
53418
  function defaultHarInvocation() {
53033
53419
  const entry = process.argv[1];
53034
53420
  if (entry && entry.endsWith(".js")) {
53035
- return `"${process.execPath}" "${path45.resolve(entry)}"`;
53421
+ return `"${process.execPath}" "${path46.resolve(entry)}"`;
53036
53422
  }
53037
- if (entry) return `"${path45.resolve(entry)}"`;
53423
+ if (entry) return `"${path46.resolve(entry)}"`;
53038
53424
  return "har";
53039
53425
  }
53040
53426
  function buildHookScript(harInvocation, subcommand, failOpenNotice) {
@@ -53113,17 +53499,17 @@ Or re-run with --force to write into that directory anyway.`
53113
53499
  fs42.mkdirSync(hooksDir, { recursive: true });
53114
53500
  const invocation = options.harInvocation ?? defaultHarInvocation();
53115
53501
  fs42.writeFileSync(
53116
- path45.join(hooksDir, "har-pre-commit"),
53502
+ path46.join(hooksDir, "har-pre-commit"),
53117
53503
  buildHookScript(invocation, "check", "har: binary not found; skipping commit gate (reinstall with har hooks install)"),
53118
53504
  { mode: 493 }
53119
53505
  );
53120
53506
  fs42.writeFileSync(
53121
- path45.join(hooksDir, "har-post-commit"),
53507
+ path46.join(hooksDir, "har-post-commit"),
53122
53508
  buildHookScript(invocation, "record-commit", "har: binary not found; skipping commit association"),
53123
53509
  { mode: 493 }
53124
53510
  );
53125
- const preCommit = upsertMarkedBlock(path45.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
53126
- const postCommit = upsertMarkedBlock(path45.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
53511
+ const preCommit = upsertMarkedBlock(path46.join(hooksDir, "pre-commit"), PRE_COMMIT_BLOCK);
53512
+ const postCommit = upsertMarkedBlock(path46.join(hooksDir, "post-commit"), POST_COMMIT_BLOCK);
53127
53513
  ensureValidationsIgnored(checkout);
53128
53514
  return { hooksDir, preCommit, postCommit };
53129
53515
  }
@@ -53132,10 +53518,10 @@ function uninstallHooks(repoPath) {
53132
53518
  if (!checkout) throw new Error(`Not a git repository: ${repoPath}`);
53133
53519
  const hooksDir = resolveHooksDir(checkout);
53134
53520
  let removed = false;
53135
- removed = removeMarkedBlock(path45.join(hooksDir, "pre-commit")) || removed;
53136
- removed = removeMarkedBlock(path45.join(hooksDir, "post-commit")) || removed;
53521
+ removed = removeMarkedBlock(path46.join(hooksDir, "pre-commit")) || removed;
53522
+ removed = removeMarkedBlock(path46.join(hooksDir, "post-commit")) || removed;
53137
53523
  for (const file of ["har-pre-commit", "har-post-commit"]) {
53138
- const full = path45.join(hooksDir, file);
53524
+ const full = path46.join(hooksDir, file);
53139
53525
  if (fs42.existsSync(full)) {
53140
53526
  fs42.rmSync(full);
53141
53527
  removed = true;
@@ -53156,10 +53542,10 @@ function isAgentWorktree(checkoutDir) {
53156
53542
  if (branch && (/^har-agent-\d+$/.test(branch) || /-har-agent-\d+-[a-z0-9]+$/.test(branch))) {
53157
53543
  return true;
53158
53544
  }
53159
- const worktreesRoot = path45.join(os14.homedir(), "worktrees");
53160
- const resolved = path45.resolve(checkoutDir);
53161
- const name = path45.basename(resolved);
53162
- return resolved.startsWith(`${worktreesRoot}${path45.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
53545
+ const worktreesRoot = path46.join(os14.homedir(), "worktrees");
53546
+ const resolved = path46.resolve(checkoutDir);
53547
+ const name = path46.basename(resolved);
53548
+ return resolved.startsWith(`${worktreesRoot}${path46.sep}`) && (/-agent-\d+$/.test(name) || /-har-agent-\d+-[a-z0-9]+$/.test(name));
53163
53549
  }
53164
53550
  function resolveEffectiveMode(checkoutDir, gate) {
53165
53551
  if (!gate.enabled) return "off";
@@ -53172,15 +53558,15 @@ function getHooksStatus(repoPath) {
53172
53558
  const hooksDir = resolveHooksDir(checkout);
53173
53559
  const gate = getCommitGateConfig(checkout);
53174
53560
  const hasBlock = (name) => {
53175
- const file = path45.join(hooksDir, name);
53561
+ const file = path46.join(hooksDir, name);
53176
53562
  return fs42.existsSync(file) && fs42.readFileSync(file, "utf8").includes(MARKER_START);
53177
53563
  };
53178
53564
  return {
53179
53565
  checkout,
53180
53566
  hooksDir,
53181
53567
  configuredHooksPath: getConfiguredHooksPath(checkout),
53182
- preCommitInstalled: hasBlock("pre-commit") && fs42.existsSync(path45.join(hooksDir, "har-pre-commit")),
53183
- postCommitInstalled: hasBlock("post-commit") && fs42.existsSync(path45.join(hooksDir, "har-post-commit")),
53568
+ preCommitInstalled: hasBlock("pre-commit") && fs42.existsSync(path46.join(hooksDir, "har-pre-commit")),
53569
+ postCommitInstalled: hasBlock("post-commit") && fs42.existsSync(path46.join(hooksDir, "har-post-commit")),
53184
53570
  gate,
53185
53571
  effectiveMode: resolveEffectiveMode(checkout, gate)
53186
53572
  };
@@ -53191,7 +53577,7 @@ function checkCommitGate(cwd) {
53191
53577
  }
53192
53578
  const checkout = resolveCheckoutRoot(cwd);
53193
53579
  if (!checkout) return { exitCode: 0, messages: [] };
53194
- if (!fs42.existsSync(path45.join(checkout, ".har", "stages.json"))) {
53580
+ if (!fs42.existsSync(path46.join(checkout, ".har", "stages.json"))) {
53195
53581
  return { exitCode: 0, messages: [] };
53196
53582
  }
53197
53583
  const gate = getCommitGateConfig(checkout);
@@ -53262,14 +53648,14 @@ async function recordCommitAssociation(cwd) {
53262
53648
  }
53263
53649
 
53264
53650
  // src/core/commit-gate-onboarding.ts
53265
- function askYesNo4(question) {
53266
- const rl = readline5.createInterface({ input: process.stdin, output: process.stderr });
53267
- return new Promise((resolve38) => {
53651
+ function askYesNo5(question) {
53652
+ const rl = readline6.createInterface({ input: process.stdin, output: process.stderr });
53653
+ return new Promise((resolve39) => {
53268
53654
  process.stderr.write(`${question} `);
53269
53655
  rl.once("line", (answer) => {
53270
53656
  rl.close();
53271
53657
  const trimmed = answer.trim();
53272
- resolve38(trimmed === "" || /^y(es)?$/i.test(trimmed));
53658
+ resolve39(trimmed === "" || /^y(es)?$/i.test(trimmed));
53273
53659
  });
53274
53660
  });
53275
53661
  }
@@ -53294,7 +53680,7 @@ async function handleCommitGateOnboarding(options) {
53294
53680
  const status = getHooksStatus(options.repoPath);
53295
53681
  let shouldInstall = status.preCommitInstalled || status.postCommitInstalled || options.install === "always" || options.autoYes === true;
53296
53682
  if (!shouldInstall && options.install === "prompt" && process.stdin.isTTY && process.stdout.isTTY) {
53297
- shouldInstall = await askYesNo4("Install the HAR commit gate for this repository? [Y/n]");
53683
+ shouldInstall = await askYesNo5("Install the HAR commit gate for this repository? [Y/n]");
53298
53684
  }
53299
53685
  if (!shouldInstall) {
53300
53686
  info("Commit gate is not installed; run `har hooks install` when ready.");
@@ -53313,12 +53699,12 @@ async function handleCommitGateOnboarding(options) {
53313
53699
  // src/core/onboarding-preferences.ts
53314
53700
  var fs43 = __toESM(require("fs"));
53315
53701
  var os15 = __toESM(require("os"));
53316
- var path46 = __toESM(require("path"));
53702
+ var path47 = __toESM(require("path"));
53317
53703
  function getOnboardingPreferencesPath() {
53318
53704
  if (process.env.HAR_PREFERENCES_PATH) {
53319
- return path46.resolve(process.env.HAR_PREFERENCES_PATH);
53705
+ return path47.resolve(process.env.HAR_PREFERENCES_PATH);
53320
53706
  }
53321
- return path46.join(os15.homedir(), ".har", "preferences.json");
53707
+ return path47.join(os15.homedir(), ".har", "preferences.json");
53322
53708
  }
53323
53709
  function readOnboardingPreferences() {
53324
53710
  const preferencePath = getOnboardingPreferencesPath();
@@ -53349,7 +53735,7 @@ function writeOnboardingPreferences(overrides) {
53349
53735
  };
53350
53736
  const parsed = OnboardingPreferencesSchema.parse(preference);
53351
53737
  const preferencePath = getOnboardingPreferencesPath();
53352
- fs43.mkdirSync(path46.dirname(preferencePath), { recursive: true });
53738
+ fs43.mkdirSync(path47.dirname(preferencePath), { recursive: true });
53353
53739
  fs43.writeFileSync(preferencePath, `${JSON.stringify(parsed, null, 2)}
53354
53740
  `);
53355
53741
  return parsed;
@@ -53630,7 +54016,7 @@ var envCommand = {
53630
54016
  }
53631
54017
  };
53632
54018
  async function handleInit(argv) {
53633
- const repoPath = path47.resolve(argv.repo);
54019
+ const repoPath = path48.resolve(argv.repo);
53634
54020
  const onboarding = resolveOnboardingOptions(argv);
53635
54021
  header("har env init");
53636
54022
  info(`Repository: ${repoPath}`);
@@ -53664,7 +54050,7 @@ async function handleInit(argv) {
53664
54050
  if (argv.auto) {
53665
54051
  await handleAgentMdProposal(repoPath, argv.yes);
53666
54052
  } else {
53667
- emitManualAdaptationPrompt(repoPath, "init", argv.profile);
54053
+ await emitManualAdaptationPrompt(repoPath, "init", argv.profile, void 0, argv.yes);
53668
54054
  }
53669
54055
  divider();
53670
54056
  success("Harness initialized!");
@@ -53694,7 +54080,7 @@ async function handleInit(argv) {
53694
54080
  }
53695
54081
  }
53696
54082
  async function handleMaintain(argv) {
53697
- const repoPath = path47.resolve(argv.repo);
54083
+ const repoPath = path48.resolve(argv.repo);
53698
54084
  const onboarding = resolveOnboardingOptions(argv);
53699
54085
  header("har env maintain");
53700
54086
  info(`Repository: ${repoPath}`);
@@ -53736,7 +54122,13 @@ async function handleMaintain(argv) {
53736
54122
  if (!result.validation.pass) {
53737
54123
  warn("Harness has validation errors \u2014 fix them before running --finalize.");
53738
54124
  }
53739
- emitManualAdaptationPrompt(repoPath, "maintain", "default", result.bundle?.report);
54125
+ await emitManualAdaptationPrompt(
54126
+ repoPath,
54127
+ "maintain",
54128
+ "default",
54129
+ result.bundle?.report,
54130
+ argv.yes
54131
+ );
53740
54132
  info("After your coding agent finishes adapting, record it with: har env maintain --finalize");
53741
54133
  }
53742
54134
  divider();
@@ -53788,7 +54180,7 @@ function resolveOnboardingOptions(argv) {
53788
54180
  }
53789
54181
  };
53790
54182
  }
53791
- function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleReport) {
54183
+ async function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleReport, autoYes = false) {
53792
54184
  const prompt2 = mode === "init" ? buildInitAdaptationPrompt(repoPath, profile) : buildMaintainAdaptationPrompt(repoPath, bundleReport);
53793
54185
  writeAdaptationPrompt(repoPath, prompt2);
53794
54186
  process.stderr.write("\n");
@@ -53804,12 +54196,13 @@ function emitManualAdaptationPrompt(repoPath, mode, profile = "default", bundleR
53804
54196
  info(" Reference templates are in .har/maintain/templates/");
53805
54197
  }
53806
54198
  printAdaptationPrompt(prompt2);
54199
+ await offerAdaptationPromptClipboard(prompt2, { autoYes });
53807
54200
  }
53808
54201
  async function handleAgentMdProposal(repoPath, autoYes) {
53809
54202
  if (autoYes) {
53810
54203
  const proposal = readAgentMdProposal(repoPath);
53811
54204
  if (proposal) {
53812
- writeFileSafe(path47.join(repoPath, "AGENT.md"), proposal.content);
54205
+ writeFileSafe(path48.join(repoPath, "AGENT.md"), proposal.content);
53813
54206
  clearAgentMdProposal(repoPath);
53814
54207
  info("Applied AGENT.md proposal (--yes)");
53815
54208
  }
@@ -53818,7 +54211,7 @@ async function handleAgentMdProposal(repoPath, autoYes) {
53818
54211
  await promptApplyAgentMdProposal(repoPath);
53819
54212
  }
53820
54213
  async function handleAddStage(argv) {
53821
- const repoPath = path47.resolve(argv.repo);
54214
+ const repoPath = path48.resolve(argv.repo);
53822
54215
  const available = listStageTemplateIds();
53823
54216
  if (argv.list) {
53824
54217
  for (const id of available) {
@@ -53895,7 +54288,7 @@ async function handleAddStage(argv) {
53895
54288
  }
53896
54289
  }
53897
54290
  async function handlePreflight(argv) {
53898
- const repo = path47.resolve(argv.repo);
54291
+ const repo = path48.resolve(argv.repo);
53899
54292
  const agentId = validateAgentId(argv.id, repo);
53900
54293
  const result = await preflightEnvironment({
53901
54294
  repoPath: repo,
@@ -53913,7 +54306,7 @@ async function handlePreflight(argv) {
53913
54306
  process.exit(result.code);
53914
54307
  }
53915
54308
  async function handleLaunch(argv) {
53916
- const repo = path47.resolve(argv.repo);
54309
+ const repo = path48.resolve(argv.repo);
53917
54310
  const agentId = validateAgentId(argv.id, repo);
53918
54311
  let confirmReplace = argv.replace;
53919
54312
  let force = argv.force;
@@ -53923,10 +54316,10 @@ async function handleLaunch(argv) {
53923
54316
  if (!confirmReplace && process.stdin.isTTY && process.stdout.isTTY) {
53924
54317
  warn("Occupied slot \u2014 review before replacing:");
53925
54318
  console.error(guard.reason ?? "");
53926
- const readline9 = await import("readline");
53927
- const rl = readline9.createInterface({ input: process.stdin, output: process.stderr });
53928
- const answer = await new Promise((resolve38) => {
53929
- rl.question("Replace this slot? [y/N] ", resolve38);
54319
+ const readline10 = await import("readline");
54320
+ const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
54321
+ const answer = await new Promise((resolve39) => {
54322
+ rl.question("Replace this slot? [y/N] ", resolve39);
53930
54323
  });
53931
54324
  rl.close();
53932
54325
  if (!/^[Yy]$/.test(answer.trim())) {
@@ -53940,10 +54333,10 @@ async function handleLaunch(argv) {
53940
54333
  if (!guardAfterConfirm.allowed && guardAfterConfirm.blocked && guardAfterConfirm.slot?.dirty) {
53941
54334
  if (!force && process.stdin.isTTY && process.stdout.isTTY) {
53942
54335
  warn("Worktree has uncommitted changes.");
53943
- const readline9 = await import("readline");
53944
- const rl = readline9.createInterface({ input: process.stdin, output: process.stderr });
53945
- const answer = await new Promise((resolve38) => {
53946
- rl.question("Discard uncommitted changes? [y/N] ", resolve38);
54336
+ const readline10 = await import("readline");
54337
+ const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
54338
+ const answer = await new Promise((resolve39) => {
54339
+ rl.question("Discard uncommitted changes? [y/N] ", resolve39);
53947
54340
  });
53948
54341
  rl.close();
53949
54342
  if (!/^[Yy]$/.test(answer.trim())) {
@@ -54007,7 +54400,7 @@ async function handleRecover(argv) {
54007
54400
  });
54008
54401
  }
54009
54402
  async function handleVerify(argv) {
54010
- const repo = path47.resolve(argv.repo);
54403
+ const repo = path48.resolve(argv.repo);
54011
54404
  const agentId = validateAgentId(argv.id, repo);
54012
54405
  const result = await runVerification({
54013
54406
  repoPath: repo,
@@ -54019,7 +54412,7 @@ async function handleVerify(argv) {
54019
54412
  process.exit(result.code);
54020
54413
  }
54021
54414
  async function handleTeardown(argv) {
54022
- const repo = path47.resolve(argv.repo);
54415
+ const repo = path48.resolve(argv.repo);
54023
54416
  const agentId = validateAgentId(argv.id, repo);
54024
54417
  const result = await teardownEnvironment({
54025
54418
  repoPath: repo,
@@ -54030,7 +54423,7 @@ async function handleTeardown(argv) {
54030
54423
  process.exit(result.code);
54031
54424
  }
54032
54425
  async function handleComplete(argv) {
54033
- const repo = path47.resolve(argv.repo);
54426
+ const repo = path48.resolve(argv.repo);
54034
54427
  const agentId = validateAgentId(argv.id, repo);
54035
54428
  const result = await completeEnvironment({
54036
54429
  repoPath: repo,
@@ -54051,7 +54444,7 @@ async function handleComplete(argv) {
54051
54444
  process.exit(result.code);
54052
54445
  }
54053
54446
  async function handleStatus(argv) {
54054
- const repoPath = path47.resolve(argv.repo);
54447
+ const repoPath = path48.resolve(argv.repo);
54055
54448
  if (argv.json) {
54056
54449
  const status = collectEnvironmentStatus(repoPath);
54057
54450
  const output = EnvironmentStatusSchema.parse(status);
@@ -54064,7 +54457,7 @@ async function handleStatus(argv) {
54064
54457
  });
54065
54458
  }
54066
54459
  async function handleRunsList(argv) {
54067
- const repoPath = path47.resolve(argv.repo);
54460
+ const repoPath = path48.resolve(argv.repo);
54068
54461
  const runs = listRuns(repoPath, { stageId: argv.stage, limit: argv.limit });
54069
54462
  if (argv.json) {
54070
54463
  process.stdout.write(JSON.stringify({ runs }, null, 2) + "\n");
@@ -54081,7 +54474,7 @@ async function handleRunsList(argv) {
54081
54474
  }
54082
54475
  }
54083
54476
  async function handleRunsGet(argv) {
54084
- const run2 = getRun(path47.resolve(argv.repo), argv.runId);
54477
+ const run2 = getRun(path48.resolve(argv.repo), argv.runId);
54085
54478
  if (!run2) {
54086
54479
  error(`Run not found: ${argv.runId}`);
54087
54480
  process.exit(1);
@@ -54146,7 +54539,7 @@ function printNextSteps(auto2) {
54146
54539
  console.error("");
54147
54540
  console.error(" Read: .har/README.md");
54148
54541
  if (!auto2) {
54149
- console.error(" Adapt: paste prompt above into your coding agent");
54542
+ console.error(" Adapt: paste clipboard / prompt above into your coding agent");
54150
54543
  console.error(" Prompt file: .har/ADAPT-PROMPT.md");
54151
54544
  } else {
54152
54545
  console.error(" Agent guide: AGENT.md (repo root, if applied)");
@@ -54160,20 +54553,20 @@ function printNextSteps(auto2) {
54160
54553
  }
54161
54554
 
54162
54555
  // src/cli/commands/control.ts
54163
- var path49 = __toESM(require("path"));
54556
+ var path50 = __toESM(require("path"));
54164
54557
  init_control_config();
54165
54558
  init_portal_credentials();
54166
54559
 
54167
54560
  // src/core/portal-login.ts
54168
54561
  var http = __toESM(require("http"));
54169
54562
  var import_crypto = require("crypto");
54170
- var import_child_process10 = require("child_process");
54563
+ var import_child_process11 = require("child_process");
54171
54564
  var CALLBACK_PATH = "/callback";
54172
54565
  var LOGIN_TIMEOUT_MS = 3 * 6e4;
54173
54566
  function openBrowser(url) {
54174
54567
  const [cmd, args] = process.platform === "darwin" ? ["open", [url]] : process.platform === "win32" ? ["cmd", ["/c", "start", "", url]] : ["xdg-open", [url]];
54175
54568
  try {
54176
- const child = (0, import_child_process10.spawn)(cmd, args, { stdio: "ignore", detached: true });
54569
+ const child = (0, import_child_process11.spawn)(cmd, args, { stdio: "ignore", detached: true });
54177
54570
  child.on("error", () => {
54178
54571
  });
54179
54572
  child.unref();
@@ -54182,7 +54575,7 @@ function openBrowser(url) {
54182
54575
  }
54183
54576
  async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
54184
54577
  const state = (0, import_crypto.randomUUID)();
54185
- return new Promise((resolve38, reject) => {
54578
+ return new Promise((resolve39, reject) => {
54186
54579
  let timer;
54187
54580
  const server = http.createServer((req, res) => {
54188
54581
  const requestUrl = new URL(req.url ?? "", "http://127.0.0.1");
@@ -54194,6 +54587,7 @@ async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
54194
54587
  const token = requestUrl.searchParams.get("token");
54195
54588
  const returnedState = requestUrl.searchParams.get("state");
54196
54589
  const workspace = requestUrl.searchParams.get("workspace") ?? void 0;
54590
+ const email2 = requestUrl.searchParams.get("email") ?? void 0;
54197
54591
  if (returnedState !== state || !token) {
54198
54592
  res.writeHead(400, { "Content-Type": "text/html" });
54199
54593
  res.end("<h1>Login failed</h1><p>You can close this tab and try again.</p>");
@@ -54204,7 +54598,7 @@ async function loginViaBrowser(portalUrl, openUrl = openBrowser) {
54204
54598
  res.writeHead(200, { "Content-Type": "text/html" });
54205
54599
  res.end("<h1>Logged in</h1><p>You can close this tab and return to the terminal.</p>");
54206
54600
  cleanup();
54207
- resolve38({ portalUrl, token, workspace, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
54601
+ resolve39({ portalUrl, token, workspace, email: email2, createdAt: (/* @__PURE__ */ new Date()).toISOString() });
54208
54602
  });
54209
54603
  const cleanup = () => {
54210
54604
  clearTimeout(timer);
@@ -54232,13 +54626,13 @@ If your browser did not open, paste that URL.
54232
54626
 
54233
54627
  // src/core/control-unregister.ts
54234
54628
  var fs44 = __toESM(require("fs"));
54235
- var path48 = __toESM(require("path"));
54629
+ var path49 = __toESM(require("path"));
54236
54630
  init_control_config();
54237
54631
  function listUnregisterWorktreeCandidates(repoPath) {
54238
54632
  const harnessRoot = canonicalizeControlRepoPath(repoPath);
54239
54633
  const byPath = /* @__PURE__ */ new Map();
54240
54634
  const add = (partial2) => {
54241
- const resolved = path48.resolve(partial2.worktreePath);
54635
+ const resolved = path49.resolve(partial2.worktreePath);
54242
54636
  if (!resolved || resolved === harnessRoot) return;
54243
54637
  const exists = partial2.exists ?? fs44.existsSync(resolved);
54244
54638
  const prev = byPath.get(resolved);
@@ -54287,12 +54681,12 @@ function listUnregisterWorktreeCandidates(repoPath) {
54287
54681
  }
54288
54682
  return [...byPath.values()].sort((a2, b2) => a2.agentId - b2.agentId);
54289
54683
  }
54290
- async function askYesNo5(question) {
54684
+ async function askYesNo6(question) {
54291
54685
  if (!process.stdin.isTTY || !process.stdout.isTTY) return false;
54292
- const readline9 = await import("readline");
54293
- const rl = readline9.createInterface({ input: process.stdin, output: process.stderr });
54294
- const answer = await new Promise((resolve38) => {
54295
- rl.question(question, resolve38);
54686
+ const readline10 = await import("readline");
54687
+ const rl = readline10.createInterface({ input: process.stdin, output: process.stderr });
54688
+ const answer = await new Promise((resolve39) => {
54689
+ rl.question(question, resolve39);
54296
54690
  });
54297
54691
  rl.close();
54298
54692
  return /^[Yy]$/.test(answer.trim());
@@ -54304,7 +54698,7 @@ async function confirmUnregister(options) {
54304
54698
  if (!process.stdin.isTTY || !process.stdout.isTTY) {
54305
54699
  throw new Error("Non-interactive terminal \u2014 pass --yes (and optionally --delete-worktrees)");
54306
54700
  }
54307
- const proceed = await askYesNo5("Unregister this repository from Mission Control? [y/N] ");
54701
+ const proceed = await askYesNo6("Unregister this repository from Mission Control? [y/N] ");
54308
54702
  if (!proceed) return { proceed: false, deleteWorktrees: false };
54309
54703
  const existing = options.worktrees.filter((w2) => w2.exists);
54310
54704
  if (existing.length === 0) {
@@ -54316,7 +54710,7 @@ async function confirmUnregister(options) {
54316
54710
  process.stderr.write(` agent-${wt2.agentId}: ${wt2.worktreePath}${dirty}
54317
54711
  `);
54318
54712
  }
54319
- const deleteWorktrees = await askYesNo5(
54713
+ const deleteWorktrees = await askYesNo6(
54320
54714
  `Also delete ${existing.length} session worktree(s) on disk? [y/N] `
54321
54715
  );
54322
54716
  return { proceed: true, deleteWorktrees };
@@ -54560,7 +54954,7 @@ async function handleDown() {
54560
54954
  process.exit(code);
54561
54955
  }
54562
54956
  async function handleRegister(argv) {
54563
- const repoPath = path49.resolve(argv.repo);
54957
+ const repoPath = path50.resolve(argv.repo);
54564
54958
  header("har control register");
54565
54959
  info(`Repository: ${repoPath}`);
54566
54960
  try {
@@ -54584,7 +54978,7 @@ async function handleRegister(argv) {
54584
54978
  }
54585
54979
  }
54586
54980
  async function handleUnregister(argv) {
54587
- const repoPath = path49.resolve(argv.repo);
54981
+ const repoPath = path50.resolve(argv.repo);
54588
54982
  const worktrees = listUnregisterWorktreeCandidates(repoPath);
54589
54983
  try {
54590
54984
  let deleteWorktrees = argv.deleteWorktrees;
@@ -54653,7 +55047,7 @@ async function handleUnregister(argv) {
54653
55047
  }
54654
55048
  }
54655
55049
  async function handleSync(argv) {
54656
- const repoPath = path49.resolve(argv.repo);
55050
+ const repoPath = path50.resolve(argv.repo);
54657
55051
  try {
54658
55052
  await syncRepoWithControl({
54659
55053
  repoPath,
@@ -54692,7 +55086,7 @@ async function handleWatch(argv) {
54692
55086
  };
54693
55087
  const tick = async () => {
54694
55088
  if (argv.repo) {
54695
- await syncOne(path49.resolve(argv.repo));
55089
+ await syncOne(path50.resolve(argv.repo));
54696
55090
  return;
54697
55091
  }
54698
55092
  try {
@@ -54742,11 +55136,11 @@ async function handleLogin(argv) {
54742
55136
  }
54743
55137
 
54744
55138
  // src/cli/commands/hooks.ts
54745
- var path51 = __toESM(require("path"));
55139
+ var path52 = __toESM(require("path"));
54746
55140
 
54747
55141
  // src/core/claude-hooks.ts
54748
55142
  var fs45 = __toESM(require("fs"));
54749
- var path50 = __toESM(require("path"));
55143
+ var path51 = __toESM(require("path"));
54750
55144
  var CLAUDE_GUARD_RELATIVE_PATH = ".har/hooks/claude-worktree-guard.sh";
54751
55145
  var CLAUDE_SETTINGS_RELATIVE_PATH = ".claude/settings.json";
54752
55146
  var GUARD_MATCHER = "Edit|Write|MultiEdit|NotebookEdit";
@@ -54767,7 +55161,7 @@ function readSettings(settingsPath) {
54767
55161
  return parsed;
54768
55162
  }
54769
55163
  function writeSettings(settingsPath, settings) {
54770
- fs45.mkdirSync(path50.dirname(settingsPath), { recursive: true });
55164
+ fs45.mkdirSync(path51.dirname(settingsPath), { recursive: true });
54771
55165
  fs45.writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + "\n");
54772
55166
  }
54773
55167
  function installClaudeGuard(repoPath) {
@@ -54775,11 +55169,11 @@ function installClaudeGuard(repoPath) {
54775
55169
  if (!templatePath) {
54776
55170
  throw new Error("Guard template not found (claude-worktree-guard.sh.template). Run npm run build.");
54777
55171
  }
54778
- const guardScript = path50.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
54779
- fs45.mkdirSync(path50.dirname(guardScript), { recursive: true });
55172
+ const guardScript = path51.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
55173
+ fs45.mkdirSync(path51.dirname(guardScript), { recursive: true });
54780
55174
  fs45.copyFileSync(templatePath, guardScript);
54781
55175
  fs45.chmodSync(guardScript, 493);
54782
- const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
55176
+ const settingsPath = path51.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
54783
55177
  const settings = readSettings(settingsPath);
54784
55178
  const hooks = settings.hooks ?? {};
54785
55179
  const preToolUse = (hooks.PreToolUse ?? []).filter((entry) => !isHarGuardEntry(entry));
@@ -54793,14 +55187,14 @@ function installClaudeGuard(repoPath) {
54793
55187
  }
54794
55188
  function uninstallClaudeGuard(repoPath) {
54795
55189
  let removed = false;
54796
- const guardScript = path50.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
55190
+ const guardScript = path51.join(repoPath, CLAUDE_GUARD_RELATIVE_PATH);
54797
55191
  if (fs45.existsSync(guardScript)) {
54798
55192
  fs45.rmSync(guardScript);
54799
55193
  removed = true;
54800
- const parent = path50.dirname(guardScript);
55194
+ const parent = path51.dirname(guardScript);
54801
55195
  if (fs45.existsSync(parent) && fs45.readdirSync(parent).length === 0) fs45.rmdirSync(parent);
54802
55196
  }
54803
- const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
55197
+ const settingsPath = path51.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
54804
55198
  if (fs45.existsSync(settingsPath)) {
54805
55199
  const settings = readSettings(settingsPath);
54806
55200
  const preToolUse = settings.hooks?.PreToolUse;
@@ -54826,7 +55220,7 @@ function uninstallClaudeGuard(repoPath) {
54826
55220
  return { removed };
54827
55221
  }
54828
55222
  function claudeGuardInstalled(repoPath) {
54829
- const settingsPath = path50.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
55223
+ const settingsPath = path51.join(repoPath, CLAUDE_SETTINGS_RELATIVE_PATH);
54830
55224
  if (!fs45.existsSync(settingsPath)) return false;
54831
55225
  try {
54832
55226
  const settings = readSettings(settingsPath);
@@ -54843,7 +55237,7 @@ function repoOption(y2) {
54843
55237
  function handleInstall2(argv) {
54844
55238
  try {
54845
55239
  if (argv.claude) {
54846
- const result2 = installClaudeGuard(path51.resolve(argv.repo));
55240
+ const result2 = installClaudeGuard(path52.resolve(argv.repo));
54847
55241
  success("Claude Code worktree guard installed.");
54848
55242
  info(`Guard script: ${result2.guardScript}`);
54849
55243
  info(`Settings: ${result2.settingsPath} (PreToolUse: Edit|Write|MultiEdit|NotebookEdit)`);
@@ -54851,7 +55245,7 @@ function handleInstall2(argv) {
54851
55245
  info("Commit both files so the guard travels with the repo.");
54852
55246
  return;
54853
55247
  }
54854
- const result = installHooks({ repoPath: path51.resolve(argv.repo), force: argv.force });
55248
+ const result = installHooks({ repoPath: path52.resolve(argv.repo), force: argv.force });
54855
55249
  success(`Commit gate installed in ${result.hooksDir}`);
54856
55250
  info(`pre-commit: ${result.preCommit}, post-commit: ${result.postCommit}`);
54857
55251
  info("Commits of unverified change batches will be blocked in agent worktrees.");
@@ -54864,7 +55258,7 @@ function handleInstall2(argv) {
54864
55258
  function handleUninstall(argv) {
54865
55259
  try {
54866
55260
  if (argv.claude) {
54867
- const result2 = uninstallClaudeGuard(path51.resolve(argv.repo));
55261
+ const result2 = uninstallClaudeGuard(path52.resolve(argv.repo));
54868
55262
  if (result2.removed) {
54869
55263
  success("Claude Code worktree guard removed.");
54870
55264
  } else {
@@ -54872,7 +55266,7 @@ function handleUninstall(argv) {
54872
55266
  }
54873
55267
  return;
54874
55268
  }
54875
- const result = uninstallHooks(path51.resolve(argv.repo));
55269
+ const result = uninstallHooks(path52.resolve(argv.repo));
54876
55270
  if (result.removed) {
54877
55271
  success(`Commit gate removed from ${result.hooksDir}`);
54878
55272
  } else {
@@ -54885,7 +55279,7 @@ function handleUninstall(argv) {
54885
55279
  }
54886
55280
  function handleStatus2(argv) {
54887
55281
  try {
54888
- const status = getHooksStatus(path51.resolve(argv.repo));
55282
+ const status = getHooksStatus(path52.resolve(argv.repo));
54889
55283
  if (argv.json) {
54890
55284
  process.stdout.write(`${JSON.stringify(status, null, 2)}
54891
55285
  `);
@@ -54903,7 +55297,7 @@ function handleStatus2(argv) {
54903
55297
  );
54904
55298
  info(`Effective: ${status.effectiveMode} (in this checkout)`);
54905
55299
  info(
54906
- `Claude guard: ${claudeGuardInstalled(path51.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
55300
+ `Claude guard: ${claudeGuardInstalled(path52.resolve(argv.repo)) ? `installed (${CLAUDE_GUARD_RELATIVE_PATH})` : "not installed"}`
54907
55301
  );
54908
55302
  } catch (err) {
54909
55303
  error(err instanceof Error ? err.message : String(err));
@@ -55164,10 +55558,10 @@ function assignProp(target, prop, value) {
55164
55558
  configurable: true
55165
55559
  });
55166
55560
  }
55167
- function getElementAtPath(obj, path54) {
55168
- if (!path54)
55561
+ function getElementAtPath(obj, path55) {
55562
+ if (!path55)
55169
55563
  return obj;
55170
- return path54.reduce((acc, key) => acc?.[key], obj);
55564
+ return path55.reduce((acc, key) => acc?.[key], obj);
55171
55565
  }
55172
55566
  function promiseAllObject(promisesObj) {
55173
55567
  const keys = Object.keys(promisesObj);
@@ -55487,11 +55881,11 @@ function aborted(x2, startIndex = 0) {
55487
55881
  }
55488
55882
  return false;
55489
55883
  }
55490
- function prefixIssues(path54, issues) {
55884
+ function prefixIssues(path55, issues) {
55491
55885
  return issues.map((iss) => {
55492
55886
  var _a3;
55493
55887
  (_a3 = iss).path ?? (_a3.path = []);
55494
- iss.path.unshift(path54);
55888
+ iss.path.unshift(path55);
55495
55889
  return iss;
55496
55890
  });
55497
55891
  }
@@ -60814,7 +61208,7 @@ var Protocol = class {
60814
61208
  return;
60815
61209
  }
60816
61210
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
60817
- await new Promise((resolve38) => setTimeout(resolve38, pollInterval));
61211
+ await new Promise((resolve39) => setTimeout(resolve39, pollInterval));
60818
61212
  options?.signal?.throwIfAborted();
60819
61213
  }
60820
61214
  } catch (error3) {
@@ -60831,7 +61225,7 @@ var Protocol = class {
60831
61225
  */
60832
61226
  request(request, resultSchema, options) {
60833
61227
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
60834
- return new Promise((resolve38, reject) => {
61228
+ return new Promise((resolve39, reject) => {
60835
61229
  const earlyReject = (error3) => {
60836
61230
  reject(error3);
60837
61231
  };
@@ -60909,7 +61303,7 @@ var Protocol = class {
60909
61303
  if (!parseResult.success) {
60910
61304
  reject(parseResult.error);
60911
61305
  } else {
60912
- resolve38(parseResult.data);
61306
+ resolve39(parseResult.data);
60913
61307
  }
60914
61308
  } catch (error3) {
60915
61309
  reject(error3);
@@ -61170,12 +61564,12 @@ var Protocol = class {
61170
61564
  }
61171
61565
  } catch {
61172
61566
  }
61173
- return new Promise((resolve38, reject) => {
61567
+ return new Promise((resolve39, reject) => {
61174
61568
  if (signal.aborted) {
61175
61569
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
61176
61570
  return;
61177
61571
  }
61178
- const timeoutId = setTimeout(resolve38, interval);
61572
+ const timeoutId = setTimeout(resolve39, interval);
61179
61573
  signal.addEventListener("abort", () => {
61180
61574
  clearTimeout(timeoutId);
61181
61575
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -61965,7 +62359,7 @@ var Server = class extends Protocol {
61965
62359
  };
61966
62360
 
61967
62361
  // src/mcp/server.ts
61968
- var path52 = __toESM(require("path"));
62362
+ var path53 = __toESM(require("path"));
61969
62363
 
61970
62364
  // node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
61971
62365
  var import_node_process2 = __toESM(require("node:process"), 1);
@@ -62048,12 +62442,12 @@ var StdioServerTransport = class {
62048
62442
  this.onclose?.();
62049
62443
  }
62050
62444
  send(message) {
62051
- return new Promise((resolve38) => {
62445
+ return new Promise((resolve39) => {
62052
62446
  const json = serializeMessage(message);
62053
62447
  if (this._stdout.write(json)) {
62054
- resolve38();
62448
+ resolve39();
62055
62449
  } else {
62056
- this._stdout.once("drain", resolve38);
62450
+ this._stdout.once("drain", resolve39);
62057
62451
  }
62058
62452
  });
62059
62453
  }
@@ -62625,7 +63019,7 @@ async function handleMcpToolCall(toolName, args, defaultRepo = ".") {
62625
63019
  const input = ControlUpInputSchema.parse({ ...args, repo });
62626
63020
  const result = await startControlAndSync({
62627
63021
  detach: input.detach,
62628
- cwd: path52.resolve(input.repo)
63022
+ cwd: path53.resolve(input.repo)
62629
63023
  });
62630
63024
  if (result.code !== 0) {
62631
63025
  return {
@@ -62766,7 +63160,7 @@ function getStore() {
62766
63160
  }
62767
63161
  return store;
62768
63162
  }
62769
- function readline6() {
63163
+ function readline7() {
62770
63164
  return getStore().rl;
62771
63165
  }
62772
63166
  function withUpdates(fn) {
@@ -62811,7 +63205,7 @@ var effectScheduler = {
62811
63205
  const { index } = store;
62812
63206
  store.hooksEffect.push(() => {
62813
63207
  store.hooksCleanup[index]?.();
62814
- const cleanFn = cb(readline6());
63208
+ const cleanFn = cb(readline7());
62815
63209
  if (cleanFn != null && typeof cleanFn !== "function") {
62816
63210
  throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
62817
63211
  }
@@ -63287,7 +63681,7 @@ function breakLines(content, width) {
63287
63681
  return content.split("\n").flatMap((line) => (0, import_wrap_ansi.default)(line, width, { trim: false, hard: true }).split("\n").map((str) => str.trimEnd())).join("\n");
63288
63682
  }
63289
63683
  function readlineWidth() {
63290
- return (0, import_cli_width.default)({ defaultWidth: 80, output: readline6().output });
63684
+ return (0, import_cli_width.default)({ defaultWidth: 80, output: readline7().output });
63291
63685
  }
63292
63686
 
63293
63687
  // node_modules/@inquirer/core/dist/esm/lib/pagination/lines.mjs
@@ -63379,7 +63773,7 @@ function usePagination({ items, active, renderItem, pageSize, loop = true }) {
63379
63773
  }
63380
63774
 
63381
63775
  // node_modules/@inquirer/core/dist/esm/lib/create-prompt.mjs
63382
- var readline7 = __toESM(require("node:readline"), 1);
63776
+ var readline8 = __toESM(require("node:readline"), 1);
63383
63777
  var import_node_async_hooks3 = require("node:async_hooks");
63384
63778
  var import_mute_stream = __toESM(require_lib3(), 1);
63385
63779
 
@@ -63705,13 +64099,13 @@ var PromisePolyfill = class extends Promise {
63705
64099
  // Available starting from Node 22
63706
64100
  // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers
63707
64101
  static withResolver() {
63708
- let resolve38;
64102
+ let resolve39;
63709
64103
  let reject;
63710
64104
  const promise = new Promise((res, rej) => {
63711
- resolve38 = res;
64105
+ resolve39 = res;
63712
64106
  reject = rej;
63713
64107
  });
63714
- return { promise, resolve: resolve38, reject };
64108
+ return { promise, resolve: resolve39, reject };
63715
64109
  }
63716
64110
  };
63717
64111
 
@@ -63722,13 +64116,13 @@ function createPrompt(view) {
63722
64116
  const cleanups = /* @__PURE__ */ new Set();
63723
64117
  const output = new import_mute_stream.default();
63724
64118
  output.pipe(context.output ?? process.stdout);
63725
- const rl = readline7.createInterface({
64119
+ const rl = readline8.createInterface({
63726
64120
  terminal: true,
63727
64121
  input,
63728
64122
  output
63729
64123
  });
63730
64124
  const screen = new ScreenManager(rl);
63731
- const { promise, resolve: resolve38, reject } = PromisePolyfill.withResolver();
64125
+ const { promise, resolve: resolve39, reject } = PromisePolyfill.withResolver();
63732
64126
  const cancel = () => reject(new CancelPromptError());
63733
64127
  if (signal) {
63734
64128
  const abort = () => reject(new AbortPromptError({ cause: signal.reason }));
@@ -63752,7 +64146,7 @@ function createPrompt(view) {
63752
64146
  cycle(() => {
63753
64147
  try {
63754
64148
  const nextView = view(config2, (value) => {
63755
- setImmediate(() => resolve38(value));
64149
+ setImmediate(() => resolve39(value));
63756
64150
  });
63757
64151
  const [content, bottomContent] = typeof nextView === "string" ? [nextView] : nextView;
63758
64152
  screen.render(content, bottomContent);
@@ -64739,9 +65133,9 @@ var import_run_async = __toESM(require_run_async(), 1);
64739
65133
  var import_mute_stream2 = __toESM(require_lib3(), 1);
64740
65134
  var import_ansi_escapes5 = __toESM(require_ansi_escapes(), 1);
64741
65135
  var _2 = {
64742
- set: (obj, path54 = "", value) => {
65136
+ set: (obj, path55 = "", value) => {
64743
65137
  let pointer = obj;
64744
- path54.split(".").forEach((key, index, arr) => {
65138
+ path55.split(".").forEach((key, index, arr) => {
64745
65139
  if (key === "__proto__" || key === "constructor")
64746
65140
  return;
64747
65141
  if (index === arr.length - 1) {
@@ -64752,8 +65146,8 @@ var _2 = {
64752
65146
  pointer = pointer[key];
64753
65147
  });
64754
65148
  },
64755
- get: (obj, path54 = "", defaultValue) => {
64756
- const travel = (regexp) => String.prototype.split.call(path54, regexp).filter(Boolean).reduce(
65149
+ get: (obj, path55 = "", defaultValue) => {
65150
+ const travel = (regexp) => String.prototype.split.call(path55, regexp).filter(Boolean).reduce(
64757
65151
  // @ts-expect-error implicit any on res[key]
64758
65152
  (res, key) => res !== null && res !== void 0 ? res[key] : res,
64759
65153
  obj
@@ -64867,7 +65261,7 @@ var PromptsRunner = class {
64867
65261
  throw new Error(`Prompt for type ${question.type} not found`);
64868
65262
  }
64869
65263
  let cleanupSignal;
64870
- const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve38, reject) => {
65264
+ const promptFn = isPromptConstructor(prompt2) ? (q2, { signal: signal2 } = {}) => new Promise((resolve39, reject) => {
64871
65265
  const rl = import_node_readline.default.createInterface(setupReadlineOptions(this.opt));
64872
65266
  rl.resume();
64873
65267
  const onClose = () => {
@@ -64903,7 +65297,7 @@ var PromptsRunner = class {
64903
65297
  cleanupSignal = void 0;
64904
65298
  };
64905
65299
  }
64906
- activePrompt.run().then(resolve38, reject).finally(cleanup);
65300
+ activePrompt.run().then(resolve39, reject).finally(cleanup);
64907
65301
  }) : prompt2;
64908
65302
  const { signal: moduleSignal } = this.opt;
64909
65303
  if (moduleSignal?.aborted) {
@@ -65117,7 +65511,7 @@ var preferencesCommand = {
65117
65511
  };
65118
65512
 
65119
65513
  // src/cli/commands/telemetry.ts
65120
- var path53 = __toESM(require("path"));
65514
+ var path54 = __toESM(require("path"));
65121
65515
  init_control_config();
65122
65516
  init_otel_hooks();
65123
65517
  init_telemetry_config();
@@ -65202,7 +65596,7 @@ async function handleOff() {
65202
65596
  info("Mission Control will not auto-start. Existing usage rows are kept.");
65203
65597
  }
65204
65598
  async function handleWriteEnv(argv) {
65205
- const repoPath = path53.resolve(argv.repo);
65599
+ const repoPath = path54.resolve(argv.repo);
65206
65600
  const harnessRoot = resolveHarnessRoot(repoPath);
65207
65601
  const session = readSlotRegistry(harnessRoot, argv.agentId);
65208
65602
  const workDir = argv.workDir ?? session?.workDir ?? repoPath;
@@ -65214,7 +65608,7 @@ async function handleWriteEnv(argv) {
65214
65608
  suffix,
65215
65609
  createdAt: session?.createdAt
65216
65610
  });
65217
- const envFile = argv.envFile ?? path53.join(workDir, `.env.agent.${argv.agentId}`);
65611
+ const envFile = argv.envFile ?? path54.join(workDir, `.env.agent.${argv.agentId}`);
65218
65612
  const attrs = {
65219
65613
  sessionKey,
65220
65614
  agentId: argv.agentId,
@@ -65233,7 +65627,7 @@ async function handleWriteEnv(argv) {
65233
65627
  success(`Wrote session attribution to ${envFile}`);
65234
65628
  }
65235
65629
  function handlePrintEnv(argv) {
65236
- const repoPath = path53.resolve(argv.repo);
65630
+ const repoPath = path54.resolve(argv.repo);
65237
65631
  const workDir = argv.workDir ?? repoPath;
65238
65632
  const sessionKey = buildSessionKey({
65239
65633
  branch: argv.branch,