@usepowerplant/cli 0.4.12 → 0.4.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7d73a97a-938c-5f0f-8b6b-c4076b82abad")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="81d65aee-a279-58bd-9476-cc1269e40adf")}catch(e){}}();
4
4
  const __cliNodeMajor = Number(process.versions.node.split('.')[0]);
5
5
  if (__cliNodeMajor < 20) {
6
6
  console.error(`powerplant needs Node 20 or newer — this is Node ${process.versions.node}.`);
@@ -6879,19 +6879,19 @@ var require_module_details_from_path = __commonJS({
6879
6879
  basedir += segments[i] + sep2;
6880
6880
  }
6881
6881
  }
6882
- var path32 = "";
6882
+ var path33 = "";
6883
6883
  var lastSegmentIndex = segments.length - 1;
6884
6884
  for (var i2 = index + offset; i2 <= lastSegmentIndex; i2++) {
6885
6885
  if (i2 === lastSegmentIndex) {
6886
- path32 += segments[i2];
6886
+ path33 += segments[i2];
6887
6887
  } else {
6888
- path32 += segments[i2] + sep2;
6888
+ path33 += segments[i2] + sep2;
6889
6889
  }
6890
6890
  }
6891
6891
  return {
6892
6892
  name,
6893
6893
  basedir,
6894
- path: path32
6894
+ path: path33
6895
6895
  };
6896
6896
  };
6897
6897
  }
@@ -6901,7 +6901,7 @@ var require_module_details_from_path = __commonJS({
6901
6901
  var require_require_in_the_middle = __commonJS({
6902
6902
  "../../node_modules/.pnpm/require-in-the-middle@8.0.1/node_modules/require-in-the-middle/index.js"(exports, module2) {
6903
6903
  "use strict";
6904
- var path32 = __require("path");
6904
+ var path33 = __require("path");
6905
6905
  var Module = __require("module");
6906
6906
  var debug2 = require_src3()("require-in-the-middle");
6907
6907
  var moduleDetailsFromPath = require_module_details_from_path();
@@ -7046,7 +7046,7 @@ var require_require_in_the_middle = __commonJS({
7046
7046
  }
7047
7047
  moduleName = filename;
7048
7048
  } else if (hasWhitelist === true && modules.includes(filename)) {
7049
- const parsedPath = path32.parse(filename);
7049
+ const parsedPath = path33.parse(filename);
7050
7050
  moduleName = parsedPath.name;
7051
7051
  basedir = parsedPath.dir;
7052
7052
  } else {
@@ -7084,7 +7084,7 @@ var require_require_in_the_middle = __commonJS({
7084
7084
  }
7085
7085
  if (res !== filename) {
7086
7086
  if (internals === true) {
7087
- moduleName = moduleName + path32.sep + path32.relative(basedir, filename);
7087
+ moduleName = moduleName + path33.sep + path33.relative(basedir, filename);
7088
7088
  debug2("preparing to process require of internal file: %s", moduleName);
7089
7089
  } else {
7090
7090
  debug2("ignoring require of non-main module file: %s", res);
@@ -7120,8 +7120,8 @@ var require_require_in_the_middle = __commonJS({
7120
7120
  }
7121
7121
  };
7122
7122
  function resolveModuleName(stat) {
7123
- const normalizedPath = path32.sep !== "/" ? stat.path.split(path32.sep).join("/") : stat.path;
7124
- return path32.posix.join(stat.name, normalizedPath).replace(normalize3, "");
7123
+ const normalizedPath = path33.sep !== "/" ? stat.path.split(path33.sep).join("/") : stat.path;
7124
+ return path33.posix.join(stat.name, normalizedPath).replace(normalize3, "");
7125
7125
  }
7126
7126
  }
7127
7127
  });
@@ -7206,7 +7206,7 @@ var require_RequireInTheMiddleSingleton = __commonJS({
7206
7206
  Object.defineProperty(exports, "__esModule", { value: true });
7207
7207
  exports.RequireInTheMiddleSingleton = void 0;
7208
7208
  var require_in_the_middle_1 = require_require_in_the_middle();
7209
- var path32 = __require("path");
7209
+ var path33 = __require("path");
7210
7210
  var ModuleNameTrie_1 = require_ModuleNameTrie();
7211
7211
  var isMocha = [
7212
7212
  "afterEach",
@@ -7270,7 +7270,7 @@ var require_RequireInTheMiddleSingleton = __commonJS({
7270
7270
  };
7271
7271
  exports.RequireInTheMiddleSingleton = RequireInTheMiddleSingleton;
7272
7272
  function normalizePathSeparators(moduleNameOrPath) {
7273
- return path32.sep !== ModuleNameTrie_1.ModuleNameSeparator ? moduleNameOrPath.split(path32.sep).join(ModuleNameTrie_1.ModuleNameSeparator) : moduleNameOrPath;
7273
+ return path33.sep !== ModuleNameTrie_1.ModuleNameSeparator ? moduleNameOrPath.split(path33.sep).join(ModuleNameTrie_1.ModuleNameSeparator) : moduleNameOrPath;
7274
7274
  }
7275
7275
  }
7276
7276
  });
@@ -7480,7 +7480,7 @@ var require_register = __commonJS({
7480
7480
  // ../../node_modules/.pnpm/import-in-the-middle@3.5.1/node_modules/import-in-the-middle/index.js
7481
7481
  var require_import_in_the_middle = __commonJS({
7482
7482
  "../../node_modules/.pnpm/import-in-the-middle@3.5.1/node_modules/import-in-the-middle/index.js"(exports, module2) {
7483
- var path32 = __require("path");
7483
+ var path33 = __require("path");
7484
7484
  var moduleDetailsFromPath = require_module_details_from_path();
7485
7485
  var { fileURLToPath: fileURLToPath3 } = __require("url");
7486
7486
  var { MessageChannel } = __require("worker_threads");
@@ -7599,7 +7599,7 @@ var require_import_in_the_middle = __commonJS({
7599
7599
  } else if (baseDir.endsWith(specifiers.get(loadUrl)) || isTurbopackSpecifier(specifiers.get(loadUrl), baseDir)) {
7600
7600
  callHookFn(hookFn, namespace, name, baseDir);
7601
7601
  } else if (internals) {
7602
- const internalPath = name + path32.sep + path32.relative(baseDir, filePath);
7602
+ const internalPath = name + path33.sep + path33.relative(baseDir, filePath);
7603
7603
  callHookFn(hookFn, namespace, internalPath, baseDir);
7604
7604
  }
7605
7605
  } else if (matchArg === specifier) {
@@ -7674,7 +7674,7 @@ var require_instrumentation2 = __commonJS({
7674
7674
  "use strict";
7675
7675
  Object.defineProperty(exports, "__esModule", { value: true });
7676
7676
  exports.InstrumentationBase = void 0;
7677
- var path32 = __require("path");
7677
+ var path33 = __require("path");
7678
7678
  var util_1 = __require("util");
7679
7679
  var semver_1 = require_semver();
7680
7680
  var shimmer_1 = require_shimmer();
@@ -7775,7 +7775,7 @@ var require_instrumentation2 = __commonJS({
7775
7775
  }
7776
7776
  _extractPackageVersion(baseDir) {
7777
7777
  try {
7778
- const json2 = (0, fs_1.readFileSync)(path32.join(baseDir, "package.json"), {
7778
+ const json2 = (0, fs_1.readFileSync)(path33.join(baseDir, "package.json"), {
7779
7779
  encoding: "utf8"
7780
7780
  });
7781
7781
  const version2 = JSON.parse(json2).version;
@@ -7817,7 +7817,7 @@ var require_instrumentation2 = __commonJS({
7817
7817
  return exports2;
7818
7818
  }
7819
7819
  const files = module3.files ?? [];
7820
- const normalizedName = path32.normalize(name);
7820
+ const normalizedName = path33.normalize(name);
7821
7821
  const supportedFileInstrumentations = files.filter((f) => f.name === normalizedName && isSupported(f.supportedVersions, version2, module3.includePrerelease));
7822
7822
  return supportedFileInstrumentations.reduce((patchedExports, file2) => {
7823
7823
  file2.moduleExports = patchedExports;
@@ -7863,8 +7863,8 @@ var require_instrumentation2 = __commonJS({
7863
7863
  this._warnOnPreloadedModules();
7864
7864
  for (const module3 of this._modules) {
7865
7865
  const hookFn = (exports2, name, baseDir) => {
7866
- if (!baseDir && path32.isAbsolute(name)) {
7867
- const parsedPath = path32.parse(name);
7866
+ if (!baseDir && path33.isAbsolute(name)) {
7867
+ const parsedPath = path33.parse(name);
7868
7868
  name = parsedPath.name;
7869
7869
  baseDir = parsedPath.dir;
7870
7870
  }
@@ -7873,7 +7873,7 @@ var require_instrumentation2 = __commonJS({
7873
7873
  const onRequire = (exports2, name, baseDir) => {
7874
7874
  return this._onRequire(module3, exports2, name, baseDir);
7875
7875
  };
7876
- const hook = path32.isAbsolute(module3.name) ? new require_in_the_middle_1.Hook([module3.name], { internals: true }, onRequire) : this._requireInTheMiddleSingleton.register(module3.name, onRequire);
7876
+ const hook = path33.isAbsolute(module3.name) ? new require_in_the_middle_1.Hook([module3.name], { internals: true }, onRequire) : this._requireInTheMiddleSingleton.register(module3.name, onRequire);
7877
7877
  this._hooks.push(hook);
7878
7878
  const esmHook = new import_in_the_middle_1.Hook([module3.name], { internals: true }, hookFn);
7879
7879
  this._hooks.push(esmHook);
@@ -8481,9 +8481,9 @@ var require_getMachineId_linux = __commonJS({
8481
8481
  var api_1 = (init_esm(), __toCommonJS(esm_exports));
8482
8482
  async function getMachineId() {
8483
8483
  const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
8484
- for (const path32 of paths) {
8484
+ for (const path33 of paths) {
8485
8485
  try {
8486
- const result = await fs_1.promises.readFile(path32, { encoding: "utf8" });
8486
+ const result = await fs_1.promises.readFile(path33, { encoding: "utf8" });
8487
8487
  return result.trim();
8488
8488
  } catch (e) {
8489
8489
  api_1.diag.debug(`error reading machine id: ${e}`);
@@ -11843,14 +11843,14 @@ var require_util = __commonJS({
11843
11843
  }
11844
11844
  const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
11845
11845
  let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
11846
- let path32 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
11846
+ let path33 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
11847
11847
  if (origin[origin.length - 1] === "/") {
11848
11848
  origin = origin.slice(0, origin.length - 1);
11849
11849
  }
11850
- if (path32 && path32[0] !== "/") {
11851
- path32 = `/${path32}`;
11850
+ if (path33 && path33[0] !== "/") {
11851
+ path33 = `/${path33}`;
11852
11852
  }
11853
- return new URL(`${origin}${path32}`);
11853
+ return new URL(`${origin}${path33}`);
11854
11854
  }
11855
11855
  if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
11856
11856
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -12671,9 +12671,9 @@ var require_diagnostics = __commonJS({
12671
12671
  "undici:client:sendHeaders",
12672
12672
  (evt) => {
12673
12673
  const {
12674
- request: { method, path: path32, origin }
12674
+ request: { method, path: path33, origin }
12675
12675
  } = evt;
12676
- debugLog3("sending request to %s %s%s", method, origin, path32);
12676
+ debugLog3("sending request to %s %s%s", method, origin, path33);
12677
12677
  }
12678
12678
  );
12679
12679
  }
@@ -12691,14 +12691,14 @@ var require_diagnostics = __commonJS({
12691
12691
  "undici:request:headers",
12692
12692
  (evt) => {
12693
12693
  const {
12694
- request: { method, path: path32, origin },
12694
+ request: { method, path: path33, origin },
12695
12695
  response: { statusCode }
12696
12696
  } = evt;
12697
12697
  debugLog3(
12698
12698
  "received response to %s %s%s - HTTP %d",
12699
12699
  method,
12700
12700
  origin,
12701
- path32,
12701
+ path33,
12702
12702
  statusCode
12703
12703
  );
12704
12704
  }
@@ -12707,23 +12707,23 @@ var require_diagnostics = __commonJS({
12707
12707
  "undici:request:trailers",
12708
12708
  (evt) => {
12709
12709
  const {
12710
- request: { method, path: path32, origin }
12710
+ request: { method, path: path33, origin }
12711
12711
  } = evt;
12712
- debugLog3("trailers received from %s %s%s", method, origin, path32);
12712
+ debugLog3("trailers received from %s %s%s", method, origin, path33);
12713
12713
  }
12714
12714
  );
12715
12715
  diagnosticsChannel9.subscribe(
12716
12716
  "undici:request:error",
12717
12717
  (evt) => {
12718
12718
  const {
12719
- request: { method, path: path32, origin },
12719
+ request: { method, path: path33, origin },
12720
12720
  error: error63
12721
12721
  } = evt;
12722
12722
  debugLog3(
12723
12723
  "request to %s %s%s errored - %s",
12724
12724
  method,
12725
12725
  origin,
12726
- path32,
12726
+ path33,
12727
12727
  error63.message
12728
12728
  );
12729
12729
  }
@@ -12838,7 +12838,7 @@ var require_request = __commonJS({
12838
12838
  var kHandler = /* @__PURE__ */ Symbol("handler");
12839
12839
  var Request2 = class {
12840
12840
  constructor(origin, {
12841
- path: path32,
12841
+ path: path33,
12842
12842
  method,
12843
12843
  body,
12844
12844
  headers,
@@ -12855,11 +12855,11 @@ var require_request = __commonJS({
12855
12855
  maxRedirections,
12856
12856
  typeOfService
12857
12857
  }, handler) {
12858
- if (typeof path32 !== "string") {
12858
+ if (typeof path33 !== "string") {
12859
12859
  throw new InvalidArgumentError("path must be a string");
12860
- } else if (path32[0] !== "/" && !(path32.startsWith("http://") || path32.startsWith("https://")) && method !== "CONNECT") {
12860
+ } else if (path33[0] !== "/" && !(path33.startsWith("http://") || path33.startsWith("https://")) && method !== "CONNECT") {
12861
12861
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
12862
- } else if (invalidPathRegex.test(path32)) {
12862
+ } else if (invalidPathRegex.test(path33)) {
12863
12863
  throw new InvalidArgumentError("invalid request path");
12864
12864
  }
12865
12865
  if (typeof method !== "string") {
@@ -12934,7 +12934,7 @@ var require_request = __commonJS({
12934
12934
  this.completed = false;
12935
12935
  this.aborted = false;
12936
12936
  this.upgrade = upgrade || null;
12937
- this.path = query ? serializePathWithQuery(path32, query) : path32;
12937
+ this.path = query ? serializePathWithQuery(path33, query) : path33;
12938
12938
  this.origin = origin;
12939
12939
  this.protocol = getProtocolFromUrlString(origin);
12940
12940
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -18116,7 +18116,7 @@ var require_client_h1 = __commonJS({
18116
18116
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
18117
18117
  }
18118
18118
  function writeH1(client, request2) {
18119
- const { method, path: path32, host, upgrade, blocking, reset } = request2;
18119
+ const { method, path: path33, host, upgrade, blocking, reset } = request2;
18120
18120
  let { body, headers, contentLength } = request2;
18121
18121
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
18122
18122
  if (util2.isFormDataLike(body)) {
@@ -18194,7 +18194,7 @@ var require_client_h1 = __commonJS({
18194
18194
  if (socket.setTypeOfService) {
18195
18195
  socket.setTypeOfService(request2.typeOfService);
18196
18196
  }
18197
- let header = `${method} ${path32} HTTP/1.1\r
18197
+ let header = `${method} ${path33} HTTP/1.1\r
18198
18198
  `;
18199
18199
  if (typeof host === "string") {
18200
18200
  header += `host: ${host}\r
@@ -18873,7 +18873,7 @@ var require_client_h2 = __commonJS({
18873
18873
  const headersTimeout = request2.headersTimeout ?? client[kHeadersTimeout];
18874
18874
  const bodyTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
18875
18875
  const session = client[kHTTP2Session];
18876
- const { method, path: path32, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
18876
+ const { method, path: path33, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
18877
18877
  let { body } = request2;
18878
18878
  if (upgrade != null && upgrade !== "websocket") {
18879
18879
  util2.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -18942,7 +18942,7 @@ var require_client_h2 = __commonJS({
18942
18942
  }
18943
18943
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
18944
18944
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
18945
- headers[HTTP2_HEADER_PATH] = path32;
18945
+ headers[HTTP2_HEADER_PATH] = path33;
18946
18946
  if (protocol === "ws:" || protocol === "wss:") {
18947
18947
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
18948
18948
  } else {
@@ -18984,7 +18984,7 @@ var require_client_h2 = __commonJS({
18984
18984
  stream.setTimeout(headersTimeout);
18985
18985
  return true;
18986
18986
  }
18987
- headers[HTTP2_HEADER_PATH] = path32;
18987
+ headers[HTTP2_HEADER_PATH] = path33;
18988
18988
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
18989
18989
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
18990
18990
  if (body && typeof body.read === "function") {
@@ -21336,10 +21336,10 @@ var require_proxy_agent = __commonJS({
21336
21336
  };
21337
21337
  const {
21338
21338
  origin,
21339
- path: path32 = "/",
21339
+ path: path33 = "/",
21340
21340
  headers = {}
21341
21341
  } = opts;
21342
- opts.path = origin + path32;
21342
+ opts.path = origin + path33;
21343
21343
  if (!("host" in headers) && !("Host" in headers)) {
21344
21344
  const { host } = new URL(origin);
21345
21345
  headers.host = host;
@@ -23448,20 +23448,20 @@ var require_mock_utils = __commonJS({
23448
23448
  }
23449
23449
  return normalizedQp;
23450
23450
  }
23451
- function safeUrl(path32) {
23452
- if (typeof path32 !== "string") {
23453
- return path32;
23451
+ function safeUrl(path33) {
23452
+ if (typeof path33 !== "string") {
23453
+ return path33;
23454
23454
  }
23455
- const pathSegments = path32.split("?", 3);
23455
+ const pathSegments = path33.split("?", 3);
23456
23456
  if (pathSegments.length !== 2) {
23457
- return path32;
23457
+ return path33;
23458
23458
  }
23459
23459
  const qp = new URLSearchParams(pathSegments.pop());
23460
23460
  qp.sort();
23461
23461
  return [...pathSegments, qp.toString()].join("?");
23462
23462
  }
23463
- function matchKey(mockDispatch2, { path: path32, method, body, headers }) {
23464
- const pathMatch = matchValue(mockDispatch2.path, path32);
23463
+ function matchKey(mockDispatch2, { path: path33, method, body, headers }) {
23464
+ const pathMatch = matchValue(mockDispatch2.path, path33);
23465
23465
  const methodMatch = matchValue(mockDispatch2.method, method);
23466
23466
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
23467
23467
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -23486,8 +23486,8 @@ var require_mock_utils = __commonJS({
23486
23486
  const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
23487
23487
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
23488
23488
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
23489
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path32, ignoreTrailingSlash }) => {
23490
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path32)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path32), resolvedPath);
23489
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path33, ignoreTrailingSlash }) => {
23490
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path33)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path33), resolvedPath);
23491
23491
  });
23492
23492
  if (matchedMockDispatches.length === 0) {
23493
23493
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -23526,19 +23526,19 @@ var require_mock_utils = __commonJS({
23526
23526
  mockDispatches.splice(index, 1);
23527
23527
  }
23528
23528
  }
23529
- function removeTrailingSlash(path32) {
23530
- while (path32.endsWith("/")) {
23531
- path32 = path32.slice(0, -1);
23529
+ function removeTrailingSlash(path33) {
23530
+ while (path33.endsWith("/")) {
23531
+ path33 = path33.slice(0, -1);
23532
23532
  }
23533
- if (path32.length === 0) {
23534
- path32 = "/";
23533
+ if (path33.length === 0) {
23534
+ path33 = "/";
23535
23535
  }
23536
- return path32;
23536
+ return path33;
23537
23537
  }
23538
23538
  function buildKey(opts) {
23539
- const { path: path32, method, body, headers, query } = opts;
23539
+ const { path: path33, method, body, headers, query } = opts;
23540
23540
  return {
23541
- path: path32,
23541
+ path: path33,
23542
23542
  method,
23543
23543
  body,
23544
23544
  headers,
@@ -24228,10 +24228,10 @@ var require_pending_interceptors_formatter = __commonJS({
24228
24228
  }
24229
24229
  format(pendingInterceptors) {
24230
24230
  const withPrettyHeaders = pendingInterceptors.map(
24231
- ({ method, path: path32, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
24231
+ ({ method, path: path33, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
24232
24232
  Method: method,
24233
24233
  Origin: origin,
24234
- Path: path32,
24234
+ Path: path33,
24235
24235
  "Status code": statusCode,
24236
24236
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
24237
24237
  Invocations: timesInvoked,
@@ -24313,9 +24313,9 @@ var require_mock_agent = __commonJS({
24313
24313
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
24314
24314
  const dispatchOpts = { ...opts };
24315
24315
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
24316
- const [path32, searchParams] = dispatchOpts.path.split("?");
24316
+ const [path33, searchParams] = dispatchOpts.path.split("?");
24317
24317
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
24318
- dispatchOpts.path = `${path32}?${normalizedSearchParams}`;
24318
+ dispatchOpts.path = `${path33}?${normalizedSearchParams}`;
24319
24319
  }
24320
24320
  return this[kAgent].dispatch(dispatchOpts, handler);
24321
24321
  }
@@ -24716,12 +24716,12 @@ var require_snapshot_recorder = __commonJS({
24716
24716
  * @return {Promise<void>} - Resolves when snapshots are loaded
24717
24717
  */
24718
24718
  async loadSnapshots(filePath) {
24719
- const path32 = filePath || this.#snapshotPath;
24720
- if (!path32) {
24719
+ const path33 = filePath || this.#snapshotPath;
24720
+ if (!path33) {
24721
24721
  throw new InvalidArgumentError("Snapshot path is required");
24722
24722
  }
24723
24723
  try {
24724
- const data = await readFile3(resolve2(path32), "utf8");
24724
+ const data = await readFile3(resolve2(path33), "utf8");
24725
24725
  const parsed = JSON.parse(data);
24726
24726
  if (Array.isArray(parsed)) {
24727
24727
  this.#snapshots.clear();
@@ -24735,7 +24735,7 @@ var require_snapshot_recorder = __commonJS({
24735
24735
  if (error63.code === "ENOENT") {
24736
24736
  this.#snapshots.clear();
24737
24737
  } else {
24738
- throw new UndiciError(`Failed to load snapshots from ${path32}`, { cause: error63 });
24738
+ throw new UndiciError(`Failed to load snapshots from ${path33}`, { cause: error63 });
24739
24739
  }
24740
24740
  }
24741
24741
  }
@@ -24746,11 +24746,11 @@ var require_snapshot_recorder = __commonJS({
24746
24746
  * @returns {Promise<void>} - Resolves when snapshots are saved
24747
24747
  */
24748
24748
  async saveSnapshots(filePath) {
24749
- const path32 = filePath || this.#snapshotPath;
24750
- if (!path32) {
24749
+ const path33 = filePath || this.#snapshotPath;
24750
+ if (!path33) {
24751
24751
  throw new InvalidArgumentError("Snapshot path is required");
24752
24752
  }
24753
- const resolvedPath = resolve2(path32);
24753
+ const resolvedPath = resolve2(path33);
24754
24754
  await mkdir(dirname2(resolvedPath), { recursive: true });
24755
24755
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
24756
24756
  hash: hash2,
@@ -25382,15 +25382,15 @@ var require_redirect_handler = __commonJS({
25382
25382
  return;
25383
25383
  }
25384
25384
  const { origin, pathname, search } = util2.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
25385
- const path32 = search ? `${pathname}${search}` : pathname;
25386
- const redirectUrlString = `${origin}${path32}`;
25385
+ const path33 = search ? `${pathname}${search}` : pathname;
25386
+ const redirectUrlString = `${origin}${path33}`;
25387
25387
  for (const historyUrl of this.history) {
25388
25388
  if (historyUrl.toString() === redirectUrlString) {
25389
25389
  throw new InvalidArgumentError(`Redirect loop detected. Cannot redirect to ${origin}. This typically happens when using a Client or Pool with cross-origin redirects. Use an Agent for cross-origin redirects.`);
25390
25390
  }
25391
25391
  }
25392
25392
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
25393
- this.opts.path = path32;
25393
+ this.opts.path = path33;
25394
25394
  this.opts.origin = origin;
25395
25395
  this.opts.query = null;
25396
25396
  }
@@ -27150,10 +27150,10 @@ var require_cache_handler = __commonJS({
27150
27150
  }
27151
27151
  return locationUrl.pathname + locationUrl.search;
27152
27152
  }
27153
- function deleteCachedUri(store, cacheKey, path32) {
27153
+ function deleteCachedUri(store, cacheKey, path33) {
27154
27154
  deleteCachedValue(store, {
27155
27155
  ...cacheKey,
27156
- path: path32
27156
+ path: path33
27157
27157
  });
27158
27158
  for (let i = 0; i < util2.safeHTTPMethods.length; i++) {
27159
27159
  const method = util2.safeHTTPMethods[i];
@@ -27161,7 +27161,7 @@ var require_cache_handler = __commonJS({
27161
27161
  deleteCachedValue(store, {
27162
27162
  ...cacheKey,
27163
27163
  method,
27164
- path: path32
27164
+ path: path33
27165
27165
  });
27166
27166
  }
27167
27167
  }
@@ -27172,9 +27172,9 @@ var require_cache_handler = __commonJS({
27172
27172
  }
27173
27173
  const values = Array.isArray(headerValue) ? headerValue : [headerValue];
27174
27174
  for (let i = 0; i < values.length; i++) {
27175
- const path32 = getSameOriginPath(cacheKey, values[i]);
27176
- if (path32 !== void 0) {
27177
- deleteCachedUri(store, cacheKey, path32);
27175
+ const path33 = getSameOriginPath(cacheKey, values[i]);
27176
+ if (path33 !== void 0) {
27177
+ deleteCachedUri(store, cacheKey, path33);
27178
27178
  }
27179
27179
  }
27180
27180
  }
@@ -32174,11 +32174,11 @@ var require_fetch = __commonJS({
32174
32174
  function dispatch({ body }) {
32175
32175
  const url2 = requestCurrentURL(request2);
32176
32176
  const agent = fetchParams.controller.dispatcher;
32177
- const path32 = url2.pathname + url2.search;
32177
+ const path33 = url2.pathname + url2.search;
32178
32178
  const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
32179
32179
  return new Promise((resolve2, reject) => agent.dispatch(
32180
32180
  {
32181
- path: hasTrailingQuestionMark ? `${path32}?` : path32,
32181
+ path: hasTrailingQuestionMark ? `${path33}?` : path33,
32182
32182
  origin: url2.origin,
32183
32183
  method: request2.method,
32184
32184
  body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body,
@@ -33125,9 +33125,9 @@ var require_util4 = __commonJS({
33125
33125
  }
33126
33126
  }
33127
33127
  }
33128
- function validateCookiePath(path32) {
33129
- for (let i = 0; i < path32.length; ++i) {
33130
- const code = path32.charCodeAt(i);
33128
+ function validateCookiePath(path33) {
33129
+ for (let i = 0; i < path33.length; ++i) {
33130
+ const code = path33.charCodeAt(i);
33131
33131
  if (code < 32 || // exclude CTLs (0-31)
33132
33132
  code > 126 || // exclude DEL and non-ascii
33133
33133
  code === 59) {
@@ -36475,11 +36475,11 @@ var require_undici = __commonJS({
36475
36475
  if (typeof opts.path !== "string") {
36476
36476
  throw new InvalidArgumentError("invalid opts.path");
36477
36477
  }
36478
- let path32 = opts.path;
36478
+ let path33 = opts.path;
36479
36479
  if (!opts.path.startsWith("/")) {
36480
- path32 = `/${path32}`;
36480
+ path33 = `/${path33}`;
36481
36481
  }
36482
- url2 = new URL(util2.parseOrigin(url2).origin + path32);
36482
+ url2 = new URL(util2.parseOrigin(url2).origin + path33);
36483
36483
  } else {
36484
36484
  if (!opts) {
36485
36485
  opts = typeof url2 === "object" ? url2 : {};
@@ -36588,14 +36588,6 @@ ${captureLines}` : capture.stack;
36588
36588
  }
36589
36589
  });
36590
36590
 
36591
- // src/clientFailure.ts
36592
- import { constants } from "node:os";
36593
-
36594
- // ../../apps/collector/src/credentials.ts
36595
- import { chmodSync as chmodSync4, existsSync as existsSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync8, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
36596
- import os12 from "node:os";
36597
- import path14 from "node:path";
36598
-
36599
36591
  // ../../node_modules/.pnpm/zod@4.6.5/node_modules/zod/v4/classic/external.js
36600
36592
  var external_exports = {};
36601
36593
  __export(external_exports, {
@@ -37412,10 +37404,10 @@ function mergeDefs(...defs) {
37412
37404
  function cloneDef(schema) {
37413
37405
  return mergeDefs(schema._zod.def);
37414
37406
  }
37415
- function getElementAtPath(obj, path32) {
37416
- if (!path32)
37407
+ function getElementAtPath(obj, path33) {
37408
+ if (!path33)
37417
37409
  return obj;
37418
- return path32.reduce((acc, key) => acc?.[key], obj);
37410
+ return path33.reduce((acc, key) => acc?.[key], obj);
37419
37411
  }
37420
37412
  function promiseAllObject(promisesObj) {
37421
37413
  const keys = Object.keys(promisesObj);
@@ -37755,11 +37747,11 @@ function explicitlyAborted(x, startIndex = 0) {
37755
37747
  }
37756
37748
  return false;
37757
37749
  }
37758
- function prefixIssues(path32, issues) {
37750
+ function prefixIssues(path33, issues) {
37759
37751
  return issues.map((iss) => {
37760
37752
  var _a4;
37761
37753
  (_a4 = iss).path ?? (_a4.path = []);
37762
- iss.path.unshift(path32);
37754
+ iss.path.unshift(path33);
37763
37755
  return iss;
37764
37756
  });
37765
37757
  }
@@ -38209,16 +38201,16 @@ function flattenError(error63, mapper = (issue2) => issue2.message) {
38209
38201
  }
38210
38202
  function formatError(error63, mapper = (issue2) => issue2.message) {
38211
38203
  const fieldErrors = { _errors: [] };
38212
- const processError = (error64, path32 = []) => {
38204
+ const processError = (error64, path33 = []) => {
38213
38205
  for (const issue2 of error64.issues) {
38214
38206
  if (issue2.code === "invalid_union" && issue2.errors.length) {
38215
- issue2.errors.map((issues) => processError({ issues }, [...path32, ...issue2.path]));
38207
+ issue2.errors.map((issues) => processError({ issues }, [...path33, ...issue2.path]));
38216
38208
  } else if (issue2.code === "invalid_key") {
38217
- processError({ issues: issue2.issues }, [...path32, ...issue2.path]);
38209
+ processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
38218
38210
  } else if (issue2.code === "invalid_element") {
38219
- processError({ issues: issue2.issues }, [...path32, ...issue2.path]);
38211
+ processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
38220
38212
  } else {
38221
- const fullpath = [...path32, ...issue2.path];
38213
+ const fullpath = [...path33, ...issue2.path];
38222
38214
  if (fullpath.length === 0) {
38223
38215
  fieldErrors._errors.push(mapper(issue2));
38224
38216
  } else {
@@ -38257,17 +38249,17 @@ function formatError(error63, mapper = (issue2) => issue2.message) {
38257
38249
  }
38258
38250
  function treeifyError(error63, mapper = (issue2) => issue2.message) {
38259
38251
  const result = { errors: [] };
38260
- const processError = (error64, path32 = []) => {
38252
+ const processError = (error64, path33 = []) => {
38261
38253
  var _a4;
38262
38254
  for (const issue2 of error64.issues) {
38263
38255
  if (issue2.code === "invalid_union" && issue2.errors.length) {
38264
- issue2.errors.map((issues) => processError({ issues }, [...path32, ...issue2.path]));
38256
+ issue2.errors.map((issues) => processError({ issues }, [...path33, ...issue2.path]));
38265
38257
  } else if (issue2.code === "invalid_key") {
38266
- processError({ issues: issue2.issues }, [...path32, ...issue2.path]);
38258
+ processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
38267
38259
  } else if (issue2.code === "invalid_element") {
38268
- processError({ issues: issue2.issues }, [...path32, ...issue2.path]);
38260
+ processError({ issues: issue2.issues }, [...path33, ...issue2.path]);
38269
38261
  } else {
38270
- const fullpath = [...path32, ...issue2.path];
38262
+ const fullpath = [...path33, ...issue2.path];
38271
38263
  if (fullpath.length === 0) {
38272
38264
  result.errors.push(mapper(issue2));
38273
38265
  continue;
@@ -38306,8 +38298,8 @@ function treeifyError(error63, mapper = (issue2) => issue2.message) {
38306
38298
  }
38307
38299
  function toDotPath(_path) {
38308
38300
  const segs = [];
38309
- const path32 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
38310
- for (const seg of path32) {
38301
+ const path33 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
38302
+ for (const seg of path33) {
38311
38303
  if (typeof seg === "number")
38312
38304
  segs.push(`[${seg}]`);
38313
38305
  else if (typeof seg === "symbol")
@@ -55409,13 +55401,13 @@ function resolveRef(ref, ctx) {
55409
55401
  if (!ref.startsWith("#")) {
55410
55402
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
55411
55403
  }
55412
- const path32 = ref.slice(1).split("/").filter(Boolean);
55413
- if (path32.length === 0) {
55404
+ const path33 = ref.slice(1).split("/").filter(Boolean);
55405
+ if (path33.length === 0) {
55414
55406
  return ctx.rootSchema;
55415
55407
  }
55416
55408
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
55417
- if (path32[0] === defsKey) {
55418
- const key = path32[1] === void 0 ? void 0 : decodeJSONPointerSegment(path32[1]);
55409
+ if (path33[0] === defsKey) {
55410
+ const key = path33[1] === void 0 ? void 0 : decodeJSONPointerSegment(path33[1]);
55419
55411
  if (!key || !ctx.defs[key]) {
55420
55412
  throw new Error(`Reference not found: ${ref}`);
55421
55413
  }
@@ -56264,6 +56256,53 @@ function date4(params) {
56264
56256
  return _coercedDate(ZodDate, params);
56265
56257
  }
56266
56258
 
56259
+ // ../core/src/mcpWarning.ts
56260
+ var mcpClientSchema = external_exports.enum(["claude", "codex", "cursor"]);
56261
+ var mcpWarningSchema = external_exports.enum(["not-connected", "sign-in-needed", "different-url"]);
56262
+ var mcpWarningDismissalSchema = external_exports.object({
56263
+ client: mcpClientSchema,
56264
+ warning: mcpWarningSchema
56265
+ }).strict();
56266
+
56267
+ // ../core/src/sessionIngest.ts
56268
+ var SESSION_SOURCES = [
56269
+ "claude-code",
56270
+ "claude-cloud",
56271
+ "codex",
56272
+ "cursor",
56273
+ "cursor-cloud",
56274
+ "github-pr"
56275
+ ];
56276
+ var SESSION_SPEED_MODES = ["standard", "fast"];
56277
+ var SESSION_SPEED_OBSERVATIONS = [...SESSION_SPEED_MODES, "unknown"];
56278
+ function isSessionSource(source) {
56279
+ return typeof source === "string" && SESSION_SOURCES.includes(source);
56280
+ }
56281
+ var SESSION_ACTIVE_WINDOW_MS = 30 * 60 * 1e3;
56282
+ var COLLECTOR_SESSION_SOURCES = ["claude-code", "codex", "cursor"];
56283
+ var PREVIEW_REGISTRABLE_SOURCES = [
56284
+ ...COLLECTOR_SESSION_SOURCES,
56285
+ "cursor-cloud"
56286
+ ];
56287
+ var MAX_INGEST_BATCH = 500;
56288
+ var MAX_RAW_UPLOAD_BYTES = 256 * 1024 * 1024;
56289
+ var MAX_PREVIEW_URL_LENGTH = 2e3;
56290
+ var MAX_REGISTERED_PREVIEWS = 10;
56291
+ var MAX_PREVIEW_LABEL_LENGTH = 60;
56292
+ var MAX_BRANCH_FACTS = 50;
56293
+
56294
+ // ../core/src/menubarAnalytics.ts
56295
+ var MENUBAR_AGENT_CLICK = "menubar:agent_click";
56296
+ var MENUBAR_MCP_WARNING_REMOVE = "menubar:mcp_warning_remove";
56297
+ var menubarAgentClickSchema = external_exports.object({
56298
+ source: external_exports.enum([...SESSION_SOURCES, "unknown"]),
56299
+ destination: external_exports.enum(["focus", "resume", "desktop", "web"])
56300
+ }).strict();
56301
+ var menubarEventSchema = external_exports.discriminatedUnion("event", [
56302
+ menubarAgentClickSchema.extend({ event: external_exports.literal(MENUBAR_AGENT_CLICK) }),
56303
+ mcpWarningDismissalSchema.extend({ event: external_exports.literal(MENUBAR_MCP_WARNING_REMOVE) })
56304
+ ]);
56305
+
56267
56306
  // ../core/src/messageOrigin.ts
56268
56307
  var CLAUDE_CODE_NATIVE_ORIGINS = /* @__PURE__ */ new Set(["human", "agent", "harness", "tool"]);
56269
56308
  var CLAUDE_CODE_TASK_NOTIFICATION_ORIGIN = "task-notification";
@@ -56725,16 +56764,16 @@ function githubRepositoryOfRemote(url2) {
56725
56764
  const afterUser = url2.replace(REMOTE_SCHEME, "").replace(REMOTE_USER, "");
56726
56765
  const host = afterUser.startsWith("ssh.") ? afterUser.slice("ssh.".length) : afterUser;
56727
56766
  if (!host.startsWith("github.com")) return null;
56728
- let path32 = host.slice("github.com".length);
56729
- const port = hasScheme ? REMOTE_PORT.exec(path32) : null;
56730
- if (port !== null) path32 = path32.slice(port[0].length);
56731
- else if (path32.startsWith("/") || path32.startsWith(":")) path32 = path32.slice(1);
56767
+ let path33 = host.slice("github.com".length);
56768
+ const port = hasScheme ? REMOTE_PORT.exec(path33) : null;
56769
+ if (port !== null) path33 = path33.slice(port[0].length);
56770
+ else if (path33.startsWith("/") || path33.startsWith(":")) path33 = path33.slice(1);
56732
56771
  else return null;
56733
- if (path32.endsWith("/")) path32 = path32.slice(0, -1);
56734
- if (path32.endsWith(".git")) path32 = path32.slice(0, -".git".length);
56735
- const segments = path32.split("/");
56772
+ if (path33.endsWith("/")) path33 = path33.slice(0, -1);
56773
+ if (path33.endsWith(".git")) path33 = path33.slice(0, -".git".length);
56774
+ const segments = path33.split("/");
56736
56775
  if (segments.length !== 2 || !segments.every((segment) => REMOTE_PATH_SEGMENT.test(segment))) return null;
56737
- return path32;
56776
+ return path33;
56738
56777
  }
56739
56778
  var PUSH_DESTINATION = /\bTo\s+([^\s\\"]+)/g;
56740
56779
  function pushDestinationsInText(text) {
@@ -57669,10 +57708,10 @@ function boundUnfamiliarPayload(record2) {
57669
57708
  }
57670
57709
  function excludeImageCarriers(record2) {
57671
57710
  const excludedKeys = [];
57672
- const withoutImages = (value, path32) => {
57711
+ const withoutImages = (value, path33) => {
57673
57712
  if (Array.isArray(value)) {
57674
57713
  return value.map((item, index) => {
57675
- const itemPath = `${path32}[${index}]`;
57714
+ const itemPath = `${path33}[${index}]`;
57676
57715
  if (typeof item === "string" && isImageCarrier(item)) {
57677
57716
  excludedKeys.push(itemPath);
57678
57717
  return null;
@@ -57683,7 +57722,7 @@ function excludeImageCarriers(record2) {
57683
57722
  if (!isRecord2(value)) return value;
57684
57723
  const kept = [];
57685
57724
  for (const [key, item] of Object.entries(value)) {
57686
- const keyPath = path32 === "" ? key : `${path32}.${key}`;
57725
+ const keyPath = path33 === "" ? key : `${path33}.${key}`;
57687
57726
  if (isImageBase64Payload(value, key) || typeof item === "string" && isImageCarrier(item)) {
57688
57727
  excludedKeys.push(keyPath);
57689
57728
  continue;
@@ -58404,8 +58443,8 @@ function primaryArg(args) {
58404
58443
  function readFilePath(name, primary) {
58405
58444
  if (!primary || !READ_TOOLS.has(name)) return null;
58406
58445
  if (ARTIFACT_PATH_RE.test(primary)) return null;
58407
- const path32 = primary.startsWith("/workspace/") ? primary.slice("/workspace/".length) : primary;
58408
- return path32.length > 0 ? path32 : null;
58446
+ const path33 = primary.startsWith("/workspace/") ? primary.slice("/workspace/".length) : primary;
58447
+ return path33.length > 0 ? path33 : null;
58409
58448
  }
58410
58449
  function asRecord3(value) {
58411
58450
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -58738,33 +58777,6 @@ function describeSyncSignals(member, now, noUpload = "no sessions uploaded yet")
58738
58777
  return `${line.charAt(0).toUpperCase()}${line.slice(1)}.`;
58739
58778
  }
58740
58779
 
58741
- // ../core/src/sessionIngest.ts
58742
- var SESSION_SOURCES = [
58743
- "claude-code",
58744
- "claude-cloud",
58745
- "codex",
58746
- "cursor",
58747
- "cursor-cloud",
58748
- "github-pr"
58749
- ];
58750
- var SESSION_SPEED_MODES = ["standard", "fast"];
58751
- var SESSION_SPEED_OBSERVATIONS = [...SESSION_SPEED_MODES, "unknown"];
58752
- function isSessionSource(source) {
58753
- return typeof source === "string" && SESSION_SOURCES.includes(source);
58754
- }
58755
- var SESSION_ACTIVE_WINDOW_MS = 30 * 60 * 1e3;
58756
- var COLLECTOR_SESSION_SOURCES = ["claude-code", "codex", "cursor"];
58757
- var PREVIEW_REGISTRABLE_SOURCES = [
58758
- ...COLLECTOR_SESSION_SOURCES,
58759
- "cursor-cloud"
58760
- ];
58761
- var MAX_INGEST_BATCH = 500;
58762
- var MAX_RAW_UPLOAD_BYTES = 256 * 1024 * 1024;
58763
- var MAX_PREVIEW_URL_LENGTH = 2e3;
58764
- var MAX_REGISTERED_PREVIEWS = 10;
58765
- var MAX_PREVIEW_LABEL_LENGTH = 60;
58766
- var MAX_BRANCH_FACTS = 50;
58767
-
58768
58780
  // ../core/src/version.ts
58769
58781
  function parseReleaseVersion(version2) {
58770
58782
  const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version2);
@@ -58837,6 +58849,15 @@ var recentSessionCursorSchema = external_exports.object({
58837
58849
  id: external_exports.uuid()
58838
58850
  });
58839
58851
 
58852
+ // src/mcpPreferences.ts
58853
+ import { mkdirSync as mkdirSync10, readFileSync as readFileSync11, renameSync as renameSync5, writeFileSync as writeFileSync9 } from "node:fs";
58854
+ import path21 from "node:path";
58855
+
58856
+ // ../../apps/collector/src/credentials.ts
58857
+ import { chmodSync as chmodSync4, existsSync as existsSync7, mkdirSync as mkdirSync9, readFileSync as readFileSync8, unlinkSync as unlinkSync3, writeFileSync as writeFileSync8 } from "node:fs";
58858
+ import os12 from "node:os";
58859
+ import path14 from "node:path";
58860
+
58840
58861
  // ../../node_modules/.pnpm/@sentry+core@10.74.0/node_modules/@sentry/core/build/esm/debug-build.js
58841
58862
  var DEBUG_BUILD = typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__;
58842
58863
 
@@ -59017,8 +59038,8 @@ function getFunctionName(fn) {
59017
59038
  return defaultFunctionName;
59018
59039
  }
59019
59040
  }
59020
- function normalizeStackTracePath(path32) {
59021
- let filename = path32?.startsWith("file://") ? path32.slice(7) : path32;
59041
+ function normalizeStackTracePath(path33) {
59042
+ let filename = path33?.startsWith("file://") ? path33.slice(7) : path33;
59022
59043
  if (filename?.match(/\/[A-Z]:/)) {
59023
59044
  filename = filename.slice(1);
59024
59045
  }
@@ -60828,8 +60849,8 @@ function isValidProtocol(protocol) {
60828
60849
  return protocol === "http" || protocol === "https";
60829
60850
  }
60830
60851
  function dsnToString(dsn, withPassword = false) {
60831
- const { host, path: path32, pass, port, projectId, protocol, publicKey } = dsn;
60832
- return `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ""}@${host}${port ? `:${port}` : ""}/${path32 ? `${path32}/` : path32}${projectId}`;
60852
+ const { host, path: path33, pass, port, projectId, protocol, publicKey } = dsn;
60853
+ return `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ""}@${host}${port ? `:${port}` : ""}/${path33 ? `${path33}/` : path33}${projectId}`;
60833
60854
  }
60834
60855
  function dsnFromString(str) {
60835
60856
  const match = DSN_REGEX.exec(str);
@@ -60840,11 +60861,11 @@ function dsnFromString(str) {
60840
60861
  return void 0;
60841
60862
  }
60842
60863
  const [protocol, publicKey, pass = "", host = "", port = "", lastPath = ""] = match.slice(1);
60843
- let path32 = "";
60864
+ let path33 = "";
60844
60865
  let projectId = lastPath;
60845
60866
  const split = projectId.split("/");
60846
60867
  if (split.length > 1) {
60847
- path32 = split.slice(0, -1).join("/");
60868
+ path33 = split.slice(0, -1).join("/");
60848
60869
  projectId = split.pop();
60849
60870
  }
60850
60871
  if (projectId) {
@@ -60853,7 +60874,7 @@ function dsnFromString(str) {
60853
60874
  projectId = projectMatch[0];
60854
60875
  }
60855
60876
  }
60856
- return dsnFromComponents({ host, pass, path: path32, projectId, port, protocol, publicKey });
60877
+ return dsnFromComponents({ host, pass, path: path33, projectId, port, protocol, publicKey });
60857
60878
  }
60858
60879
  function dsnFromComponents(components) {
60859
60880
  return {
@@ -65382,9 +65403,9 @@ function stripUrlQueryAndFragment(urlPath) {
65382
65403
  return urlPath.split(/[?#]/, 1)[0];
65383
65404
  }
65384
65405
  function getSanitizedUrlString(url2) {
65385
- const { protocol, host, path: path32 } = url2;
65406
+ const { protocol, host, path: path33 } = url2;
65386
65407
  const filteredHost = host?.replace(/^.*@/, "[filtered]:[filtered]@").replace(/(:80)$/, "").replace(/(:443)$/, "") || "";
65387
- return `${protocol ? `${protocol}://` : ""}${filteredHost}${path32}`;
65408
+ return `${protocol ? `${protocol}://` : ""}${filteredHost}${path33}`;
65388
65409
  }
65389
65410
  function stripDataUrlContent(url2, includeDataPrefix = true) {
65390
65411
  if (url2.startsWith("data:")) {
@@ -66329,8 +66350,8 @@ function splitPath(filename) {
66329
66350
  const parts = splitPathRe.exec(truncated);
66330
66351
  return parts ? parts.slice(1) : [];
66331
66352
  }
66332
- function dirname(path32) {
66333
- const result = splitPath(path32);
66353
+ function dirname(path33) {
66354
+ const result = splitPath(path33);
66334
66355
  const root = result[0] || "";
66335
66356
  let dir = result[1];
66336
66357
  if (!root && !dir) {
@@ -70173,15 +70194,15 @@ var getLayerMetadata = (route, layer, layerPath) => {
70173
70194
  };
70174
70195
  }
70175
70196
  };
70176
- var getRouterPath = (path32, layer) => {
70197
+ var getRouterPath = (path33, layer) => {
70177
70198
  const stackLayer = Array.isArray(layer.handle?.stack) ? layer.handle?.stack?.[0] : void 0;
70178
70199
  if (stackLayer?.route?.path) {
70179
- return `${path32}${stackLayer.route.path}`;
70200
+ return `${path33}${stackLayer.route.path}`;
70180
70201
  }
70181
70202
  if (stackLayer && Array.isArray(stackLayer?.handle?.stack)) {
70182
- return getRouterPath(path32, stackLayer);
70203
+ return getRouterPath(path33, stackLayer);
70183
70204
  }
70184
- return path32;
70205
+ return path33;
70185
70206
  };
70186
70207
  var isLayerIgnored = (name, type, config2) => {
70187
70208
  if (Array.isArray(config2?.ignoreLayersType) && config2?.ignoreLayersType?.includes(type)) {
@@ -70201,7 +70222,7 @@ function getActualMatchedRoute(req, constructedRoute) {
70201
70222
  if (layersStore.length === 0) {
70202
70223
  return void 0;
70203
70224
  }
70204
- if (layersStore.every((path32) => path32 === "/")) {
70225
+ if (layersStore.every((path33) => path33 === "/")) {
70205
70226
  return req.originalUrl === "/" ? "/" : void 0;
70206
70227
  }
70207
70228
  if (constructedRoute === "*") {
@@ -70217,11 +70238,11 @@ function getActualMatchedRoute(req, constructedRoute) {
70217
70238
  function getConstructedRoute(req) {
70218
70239
  const layersStore = getStoredLayers(req);
70219
70240
  let constructedRoute = "";
70220
- for (const path32 of layersStore) {
70221
- if (path32 === "/" || path32 === "/*") {
70241
+ for (const path33 of layersStore) {
70242
+ if (path33 === "/" || path33 === "/*") {
70222
70243
  continue;
70223
70244
  }
70224
- constructedRoute += !constructedRoute || constructedRoute.endsWith("/") ? path32 : `/${path32}`;
70245
+ constructedRoute += !constructedRoute || constructedRoute.endsWith("/") ? path33 : `/${path33}`;
70225
70246
  }
70226
70247
  return constructedRoute.replace(/\/{2,}/g, "/");
70227
70248
  }
@@ -70726,9 +70747,9 @@ function getRequestUrlObject(requestOptions) {
70726
70747
  const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);
70727
70748
  const hostname4 = hostHeader || requestOptions.hostname || requestOptions.host || "";
70728
70749
  const port = !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\d+)$/.test(hostname4) ? "" : `:${requestOptions.port}`;
70729
- const path32 = requestOptions.path ? requestOptions.path : "/";
70750
+ const path33 = requestOptions.path ? requestOptions.path : "/";
70730
70751
  const base = `${protocol}//${hostname4}${port}`;
70731
- return new URL(path32.startsWith("//") ? `${base}${path32}` : path32, base);
70752
+ return new URL(path33.startsWith("//") ? `${base}${path33}` : path33, base);
70732
70753
  }
70733
70754
  function getRequestUrlFromClientRequest(request2) {
70734
70755
  return String(getRequestUrl(getRequestOptions(request2)));
@@ -71401,11 +71422,11 @@ function shouldIgnoreSpansForIncomingRequest(request2, {
71401
71422
  return false;
71402
71423
  }
71403
71424
  function isStaticAssetRequest(urlPath) {
71404
- const path32 = stripUrlQueryAndFragment(urlPath);
71405
- if (path32.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
71425
+ const path33 = stripUrlQueryAndFragment(urlPath);
71426
+ if (path33.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
71406
71427
  return true;
71407
71428
  }
71408
- if (path32.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
71429
+ if (path33.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
71409
71430
  return true;
71410
71431
  }
71411
71432
  return false;
@@ -71646,11 +71667,11 @@ function isKnownPrefetchRequest2(req) {
71646
71667
  return req.headers["next-router-prefetch"] === "1";
71647
71668
  }
71648
71669
  function isStaticAssetRequest2(urlPath) {
71649
- const path32 = stripUrlQueryAndFragment(urlPath);
71650
- if (path32.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
71670
+ const path33 = stripUrlQueryAndFragment(urlPath);
71671
+ if (path33.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
71651
71672
  return true;
71652
71673
  }
71653
- if (path32.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
71674
+ if (path33.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
71654
71675
  return true;
71655
71676
  }
71656
71677
  return false;
@@ -72010,19 +72031,19 @@ function getBreadcrumbData(request2) {
72010
72031
  return {};
72011
72032
  }
72012
72033
  }
72013
- function getAbsoluteUrl2(origin, path32 = "/") {
72034
+ function getAbsoluteUrl2(origin, path33 = "/") {
72014
72035
  try {
72015
- const url2 = new URL(path32, origin);
72036
+ const url2 = new URL(path33, origin);
72016
72037
  return url2.toString();
72017
72038
  } catch {
72018
72039
  const url2 = `${origin}`;
72019
- if (url2.endsWith("/") && path32.startsWith("/")) {
72020
- return `${url2}${path32.slice(1)}`;
72040
+ if (url2.endsWith("/") && path33.startsWith("/")) {
72041
+ return `${url2}${path33.slice(1)}`;
72021
72042
  }
72022
- if (!url2.endsWith("/") && !path32.startsWith("/")) {
72023
- return `${url2}/${path32}`;
72043
+ if (!url2.endsWith("/") && !path33.startsWith("/")) {
72044
+ return `${url2}/${path33}`;
72024
72045
  }
72025
- return `${url2}${path32}`;
72046
+ return `${url2}${path33}`;
72026
72047
  }
72027
72048
  }
72028
72049
 
@@ -72267,15 +72288,15 @@ function getRequestMethod(original) {
72267
72288
  }
72268
72289
  return "_OTHER";
72269
72290
  }
72270
- function getAbsoluteUrl3(origin, path32 = "/") {
72291
+ function getAbsoluteUrl3(origin, path33 = "/") {
72271
72292
  const url2 = `${origin}`;
72272
- if (url2.endsWith("/") && path32.startsWith("/")) {
72273
- return `${url2}${path32.slice(1)}`;
72293
+ if (url2.endsWith("/") && path33.startsWith("/")) {
72294
+ return `${url2}${path33.slice(1)}`;
72274
72295
  }
72275
- if (!url2.endsWith("/") && !path32.startsWith("/")) {
72276
- return `${url2}/${path32}`;
72296
+ if (!url2.endsWith("/") && !path33.startsWith("/")) {
72297
+ return `${url2}/${path33}`;
72277
72298
  }
72278
- return `${url2}${path32}`;
72299
+ return `${url2}${path33}`;
72279
72300
  }
72280
72301
 
72281
72302
  // ../../node_modules/.pnpm/@sentry+node-core@10.74.0_@opentelemetry+api@1.9.1_@opentelemetry+core@2.11.0_@opentele_b542b1cf9336850aabd631474d797bed/node_modules/@sentry/node-core/build/esm/integrations/node-fetch/index.js
@@ -74768,12 +74789,12 @@ function emplace(map2, key, contents) {
74768
74789
  }
74769
74790
  return value;
74770
74791
  }
74771
- function shouldSkipContextLinesForFile(path32) {
74772
- if (path32.startsWith("node:")) return true;
74773
- if (path32.endsWith(".min.js")) return true;
74774
- if (path32.endsWith(".min.cjs")) return true;
74775
- if (path32.endsWith(".min.mjs")) return true;
74776
- if (path32.startsWith("data:")) return true;
74792
+ function shouldSkipContextLinesForFile(path33) {
74793
+ if (path33.startsWith("node:")) return true;
74794
+ if (path33.endsWith(".min.js")) return true;
74795
+ if (path33.endsWith(".min.cjs")) return true;
74796
+ if (path33.endsWith(".min.mjs")) return true;
74797
+ if (path33.startsWith("data:")) return true;
74777
74798
  return false;
74778
74799
  }
74779
74800
  function shouldSkipContextLinesForFrame(frame) {
@@ -74821,9 +74842,9 @@ function makeLineReaderRanges(lines, linecontext) {
74821
74842
  }
74822
74843
  return out;
74823
74844
  }
74824
- function getContextLinesFromFile(path32, ranges, output2) {
74845
+ function getContextLinesFromFile(path33, ranges, output2) {
74825
74846
  return new Promise((resolve2, _reject) => {
74826
- const stream = createReadStream(path32);
74847
+ const stream = createReadStream(path33);
74827
74848
  const lineReaded = createInterface({
74828
74849
  input: stream
74829
74850
  });
@@ -74841,8 +74862,8 @@ function getContextLinesFromFile(path32, ranges, output2) {
74841
74862
  let rangeStart = range[0];
74842
74863
  let rangeEnd = range[1];
74843
74864
  function onStreamError(e) {
74844
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path32, 1);
74845
- DEBUG_BUILD2 && debug.error(`Failed to read file: ${path32}. Error: ${e}`);
74865
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path33, 1);
74866
+ DEBUG_BUILD2 && debug.error(`Failed to read file: ${path33}. Error: ${e}`);
74846
74867
  lineReaded.close();
74847
74868
  lineReaded.removeAllListeners();
74848
74869
  destroyStreamAndResolve();
@@ -76281,8 +76302,8 @@ function getSpotlightConfig(optionsSpotlight) {
76281
76302
 
76282
76303
  // ../../node_modules/.pnpm/@sentry+node-core@10.74.0_@opentelemetry+api@1.9.1_@opentelemetry+core@2.11.0_@opentele_b542b1cf9336850aabd631474d797bed/node_modules/@sentry/node-core/build/esm/utils/module.js
76283
76304
  import { posix, sep } from "node:path";
76284
- function normalizeWindowsPath(path32) {
76285
- return path32.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
76305
+ function normalizeWindowsPath(path33) {
76306
+ return path33.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
76286
76307
  }
76287
76308
  function createGetModuleFromFilename(basePath = process.argv[1] ? dirname(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
76288
76309
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
@@ -79167,22 +79188,22 @@ function addSpanSource(span, loc, start, end) {
79167
79188
  span.setAttribute(AttributeNames2.SOURCE, source);
79168
79189
  }
79169
79190
  }
79170
- function createFieldIfNotExists(contextValue, info, path32) {
79171
- let field = getField(contextValue, path32);
79191
+ function createFieldIfNotExists(contextValue, info, path33) {
79192
+ let field = getField(contextValue, path33);
79172
79193
  if (field) {
79173
79194
  return { field, spanAdded: false };
79174
79195
  }
79175
- const parentSpan = getParentFieldSpan(contextValue, path32);
79196
+ const parentSpan = getParentFieldSpan(contextValue, path33);
79176
79197
  field = {
79177
- span: createResolverSpan(contextValue, info, path32, parentSpan)
79198
+ span: createResolverSpan(contextValue, info, path33, parentSpan)
79178
79199
  };
79179
- addField(contextValue, path32, field);
79200
+ addField(contextValue, path33, field);
79180
79201
  return { field, spanAdded: true };
79181
79202
  }
79182
- function createResolverSpan(contextValue, info, path32, parentSpan) {
79203
+ function createResolverSpan(contextValue, info, path33, parentSpan) {
79183
79204
  const attributes = {
79184
79205
  [AttributeNames2.FIELD_NAME]: info.fieldName,
79185
- [AttributeNames2.FIELD_PATH]: path32.join("."),
79206
+ [AttributeNames2.FIELD_PATH]: path33.join("."),
79186
79207
  [AttributeNames2.FIELD_TYPE]: info.returnType.toString(),
79187
79208
  [AttributeNames2.PARENT_NAME]: info.parentType.name
79188
79209
  };
@@ -79214,15 +79235,15 @@ function getOperation(document2, operationName) {
79214
79235
  return document2.definitions.find((definition) => OPERATION_VALUES.indexOf(definition?.operation) !== -1);
79215
79236
  }
79216
79237
  }
79217
- function addField(contextValue, path32, field) {
79218
- return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path32.join(".")] = field;
79238
+ function addField(contextValue, path33, field) {
79239
+ return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path33.join(".")] = field;
79219
79240
  }
79220
- function getField(contextValue, path32) {
79221
- return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path32.join(".")];
79241
+ function getField(contextValue, path33) {
79242
+ return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path33.join(".")];
79222
79243
  }
79223
- function getParentFieldSpan(contextValue, path32) {
79224
- for (let i = path32.length - 1; i > 0; i--) {
79225
- const field = getField(contextValue, path32.slice(0, i));
79244
+ function getParentFieldSpan(contextValue, path33) {
79245
+ for (let i = path33.length - 1; i > 0; i--) {
79246
+ const field = getField(contextValue, path33.slice(0, i));
79226
79247
  if (field) {
79227
79248
  return field.span;
79228
79249
  }
@@ -79232,9 +79253,9 @@ function getParentFieldSpan(contextValue, path32) {
79232
79253
  function getRootSpan2(contextValue) {
79233
79254
  return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].span;
79234
79255
  }
79235
- function pathToArray(path32) {
79256
+ function pathToArray(path33) {
79236
79257
  const flattened = [];
79237
- let curr = path32;
79258
+ let curr = path33;
79238
79259
  while (curr) {
79239
79260
  flattened.push(String(curr.key));
79240
79261
  curr = curr.prev;
@@ -79375,8 +79396,8 @@ function wrapFieldResolver(getConfig3, fieldResolver, isDefaultResolver = false)
79375
79396
  if (!contextValue[OTEL_GRAPHQL_DATA_SYMBOL]) {
79376
79397
  return fieldResolver.call(this, source, args, contextValue, info);
79377
79398
  }
79378
- const path32 = pathToArray(info?.path);
79379
- const { field, spanAdded } = createFieldIfNotExists(contextValue, info, path32);
79399
+ const path33 = pathToArray(info?.path);
79400
+ const { field, spanAdded } = createFieldIfNotExists(contextValue, info, path33);
79380
79401
  const span = field.span;
79381
79402
  const shouldEndSpan = spanAdded;
79382
79403
  return withActiveSpan(span, () => {
@@ -82359,10 +82380,10 @@ var PostgresJsInstrumentation = class extends import_instrumentation24.Instrumen
82359
82380
  },
82360
82381
  (exports) => exports
82361
82382
  );
82362
- ["src", "cf/src", "cjs/src"].forEach((path32) => {
82383
+ ["src", "cf/src", "cjs/src"].forEach((path33) => {
82363
82384
  module2.files.push(
82364
82385
  new InstrumentationNodeModuleFile(
82365
- `postgres/${path32}/query.js`,
82386
+ `postgres/${path33}/query.js`,
82366
82387
  SUPPORTED_VERSIONS4,
82367
82388
  this._patchQueryPrototype.bind(this),
82368
82389
  this._unpatchQueryPrototype.bind(this)
@@ -82993,13 +83014,13 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
82993
83014
  return function(original) {
82994
83015
  return function wrappedHandler(...args) {
82995
83016
  if (typeof args[0] === "string") {
82996
- const path32 = args[0];
83017
+ const path33 = args[0];
82997
83018
  if (args.length === 1) {
82998
- return original.apply(this, [path32]);
83019
+ return original.apply(this, [path33]);
82999
83020
  }
83000
83021
  const handlers2 = args.slice(1);
83001
83022
  return original.apply(this, [
83002
- path32,
83023
+ path33,
83003
83024
  ...handlers2.map((handler) => instrumentation._wrapHandler(handler))
83004
83025
  ]);
83005
83026
  }
@@ -83033,13 +83054,13 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
83033
83054
  return function(original) {
83034
83055
  return function wrappedHandler(...args) {
83035
83056
  if (typeof args[0] === "string") {
83036
- const path32 = args[0];
83057
+ const path33 = args[0];
83037
83058
  if (args.length === 1) {
83038
- return original.apply(this, [path32]);
83059
+ return original.apply(this, [path33]);
83039
83060
  }
83040
83061
  const handlers2 = args.slice(1);
83041
83062
  return original.apply(this, [
83042
- path32,
83063
+ path33,
83043
83064
  ...handlers2.map((handler) => instrumentation._wrapHandler(handler))
83044
83065
  ]);
83045
83066
  }
@@ -83059,8 +83080,8 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
83059
83080
  if (!instrumentation.isEnabled()) {
83060
83081
  return handler.apply(this, [c, next]);
83061
83082
  }
83062
- const path32 = c.req.path;
83063
- const span = instrumentation.tracer.startSpan(path32);
83083
+ const path33 = c.req.path;
83084
+ const span = instrumentation.tracer.startSpan(path33);
83064
83085
  return context.with(trace.setSpan(context.active(), span), () => {
83065
83086
  return instrumentation._safeExecute(
83066
83087
  () => {
@@ -83070,7 +83091,7 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
83070
83091
  const type = instrumentation._determineHandlerType(result2);
83071
83092
  span.setAttributes({
83072
83093
  [AttributeNames5.HONO_TYPE]: type,
83073
- [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path32 : handler.name || "anonymous"
83094
+ [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path33 : handler.name || "anonymous"
83074
83095
  });
83075
83096
  instrumentation.getConfig().responseHook?.(span);
83076
83097
  return result2;
@@ -83079,7 +83100,7 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
83079
83100
  const type = instrumentation._determineHandlerType(result);
83080
83101
  span.setAttributes({
83081
83102
  [AttributeNames5.HONO_TYPE]: type,
83082
- [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path32 : handler.name || "anonymous"
83103
+ [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path33 : handler.name || "anonymous"
83083
83104
  });
83084
83105
  instrumentation.getConfig().responseHook?.(span);
83085
83106
  return result;
@@ -83283,11 +83304,11 @@ var KoaInstrumentation = class extends import_instrumentation29.InstrumentationB
83283
83304
  const router = dispatchLayer.router;
83284
83305
  const routesStack = router?.stack ?? [];
83285
83306
  for (const pathLayer of routesStack) {
83286
- const path32 = pathLayer.path;
83307
+ const path33 = pathLayer.path;
83287
83308
  const pathStack = pathLayer.stack;
83288
83309
  for (let j = 0; j < pathStack.length; j++) {
83289
83310
  const routedMiddleware = pathStack[j];
83290
- pathStack[j] = this._patchLayer(routedMiddleware, true, path32);
83311
+ pathStack[j] = this._patchLayer(routedMiddleware, true, path33);
83291
83312
  }
83292
83313
  }
83293
83314
  return dispatchLayer;
@@ -85883,11 +85904,11 @@ import path12 from "node:path";
85883
85904
  import { existsSync as existsSync6, lstatSync as lstatSync4 } from "node:fs";
85884
85905
  import path11 from "node:path";
85885
85906
 
85886
- // ../../apps/collector/src/codexTranscriptHints.ts
85907
+ // ../../apps/collector/src/codexTranscriptDiscovery.ts
85887
85908
  import { createHash } from "node:crypto";
85888
85909
  import { closeSync, lstatSync, openSync, readSync, readdirSync, realpathSync } from "node:fs";
85889
85910
  import path2 from "node:path";
85890
- var hintSchema = external_exports.object({
85911
+ var transcriptDiscoveryRecordSchema = external_exports.object({
85891
85912
  sessionId: external_exports.string().regex(/^[a-zA-Z0-9_-]{1,200}$/),
85892
85913
  transcriptPath: external_exports.string().max(4096).nullable()
85893
85914
  });
@@ -85900,7 +85921,7 @@ function codexTranscriptRecordPath(home, sessionId) {
85900
85921
  `${createHash("sha256").update(sessionId).digest("hex")}.json`
85901
85922
  );
85902
85923
  }
85903
- function readCodexTranscriptHints(home, roots) {
85924
+ function readCodexTranscriptDiscoveryRecords(home, roots) {
85904
85925
  const dir = codexTranscriptRecordsDir(home);
85905
85926
  let files;
85906
85927
  try {
@@ -85912,9 +85933,9 @@ function readCodexTranscriptHints(home, roots) {
85912
85933
  for (const file2 of files) {
85913
85934
  if (!/^[a-f0-9]{64}\.json$/.test(file2)) continue;
85914
85935
  try {
85915
- const hintPath = path2.join(dir, file2);
85916
- if (!lstatSync(hintPath).isFile()) continue;
85917
- const fd = openSync(hintPath, "r");
85936
+ const recordPath = path2.join(dir, file2);
85937
+ if (!lstatSync(recordPath).isFile()) continue;
85938
+ const fd = openSync(recordPath, "r");
85918
85939
  let text;
85919
85940
  try {
85920
85941
  const buffer = Buffer.alloc(32 * 1024 + 1);
@@ -85924,10 +85945,10 @@ function readCodexTranscriptHints(home, roots) {
85924
85945
  } finally {
85925
85946
  closeSync(fd);
85926
85947
  }
85927
- const hint = hintSchema.parse(JSON.parse(text));
85928
- if (file2 !== `${createHash("sha256").update(hint.sessionId).digest("hex")}.json`) continue;
85929
- if (hint.transcriptPath === null || !path2.isAbsolute(hint.transcriptPath)) continue;
85930
- const rolloutPath = path2.normalize(hint.transcriptPath);
85948
+ const record2 = transcriptDiscoveryRecordSchema.parse(JSON.parse(text));
85949
+ if (file2 !== `${createHash("sha256").update(record2.sessionId).digest("hex")}.json`) continue;
85950
+ if (record2.transcriptPath === null || !path2.isAbsolute(record2.transcriptPath)) continue;
85951
+ const rolloutPath = path2.normalize(record2.transcriptPath);
85931
85952
  if (path2.extname(rolloutPath) !== ".jsonl") continue;
85932
85953
  const rootIndex = roots.findIndex((root2) => {
85933
85954
  const relative2 = path2.relative(root2, rolloutPath);
@@ -85937,7 +85958,7 @@ function readCodexTranscriptHints(home, roots) {
85937
85958
  const root = roots[rootIndex];
85938
85959
  if (realpathSync(rolloutPath) !== path2.join(realpathSync(root), path2.relative(root, rolloutPath)))
85939
85960
  continue;
85940
- result.push({ rolloutPath, sessionId: hint.sessionId, archived: rootIndex === 1 });
85961
+ result.push({ rolloutPath, sessionId: record2.sessionId, archived: rootIndex === 1 });
85941
85962
  } catch {
85942
85963
  }
85943
85964
  }
@@ -85950,7 +85971,7 @@ import { createHmac } from "node:crypto";
85950
85971
  // ../../apps/collector/src/http.ts
85951
85972
  var import_undici = __toESM(require_undici(), 1);
85952
85973
  var CLI_VERSION_HEADER = "x-powerplant-cli-version";
85953
- var cliVersion = true ? "0.4.12" : "0.0.0-checkout";
85974
+ var cliVersion = true ? "0.4.14" : "0.0.0-checkout";
85954
85975
  function cliVersionHeaders() {
85955
85976
  return { [CLI_VERSION_HEADER]: cliVersion, "user-agent": `powerplant-cli/${cliVersion}` };
85956
85977
  }
@@ -86074,8 +86095,8 @@ function createStructureDiagnostics() {
86074
86095
  observe: (source) => (observation) => {
86075
86096
  try {
86076
86097
  const formatVersion = admitted("formatVersion", observation.formatVersion ?? null);
86077
- const path32 = observation.path.replace(/[^A-Za-z0-9_.$:/=[\]-]/g, "_").slice(0, 160) || "other";
86078
- const key = [source, path32, observation.reason, observation.valueType, formatVersion].join("\0");
86098
+ const path33 = observation.path.replace(/[^A-Za-z0-9_.$:/=[\]-]/g, "_").slice(0, 160) || "other";
86099
+ const key = [source, path33, observation.reason, observation.valueType, formatVersion].join("\0");
86079
86100
  const count3 = observation.count ?? 1;
86080
86101
  const existing = groups.get(key);
86081
86102
  if (existing) {
@@ -86085,7 +86106,7 @@ function createStructureDiagnostics() {
86085
86106
  if (samples.length >= MAX_STRUCTURE_DIAGNOSTICS) return;
86086
86107
  const sample = {
86087
86108
  source,
86088
- path: path32,
86109
+ path: path33,
86089
86110
  reason: observation.reason,
86090
86111
  valueType: observation.valueType,
86091
86112
  formatVersion,
@@ -86257,7 +86278,7 @@ function bindDiagnosticEnrollment(diagnostic, token) {
86257
86278
  passEnrollments.set(diagnostic, token);
86258
86279
  }
86259
86280
 
86260
- // ../../apps/collector/src/codexCli.ts
86281
+ // ../../apps/collector/src/codexSessions.ts
86261
86282
  import { closeSync as closeSync3, mkdirSync as mkdirSync2, openSync as openSync3, renameSync, rmSync as rmSync2, utimesSync, writeSync } from "node:fs";
86262
86283
  import os6 from "node:os";
86263
86284
  import path5 from "node:path";
@@ -86697,13 +86718,17 @@ function isPathWithinScopes(resolved, scopePaths) {
86697
86718
  );
86698
86719
  }
86699
86720
 
86700
- // ../../apps/collector/src/codexCli.ts
86721
+ // ../../apps/collector/src/codexSessions.ts
86701
86722
  function parseCodexRollout(text, sharedUsage) {
86702
86723
  let meta3 = null;
86724
+ let initialEvent;
86725
+ let records = 0;
86703
86726
  let model;
86704
86727
  const timestamps = [];
86705
86728
  const usage = sharedUsage ?? createCodexUsageReader();
86706
86729
  for (const line of parseJsonl(text)) {
86730
+ records += 1;
86731
+ if (records === 2 && meta3 !== null) initialEvent = line;
86707
86732
  if (typeof line.timestamp === "string") timestamps.push(line.timestamp);
86708
86733
  usage.pushRecord(line);
86709
86734
  const payload = line.payload;
@@ -86719,8 +86744,10 @@ function parseCodexRollout(text, sharedUsage) {
86719
86744
  if (meta3 === null && timestamps.length === 0) return null;
86720
86745
  const git = meta3?.git ?? null;
86721
86746
  const sessionId = meta3?.id ?? meta3?.session_id;
86747
+ const facts = meta3 === null ? {} : harnessSessionFacts("codex", { ...meta3, initialEvent });
86722
86748
  return {
86723
- kind: meta3 !== null && isSidecarThread(meta3) ? "subagent" : "session",
86749
+ kind: facts.subagent ? "subagent" : "session",
86750
+ ...facts.standaloneReview && { standaloneReview: true },
86724
86751
  ...typeof sessionId === "string" && sessionId !== "" && { sessionId },
86725
86752
  startedAt: timestamps[0],
86726
86753
  endedAt: timestamps[timestamps.length - 1],
@@ -86756,6 +86783,7 @@ function foldRolloutPages(pages, usage) {
86756
86783
  const repoFullName = first("repoFullName");
86757
86784
  return {
86758
86785
  kind: pages[0].kind,
86786
+ ...pages[0].standaloneReview && { standaloneReview: true },
86759
86787
  ...sessionId !== void 0 && { sessionId },
86760
86788
  ...startedAt !== void 0 && { startedAt },
86761
86789
  ...endedAt !== void 0 && { endedAt },
@@ -86777,21 +86805,21 @@ function rolloutIdentity(rolloutPath) {
86777
86805
  if (!conventional) return { threadId: name, page: false };
86778
86806
  return { threadId: threadId2.toLowerCase(), page: pageId !== void 0 };
86779
86807
  }
86780
- function codexSpoolDir(home) {
86808
+ function codexMergedTranscriptsDir(home) {
86781
86809
  return path5.join(home, ".config", "powerplant", "codex");
86782
86810
  }
86783
- function mergedSpoolIsFresh(spoolPath, mtimeMs) {
86784
- const existing = statIfExists(spoolPath);
86811
+ function mergedTranscriptIsFresh(mergedTranscriptPath, mtimeMs) {
86812
+ const existing = statIfExists(mergedTranscriptPath);
86785
86813
  return existing !== null && Math.abs(existing.mtimeMs - mtimeMs) < 1;
86786
86814
  }
86787
- var MergedSpoolWriter = class {
86788
- constructor(spoolPath) {
86789
- this.spoolPath = spoolPath;
86790
- mkdirSync2(path5.dirname(spoolPath), { recursive: true, mode: 448 });
86791
- this.tmpPath = `${spoolPath}.${process.pid}.tmp`;
86815
+ var MergedTranscriptWriter = class {
86816
+ constructor(mergedTranscriptPath) {
86817
+ this.mergedTranscriptPath = mergedTranscriptPath;
86818
+ mkdirSync2(path5.dirname(mergedTranscriptPath), { recursive: true, mode: 448 });
86819
+ this.tmpPath = `${mergedTranscriptPath}.${process.pid}.tmp`;
86792
86820
  this.fd = openSync3(this.tmpPath, "w", 384);
86793
86821
  }
86794
- spoolPath;
86822
+ mergedTranscriptPath;
86795
86823
  tmpPath;
86796
86824
  fd;
86797
86825
  bytes = 0;
@@ -86805,7 +86833,7 @@ var MergedSpoolWriter = class {
86805
86833
  finish(mtimeMs) {
86806
86834
  this.close();
86807
86835
  utimesSync(this.tmpPath, mtimeMs / 1e3, mtimeMs / 1e3);
86808
- renameSync(this.tmpPath, this.spoolPath);
86836
+ renameSync(this.tmpPath, this.mergedTranscriptPath);
86809
86837
  return this.bytes;
86810
86838
  }
86811
86839
  abandon() {
@@ -86875,7 +86903,7 @@ async function collectCodexSessions(options = {}) {
86875
86903
  const now = options.now ?? Date.now();
86876
86904
  const capture = options.capture ?? captureEverythingUnresolved;
86877
86905
  const maxBytes = options.maxTranscriptBytes ?? MAX_TRANSCRIPT_FILE_BYTES;
86878
- const spoolDir = options.spoolDir ?? codexSpoolDir(options.homeDir ?? os6.homedir());
86906
+ const mergedTranscriptsDir = options.mergedTranscriptsDir ?? codexMergedTranscriptsDir(options.homeDir ?? os6.homedir());
86879
86907
  const items = [];
86880
86908
  const candidates = [];
86881
86909
  const unreadable = [];
@@ -86886,12 +86914,12 @@ async function collectCodexSessions(options = {}) {
86886
86914
  let largestMergedBytes = 0;
86887
86915
  const externalIdOf = (rolloutPath) => path5.basename(rolloutPath, ".jsonl");
86888
86916
  const files = /* @__PURE__ */ new Map();
86889
- const observe = async (paths, archived, hintSessionId) => {
86917
+ const observe = async (paths, archived, discoverySessionId) => {
86890
86918
  for (const rolloutPath of paths) {
86891
86919
  const known = files.get(rolloutPath);
86892
86920
  if (known !== void 0) {
86893
- if (hintSessionId === void 0) delete known.hintSessionIds;
86894
- else known.hintSessionIds?.push(hintSessionId);
86921
+ if (discoverySessionId === void 0) delete known.discoverySessionIds;
86922
+ else known.discoverySessionIds?.push(discoverySessionId);
86895
86923
  continue;
86896
86924
  }
86897
86925
  await yieldToEventLoop();
@@ -86904,15 +86932,15 @@ async function collectCodexSessions(options = {}) {
86904
86932
  mtimeMs: stat.mtimeMs,
86905
86933
  changedMs: Math.max(stat.mtimeMs, stat.ctimeMs),
86906
86934
  sizeBytes: stat.size,
86907
- ...hintSessionId !== void 0 && { hintSessionIds: [hintSessionId] }
86935
+ ...discoverySessionId !== void 0 && { discoverySessionIds: [discoverySessionId] }
86908
86936
  });
86909
86937
  }
86910
86938
  };
86911
86939
  const archiveDir = codexArchivedSessionsDir(sessionsDir);
86912
- const hintHome = options.homeDir ?? (options.codexDir === void 0 ? os6.homedir() : void 0);
86913
- if (hintHome !== void 0) {
86914
- for (const hint of readCodexTranscriptHints(hintHome, [sessionsDir, archiveDir])) {
86915
- await observe([hint.rolloutPath], hint.archived, hint.sessionId);
86940
+ const discoveryHome = options.homeDir ?? (options.codexDir === void 0 ? os6.homedir() : void 0);
86941
+ if (discoveryHome !== void 0) {
86942
+ for (const record2 of readCodexTranscriptDiscoveryRecords(discoveryHome, [sessionsDir, archiveDir])) {
86943
+ await observe([record2.rolloutPath], record2.archived, record2.sessionId);
86916
86944
  }
86917
86945
  }
86918
86946
  await observe(rolloutFiles(sessionsDir), false);
@@ -86927,17 +86955,17 @@ async function collectCodexSessions(options = {}) {
86927
86955
  const stored = dedupeStoreCopies(observed);
86928
86956
  let externalId = externalIdOf((stored.find((file2) => !file2.identity.page) ?? stored[0]).rolloutPath);
86929
86957
  try {
86930
- const spoolPath = stored.length > 1 ? path5.join(spoolDir, `${threadId2}.jsonl`) : void 0;
86958
+ const mergedTranscriptPath = stored.length > 1 ? path5.join(mergedTranscriptsDir, `${threadId2}.jsonl`) : void 0;
86931
86959
  const changedMs = Math.max(...stored.map((file2) => file2.changedMs));
86932
86960
  if (options.sinceMs !== void 0 && changedMs < options.sinceMs) {
86933
- const neverMerged = spoolPath !== void 0 && !options.locationsOnly && statIfExists(spoolPath) === null;
86961
+ const neverMerged = mergedTranscriptPath !== void 0 && !options.locationsOnly && statIfExists(mergedTranscriptPath) === null;
86934
86962
  if (!neverMerged) continue;
86935
86963
  }
86936
86964
  await yieldToEventLoop();
86937
86965
  const named = stored.filter((file2) => {
86938
- if (file2.hintSessionIds === void 0) return true;
86966
+ if (file2.discoverySessionIds === void 0) return true;
86939
86967
  const { sessionId } = rolloutLocation(file2.rolloutPath);
86940
- return sessionId !== void 0 && file2.hintSessionIds.includes(sessionId);
86968
+ return sessionId !== void 0 && file2.discoverySessionIds.includes(sessionId);
86941
86969
  });
86942
86970
  if (named.length === 0) continue;
86943
86971
  const threadFiles = named.length > 1 ? orderPages(named) : named;
@@ -86967,7 +86995,7 @@ async function collectCodexSessions(options = {}) {
86967
86995
  const thread = {
86968
86996
  externalId,
86969
86997
  files: threadFiles,
86970
- ...threadFiles.length > 1 && spoolPath !== void 0 && { spoolPath },
86998
+ ...threadFiles.length > 1 && mergedTranscriptPath !== void 0 && { mergedTranscriptPath },
86971
86999
  mtimeMs,
86972
87000
  archived: threadFiles.every((file2) => file2.archived)
86973
87001
  };
@@ -87017,8 +87045,8 @@ async function collectCodexSessions(options = {}) {
87017
87045
  const { thread, cwd, decision } = candidate;
87018
87046
  let writer;
87019
87047
  try {
87020
- const rewrite = thread.spoolPath !== void 0 && !mergedSpoolIsFresh(thread.spoolPath, thread.mtimeMs);
87021
- if (thread.spoolPath !== void 0 && rewrite) writer = new MergedSpoolWriter(thread.spoolPath);
87048
+ const rewrite = thread.mergedTranscriptPath !== void 0 && !mergedTranscriptIsFresh(thread.mergedTranscriptPath, thread.mtimeMs);
87049
+ if (thread.mergedTranscriptPath !== void 0 && rewrite) writer = new MergedTranscriptWriter(thread.mergedTranscriptPath);
87022
87050
  const pages = [];
87023
87051
  const usage = createCodexUsageReader();
87024
87052
  let vanished = false;
@@ -87039,11 +87067,11 @@ async function collectCodexSessions(options = {}) {
87039
87067
  continue;
87040
87068
  }
87041
87069
  const summary = foldRolloutPages(pages, usage.finish());
87042
- let transcriptPath = thread.files[0].rolloutPath;
87043
- if (thread.spoolPath !== void 0) {
87044
- const mergedBytes = writer ? writer.finish(thread.mtimeMs) : statIfExists(thread.spoolPath)?.size ?? 0;
87070
+ let transcriptUploadSourcePath = thread.files[0].rolloutPath;
87071
+ if (thread.mergedTranscriptPath !== void 0) {
87072
+ const mergedBytes = writer ? writer.finish(thread.mtimeMs) : statIfExists(thread.mergedTranscriptPath)?.size ?? 0;
87045
87073
  writer = void 0;
87046
- transcriptPath = thread.spoolPath;
87074
+ transcriptUploadSourcePath = thread.mergedTranscriptPath;
87047
87075
  mergedThreads += 1;
87048
87076
  largestMergedBytes = Math.max(largestMergedBytes, mergedBytes);
87049
87077
  }
@@ -87052,13 +87080,14 @@ async function collectCodexSessions(options = {}) {
87052
87080
  const title = summary.sessionId ? threadNames.get(summary.sessionId) : void 0;
87053
87081
  items.push({
87054
87082
  mtimeMs: thread.mtimeMs,
87055
- transcriptPath,
87083
+ transcriptPath: transcriptUploadSourcePath,
87056
87084
  ...cwd && { cwd },
87057
87085
  item: {
87058
87086
  source: "codex",
87059
87087
  externalId: thread.externalId,
87060
87088
  status: now - thread.mtimeMs < ACTIVE_GRACE_MS ? "active" : "inactive",
87061
87089
  archived: thread.archived,
87090
+ ...summary.standaloneReview && { automation: true },
87062
87091
  ...summary.startedAt && { startedAt: summary.startedAt },
87063
87092
  ...summary.endedAt && { endedAt: summary.endedAt },
87064
87093
  ...summary.model && { model: summary.model },
@@ -87162,21 +87191,21 @@ function createOmissionRecorder() {
87162
87191
  const count3 = (reason, by = 1) => {
87163
87192
  if (by > 0) counts[reason] = (counts[reason] ?? 0) + by;
87164
87193
  };
87165
- const shape = (reason, path32, valueType, formatVersion, by = 1) => {
87194
+ const shape = (reason, path33, valueType, formatVersion, by = 1) => {
87166
87195
  if (!REPORTED_REASONS.has(reason)) return;
87167
- const key = `${path32}\0${reason}\0${valueType}\0${formatVersion ?? ""}`;
87196
+ const key = `${path33}\0${reason}\0${valueType}\0${formatVersion ?? ""}`;
87168
87197
  const group = groups.get(key);
87169
87198
  if (group) group.count += by;
87170
87199
  else if (groups.size < MAX_STRUCTURE_DIAGNOSTICS) {
87171
- groups.set(key, { path: path32, reason, valueType, count: by, ...formatVersion !== void 0 && { formatVersion } });
87200
+ groups.set(key, { path: path33, reason, valueType, count: by, ...formatVersion !== void 0 && { formatVersion } });
87172
87201
  }
87173
87202
  };
87174
87203
  return {
87175
87204
  count: count3,
87176
87205
  shape,
87177
- note(reason, path32, valueType, formatVersion) {
87206
+ note(reason, path33, valueType, formatVersion) {
87178
87207
  count3(reason);
87179
- shape(reason, path32, valueType, formatVersion);
87208
+ shape(reason, path33, valueType, formatVersion);
87180
87209
  },
87181
87210
  absorb(other) {
87182
87211
  for (const [reason, by] of Object.entries(other.omissions())) {
@@ -87219,7 +87248,7 @@ function defaultCursorUserDir(home) {
87219
87248
  function cursorGlobalStorageDir(home) {
87220
87249
  return path6.join(defaultCursorUserDir(home), "globalStorage");
87221
87250
  }
87222
- function cursorSpoolDir(home) {
87251
+ function cursorExtractedTranscriptsDir(home) {
87223
87252
  return path6.join(home, ".config", "powerplant", "cursor");
87224
87253
  }
87225
87254
  var emptyResult = () => ({
@@ -87275,7 +87304,7 @@ var cachedMetaSchema = external_exports.object({
87275
87304
  model: external_exports.string().optional(),
87276
87305
  ...cursorTranscriptMetaDisclosureSchema.shape
87277
87306
  });
87278
- function spoolFileName(composerId) {
87307
+ function extractedTranscriptFileName(composerId) {
87279
87308
  const sanitized = composerId.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 80);
87280
87309
  const hash2 = createHash2("sha256").update(composerId).digest("hex").slice(0, 8);
87281
87310
  return `${sanitized}-${hash2}.jsonl`;
@@ -87338,7 +87367,7 @@ function toolFilePathOf(args) {
87338
87367
  }
87339
87368
  return void 0;
87340
87369
  }
87341
- var SPOOL_META_RESERVE_BYTES = 64 * 1024;
87370
+ var EXTRACTED_TRANSCRIPT_META_RESERVE_BYTES = 64 * 1024;
87342
87371
  var BUBBLE_FIELDS_SHARED = ["_v", "type", "bubbleId", "serverBubbleId", "text", "createdAt"];
87343
87372
  var USER_BUBBLE_FIELDS = /* @__PURE__ */ new Set([...BUBBLE_FIELDS_SHARED, "context"]);
87344
87373
  var ASSISTANT_BUBBLE_FIELDS = /* @__PURE__ */ new Set([
@@ -87416,8 +87445,8 @@ var MODEL_INFO_FIELDS_INTERPRETED = /* @__PURE__ */ new Set(["modelName"]);
87416
87445
  function collectUnfamiliar(record2, interpreted, excluded, prefix, into, recorder, formatVersion) {
87417
87446
  for (const [key, value] of Object.entries(record2)) {
87418
87447
  if (interpreted.has(key) || excluded.has(key)) continue;
87419
- const path32 = prefix === "" ? key : `${prefix}.${key}`;
87420
- into.set(path32, value);
87448
+ const path33 = prefix === "" ? key : `${prefix}.${key}`;
87449
+ into.set(path33, value);
87421
87450
  recorder.shape("unsupported", `bubble.${prefix === "" ? "" : `${prefix}.`}${nativeTypeLabel(key) ?? "other"}`, jsonValueType(value), formatVersion);
87422
87451
  }
87423
87452
  }
@@ -87503,8 +87532,8 @@ function bubbleLines(bubble, at, recorder) {
87503
87532
  const formatVersion = typeof bubble._v === "number" || typeof bubble._v === "string" ? String(bubble._v) : void 0;
87504
87533
  if (bubble.type !== 1 && bubble.type !== 2) {
87505
87534
  const nativeType = nativeTypeLabel(String(bubble.type));
87506
- const path32 = `bubble.type=${nativeType ?? "other"}`;
87507
- recorder.note("unsupported", path32, jsonValueType(bubble.type), formatVersion);
87535
+ const path33 = `bubble.type=${nativeType ?? "other"}`;
87536
+ recorder.note("unsupported", path33, jsonValueType(bubble.type), formatVersion);
87508
87537
  const retained = Object.fromEntries(Object.entries(bubble).filter(([key]) => !BUBBLE_FIELDS_EXCLUDED.has(key)));
87509
87538
  const bounded = boundUnfamiliarPayload(retained);
87510
87539
  if (bounded.payload === void 0) recorder.count("truncated");
@@ -87582,7 +87611,7 @@ function extractTranscript(db, composerId, maxBytes) {
87582
87611
  const spine = Array.isArray(data?.fullConversationHeadersOnly) ? data.fullConversationHeadersOnly : [];
87583
87612
  if (spine.length === 0) return null;
87584
87613
  const recorder = createOmissionRecorder();
87585
- const budget = maxBytes - SPOOL_META_RESERVE_BYTES;
87614
+ const budget = maxBytes - EXTRACTED_TRANSCRIPT_META_RESERVE_BYTES;
87586
87615
  const serialized = [];
87587
87616
  const modelCounts = /* @__PURE__ */ new Map();
87588
87617
  let bytes = 0;
@@ -87663,7 +87692,7 @@ async function collectCursorSessions(options = {}) {
87663
87692
  collectCursorTranscriptFiles(options, (id) => {
87664
87693
  if (knownIds.has(id)) return true;
87665
87694
  return db?.prepare("select composerId from composerHeaders where composerId = ?").get(id) != null;
87666
- }, result, options.spoolDir ?? cursorSpoolDir(options.homeDir ?? os7.homedir()), spoolFileName);
87695
+ }, result, options.extractedTranscriptsDir ?? cursorExtractedTranscriptsDir(options.homeDir ?? os7.homedir()), extractedTranscriptFileName);
87667
87696
  }
87668
87697
  } finally {
87669
87698
  try {
@@ -87677,9 +87706,9 @@ async function collectCursorSessions(options = {}) {
87677
87706
  function collectFromStore(db, userDir, options, result, knownIds) {
87678
87707
  const now = options.now ?? Date.now();
87679
87708
  const capture = options.capture ?? captureEverythingUnresolved;
87680
- const spoolDir = options.spoolDir ?? cursorSpoolDir(options.homeDir ?? os7.homedir());
87709
+ const extractedTranscriptsDir = options.extractedTranscriptsDir ?? cursorExtractedTranscriptsDir(options.homeDir ?? os7.homedir());
87681
87710
  const maxBytes = options.maxTranscriptBytes ?? MAX_TRANSCRIPT_FILE_BYTES;
87682
- let spoolDirReady = false;
87711
+ let extractedTranscriptsDirReady = false;
87683
87712
  const columns = new Set(
87684
87713
  db.prepare("pragma table_info(composerHeaders)").all().map((row) => isRecord2(row) ? row.name : void 0)
87685
87714
  );
@@ -87729,15 +87758,15 @@ function collectFromStore(db, userDir, options, result, knownIds) {
87729
87758
  });
87730
87759
  continue;
87731
87760
  }
87732
- const spoolPath = path6.join(spoolDir, spoolFileName(raw.composerId));
87733
- const spoolStat = statIfExists(spoolPath);
87761
+ const transcriptUploadSourcePath = path6.join(extractedTranscriptsDir, extractedTranscriptFileName(raw.composerId));
87762
+ const extractedTranscriptStat = statIfExists(transcriptUploadSourcePath);
87734
87763
  let model;
87735
- const sourceUnchanged = spoolStat !== null && Math.abs(spoolStat.mtimeMs - lastUpdatedAt) < 1;
87736
- if (sourceUnchanged && spoolStat.size > maxBytes) {
87764
+ const sourceUnchanged = extractedTranscriptStat !== null && Math.abs(extractedTranscriptStat.mtimeMs - lastUpdatedAt) < 1;
87765
+ if (sourceUnchanged && extractedTranscriptStat.size > maxBytes) {
87737
87766
  result.skippedTooLarge += 1;
87738
87767
  continue;
87739
87768
  }
87740
- const cached3 = sourceUnchanged ? readFirstRecord(spoolPath, () => true) : null;
87769
+ const cached3 = sourceUnchanged ? readFirstRecord(transcriptUploadSourcePath, () => true) : null;
87741
87770
  const cachedMeta = cachedMetaSchema.safeParse(cached3);
87742
87771
  const preparationCurrent = cachedMeta.success && cachedMeta.data.composerId === raw.composerId;
87743
87772
  let omissions;
@@ -87770,15 +87799,15 @@ function collectFromStore(db, userDir, options, result, knownIds) {
87770
87799
  ...counted && { omissions: transcript.omissions },
87771
87800
  ...unhandled.length > 0 && { unhandled }
87772
87801
  };
87773
- if (!spoolDirReady) {
87774
- mkdirSync3(spoolDir, { recursive: true, mode: 448 });
87775
- chmodSync2(spoolDir, 448);
87776
- spoolDirReady = true;
87802
+ if (!extractedTranscriptsDirReady) {
87803
+ mkdirSync3(extractedTranscriptsDir, { recursive: true, mode: 448 });
87804
+ chmodSync2(extractedTranscriptsDir, 448);
87805
+ extractedTranscriptsDirReady = true;
87777
87806
  }
87778
87807
  const body = [JSON.stringify(meta3), ...transcript.serialized, ""].join("\n");
87779
- if (spoolStat !== null) chmodSync2(spoolPath, 384);
87780
- writeFileSync2(spoolPath, body, { encoding: "utf8", mode: 384 });
87781
- utimesSync2(spoolPath, new Date(lastUpdatedAt), new Date(lastUpdatedAt));
87808
+ if (extractedTranscriptStat !== null) chmodSync2(transcriptUploadSourcePath, 384);
87809
+ writeFileSync2(transcriptUploadSourcePath, body, { encoding: "utf8", mode: 384 });
87810
+ utimesSync2(transcriptUploadSourcePath, new Date(lastUpdatedAt), new Date(lastUpdatedAt));
87782
87811
  }
87783
87812
  if (hasCaptureGaps(omissions)) result.partiallyInterpreted += 1;
87784
87813
  for (const observation of unhandledObservations(unhandled, raw.composerId)) {
@@ -87797,7 +87826,7 @@ function collectFromStore(db, userDir, options, result, knownIds) {
87797
87826
  const startBranch = facts.branches[0];
87798
87827
  result.sessions.push({
87799
87828
  mtimeMs: lastUpdatedAt,
87800
- transcriptPath: spoolPath,
87829
+ transcriptPath: transcriptUploadSourcePath,
87801
87830
  ...cwd && { cwd },
87802
87831
  item: {
87803
87832
  source: "cursor",
@@ -87855,12 +87884,12 @@ var CONTENT_LINE_TYPES2 = /* @__PURE__ */ new Set([
87855
87884
  function parseCursorTranscriptFile(text) {
87856
87885
  const lines = [];
87857
87886
  const recorder = createOmissionRecorder();
87858
- const retainUnsupported = (record2, at, path32, discriminator) => {
87887
+ const retainUnsupported = (record2, at, path33, discriminator) => {
87859
87888
  const nativeType = nativeTypeLabel(discriminator);
87860
87889
  const bounded = boundUnfamiliarPayload(record2);
87861
87890
  lines.push({ type: "unsupported", ...nativeType !== void 0 && { nativeType }, ...at, ...bounded });
87862
- recorder.note("unsupported", `${path32}=${nativeType ?? "other"}`, jsonValueType(discriminator));
87863
- if (bounded.payload === void 0) recorder.note("truncated", `${path32}=${nativeType ?? "other"}`, "object");
87891
+ recorder.note("unsupported", `${path33}=${nativeType ?? "other"}`, jsonValueType(discriminator));
87892
+ if (bounded.payload === void 0) recorder.note("truncated", `${path33}=${nativeType ?? "other"}`, "object");
87864
87893
  };
87865
87894
  text.split("\n").forEach((row, recordIndex) => {
87866
87895
  if (!row.trim()) return;
@@ -87882,8 +87911,8 @@ function parseCursorTranscriptFile(text) {
87882
87911
  }
87883
87912
  const record2 = message.safeParse(value);
87884
87913
  if (!record2.success) {
87885
- const [path32, discriminator] = typeof value.type === "string" ? ["record.type", value.type] : typeof value.role === "string" ? ["message.role", value.role] : ["record", void 0];
87886
- retainUnsupported(value, { recordIndex }, path32, discriminator);
87914
+ const [path33, discriminator] = typeof value.type === "string" ? ["record.type", value.type] : typeof value.role === "string" ? ["message.role", value.role] : ["record", void 0];
87915
+ retainUnsupported(value, { recordIndex }, path33, discriminator);
87887
87916
  return;
87888
87917
  }
87889
87918
  const role = record2.data.role;
@@ -87931,7 +87960,7 @@ function parseCursorTranscriptFile(text) {
87931
87960
  if (!lines.some((line) => CONTENT_LINE_TYPES2.has(line.type))) return null;
87932
87961
  return { lines, omissions: recorder.omissions(), unhandled: recorder.unhandled() };
87933
87962
  }
87934
- function spoolBody(metaFor, lines, maxBytes) {
87963
+ function extractedTranscriptBody(metaFor, lines, maxBytes) {
87935
87964
  for (const keepPayloads of [true, false]) {
87936
87965
  const payloadsDropped = keepPayloads ? 0 : lines.filter((line) => line.type === "unsupported" && line.payload !== void 0).length;
87937
87966
  const records = [
@@ -87950,7 +87979,7 @@ function spoolBody(metaFor, lines, maxBytes) {
87950
87979
  }
87951
87980
  return null;
87952
87981
  }
87953
- var spoolMetaSchema = external_exports.object({
87982
+ var extractedTranscriptMetaSchema = external_exports.object({
87954
87983
  type: external_exports.literal("meta"),
87955
87984
  format: external_exports.literal("cursor-local-transcript"),
87956
87985
  version: external_exports.literal(1),
@@ -87962,7 +87991,7 @@ var spoolMetaSchema = external_exports.object({
87962
87991
  model: external_exports.string().optional(),
87963
87992
  ...cursorTranscriptMetaDisclosureSchema.shape
87964
87993
  });
87965
- var hintSchema2 = external_exports.object({
87994
+ var transcriptDiscoveryRecordSchema2 = external_exports.object({
87966
87995
  sessionId: external_exports.string().regex(/^[a-zA-Z0-9_-]{1,200}$/),
87967
87996
  transcriptPath: external_exports.string().max(4096).nullable(),
87968
87997
  workspaceRoots: external_exports.array(external_exports.string().max(4096)).max(8),
@@ -87994,15 +88023,15 @@ function cursorTranscriptRecordPath(home, sessionId) {
87994
88023
  `${createHash3("sha256").update(sessionId).digest("hex")}.json`
87995
88024
  );
87996
88025
  }
87997
- function collectCursorTranscriptFiles(options, isDatabaseSession, result, databaseSpoolDir, spoolName) {
88026
+ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databaseExtractedTranscriptsDir, extractedTranscriptFileName2) {
87998
88027
  const home = options.homeDir ?? os8.homedir();
87999
- const hintsDir = cursorTranscriptRecordsDir(home);
88000
- if (!existsSync3(hintsDir)) return;
88028
+ const recordsDir = cursorTranscriptRecordsDir(home);
88029
+ if (!existsSync3(recordsDir)) return;
88001
88030
  const maxBytes = options.maxTranscriptBytes ?? MAX_TRANSCRIPT_FILE_BYTES;
88002
- const spoolDir = path7.join(databaseSpoolDir, "native");
88031
+ const nativeExtractedTranscriptsDir = path7.join(databaseExtractedTranscriptsDir, "native");
88003
88032
  let files;
88004
88033
  try {
88005
- files = readdirSync3(hintsDir);
88034
+ files = readdirSync3(recordsDir);
88006
88035
  } catch {
88007
88036
  result.skippedUnreadable++;
88008
88037
  return;
@@ -88010,15 +88039,15 @@ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databa
88010
88039
  for (const file2 of files) {
88011
88040
  if (!/^[a-f0-9]{64}\.json$/.test(file2)) continue;
88012
88041
  try {
88013
- const hintPath = path7.join(hintsDir, file2);
88014
- if (!lstatSync2(hintPath).isFile()) continue;
88015
- const text = readBounded(hintPath, 40 * 1024);
88016
- const hint = hintSchema2.parse(text === null ? null : JSON.parse(text));
88017
- if (file2 !== `${createHash3("sha256").update(hint.sessionId).digest("hex")}.json`) continue;
88018
- if (isDatabaseSession(hint.sessionId) || existsSync3(path7.join(databaseSpoolDir, spoolName(hint.sessionId))))
88042
+ const recordPath = path7.join(recordsDir, file2);
88043
+ if (!lstatSync2(recordPath).isFile()) continue;
88044
+ const text = readBounded(recordPath, 40 * 1024);
88045
+ const record2 = transcriptDiscoveryRecordSchema2.parse(text === null ? null : JSON.parse(text));
88046
+ if (file2 !== `${createHash3("sha256").update(record2.sessionId).digest("hex")}.json`) continue;
88047
+ if (isDatabaseSession(record2.sessionId) || existsSync3(path7.join(databaseExtractedTranscriptsDir, extractedTranscriptFileName2(record2.sessionId))))
88019
88048
  continue;
88020
- if (hint.transcriptPath === null || hint.workspaceRoots.length !== 1) continue;
88021
- const cwd = hint.workspaceRoots[0];
88049
+ if (record2.transcriptPath === null || record2.workspaceRoots.length !== 1) continue;
88050
+ const cwd = record2.workspaceRoots[0];
88022
88051
  if (!path7.isAbsolute(cwd)) continue;
88023
88052
  const decision = captureDecision(cwd, options.capture ?? captureEverythingUnresolved);
88024
88053
  if (!decision.capture) {
@@ -88028,14 +88057,14 @@ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databa
88028
88057
  const projects = path7.join(home, ".cursor", "projects");
88029
88058
  const project = cwd.replace(/[^a-zA-Z0-9]/g, "-").replace(/^-+/, "");
88030
88059
  const base = path7.join(projects, project, "agent-transcripts");
88031
- const basename2 = `${hint.sessionId}.jsonl`;
88032
- const allowed = [path7.join(base, basename2), path7.join(base, hint.sessionId, basename2)];
88033
- if (!allowed.includes(hint.transcriptPath)) {
88060
+ const basename2 = `${record2.sessionId}.jsonl`;
88061
+ const allowed = [path7.join(base, basename2), path7.join(base, record2.sessionId, basename2)];
88062
+ if (!allowed.includes(record2.transcriptPath)) {
88034
88063
  result.skippedUnreadable++;
88035
88064
  continue;
88036
88065
  }
88037
- const stat = lstatSync2(hint.transcriptPath);
88038
- if (!stat.isFile() || realpathSync2(hint.transcriptPath) !== path7.join(realpathSync2(projects), path7.relative(projects, hint.transcriptPath))) {
88066
+ const stat = lstatSync2(record2.transcriptPath);
88067
+ if (!stat.isFile() || realpathSync2(record2.transcriptPath) !== path7.join(realpathSync2(projects), path7.relative(projects, record2.transcriptPath))) {
88039
88068
  result.skippedUnreadable++;
88040
88069
  continue;
88041
88070
  }
@@ -88046,7 +88075,7 @@ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databa
88046
88075
  }
88047
88076
  const common = {
88048
88077
  source: "cursor",
88049
- externalId: hint.sessionId,
88078
+ externalId: record2.sessionId,
88050
88079
  status: (options.now ?? Date.now()) - stat.mtimeMs < ACTIVE_GRACE_MS ? "active" : "inactive",
88051
88080
  ...decision.repoFullName && { repoFullName: decision.repoFullName },
88052
88081
  capturedVia: decision.via
@@ -88055,15 +88084,15 @@ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databa
88055
88084
  result.sessions.push({
88056
88085
  cwd,
88057
88086
  mtimeMs: stat.mtimeMs,
88058
- transcriptPath: hint.transcriptPath,
88087
+ transcriptPath: record2.transcriptPath,
88059
88088
  item: common
88060
88089
  });
88061
88090
  continue;
88062
88091
  }
88063
- const spool = path7.join(spoolDir, spoolName(hint.sessionId));
88064
- const spoolStat = statIfExists(spool);
88065
- const cached3 = spoolStat !== null && spoolStat.size <= maxBytes && Math.abs(spoolStat.mtimeMs - stat.mtimeMs) < 1 ? spoolMetaSchema.safeParse(readFirstRecord(spool, () => true)) : null;
88066
- const fresh = cached3?.success && cached3.data.composerId === hint.sessionId && cached3.data.workspacePath === cwd && cached3.data.nativeSourceSize === stat.size && cached3.data.model === hint.model;
88092
+ const transcriptUploadSourcePath = path7.join(nativeExtractedTranscriptsDir, extractedTranscriptFileName2(record2.sessionId));
88093
+ const extractedTranscriptStat = statIfExists(transcriptUploadSourcePath);
88094
+ const cached3 = extractedTranscriptStat !== null && extractedTranscriptStat.size <= maxBytes && Math.abs(extractedTranscriptStat.mtimeMs - stat.mtimeMs) < 1 ? extractedTranscriptMetaSchema.safeParse(readFirstRecord(transcriptUploadSourcePath, () => true)) : null;
88095
+ const fresh = cached3?.success && cached3.data.composerId === record2.sessionId && cached3.data.workspacePath === cwd && cached3.data.nativeSourceSize === stat.size && cached3.data.model === record2.model;
88067
88096
  let title;
88068
88097
  let omissions;
88069
88098
  let unhandled = [];
@@ -88072,7 +88101,7 @@ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databa
88072
88101
  omissions = cached3.data.omissions;
88073
88102
  unhandled = cached3.data.unhandled ?? [];
88074
88103
  } else {
88075
- const raw = readBounded(hint.transcriptPath, maxBytes);
88104
+ const raw = readBounded(record2.transcriptPath, maxBytes);
88076
88105
  if (raw === null) {
88077
88106
  result.skippedTooLarge++;
88078
88107
  continue;
@@ -88093,40 +88122,40 @@ function collectCursorTranscriptFiles(options, isDatabaseSession, result, databa
88093
88122
  format: "cursor-local-transcript",
88094
88123
  version: 1,
88095
88124
  preparationVersion: CURSOR_TRANSCRIPT_PREPARATION_VERSION,
88096
- composerId: hint.sessionId,
88125
+ composerId: record2.sessionId,
88097
88126
  workspacePath: cwd,
88098
88127
  nativeSourceSize: stat.size,
88099
88128
  ...title !== void 0 && { name: title },
88100
- ...hint.model && { model: hint.model },
88129
+ ...record2.model && { model: record2.model },
88101
88130
  ...Object.keys(written).length > 0 && { omissions: written },
88102
88131
  ...prepared.unhandled.length > 0 && { unhandled: prepared.unhandled }
88103
88132
  };
88104
88133
  };
88105
- const body = spoolBody(metaFor, prepared.lines, maxBytes);
88134
+ const body = extractedTranscriptBody(metaFor, prepared.lines, maxBytes);
88106
88135
  if (body === null) {
88107
88136
  result.skippedTooLarge++;
88108
88137
  continue;
88109
88138
  }
88110
- mkdirSync4(spoolDir, { recursive: true, mode: 448 });
88111
- if (spoolStat !== null) chmodSync3(spool, 384);
88112
- writeFileSync3(spool, body, { mode: 384 });
88113
- utimesSync3(spool, stat.atime, stat.mtime);
88139
+ mkdirSync4(nativeExtractedTranscriptsDir, { recursive: true, mode: 448 });
88140
+ if (extractedTranscriptStat !== null) chmodSync3(transcriptUploadSourcePath, 384);
88141
+ writeFileSync3(transcriptUploadSourcePath, body, { mode: 384 });
88142
+ utimesSync3(transcriptUploadSourcePath, stat.atime, stat.mtime);
88114
88143
  omissions = Object.keys(written).length > 0 ? written : void 0;
88115
88144
  unhandled = prepared.unhandled;
88116
88145
  }
88117
88146
  if (hasCaptureGaps(omissions)) result.partiallyInterpreted++;
88118
- for (const observation of unhandledObservations(unhandled, hint.sessionId)) {
88147
+ for (const observation of unhandledObservations(unhandled, record2.sessionId)) {
88119
88148
  observeStructure(options.onStructureDiagnostic, observation);
88120
88149
  }
88121
88150
  result.sessions.push({
88122
88151
  cwd,
88123
88152
  mtimeMs: stat.mtimeMs,
88124
- transcriptPath: spool,
88153
+ transcriptPath: transcriptUploadSourcePath,
88125
88154
  item: {
88126
88155
  ...common,
88127
88156
  endedAt: stat.mtime.toISOString(),
88128
88157
  repoDir: path7.basename(cwd),
88129
- ...hint.model && { model: hint.model },
88158
+ ...record2.model && { model: record2.model },
88130
88159
  ...title !== void 0 && { title }
88131
88160
  }
88132
88161
  });
@@ -88290,7 +88319,7 @@ function observedSessionEnd(entry, mtimeMs) {
88290
88319
  return entry.at;
88291
88320
  }
88292
88321
 
88293
- // ../../apps/collector/src/providerHooks.ts
88322
+ // ../../apps/collector/src/harnessHooks.ts
88294
88323
  import {
88295
88324
  existsSync as existsSync5,
88296
88325
  lstatSync as lstatSync3,
@@ -88306,26 +88335,39 @@ var SESSION_CHANGE_HOOK = "powerplant-session-change.mjs";
88306
88335
  var CODEX_TRANSCRIPT_HOOK = "powerplant-codex-transcript.mjs";
88307
88336
  var CURSOR_TRANSCRIPT_HOOK = "powerplant-cursor-transcript.mjs";
88308
88337
  var SESSION_CHANGE_FILENAME = "session-change";
88338
+ var SUPPORTED_HOOK_HARNESSES = ["codex-local", "cursor-local"];
88309
88339
  var jsonObject = external_exports.record(external_exports.string(), external_exports.json());
88310
- function providerEvents(provider) {
88311
- return provider === "cursor" ? ["sessionStart", "sessionEnd", "stop"] : ["SessionStart", "SessionEnd", "Stop"];
88340
+ function nativeHarnessName(harness) {
88341
+ switch (harness) {
88342
+ case "codex-local":
88343
+ return "codex";
88344
+ case "cursor-local":
88345
+ return "cursor";
88346
+ default:
88347
+ throw new Error(`unsupported hook harness: ${String(harness)}`);
88348
+ }
88349
+ }
88350
+ function harnessEvents(harness) {
88351
+ return nativeHarnessName(harness) === "cursor" ? ["sessionStart", "sessionEnd", "stop"] : ["SessionStart", "SessionEnd", "Stop"];
88312
88352
  }
88313
- function providerConfigPath(provider, home) {
88314
- return path10.join(home, `.${provider}`, "hooks.json");
88353
+ function harnessHookConfigPath(harness, home) {
88354
+ const nativeName = nativeHarnessName(harness);
88355
+ return path10.join(home, `.${nativeName}`, "hooks.json");
88315
88356
  }
88316
88357
  var UNUSABLE_CONFIG = "hooks.json contains invalid JSON or an unsupported hook structure";
88317
88358
  var NON_REGULAR_CONFIG = "hooks.json is not a regular file; configure the hook manually";
88318
- function providerHookCommands(provider, text) {
88359
+ function harnessHookCommands(harness, text) {
88319
88360
  try {
88361
+ const nativeName = nativeHarnessName(harness);
88320
88362
  const settings = jsonObject.parse(text === null ? {} : JSON.parse(text));
88321
- if (provider === "cursor" && settings.version !== void 0 && settings.version !== 1) {
88363
+ if (nativeName === "cursor" && settings.version !== void 0 && settings.version !== 1) {
88322
88364
  return { kind: "unusable", reason: "Unsupported Cursor hooks version" };
88323
88365
  }
88324
88366
  const hooks = jsonObject.parse(settings.hooks === void 0 ? {} : settings.hooks);
88325
88367
  const commands = [];
88326
- for (const event of providerEvents(provider)) {
88368
+ for (const event of harnessEvents(harness)) {
88327
88369
  const entries = external_exports.array(jsonObject).parse(hooks[event] === void 0 ? [] : hooks[event]);
88328
- const handlers2 = provider === "cursor" ? entries : entries.flatMap((entry) => external_exports.array(jsonObject).parse(entry.hooks));
88370
+ const handlers2 = nativeName === "cursor" ? entries : entries.flatMap((entry) => external_exports.array(jsonObject).parse(entry.hooks));
88329
88371
  const ours = handlers2.filter(isOurHook);
88330
88372
  if (ours.length === 0) return { kind: "missing" };
88331
88373
  for (const hook of ours) {
@@ -88341,20 +88383,21 @@ function isOurHook(hook) {
88341
88383
  const command = hook.command;
88342
88384
  return typeof command === "string" && [SESSION_CHANGE_HOOK, CODEX_TRANSCRIPT_HOOK, CURSOR_TRANSCRIPT_HOOK].some((script) => command.endsWith(`/${script}'`) || command.endsWith(`/${script}"`));
88343
88385
  }
88344
- function mergeProviderHooks(provider, text, command) {
88386
+ function mergeHarnessHooks(harness, text, command) {
88345
88387
  try {
88388
+ const nativeName = nativeHarnessName(harness);
88346
88389
  const settings = jsonObject.parse(text === null ? {} : JSON.parse(text));
88347
- if (provider === "cursor" && settings.version !== void 0 && settings.version !== 1) {
88390
+ if (nativeName === "cursor" && settings.version !== void 0 && settings.version !== 1) {
88348
88391
  return { action: "skip", reason: "Unsupported Cursor hooks version" };
88349
88392
  }
88350
88393
  const hooks = jsonObject.parse(settings.hooks === void 0 ? {} : settings.hooks);
88351
- for (const event of providerEvents(provider)) {
88394
+ for (const event of harnessEvents(harness)) {
88352
88395
  const entries = external_exports.array(jsonObject).parse(hooks[event] === void 0 ? [] : hooks[event]);
88353
- const handler = provider === "cursor" ? { command, timeout: 2 } : { type: "command", command, timeout: 2 };
88354
- const ours = provider === "cursor" ? handler : { hooks: [handler] };
88396
+ const handler = nativeName === "cursor" ? { command, timeout: 2 } : { type: "command", command, timeout: 2 };
88397
+ const ours = nativeName === "cursor" ? handler : { hooks: [handler] };
88355
88398
  const kept = [];
88356
88399
  for (const entry of entries) {
88357
- if (provider === "cursor") {
88400
+ if (nativeName === "cursor") {
88358
88401
  if (!isOurHook(entry)) kept.push(entry);
88359
88402
  continue;
88360
88403
  }
@@ -88365,7 +88408,7 @@ function mergeProviderHooks(provider, text, command) {
88365
88408
  }
88366
88409
  hooks[event] = [...kept, ours];
88367
88410
  }
88368
- const next = { ...settings, ...provider === "cursor" ? { version: 1 } : {}, hooks };
88411
+ const next = { ...settings, ...nativeName === "cursor" ? { version: 1 } : {}, hooks };
88369
88412
  if (JSON.stringify(next) === JSON.stringify(settings)) return { action: "unchanged" };
88370
88413
  return { action: "write", text: `${JSON.stringify(next, null, 2)}
88371
88414
  ` };
@@ -88376,42 +88419,47 @@ function mergeProviderHooks(provider, text, command) {
88376
88419
  function shellQuote2(value) {
88377
88420
  return `'${value.replaceAll("'", "'\\''")}'`;
88378
88421
  }
88379
- function installProviderHook(provider, home) {
88380
- const configDir = path10.join(home, `.${provider}`);
88381
- if (!existsSync5(configDir)) return { provider, settings: "absent" };
88382
- const configPath = providerConfigPath(provider, home);
88422
+ function installHarnessHook(harness, home) {
88423
+ const nativeName = nativeHarnessName(harness);
88424
+ const configDir = path10.join(home, `.${nativeName}`);
88425
+ if (!existsSync5(configDir)) return { provider: nativeName, settings: "absent" };
88426
+ const configPath = harnessHookConfigPath(harness, home);
88383
88427
  let original = null;
88384
88428
  let mode = 384;
88385
88429
  try {
88386
88430
  const stat = lstatSync3(configPath);
88387
- if (!stat.isFile()) return { provider, settings: "skip", detail: NON_REGULAR_CONFIG };
88431
+ if (!stat.isFile()) {
88432
+ return { provider: nativeName, settings: "skip", detail: NON_REGULAR_CONFIG };
88433
+ }
88388
88434
  mode = stat.mode & 511;
88389
88435
  original = readFileSync6(configPath, "utf8");
88390
88436
  } catch (error63) {
88391
88437
  if (!(error63 instanceof Error && "code" in error63 && error63.code === "ENOENT")) throw error63;
88392
88438
  }
88393
88439
  const hookDir = path10.join(home, ".config", "powerplant", "hooks");
88394
- const script = provider === "cursor" ? CURSOR_TRANSCRIPT_HOOK : CODEX_TRANSCRIPT_HOOK;
88440
+ const script = nativeName === "cursor" ? CURSOR_TRANSCRIPT_HOOK : CODEX_TRANSCRIPT_HOOK;
88395
88441
  const scriptPath = path10.join(hookDir, script);
88396
- const merged = mergeProviderHooks(
88397
- provider,
88442
+ const merged = mergeHarnessHooks(
88443
+ harness,
88398
88444
  original,
88399
88445
  `${shellQuote2(process.execPath)} ${shellQuote2(scriptPath)}`
88400
88446
  );
88401
- if (merged.action === "skip") return { provider, settings: "skip", detail: merged.reason };
88447
+ if (merged.action === "skip") {
88448
+ return { provider: nativeName, settings: "skip", detail: merged.reason };
88449
+ }
88402
88450
  mkdirSync6(hookDir, { recursive: true });
88403
88451
  writeAtomic(scriptPath, readFileSync6(hookSourcePath(script), "utf8"), 448);
88404
88452
  if (merged.action === "write") {
88405
88453
  const current = existsSync5(configPath) ? readFileSync6(configPath, "utf8") : null;
88406
88454
  if (current !== original)
88407
88455
  return {
88408
- provider,
88456
+ provider: nativeName,
88409
88457
  settings: "skip",
88410
88458
  detail: "hooks.json changed during installation; restart the collector to retry"
88411
88459
  };
88412
88460
  writeAtomic(configPath, merged.text, mode);
88413
88461
  }
88414
- return { provider, settings: merged.action };
88462
+ return { provider: nativeName, settings: merged.action };
88415
88463
  }
88416
88464
  function writeAtomic(file2, text, mode) {
88417
88465
  const temporary = `${file2}.${randomUUID()}.tmp`;
@@ -88422,13 +88470,13 @@ function writeAtomic(file2, text, mode) {
88422
88470
  rmSync4(temporary, { force: true });
88423
88471
  }
88424
88472
  }
88425
- function installProviderHooks(home) {
88426
- return ["codex", "cursor"].map((provider) => {
88473
+ function installHarnessHooks(home) {
88474
+ return SUPPORTED_HOOK_HARNESSES.map((harness) => {
88427
88475
  try {
88428
- return installProviderHook(provider, home);
88476
+ return installHarnessHook(harness, home);
88429
88477
  } catch (error63) {
88430
88478
  return {
88431
- provider,
88479
+ provider: nativeHarnessName(harness),
88432
88480
  settings: "skip",
88433
88481
  detail: error63 instanceof Error ? error63.message : String(error63)
88434
88482
  };
@@ -88440,7 +88488,7 @@ function installProviderHooks(home) {
88440
88488
  var HOOK_OBSERVATION_GRACE_MS = 2 * 6e4;
88441
88489
  var hookHealthSchema = external_exports.object({
88442
88490
  harness: hookHarnessSchema,
88443
- /** What this daemon's boot-time install did (installCollectorHooks / installProviderHooks). */
88491
+ /** What this daemon's boot-time install did (installCollectorHooks / installHarnessHooks). */
88444
88492
  install: hookInstallOutcomeSchema,
88445
88493
  /** unverified: no in-scope session started since the install has been
88446
88494
  * judged yet. firing: one carried a hook record. silent: one had none. */
@@ -88469,7 +88517,10 @@ var HARNESS_NAMES = {
88469
88517
  cursor: "Cursor"
88470
88518
  };
88471
88519
  function configPathOf(harness, home) {
88472
- return harness === "claude" ? claudeSettingsPath(home) : providerConfigPath(harness, home);
88520
+ return harness === "claude" ? claudeSettingsPath(home) : harnessHookConfigPath(localHookHarness(harness), home);
88521
+ }
88522
+ function localHookHarness(harness) {
88523
+ return harness === "codex" ? "codex-local" : "cursor-local";
88473
88524
  }
88474
88525
  function commandPaths(command) {
88475
88526
  const paths = [];
@@ -88504,7 +88555,7 @@ function inspectHookConfig(harness, home) {
88504
88555
  detail: error63 instanceof Error ? error63.message : String(error63)
88505
88556
  };
88506
88557
  }
88507
- const read = harness === "claude" ? collectorHookCommands(text) : providerHookCommands(harness, text);
88558
+ const read = harness === "claude" ? collectorHookCommands(text) : harnessHookCommands(localHookHarness(harness), text);
88508
88559
  if (read.kind === "unusable") return { kind: "config-unusable", configPath, detail: read.reason };
88509
88560
  if (read.kind === "missing") return { kind: "entries-missing", configPath };
88510
88561
  for (const command of read.commands) {
@@ -89406,7 +89457,7 @@ async function uploadPreviewRegistration(apiUrl, machineToken, registration) {
89406
89457
  function encodeRawTranscript(text) {
89407
89458
  return gzipSync(redactJsonl(text));
89408
89459
  }
89409
- async function uploadRawSessions(apiUrl, machineToken, collected, readTranscript = (p) => readFileSync9(p, "utf8"), shipped, progress) {
89460
+ async function uploadRawSessions(apiUrl, machineToken, transcriptUploadSources, readTranscript = (p) => readFileSync9(p, "utf8"), shipped, progress) {
89410
89461
  const summary = {
89411
89462
  uploaded: 0,
89412
89463
  skippedTooLarge: 0,
@@ -89417,18 +89468,19 @@ async function uploadRawSessions(apiUrl, machineToken, collected, readTranscript
89417
89468
  };
89418
89469
  const initiallyShipped = new Map(shipped);
89419
89470
  let rateLimited;
89420
- for (const session of collected) {
89471
+ for (const session of transcriptUploadSources) {
89421
89472
  summary.uploaded += await progress?.beforeUpload?.() ?? 0;
89422
- const acknowledged = shipped?.get(session.transcriptPath);
89423
- if (acknowledged === session.mtimeMs || acknowledged !== void 0 && acknowledged !== initiallyShipped.get(session.transcriptPath)) {
89473
+ const transcriptUploadSourcePath = session.transcriptPath;
89474
+ const acknowledged = shipped?.get(transcriptUploadSourcePath);
89475
+ if (acknowledged === session.mtimeMs || acknowledged !== void 0 && acknowledged !== initiallyShipped.get(transcriptUploadSourcePath)) {
89424
89476
  summary.skippedUnchanged += 1;
89425
89477
  continue;
89426
89478
  }
89427
89479
  try {
89428
- const body = encodeRawTranscript(readTranscript(session.transcriptPath));
89480
+ const body = encodeRawTranscript(readTranscript(transcriptUploadSourcePath));
89429
89481
  if (body.byteLength > MAX_RAW_UPLOAD_BYTES) {
89430
89482
  summary.skippedTooLarge += 1;
89431
- shipped?.set(session.transcriptPath, session.mtimeMs);
89483
+ shipped?.set(transcriptUploadSourcePath, session.mtimeMs);
89432
89484
  continue;
89433
89485
  }
89434
89486
  const query = `source=${session.item.source}&externalId=${encodeURIComponent(session.item.externalId)}`;
@@ -89461,7 +89513,7 @@ async function uploadRawSessions(apiUrl, machineToken, collected, readTranscript
89461
89513
  }
89462
89514
  summary.uploaded += 1;
89463
89515
  progress?.onUploaded?.();
89464
- shipped?.set(session.transcriptPath, session.mtimeMs);
89516
+ shipped?.set(transcriptUploadSourcePath, session.mtimeMs);
89465
89517
  } catch (error63) {
89466
89518
  if (error63 instanceof RateLimitedError) rateLimited ??= error63;
89467
89519
  summary.failed.push(
@@ -91332,7 +91384,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
91332
91384
  );
91333
91385
  reportCollectorError(error63, "watch-hook-install");
91334
91386
  }
91335
- for (const hook of installProviderHooks(home)) {
91387
+ for (const hook of installHarnessHooks(home)) {
91336
91388
  hookInstalls[hook.provider] = hook.settings;
91337
91389
  if (hook.settings === "absent") continue;
91338
91390
  if (hook.settings === "skip") {
@@ -91718,6 +91770,7 @@ async function readLocalSessionFacts(sessions, onError2, home = os17.homedir(),
91718
91770
  if (file2 === null || !existsSync9(file2)) continue;
91719
91771
  const db = await openLocalDatabase(file2);
91720
91772
  try {
91773
+ db.prepare("pragma busy_timeout = 250").get();
91721
91774
  const columns = new Set(
91722
91775
  external_exports.array(external_exports.object({ name: external_exports.string() })).parse(db.prepare(`pragma table_info(${store.table})`).all()).map((column) => column.name)
91723
91776
  );
@@ -91786,7 +91839,90 @@ function localSessionKey(session) {
91786
91839
  return JSON.stringify([session.source, session.externalId]);
91787
91840
  }
91788
91841
 
91842
+ // src/mcpPreferences.ts
91843
+ var preferenceSchema = external_exports.object({
91844
+ optedIn: external_exports.boolean().optional(),
91845
+ dismissedWarning: mcpWarningSchema.optional()
91846
+ });
91847
+ var preferencesSchema = external_exports.object({
91848
+ version: external_exports.literal(1),
91849
+ clients: external_exports.object({
91850
+ claude: preferenceSchema.optional(),
91851
+ codex: preferenceSchema.optional(),
91852
+ cursor: preferenceSchema.optional()
91853
+ })
91854
+ });
91855
+ var emptyMcpPreferences = () => ({ version: 1, clients: {} });
91856
+ function mcpPreferencesPath(appEnv, home) {
91857
+ return path21.join(collectorStateDir(home), `mcp-preferences-${appEnv}.json`);
91858
+ }
91859
+ function readMcpPreferences(appEnv, home) {
91860
+ const file2 = mcpPreferencesPath(appEnv, home);
91861
+ try {
91862
+ return preferencesSchema.parse(JSON.parse(readFileSync11(file2, "utf8")));
91863
+ } catch (error63) {
91864
+ if (error63 instanceof Error && "code" in error63 && error63.code === "ENOENT") return emptyMcpPreferences();
91865
+ throw new ExpectedCliError(`Cannot read MCP preferences at ${file2}. Restore or remove that file, then retry.`, { cause: error63 });
91866
+ }
91867
+ }
91868
+ function writeMcpPreferences(appEnv, preferences, home) {
91869
+ const file2 = mcpPreferencesPath(appEnv, home);
91870
+ mkdirSync10(path21.dirname(file2), { recursive: true });
91871
+ const temporary = `${file2}.${process.pid}.tmp`;
91872
+ writeFileSync9(temporary, JSON.stringify(preferencesSchema.parse(preferences), null, 2), { mode: 384 });
91873
+ renameSync5(temporary, file2);
91874
+ }
91875
+ function recordMcpChoices(appEnv, offered, selected, home) {
91876
+ const preferences = readMcpPreferences(appEnv, home);
91877
+ for (const client of offered) {
91878
+ preferences.clients[client] = { optedIn: selected.includes(client) };
91879
+ }
91880
+ writeMcpPreferences(appEnv, preferences, home);
91881
+ }
91882
+ function recordMcpConnectChoices(appEnv, detected, requested, home) {
91883
+ const chosen = requested === void 0 ? detected : detected.filter((client) => requested.has(client));
91884
+ recordMcpChoices(appEnv, chosen, chosen, home);
91885
+ }
91886
+ function readMcpPreferencesForMenu(appEnv, home) {
91887
+ try {
91888
+ return { mcpPreferences: readMcpPreferences(appEnv, home) };
91889
+ } catch (error63) {
91890
+ if (!(error63 instanceof ExpectedCliError)) throw error63;
91891
+ return { mcpPreferencesError: error63.message };
91892
+ }
91893
+ }
91894
+ function dismissMcpWarning(appEnv, event, home) {
91895
+ const preferences = readMcpPreferences(appEnv, home);
91896
+ const previous = preferences.clients[event.client];
91897
+ if (previous?.dismissedWarning === event.warning) return false;
91898
+ preferences.clients[event.client] = { ...previous, dismissedWarning: event.warning };
91899
+ writeMcpPreferences(appEnv, preferences, home);
91900
+ return true;
91901
+ }
91902
+
91903
+ // src/menubarAnalytics.ts
91904
+ import { randomUUID as randomUUID3 } from "node:crypto";
91905
+ async function reportMenubarEvent(event, credentials, warn2, fetchImpl = fetch) {
91906
+ if (credentials === null) return false;
91907
+ const runId = randomUUID3();
91908
+ let status;
91909
+ try {
91910
+ const response = await fetchImpl(`${credentials.apiUrl}/api/collector/menubar-events`, {
91911
+ method: "POST",
91912
+ headers: { authorization: `Bearer ${credentials.token}`, "content-type": "application/json", ...cliVersionHeaders() },
91913
+ body: JSON.stringify(event),
91914
+ signal: AbortSignal.timeout(3e3)
91915
+ });
91916
+ if (response.ok) return true;
91917
+ status = response.status;
91918
+ } catch {
91919
+ }
91920
+ warn2(JSON.stringify({ level: "warn", runId, operation: "menubar-analytics", outcome: status === void 0 ? "unavailable" : "refused", ...status === void 0 ? {} : { status } }));
91921
+ return false;
91922
+ }
91923
+
91789
91924
  // src/clientFailure.ts
91925
+ import { constants } from "node:os";
91790
91926
  function clientFailure(error63) {
91791
91927
  if (error63 instanceof ExpectedCliError) {
91792
91928
  return { outcome: "failed", domain: "Powerplant", code: "EXPECTED_CLI_OUTCOME" };
@@ -91804,14 +91940,14 @@ function nativeFailureRecord(error63) {
91804
91940
 
91805
91941
  // src/desktopDiagnostics.ts
91806
91942
  import os19 from "node:os";
91807
- import path22 from "node:path";
91943
+ import path23 from "node:path";
91808
91944
 
91809
91945
  // src/memberSessions.ts
91810
91946
  import { execFileSync as execFileSync4 } from "node:child_process";
91811
91947
  import { existsSync as existsSync10 } from "node:fs";
91812
91948
  import { open as open2, readdir as readdir2 } from "node:fs/promises";
91813
91949
  import os18 from "node:os";
91814
- import path21 from "node:path";
91950
+ import path22 from "node:path";
91815
91951
  var memberSessionSchema = external_exports.object({
91816
91952
  id: external_exports.string().min(1),
91817
91953
  source: external_exports.string().min(1),
@@ -91928,10 +92064,10 @@ function detectClaudeDesktop(probe) {
91928
92064
  return detectDesktopScheme(["Claude.app"], "claude", probe);
91929
92065
  }
91930
92066
  function detectDesktopScheme(bundles, scheme, probe = { exists: existsSync10, readUrlSchemes: realReadUrlSchemes }) {
91931
- const roots = ["/Applications", path21.join(os18.homedir(), "Applications")];
92067
+ const roots = ["/Applications", path22.join(os18.homedir(), "Applications")];
91932
92068
  return roots.some(
91933
92069
  (root) => bundles.some((bundle) => {
91934
- const bundlePath = path21.join(root, bundle);
92070
+ const bundlePath = path22.join(root, bundle);
91935
92071
  return probe.exists(bundlePath) && probe.readUrlSchemes(bundlePath).includes(scheme);
91936
92072
  })
91937
92073
  );
@@ -91941,7 +92077,7 @@ function realReadUrlSchemes(bundlePath) {
91941
92077
  try {
91942
92078
  const json2 = execFileSync4(
91943
92079
  "plutil",
91944
- ["-extract", "CFBundleURLTypes", "json", "-o", "-", path21.join(bundlePath, "Contents", "Info.plist")],
92080
+ ["-extract", "CFBundleURLTypes", "json", "-o", "-", path22.join(bundlePath, "Contents", "Info.plist")],
91945
92081
  { stdio: ["ignore", "pipe", "ignore"] }
91946
92082
  ).toString();
91947
92083
  const parsed = urlSchemesSchema.safeParse(JSON.parse(json2));
@@ -91960,7 +92096,7 @@ var claudeDesktopSessionSchema = external_exports.object({
91960
92096
  * and still links: the flag must never cost the row its desktop link. */
91961
92097
  isArchived: external_exports.unknown().optional()
91962
92098
  });
91963
- async function readClaudeDesktopSessions(wanted, root = path21.join(os18.homedir(), "Library/Application Support/Claude/claude-code-sessions")) {
92099
+ async function readClaudeDesktopSessions(wanted, root = path22.join(os18.homedir(), "Library/Application Support/Claude/claude-code-sessions")) {
91964
92100
  const sessions = /* @__PURE__ */ new Map();
91965
92101
  const ambiguous = /* @__PURE__ */ new Set();
91966
92102
  if (wanted.size === 0) return sessions;
@@ -91971,7 +92107,7 @@ async function readClaudeDesktopSessions(wanted, root = path21.join(os18.homedir
91971
92107
  throw error63;
91972
92108
  });
91973
92109
  for (const entry of entries) {
91974
- const file2 = path21.join(directory, entry.name);
92110
+ const file2 = path22.join(directory, entry.name);
91975
92111
  if (entry.isDirectory() && depth < 2) {
91976
92112
  await visit3(file2, depth + 1);
91977
92113
  } else if (depth === 2 && entry.isFile() && /^local_.*\.json$/.test(entry.name)) {
@@ -92011,7 +92147,7 @@ function isMissingFile(error63) {
92011
92147
  }
92012
92148
 
92013
92149
  // src/desktopDiagnostics.ts
92014
- async function probeClaudeDesktopSessions(wanted, installed, reportFault, root = path22.join(os19.homedir(), "Library/Application Support/Claude/claude-code-sessions"), read = readClaudeDesktopSessions) {
92150
+ async function probeClaudeDesktopSessions(wanted, installed, reportFault, root = path23.join(os19.homedir(), "Library/Application Support/Claude/claude-code-sessions"), read = readClaudeDesktopSessions) {
92015
92151
  if (!installed || wanted.size === 0) {
92016
92152
  return { sessions: /* @__PURE__ */ new Map(), diagnostic: { outcome: "not-needed" } };
92017
92153
  }
@@ -92028,24 +92164,25 @@ async function probeClaudeDesktopSessions(wanted, installed, reportFault, root =
92028
92164
 
92029
92165
  // src/cli.ts
92030
92166
  import { spawn as spawn3 } from "node:child_process";
92031
- import { existsSync as existsSync14, mkdirSync as mkdirSync14, openSync as openSync9, realpathSync as realpathSync5, rmSync as rmSync7 } from "node:fs";
92032
- import path31 from "node:path";
92167
+ import { randomUUID as randomUUID4 } from "node:crypto";
92168
+ import { existsSync as existsSync14, mkdirSync as mkdirSync15, openSync as openSync9, realpathSync as realpathSync5, rmSync as rmSync7 } from "node:fs";
92169
+ import path32 from "node:path";
92033
92170
  import { parseArgs } from "node:util";
92034
92171
 
92035
92172
  // src/connect.ts
92036
92173
  import { execFileSync as execFileSync5, spawnSync } from "node:child_process";
92037
92174
  import {
92038
92175
  existsSync as existsSync11,
92039
- mkdirSync as mkdirSync10,
92176
+ mkdirSync as mkdirSync11,
92040
92177
  mkdtempSync,
92041
92178
  readdirSync as readdirSync5,
92042
- readFileSync as readFileSync11,
92179
+ readFileSync as readFileSync12,
92043
92180
  realpathSync as realpathSync4,
92044
92181
  statSync as statSync5,
92045
- writeFileSync as writeFileSync9
92182
+ writeFileSync as writeFileSync10
92046
92183
  } from "node:fs";
92047
92184
  import os20 from "node:os";
92048
- import path23 from "node:path";
92185
+ import path24 from "node:path";
92049
92186
  import { emitKeypressEvents } from "node:readline";
92050
92187
 
92051
92188
  // src/agentVersions.ts
@@ -92119,7 +92256,7 @@ function startTimeBudget(totalMs, now = Date.now) {
92119
92256
  return { remainingMs: () => Math.max(0, deadline - now()) };
92120
92257
  }
92121
92258
  function defaultApplicationsDirs(homeDir) {
92122
- return process.platform === "darwin" ? ["/Applications", path23.join(homeDir, "Applications")] : [];
92259
+ return process.platform === "darwin" ? ["/Applications", path24.join(homeDir, "Applications")] : [];
92123
92260
  }
92124
92261
  function detectClients(options = {}) {
92125
92262
  const homeDir = options.homeDir ?? os20.homedir();
@@ -92147,7 +92284,7 @@ function detectClients(options = {}) {
92147
92284
  clients.push({ client, bin, ...configDir !== void 0 && { configDir } });
92148
92285
  };
92149
92286
  for (const bin of whichAll("claude")) add("claude", bin);
92150
- const localClaude = path23.join(homeDir, ".local", "bin", "claude");
92287
+ const localClaude = path24.join(homeDir, ".local", "bin", "claude");
92151
92288
  if (existsSync11(localClaude)) add("claude", localClaude);
92152
92289
  for (const bin of desktopClaudeBinaries(homeDir)) add("claude", bin);
92153
92290
  const claudeBins = clients.filter((client) => client.client === "claude" && client.configDir === void 0).map((client) => client.bin);
@@ -92155,12 +92292,12 @@ function detectClients(options = {}) {
92155
92292
  for (const bin of claudeBins) add("claude", bin, configDir);
92156
92293
  }
92157
92294
  for (const bin of whichAll("codex")) add("codex", bin);
92158
- const localCodex = path23.join(homeDir, ".local", "bin", "codex");
92295
+ const localCodex = path24.join(homeDir, ".local", "bin", "codex");
92159
92296
  if (existsSync11(localCodex)) add("codex", localCodex);
92160
92297
  for (const bin of codexBundleBinaries(applicationsDirs, bundleSeams)) add("codex", bin);
92161
- const cursorDir = path23.join(homeDir, ".cursor");
92162
- if (existsSync11(cursorDir) || cursorAppInstalled(applicationsDirs, bundleSeams)) {
92163
- clients.push({ client: "cursor", bin: path23.join(cursorDir, "mcp.json") });
92298
+ const cursorDir = path24.join(homeDir, ".cursor");
92299
+ if (!options.requireCursorApp && existsSync11(cursorDir) || cursorAppInstalled(applicationsDirs, bundleSeams)) {
92300
+ clients.push({ client: "cursor", bin: path24.join(cursorDir, "mcp.json") });
92164
92301
  }
92165
92302
  return clients;
92166
92303
  }
@@ -92168,7 +92305,7 @@ function claudeConfigHomes(homeDir, env) {
92168
92305
  const homes = [];
92169
92306
  const seen = /* @__PURE__ */ new Set();
92170
92307
  try {
92171
- seen.add(realpathSync4(path23.join(homeDir, ".claude")));
92308
+ seen.add(realpathSync4(path24.join(homeDir, ".claude")));
92172
92309
  } catch {
92173
92310
  }
92174
92311
  const add = (configDir) => {
@@ -92180,7 +92317,7 @@ function claudeConfigHomes(homeDir, env) {
92180
92317
  }
92181
92318
  if (seen.has(real)) return;
92182
92319
  seen.add(real);
92183
- homes.push(path23.resolve(configDir));
92320
+ homes.push(path24.resolve(configDir));
92184
92321
  };
92185
92322
  let entries = [];
92186
92323
  try {
@@ -92188,8 +92325,8 @@ function claudeConfigHomes(homeDir, env) {
92188
92325
  } catch {
92189
92326
  }
92190
92327
  for (const entry of entries.sort()) {
92191
- if (entry.startsWith(".claude-") && existsSync11(path23.join(homeDir, entry, ".claude.json"))) {
92192
- add(path23.join(homeDir, entry));
92328
+ if (entry.startsWith(".claude-") && existsSync11(path24.join(homeDir, entry, ".claude.json"))) {
92329
+ add(path24.join(homeDir, entry));
92193
92330
  }
92194
92331
  }
92195
92332
  if (env.CLAUDE_CONFIG_DIR) add(env.CLAUDE_CONFIG_DIR);
@@ -92217,7 +92354,7 @@ function appBundles(applicationsDirs, namePrefixes) {
92217
92354
  for (const entry of entries) {
92218
92355
  if (!entry.endsWith(".app")) continue;
92219
92356
  if (!namePrefixes.some((prefix) => entry.startsWith(prefix))) continue;
92220
- bundles.push(path23.join(dir, entry));
92357
+ bundles.push(path24.join(dir, entry));
92221
92358
  }
92222
92359
  }
92223
92360
  return bundles;
@@ -92237,7 +92374,7 @@ function codexBundleBinaries(applicationsDirs, seams) {
92237
92374
  const infoTimeoutMs = budgetedTimeout(BUNDLE_INFO_TIMEOUT_MS, appDir, seams);
92238
92375
  if (infoTimeoutMs === null) continue;
92239
92376
  if (seams.readBundleInfo(appDir, infoTimeoutMs)?.bundleId !== CODEX_BUNDLE_ID) continue;
92240
- const bin = path23.join(appDir, "Contents", "Resources", "codex");
92377
+ const bin = path24.join(appDir, "Contents", "Resources", "codex");
92241
92378
  if (!isExecutableFile(bin)) continue;
92242
92379
  if (!signedByTeam(bin, OPENAI_TEAM_ID, "OpenAI", appDir, seams)) continue;
92243
92380
  found.push(bin);
@@ -92249,7 +92386,7 @@ function trustedCursorBundle(appDir, seams) {
92249
92386
  if (infoTimeoutMs === null) return null;
92250
92387
  const info = seams.readBundleInfo(appDir, infoTimeoutMs);
92251
92388
  if (info?.executable === void 0) return null;
92252
- const bin = path23.join(appDir, "Contents", "MacOS", info.executable);
92389
+ const bin = path24.join(appDir, "Contents", "MacOS", info.executable);
92253
92390
  if (!isExecutableFile(bin)) return null;
92254
92391
  if (!signedByTeam(bin, CURSOR_TEAM_ID, "Cursor", appDir, seams)) return null;
92255
92392
  return info;
@@ -92286,7 +92423,7 @@ var bundleInfoSchema = external_exports.object({
92286
92423
  function realReadBundleInfo(appDir, timeoutMs) {
92287
92424
  const result = spawnSync(
92288
92425
  "plutil",
92289
- ["-convert", "json", "-o", "-", path23.join(appDir, "Contents", "Info.plist")],
92426
+ ["-convert", "json", "-o", "-", path24.join(appDir, "Contents", "Info.plist")],
92290
92427
  { encoding: "utf8", timeout: timeoutMs }
92291
92428
  );
92292
92429
  if (result.status !== 0) return null;
@@ -92308,14 +92445,14 @@ function realVerifySignature(binPath, teamId, timeoutMs) {
92308
92445
  }).status === 0;
92309
92446
  }
92310
92447
  function desktopClaudeBinaries(homeDir) {
92311
- const root = path23.join(homeDir, "Library", "Application Support", "Claude", "claude-code");
92448
+ const root = path24.join(homeDir, "Library", "Application Support", "Claude", "claude-code");
92312
92449
  let versions;
92313
92450
  try {
92314
92451
  versions = readdirSync5(root);
92315
92452
  } catch {
92316
92453
  return [];
92317
92454
  }
92318
- return versions.map((version2) => path23.join(root, version2, "claude.app", "Contents", "MacOS", "claude")).filter((bin) => existsSync11(bin));
92455
+ return versions.map((version2) => path24.join(root, version2, "claude.app", "Contents", "MacOS", "claude")).filter((bin) => existsSync11(bin));
92319
92456
  }
92320
92457
  function defaultWhichAll(name) {
92321
92458
  try {
@@ -92437,7 +92574,9 @@ async function pickAgents(clients, deps) {
92437
92574
  const kept = new Set(selected);
92438
92575
  const skippedNames = products.filter((product) => !kept.has(product)).map((product) => AGENT_DISPLAY_NAMES[product]);
92439
92576
  if (skippedNames.length > 0) deps.log(`Skipping ${skippedNames.join(" and ")}.`);
92440
- return clients.filter((client) => kept.has(client.client));
92577
+ const chosen = clients.filter((client) => kept.has(client.client));
92578
+ deps.onChoice?.(chosen);
92579
+ return chosen;
92441
92580
  }
92442
92581
  function realCheckboxPrompt(question, choices, seams = {}) {
92443
92582
  const input2 = seams.input ?? process.stdin;
@@ -92908,7 +93047,9 @@ function runDisconnect(clients, deps) {
92908
93047
  const results = [...groupByConnectionTarget(candidates).values()].map(
92909
93048
  (targetCandidates) => disconnectTarget(agent, targetCandidates, deps)
92910
93049
  );
92911
- outcome[aggregateDisconnectTargets(results)] += 1;
93050
+ const state = aggregateDisconnectTargets(results);
93051
+ outcome[state] += 1;
93052
+ if (state !== "failed") deps.onDisconnected?.(agent);
92912
93053
  }
92913
93054
  return outcome;
92914
93055
  }
@@ -93014,11 +93155,11 @@ function anyClientStillConnected(clients, deps) {
93014
93155
  });
93015
93156
  }
93016
93157
  function describeBinary(bin) {
93017
- return `${path23.basename(bin)} (${bin.replace(os20.homedir(), "~")})`;
93158
+ return `${path24.basename(bin)} (${bin.replace(os20.homedir(), "~")})`;
93018
93159
  }
93019
93160
  function describeClaudeTarget(client) {
93020
93161
  if (client.configDir === void 0) return describeBinary(client.bin);
93021
- return `${path23.basename(client.bin)} (${client.configDir.replace(os20.homedir(), "~")})`;
93162
+ return `${path24.basename(client.bin)} (${client.configDir.replace(os20.homedir(), "~")})`;
93022
93163
  }
93023
93164
  var FAILURE_DETAIL_MAX_CHARS = 200;
93024
93165
  function describeFailure(result) {
@@ -93031,7 +93172,7 @@ function describeFailure(result) {
93031
93172
  }
93032
93173
  var neutralDirMemo;
93033
93174
  function neutralWorkdir() {
93034
- neutralDirMemo ??= mkdtempSync(path23.join(os20.tmpdir(), "powerplant-connect-"));
93175
+ neutralDirMemo ??= mkdtempSync(path24.join(os20.tmpdir(), "powerplant-connect-"));
93035
93176
  return neutralDirMemo;
93036
93177
  }
93037
93178
  async function fetchOfficialClients(apiUrl, log3) {
@@ -93061,25 +93202,25 @@ async function fetchOfficialClients(apiUrl, log3) {
93061
93202
  }
93062
93203
  function realReadTextFile(filePath) {
93063
93204
  try {
93064
- return readFileSync11(filePath, "utf8");
93205
+ return readFileSync12(filePath, "utf8");
93065
93206
  } catch {
93066
93207
  return null;
93067
93208
  }
93068
93209
  }
93069
93210
  function realReadTextFileStrict(filePath) {
93070
93211
  try {
93071
- return readFileSync11(filePath, "utf8");
93212
+ return readFileSync12(filePath, "utf8");
93072
93213
  } catch (error63) {
93073
93214
  if (error63 instanceof Error && error63.code === "ENOENT") return null;
93074
93215
  throw error63;
93075
93216
  }
93076
93217
  }
93077
93218
  function realWriteTextFile(filePath, content) {
93078
- mkdirSync10(path23.dirname(filePath), { recursive: true });
93079
- writeFileSync9(filePath, content);
93219
+ mkdirSync11(path24.dirname(filePath), { recursive: true });
93220
+ writeFileSync10(filePath, content);
93080
93221
  }
93081
93222
  function codexConfigPath(homeDir = os20.homedir()) {
93082
- return path23.join(process.env.CODEX_HOME ?? path23.join(homeDir, ".codex"), "config.toml");
93223
+ return path24.join(process.env.CODEX_HOME ?? path24.join(homeDir, ".codex"), "config.toml");
93083
93224
  }
93084
93225
  function realOpenUrl(url2) {
93085
93226
  const bin = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : null;
@@ -93140,8 +93281,8 @@ function realRunInteractive(bin, args, env) {
93140
93281
 
93141
93282
  // src/connections.ts
93142
93283
  import { execFileSync as execFileSync6, spawnSync as spawnSync2 } from "node:child_process";
93143
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync10 } from "node:fs";
93144
- import path24 from "node:path";
93284
+ import { mkdirSync as mkdirSync12, writeFileSync as writeFileSync11 } from "node:fs";
93285
+ import path25 from "node:path";
93145
93286
  function probeConnections(clients, deps) {
93146
93287
  const reports = [];
93147
93288
  for (const kind of ["claude", "codex", "cursor"]) {
@@ -93185,7 +93326,7 @@ function aggregateClaudeTargets(targets) {
93185
93326
  if (targets.length === 1 || worst.report.state === "signed-in") return worst.report;
93186
93327
  return {
93187
93328
  ...worst.report,
93188
- target: worst.configDir === void 0 ? "default profile" : path24.basename(worst.configDir)
93329
+ target: worst.configDir === void 0 ? "default profile" : path25.basename(worst.configDir)
93189
93330
  };
93190
93331
  }
93191
93332
  function probeClient(client, deps) {
@@ -93264,12 +93405,12 @@ var detectedClientsSchema = external_exports.object({
93264
93405
  )
93265
93406
  });
93266
93407
  function detectedClientsPath(homeDir) {
93267
- return path24.join(collectorStateDir(homeDir), "detected-clients.json");
93408
+ return path25.join(collectorStateDir(homeDir), "detected-clients.json");
93268
93409
  }
93269
93410
  function saveDetectedClients(clients, pathValue, homeDir) {
93270
93411
  try {
93271
93412
  const file2 = detectedClientsPath(homeDir);
93272
- mkdirSync11(path24.dirname(file2), { recursive: true });
93413
+ mkdirSync12(path25.dirname(file2), { recursive: true });
93273
93414
  const record2 = {
93274
93415
  detectedAt: (/* @__PURE__ */ new Date()).toISOString(),
93275
93416
  path: pathValue,
@@ -93279,7 +93420,7 @@ function saveDetectedClients(clients, pathValue, homeDir) {
93279
93420
  ...configDir !== void 0 && { configDir }
93280
93421
  }))
93281
93422
  };
93282
- writeFileSync10(file2, JSON.stringify(record2, null, 2));
93423
+ writeFileSync11(file2, JSON.stringify(record2, null, 2));
93283
93424
  } catch {
93284
93425
  }
93285
93426
  }
@@ -93301,7 +93442,7 @@ function mergeDetectedClients(detected, saved, exists) {
93301
93442
  const known = new Set(detected.map(key));
93302
93443
  const revived = saved.clients.filter((client) => {
93303
93444
  const clientKey = key(client);
93304
- if (known.has(clientKey) || client.bin.includes(".app/") || !exists(client.bin) || client.configDir !== void 0 && !exists(client.configDir)) {
93445
+ if (known.has(clientKey) || client.client === "cursor" || client.bin.includes(".app/") || !exists(client.bin) || client.configDir !== void 0 && !exists(client.configDir)) {
93305
93446
  return false;
93306
93447
  }
93307
93448
  known.add(clientKey);
@@ -93356,7 +93497,7 @@ function whichAllWith(pathValue) {
93356
93497
  import { closeSync as closeSync7, fstatSync, openSync as openSync7, readSync as readSync5 } from "node:fs";
93357
93498
 
93358
93499
  // src/update.ts
93359
- import path26 from "node:path";
93500
+ import path27 from "node:path";
93360
93501
 
93361
93502
  // src/duration.ts
93362
93503
  function duration3(ms) {
@@ -93374,11 +93515,11 @@ function ago(ms) {
93374
93515
  }
93375
93516
 
93376
93517
  // src/installOwner.ts
93377
- import { accessSync, constants as constants2, readFileSync as readFileSync12 } from "node:fs";
93378
- import path25 from "node:path";
93518
+ import { accessSync, constants as constants2, readFileSync as readFileSync13 } from "node:fs";
93519
+ import path26 from "node:path";
93379
93520
 
93380
93521
  // src/version.ts
93381
- var CLI_VERSION = true ? "0.4.12" : "0.0.0-checkout";
93522
+ var CLI_VERSION = true ? "0.4.14" : "0.0.0-checkout";
93382
93523
  var CLI_RELEASE_BUILD = true ? true : false;
93383
93524
  var CLI_PACKAGE_NAME = "@usepowerplant/cli";
93384
93525
 
@@ -93402,13 +93543,13 @@ function inspectInstall(entryPath2, env) {
93402
93543
  inPlace: { ok: false, reason: `the install at ${packageDir} isn't a layout this CLI recognises` }
93403
93544
  };
93404
93545
  }
93405
- const modulesDir = path25.dirname(path25.dirname(packageDir));
93406
- const prefix = manager === "npm" ? path25.dirname(path25.dirname(modulesDir)) : null;
93546
+ const modulesDir = path26.dirname(path26.dirname(packageDir));
93547
+ const prefix = manager === "npm" ? path26.dirname(path26.dirname(modulesDir)) : null;
93407
93548
  const group = /^(.*\/global\/v11\/[^/]+)\/node_modules\//.exec(packageDir)?.[1];
93408
93549
  if (manager === "pnpm" && group !== void 0) {
93409
93550
  let dependencies = [];
93410
93551
  try {
93411
- const raw = env.readTextFile?.(path25.join(group, "package.json"));
93552
+ const raw = env.readTextFile?.(path26.join(group, "package.json"));
93412
93553
  const manifest = external_exports.object({ dependencies: external_exports.record(external_exports.string(), external_exports.string()) }).parse(JSON.parse(raw ?? "null"));
93413
93554
  dependencies = Object.keys(manifest.dependencies);
93414
93555
  } catch {
@@ -93435,7 +93576,7 @@ function detectManager(packageDir, pnpmHome) {
93435
93576
  return null;
93436
93577
  }
93437
93578
  function linkedEntryPath(realEntryPath, invokedEntryPath) {
93438
- if (invokedEntryPath !== void 0 && /\/global\/v11\/[^/]+\/node_modules\//.test(invokedEntryPath) && invokedEntryPath.endsWith(`${PACKAGE_SEGMENT}dist/cli.js`)) return path25.normalize(invokedEntryPath);
93579
+ if (invokedEntryPath !== void 0 && /\/global\/v11\/[^/]+\/node_modules\//.test(invokedEntryPath) && invokedEntryPath.endsWith(`${PACKAGE_SEGMENT}dist/cli.js`)) return path26.normalize(invokedEntryPath);
93439
93580
  const store = realEntryPath.lastIndexOf("/.pnpm/");
93440
93581
  if (store === -1) return realEntryPath;
93441
93582
  const at = realEntryPath.indexOf(PACKAGE_SEGMENT, store);
@@ -93462,7 +93603,7 @@ function manualUpdateCommand(manager, version2, prefix = null, channel3 = "lates
93462
93603
  return [bin, ...args].join(" ");
93463
93604
  }
93464
93605
  function installedVersion(packageDir, readTextFile) {
93465
- const raw = readTextFile(path25.join(packageDir, "package.json"));
93606
+ const raw = readTextFile(path26.join(packageDir, "package.json"));
93466
93607
  if (raw === null) return null;
93467
93608
  try {
93468
93609
  const parsed = JSON.parse(raw);
@@ -93479,7 +93620,7 @@ function realInspectEnvironment() {
93479
93620
  pnpmHome: process.env.PNPM_HOME,
93480
93621
  readTextFile: (file2) => {
93481
93622
  try {
93482
- return readFileSync12(file2, "utf8");
93623
+ return readFileSync13(file2, "utf8");
93483
93624
  } catch (error63) {
93484
93625
  if (error63 instanceof Error && "code" in error63 && error63.code === "ENOENT") return null;
93485
93626
  throw error63;
@@ -93498,7 +93639,13 @@ function realInspectEnvironment() {
93498
93639
 
93499
93640
  // src/update.ts
93500
93641
  var updateProgressSchema = external_exports.object({
93501
- state: external_exports.enum(["installing", "failed"]),
93642
+ /** "up-to-date": the last run installed nothing, because this build is
93643
+ * already at or past the release. That record is kept only so the menu
93644
+ * bar app that started the run can stop showing "Updating CLI…"
93645
+ * (menu.ts cliUpToDateAt); to every other reader it is no update at all.
93646
+ * A CLI from before this state rejects the record, which it reads as no
93647
+ * record. */
93648
+ state: external_exports.enum(["installing", "failed", "up-to-date"]),
93502
93649
  /** The release aimed at; null when the registry couldn't be asked (its latest). */
93503
93650
  target: external_exports.string().nullable(),
93504
93651
  startedAt: external_exports.string(),
@@ -93522,10 +93669,10 @@ function releaseNotServed(managerOutput) {
93522
93669
  return /\bETARGET\b|\bnotarget\b|ERR_PNPM_NO_MATCHING_VERSION/.test(managerOutput);
93523
93670
  }
93524
93671
  function updateProgressPath(homeDir) {
93525
- return path26.join(collectorStateDir(homeDir), "cli-update.json");
93672
+ return path27.join(collectorStateDir(homeDir), "cli-update.json");
93526
93673
  }
93527
93674
  function updateLogPath(homeDir) {
93528
- return path26.join(collectorStateDir(homeDir), "cli-update.log");
93675
+ return path27.join(collectorStateDir(homeDir), "cli-update.log");
93529
93676
  }
93530
93677
  function readUpdateProgress(readTextFile, file2 = updateProgressPath()) {
93531
93678
  const raw = readTextFile(file2);
@@ -93538,7 +93685,7 @@ function readUpdateProgress(readTextFile, file2 = updateProgressPath()) {
93538
93685
  }
93539
93686
  }
93540
93687
  function updateProgressView(progress, cliVersion2, now) {
93541
- if (progress === null) return { kind: "none" };
93688
+ if (progress === null || progress.state === "up-to-date") return { kind: "none" };
93542
93689
  const reached = progress.target === null ? null : compareReleaseVersions(cliVersion2, progress.target);
93543
93690
  if (reached === 0 || reached === 1) return { kind: "none" };
93544
93691
  if (progress.state === "failed") {
@@ -93571,13 +93718,29 @@ async function runUpdate(deps) {
93571
93718
  const reserved = running?.state === "installing" ? running.target : null;
93572
93719
  const attempts = (release2) => running?.target === release2 && running.attempts !== void 0 ? { attempts: running.attempts } : {};
93573
93720
  deps.writeProgress({ state: "installing", target: reserved, startedAt, pid: deps.pid, ...attempts(reserved) });
93574
- const target = await deps.resolveTarget() ?? reserved;
93721
+ const resolved = await deps.resolveTarget();
93722
+ if (resolved !== null) deps.recordAvailableVersion(resolved);
93723
+ const target = resolved ?? reserved;
93575
93724
  if (target === null && deps.targetRequired) {
93576
93725
  deps.clearProgress();
93577
93726
  throw new ExpectedCliError(
93578
93727
  "No release is promoted for production right now (or the API couldn't be reached), so there is nothing to update to. Production machines only install the promoted release."
93579
93728
  );
93580
93729
  }
93730
+ const reached = target === null ? null : compareReleaseVersions(deps.cliVersion, target);
93731
+ if (reached === 0 || reached === 1) {
93732
+ deps.writeProgress({
93733
+ state: "up-to-date",
93734
+ target,
93735
+ startedAt,
93736
+ pid: deps.pid,
93737
+ finishedAt: new Date(deps.now()).toISOString()
93738
+ });
93739
+ deps.log(
93740
+ reached === 0 ? `Already up to date (v${deps.cliVersion}).` : `Already on v${deps.cliVersion}, newer than the available release (v${target}). Nothing was installed.`
93741
+ );
93742
+ return;
93743
+ }
93581
93744
  deps.writeProgress({ state: "installing", target, startedAt, pid: deps.pid, ...attempts(target) });
93582
93745
  const { bin, args } = updateCommand(manager, target, inspection.prefix, deps.channel);
93583
93746
  deps.log(`Updating ${CLI_PACKAGE_NAME}${target === null ? "" : ` to ${target}`} via ${manager}\u2026`);
@@ -93739,13 +93902,13 @@ function redactedLogTail(raw) {
93739
93902
  while (lines.length > 0 && lines[lines.length - 1]?.trim() === "") lines.pop();
93740
93903
  return lines.slice(-DOCTOR_LOG_TAIL_LINES);
93741
93904
  }
93742
- function readDoctorLogTail(path32) {
93905
+ function readDoctorLogTail(path33) {
93743
93906
  let fd;
93744
93907
  try {
93745
- fd = openSync7(path32, "r");
93908
+ fd = openSync7(path33, "r");
93746
93909
  } catch (error63) {
93747
- if (error63.code === "ENOENT") return { path: path32, lines: null };
93748
- return { path: path32, lines: null, readError: error63 instanceof Error ? error63.message : String(error63) };
93910
+ if (error63.code === "ENOENT") return { path: path33, lines: null };
93911
+ return { path: path33, lines: null, readError: error63 instanceof Error ? error63.message : String(error63) };
93749
93912
  }
93750
93913
  try {
93751
93914
  const size = fstatSync(fd).size;
@@ -93754,9 +93917,9 @@ function readDoctorLogTail(path32) {
93754
93917
  readSync5(fd, buffer, 0, buffer.length, offset);
93755
93918
  let text = buffer.toString("utf8");
93756
93919
  if (offset > 0) text = text.slice(text.indexOf("\n") + 1);
93757
- return { path: path32, lines: redactedLogTail(text) };
93920
+ return { path: path33, lines: redactedLogTail(text) };
93758
93921
  } catch (error63) {
93759
- return { path: path32, lines: null, readError: error63 instanceof Error ? error63.message : String(error63) };
93922
+ return { path: path33, lines: null, readError: error63 instanceof Error ? error63.message : String(error63) };
93760
93923
  } finally {
93761
93924
  closeSync7(fd);
93762
93925
  }
@@ -94313,7 +94476,7 @@ async function realPromptLine(question) {
94313
94476
  }
94314
94477
 
94315
94478
  // src/menu.ts
94316
- import path27 from "node:path";
94479
+ import path28 from "node:path";
94317
94480
  var MENU_CONTRACT = 1;
94318
94481
  var CLIENT_NAMES = { claude: "Claude Code", codex: "Codex", cursor: "Cursor" };
94319
94482
  function renderMenu(i) {
@@ -94329,13 +94492,22 @@ function renderMenu(i) {
94329
94492
  more.push({ type: "section", title: "Agents authorized for MCP" });
94330
94493
  for (const connection of i.connections) {
94331
94494
  const { row, action, warns } = connectionRow(connection, envArgs);
94332
- if (warns) {
94495
+ const preference = i.mcpPreferences?.clients[connection.client];
94496
+ const eligible = warns && (connection.state !== "not-connected" || preference?.optedIn === true);
94497
+ const visible = eligible && preference?.dismissedWarning !== connection.state;
94498
+ const dismiss = i.mcpPreferencesError === void 0 ? {
94499
+ type: "action",
94500
+ title: `Dismiss ${CLIENT_NAMES[connection.client]} warning`,
94501
+ run: ["dismiss-mcp-warning", connection.client, connection.state, ...envArgs]
94502
+ } : void 0;
94503
+ if (visible) {
94333
94504
  attention = true;
94334
- items.push(row);
94505
+ items.push({ ...row, ...dismiss && { dismiss } });
94335
94506
  if (action) items.push(action);
94336
94507
  }
94337
- more.push(row);
94508
+ more.push(warns && !visible ? { ...row, mark: "muted" } : row);
94338
94509
  if (action) more.push(action);
94510
+ if (visible && dismiss) more.push(dismiss);
94339
94511
  }
94340
94512
  more.push({ type: "separator" });
94341
94513
  }
@@ -94361,6 +94533,11 @@ function renderMenu(i) {
94361
94533
  items.push({ type: "action", title: "Restart background sync\u2026", terminal: ["restart", ...envArgs] });
94362
94534
  items.push({ type: "separator" });
94363
94535
  }
94536
+ if (i.mcpPreferencesError !== void 0) {
94537
+ items.push(problem("MCP choices can't be read", "Restore or remove the preferences file."));
94538
+ items.push({ type: "action", title: "Copy MCP repair details", copy: i.mcpPreferencesError });
94539
+ items.push({ type: "separator" });
94540
+ }
94364
94541
  if (i.credentialsError !== void 0) {
94365
94542
  items.push(problem("Stored enrollment can't be read", i.credentialsError));
94366
94543
  items.push({ type: "action", title: "Enroll Again\u2026", terminal: ["init", ...envArgs] });
@@ -94422,6 +94599,7 @@ function renderMenu(i) {
94422
94599
  logPath: updateLogPath()
94423
94600
  }
94424
94601
  },
94602
+ ...i.update.progress?.state === "up-to-date" && { cliUpToDateAt: i.update.progress.finishedAt },
94425
94603
  ...i.desktopDiagnostic && { desktopDiagnostic: i.desktopDiagnostic },
94426
94604
  appEnv: i.config.appEnv,
94427
94605
  cliVersion: i.cliVersion,
@@ -94594,6 +94772,12 @@ function agentRow(session, i) {
94594
94772
  agent.harness = {
94595
94773
  type: "action",
94596
94774
  title: links.extra.label,
94775
+ reportClick: [
94776
+ "report-agent-click",
94777
+ isSessionSource(session.source) ? session.source : "unknown",
94778
+ "focus" in links.extra ? "focus" : "terminal" in links.extra ? "resume" : /^(codex|claude):/.test(links.extra.url) ? "desktop" : "web",
94779
+ ...envArgs
94780
+ ],
94597
94781
  ..."url" in links.extra ? { url: links.extra.url } : {
94598
94782
  ..."focus" in links.extra && { focus: links.extra.focus },
94599
94783
  terminal: [...links.extra.terminal, ...envArgs]
@@ -94710,7 +94894,7 @@ function daemonVersionNote(i) {
94710
94894
  }
94711
94895
  var VERSION_CACHE_TTL_MS = 60 * 6e4;
94712
94896
  function versionCachePath(homeDir, source = "npm") {
94713
- return path27.join(collectorStateDir(homeDir), source === "npm" ? "version-check.json" : "version-check-promoted.json");
94897
+ return path28.join(collectorStateDir(homeDir), source === "npm" ? "version-check.json" : "version-check-promoted.json");
94714
94898
  }
94715
94899
  async function cachedLatestVersion(options) {
94716
94900
  const raw = options.readTextFile(options.cacheFile);
@@ -94725,21 +94909,24 @@ async function cachedLatestVersion(options) {
94725
94909
  }
94726
94910
  }
94727
94911
  const version2 = await options.fetchLatest();
94912
+ writeVersionCache({ ...options, version: version2 });
94913
+ return version2;
94914
+ }
94915
+ function writeVersionCache(options) {
94728
94916
  try {
94729
94917
  options.writeTextFile(
94730
94918
  options.cacheFile,
94731
- JSON.stringify({ checkedAt: new Date(options.now).toISOString(), version: version2 })
94919
+ JSON.stringify({ checkedAt: new Date(options.now).toISOString(), version: options.version })
94732
94920
  );
94733
94921
  } catch {
94734
94922
  }
94735
- return version2;
94736
94923
  }
94737
94924
 
94738
94925
  // src/liveTerminalSessions.ts
94739
94926
  import { execFileSync as execFileSync7 } from "node:child_process";
94740
94927
  import { readdir as readdir3, readFile as readFile2 } from "node:fs/promises";
94741
94928
  import os21 from "node:os";
94742
- import path28 from "node:path";
94929
+ import path29 from "node:path";
94743
94930
  var sessionFileAsObserved = external_exports.looseObject({
94744
94931
  pid: external_exports.number().int().positive(),
94745
94932
  sessionId: external_exports.string().min(1),
@@ -94748,7 +94935,7 @@ var sessionFileAsObserved = external_exports.looseObject({
94748
94935
  var START_TIME_TOLERANCE_MS = 3e4;
94749
94936
  var SESSION_FILE = /^(\d+)\.json$/;
94750
94937
  function claudeSessionsDir(homeDir = os21.homedir()) {
94751
- return path28.join(homeDir, ".claude", "sessions");
94938
+ return path29.join(homeDir, ".claude", "sessions");
94752
94939
  }
94753
94940
  async function readLiveTerminalSessions(wanted, deps = {}) {
94754
94941
  const found = /* @__PURE__ */ new Map();
@@ -94773,7 +94960,7 @@ async function readLiveTerminalSessions(wanted, deps = {}) {
94773
94960
  }
94774
94961
  continue;
94775
94962
  }
94776
- const session = await readSessionFile(path28.join(sessionsDir, entry), report2);
94963
+ const session = await readSessionFile(path29.join(sessionsDir, entry), report2);
94777
94964
  if (session === null) continue;
94778
94965
  if (session.pid !== Number(match[1])) {
94779
94966
  report2({
@@ -94811,7 +94998,7 @@ async function readSessionFile(file2, report2) {
94811
94998
  report2({
94812
94999
  operation: "claude-session-registry-shape",
94813
95000
  message: "A Claude Code session file has a shape this CLI can't read",
94814
- context: { file: path28.basename(file2), shape: describeShape(raw) }
95001
+ context: { file: path29.basename(file2), shape: describeShape(raw) }
94815
95002
  });
94816
95003
  return null;
94817
95004
  }
@@ -95230,8 +95417,8 @@ function createTerminalOutput(options) {
95230
95417
 
95231
95418
  // src/credentialUpgrade.ts
95232
95419
  import { spawn as spawn2 } from "node:child_process";
95233
- import { closeSync as closeSync8, mkdirSync as mkdirSync12, openSync as openSync8 } from "node:fs";
95234
- import path29 from "node:path";
95420
+ import { closeSync as closeSync8, mkdirSync as mkdirSync13, openSync as openSync8 } from "node:fs";
95421
+ import path30 from "node:path";
95235
95422
  async function prepareCredentialUpgrade(deps) {
95236
95423
  if (!deps.needsMigration() || !deps.serviceExists() || deps.ready()) return "ready";
95237
95424
  if (deps.installing()) return "busy";
@@ -95264,7 +95451,7 @@ async function prepareCredentialUpgrade(deps) {
95264
95451
  }
95265
95452
  }
95266
95453
  async function tryCredentialUpgradeLock(file2) {
95267
- mkdirSync12(path29.dirname(file2), { recursive: true, mode: 448 });
95454
+ mkdirSync13(path30.dirname(file2), { recursive: true, mode: 448 });
95268
95455
  closeSync8(openSync8(file2, "a", 384));
95269
95456
  const child = spawn2("/usr/bin/lockf", ["-k", "-s", "-t", "0", file2, "/bin/sh", "-c", "printf 'ready\\n'; exec /bin/cat >/dev/null"], {
95270
95457
  detached: true,
@@ -95382,9 +95569,9 @@ async function tryCredentialUpgradeLock(file2) {
95382
95569
  }
95383
95570
 
95384
95571
  // src/menubarApp.ts
95385
- import { existsSync as existsSync13, mkdirSync as mkdirSync13, renameSync as renameSync5, rmSync as rmSync6 } from "node:fs";
95572
+ import { existsSync as existsSync13, mkdirSync as mkdirSync14, renameSync as renameSync6, rmSync as rmSync6 } from "node:fs";
95386
95573
  import os22 from "node:os";
95387
- import path30 from "node:path";
95574
+ import path31 from "node:path";
95388
95575
  import { spawnSync as spawnSync4 } from "node:child_process";
95389
95576
  var MENUBAR_APP_ZIP = "dist/menubar/Powerplant.app.zip";
95390
95577
  var MENUBAR_APP_NAME = "Powerplant.app";
@@ -95423,13 +95610,13 @@ async function syncMenubarApp(ops, context2) {
95423
95610
  }
95424
95611
  function realMenubarAppOps(input2) {
95425
95612
  const home = input2.homeDir ?? os22.homedir();
95426
- const userAppPath = path30.join(home, "Applications", MENUBAR_APP_NAME);
95427
- const candidates = [userAppPath, path30.join("/Applications", MENUBAR_APP_NAME)];
95613
+ const userAppPath = path31.join(home, "Applications", MENUBAR_APP_NAME);
95614
+ const candidates = [userAppPath, path31.join("/Applications", MENUBAR_APP_NAME)];
95428
95615
  return {
95429
95616
  cliVersion: input2.cliVersion,
95430
95617
  packagedZip: () => {
95431
95618
  if (input2.packageDir === null) return null;
95432
- const zip = path30.join(input2.packageDir, MENUBAR_APP_ZIP);
95619
+ const zip = path31.join(input2.packageDir, MENUBAR_APP_ZIP);
95433
95620
  return existsSync13(zip) ? zip : null;
95434
95621
  },
95435
95622
  installedApp: () => {
@@ -95449,10 +95636,10 @@ function realMenubarAppOps(input2) {
95449
95636
  throw new Error(`the running app at ${appPath} did not quit`);
95450
95637
  },
95451
95638
  replace: (zip, appPath) => {
95452
- const parent = path30.dirname(appPath);
95453
- mkdirSync13(parent, { recursive: true });
95454
- const staging = path30.join(parent, `.${MENUBAR_APP_NAME}.swap-${process.pid}`);
95455
- const retired = path30.join(parent, `.${MENUBAR_APP_NAME}.old-${process.pid}`);
95639
+ const parent = path31.dirname(appPath);
95640
+ mkdirSync14(parent, { recursive: true });
95641
+ const staging = path31.join(parent, `.${MENUBAR_APP_NAME}.swap-${process.pid}`);
95642
+ const retired = path31.join(parent, `.${MENUBAR_APP_NAME}.old-${process.pid}`);
95456
95643
  rmSync6(staging, { recursive: true, force: true });
95457
95644
  rmSync6(retired, { recursive: true, force: true });
95458
95645
  try {
@@ -95462,16 +95649,16 @@ function realMenubarAppOps(input2) {
95462
95649
  `ditto could not extract ${zip} (${extract.stderr?.toString().trim() || `exit ${extract.status}`})`
95463
95650
  );
95464
95651
  }
95465
- const extracted = path30.join(staging, MENUBAR_APP_NAME);
95466
- if (!existsSync13(path30.join(extracted, "Contents", "Info.plist"))) {
95652
+ const extracted = path31.join(staging, MENUBAR_APP_NAME);
95653
+ if (!existsSync13(path31.join(extracted, "Contents", "Info.plist"))) {
95467
95654
  throw new Error(`${zip} does not contain ${MENUBAR_APP_NAME}`);
95468
95655
  }
95469
95656
  const hadOld = existsSync13(appPath);
95470
- if (hadOld) renameSync5(appPath, retired);
95657
+ if (hadOld) renameSync6(appPath, retired);
95471
95658
  try {
95472
- renameSync5(extracted, appPath);
95659
+ renameSync6(extracted, appPath);
95473
95660
  } catch (error63) {
95474
- if (hadOld) renameSync5(retired, appPath);
95661
+ if (hadOld) renameSync6(retired, appPath);
95475
95662
  throw error63;
95476
95663
  }
95477
95664
  } finally {
@@ -95491,7 +95678,7 @@ function realMenubarAppOps(input2) {
95491
95678
  };
95492
95679
  }
95493
95680
  function appProcessIds(appPath) {
95494
- const executable = path30.join(appPath, "Contents", "MacOS", "PowerplantMenubar");
95681
+ const executable = path31.join(appPath, "Contents", "MacOS", "PowerplantMenubar");
95495
95682
  const result = spawnSync4("ps", ["-axo", "pid=,comm="], { encoding: "utf8" });
95496
95683
  if (result.status !== 0) {
95497
95684
  throw new Error(`ps could not list processes (${result.error?.message ?? `exit ${result.status}`})`);
@@ -95520,10 +95707,10 @@ var workspaceSchema = external_exports.object({
95520
95707
  active: external_exports.boolean()
95521
95708
  });
95522
95709
  var FETCH_TIMEOUT_MS2 = 1e4;
95523
- async function callApi(credentials, path32, init3, fetchImpl) {
95710
+ async function callApi(credentials, path33, init3, fetchImpl) {
95524
95711
  let response;
95525
95712
  try {
95526
- response = await fetchImpl(`${credentials.apiUrl}${path32}`, {
95713
+ response = await fetchImpl(`${credentials.apiUrl}${path33}`, {
95527
95714
  ...init3,
95528
95715
  headers: {
95529
95716
  authorization: `Bearer ${credentials.token}`,
@@ -95542,7 +95729,7 @@ async function callApi(credentials, path32, init3, fetchImpl) {
95542
95729
  );
95543
95730
  }
95544
95731
  if (!response.ok) {
95545
- throw new ExpectedCliError(`Powerplant answered ${response.status} for ${path32}.`);
95732
+ throw new ExpectedCliError(`Powerplant answered ${response.status} for ${path33}.`);
95546
95733
  }
95547
95734
  return response.json();
95548
95735
  }
@@ -95759,7 +95946,7 @@ ${USAGE}`);
95759
95946
  install: () => {
95760
95947
  installService(config2, watchCommand(config2));
95761
95948
  },
95762
- tryLock: () => tryCredentialUpgradeLock(path31.join(collectorStateDir(), `credential-upgrade-${config2.appEnv}.lock`)),
95949
+ tryLock: () => tryCredentialUpgradeLock(path32.join(collectorStateDir(), `credential-upgrade-${config2.appEnv}.lock`)),
95763
95950
  now: Date.now,
95764
95951
  sleep: () => new Promise((resolve2) => setTimeout(resolve2, 250)),
95765
95952
  restartCommand: `powerplant restart${config2.appEnv === "production" ? "" : ` --env ${config2.appEnv}`}`,
@@ -95806,6 +95993,9 @@ ${USAGE}`);
95806
95993
  const detected = detectClients({ warn: log3 });
95807
95994
  saveDetectedClients(detected, process.env.PATH ?? "");
95808
95995
  let clients = clientFilter === void 0 ? detected : detected.filter((client) => clientFilter.has(client.client));
95996
+ if (!pickerOn || clientFilter !== void 0) {
95997
+ recordMcpConnectChoices(config2.appEnv, detected.map((client) => client.client), clientFilter);
95998
+ }
95809
95999
  if (clientFilter !== void 0 && clients.length === 0) {
95810
96000
  log3(
95811
96001
  `No ${[...clientFilter].join(" or ")} installation found on this machine, nothing to connect.`
@@ -95822,7 +96012,11 @@ ${USAGE}`);
95822
96012
  }
95823
96013
  let skipped = 0;
95824
96014
  if (pickerOn && clientFilter === void 0 && clients.length > 0) {
95825
- clients = await pickAgents(clients, { log: log3, promptCheckboxes: realCheckboxPrompt });
96015
+ clients = await pickAgents(clients, {
96016
+ log: log3,
96017
+ promptCheckboxes: realCheckboxPrompt,
96018
+ onChoice: (selected) => recordMcpChoices(config2.appEnv, detected.map((client) => client.client), selected.map((client) => client.client))
96019
+ });
95826
96020
  skipped = agentCount(detected) - agentCount(clients);
95827
96021
  if (clients.length === 0) {
95828
96022
  log3(`Powerplant MCP wasn't added to any agents. Run any time: ${connectCommand}`);
@@ -95926,6 +96120,7 @@ ${USAGE}`);
95926
96120
  return;
95927
96121
  }
95928
96122
  const outcome = runDisconnect(clients, {
96123
+ onDisconnected: (client) => recordMcpChoices(config2.appEnv, [client], []),
95929
96124
  log: console.log,
95930
96125
  serverName: mcpServerNameFor(config2.appEnv),
95931
96126
  disconnectCommand,
@@ -96012,8 +96207,9 @@ The access you granted these agents stays on your Powerplant account until you r
96012
96207
  const budget = menuBudget;
96013
96208
  const saved = loadDetectedClients(realReadTextFile);
96014
96209
  const probePath = mergedPath(process.env.PATH, saved);
96210
+ const detected = detectClients({ whichAll: whichAllWith(probePath), budget, requireCursorApp: process.platform === "darwin" });
96015
96211
  const clients = mergeDetectedClients(
96016
- detectClients({ whichAll: whichAllWith(probePath), budget }),
96212
+ detected,
96017
96213
  saved,
96018
96214
  existsSync14
96019
96215
  );
@@ -96059,6 +96255,7 @@ The access you granted these agents stays on your Powerplant account until you r
96059
96255
  control: readCollectorControl(config2.appEnv),
96060
96256
  latestVersion,
96061
96257
  oldestSupportedVersion,
96258
+ ...readMcpPreferencesForMenu(config2.appEnv),
96062
96259
  connections: probeConnections(clients, {
96063
96260
  mcpUrl: `${config2.apiUrl}/mcp`,
96064
96261
  serverName: mcpServerNameFor(config2.appEnv),
@@ -96078,6 +96275,23 @@ The access you granted these agents stays on your Powerplant account until you r
96078
96275
  console.log(JSON.stringify(payload));
96079
96276
  return;
96080
96277
  }
96278
+ case "report-agent-click": {
96279
+ const parsed2 = menubarAgentClickSchema.safeParse({ source: positionals[1], destination: positionals[2] });
96280
+ if (!parsed2.success) throw new ExpectedCliError("Expected an agent source and menu destination.");
96281
+ const stored = loadCredentialsSafely(config2);
96282
+ if (!await reportMenubarEvent({ event: MENUBAR_AGENT_CLICK, ...parsed2.data }, stored.credentials, console.error)) process.exitCode = 1;
96283
+ return;
96284
+ }
96285
+ case "dismiss-mcp-warning": {
96286
+ const parsed2 = mcpWarningDismissalSchema.safeParse({ client: positionals[1], warning: positionals[2] });
96287
+ if (!parsed2.success) throw new ExpectedCliError("Expected a client and MCP warning type to dismiss.");
96288
+ if (dismissMcpWarning(config2.appEnv, parsed2.data)) {
96289
+ const stored = loadCredentialsSafely(config2);
96290
+ if (stored.credentialsError) console.error(JSON.stringify({ level: "warn", runId: randomUUID4(), operation: "menubar-analytics", outcome: "credentials-unavailable" }));
96291
+ await reportMenubarEvent({ event: MENUBAR_MCP_WARNING_REMOVE, ...parsed2.data }, stored.credentials, console.error);
96292
+ }
96293
+ return;
96294
+ }
96081
96295
  // Which workspace this account resolves to — the web app and the MCP
96082
96296
  // follow it. Needs the machine credential only to name the member.
96083
96297
  case "workspace": {
@@ -96111,7 +96325,14 @@ The access you granted these agents stays on your Powerplant account until you r
96111
96325
  }
96112
96326
  await runUpdate({
96113
96327
  inspection,
96328
+ cliVersion: CLI_VERSION,
96114
96329
  resolveTarget: () => fetchAvailableVersion(config2, loadCredentialsSafely(config2).credentials),
96330
+ recordAvailableVersion: (version2) => writeVersionCache({
96331
+ now: Date.now(),
96332
+ cacheFile: versionCachePath(void 0, releaseSource(config2.appEnv)),
96333
+ writeTextFile: realWriteTextFile,
96334
+ version: version2
96335
+ }),
96115
96336
  channel: releaseSource(config2.appEnv) === "npm" ? "next" : "latest",
96116
96337
  targetRequired: releaseSource(config2.appEnv) === "promoted",
96117
96338
  claimsReservation: process.env[UPDATE_CHILD_ENV] === "1",
@@ -96289,7 +96510,7 @@ function startBackgroundUpdate(config2, target) {
96289
96510
  readProgress: updateProgress.read,
96290
96511
  writeProgress: updateProgress.write,
96291
96512
  spawnChild: () => {
96292
- mkdirSync14(path31.dirname(updateLogPath()), { recursive: true });
96513
+ mkdirSync15(path32.dirname(updateLogPath()), { recursive: true });
96293
96514
  const log3 = openSync9(updateLogPath(), "a");
96294
96515
  const child = spawn3(process.execPath, [entryPath(), "update", ...envArgsFor(config2)], {
96295
96516
  detached: true,
@@ -96398,4 +96619,4 @@ undici/lib/web/websocket/frame.js:
96398
96619
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
96399
96620
  */
96400
96621
 
96401
- //# debugId=7d73a97a-938c-5f0f-8b6b-c4076b82abad
96622
+ //# debugId=81d65aee-a279-58bd-9476-cc1269e40adf