@usepowerplant/cli 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -6877,19 +6877,19 @@ var require_module_details_from_path = __commonJS({
6877
6877
  basedir += segments[i] + sep2;
6878
6878
  }
6879
6879
  }
6880
- var path19 = "";
6880
+ var path18 = "";
6881
6881
  var lastSegmentIndex = segments.length - 1;
6882
6882
  for (var i2 = index + offset; i2 <= lastSegmentIndex; i2++) {
6883
6883
  if (i2 === lastSegmentIndex) {
6884
- path19 += segments[i2];
6884
+ path18 += segments[i2];
6885
6885
  } else {
6886
- path19 += segments[i2] + sep2;
6886
+ path18 += segments[i2] + sep2;
6887
6887
  }
6888
6888
  }
6889
6889
  return {
6890
6890
  name,
6891
6891
  basedir,
6892
- path: path19
6892
+ path: path18
6893
6893
  };
6894
6894
  };
6895
6895
  }
@@ -6899,7 +6899,7 @@ var require_module_details_from_path = __commonJS({
6899
6899
  var require_require_in_the_middle = __commonJS({
6900
6900
  "../../node_modules/.pnpm/require-in-the-middle@8.0.1/node_modules/require-in-the-middle/index.js"(exports, module2) {
6901
6901
  "use strict";
6902
- var path19 = __require("path");
6902
+ var path18 = __require("path");
6903
6903
  var Module = __require("module");
6904
6904
  var debug2 = require_src3()("require-in-the-middle");
6905
6905
  var moduleDetailsFromPath = require_module_details_from_path();
@@ -7044,7 +7044,7 @@ var require_require_in_the_middle = __commonJS({
7044
7044
  }
7045
7045
  moduleName = filename;
7046
7046
  } else if (hasWhitelist === true && modules.includes(filename)) {
7047
- const parsedPath = path19.parse(filename);
7047
+ const parsedPath = path18.parse(filename);
7048
7048
  moduleName = parsedPath.name;
7049
7049
  basedir = parsedPath.dir;
7050
7050
  } else {
@@ -7082,7 +7082,7 @@ var require_require_in_the_middle = __commonJS({
7082
7082
  }
7083
7083
  if (res !== filename) {
7084
7084
  if (internals === true) {
7085
- moduleName = moduleName + path19.sep + path19.relative(basedir, filename);
7085
+ moduleName = moduleName + path18.sep + path18.relative(basedir, filename);
7086
7086
  debug2("preparing to process require of internal file: %s", moduleName);
7087
7087
  } else {
7088
7088
  debug2("ignoring require of non-main module file: %s", res);
@@ -7118,8 +7118,8 @@ var require_require_in_the_middle = __commonJS({
7118
7118
  }
7119
7119
  };
7120
7120
  function resolveModuleName(stat) {
7121
- const normalizedPath = path19.sep !== "/" ? stat.path.split(path19.sep).join("/") : stat.path;
7122
- return path19.posix.join(stat.name, normalizedPath).replace(normalize3, "");
7121
+ const normalizedPath = path18.sep !== "/" ? stat.path.split(path18.sep).join("/") : stat.path;
7122
+ return path18.posix.join(stat.name, normalizedPath).replace(normalize3, "");
7123
7123
  }
7124
7124
  }
7125
7125
  });
@@ -7204,7 +7204,7 @@ var require_RequireInTheMiddleSingleton = __commonJS({
7204
7204
  Object.defineProperty(exports, "__esModule", { value: true });
7205
7205
  exports.RequireInTheMiddleSingleton = void 0;
7206
7206
  var require_in_the_middle_1 = require_require_in_the_middle();
7207
- var path19 = __require("path");
7207
+ var path18 = __require("path");
7208
7208
  var ModuleNameTrie_1 = require_ModuleNameTrie();
7209
7209
  var isMocha = [
7210
7210
  "afterEach",
@@ -7268,7 +7268,7 @@ var require_RequireInTheMiddleSingleton = __commonJS({
7268
7268
  };
7269
7269
  exports.RequireInTheMiddleSingleton = RequireInTheMiddleSingleton;
7270
7270
  function normalizePathSeparators(moduleNameOrPath) {
7271
- return path19.sep !== ModuleNameTrie_1.ModuleNameSeparator ? moduleNameOrPath.split(path19.sep).join(ModuleNameTrie_1.ModuleNameSeparator) : moduleNameOrPath;
7271
+ return path18.sep !== ModuleNameTrie_1.ModuleNameSeparator ? moduleNameOrPath.split(path18.sep).join(ModuleNameTrie_1.ModuleNameSeparator) : moduleNameOrPath;
7272
7272
  }
7273
7273
  }
7274
7274
  });
@@ -7434,7 +7434,7 @@ var require_register = __commonJS({
7434
7434
  // ../../node_modules/.pnpm/import-in-the-middle@3.3.3/node_modules/import-in-the-middle/index.js
7435
7435
  var require_import_in_the_middle = __commonJS({
7436
7436
  "../../node_modules/.pnpm/import-in-the-middle@3.3.3/node_modules/import-in-the-middle/index.js"(exports, module2) {
7437
- var path19 = __require("path");
7437
+ var path18 = __require("path");
7438
7438
  var moduleDetailsFromPath = require_module_details_from_path();
7439
7439
  var { fileURLToPath: fileURLToPath3 } = __require("url");
7440
7440
  var { MessageChannel } = __require("worker_threads");
@@ -7553,7 +7553,7 @@ var require_import_in_the_middle = __commonJS({
7553
7553
  } else if (baseDir.endsWith(specifiers.get(loadUrl)) || isTurbopackSpecifier(specifiers.get(loadUrl), baseDir)) {
7554
7554
  callHookFn(hookFn, namespace, name, baseDir);
7555
7555
  } else if (internals) {
7556
- const internalPath = name + path19.sep + path19.relative(baseDir, filePath);
7556
+ const internalPath = name + path18.sep + path18.relative(baseDir, filePath);
7557
7557
  callHookFn(hookFn, namespace, internalPath, baseDir);
7558
7558
  }
7559
7559
  } else if (matchArg === specifier) {
@@ -7628,7 +7628,7 @@ var require_instrumentation2 = __commonJS({
7628
7628
  "use strict";
7629
7629
  Object.defineProperty(exports, "__esModule", { value: true });
7630
7630
  exports.InstrumentationBase = void 0;
7631
- var path19 = __require("path");
7631
+ var path18 = __require("path");
7632
7632
  var util_1 = __require("util");
7633
7633
  var semver_1 = require_semver();
7634
7634
  var shimmer_1 = require_shimmer();
@@ -7729,7 +7729,7 @@ var require_instrumentation2 = __commonJS({
7729
7729
  }
7730
7730
  _extractPackageVersion(baseDir) {
7731
7731
  try {
7732
- const json2 = (0, fs_1.readFileSync)(path19.join(baseDir, "package.json"), {
7732
+ const json2 = (0, fs_1.readFileSync)(path18.join(baseDir, "package.json"), {
7733
7733
  encoding: "utf8"
7734
7734
  });
7735
7735
  const version2 = JSON.parse(json2).version;
@@ -7771,7 +7771,7 @@ var require_instrumentation2 = __commonJS({
7771
7771
  return exports2;
7772
7772
  }
7773
7773
  const files = module3.files ?? [];
7774
- const normalizedName = path19.normalize(name);
7774
+ const normalizedName = path18.normalize(name);
7775
7775
  const supportedFileInstrumentations = files.filter((f) => f.name === normalizedName && isSupported(f.supportedVersions, version2, module3.includePrerelease));
7776
7776
  return supportedFileInstrumentations.reduce((patchedExports, file2) => {
7777
7777
  file2.moduleExports = patchedExports;
@@ -7817,8 +7817,8 @@ var require_instrumentation2 = __commonJS({
7817
7817
  this._warnOnPreloadedModules();
7818
7818
  for (const module3 of this._modules) {
7819
7819
  const hookFn = (exports2, name, baseDir) => {
7820
- if (!baseDir && path19.isAbsolute(name)) {
7821
- const parsedPath = path19.parse(name);
7820
+ if (!baseDir && path18.isAbsolute(name)) {
7821
+ const parsedPath = path18.parse(name);
7822
7822
  name = parsedPath.name;
7823
7823
  baseDir = parsedPath.dir;
7824
7824
  }
@@ -7827,7 +7827,7 @@ var require_instrumentation2 = __commonJS({
7827
7827
  const onRequire = (exports2, name, baseDir) => {
7828
7828
  return this._onRequire(module3, exports2, name, baseDir);
7829
7829
  };
7830
- const hook = path19.isAbsolute(module3.name) ? new require_in_the_middle_1.Hook([module3.name], { internals: true }, onRequire) : this._requireInTheMiddleSingleton.register(module3.name, onRequire);
7830
+ const hook = path18.isAbsolute(module3.name) ? new require_in_the_middle_1.Hook([module3.name], { internals: true }, onRequire) : this._requireInTheMiddleSingleton.register(module3.name, onRequire);
7831
7831
  this._hooks.push(hook);
7832
7832
  const esmHook = new import_in_the_middle_1.Hook([module3.name], { internals: true }, hookFn);
7833
7833
  this._hooks.push(esmHook);
@@ -8435,9 +8435,9 @@ var require_getMachineId_linux = __commonJS({
8435
8435
  var api_1 = (init_esm(), __toCommonJS(esm_exports));
8436
8436
  async function getMachineId() {
8437
8437
  const paths = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
8438
- for (const path19 of paths) {
8438
+ for (const path18 of paths) {
8439
8439
  try {
8440
- const result = await fs_1.promises.readFile(path19, { encoding: "utf8" });
8440
+ const result = await fs_1.promises.readFile(path18, { encoding: "utf8" });
8441
8441
  return result.trim();
8442
8442
  } catch (e) {
8443
8443
  api_1.diag.debug(`error reading machine id: ${e}`);
@@ -11792,14 +11792,14 @@ var require_util = __commonJS({
11792
11792
  }
11793
11793
  const port = url2.port != null ? url2.port : url2.protocol === "https:" ? 443 : 80;
11794
11794
  let origin = url2.origin != null ? url2.origin : `${url2.protocol || ""}//${url2.hostname || ""}:${port}`;
11795
- let path19 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
11795
+ let path18 = url2.path != null ? url2.path : `${url2.pathname || ""}${url2.search || ""}`;
11796
11796
  if (origin[origin.length - 1] === "/") {
11797
11797
  origin = origin.slice(0, origin.length - 1);
11798
11798
  }
11799
- if (path19 && path19[0] !== "/") {
11800
- path19 = `/${path19}`;
11799
+ if (path18 && path18[0] !== "/") {
11800
+ path18 = `/${path18}`;
11801
11801
  }
11802
- return new URL(`${origin}${path19}`);
11802
+ return new URL(`${origin}${path18}`);
11803
11803
  }
11804
11804
  if (!isHttpOrHttpsPrefixed(url2.origin || url2.protocol)) {
11805
11805
  throw new InvalidArgumentError("Invalid URL protocol: the URL must start with `http:` or `https:`.");
@@ -12620,9 +12620,9 @@ var require_diagnostics = __commonJS({
12620
12620
  "undici:client:sendHeaders",
12621
12621
  (evt) => {
12622
12622
  const {
12623
- request: { method, path: path19, origin }
12623
+ request: { method, path: path18, origin }
12624
12624
  } = evt;
12625
- debugLog3("sending request to %s %s%s", method, origin, path19);
12625
+ debugLog3("sending request to %s %s%s", method, origin, path18);
12626
12626
  }
12627
12627
  );
12628
12628
  }
@@ -12640,14 +12640,14 @@ var require_diagnostics = __commonJS({
12640
12640
  "undici:request:headers",
12641
12641
  (evt) => {
12642
12642
  const {
12643
- request: { method, path: path19, origin },
12643
+ request: { method, path: path18, origin },
12644
12644
  response: { statusCode }
12645
12645
  } = evt;
12646
12646
  debugLog3(
12647
12647
  "received response to %s %s%s - HTTP %d",
12648
12648
  method,
12649
12649
  origin,
12650
- path19,
12650
+ path18,
12651
12651
  statusCode
12652
12652
  );
12653
12653
  }
@@ -12656,23 +12656,23 @@ var require_diagnostics = __commonJS({
12656
12656
  "undici:request:trailers",
12657
12657
  (evt) => {
12658
12658
  const {
12659
- request: { method, path: path19, origin }
12659
+ request: { method, path: path18, origin }
12660
12660
  } = evt;
12661
- debugLog3("trailers received from %s %s%s", method, origin, path19);
12661
+ debugLog3("trailers received from %s %s%s", method, origin, path18);
12662
12662
  }
12663
12663
  );
12664
12664
  diagnosticsChannel9.subscribe(
12665
12665
  "undici:request:error",
12666
12666
  (evt) => {
12667
12667
  const {
12668
- request: { method, path: path19, origin },
12668
+ request: { method, path: path18, origin },
12669
12669
  error: error52
12670
12670
  } = evt;
12671
12671
  debugLog3(
12672
12672
  "request to %s %s%s errored - %s",
12673
12673
  method,
12674
12674
  origin,
12675
- path19,
12675
+ path18,
12676
12676
  error52.message
12677
12677
  );
12678
12678
  }
@@ -12787,7 +12787,7 @@ var require_request = __commonJS({
12787
12787
  var kHandler = /* @__PURE__ */ Symbol("handler");
12788
12788
  var Request2 = class {
12789
12789
  constructor(origin, {
12790
- path: path19,
12790
+ path: path18,
12791
12791
  method,
12792
12792
  body,
12793
12793
  headers,
@@ -12804,11 +12804,11 @@ var require_request = __commonJS({
12804
12804
  maxRedirections,
12805
12805
  typeOfService
12806
12806
  }, handler) {
12807
- if (typeof path19 !== "string") {
12807
+ if (typeof path18 !== "string") {
12808
12808
  throw new InvalidArgumentError("path must be a string");
12809
- } else if (path19[0] !== "/" && !(path19.startsWith("http://") || path19.startsWith("https://")) && method !== "CONNECT") {
12809
+ } else if (path18[0] !== "/" && !(path18.startsWith("http://") || path18.startsWith("https://")) && method !== "CONNECT") {
12810
12810
  throw new InvalidArgumentError("path must be an absolute URL or start with a slash");
12811
- } else if (invalidPathRegex.test(path19)) {
12811
+ } else if (invalidPathRegex.test(path18)) {
12812
12812
  throw new InvalidArgumentError("invalid request path");
12813
12813
  }
12814
12814
  if (typeof method !== "string") {
@@ -12883,7 +12883,7 @@ var require_request = __commonJS({
12883
12883
  this.completed = false;
12884
12884
  this.aborted = false;
12885
12885
  this.upgrade = upgrade || null;
12886
- this.path = query ? serializePathWithQuery(path19, query) : path19;
12886
+ this.path = query ? serializePathWithQuery(path18, query) : path18;
12887
12887
  this.origin = origin;
12888
12888
  this.protocol = getProtocolFromUrlString(origin);
12889
12889
  this.idempotent = idempotent == null ? method === "HEAD" || method === "GET" : idempotent;
@@ -18066,7 +18066,7 @@ var require_client_h1 = __commonJS({
18066
18066
  return method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && method !== "TRACE" && method !== "CONNECT";
18067
18067
  }
18068
18068
  function writeH1(client, request2) {
18069
- const { method, path: path19, host, upgrade, blocking, reset } = request2;
18069
+ const { method, path: path18, host, upgrade, blocking, reset } = request2;
18070
18070
  let { body, headers, contentLength } = request2;
18071
18071
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH" || method === "QUERY" || method === "PROPFIND" || method === "PROPPATCH";
18072
18072
  if (util2.isFormDataLike(body)) {
@@ -18144,7 +18144,7 @@ var require_client_h1 = __commonJS({
18144
18144
  if (socket.setTypeOfService) {
18145
18145
  socket.setTypeOfService(request2.typeOfService);
18146
18146
  }
18147
- let header = `${method} ${path19} HTTP/1.1\r
18147
+ let header = `${method} ${path18} HTTP/1.1\r
18148
18148
  `;
18149
18149
  if (typeof host === "string") {
18150
18150
  header += `host: ${host}\r
@@ -18797,7 +18797,7 @@ var require_client_h2 = __commonJS({
18797
18797
  function writeH2(client, request2) {
18798
18798
  const requestTimeout = request2.bodyTimeout ?? client[kBodyTimeout];
18799
18799
  const session = client[kHTTP2Session];
18800
- const { method, path: path19, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
18800
+ const { method, path: path18, host, upgrade, expectContinue, signal, protocol, headers: reqHeaders } = request2;
18801
18801
  let { body } = request2;
18802
18802
  if (upgrade != null && upgrade !== "websocket") {
18803
18803
  util2.errorRequest(client, request2, new InvalidArgumentError(`Custom upgrade "${upgrade}" not supported over HTTP/2`));
@@ -18865,7 +18865,7 @@ var require_client_h2 = __commonJS({
18865
18865
  }
18866
18866
  headers[HTTP2_HEADER_METHOD] = "CONNECT";
18867
18867
  headers[HTTP2_HEADER_PROTOCOL] = "websocket";
18868
- headers[HTTP2_HEADER_PATH] = path19;
18868
+ headers[HTTP2_HEADER_PATH] = path18;
18869
18869
  if (protocol === "ws:" || protocol === "wss:") {
18870
18870
  headers[HTTP2_HEADER_SCHEME] = protocol === "ws:" ? "http" : "https";
18871
18871
  } else {
@@ -18906,7 +18906,7 @@ var require_client_h2 = __commonJS({
18906
18906
  stream.setTimeout(requestTimeout);
18907
18907
  return true;
18908
18908
  }
18909
- headers[HTTP2_HEADER_PATH] = path19;
18909
+ headers[HTTP2_HEADER_PATH] = path18;
18910
18910
  headers[HTTP2_HEADER_SCHEME] = protocol === "http:" ? "http" : "https";
18911
18911
  const expectsPayload = method === "PUT" || method === "POST" || method === "PATCH";
18912
18912
  if (body && typeof body.read === "function") {
@@ -21249,10 +21249,10 @@ var require_proxy_agent = __commonJS({
21249
21249
  };
21250
21250
  const {
21251
21251
  origin,
21252
- path: path19 = "/",
21252
+ path: path18 = "/",
21253
21253
  headers = {}
21254
21254
  } = opts;
21255
- opts.path = origin + path19;
21255
+ opts.path = origin + path18;
21256
21256
  if (!("host" in headers) && !("Host" in headers)) {
21257
21257
  const { host } = new URL(origin);
21258
21258
  headers.host = host;
@@ -23335,20 +23335,20 @@ var require_mock_utils = __commonJS({
23335
23335
  }
23336
23336
  return normalizedQp;
23337
23337
  }
23338
- function safeUrl(path19) {
23339
- if (typeof path19 !== "string") {
23340
- return path19;
23338
+ function safeUrl(path18) {
23339
+ if (typeof path18 !== "string") {
23340
+ return path18;
23341
23341
  }
23342
- const pathSegments = path19.split("?", 3);
23342
+ const pathSegments = path18.split("?", 3);
23343
23343
  if (pathSegments.length !== 2) {
23344
- return path19;
23344
+ return path18;
23345
23345
  }
23346
23346
  const qp = new URLSearchParams(pathSegments.pop());
23347
23347
  qp.sort();
23348
23348
  return [...pathSegments, qp.toString()].join("?");
23349
23349
  }
23350
- function matchKey(mockDispatch2, { path: path19, method, body, headers }) {
23351
- const pathMatch = matchValue(mockDispatch2.path, path19);
23350
+ function matchKey(mockDispatch2, { path: path18, method, body, headers }) {
23351
+ const pathMatch = matchValue(mockDispatch2.path, path18);
23352
23352
  const methodMatch = matchValue(mockDispatch2.method, method);
23353
23353
  const bodyMatch = typeof mockDispatch2.body !== "undefined" ? matchValue(mockDispatch2.body, body) : true;
23354
23354
  const headersMatch = matchHeaders(mockDispatch2, headers);
@@ -23373,8 +23373,8 @@ var require_mock_utils = __commonJS({
23373
23373
  const basePath = key.query ? serializePathWithQuery(key.path, key.query) : key.path;
23374
23374
  const resolvedPath = typeof basePath === "string" ? safeUrl(basePath) : basePath;
23375
23375
  const resolvedPathWithoutTrailingSlash = removeTrailingSlash(resolvedPath);
23376
- let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path19, ignoreTrailingSlash }) => {
23377
- return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path19)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path19), resolvedPath);
23376
+ let matchedMockDispatches = mockDispatches.filter(({ consumed }) => !consumed).filter(({ path: path18, ignoreTrailingSlash }) => {
23377
+ return ignoreTrailingSlash ? matchValue(removeTrailingSlash(safeUrl(path18)), resolvedPathWithoutTrailingSlash) : matchValue(safeUrl(path18), resolvedPath);
23378
23378
  });
23379
23379
  if (matchedMockDispatches.length === 0) {
23380
23380
  throw new MockNotMatchedError(`Mock dispatch not matched for path '${resolvedPath}'`);
@@ -23413,19 +23413,19 @@ var require_mock_utils = __commonJS({
23413
23413
  mockDispatches.splice(index, 1);
23414
23414
  }
23415
23415
  }
23416
- function removeTrailingSlash(path19) {
23417
- while (path19.endsWith("/")) {
23418
- path19 = path19.slice(0, -1);
23416
+ function removeTrailingSlash(path18) {
23417
+ while (path18.endsWith("/")) {
23418
+ path18 = path18.slice(0, -1);
23419
23419
  }
23420
- if (path19.length === 0) {
23421
- path19 = "/";
23420
+ if (path18.length === 0) {
23421
+ path18 = "/";
23422
23422
  }
23423
- return path19;
23423
+ return path18;
23424
23424
  }
23425
23425
  function buildKey(opts) {
23426
- const { path: path19, method, body, headers, query } = opts;
23426
+ const { path: path18, method, body, headers, query } = opts;
23427
23427
  return {
23428
- path: path19,
23428
+ path: path18,
23429
23429
  method,
23430
23430
  body,
23431
23431
  headers,
@@ -24115,10 +24115,10 @@ var require_pending_interceptors_formatter = __commonJS({
24115
24115
  }
24116
24116
  format(pendingInterceptors) {
24117
24117
  const withPrettyHeaders = pendingInterceptors.map(
24118
- ({ method, path: path19, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
24118
+ ({ method, path: path18, data: { statusCode }, persist, times, timesInvoked, origin }) => ({
24119
24119
  Method: method,
24120
24120
  Origin: origin,
24121
- Path: path19,
24121
+ Path: path18,
24122
24122
  "Status code": statusCode,
24123
24123
  Persistent: persist ? PERSISTENT : NOT_PERSISTENT,
24124
24124
  Invocations: timesInvoked,
@@ -24200,9 +24200,9 @@ var require_mock_agent = __commonJS({
24200
24200
  const acceptNonStandardSearchParameters = this[kMockAgentAcceptsNonStandardSearchParameters];
24201
24201
  const dispatchOpts = { ...opts };
24202
24202
  if (acceptNonStandardSearchParameters && dispatchOpts.path) {
24203
- const [path19, searchParams] = dispatchOpts.path.split("?");
24203
+ const [path18, searchParams] = dispatchOpts.path.split("?");
24204
24204
  const normalizedSearchParams = normalizeSearchParams(searchParams, acceptNonStandardSearchParameters);
24205
- dispatchOpts.path = `${path19}?${normalizedSearchParams}`;
24205
+ dispatchOpts.path = `${path18}?${normalizedSearchParams}`;
24206
24206
  }
24207
24207
  return this[kAgent].dispatch(dispatchOpts, handler);
24208
24208
  }
@@ -24603,12 +24603,12 @@ var require_snapshot_recorder = __commonJS({
24603
24603
  * @return {Promise<void>} - Resolves when snapshots are loaded
24604
24604
  */
24605
24605
  async loadSnapshots(filePath) {
24606
- const path19 = filePath || this.#snapshotPath;
24607
- if (!path19) {
24606
+ const path18 = filePath || this.#snapshotPath;
24607
+ if (!path18) {
24608
24608
  throw new InvalidArgumentError("Snapshot path is required");
24609
24609
  }
24610
24610
  try {
24611
- const data = await readFile2(resolve2(path19), "utf8");
24611
+ const data = await readFile2(resolve2(path18), "utf8");
24612
24612
  const parsed = JSON.parse(data);
24613
24613
  if (Array.isArray(parsed)) {
24614
24614
  this.#snapshots.clear();
@@ -24622,7 +24622,7 @@ var require_snapshot_recorder = __commonJS({
24622
24622
  if (error52.code === "ENOENT") {
24623
24623
  this.#snapshots.clear();
24624
24624
  } else {
24625
- throw new UndiciError(`Failed to load snapshots from ${path19}`, { cause: error52 });
24625
+ throw new UndiciError(`Failed to load snapshots from ${path18}`, { cause: error52 });
24626
24626
  }
24627
24627
  }
24628
24628
  }
@@ -24633,11 +24633,11 @@ var require_snapshot_recorder = __commonJS({
24633
24633
  * @returns {Promise<void>} - Resolves when snapshots are saved
24634
24634
  */
24635
24635
  async saveSnapshots(filePath) {
24636
- const path19 = filePath || this.#snapshotPath;
24637
- if (!path19) {
24636
+ const path18 = filePath || this.#snapshotPath;
24637
+ if (!path18) {
24638
24638
  throw new InvalidArgumentError("Snapshot path is required");
24639
24639
  }
24640
- const resolvedPath = resolve2(path19);
24640
+ const resolvedPath = resolve2(path18);
24641
24641
  await mkdir(dirname2(resolvedPath), { recursive: true });
24642
24642
  const data = Array.from(this.#snapshots.entries()).map(([hash2, snapshot]) => ({
24643
24643
  hash: hash2,
@@ -25269,15 +25269,15 @@ var require_redirect_handler = __commonJS({
25269
25269
  return;
25270
25270
  }
25271
25271
  const { origin, pathname, search } = util2.parseURL(new URL(this.location, this.opts.origin && new URL(this.opts.path, this.opts.origin)));
25272
- const path19 = search ? `${pathname}${search}` : pathname;
25273
- const redirectUrlString = `${origin}${path19}`;
25272
+ const path18 = search ? `${pathname}${search}` : pathname;
25273
+ const redirectUrlString = `${origin}${path18}`;
25274
25274
  for (const historyUrl of this.history) {
25275
25275
  if (historyUrl.toString() === redirectUrlString) {
25276
25276
  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.`);
25277
25277
  }
25278
25278
  }
25279
25279
  this.opts.headers = cleanRequestHeaders(this.opts.headers, statusCode === 303, this.opts.origin !== origin);
25280
- this.opts.path = path19;
25280
+ this.opts.path = path18;
25281
25281
  this.opts.origin = origin;
25282
25282
  this.opts.query = null;
25283
25283
  }
@@ -27046,10 +27046,10 @@ var require_cache_handler = __commonJS({
27046
27046
  }
27047
27047
  return locationUrl.pathname + locationUrl.search;
27048
27048
  }
27049
- function deleteCachedUri(store, cacheKey, path19) {
27049
+ function deleteCachedUri(store, cacheKey, path18) {
27050
27050
  deleteCachedValue(store, {
27051
27051
  ...cacheKey,
27052
- path: path19
27052
+ path: path18
27053
27053
  });
27054
27054
  for (let i = 0; i < util2.safeHTTPMethods.length; i++) {
27055
27055
  const method = util2.safeHTTPMethods[i];
@@ -27057,7 +27057,7 @@ var require_cache_handler = __commonJS({
27057
27057
  deleteCachedValue(store, {
27058
27058
  ...cacheKey,
27059
27059
  method,
27060
- path: path19
27060
+ path: path18
27061
27061
  });
27062
27062
  }
27063
27063
  }
@@ -27068,9 +27068,9 @@ var require_cache_handler = __commonJS({
27068
27068
  }
27069
27069
  const values = Array.isArray(headerValue) ? headerValue : [headerValue];
27070
27070
  for (let i = 0; i < values.length; i++) {
27071
- const path19 = getSameOriginPath(cacheKey, values[i]);
27072
- if (path19 !== void 0) {
27073
- deleteCachedUri(store, cacheKey, path19);
27071
+ const path18 = getSameOriginPath(cacheKey, values[i]);
27072
+ if (path18 !== void 0) {
27073
+ deleteCachedUri(store, cacheKey, path18);
27074
27074
  }
27075
27075
  }
27076
27076
  }
@@ -31948,11 +31948,11 @@ var require_fetch = __commonJS({
31948
31948
  function dispatch({ body }) {
31949
31949
  const url2 = requestCurrentURL(request2);
31950
31950
  const agent = fetchParams.controller.dispatcher;
31951
- const path19 = url2.pathname + url2.search;
31951
+ const path18 = url2.pathname + url2.search;
31952
31952
  const hasTrailingQuestionMark = url2.search.length === 0 && url2.href[url2.href.length - url2.hash.length - 1] === "?";
31953
31953
  return new Promise((resolve2, reject) => agent.dispatch(
31954
31954
  {
31955
- path: hasTrailingQuestionMark ? `${path19}?` : path19,
31955
+ path: hasTrailingQuestionMark ? `${path18}?` : path18,
31956
31956
  origin: url2.origin,
31957
31957
  method: request2.method,
31958
31958
  body: agent.isMockActive ? request2.body && (request2.body.source || request2.body.stream) : body,
@@ -32899,9 +32899,9 @@ var require_util4 = __commonJS({
32899
32899
  }
32900
32900
  }
32901
32901
  }
32902
- function validateCookiePath(path19) {
32903
- for (let i = 0; i < path19.length; ++i) {
32904
- const code = path19.charCodeAt(i);
32902
+ function validateCookiePath(path18) {
32903
+ for (let i = 0; i < path18.length; ++i) {
32904
+ const code = path18.charCodeAt(i);
32905
32905
  if (code < 32 || // exclude CTLs (0-31)
32906
32906
  code > 126 || // exclude DEL and non-ascii
32907
32907
  code === 59) {
@@ -36138,11 +36138,11 @@ var require_undici = __commonJS({
36138
36138
  if (typeof opts.path !== "string") {
36139
36139
  throw new InvalidArgumentError("invalid opts.path");
36140
36140
  }
36141
- let path19 = opts.path;
36141
+ let path18 = opts.path;
36142
36142
  if (!opts.path.startsWith("/")) {
36143
- path19 = `/${path19}`;
36143
+ path18 = `/${path18}`;
36144
36144
  }
36145
- url2 = new URL(util2.parseOrigin(url2).origin + path19);
36145
+ url2 = new URL(util2.parseOrigin(url2).origin + path18);
36146
36146
  } else {
36147
36147
  if (!opts) {
36148
36148
  opts = typeof url2 === "object" ? url2 : {};
@@ -36253,7 +36253,7 @@ ${captureLines}` : capture.stack;
36253
36253
 
36254
36254
  // src/cli.ts
36255
36255
  import { spawnSync as spawnSync5 } from "node:child_process";
36256
- import { existsSync as existsSync7, realpathSync as realpathSync2 } from "node:fs";
36256
+ import { existsSync as existsSync6, realpathSync as realpathSync2 } from "node:fs";
36257
36257
  import { parseArgs } from "node:util";
36258
36258
 
36259
36259
  // ../../apps/collector/src/credentials.ts
@@ -37028,10 +37028,10 @@ function mergeDefs(...defs) {
37028
37028
  function cloneDef(schema) {
37029
37029
  return mergeDefs(schema._zod.def);
37030
37030
  }
37031
- function getElementAtPath(obj, path19) {
37032
- if (!path19)
37031
+ function getElementAtPath(obj, path18) {
37032
+ if (!path18)
37033
37033
  return obj;
37034
- return path19.reduce((acc, key) => acc?.[key], obj);
37034
+ return path18.reduce((acc, key) => acc?.[key], obj);
37035
37035
  }
37036
37036
  function promiseAllObject(promisesObj) {
37037
37037
  const keys = Object.keys(promisesObj);
@@ -37440,11 +37440,11 @@ function explicitlyAborted(x, startIndex = 0) {
37440
37440
  }
37441
37441
  return false;
37442
37442
  }
37443
- function prefixIssues(path19, issues) {
37443
+ function prefixIssues(path18, issues) {
37444
37444
  return issues.map((iss) => {
37445
37445
  var _a4;
37446
37446
  (_a4 = iss).path ?? (_a4.path = []);
37447
- iss.path.unshift(path19);
37447
+ iss.path.unshift(path18);
37448
37448
  return iss;
37449
37449
  });
37450
37450
  }
@@ -37591,16 +37591,16 @@ function flattenError(error52, mapper = (issue2) => issue2.message) {
37591
37591
  }
37592
37592
  function formatError(error52, mapper = (issue2) => issue2.message) {
37593
37593
  const fieldErrors = { _errors: [] };
37594
- const processError = (error53, path19 = []) => {
37594
+ const processError = (error53, path18 = []) => {
37595
37595
  for (const issue2 of error53.issues) {
37596
37596
  if (issue2.code === "invalid_union" && issue2.errors.length) {
37597
- issue2.errors.map((issues) => processError({ issues }, [...path19, ...issue2.path]));
37597
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
37598
37598
  } else if (issue2.code === "invalid_key") {
37599
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
37599
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
37600
37600
  } else if (issue2.code === "invalid_element") {
37601
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
37601
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
37602
37602
  } else {
37603
- const fullpath = [...path19, ...issue2.path];
37603
+ const fullpath = [...path18, ...issue2.path];
37604
37604
  if (fullpath.length === 0) {
37605
37605
  fieldErrors._errors.push(mapper(issue2));
37606
37606
  } else {
@@ -37627,17 +37627,17 @@ function formatError(error52, mapper = (issue2) => issue2.message) {
37627
37627
  }
37628
37628
  function treeifyError(error52, mapper = (issue2) => issue2.message) {
37629
37629
  const result = { errors: [] };
37630
- const processError = (error53, path19 = []) => {
37630
+ const processError = (error53, path18 = []) => {
37631
37631
  var _a4, _b;
37632
37632
  for (const issue2 of error53.issues) {
37633
37633
  if (issue2.code === "invalid_union" && issue2.errors.length) {
37634
- issue2.errors.map((issues) => processError({ issues }, [...path19, ...issue2.path]));
37634
+ issue2.errors.map((issues) => processError({ issues }, [...path18, ...issue2.path]));
37635
37635
  } else if (issue2.code === "invalid_key") {
37636
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
37636
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
37637
37637
  } else if (issue2.code === "invalid_element") {
37638
- processError({ issues: issue2.issues }, [...path19, ...issue2.path]);
37638
+ processError({ issues: issue2.issues }, [...path18, ...issue2.path]);
37639
37639
  } else {
37640
- const fullpath = [...path19, ...issue2.path];
37640
+ const fullpath = [...path18, ...issue2.path];
37641
37641
  if (fullpath.length === 0) {
37642
37642
  result.errors.push(mapper(issue2));
37643
37643
  continue;
@@ -37669,8 +37669,8 @@ function treeifyError(error52, mapper = (issue2) => issue2.message) {
37669
37669
  }
37670
37670
  function toDotPath(_path) {
37671
37671
  const segs = [];
37672
- const path19 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
37673
- for (const seg of path19) {
37672
+ const path18 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
37673
+ for (const seg of path18) {
37674
37674
  if (typeof seg === "number")
37675
37675
  segs.push(`[${seg}]`);
37676
37676
  else if (typeof seg === "symbol")
@@ -50362,13 +50362,13 @@ function resolveRef(ref, ctx) {
50362
50362
  if (!ref.startsWith("#")) {
50363
50363
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
50364
50364
  }
50365
- const path19 = ref.slice(1).split("/").filter(Boolean);
50366
- if (path19.length === 0) {
50365
+ const path18 = ref.slice(1).split("/").filter(Boolean);
50366
+ if (path18.length === 0) {
50367
50367
  return ctx.rootSchema;
50368
50368
  }
50369
50369
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
50370
- if (path19[0] === defsKey) {
50371
- const key = path19[1];
50370
+ if (path18[0] === defsKey) {
50371
+ const key = path18[1];
50372
50372
  if (!key || !ctx.defs[key]) {
50373
50373
  throw new Error(`Reference not found: ${ref}`);
50374
50374
  }
@@ -51409,8 +51409,8 @@ function primaryArg(args) {
51409
51409
  function readFilePath(name, primary) {
51410
51410
  if (!primary || !READ_TOOLS.has(name)) return null;
51411
51411
  if (ARTIFACT_PATH_RE.test(primary)) return null;
51412
- const path19 = primary.startsWith("/workspace/") ? primary.slice("/workspace/".length) : primary;
51413
- return path19.length > 0 ? path19 : null;
51412
+ const path18 = primary.startsWith("/workspace/") ? primary.slice("/workspace/".length) : primary;
51413
+ return path18.length > 0 ? path18 : null;
51414
51414
  }
51415
51415
  function asRecord3(value) {
51416
51416
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -51919,8 +51919,8 @@ function getFunctionName(fn) {
51919
51919
  return defaultFunctionName;
51920
51920
  }
51921
51921
  }
51922
- function normalizeStackTracePath(path19) {
51923
- let filename = path19?.startsWith("file://") ? path19.slice(7) : path19;
51922
+ function normalizeStackTracePath(path18) {
51923
+ let filename = path18?.startsWith("file://") ? path18.slice(7) : path18;
51924
51924
  if (filename?.match(/\/[A-Z]:/)) {
51925
51925
  filename = filename.slice(1);
51926
51926
  }
@@ -53730,8 +53730,8 @@ function isValidProtocol(protocol) {
53730
53730
  return protocol === "http" || protocol === "https";
53731
53731
  }
53732
53732
  function dsnToString(dsn, withPassword = false) {
53733
- const { host, path: path19, pass, port, projectId, protocol, publicKey } = dsn;
53734
- return `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ""}@${host}${port ? `:${port}` : ""}/${path19 ? `${path19}/` : path19}${projectId}`;
53733
+ const { host, path: path18, pass, port, projectId, protocol, publicKey } = dsn;
53734
+ return `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ""}@${host}${port ? `:${port}` : ""}/${path18 ? `${path18}/` : path18}${projectId}`;
53735
53735
  }
53736
53736
  function dsnFromString(str) {
53737
53737
  const match = DSN_REGEX.exec(str);
@@ -53742,11 +53742,11 @@ function dsnFromString(str) {
53742
53742
  return void 0;
53743
53743
  }
53744
53744
  const [protocol, publicKey, pass = "", host = "", port = "", lastPath = ""] = match.slice(1);
53745
- let path19 = "";
53745
+ let path18 = "";
53746
53746
  let projectId = lastPath;
53747
53747
  const split = projectId.split("/");
53748
53748
  if (split.length > 1) {
53749
- path19 = split.slice(0, -1).join("/");
53749
+ path18 = split.slice(0, -1).join("/");
53750
53750
  projectId = split.pop();
53751
53751
  }
53752
53752
  if (projectId) {
@@ -53755,7 +53755,7 @@ function dsnFromString(str) {
53755
53755
  projectId = projectMatch[0];
53756
53756
  }
53757
53757
  }
53758
- return dsnFromComponents({ host, pass, path: path19, projectId, port, protocol, publicKey });
53758
+ return dsnFromComponents({ host, pass, path: path18, projectId, port, protocol, publicKey });
53759
53759
  }
53760
53760
  function dsnFromComponents(components) {
53761
53761
  return {
@@ -58289,9 +58289,9 @@ function stripUrlQueryAndFragment(urlPath) {
58289
58289
  return urlPath.split(/[?#]/, 1)[0];
58290
58290
  }
58291
58291
  function getSanitizedUrlString(url2) {
58292
- const { protocol, host, path: path19 } = url2;
58292
+ const { protocol, host, path: path18 } = url2;
58293
58293
  const filteredHost = host?.replace(/^.*@/, "[filtered]:[filtered]@").replace(/(:80)$/, "").replace(/(:443)$/, "") || "";
58294
- return `${protocol ? `${protocol}://` : ""}${filteredHost}${path19}`;
58294
+ return `${protocol ? `${protocol}://` : ""}${filteredHost}${path18}`;
58295
58295
  }
58296
58296
  function stripDataUrlContent(url2, includeDataPrefix = true) {
58297
58297
  if (url2.startsWith("data:")) {
@@ -59234,8 +59234,8 @@ function splitPath(filename) {
59234
59234
  const parts = splitPathRe.exec(truncated);
59235
59235
  return parts ? parts.slice(1) : [];
59236
59236
  }
59237
- function dirname(path19) {
59238
- const result = splitPath(path19);
59237
+ function dirname(path18) {
59238
+ const result = splitPath(path18);
59239
59239
  const root = result[0] || "";
59240
59240
  let dir = result[1];
59241
59241
  if (!root && !dir) {
@@ -63161,15 +63161,15 @@ var getLayerMetadata = (route, layer, layerPath) => {
63161
63161
  };
63162
63162
  }
63163
63163
  };
63164
- var getRouterPath = (path19, layer) => {
63164
+ var getRouterPath = (path18, layer) => {
63165
63165
  const stackLayer = Array.isArray(layer.handle?.stack) ? layer.handle?.stack?.[0] : void 0;
63166
63166
  if (stackLayer?.route?.path) {
63167
- return `${path19}${stackLayer.route.path}`;
63167
+ return `${path18}${stackLayer.route.path}`;
63168
63168
  }
63169
63169
  if (stackLayer && Array.isArray(stackLayer?.handle?.stack)) {
63170
- return getRouterPath(path19, stackLayer);
63170
+ return getRouterPath(path18, stackLayer);
63171
63171
  }
63172
- return path19;
63172
+ return path18;
63173
63173
  };
63174
63174
  var isLayerIgnored = (name, type, config2) => {
63175
63175
  if (Array.isArray(config2?.ignoreLayersType) && config2?.ignoreLayersType?.includes(type)) {
@@ -63189,7 +63189,7 @@ function getActualMatchedRoute(req, constructedRoute) {
63189
63189
  if (layersStore.length === 0) {
63190
63190
  return void 0;
63191
63191
  }
63192
- if (layersStore.every((path19) => path19 === "/")) {
63192
+ if (layersStore.every((path18) => path18 === "/")) {
63193
63193
  return req.originalUrl === "/" ? "/" : void 0;
63194
63194
  }
63195
63195
  if (constructedRoute === "*") {
@@ -63205,11 +63205,11 @@ function getActualMatchedRoute(req, constructedRoute) {
63205
63205
  function getConstructedRoute(req) {
63206
63206
  const layersStore = getStoredLayers(req);
63207
63207
  let constructedRoute = "";
63208
- for (const path19 of layersStore) {
63209
- if (path19 === "/" || path19 === "/*") {
63208
+ for (const path18 of layersStore) {
63209
+ if (path18 === "/" || path18 === "/*") {
63210
63210
  continue;
63211
63211
  }
63212
- constructedRoute += !constructedRoute || constructedRoute.endsWith("/") ? path19 : `/${path19}`;
63212
+ constructedRoute += !constructedRoute || constructedRoute.endsWith("/") ? path18 : `/${path18}`;
63213
63213
  }
63214
63214
  return constructedRoute.replace(/\/{2,}/g, "/");
63215
63215
  }
@@ -63714,9 +63714,9 @@ function getRequestUrlObject(requestOptions) {
63714
63714
  const hostHeader = requestOptions.headers?.host && String(requestOptions.headers?.host);
63715
63715
  const hostname4 = hostHeader || requestOptions.hostname || requestOptions.host || "";
63716
63716
  const port = !requestOptions.port || requestOptions.port === 80 || requestOptions.port === 443 || /^(.*):(\d+)$/.test(hostname4) ? "" : `:${requestOptions.port}`;
63717
- const path19 = requestOptions.path ? requestOptions.path : "/";
63717
+ const path18 = requestOptions.path ? requestOptions.path : "/";
63718
63718
  const base = `${protocol}//${hostname4}${port}`;
63719
- return new URL(path19.startsWith("//") ? `${base}${path19}` : path19, base);
63719
+ return new URL(path18.startsWith("//") ? `${base}${path18}` : path18, base);
63720
63720
  }
63721
63721
  function getRequestUrlFromClientRequest(request2) {
63722
63722
  return String(getRequestUrl(getRequestOptions(request2)));
@@ -64389,11 +64389,11 @@ function shouldIgnoreSpansForIncomingRequest(request2, {
64389
64389
  return false;
64390
64390
  }
64391
64391
  function isStaticAssetRequest(urlPath) {
64392
- const path19 = stripUrlQueryAndFragment(urlPath);
64393
- if (path19.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
64392
+ const path18 = stripUrlQueryAndFragment(urlPath);
64393
+ if (path18.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
64394
64394
  return true;
64395
64395
  }
64396
- if (path19.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
64396
+ if (path18.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
64397
64397
  return true;
64398
64398
  }
64399
64399
  return false;
@@ -64634,11 +64634,11 @@ function isKnownPrefetchRequest2(req) {
64634
64634
  return req.headers["next-router-prefetch"] === "1";
64635
64635
  }
64636
64636
  function isStaticAssetRequest2(urlPath) {
64637
- const path19 = stripUrlQueryAndFragment(urlPath);
64638
- if (path19.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
64637
+ const path18 = stripUrlQueryAndFragment(urlPath);
64638
+ if (path18.match(/\.(ico|png|jpg|jpeg|gif|svg|css|js|woff|woff2|ttf|eot|webp|avif)$/)) {
64639
64639
  return true;
64640
64640
  }
64641
- if (path19.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
64641
+ if (path18.match(/^\/(robots\.txt|sitemap\.xml|manifest\.json|browserconfig\.xml)$/)) {
64642
64642
  return true;
64643
64643
  }
64644
64644
  return false;
@@ -64998,19 +64998,19 @@ function getBreadcrumbData(request2) {
64998
64998
  return {};
64999
64999
  }
65000
65000
  }
65001
- function getAbsoluteUrl2(origin, path19 = "/") {
65001
+ function getAbsoluteUrl2(origin, path18 = "/") {
65002
65002
  try {
65003
- const url2 = new URL(path19, origin);
65003
+ const url2 = new URL(path18, origin);
65004
65004
  return url2.toString();
65005
65005
  } catch {
65006
65006
  const url2 = `${origin}`;
65007
- if (url2.endsWith("/") && path19.startsWith("/")) {
65008
- return `${url2}${path19.slice(1)}`;
65007
+ if (url2.endsWith("/") && path18.startsWith("/")) {
65008
+ return `${url2}${path18.slice(1)}`;
65009
65009
  }
65010
- if (!url2.endsWith("/") && !path19.startsWith("/")) {
65011
- return `${url2}/${path19}`;
65010
+ if (!url2.endsWith("/") && !path18.startsWith("/")) {
65011
+ return `${url2}/${path18}`;
65012
65012
  }
65013
- return `${url2}${path19}`;
65013
+ return `${url2}${path18}`;
65014
65014
  }
65015
65015
  }
65016
65016
 
@@ -65255,15 +65255,15 @@ function getRequestMethod(original) {
65255
65255
  }
65256
65256
  return "_OTHER";
65257
65257
  }
65258
- function getAbsoluteUrl3(origin, path19 = "/") {
65258
+ function getAbsoluteUrl3(origin, path18 = "/") {
65259
65259
  const url2 = `${origin}`;
65260
- if (url2.endsWith("/") && path19.startsWith("/")) {
65261
- return `${url2}${path19.slice(1)}`;
65260
+ if (url2.endsWith("/") && path18.startsWith("/")) {
65261
+ return `${url2}${path18.slice(1)}`;
65262
65262
  }
65263
- if (!url2.endsWith("/") && !path19.startsWith("/")) {
65264
- return `${url2}/${path19}`;
65263
+ if (!url2.endsWith("/") && !path18.startsWith("/")) {
65264
+ return `${url2}/${path18}`;
65265
65265
  }
65266
- return `${url2}${path19}`;
65266
+ return `${url2}${path18}`;
65267
65267
  }
65268
65268
 
65269
65269
  // ../../node_modules/.pnpm/@sentry+node-core@10.71.0_@opentelemetry+api@1.9.1_@opentelemetry+core@2.10.0_@opentele_e57ddc8c682f93a270df4265a143e64e/node_modules/@sentry/node-core/build/esm/integrations/node-fetch/index.js
@@ -67749,12 +67749,12 @@ function emplace(map2, key, contents) {
67749
67749
  }
67750
67750
  return value;
67751
67751
  }
67752
- function shouldSkipContextLinesForFile(path19) {
67753
- if (path19.startsWith("node:")) return true;
67754
- if (path19.endsWith(".min.js")) return true;
67755
- if (path19.endsWith(".min.cjs")) return true;
67756
- if (path19.endsWith(".min.mjs")) return true;
67757
- if (path19.startsWith("data:")) return true;
67752
+ function shouldSkipContextLinesForFile(path18) {
67753
+ if (path18.startsWith("node:")) return true;
67754
+ if (path18.endsWith(".min.js")) return true;
67755
+ if (path18.endsWith(".min.cjs")) return true;
67756
+ if (path18.endsWith(".min.mjs")) return true;
67757
+ if (path18.startsWith("data:")) return true;
67758
67758
  return false;
67759
67759
  }
67760
67760
  function shouldSkipContextLinesForFrame(frame) {
@@ -67802,9 +67802,9 @@ function makeLineReaderRanges(lines, linecontext) {
67802
67802
  }
67803
67803
  return out;
67804
67804
  }
67805
- function getContextLinesFromFile(path19, ranges, output) {
67805
+ function getContextLinesFromFile(path18, ranges, output) {
67806
67806
  return new Promise((resolve2, _reject) => {
67807
- const stream = createReadStream(path19);
67807
+ const stream = createReadStream(path18);
67808
67808
  const lineReaded = createInterface({
67809
67809
  input: stream
67810
67810
  });
@@ -67822,8 +67822,8 @@ function getContextLinesFromFile(path19, ranges, output) {
67822
67822
  let rangeStart = range[0];
67823
67823
  let rangeEnd = range[1];
67824
67824
  function onStreamError(e) {
67825
- LRU_FILE_CONTENTS_FS_READ_FAILED.set(path19, 1);
67826
- DEBUG_BUILD2 && debug.error(`Failed to read file: ${path19}. Error: ${e}`);
67825
+ LRU_FILE_CONTENTS_FS_READ_FAILED.set(path18, 1);
67826
+ DEBUG_BUILD2 && debug.error(`Failed to read file: ${path18}. Error: ${e}`);
67827
67827
  lineReaded.close();
67828
67828
  lineReaded.removeAllListeners();
67829
67829
  destroyStreamAndResolve();
@@ -69262,8 +69262,8 @@ function getSpotlightConfig(optionsSpotlight) {
69262
69262
 
69263
69263
  // ../../node_modules/.pnpm/@sentry+node-core@10.71.0_@opentelemetry+api@1.9.1_@opentelemetry+core@2.10.0_@opentele_e57ddc8c682f93a270df4265a143e64e/node_modules/@sentry/node-core/build/esm/utils/module.js
69264
69264
  import { posix, sep } from "node:path";
69265
- function normalizeWindowsPath(path19) {
69266
- return path19.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
69265
+ function normalizeWindowsPath(path18) {
69266
+ return path18.replace(/^[A-Z]:/, "").replace(/\\/g, "/");
69267
69267
  }
69268
69268
  function createGetModuleFromFilename(basePath = process.argv[1] ? dirname(process.argv[1]) : process.cwd(), isWindows = sep === "\\") {
69269
69269
  const normalizedBase = isWindows ? normalizeWindowsPath(basePath) : basePath;
@@ -72135,22 +72135,22 @@ function addSpanSource(span, loc, start, end) {
72135
72135
  span.setAttribute(AttributeNames2.SOURCE, source);
72136
72136
  }
72137
72137
  }
72138
- function createFieldIfNotExists(contextValue, info, path19) {
72139
- let field = getField(contextValue, path19);
72138
+ function createFieldIfNotExists(contextValue, info, path18) {
72139
+ let field = getField(contextValue, path18);
72140
72140
  if (field) {
72141
72141
  return { field, spanAdded: false };
72142
72142
  }
72143
- const parentSpan = getParentFieldSpan(contextValue, path19);
72143
+ const parentSpan = getParentFieldSpan(contextValue, path18);
72144
72144
  field = {
72145
- span: createResolverSpan(contextValue, info, path19, parentSpan)
72145
+ span: createResolverSpan(contextValue, info, path18, parentSpan)
72146
72146
  };
72147
- addField(contextValue, path19, field);
72147
+ addField(contextValue, path18, field);
72148
72148
  return { field, spanAdded: true };
72149
72149
  }
72150
- function createResolverSpan(contextValue, info, path19, parentSpan) {
72150
+ function createResolverSpan(contextValue, info, path18, parentSpan) {
72151
72151
  const attributes = {
72152
72152
  [AttributeNames2.FIELD_NAME]: info.fieldName,
72153
- [AttributeNames2.FIELD_PATH]: path19.join("."),
72153
+ [AttributeNames2.FIELD_PATH]: path18.join("."),
72154
72154
  [AttributeNames2.FIELD_TYPE]: info.returnType.toString(),
72155
72155
  [AttributeNames2.PARENT_NAME]: info.parentType.name
72156
72156
  };
@@ -72182,15 +72182,15 @@ function getOperation(document2, operationName) {
72182
72182
  return document2.definitions.find((definition) => OPERATION_VALUES.indexOf(definition?.operation) !== -1);
72183
72183
  }
72184
72184
  }
72185
- function addField(contextValue, path19, field) {
72186
- return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path19.join(".")] = field;
72185
+ function addField(contextValue, path18, field) {
72186
+ return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path18.join(".")] = field;
72187
72187
  }
72188
- function getField(contextValue, path19) {
72189
- return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path19.join(".")];
72188
+ function getField(contextValue, path18) {
72189
+ return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].fields[path18.join(".")];
72190
72190
  }
72191
- function getParentFieldSpan(contextValue, path19) {
72192
- for (let i = path19.length - 1; i > 0; i--) {
72193
- const field = getField(contextValue, path19.slice(0, i));
72191
+ function getParentFieldSpan(contextValue, path18) {
72192
+ for (let i = path18.length - 1; i > 0; i--) {
72193
+ const field = getField(contextValue, path18.slice(0, i));
72194
72194
  if (field) {
72195
72195
  return field.span;
72196
72196
  }
@@ -72200,9 +72200,9 @@ function getParentFieldSpan(contextValue, path19) {
72200
72200
  function getRootSpan2(contextValue) {
72201
72201
  return contextValue[OTEL_GRAPHQL_DATA_SYMBOL].span;
72202
72202
  }
72203
- function pathToArray(path19) {
72203
+ function pathToArray(path18) {
72204
72204
  const flattened = [];
72205
- let curr = path19;
72205
+ let curr = path18;
72206
72206
  while (curr) {
72207
72207
  flattened.push(String(curr.key));
72208
72208
  curr = curr.prev;
@@ -72343,8 +72343,8 @@ function wrapFieldResolver(getConfig3, fieldResolver, isDefaultResolver = false)
72343
72343
  if (!contextValue[OTEL_GRAPHQL_DATA_SYMBOL]) {
72344
72344
  return fieldResolver.call(this, source, args, contextValue, info);
72345
72345
  }
72346
- const path19 = pathToArray(info?.path);
72347
- const { field, spanAdded } = createFieldIfNotExists(contextValue, info, path19);
72346
+ const path18 = pathToArray(info?.path);
72347
+ const { field, spanAdded } = createFieldIfNotExists(contextValue, info, path18);
72348
72348
  const span = field.span;
72349
72349
  const shouldEndSpan = spanAdded;
72350
72350
  return withActiveSpan(span, () => {
@@ -75327,10 +75327,10 @@ var PostgresJsInstrumentation = class extends import_instrumentation24.Instrumen
75327
75327
  },
75328
75328
  (exports) => exports
75329
75329
  );
75330
- ["src", "cf/src", "cjs/src"].forEach((path19) => {
75330
+ ["src", "cf/src", "cjs/src"].forEach((path18) => {
75331
75331
  module2.files.push(
75332
75332
  new InstrumentationNodeModuleFile(
75333
- `postgres/${path19}/query.js`,
75333
+ `postgres/${path18}/query.js`,
75334
75334
  SUPPORTED_VERSIONS4,
75335
75335
  this._patchQueryPrototype.bind(this),
75336
75336
  this._unpatchQueryPrototype.bind(this)
@@ -75961,13 +75961,13 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
75961
75961
  return function(original) {
75962
75962
  return function wrappedHandler(...args) {
75963
75963
  if (typeof args[0] === "string") {
75964
- const path19 = args[0];
75964
+ const path18 = args[0];
75965
75965
  if (args.length === 1) {
75966
- return original.apply(this, [path19]);
75966
+ return original.apply(this, [path18]);
75967
75967
  }
75968
75968
  const handlers2 = args.slice(1);
75969
75969
  return original.apply(this, [
75970
- path19,
75970
+ path18,
75971
75971
  ...handlers2.map((handler) => instrumentation._wrapHandler(handler))
75972
75972
  ]);
75973
75973
  }
@@ -76001,13 +76001,13 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
76001
76001
  return function(original) {
76002
76002
  return function wrappedHandler(...args) {
76003
76003
  if (typeof args[0] === "string") {
76004
- const path19 = args[0];
76004
+ const path18 = args[0];
76005
76005
  if (args.length === 1) {
76006
- return original.apply(this, [path19]);
76006
+ return original.apply(this, [path18]);
76007
76007
  }
76008
76008
  const handlers2 = args.slice(1);
76009
76009
  return original.apply(this, [
76010
- path19,
76010
+ path18,
76011
76011
  ...handlers2.map((handler) => instrumentation._wrapHandler(handler))
76012
76012
  ]);
76013
76013
  }
@@ -76027,8 +76027,8 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
76027
76027
  if (!instrumentation.isEnabled()) {
76028
76028
  return handler.apply(this, [c, next]);
76029
76029
  }
76030
- const path19 = c.req.path;
76031
- const span = instrumentation.tracer.startSpan(path19);
76030
+ const path18 = c.req.path;
76031
+ const span = instrumentation.tracer.startSpan(path18);
76032
76032
  return context.with(trace.setSpan(context.active(), span), () => {
76033
76033
  return instrumentation._safeExecute(
76034
76034
  () => {
@@ -76038,7 +76038,7 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
76038
76038
  const type = instrumentation._determineHandlerType(result2);
76039
76039
  span.setAttributes({
76040
76040
  [AttributeNames5.HONO_TYPE]: type,
76041
- [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path19 : handler.name || "anonymous"
76041
+ [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path18 : handler.name || "anonymous"
76042
76042
  });
76043
76043
  instrumentation.getConfig().responseHook?.(span);
76044
76044
  return result2;
@@ -76047,7 +76047,7 @@ var HonoInstrumentation = class extends import_instrumentation27.Instrumentation
76047
76047
  const type = instrumentation._determineHandlerType(result);
76048
76048
  span.setAttributes({
76049
76049
  [AttributeNames5.HONO_TYPE]: type,
76050
- [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path19 : handler.name || "anonymous"
76050
+ [AttributeNames5.HONO_NAME]: type === HonoTypes.REQUEST_HANDLER ? path18 : handler.name || "anonymous"
76051
76051
  });
76052
76052
  instrumentation.getConfig().responseHook?.(span);
76053
76053
  return result;
@@ -76251,11 +76251,11 @@ var KoaInstrumentation = class extends import_instrumentation29.InstrumentationB
76251
76251
  const router = dispatchLayer.router;
76252
76252
  const routesStack = router?.stack ?? [];
76253
76253
  for (const pathLayer of routesStack) {
76254
- const path19 = pathLayer.path;
76254
+ const path18 = pathLayer.path;
76255
76255
  const pathStack = pathLayer.stack;
76256
76256
  for (let j = 0; j < pathStack.length; j++) {
76257
76257
  const routedMiddleware = pathStack[j];
76258
- pathStack[j] = this._patchLayer(routedMiddleware, true, path19);
76258
+ pathStack[j] = this._patchLayer(routedMiddleware, true, path18);
76259
76259
  }
76260
76260
  }
76261
76261
  return dispatchLayer;
@@ -78613,7 +78613,7 @@ function parseStoredCredentials(raw, appEnv) {
78613
78613
  const parsed = storedCredentialsSchema.safeParse(json2);
78614
78614
  if (!parsed.success) {
78615
78615
  throw new InvalidStoredCredentialsError(
78616
- `Stored sync service credentials for ${appEnv} are invalid (corrupted or from an incompatible version) \u2014 re-enroll this machine (powerplant enroll, or pnpm collector enroll from the checkout)`
78616
+ `Stored sync service credentials for ${appEnv} are invalid (corrupted or from an incompatible version), re-enroll this machine (powerplant enroll, or pnpm collector enroll from the checkout)`
78617
78617
  );
78618
78618
  }
78619
78619
  return parsed.data;
@@ -78675,14 +78675,14 @@ function fallbackFile(appEnv) {
78675
78675
 
78676
78676
  // ../../apps/collector/src/enroll.ts
78677
78677
  import { spawn } from "node:child_process";
78678
- import { randomBytes } from "node:crypto";
78678
+ import { createHash, randomBytes } from "node:crypto";
78679
78679
  import http5 from "node:http";
78680
78680
  import os6 from "node:os";
78681
78681
 
78682
78682
  // ../../apps/collector/src/http.ts
78683
78683
  var import_undici = __toESM(require_undici(), 1);
78684
78684
  var CLI_VERSION_HEADER = "x-powerplant-cli-version";
78685
- var cliVersion = true ? "0.4.0" : "0.0.0-checkout";
78685
+ var cliVersion = true ? "0.4.1" : "0.0.0-checkout";
78686
78686
  function cliVersionHeaders() {
78687
78687
  return { [CLI_VERSION_HEADER]: cliVersion, "user-agent": `powerplant-cli/${cliVersion}` };
78688
78688
  }
@@ -78698,11 +78698,11 @@ function installHttp1Transport() {
78698
78698
  }
78699
78699
  async function fetchWithRetry(operation, url2, init3, options = {}) {
78700
78700
  const settled = (status) => status < 500 || status === 503 && options.treat503AsFinal === true;
78701
- const wrapped = (cause) => new Error(`${operation}: couldn't reach ${new URL(url2).host} \u2014 ${describeFetchFailure(cause)}`, {
78701
+ const wrapped = (cause) => new Error(`${operation}: couldn't reach ${new URL(url2).host}, ${describeFetchFailure(cause)}`, {
78702
78702
  cause
78703
78703
  });
78704
78704
  const request2 = withVersionHeader(init3);
78705
- const delaysMs = [250, 1e3];
78705
+ const delaysMs = options.retry === false ? [] : [250, 1e3];
78706
78706
  for (const delayMs of delaysMs) {
78707
78707
  try {
78708
78708
  const response = await fetch(url2, request2);
@@ -78970,7 +78970,7 @@ function describeCapturePolicy(policy) {
78970
78970
  case "scope":
78971
78971
  return `sessions under ${policy.scopePaths.join(", ")}`;
78972
78972
  case "org-repos": {
78973
- const repoPart = policy.allowedRepos !== null ? policy.allowedRepos.length > 0 ? `sessions in the org's allowlisted repos: ${listSome(policy.allowedRepos)}` : "the org's repo allowlist is empty \u2014 no repo-based uploads" : policy.allowedOwners.length > 0 ? `sessions in GitHub repos owned by ${policy.allowedOwners.join(", ")}` : "org-owned GitHub repos \u2014 but the org has no GitHub integration, so nothing uploads";
78973
+ const repoPart = policy.allowedRepos !== null ? policy.allowedRepos.length > 0 ? `sessions in the org's allowlisted repos: ${listSome(policy.allowedRepos)}` : "the org's repo allowlist is empty, no repo-based uploads" : policy.allowedOwners.length > 0 ? `sessions in GitHub repos owned by ${policy.allowedOwners.join(", ")}` : "org-owned GitHub repos, but the org has no GitHub integration, so nothing uploads";
78974
78974
  const claiming = (policy.workspaceClaims ?? []).filter(workspaceClaimsAnyRepo);
78975
78975
  const severalWorkspaces = (policy.workspaceClaims?.length ?? 0) > 1;
78976
78976
  const withOthers = severalWorkspaces && claiming.length > 0 ? `${repoPart}, routing each repo to the workspace that syncs it (${listSome(claiming.map((workspace) => workspace.name))})` : repoPart;
@@ -79272,7 +79272,6 @@ async function uploadRawSessions(apiUrl, machineToken, collected, readTranscript
79272
79272
 
79273
79273
  // ../../apps/collector/src/enroll.ts
79274
79274
  var APPROVAL_TIMEOUT_MS = 5 * 60 * 1e3;
79275
- var MAX_DELIVERY_BYTES = 64 * 1024;
79276
79275
  var gotrueTokenSchema = external_exports.object({ access_token: external_exports.string().min(1) });
79277
79276
  var gotrueErrorSchema = external_exports.object({
79278
79277
  error_description: external_exports.string().optional(),
@@ -79344,7 +79343,7 @@ async function runEnrollment(config2, options) {
79344
79343
  if (config2.appEnv === "development") {
79345
79344
  const home = normalizeScopePath(os6.homedir());
79346
79345
  log3(
79347
- `No GitHub integration on org "${result.org.name}" \u2014 syncing sessions under ${home} (your home folder, local DB only). Re-enroll with --scope <path> to narrow.`
79346
+ `No GitHub integration on org "${result.org.name}", syncing sessions under ${home} (your home folder, local DB only). Re-enroll with --scope <path> to narrow.`
79348
79347
  );
79349
79348
  captureMode = "scope";
79350
79349
  scopePaths = [home];
@@ -79363,7 +79362,7 @@ async function runEnrollment(config2, options) {
79363
79362
  throw new ExpectedCliError(
79364
79363
  [
79365
79364
  `Your org "${result.org.name}" has no GitHub integration yet, so "work = org-owned repos" can't be resolved.`,
79366
- "If that isn't the org you expected, sign in with your work email \u2014 org membership follows the email's domain.",
79365
+ "If that isn't the org you expected, sign in with your work email, org membership follows the email's domain.",
79367
79366
  "Either:",
79368
79367
  ` \xB7 connect GitHub in Settings, then re-run: ${options.enrollCommand}`,
79369
79368
  " \xB7 or choose the upload boundary by hand:",
@@ -79412,24 +79411,73 @@ async function runEnrollment(config2, options) {
79412
79411
  );
79413
79412
  return credentials;
79414
79413
  }
79415
- async function enroll(config2, options, createAuthClient = gotrueAuthClient) {
79414
+ async function enroll(config2, options, createAuthClient = gotrueAuthClient, listener = {}) {
79416
79415
  if (options.email && options.password) {
79417
79416
  return enrollWithPassword(config2, options.name, options.email, options.password, createAuthClient);
79418
79417
  }
79419
79418
  const state = randomBytes(16).toString("base64url");
79419
+ const verifier = randomBytes(32).toString("base64url");
79420
79420
  return waitForApproval(
79421
- enrollApprovalUrl(config2.webUrl, options.name, state, options.capture),
79421
+ enrollApprovalUrl(config2.webUrl, {
79422
+ name: options.name,
79423
+ state,
79424
+ challenge: challengeFor(verifier),
79425
+ capture: options.capture
79426
+ }),
79422
79427
  state,
79423
- { log: options.log }
79428
+ { ...listener, log: options.log, redeem: (code) => redeemApproval(config2.apiUrl, code, verifier) }
79424
79429
  );
79425
79430
  }
79426
- function enrollApprovalUrl(webUrl, name, state, capture) {
79431
+ var challengeFor = (verifier) => createHash("sha256").update(verifier).digest("hex");
79432
+ function enrollApprovalUrl(webUrl, {
79433
+ name,
79434
+ state,
79435
+ challenge,
79436
+ capture
79437
+ }) {
79427
79438
  return `${webUrl}/enroll-machine?${new URLSearchParams({
79428
79439
  name,
79429
79440
  state,
79441
+ challenge,
79430
79442
  ...capture && { capture: capture.mode, folders: String(capture.folderCount) }
79431
79443
  }).toString()}`;
79432
79444
  }
79445
+ async function redeemApproval(apiUrl, code, verifier) {
79446
+ const response = await fetchWithRetry(
79447
+ "redeeming the enrollment approval",
79448
+ `${apiUrl}/api/machines/redeem`,
79449
+ {
79450
+ method: "POST",
79451
+ headers: { "content-type": "application/json" },
79452
+ body: JSON.stringify({ code, verifier })
79453
+ },
79454
+ { retry: false }
79455
+ );
79456
+ if (response.status === 404) {
79457
+ throw new ExpectedCliError(
79458
+ "the API doesn't know how to redeem an enrollment approval yet. It is likely older than this CLI (deploy in progress?). Try again in a minute."
79459
+ );
79460
+ }
79461
+ if (response.status >= 400 && response.status < 500) {
79462
+ const body = await response.json().catch(() => null);
79463
+ throw new ExpectedCliError(`enrollment failed: ${body?.error ?? `the API answered ${response.status}`}`);
79464
+ }
79465
+ return readEnrollmentResponse(response);
79466
+ }
79467
+ async function readEnrollmentResponse(response) {
79468
+ if (response.status !== 201) {
79469
+ const body2 = await response.json().catch(() => null);
79470
+ throw new Error(`enrollment failed (${response.status}): ${body2?.error ?? "no detail"}`);
79471
+ }
79472
+ const body = await response.json().catch(() => null);
79473
+ const enrollment = body?.data;
79474
+ if (!isEnrollResult(enrollment)) {
79475
+ throw new ExpectedCliError(
79476
+ "enrollment answered 201 without the expected machine/org/token. The API is likely older than this CLI (deploy in progress?). Try again in a minute."
79477
+ );
79478
+ }
79479
+ return enrollment;
79480
+ }
79433
79481
  async function enrollWithPassword(config2, name, email3, password, createAuthClient) {
79434
79482
  const client = createAuthClient(config2.supabaseUrl, config2.supabasePublishableKey);
79435
79483
  const { data, error: error52 } = await client.auth.signInWithPassword({ email: email3, password });
@@ -79441,18 +79489,7 @@ async function enrollWithPassword(config2, name, email3, password, createAuthCli
79441
79489
  headers: { authorization: `Bearer ${data.session.access_token}`, "content-type": "application/json" },
79442
79490
  body: JSON.stringify({ name })
79443
79491
  });
79444
- if (response.status !== 201) {
79445
- const body2 = await response.json().catch(() => null);
79446
- throw new Error(`enrollment failed (${response.status}): ${body2?.error ?? "no detail"}`);
79447
- }
79448
- const body = await response.json().catch(() => null);
79449
- const enrollment = body?.data;
79450
- if (!isEnrollResult(enrollment)) {
79451
- throw new ExpectedCliError(
79452
- "enrollment answered 201 without the expected machine/org/token \u2014 the API is likely older than this CLI (deploy in progress?). Try again in a minute."
79453
- );
79454
- }
79455
- return enrollment;
79492
+ return await readEnrollmentResponse(response);
79456
79493
  } finally {
79457
79494
  await client.auth.signOut({ scope: "local" });
79458
79495
  }
@@ -79461,61 +79498,84 @@ function isEnrollResult(value) {
79461
79498
  const candidate = value;
79462
79499
  return typeof candidate?.machine?.id === "string" && typeof candidate.machine.name === "string" && typeof candidate.org?.id === "string" && typeof candidate.org.name === "string" && typeof candidate.token === "string";
79463
79500
  }
79464
- function waitForApproval(approvalUrl, state, options = {}) {
79501
+ function waitForApproval(approvalUrl, state, options) {
79465
79502
  const {
79503
+ redeem,
79466
79504
  port = MACHINE_ENROLL_CALLBACK_PORT,
79467
79505
  open = openBrowser,
79506
+ onListening,
79468
79507
  timeoutMs = APPROVAL_TIMEOUT_MS,
79469
79508
  log: log3 = console.log
79470
79509
  } = options;
79471
79510
  return new Promise((resolve2, reject) => {
79472
79511
  const baseHeaders = { connection: "close" };
79512
+ let redeeming = false;
79473
79513
  const server = http5.createServer((request2, response) => {
79474
- if (request2.method !== "POST" || request2.url !== MACHINE_ENROLL_CALLBACK_PATH) {
79514
+ const url2 = new URL(request2.url ?? "/", "http://127.0.0.1");
79515
+ if (request2.method !== "GET" || url2.pathname !== MACHINE_ENROLL_CALLBACK_PATH) {
79475
79516
  response.writeHead(404, baseHeaders).end();
79476
79517
  return;
79477
79518
  }
79478
79519
  const answer = (status, html, onFlushed) => {
79479
79520
  response.writeHead(status, { ...baseHeaders, "content-type": "text/html; charset=utf-8" }).end(html, onFlushed);
79480
79521
  };
79481
- void readRawBody(request2).then((raw) => {
79482
- const delivery = parseDelivery(raw);
79483
- if (delivery?.state !== state) {
79484
- answer(
79485
- 403,
79486
- approvalAnswerPage(
79487
- "This isn't the enrollment the terminal is waiting for",
79488
- "Go back to the terminal that's waiting, open the link it printed, and approve from there."
79489
- )
79490
- );
79491
- return;
79492
- }
79493
- if (!isEnrollResult(delivery.data)) {
79494
- answer(
79495
- 400,
79496
- approvalAnswerPage(
79497
- "The approval couldn't be read",
79498
- "Close this tab and start over from the terminal."
79499
- )
79500
- );
79501
- return;
79502
- }
79503
- const data = delivery.data;
79522
+ if (url2.searchParams.get("state") !== state) {
79523
+ answer(
79524
+ 403,
79525
+ approvalAnswerPage(
79526
+ "This isn't the enrollment the terminal is waiting for",
79527
+ "Go back to the terminal that's waiting, open the link it printed, and approve from there."
79528
+ )
79529
+ );
79530
+ return;
79531
+ }
79532
+ const code = url2.searchParams.get("code");
79533
+ if (code === null || code === "") {
79504
79534
  answer(
79535
+ 400,
79536
+ approvalAnswerPage(
79537
+ "The approval couldn't be read",
79538
+ "Close this tab and start over from the terminal."
79539
+ )
79540
+ );
79541
+ return;
79542
+ }
79543
+ if (redeeming) {
79544
+ answer(
79545
+ 409,
79546
+ approvalAnswerPage(
79547
+ "This approval is already being handled",
79548
+ "The terminal is finishing this enrollment. You can close this tab."
79549
+ )
79550
+ );
79551
+ return;
79552
+ }
79553
+ redeeming = true;
79554
+ clearTimeout(timeout);
79555
+ void redeem(code).then(
79556
+ (data) => answer(
79505
79557
  200,
79506
79558
  approvalAnswerPage(
79507
79559
  `${data.machine.name} is enrolled in ${data.org.name}`,
79508
79560
  "You can close this tab and return to the terminal."
79509
79561
  ),
79510
79562
  () => finish(() => resolve2(data))
79511
- );
79512
- });
79563
+ ),
79564
+ (cause) => answer(
79565
+ 500,
79566
+ approvalAnswerPage(
79567
+ "The approval couldn't be completed",
79568
+ "Return to the terminal. It says what went wrong and how to retry."
79569
+ ),
79570
+ () => finish(() => reject(cause instanceof Error ? cause : new Error(String(cause))))
79571
+ )
79572
+ );
79513
79573
  });
79514
79574
  const timeout = setTimeout(
79515
79575
  () => finish(
79516
79576
  () => reject(
79517
79577
  new ExpectedCliError(
79518
- "enrollment approval timed out after 5 minutes \u2014 run the same command again to retry"
79578
+ "enrollment approval timed out after 5 minutes, run the same command again to retry"
79519
79579
  )
79520
79580
  )
79521
79581
  ),
@@ -79529,41 +79589,16 @@ function waitForApproval(approvalUrl, state, options = {}) {
79529
79589
  };
79530
79590
  server.once("error", (cause) => finish(() => reject(cause)));
79531
79591
  server.listen(port, "127.0.0.1", () => {
79592
+ const address = server.address();
79593
+ if (onListening && address !== null && typeof address === "object") onListening(address.port);
79532
79594
  log3(`Open approval page: ${approvalUrl}`);
79533
79595
  open(approvalUrl);
79534
79596
  });
79535
79597
  });
79536
79598
  }
79537
- function readRawBody(request2) {
79538
- return new Promise((resolve2) => {
79539
- const chunks = [];
79540
- let size = 0;
79541
- request2.on("data", (chunk) => {
79542
- size += chunk.length;
79543
- if (size > MAX_DELIVERY_BYTES) {
79544
- request2.destroy();
79545
- resolve2(null);
79546
- return;
79547
- }
79548
- chunks.push(chunk);
79549
- });
79550
- request2.on("end", () => resolve2(Buffer.concat(chunks).toString("utf8")));
79551
- request2.on("error", () => resolve2(null));
79552
- });
79553
- }
79554
- function parseDelivery(raw) {
79555
- if (raw === null) return null;
79556
- const fields = new URLSearchParams(raw);
79557
- let data;
79558
- try {
79559
- data = JSON.parse(fields.get("data") ?? "");
79560
- } catch {
79561
- data = void 0;
79562
- }
79563
- return { state: fields.get("state") ?? void 0, data };
79564
- }
79599
+ var PPLOGO_SVG = '<svg width="20" height="20" viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M35.4167 7.5H17.5L3.75 30L17.5 52.5L30 30H17.0833L35.4167 7.5Z" fill="#FFD17A"/><path d="M24.5833 52.5H42.5L56.25 30L42.5 7.5L30 30H42.9167L24.5833 52.5Z" fill="#FFA600"/></svg>';
79565
79600
  function approvalAnswerPage(heading, detail) {
79566
- return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Powerplant</title></head><body style="margin:0;padding:4rem 1.5rem;display:flex;justify-content:center;font-family:system-ui,sans-serif"><main style="max-width:26rem"><h1 style="font-size:1.25rem">${escapeHtml(heading)}</h1><p style="line-height:1.5">${escapeHtml(detail)}</p></main></body></html>`;
79601
+ return `<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Powerplant</title><style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:oklch(98.7% 0.004 250);color:#232422;font-family:"Figtree",system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;-webkit-font-smoothing:antialiased}main{display:flex;flex-direction:column;align-items:center;gap:0.75rem;max-width:24rem;padding:1.5rem;text-align:center}.mark{display:flex;align-items:center;justify-content:center;width:2.5rem;height:2.5rem;border:1px solid oklch(92.5% 0.006 250);border-radius:0.375rem;background:#ffffff}h1{margin:0;font-size:1.25rem;line-height:1.75rem;font-weight:700}p{margin:0;font-size:0.875rem;line-height:1.5;color:#6a6d69}</style></head><body><main><span class="mark">${PPLOGO_SVG}</span><h1>${escapeHtml(heading)}</h1><p>${escapeHtml(detail)}</p></main></body></html>`;
79567
79602
  }
79568
79603
  var escapeHtml = (text) => text.replace(/[&<>"']/g, (character) => `&#${character.charCodeAt(0)};`);
79569
79604
  function openBrowser(url2) {
@@ -79577,7 +79612,7 @@ function requireEnrolled(config2, enrollCommand, deps) {
79577
79612
  const credentials = deps.load(config2.appEnv);
79578
79613
  if (!credentials) {
79579
79614
  throw new ExpectedCliError(
79580
- `This machine isn't enrolled for ${config2.appEnv} \u2014 run: ${enrollCommand}`
79615
+ `This machine isn't enrolled for ${config2.appEnv}, run: ${enrollCommand}`
79581
79616
  );
79582
79617
  }
79583
79618
  return credentials;
@@ -79606,7 +79641,7 @@ function addFolder(config2, rawPath, enrollCommand, log3, deps = defaultDeps) {
79606
79641
  });
79607
79642
  const org = credentials.orgName ?? "your org";
79608
79643
  log3(
79609
- credentials.captureMode === "org-repos" ? `Sessions under ${folder} will now upload to ${org} \u2014 even outside the org's allowlisted repos.` : `Added ${folder} to this machine's sync boundary.`
79644
+ credentials.captureMode === "org-repos" ? `Sessions under ${folder} will now upload to ${org}, even outside the org's allowlisted repos.` : `Added ${folder} to this machine's sync boundary.`
79610
79645
  );
79611
79646
  log3("Takes effect on the next sync pass; run the sync command to apply now.");
79612
79647
  }
@@ -79622,14 +79657,14 @@ function removeFolder(config2, rawPath, enrollCommand, log3, deps = defaultDeps)
79622
79657
  const remaining = folders.filter((existing) => existing !== folder);
79623
79658
  if (credentials.captureMode === "scope" && remaining.length === 0) {
79624
79659
  throw new ExpectedCliError(
79625
- "A --scope enrollment needs at least one folder \u2014 re-enroll to change the sync boundary instead."
79660
+ "A --scope enrollment needs at least one folder, re-enroll to change the sync boundary instead."
79626
79661
  );
79627
79662
  }
79628
79663
  deps.persist(config2.appEnv, {
79629
79664
  ...credentials,
79630
79665
  scopePaths: remaining
79631
79666
  });
79632
- log3(`Removed ${folder} \u2014 sessions there stay local from the next sync pass.`);
79667
+ log3(`Removed ${folder}, sessions there stay local from the next sync pass.`);
79633
79668
  }
79634
79669
 
79635
79670
  // ../../apps/collector/src/protectedRepoDiscovery.ts
@@ -80295,7 +80330,7 @@ async function collectCodexSessions(options = {}) {
80295
80330
  }
80296
80331
 
80297
80332
  // ../../apps/collector/src/cursorLocal.ts
80298
- import { createHash } from "node:crypto";
80333
+ import { createHash as createHash2 } from "node:crypto";
80299
80334
  import { mkdirSync as mkdirSync2, utimesSync, writeFileSync as writeFileSync2 } from "node:fs";
80300
80335
  import os9 from "node:os";
80301
80336
  import path7 from "node:path";
@@ -80364,7 +80399,7 @@ function safeJsonRecord2(text) {
80364
80399
  }
80365
80400
  function spoolFileName(composerId) {
80366
80401
  const sanitized = composerId.replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 80);
80367
- const hash2 = createHash("sha256").update(composerId).digest("hex").slice(0, 8);
80402
+ const hash2 = createHash2("sha256").update(composerId).digest("hex").slice(0, 8);
80368
80403
  return `${sanitized}-${hash2}.jsonl`;
80369
80404
  }
80370
80405
  function workspaceFolderOf(cursorUserDir, workspaceId) {
@@ -80738,7 +80773,7 @@ function allowProtectedRepoDiscovery(config2, found, environment = {}, deps = de
80738
80773
  const credentials = deps.load(config2.appEnv);
80739
80774
  if (credentials === null || credentials.token !== enrollment.token || credentials.enrolledAt !== enrollment.enrolledAt) {
80740
80775
  throw new ExpectedCliError(
80741
- "This machine's enrollment changed while the folders were being reviewed, so the approval was not saved \u2014 run `powerplant init` again to review them."
80776
+ "This machine's enrollment changed while the folders were being reviewed, so the approval was not saved, run `powerplant init` again to review them."
80742
80777
  );
80743
80778
  }
80744
80779
  const allowedProtectedRoots = [
@@ -80754,17 +80789,16 @@ function allowProtectedRepoDiscovery(config2, found, environment = {}, deps = de
80754
80789
  }
80755
80790
 
80756
80791
  // ../../apps/collector/src/hookInstall.ts
80757
- import { existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "node:fs";
80792
+ import { existsSync, mkdirSync as mkdirSync3, readFileSync as readFileSync6, rmSync, writeFileSync as writeFileSync3 } from "node:fs";
80758
80793
  import os11 from "node:os";
80759
80794
  import path9 from "node:path";
80760
80795
  import { fileURLToPath as fileURLToPath2 } from "node:url";
80761
- var INBOX_HOOK_FILENAME = "powerplant-inbox.mjs";
80762
80796
  var LIFECYCLE_HOOK_FILENAME = "powerplant-session-lifecycle.mjs";
80763
80797
  var HOOK_WIRINGS = [
80764
- { event: "UserPromptSubmit", script: INBOX_HOOK_FILENAME },
80765
80798
  { event: "SessionStart", script: LIFECYCLE_HOOK_FILENAME },
80766
80799
  { event: "SessionEnd", script: LIFECYCLE_HOOK_FILENAME }
80767
80800
  ];
80801
+ var RETIRED_HOOK_WIRINGS = [{ event: "UserPromptSubmit", script: "powerplant-inbox.mjs" }];
80768
80802
  var HOOK_SCRIPTS = [...new Set(HOOK_WIRINGS.map((wiring) => wiring.script))];
80769
80803
  function isOurGroup(group, script) {
80770
80804
  return Array.isArray(group.hooks) && group.hooks.some((hook) => typeof hook.command === "string" && hook.command.includes(script));
@@ -80785,9 +80819,10 @@ function mergeCollectorHooks(settingsText, commandFor) {
80785
80819
  }
80786
80820
  }
80787
80821
  const hooks = settings.hooks !== null && typeof settings.hooks === "object" && !Array.isArray(settings.hooks) ? { ...settings.hooks } : {};
80822
+ const groupsOf = (event) => Array.isArray(hooks[event]) ? hooks[event] : [];
80788
80823
  let changed = false;
80789
80824
  for (const wiring of HOOK_WIRINGS) {
80790
- const groups = Array.isArray(hooks[wiring.event]) ? hooks[wiring.event] : [];
80825
+ const groups = groupsOf(wiring.event);
80791
80826
  const ourGroup = {
80792
80827
  hooks: [{ type: "command", command: commandFor(wiring.script), timeout: 5 }]
80793
80828
  };
@@ -80796,6 +80831,14 @@ function mergeCollectorHooks(settingsText, commandFor) {
80796
80831
  hooks[wiring.event] = [...groups.filter((group) => !isOurGroup(group, wiring.script)), ourGroup];
80797
80832
  changed = true;
80798
80833
  }
80834
+ for (const retired of RETIRED_HOOK_WIRINGS) {
80835
+ const groups = groupsOf(retired.event);
80836
+ const kept = groups.filter((group) => !isOurGroup(group, retired.script));
80837
+ if (kept.length === groups.length) continue;
80838
+ if (kept.length === 0) delete hooks[retired.event];
80839
+ else hooks[retired.event] = kept;
80840
+ changed = true;
80841
+ }
80799
80842
  if (!changed) return { action: "unchanged" };
80800
80843
  const next = { ...settings, hooks };
80801
80844
  return { action: "write", text: `${JSON.stringify(next, null, 2)}
@@ -80833,6 +80876,11 @@ function installCollectorHooks(homeDir = os11.homedir()) {
80833
80876
  mkdirSync3(settingsDir, { recursive: true });
80834
80877
  writeFileSync3(settingsPath, merged.text);
80835
80878
  }
80879
+ if (merged.action !== "skip") {
80880
+ for (const retired of RETIRED_HOOK_WIRINGS) {
80881
+ rmSync(path9.join(hookDir, retired.script), { force: true });
80882
+ }
80883
+ }
80836
80884
  return {
80837
80885
  hookDir,
80838
80886
  settings: merged.action,
@@ -80842,7 +80890,7 @@ function installCollectorHooks(homeDir = os11.homedir()) {
80842
80890
 
80843
80891
  // ../../apps/collector/src/service.ts
80844
80892
  import { execFileSync as execFileSync3 } from "node:child_process";
80845
- import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync7, rmSync, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
80893
+ import { chmodSync as chmodSync2, existsSync as existsSync2, mkdirSync as mkdirSync4, readFileSync as readFileSync7, rmSync as rmSync2, unlinkSync as unlinkSync2, writeFileSync as writeFileSync4 } from "node:fs";
80846
80894
  import os12 from "node:os";
80847
80895
  import path10 from "node:path";
80848
80896
  var RESTART_THROTTLE_SECONDS = 60;
@@ -80873,7 +80921,7 @@ function refuseStaleAppEnvLauncher(env, readLauncher = readLauncherIfExists) {
80873
80921
  const script = readLauncher(launcherPath(appEnv));
80874
80922
  if (script === null || !script.includes("APP_ENV=") || script.includes("POWERPLANT_ENV=")) return;
80875
80923
  throw new ExpectedCliError(
80876
- `This background service was installed before the POWERPLANT_ENV rename and is no longer supported. Remove it with: powerplant uninstall --env ${appEnv}` + (appEnv === "production" ? " \u2014 then powerplant init reinstalls it." : ` \u2014 then powerplant init --env ${appEnv} reinstalls it if you still need it.`)
80924
+ `This background service was installed before the POWERPLANT_ENV rename and is no longer supported. Remove it with: powerplant uninstall --env ${appEnv}` + (appEnv === "production" ? ", then powerplant init reinstalls it." : `, then powerplant init --env ${appEnv} reinstalls it if you still need it.`)
80877
80925
  );
80878
80926
  }
80879
80927
  function readLauncherIfExists(launcherFile) {
@@ -80918,7 +80966,7 @@ function installService(config2, command) {
80918
80966
  if (!waitForUnload(() => isLoaded(config2.appEnv))) {
80919
80967
  const service = `gui/${uid()}/${label(config2.appEnv)}`;
80920
80968
  throw new Error(
80921
- `launchd is still unloading ${label(config2.appEnv)} after ${UNLOAD_WAIT_MS / 1e3}s \u2014 re-run powerplant init, or unload it by hand first: launchctl bootout ${service}`
80969
+ `launchd is still unloading ${label(config2.appEnv)} after ${UNLOAD_WAIT_MS / 1e3}s, re-run powerplant init, or unload it by hand first: launchctl bootout ${service}`
80922
80970
  );
80923
80971
  }
80924
80972
  const launcher = launcherPath(config2.appEnv);
@@ -80964,7 +81012,7 @@ function serviceUpToDate(config2, command) {
80964
81012
  function uninstallService(config2) {
80965
81013
  requireMacos();
80966
81014
  const existed = bootout(config2.appEnv);
80967
- rmSync(launcherPath(config2.appEnv), { force: true });
81015
+ rmSync2(launcherPath(config2.appEnv), { force: true });
80968
81016
  if (existsSync2(plistPath(config2.appEnv))) {
80969
81017
  unlinkSync2(plistPath(config2.appEnv));
80970
81018
  return true;
@@ -81034,7 +81082,7 @@ function xmlEscape(value) {
81034
81082
  }
81035
81083
 
81036
81084
  // ../../apps/collector/src/status.ts
81037
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, renameSync, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "node:fs";
81085
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, renameSync, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
81038
81086
  import os13 from "node:os";
81039
81087
  import path11 from "node:path";
81040
81088
  var HEARTBEAT_INTERVAL_MS = 6e4;
@@ -81137,10 +81185,10 @@ function writeCollectorControl(appEnv, control, homeDir) {
81137
81185
  writeAtomically(controlFilePath(appEnv, homeDir), JSON.stringify(control, null, 2));
81138
81186
  }
81139
81187
  function clearCollectorControl(appEnv, homeDir) {
81140
- rmSync2(controlFilePath(appEnv, homeDir), { force: true });
81188
+ rmSync3(controlFilePath(appEnv, homeDir), { force: true });
81141
81189
  }
81142
81190
  function clearCollectorStatus(appEnv, homeDir) {
81143
- rmSync2(statusFilePath(appEnv, homeDir), { force: true });
81191
+ rmSync3(statusFilePath(appEnv, homeDir), { force: true });
81144
81192
  }
81145
81193
  function describeDaemonState(read, probes = {}) {
81146
81194
  if (read.file === "invalid") return { state: "unreadable" };
@@ -81360,14 +81408,14 @@ async function resolveCapturePolicy(config2, credentials, log3, deps = defaultPo
81360
81408
  claimsUnresolved = true;
81361
81409
  }
81362
81410
  log3(
81363
- `\u26A0 Couldn't refresh the org's repo sync policy (${describeSyncError(cause)}) \u2014 ` + (cachedCoversSomething ? "using the cached policy." : "nothing will upload this pass.")
81411
+ `\u26A0 Couldn't refresh the org's repo sync policy (${describeSyncError(cause)}), ` + (cachedCoversSomething ? "using the cached policy." : "nothing will upload this pass.")
81364
81412
  );
81365
81413
  }
81366
81414
  const memberFolders = credentials.scopePaths ?? [];
81367
81415
  if (ownersUnresolved && owners.length === 0 && repos === null) claimsUnresolved = true;
81368
81416
  if (ownersUnresolved) {
81369
81417
  log3(
81370
- "\u26A0 The org's GitHub is connected, but its account couldn't be resolved just now \u2014 " + (owners.length > 0 ? `using the cached owner list: ${owners.join(", ")}.` : "no owner-based uploads this pass. This is usually temporary; syncing resumes when it resolves.")
81418
+ "\u26A0 The org's GitHub is connected, but its account couldn't be resolved just now, " + (owners.length > 0 ? `using the cached owner list: ${owners.join(", ")}.` : "no owner-based uploads this pass. This is usually temporary; syncing resumes when it resolves.")
81371
81419
  );
81372
81420
  }
81373
81421
  const homeOrgId = credentials.orgId ?? workspacePolicies?.[0]?.orgId;
@@ -81376,11 +81424,11 @@ async function resolveCapturePolicy(config2, credentials, log3, deps = defaultPo
81376
81424
  );
81377
81425
  if (repos !== null && repos.length === 0) {
81378
81426
  log3(
81379
- "\u26A0 The org's repo allowlist is empty \u2014 no repo-based uploads for it" + (foreignClaims.length > 0 ? `; repos synced by ${foreignClaims.map((entry) => entry.name).join(", ")} still upload.` : memberFolders.length > 0 ? "; only folders you added upload." : ".")
81427
+ "\u26A0 The org's repo allowlist is empty, no repo-based uploads for it" + (foreignClaims.length > 0 ? `; repos synced by ${foreignClaims.map((entry) => entry.name).join(", ")} still upload.` : memberFolders.length > 0 ? "; only folders you added upload." : ".")
81380
81428
  );
81381
81429
  } else if (repos === null && owners.length === 0 && !ownersUnresolved) {
81382
81430
  log3(
81383
- foreignClaims.length > 0 ? `Your home workspace has no GitHub integration \u2014 syncing repos for ${foreignClaims.map((entry) => entry.name).join(", ")}.` : "\u26A0 Syncing is gated on org-owned GitHub repos, but the org has no GitHub integration \u2014 nothing uploads. Connect GitHub in Settings, or add folders with `powerplant folders add`."
81431
+ foreignClaims.length > 0 ? `Your home workspace has no GitHub integration, syncing repos for ${foreignClaims.map((entry) => entry.name).join(", ")}.` : "\u26A0 Syncing is gated on org-owned GitHub repos, but the org has no GitHub integration, nothing uploads. Connect GitHub in Settings, or add folders with `powerplant folders add`."
81384
81432
  );
81385
81433
  }
81386
81434
  return {
@@ -81399,13 +81447,13 @@ async function runSyncPass(config2, options = {}) {
81399
81447
  const credentials = loadCredentials(config2.appEnv);
81400
81448
  if (!credentials) {
81401
81449
  throw new ExpectedCliError(
81402
- `This machine isn't enrolled for ${config2.appEnv} \u2014 run: ${options.enrollCommand ?? "pnpm collector enroll"}`
81450
+ `This machine isn't enrolled for ${config2.appEnv}, run: ${options.enrollCommand ?? "pnpm collector enroll"}`
81403
81451
  );
81404
81452
  }
81405
81453
  const window2 = resolveSyncWindow(options.explicitSince, credentials.deepSyncedAt);
81406
81454
  if (window2.deepSweep) {
81407
81455
  log3(
81408
- `First sync for this enrollment \u2014 sweeping the last ${window2.days} days and backfilling up to the ${DEEP_FIRST_SYNC_MAX_SESSIONS} most recently active sessions already on this machine (later syncs cover ${STEADY_SYNC_WINDOW_DAYS} days).`
81456
+ `First sync for this enrollment, sweeping the last ${window2.days} days and backfilling up to the ${DEEP_FIRST_SYNC_MAX_SESSIONS} most recently active sessions already on this machine (later syncs cover ${STEADY_SYNC_WINDOW_DAYS} days).`
81409
81457
  );
81410
81458
  }
81411
81459
  const capture = await resolveCapturePolicy(config2, credentials, log3);
@@ -81415,7 +81463,7 @@ async function runSyncPass(config2, options = {}) {
81415
81463
  const codex = await collectCodexSessions({ sinceMs, capture, maxSessions });
81416
81464
  const cursor = await collectCursorSessions({ sinceMs, capture });
81417
81465
  if (cursor.unavailable !== null) {
81418
- log3(`\u26A0 Cursor sessions skipped this pass \u2014 ${cursor.unavailable}. Other syncing is unaffected.`);
81466
+ log3(`\u26A0 Cursor sessions skipped this pass, ${cursor.unavailable}. Other syncing is unaffected.`);
81419
81467
  }
81420
81468
  const inWindow = [...claude.sessions, ...codex.sessions, ...cursor.sessions].sort(
81421
81469
  (a, b2) => b2.mtimeMs - a.mtimeMs
@@ -81426,41 +81474,41 @@ async function runSyncPass(config2, options = {}) {
81426
81474
  const skippedNoRepo = claude.skippedNoRepo + codex.skippedNoRepo + cursor.skippedNoRepo;
81427
81475
  const items = collected.map((c) => c.item);
81428
81476
  const active = items.filter((s) => s.status === "active").length;
81429
- const tooLarge = (count, what) => count > 0 ? ` \xB7 ${count} ${what} skipped (over ${MAX_TRANSCRIPT_FILE_BYTES / (1024 * 1024)}MB \u2014 too large to read)` : "";
81477
+ const tooLarge = (count, what) => count > 0 ? ` \xB7 ${count} ${what} skipped (over ${MAX_TRANSCRIPT_FILE_BYTES / (1024 * 1024)}MB, too large to read)` : "";
81430
81478
  log3(
81431
- `Found ${inWindow.length} local session(s) (${claude.sessions.length} claude, ${codex.sessions.length} codex, ${cursor.sessions.length} cursor) ` + describeScanReach(window2, options.narrowSinceMs) + (active > 0 ? ` (${active} still active)` : "") + (skippedOutOfScope > 0 ? ` \xB7 ${skippedOutOfScope} ${describeSkipReason(capture)}` : "") + (skippedNoRepo > 0 ? ` \xB7 ${skippedNoRepo} ${describeNoRepoSkipReason(capture)}` : "") + (codex.skippedSubagentThreads > 0 ? ` \xB7 ${codex.skippedSubagentThreads} codex subagent thread(s) skipped (spend unmeasured)` : "") + (cursor.skippedSubagentComposers > 0 ? ` \xB7 ${cursor.skippedSubagentComposers} cursor subagent thread(s) skipped` : "") + (cursor.skippedNonLocalComposers > 0 ? ` \xB7 ${cursor.skippedNonLocalComposers} cursor session(s) skipped (not local to this machine)` : "") + (cursor.skippedUnreadable > 0 ? ` \xB7 ${cursor.skippedUnreadable} cursor session(s) unreadable, skipped` : "") + tooLarge(claude.skippedTooLarge, "claude transcript(s)") + (claude.unreadable.length > 0 ? ` \xB7 ${claude.unreadable.length} claude transcript(s) unreadable, skipped` : "") + tooLarge(codex.skippedTooLarge, "codex rollout(s)") + (codex.unreadable.length > 0 ? ` \xB7 ${codex.unreadable.length} codex rollout(s) unreadable, skipped` : "") + tooLarge(cursor.skippedTooLarge, "cursor transcript(s)") + (cursor.truncatedTranscripts > 0 ? ` \xB7 ${cursor.truncatedTranscripts} cursor transcript(s) cut at ${MAX_TRANSCRIPT_FILE_BYTES / (1024 * 1024)}MB (the rest of the conversation stays local)` : "") + (heldBack > 0 ? ` \xB7 ${heldBack} older session(s) held back \u2014 the first sync backfills the ${DEEP_FIRST_SYNC_MAX_SESSIONS} most recently active` : "") + "."
81479
+ `Found ${inWindow.length} local session(s) (${claude.sessions.length} claude, ${codex.sessions.length} codex, ${cursor.sessions.length} cursor) ` + describeScanReach(window2, options.narrowSinceMs) + (active > 0 ? ` (${active} still active)` : "") + (skippedOutOfScope > 0 ? ` \xB7 ${skippedOutOfScope} ${describeSkipReason(capture)}` : "") + (skippedNoRepo > 0 ? ` \xB7 ${skippedNoRepo} ${describeNoRepoSkipReason(capture)}` : "") + (codex.skippedSubagentThreads > 0 ? ` \xB7 ${codex.skippedSubagentThreads} codex subagent thread(s) skipped (spend unmeasured)` : "") + (cursor.skippedSubagentComposers > 0 ? ` \xB7 ${cursor.skippedSubagentComposers} cursor subagent thread(s) skipped` : "") + (cursor.skippedNonLocalComposers > 0 ? ` \xB7 ${cursor.skippedNonLocalComposers} cursor session(s) skipped (not local to this machine)` : "") + (cursor.skippedUnreadable > 0 ? ` \xB7 ${cursor.skippedUnreadable} cursor session(s) unreadable, skipped` : "") + tooLarge(claude.skippedTooLarge, "claude transcript(s)") + (claude.unreadable.length > 0 ? ` \xB7 ${claude.unreadable.length} claude transcript(s) unreadable, skipped` : "") + tooLarge(codex.skippedTooLarge, "codex rollout(s)") + (codex.unreadable.length > 0 ? ` \xB7 ${codex.unreadable.length} codex rollout(s) unreadable, skipped` : "") + tooLarge(cursor.skippedTooLarge, "cursor transcript(s)") + (cursor.truncatedTranscripts > 0 ? ` \xB7 ${cursor.truncatedTranscripts} cursor transcript(s) cut at ${MAX_TRANSCRIPT_FILE_BYTES / (1024 * 1024)}MB (the rest of the conversation stays local)` : "") + (heldBack > 0 ? ` \xB7 ${heldBack} older session(s) held back, the first sync backfills the ${DEEP_FIRST_SYNC_MAX_SESSIONS} most recently active` : "") + "."
81432
81480
  );
81433
- for (const failure of claude.unreadable) log3(` claude transcript skipped \u2014 ${failure}`);
81434
- for (const failure of codex.unreadable) log3(` codex rollout skipped \u2014 ${failure}`);
81481
+ for (const failure of claude.unreadable) log3(` claude transcript skipped, ${failure}`);
81482
+ for (const failure of codex.unreadable) log3(` codex rollout skipped, ${failure}`);
81435
81483
  if (options.dryRun) {
81436
81484
  for (const s of items.slice(0, 10)) {
81437
81485
  log3(` ${s.externalId} ${s.model ?? "model unmeasured"} ${s.title ?? "(untitled)"}`);
81438
81486
  }
81439
81487
  if (items.length > 10) log3(` ... and ${items.length - 10} more`);
81440
- log3("Dry run \u2014 nothing uploaded.");
81488
+ log3("Dry run, nothing uploaded.");
81441
81489
  return { sessions: collected, upserted: 0 };
81442
81490
  }
81443
81491
  const markDeepSynced = () => {
81444
81492
  if (!window2.deepSweep) return;
81445
81493
  const current = loadCredentials(config2.appEnv);
81446
81494
  if (current === null) {
81447
- log3("Deep sync finished, but this machine's credentials are gone \u2014 nothing to stamp.");
81495
+ log3("Deep sync finished, but this machine's credentials are gone, nothing to stamp.");
81448
81496
  return;
81449
81497
  }
81450
81498
  if (current.token !== credentials.token || current.enrolledAt !== credentials.enrolledAt) {
81451
81499
  log3(
81452
- "Deep sync finished for a superseded enrollment \u2014 the current enrollment still owes its own deep sweep."
81500
+ "Deep sync finished for a superseded enrollment, the current enrollment still owes its own deep sweep."
81453
81501
  );
81454
81502
  return;
81455
81503
  }
81456
81504
  saveCredentials(config2.appEnv, { ...current, deepSyncedAt: (/* @__PURE__ */ new Date()).toISOString() });
81457
- log3(`Deep sync complete \u2014 future syncs cover the last ${STEADY_SYNC_WINDOW_DAYS} days.`);
81505
+ log3(`Deep sync complete, future syncs cover the last ${STEADY_SYNC_WINDOW_DAYS} days.`);
81458
81506
  };
81459
81507
  const claimsUnresolved = capture.mode === "org-repos" && capture.claimsUnresolved === true;
81460
81508
  if (items.length === 0) {
81461
81509
  if (claimsUnresolved) {
81462
81510
  if (window2.deepSweep) {
81463
- log3("Deep sync not stamped \u2014 a workspace's claims are unresolved; the sweep re-runs next pass.");
81511
+ log3("Deep sync not stamped, a workspace's claims are unresolved; the sweep re-runs next pass.");
81464
81512
  }
81465
81513
  } else {
81466
81514
  markDeepSynced();
@@ -81477,12 +81525,12 @@ async function runSyncPass(config2, options = {}) {
81477
81525
  );
81478
81526
  if (deferred > 0) {
81479
81527
  log3(
81480
- `\u26A0 ${deferred} session(s) deferred \u2014 a workspace's GitHub owners couldn't be resolved just now, so routing waited rather than guessing a workspace. They upload on a later pass.`
81528
+ `\u26A0 ${deferred} session(s) deferred, a workspace's GitHub owners couldn't be resolved just now, so routing waited rather than guessing a workspace. They upload on a later pass.`
81481
81529
  );
81482
81530
  }
81483
81531
  if (outOfPolicy > 0) {
81484
81532
  log3(
81485
- `\u26A0 ${outOfPolicy} session(s) refused by the org's repo sync policy \u2014 they stayed out of Powerplant. The next pass refreshes the policy and stops offering them.`
81533
+ `\u26A0 ${outOfPolicy} session(s) refused by the org's repo sync policy, they stayed out of Powerplant. The next pass refreshes the policy and stops offering them.`
81486
81534
  );
81487
81535
  }
81488
81536
  const registerPreviews = options.registerPreviews ?? registerAnnouncedPreviews;
@@ -81497,13 +81545,13 @@ async function runSyncPass(config2, options = {}) {
81497
81545
  }
81498
81546
  for (const externalId of previewSummary.foreignOwned) {
81499
81547
  log3(
81500
- `Previews for ${externalId} are registered by another machine \u2014 leaving its list in place.`
81548
+ `Previews for ${externalId} are registered by another machine, leaving its list in place.`
81501
81549
  );
81502
81550
  }
81503
81551
  for (const externalId of previewSummary.previewsOff) {
81504
- log3(`Previews for ${externalId} refused \u2014 this organization has previews switched off.`);
81552
+ log3(`Previews for ${externalId} refused, this organization has previews switched off.`);
81505
81553
  }
81506
- for (const failure of previewSummary.failed) log3(` preview registration failed \u2014 ${failure}`);
81554
+ for (const failure of previewSummary.failed) log3(` preview registration failed, ${failure}`);
81507
81555
  try {
81508
81556
  const observe = options.observeBranch ? options.observeBranch() : branchObserver({ allowedProtectedRoots: credentials.repoDiscoveryRoots ?? [] });
81509
81557
  const facts = branchFactsOf(collected, observe);
@@ -81513,7 +81561,7 @@ async function runSyncPass(config2, options = {}) {
81513
81561
  log3(`Branch facts: ${recorded} branch state(s) recorded.`);
81514
81562
  }
81515
81563
  } catch (cause) {
81516
- log3(`\u26A0 Branch facts skipped this pass \u2014 ${describeSyncError(cause)}`);
81564
+ log3(`\u26A0 Branch facts skipped this pass, ${describeSyncError(cause)}`);
81517
81565
  }
81518
81566
  const rawFloor = rawShipFloorMs(config2.appEnv, Date.now(), options.explicitSince);
81519
81567
  const rawEligible = rawFloor === null ? collected : collected.filter((c) => c.mtimeMs >= rawFloor);
@@ -81526,7 +81574,7 @@ async function runSyncPass(config2, options = {}) {
81526
81574
  options.rawShipped
81527
81575
  );
81528
81576
  if (raw.unconfigured) {
81529
- log3("Raw content: this environment has no raw storage yet \u2014 skipped.");
81577
+ log3("Raw content: this environment has no raw storage yet, skipped.");
81530
81578
  } else {
81531
81579
  const parts = [`${raw.uploaded} uploaded`];
81532
81580
  if (raw.skippedUnchanged > 0) parts.push(`${raw.skippedUnchanged} unchanged`);
@@ -81534,20 +81582,20 @@ async function runSyncPass(config2, options = {}) {
81534
81582
  if (raw.skippedTooLarge > 0) parts.push(`${raw.skippedTooLarge} skipped (too large)`);
81535
81583
  if (raw.failed.length > 0) parts.push(`${raw.failed.length} failed`);
81536
81584
  log3(`Raw content: ${parts.join(", ")}.`);
81537
- for (const failure of raw.failed) log3(` raw upload failed \u2014 ${failure}`);
81585
+ for (const failure of raw.failed) log3(` raw upload failed, ${failure}`);
81538
81586
  if (raw.missingMetadata > 0) {
81539
81587
  log3(
81540
- `${raw.missingMetadata} raw transcript(s) waiting on their session metadata \u2014 they re-send once it lands.`
81588
+ `${raw.missingMetadata} raw transcript(s) waiting on their session metadata, they re-send once it lands.`
81541
81589
  );
81542
81590
  }
81543
81591
  const nothingElseAccountedFor = raw.skippedUnchanged === 0 && raw.skippedTooLarge === 0 && rawWindowSkipped === 0 && raw.missingMetadata === 0;
81544
81592
  if (raw.uploaded === 0 && (raw.failed.length > 1 || raw.failed.length === 1 && nothingElseAccountedFor)) {
81545
- throw new Error(`all ${raw.failed.length} raw upload(s) failed this pass \u2014 ${raw.failed[0]}`);
81593
+ throw new Error(`all ${raw.failed.length} raw upload(s) failed this pass, ${raw.failed[0]}`);
81546
81594
  }
81547
81595
  if (deferred > 0 || claimsUnresolved) {
81548
81596
  if (window2.deepSweep) {
81549
81597
  log3(
81550
- deferred > 0 ? "Deep sync not stamped \u2014 deferred sessions still owe their upload; the sweep re-runs next pass." : "Deep sync not stamped \u2014 a workspace's claims are unresolved; the sweep re-runs next pass."
81598
+ deferred > 0 ? "Deep sync not stamped, deferred sessions still owe their upload; the sweep re-runs next pass." : "Deep sync not stamped, a workspace's claims are unresolved; the sweep re-runs next pass."
81551
81599
  );
81552
81600
  }
81553
81601
  } else {
@@ -81589,300 +81637,9 @@ function unsupportedVersionNotice(cliVersion2, oldestSupportedVersion) {
81589
81637
  }
81590
81638
 
81591
81639
  // ../../apps/collector/src/watch.ts
81592
- import { existsSync as existsSync4, watch as fsWatch } from "node:fs";
81640
+ import { existsSync as existsSync3, watch as fsWatch } from "node:fs";
81593
81641
  import os14 from "node:os";
81594
- import path14 from "node:path";
81595
-
81596
- // ../../apps/collector/src/wake.ts
81597
- import { execFile as execFile2, execFileSync as execFileSync4 } from "node:child_process";
81598
- import { existsSync as existsSync3 } from "node:fs";
81599
81642
  import path13 from "node:path";
81600
- var WAKE_POLL_MS = 5e3;
81601
- var WAKE_QUIET_MS = 2 * 6e4;
81602
- var WAKE_TURN_TIMEOUT_MS = 10 * 6e4;
81603
- var FETCH_TIMEOUT_MS2 = 5e3;
81604
- function findClaudeTranscript(homeDir, externalId) {
81605
- for (const projectDir of listDirs(path13.join(homeDir, ".claude", "projects"))) {
81606
- const transcript = path13.join(projectDir, `${externalId}.jsonl`);
81607
- const stat = statIfExists(transcript);
81608
- if (stat === null) continue;
81609
- const record2 = readFirstRecord(
81610
- transcript,
81611
- (candidate) => typeof candidate.cwd === "string" && candidate.cwd !== ""
81612
- );
81613
- return typeof record2?.cwd === "string" ? { cwd: record2.cwd, mtimeMs: stat.mtimeMs } : null;
81614
- }
81615
- return null;
81616
- }
81617
- function formatWakePrompt(messages) {
81618
- const lines = messages.map(
81619
- (message) => `- From ${message.authorEmail ?? "a teammate"} (sent ${message.createdAt}): ${message.body}`
81620
- );
81621
- return [
81622
- `While this session was idle, ${messages.length === 1 ? "a teammate sent a message" : `teammates sent ${messages.length} messages`} to it via Powerplant:`,
81623
- ...lines,
81624
- "This prompt was submitted automatically by Powerplant's message delivery \u2014 no one is at the keyboard. Acknowledge the message and act on it as an instruction from that teammate."
81625
- ].join("\n");
81626
- }
81627
- function createWakePoller(deps) {
81628
- const inFlight = /* @__PURE__ */ new Set();
81629
- let polling = false;
81630
- let consecutivePollFailures = 0;
81631
- return {
81632
- async poll() {
81633
- if (polling) return;
81634
- polling = true;
81635
- try {
81636
- for (const target of await deps.listPending()) {
81637
- if (inFlight.has(target.externalId)) continue;
81638
- const home = inspectTarget(deps, target);
81639
- if (home === null) continue;
81640
- if (deps.now() - home.mtimeMs < WAKE_QUIET_MS) continue;
81641
- const messages = await deps.claim(target);
81642
- if (messages.length === 0) continue;
81643
- inFlight.add(target.externalId);
81644
- deps.log(
81645
- `waking session ${target.externalId} with ${messages.length} message(s) in ${home.cwd}`
81646
- );
81647
- void deps.runClaude(target, formatWakePrompt(messages), home.cwd).then(() => deps.log(`wake finished for session ${target.externalId}`)).catch(
81648
- (error52) => reportFailedWake(deps, target, messages, describeError(error52))
81649
- ).finally(() => inFlight.delete(target.externalId));
81650
- }
81651
- consecutivePollFailures = 0;
81652
- } catch (error52) {
81653
- consecutivePollFailures += 1;
81654
- deps.log(`\u26A0 wake poll failed (${describeError(error52)}) \u2014 next poll retries`);
81655
- if (consecutivePollFailures === REPORT_AFTER_CONSECUTIVE_FAILURES) {
81656
- deps.reportError?.(error52, "wake-poll", { consecutivePollFailures });
81657
- }
81658
- } finally {
81659
- polling = false;
81660
- }
81661
- }
81662
- };
81663
- }
81664
- function inspectTarget(deps, target) {
81665
- try {
81666
- return deps.inspect(target);
81667
- } catch (error52) {
81668
- deps.log(
81669
- `\u26A0 wake skipped for session ${target.externalId} \u2014 its transcript could not be read (${describeError(error52)}); next poll retries`
81670
- );
81671
- return null;
81672
- }
81673
- }
81674
- async function reportFailedWake(deps, target, messages, reason) {
81675
- deps.log(
81676
- `\u26A0 wake failed for session ${target.externalId} AFTER its messages were claimed (${reason})`
81677
- );
81678
- const messageIds = messages.flatMap((message) => message.id === null ? [] : [message.id]);
81679
- try {
81680
- await deps.reportWakeFailure(target, messageIds, reason);
81681
- deps.log(
81682
- `wake failure reported for session ${target.externalId} \u2014 its ${messageIds.length} message(s) now read "Not delivered"`
81683
- );
81684
- } catch (reportError) {
81685
- deps.log(
81686
- `\u26A0 wake failure report for session ${target.externalId} ALSO failed \u2014 its messages read Delivered but no agent ran (${describeError(reportError)})`
81687
- );
81688
- deps.reportError?.(reportError, "wake-failure-report", {
81689
- externalId: target.externalId,
81690
- messageCount: messageIds.length
81691
- });
81692
- }
81693
- }
81694
- function resolveClaudeBin(homeDir, env = process.env) {
81695
- if (env.POWERPLANT_CLAUDE_BIN) {
81696
- return existsSync3(env.POWERPLANT_CLAUDE_BIN) ? env.POWERPLANT_CLAUDE_BIN : null;
81697
- }
81698
- const candidates = [
81699
- path13.join(homeDir, ".local", "bin", "claude"),
81700
- "/opt/homebrew/bin/claude",
81701
- "/usr/local/bin/claude"
81702
- ];
81703
- const found = candidates.find((candidate) => existsSync3(candidate));
81704
- if (found) return found;
81705
- try {
81706
- const fromPath = execFileSync4("which", ["claude"], { stdio: ["ignore", "pipe", "ignore"] }).toString().trim();
81707
- return fromPath === "" ? null : fromPath;
81708
- } catch {
81709
- return null;
81710
- }
81711
- }
81712
- var WAKE_MIN_CLAUDE_VERSION = "2.1.0";
81713
- var VERSION_TIMEOUT_MS = 15e3;
81714
- function versionParts(version2) {
81715
- return version2.split(".").map(Number);
81716
- }
81717
- function versionAtLeast(version2, floor) {
81718
- const have = versionParts(version2);
81719
- const need = versionParts(floor);
81720
- for (let i = 0; i < need.length; i += 1) {
81721
- const a = have[i] ?? 0;
81722
- const b2 = need[i] ?? 0;
81723
- if (a !== b2) return a > b2;
81724
- }
81725
- return true;
81726
- }
81727
- function execClaudeVersion(claudeBin) {
81728
- return execFileSync4(claudeBin, ["--version"], {
81729
- stdio: ["ignore", "pipe", "ignore"],
81730
- timeout: VERSION_TIMEOUT_MS
81731
- }).toString();
81732
- }
81733
- function preflightClaudeVersion(claudeBin, readVersionOutput = execClaudeVersion) {
81734
- let output;
81735
- try {
81736
- output = readVersionOutput(claudeBin);
81737
- } catch (error52) {
81738
- return { ok: false, problem: `\`${claudeBin} --version\` failed (${describeError(error52)})` };
81739
- }
81740
- const version2 = /\d+\.\d+\.\d+/.exec(output)?.[0] ?? null;
81741
- if (version2 === null) {
81742
- return {
81743
- ok: false,
81744
- problem: `\`${claudeBin} --version\` answered "${output.trim()}" \u2014 no version in that`
81745
- };
81746
- }
81747
- if (!versionAtLeast(version2, WAKE_MIN_CLAUDE_VERSION)) {
81748
- return {
81749
- ok: false,
81750
- problem: `claude ${version2} is older than ${WAKE_MIN_CLAUDE_VERSION} \u2014 too old to headlessly resume current transcripts (it hangs until the wake timeout)`
81751
- };
81752
- }
81753
- return { ok: true, version: version2 };
81754
- }
81755
- async function collectorApiList(credentials, pathAndQuery, key) {
81756
- const response = await fetch(`${credentials.apiUrl}${pathAndQuery}`, {
81757
- headers: { authorization: `Bearer ${credentials.token}`, ...cliVersionHeaders() },
81758
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
81759
- });
81760
- const route = pathAndQuery.split("?")[0];
81761
- if (!response.ok) throw new Error(`${route} answered ${response.status}`);
81762
- const envelope = external_exports.object({ data: external_exports.record(external_exports.string(), external_exports.unknown()) }).safeParse(await response.json().catch(() => null));
81763
- if (!envelope.success) {
81764
- throw new Error(`${route} answered an unexpected shape: ${zodIssueSummary(envelope.error)}`, {
81765
- cause: envelope.error
81766
- });
81767
- }
81768
- const list = envelope.data.data[key];
81769
- if (!Array.isArray(list)) {
81770
- throw new Error(`${route} answered an unexpected shape: data.${key} is not a list`);
81771
- }
81772
- const values = list;
81773
- return values;
81774
- }
81775
- var wakeTargetSchema = external_exports.object({ source: external_exports.string().min(1), externalId: external_exports.string().min(1) });
81776
- async function fetchWakePending(credentials) {
81777
- const sessions = await collectorApiList(credentials, "/api/collector/wake-pending", "sessions");
81778
- return sessions.flatMap((entry) => {
81779
- const parsed = wakeTargetSchema.safeParse(entry);
81780
- return parsed.success ? [{ source: parsed.data.source, externalId: parsed.data.externalId }] : [];
81781
- });
81782
- }
81783
- var wakeMessageSchema = external_exports.object({
81784
- id: external_exports.string().nullable().catch(null),
81785
- authorEmail: external_exports.string().nullable().catch(null),
81786
- body: external_exports.string(),
81787
- createdAt: external_exports.string().catch("")
81788
- });
81789
- async function claimInbox(credentials, target) {
81790
- const messages = await collectorApiList(
81791
- credentials,
81792
- `/api/collector/inbox?source=${encodeURIComponent(target.source)}&externalId=${encodeURIComponent(target.externalId)}`,
81793
- "messages"
81794
- );
81795
- return messages.flatMap((entry) => {
81796
- const parsed = wakeMessageSchema.safeParse(entry);
81797
- return parsed.success ? [parsed.data] : [];
81798
- });
81799
- }
81800
- async function postWakeFailure(credentials, target, messageIds, reason) {
81801
- const response = await fetchWithRetry(
81802
- "reporting a failed wake",
81803
- `${credentials.apiUrl}/api/collector/wake-failed`,
81804
- {
81805
- method: "POST",
81806
- headers: {
81807
- authorization: `Bearer ${credentials.token}`,
81808
- "content-type": "application/json"
81809
- },
81810
- body: JSON.stringify({
81811
- source: target.source,
81812
- externalId: target.externalId,
81813
- messageIds,
81814
- reason
81815
- })
81816
- }
81817
- );
81818
- if (!response.ok) throw new Error(`/api/collector/wake-failed answered ${response.status}`);
81819
- }
81820
- function runClaudeResume(claudeBin, externalId, prompt, cwd) {
81821
- return new Promise((resolve2, reject) => {
81822
- const child = execFile2(
81823
- claudeBin,
81824
- ["-p", "--resume", externalId, prompt],
81825
- { cwd, timeout: WAKE_TURN_TIMEOUT_MS, maxBuffer: 16 * 1024 * 1024 },
81826
- (error52, _stdout, stderr) => error52 ? reject(new Error(describeWakeTurnFailure(error52, stderr))) : resolve2()
81827
- );
81828
- child.stdin?.end();
81829
- });
81830
- }
81831
- var STDERR_TAIL_CHARS = 300;
81832
- function describeWakeTurnFailure(error52, stderr) {
81833
- const tail = redactText(stderr.trim()).slice(-STDERR_TAIL_CHARS);
81834
- const base = baseWakeTurnReason(error52);
81835
- return tail === "" ? base : `${base} \u2014 stderr: ${tail}`;
81836
- }
81837
- function baseWakeTurnReason(error52) {
81838
- if (error52.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER") return error52.message;
81839
- if (error52.killed) {
81840
- return `wake turn killed after ${WAKE_TURN_TIMEOUT_MS / 6e4} minutes \u2014 the resumed claude turn never finished`;
81841
- }
81842
- if (typeof error52.code === "number") return `claude exited with code ${error52.code}`;
81843
- if (error52.signal) return `claude died on signal ${error52.signal}`;
81844
- return error52.message;
81845
- }
81846
- function startWakeService(config2, homeDir, log3) {
81847
- if (process.env.POWERPLANT_WAKE_ON_MESSAGE === "0") {
81848
- log3("wake-on-message disabled (POWERPLANT_WAKE_ON_MESSAGE=0)");
81849
- return null;
81850
- }
81851
- const credentials = loadCredentials(config2.appEnv);
81852
- if (credentials === null) {
81853
- log3("wake-on-message off: machine not enrolled");
81854
- return null;
81855
- }
81856
- const claudeBin = resolveClaudeBin(homeDir);
81857
- if (claudeBin === null) {
81858
- log3("wake-on-message off: claude CLI not found (set POWERPLANT_CLAUDE_BIN)");
81859
- return null;
81860
- }
81861
- const preflight = preflightClaudeVersion(claudeBin);
81862
- if (!preflight.ok) {
81863
- log3(
81864
- `wake-on-message off: ${preflight.problem} \u2014 update Claude Code (npm install -g @anthropic-ai/claude-code) or point POWERPLANT_CLAUDE_BIN at a ${WAKE_MIN_CLAUDE_VERSION}+ CLI, then restart the sync service to re-arm wake`
81865
- );
81866
- return null;
81867
- }
81868
- log3(`wake-on-message claude binary: ${claudeBin} (version ${preflight.version})`);
81869
- const poller = createWakePoller({
81870
- listPending: () => fetchWakePending(credentials),
81871
- claim: (target) => claimInbox(credentials, target),
81872
- inspect: (target) => findClaudeTranscript(homeDir, target.externalId),
81873
- runClaude: (target, prompt, cwd) => runClaudeResume(claudeBin, target.externalId, prompt, cwd),
81874
- reportWakeFailure: (target, messageIds, reason) => postWakeFailure(credentials, target, messageIds, reason),
81875
- now: Date.now,
81876
- log: log3,
81877
- reportError: reportCollectorError
81878
- });
81879
- const timer = setInterval(() => void poller.poll(), WAKE_POLL_MS);
81880
- log3(`wake-on-message armed: polling every ${WAKE_POLL_MS / 1e3}s (${config2.appEnv})`);
81881
- return () => clearInterval(timer);
81882
- }
81883
- function describeError(error52) {
81884
- return error52 instanceof Error ? error52.message : String(error52);
81885
- }
81886
81643
 
81887
81644
  // ../../apps/collector/src/selfRestart.ts
81888
81645
  import { statSync as statSync3 } from "node:fs";
@@ -81964,7 +81721,7 @@ function createWatchLoop(deps) {
81964
81721
  if (stopped) return;
81965
81722
  try {
81966
81723
  closeWatcher = deps.watch(onEvent, (error52) => {
81967
- deps.log(`watcher lost (${describeError2(error52)}) \u2014 re-arming and re-scanning`);
81724
+ deps.log(`watcher lost (${describeError(error52)}), re-arming and re-scanning`);
81968
81725
  closeWatcher?.();
81969
81726
  closeWatcher = null;
81970
81727
  arm();
@@ -81972,7 +81729,7 @@ function createWatchLoop(deps) {
81972
81729
  });
81973
81730
  } catch (error52) {
81974
81731
  deps.log(
81975
- `cannot watch yet (${describeError2(error52)}) \u2014 retrying in ${WATCHER_RETRY_MS / 1e3}s`
81732
+ `cannot watch yet (${describeError(error52)}), retrying in ${WATCHER_RETRY_MS / 1e3}s`
81976
81733
  );
81977
81734
  watcherRetry = setTimeout(arm, WATCHER_RETRY_MS);
81978
81735
  }
@@ -81981,7 +81738,7 @@ function createWatchLoop(deps) {
81981
81738
  if (stopped) return;
81982
81739
  if (deps.paused?.()) {
81983
81740
  if (!pausedLogged) {
81984
- deps.log("syncing paused \u2014 skipping sync passes until resumed");
81741
+ deps.log("syncing paused, skipping sync passes until resumed");
81985
81742
  pausedLogged = true;
81986
81743
  }
81987
81744
  return;
@@ -82059,11 +81816,11 @@ function createWatchLoop(deps) {
82059
81816
  kind,
82060
81817
  at: startedAt,
82061
81818
  ok: false,
82062
- error: describeError2(error52),
81819
+ error: describeError(error52),
82063
81820
  sessions: 0,
82064
81821
  upserted: 0
82065
81822
  });
82066
- const failLine = `${kind} pass failed (${describeError2(error52)})`;
81823
+ const failLine = `${kind} pass failed (${describeError(error52)})`;
82067
81824
  deps.log(
82068
81825
  streakCount > 1 ? `${failLine}: same failure ${streakCount} times in a row, next attempt in ${describeDelay(holdMs)}` : `${failLine}, next attempt in ${describeDelay(holdMs)} re-covers this window`
82069
81826
  );
@@ -82073,7 +81830,7 @@ function createWatchLoop(deps) {
82073
81830
  if (isPoisonedHttp2Session(error52)) {
82074
81831
  deps.reportError?.(error52, `watch-pass-${kind}-poisoned-pool`);
82075
81832
  deps.fatal?.(
82076
- "connection pool poisoned by a destroyed HTTP/2 session \u2014 exiting so the service restarts clean"
81833
+ "connection pool poisoned by a destroyed HTTP/2 session, exiting so the service restarts clean"
82077
81834
  );
82078
81835
  return;
82079
81836
  }
@@ -82137,7 +81894,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82137
81894
  const home = homeDir ?? os14.homedir();
82138
81895
  process.on("uncaughtException", (error52) => {
82139
81896
  console.error(
82140
- `${(/* @__PURE__ */ new Date()).toISOString()} \u26A0 uncaught exception \u2014 exiting for a clean restart`,
81897
+ `${(/* @__PURE__ */ new Date()).toISOString()} \u26A0 uncaught exception, exiting for a clean restart`,
82141
81898
  error52
82142
81899
  );
82143
81900
  reportCollectorError(error52, "watch-uncaught-exception");
@@ -82145,16 +81902,16 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82145
81902
  });
82146
81903
  process.on("unhandledRejection", (reason) => {
82147
81904
  console.error(
82148
- `${(/* @__PURE__ */ new Date()).toISOString()} \u26A0 unhandled rejection \u2014 exiting for a clean restart`,
81905
+ `${(/* @__PURE__ */ new Date()).toISOString()} \u26A0 unhandled rejection, exiting for a clean restart`,
82149
81906
  reason
82150
81907
  );
82151
81908
  reportCollectorError(reason, "watch-unhandled-rejection");
82152
81909
  void flushReporting().then(() => process.exit(1));
82153
81910
  });
82154
81911
  const storeRoots = [
82155
- { dir: path14.join(home, ".claude", "projects"), recursive: true },
82156
- { dir: path14.join(home, ".codex", "sessions"), recursive: true },
82157
- { dir: path14.join(home, ".codex", "archived_sessions"), recursive: true },
81912
+ { dir: path13.join(home, ".claude", "projects"), recursive: true },
81913
+ { dir: path13.join(home, ".codex", "sessions"), recursive: true },
81914
+ { dir: path13.join(home, ".codex", "archived_sessions"), recursive: true },
82158
81915
  // Cursor keeps every local session in one SQLite store here; its WAL
82159
81916
  // file changes on session writes, so a non-recursive watch on the
82160
81917
  // directory is the freshness signal. Cursor's own unrelated writes to
@@ -82162,7 +81919,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82162
81919
  { dir: cursorGlobalStorageDir(home), recursive: false }
82163
81920
  ];
82164
81921
  const lifecycleRoot = {
82165
- dir: path14.join(home, ".config", "powerplant"),
81922
+ dir: path13.join(home, ".config", "powerplant"),
82166
81923
  recursive: false,
82167
81924
  lifecycle: true
82168
81925
  };
@@ -82171,7 +81928,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82171
81928
  try {
82172
81929
  return loadCredentials(config2.appEnv);
82173
81930
  } catch (error52) {
82174
- log3(`\u26A0 credential store unreadable (${describeError2(error52)}) \u2014 identity omitted from status`);
81931
+ log3(`\u26A0 credential store unreadable (${describeError(error52)}), identity omitted from status`);
82175
81932
  return null;
82176
81933
  }
82177
81934
  })();
@@ -82181,21 +81938,15 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82181
81938
  try {
82182
81939
  const hook = installCollectorHooks(home);
82183
81940
  log3(
82184
- hook.settings === "skip" ? `\u26A0 Claude Code hooks not wired: ${hook.detail ?? "settings.json unusable"} \u2014 fix ~/.claude/settings.json and restart` : `Claude Code hooks ${hook.settings === "write" ? "installed" : "current"} at ${hook.hookDir} (new Claude sessions pick them up)`
81941
+ hook.settings === "skip" ? `\u26A0 Claude Code hooks not wired: ${hook.detail ?? "settings.json unusable"}, fix ~/.claude/settings.json and restart` : `Claude Code hooks ${hook.settings === "write" ? "installed" : "current"} at ${hook.hookDir} (new Claude sessions pick them up)`
82185
81942
  );
82186
81943
  } catch (error52) {
82187
81944
  log3(
82188
- `\u26A0 Claude Code hook install failed (${describeError2(error52)}) \u2014 syncing continues without them`
81945
+ `\u26A0 Claude Code hook install failed (${describeError(error52)}), syncing continues without them`
82189
81946
  );
82190
81947
  reportCollectorError(error52, "watch-hook-install");
82191
81948
  }
82192
- try {
82193
- startWakeService(config2, home, log3);
82194
- } catch (error52) {
82195
- log3(`\u26A0 wake-on-message failed to start (${describeError2(error52)}) \u2014 syncing continues`);
82196
- reportCollectorError(error52, "watch-wake-start");
82197
- }
82198
- const presentRoots = storeRoots.filter(({ dir }) => existsSync4(dir)).map(({ dir }) => dir);
81949
+ const presentRoots = storeRoots.filter(({ dir }) => existsSync3(dir)).map(({ dir }) => dir);
82199
81950
  const initialControl = readCollectorControl(config2.appEnv, home);
82200
81951
  const pausedAtMs = initialControl.paused ? Date.parse(initialControl.pausedAt ?? "") : Number.NaN;
82201
81952
  let status = {
@@ -82223,7 +81974,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82223
81974
  statusWriteFailed = false;
82224
81975
  } catch (error52) {
82225
81976
  if (!statusWriteFailed) {
82226
- log3(`\u26A0 status file write failed (${describeError2(error52)}) \u2014 syncing continues`);
81977
+ log3(`\u26A0 status file write failed (${describeError(error52)}), syncing continues`);
82227
81978
  reportCollectorError(error52, "watch-status-write");
82228
81979
  }
82229
81980
  statusWriteFailed = true;
@@ -82277,7 +82028,7 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82277
82028
  },
82278
82029
  ...Number.isFinite(pausedAtMs) && { initialCoveredSinceMs: pausedAtMs },
82279
82030
  watch: (onEvent, onLost) => {
82280
- const present = armableWatchRoots(storeRoots, lifecycleRoot, existsSync4);
82031
+ const present = armableWatchRoots(storeRoots, lifecycleRoot, existsSync3);
82281
82032
  if (present === null) throw new Error(`no session stores found under ${home}`);
82282
82033
  log3(
82283
82034
  `watching ${present.map(({ dir }) => dir).join(" + ")} for session changes (${config2.appEnv})`
@@ -82314,14 +82065,14 @@ function startWatch(config2, homeDir, runtime = { version: "checkout" }) {
82314
82065
  controlPoll.unref?.();
82315
82066
  if (runtime.entryPath) {
82316
82067
  watchEntryForUpdate(runtime.entryPath, (detail) => {
82317
- log3(`${detail} \u2014 exiting so the service restarts on the new version`);
82068
+ log3(`${detail}, exiting so the service restarts on the new version`);
82318
82069
  void flushReporting().then(() => process.exit(1));
82319
82070
  });
82320
82071
  }
82321
82072
  return new Promise(() => {
82322
82073
  });
82323
82074
  }
82324
- function describeError2(error52) {
82075
+ function describeError(error52) {
82325
82076
  return error52 instanceof Error ? error52.message : String(error52);
82326
82077
  }
82327
82078
  function errorSignature(error52) {
@@ -82338,9 +82089,9 @@ function describeDelay(ms) {
82338
82089
  }
82339
82090
 
82340
82091
  // src/connect.ts
82341
- import { execFileSync as execFileSync5, spawnSync } from "node:child_process";
82092
+ import { execFileSync as execFileSync4, spawnSync } from "node:child_process";
82342
82093
  import {
82343
- existsSync as existsSync5,
82094
+ existsSync as existsSync4,
82344
82095
  mkdirSync as mkdirSync6,
82345
82096
  mkdtempSync,
82346
82097
  readdirSync as readdirSync2,
@@ -82350,7 +82101,7 @@ import {
82350
82101
  writeFileSync as writeFileSync6
82351
82102
  } from "node:fs";
82352
82103
  import os15 from "node:os";
82353
- import path15 from "node:path";
82104
+ import path14 from "node:path";
82354
82105
  import { emitKeypressEvents } from "node:readline";
82355
82106
  var MCP_SERVER_NAME = "powerplant";
82356
82107
  var AGENT_DISPLAY_NAMES = {
@@ -82364,7 +82115,7 @@ function parseClientFilter(values) {
82364
82115
  for (const value of values) {
82365
82116
  if (value === "claude" || value === "claude-code") filter.add("claude");
82366
82117
  else if (value === "codex" || value === "cursor") filter.add(value);
82367
- else throw new ExpectedCliError(`Unknown --client "${value}" \u2014 one of: claude, codex, cursor`);
82118
+ else throw new ExpectedCliError(`Unknown --client "${value}", one of: claude, codex, cursor`);
82368
82119
  }
82369
82120
  return filter;
82370
82121
  }
@@ -82388,7 +82139,7 @@ function detectClients(options = {}) {
82388
82139
  const homeDir = options.homeDir ?? os15.homedir();
82389
82140
  const whichAll = options.whichAll ?? defaultWhichAll;
82390
82141
  const env = options.env ?? process.env;
82391
- const applicationsDirs = options.applicationsDirs ?? (process.platform === "darwin" ? ["/Applications", path15.join(homeDir, "Applications")] : []);
82142
+ const applicationsDirs = options.applicationsDirs ?? (process.platform === "darwin" ? ["/Applications", path14.join(homeDir, "Applications")] : []);
82392
82143
  const bundleSeams = {
82393
82144
  readBundleInfo: options.readBundleInfo ?? realReadBundleInfo,
82394
82145
  verifySignature: options.verifySignature ?? realVerifySignature,
@@ -82410,20 +82161,20 @@ function detectClients(options = {}) {
82410
82161
  clients.push({ client, bin, ...configDir !== void 0 && { configDir } });
82411
82162
  };
82412
82163
  for (const bin of whichAll("claude")) add("claude", bin);
82413
- const localClaude = path15.join(homeDir, ".local", "bin", "claude");
82414
- if (existsSync5(localClaude)) add("claude", localClaude);
82164
+ const localClaude = path14.join(homeDir, ".local", "bin", "claude");
82165
+ if (existsSync4(localClaude)) add("claude", localClaude);
82415
82166
  for (const bin of desktopClaudeBinaries(homeDir)) add("claude", bin);
82416
82167
  const claudeBins = clients.filter((client) => client.client === "claude" && client.configDir === void 0).map((client) => client.bin);
82417
82168
  for (const configDir of claudeConfigHomes(homeDir, env)) {
82418
82169
  for (const bin of claudeBins) add("claude", bin, configDir);
82419
82170
  }
82420
82171
  for (const bin of whichAll("codex")) add("codex", bin);
82421
- const localCodex = path15.join(homeDir, ".local", "bin", "codex");
82422
- if (existsSync5(localCodex)) add("codex", localCodex);
82172
+ const localCodex = path14.join(homeDir, ".local", "bin", "codex");
82173
+ if (existsSync4(localCodex)) add("codex", localCodex);
82423
82174
  for (const bin of codexBundleBinaries(applicationsDirs, bundleSeams)) add("codex", bin);
82424
- const cursorDir = path15.join(homeDir, ".cursor");
82425
- if (existsSync5(cursorDir) || cursorAppInstalled(applicationsDirs, bundleSeams)) {
82426
- clients.push({ client: "cursor", bin: path15.join(cursorDir, "mcp.json") });
82175
+ const cursorDir = path14.join(homeDir, ".cursor");
82176
+ if (existsSync4(cursorDir) || cursorAppInstalled(applicationsDirs, bundleSeams)) {
82177
+ clients.push({ client: "cursor", bin: path14.join(cursorDir, "mcp.json") });
82427
82178
  }
82428
82179
  return clients;
82429
82180
  }
@@ -82431,7 +82182,7 @@ function claudeConfigHomes(homeDir, env) {
82431
82182
  const homes = [];
82432
82183
  const seen = /* @__PURE__ */ new Set();
82433
82184
  try {
82434
- seen.add(realpathSync(path15.join(homeDir, ".claude")));
82185
+ seen.add(realpathSync(path14.join(homeDir, ".claude")));
82435
82186
  } catch {
82436
82187
  }
82437
82188
  const add = (configDir) => {
@@ -82443,7 +82194,7 @@ function claudeConfigHomes(homeDir, env) {
82443
82194
  }
82444
82195
  if (seen.has(real)) return;
82445
82196
  seen.add(real);
82446
- homes.push(path15.resolve(configDir));
82197
+ homes.push(path14.resolve(configDir));
82447
82198
  };
82448
82199
  let entries = [];
82449
82200
  try {
@@ -82451,8 +82202,8 @@ function claudeConfigHomes(homeDir, env) {
82451
82202
  } catch {
82452
82203
  }
82453
82204
  for (const entry of entries.sort()) {
82454
- if (entry.startsWith(".claude-") && existsSync5(path15.join(homeDir, entry, ".claude.json"))) {
82455
- add(path15.join(homeDir, entry));
82205
+ if (entry.startsWith(".claude-") && existsSync4(path14.join(homeDir, entry, ".claude.json"))) {
82206
+ add(path14.join(homeDir, entry));
82456
82207
  }
82457
82208
  }
82458
82209
  if (env.CLAUDE_CONFIG_DIR) add(env.CLAUDE_CONFIG_DIR);
@@ -82463,7 +82214,7 @@ var CODESIGN_TIMEOUT_MS = 1e4;
82463
82214
  function budgetedTimeout(capMs, appDir, seams) {
82464
82215
  const remaining = seams.budget.remainingMs();
82465
82216
  if (remaining <= 0) {
82466
- seams.warn(`Skipping ${appDir} \u2014 out of time to verify app bundles this run.`);
82217
+ seams.warn(`Skipping ${appDir}, out of time to verify app bundles this run.`);
82467
82218
  return null;
82468
82219
  }
82469
82220
  return Math.min(capMs, remaining);
@@ -82480,7 +82231,7 @@ function appBundles(applicationsDirs, namePrefixes) {
82480
82231
  for (const entry of entries) {
82481
82232
  if (!entry.endsWith(".app")) continue;
82482
82233
  if (!namePrefixes.some((prefix) => entry.startsWith(prefix))) continue;
82483
- bundles.push(path15.join(dir, entry));
82234
+ bundles.push(path14.join(dir, entry));
82484
82235
  }
82485
82236
  }
82486
82237
  return bundles;
@@ -82490,7 +82241,7 @@ function signedByTeam(binPath, teamId, vendor, appDir, seams) {
82490
82241
  if (timeoutMs === null) return false;
82491
82242
  if (seams.verifySignature(binPath, teamId, timeoutMs)) return true;
82492
82243
  seams.warn(
82493
- `Skipping ${appDir} \u2014 its bundled binary is not verifiably signed by ${vendor} (the Apple-anchored signature check failed).`
82244
+ `Skipping ${appDir}, its bundled binary is not verifiably signed by ${vendor} (the Apple-anchored signature check failed).`
82494
82245
  );
82495
82246
  return false;
82496
82247
  }
@@ -82500,7 +82251,7 @@ function codexBundleBinaries(applicationsDirs, seams) {
82500
82251
  const infoTimeoutMs = budgetedTimeout(BUNDLE_INFO_TIMEOUT_MS, appDir, seams);
82501
82252
  if (infoTimeoutMs === null) continue;
82502
82253
  if (seams.readBundleInfo(appDir, infoTimeoutMs)?.bundleId !== CODEX_BUNDLE_ID) continue;
82503
- const bin = path15.join(appDir, "Contents", "Resources", "codex");
82254
+ const bin = path14.join(appDir, "Contents", "Resources", "codex");
82504
82255
  if (!isExecutableFile(bin)) continue;
82505
82256
  if (!signedByTeam(bin, OPENAI_TEAM_ID, "OpenAI", appDir, seams)) continue;
82506
82257
  found.push(bin);
@@ -82513,7 +82264,7 @@ function cursorAppInstalled(applicationsDirs, seams) {
82513
82264
  if (infoTimeoutMs === null) continue;
82514
82265
  const executable = seams.readBundleInfo(appDir, infoTimeoutMs)?.executable;
82515
82266
  if (executable === void 0) continue;
82516
- const bin = path15.join(appDir, "Contents", "MacOS", executable);
82267
+ const bin = path14.join(appDir, "Contents", "MacOS", executable);
82517
82268
  if (!isExecutableFile(bin)) continue;
82518
82269
  if (!signedByTeam(bin, CURSOR_TEAM_ID, "Cursor", appDir, seams)) continue;
82519
82270
  return true;
@@ -82535,7 +82286,7 @@ var bundleInfoSchema = external_exports.object({
82535
82286
  function realReadBundleInfo(appDir, timeoutMs) {
82536
82287
  const result = spawnSync(
82537
82288
  "plutil",
82538
- ["-convert", "json", "-o", "-", path15.join(appDir, "Contents", "Info.plist")],
82289
+ ["-convert", "json", "-o", "-", path14.join(appDir, "Contents", "Info.plist")],
82539
82290
  { encoding: "utf8", timeout: timeoutMs }
82540
82291
  );
82541
82292
  if (result.status !== 0) return null;
@@ -82553,18 +82304,18 @@ function realVerifySignature(binPath, teamId, timeoutMs) {
82553
82304
  }).status === 0;
82554
82305
  }
82555
82306
  function desktopClaudeBinaries(homeDir) {
82556
- const root = path15.join(homeDir, "Library", "Application Support", "Claude", "claude-code");
82307
+ const root = path14.join(homeDir, "Library", "Application Support", "Claude", "claude-code");
82557
82308
  let versions;
82558
82309
  try {
82559
82310
  versions = readdirSync2(root);
82560
82311
  } catch {
82561
82312
  return [];
82562
82313
  }
82563
- return versions.map((version2) => path15.join(root, version2, "claude.app", "Contents", "MacOS", "claude")).filter((bin) => existsSync5(bin));
82314
+ return versions.map((version2) => path14.join(root, version2, "claude.app", "Contents", "MacOS", "claude")).filter((bin) => existsSync4(bin));
82564
82315
  }
82565
82316
  function defaultWhichAll(name) {
82566
82317
  try {
82567
- return execFileSync5("which", ["-a", name], { encoding: "utf8" }).split("\n").map((line) => line.trim()).filter(Boolean);
82318
+ return execFileSync4("which", ["-a", name], { encoding: "utf8" }).split("\n").map((line) => line.trim()).filter(Boolean);
82568
82319
  } catch {
82569
82320
  return [];
82570
82321
  }
@@ -82581,7 +82332,7 @@ function runConnect(clients, deps) {
82581
82332
  failed: 0
82582
82333
  };
82583
82334
  if (clients.length === 0) {
82584
- deps.log("No coding agents found (looked for `claude`, `codex`, and Cursor) \u2014 nothing to connect.");
82335
+ deps.log("No coding agents found (looked for `claude`, `codex`, and Cursor), nothing to connect.");
82585
82336
  return outcome;
82586
82337
  }
82587
82338
  for (const [agent, candidates] of agents) {
@@ -82767,30 +82518,30 @@ function connectClaude(client, name, deps) {
82767
82518
  const env = claudeEnv(client);
82768
82519
  const probe = parseClaudeProbe(deps.run(bin, ["mcp", "get", MCP_SERVER_NAME], env));
82769
82520
  if (probe.broken) {
82770
- deps.log(`\u2717 ${name}: probing for the Powerplant MCP failed \u2014 ${probe.detail}`);
82521
+ deps.log(`\u2717 ${name}: probing for the Powerplant MCP failed, ${probe.detail}`);
82771
82522
  return { state: "failed", unchanged: false };
82772
82523
  }
82773
82524
  const { missing, registeredUrl } = probe;
82774
82525
  if (missing || registeredUrl !== void 0 && registeredUrl !== deps.mcpUrl) {
82775
82526
  if (!missing) {
82776
- deps.log(`${name}: registered against ${registeredUrl} \u2014 re-registering for ${deps.mcpUrl}.`);
82527
+ deps.log(`${name}: registered against ${registeredUrl}, re-registering for ${deps.mcpUrl}.`);
82777
82528
  deps.run(bin, ["mcp", "remove", "--scope", "user", MCP_SERVER_NAME], env);
82778
82529
  }
82779
82530
  const add = deps.run(bin, claudeAddArgs(deps), env);
82780
82531
  if (add.status !== 0) {
82781
- deps.log(`\u2717 ${name}: registering the Powerplant MCP failed \u2014 ${describeFailure(add)}`);
82532
+ deps.log(`\u2717 ${name}: registering the Powerplant MCP failed, ${describeFailure(add)}`);
82782
82533
  return { state: "failed", unchanged: false };
82783
82534
  }
82784
82535
  deps.log(`${name}: Powerplant MCP registered (user scope).`);
82785
82536
  } else if (probe.authenticated) {
82786
- deps.log(`\u2713 ${name} already connected`);
82537
+ deps.log(`\u2713 ${name} MCP already connected`);
82787
82538
  return { state: "connected", unchanged: true };
82788
82539
  } else if (deps.officialClients?.["claude-code"]) {
82789
82540
  deps.log(`${name}: re-registering with the pre-registered client before sign-in.`);
82790
82541
  deps.run(bin, ["mcp", "remove", "--scope", "user", MCP_SERVER_NAME], env);
82791
82542
  const add = deps.run(bin, claudeAddArgs(deps), env);
82792
82543
  if (add.status !== 0) {
82793
- deps.log(`\u2717 ${name}: registering the Powerplant MCP failed \u2014 ${describeFailure(add)}`);
82544
+ deps.log(`\u2717 ${name}: registering the Powerplant MCP failed, ${describeFailure(add)}`);
82794
82545
  return { state: "failed", unchanged: false };
82795
82546
  }
82796
82547
  } else {
@@ -82967,7 +82718,7 @@ function parseCodexProbe(result) {
82967
82718
  if (result.status !== 0) {
82968
82719
  return {
82969
82720
  broken: true,
82970
- detail: `listing MCP servers failed \u2014 ${describeFailure(result)}`,
82721
+ detail: `listing MCP servers failed, ${describeFailure(result)}`,
82971
82722
  missing: false,
82972
82723
  authenticated: false
82973
82724
  };
@@ -82976,7 +82727,7 @@ function parseCodexProbe(result) {
82976
82727
  if (servers === null) {
82977
82728
  return {
82978
82729
  broken: true,
82979
- detail: "could not read its MCP server list \u2014 is this codex version very old?",
82730
+ detail: "could not read its MCP server list, is this codex version very old?",
82980
82731
  missing: false,
82981
82732
  authenticated: false
82982
82733
  };
@@ -83014,7 +82765,7 @@ function healOrphanCodexOauthTable(name, deps) {
83014
82765
  if (!changed) return;
83015
82766
  deps.writeTextFile(deps.codexConfigPath, content);
83016
82767
  deps.log(
83017
- `${name}: removed leftover sign-in settings from an interrupted setup \u2014 codex can read its configuration again.`
82768
+ `${name}: removed leftover sign-in settings from an interrupted setup, codex can read its configuration again.`
83018
82769
  );
83019
82770
  }
83020
82771
  function connectCodex(bin, name, deps) {
@@ -83028,7 +82779,7 @@ function connectCodex(bin, name, deps) {
83028
82779
  const wrongUrl = registeredUrl !== void 0 && registeredUrl !== deps.mcpUrl;
83029
82780
  const alreadyConnected = !missing && !wrongUrl && probe.authenticated;
83030
82781
  if (missing || wrongUrl) {
83031
- if (wrongUrl) deps.log(`${name}: registered against ${registeredUrl} \u2014 re-registering for ${deps.mcpUrl}.`);
82782
+ if (wrongUrl) deps.log(`${name}: registered against ${registeredUrl}, re-registering for ${deps.mcpUrl}.`);
83032
82783
  if (codexAddLogsIn(bin, deps)) {
83033
82784
  ensureCodexCallbackPort(name, deps);
83034
82785
  const outcome = login(bin, name, codexAddArgs(deps, { withOfficialClientId: true }), deps);
@@ -83037,12 +82788,12 @@ function connectCodex(bin, name, deps) {
83037
82788
  }
83038
82789
  const add = deps.run(bin, codexAddArgs(deps, { withOfficialClientId: false }));
83039
82790
  if (add.status !== 0) {
83040
- deps.log(`\u2717 ${name}: registering the Powerplant MCP failed \u2014 ${describeFailure(add)}`);
82791
+ deps.log(`\u2717 ${name}: registering the Powerplant MCP failed, ${describeFailure(add)}`);
83041
82792
  return { state: "failed", unchanged: false };
83042
82793
  }
83043
82794
  deps.log(`${name}: Powerplant MCP registered.`);
83044
82795
  } else if (alreadyConnected) {
83045
- deps.log(`\u2713 ${name} already connected`);
82796
+ deps.log(`\u2713 ${name} MCP already connected`);
83046
82797
  } else {
83047
82798
  deps.log(`${name}: Powerplant MCP already registered.`);
83048
82799
  }
@@ -83053,7 +82804,7 @@ function connectCodex(bin, name, deps) {
83053
82804
  function applyCodexConfigPatch(name, deps, patch, successLine) {
83054
82805
  if (patch.conflict !== void 0) {
83055
82806
  deps.log(
83056
- `${name}: ${patch.conflict} \u2014 sign-in may fail until the port conflict is resolved; then re-run ${deps.connectCommand}.`
82807
+ `${name}: ${patch.conflict}, sign-in may fail until the port conflict is resolved; then re-run ${deps.connectCommand}.`
83057
82808
  );
83058
82809
  return;
83059
82810
  }
@@ -83097,18 +82848,18 @@ function connectCursor(mcpJsonPath, name, deps) {
83097
82848
  );
83098
82849
  if (patch.error !== void 0 || patch.entry === void 0) {
83099
82850
  deps.log(
83100
- `\u2717 ${name}: ${mcpJsonPath.replace(os15.homedir(), "~")} is ${patch.error} \u2014 fix it by hand, then re-run ${deps.connectCommand}.`
82851
+ `\u2717 ${name}: ${mcpJsonPath.replace(os15.homedir(), "~")} is ${patch.error}, fix it by hand, then re-run ${deps.connectCommand}.`
83101
82852
  );
83102
82853
  return { state: "failed", unchanged: false };
83103
82854
  }
83104
82855
  if (patch.changed) deps.writeTextFile(mcpJsonPath, patch.content);
83105
82856
  const configured = patch.changed ? "configured" : "already configured";
83106
82857
  if (deps.openUrl(cursorInstallDeeplink(MCP_SERVER_NAME, patch.entry))) {
83107
- deps.log(`\u2192 ${name} ${configured} \u2014 approve inside Cursor when it asks.`);
82858
+ deps.log(`\u2192 ${name} ${configured}, approve inside Cursor when it asks.`);
83108
82859
  return { state: "configured", unchanged: !patch.changed };
83109
82860
  }
83110
82861
  deps.log(
83111
- `\u2192 ${name} ${configured} \u2014 could not open Cursor; in Cursor's MCP settings, enable the powerplant server and sign in.`
82862
+ `\u2192 ${name} ${configured}, could not open Cursor; in Cursor's MCP settings, enable the powerplant server and sign in.`
83112
82863
  );
83113
82864
  return { state: "pending", unchanged: false };
83114
82865
  }
@@ -83116,10 +82867,10 @@ function login(bin, name, args, deps, env) {
83116
82867
  deps.log(`\u2192 ${name} approve in your browser\u2026`);
83117
82868
  const status = deps.runInteractive(bin, args, env);
83118
82869
  if (status === 0) {
83119
- deps.log(`\u2713 ${name} connected`);
82870
+ deps.log(`\u2713 ${name} MCP connected`);
83120
82871
  return { state: "connected", unchanged: false };
83121
82872
  }
83122
- deps.log(`\u2192 ${name} login not completed \u2014 finish later with: ${deps.connectCommand}`);
82873
+ deps.log(`\u2192 ${name} MCP sign-in not completed, finish later with: ${deps.connectCommand}`);
83123
82874
  return { state: "pending", unchanged: false };
83124
82875
  }
83125
82876
  function runDisconnect(clients, deps) {
@@ -83132,7 +82883,7 @@ function runDisconnect(clients, deps) {
83132
82883
  };
83133
82884
  if (clients.length === 0) {
83134
82885
  deps.log(
83135
- "No coding agents found (looked for `claude`, `codex`, and Cursor) \u2014 nothing to disconnect."
82886
+ "No coding agents found (looked for `claude`, `codex`, and Cursor), nothing to disconnect."
83136
82887
  );
83137
82888
  return outcome;
83138
82889
  }
@@ -83176,12 +82927,12 @@ function disconnectClaude(client, deps) {
83176
82927
  return "notConnected";
83177
82928
  }
83178
82929
  if (get.status !== 0) {
83179
- deps.log(`\u2717 ${name}: probing for the Powerplant MCP failed \u2014 ${describeFailure(get)}`);
82930
+ deps.log(`\u2717 ${name}: probing for the Powerplant MCP failed, ${describeFailure(get)}`);
83180
82931
  return "failed";
83181
82932
  }
83182
82933
  const remove = deps.run(bin, ["mcp", "remove", "--scope", "user", MCP_SERVER_NAME], env);
83183
82934
  if (remove.status !== 0) {
83184
- deps.log(`\u2717 ${name}: removing the Powerplant MCP failed \u2014 ${describeFailure(remove)}`);
82935
+ deps.log(`\u2717 ${name}: removing the Powerplant MCP failed, ${describeFailure(remove)}`);
83185
82936
  return "failed";
83186
82937
  }
83187
82938
  deps.log(`${name}: Powerplant MCP removed, sign-in included.`);
@@ -83191,12 +82942,12 @@ function disconnectCodex(bin, deps) {
83191
82942
  const name = describeBinary(bin);
83192
82943
  const list = deps.run(bin, ["mcp", "list", "--json"]);
83193
82944
  if (list.status !== 0) {
83194
- deps.log(`\u2717 ${name}: listing MCP servers failed \u2014 ${describeFailure(list)}`);
82945
+ deps.log(`\u2717 ${name}: listing MCP servers failed, ${describeFailure(list)}`);
83195
82946
  return "failed";
83196
82947
  }
83197
82948
  const servers = parseCodexServers(list.stdout);
83198
82949
  if (servers === null) {
83199
- deps.log(`\u2717 ${name}: could not read its MCP server list \u2014 is this codex version very old?`);
82950
+ deps.log(`\u2717 ${name}: could not read its MCP server list, is this codex version very old?`);
83200
82951
  return "failed";
83201
82952
  }
83202
82953
  const registered = servers.some((server) => server.name === MCP_SERVER_NAME);
@@ -83209,7 +82960,7 @@ function disconnectCodex(bin, deps) {
83209
82960
  deps.run(bin, ["mcp", "logout", MCP_SERVER_NAME]);
83210
82961
  const remove = deps.run(bin, ["mcp", "remove", MCP_SERVER_NAME]);
83211
82962
  if (remove.status !== 0) {
83212
- deps.log(`\u2717 ${name}: removing the Powerplant MCP failed \u2014 ${describeFailure(remove)}`);
82963
+ deps.log(`\u2717 ${name}: removing the Powerplant MCP failed, ${describeFailure(remove)}`);
83213
82964
  return "failed";
83214
82965
  }
83215
82966
  deps.log(`${name}: Powerplant MCP removed, sign-in included.`);
@@ -83219,7 +82970,7 @@ function disconnectCursor(mcpJsonPath, deps) {
83219
82970
  const name = `Cursor (${mcpJsonPath.replace(os15.homedir(), "~")})`;
83220
82971
  const patch = unpatchCursorMcpJson(deps.readTextFile(mcpJsonPath), MCP_SERVER_NAME);
83221
82972
  if (patch.error !== void 0) {
83222
- deps.log(`\u2717 ${name}: mcp.json is ${patch.error} \u2014 fix it by hand, then re-run powerplant disconnect.`);
82973
+ deps.log(`\u2717 ${name}: mcp.json is ${patch.error}, fix it by hand, then re-run powerplant disconnect.`);
83223
82974
  return "failed";
83224
82975
  }
83225
82976
  if (!patch.changed) {
@@ -83246,11 +82997,11 @@ function anyClientStillConnected(clients, deps) {
83246
82997
  });
83247
82998
  }
83248
82999
  function describeBinary(bin) {
83249
- return `${path15.basename(bin)} (${bin.replace(os15.homedir(), "~")})`;
83000
+ return `${path14.basename(bin)} (${bin.replace(os15.homedir(), "~")})`;
83250
83001
  }
83251
83002
  function describeClaudeTarget(client) {
83252
83003
  if (client.configDir === void 0) return describeBinary(client.bin);
83253
- return `${path15.basename(client.bin)} (${client.configDir.replace(os15.homedir(), "~")})`;
83004
+ return `${path14.basename(client.bin)} (${client.configDir.replace(os15.homedir(), "~")})`;
83254
83005
  }
83255
83006
  function describeFailure(result) {
83256
83007
  return result.error ?? lastLine(result.stdout + result.stderr);
@@ -83261,7 +83012,7 @@ function lastLine(output) {
83261
83012
  }
83262
83013
  var neutralDirMemo;
83263
83014
  function neutralWorkdir() {
83264
- neutralDirMemo ??= mkdtempSync(path15.join(os15.tmpdir(), "powerplant-connect-"));
83015
+ neutralDirMemo ??= mkdtempSync(path14.join(os15.tmpdir(), "powerplant-connect-"));
83265
83016
  return neutralDirMemo;
83266
83017
  }
83267
83018
  async function fetchOfficialClients(apiUrl, log3) {
@@ -83284,7 +83035,7 @@ async function fetchOfficialClients(apiUrl, log3) {
83284
83035
  return officialClientsDocumentSchema.parse(await response.json()).clients;
83285
83036
  } catch (error52) {
83286
83037
  log3(
83287
- `Official client ids unavailable (${error52 instanceof Error ? error52.message : String(error52)}) \u2014 agents will use dynamic registration where the environment allows it.`
83038
+ `Official client ids unavailable (${error52 instanceof Error ? error52.message : String(error52)}), agents will use dynamic registration where the environment allows it.`
83288
83039
  );
83289
83040
  return null;
83290
83041
  }
@@ -83305,11 +83056,11 @@ function realReadTextFileStrict(filePath) {
83305
83056
  }
83306
83057
  }
83307
83058
  function realWriteTextFile(filePath, content) {
83308
- mkdirSync6(path15.dirname(filePath), { recursive: true });
83059
+ mkdirSync6(path14.dirname(filePath), { recursive: true });
83309
83060
  writeFileSync6(filePath, content);
83310
83061
  }
83311
83062
  function codexConfigPath(homeDir = os15.homedir()) {
83312
- return path15.join(process.env.CODEX_HOME ?? path15.join(homeDir, ".codex"), "config.toml");
83063
+ return path14.join(process.env.CODEX_HOME ?? path14.join(homeDir, ".codex"), "config.toml");
83313
83064
  }
83314
83065
  function realOpenUrl(url2) {
83315
83066
  const bin = process.platform === "darwin" ? "open" : process.platform === "linux" ? "xdg-open" : null;
@@ -83357,9 +83108,9 @@ function realRunInteractive(bin, args, env) {
83357
83108
  }
83358
83109
 
83359
83110
  // src/connections.ts
83360
- import { execFileSync as execFileSync6, spawnSync as spawnSync2 } from "node:child_process";
83111
+ import { execFileSync as execFileSync5, spawnSync as spawnSync2 } from "node:child_process";
83361
83112
  import { mkdirSync as mkdirSync7, writeFileSync as writeFileSync7 } from "node:fs";
83362
- import path16 from "node:path";
83113
+ import path15 from "node:path";
83363
83114
  function probeConnections(clients, deps) {
83364
83115
  const reports = [];
83365
83116
  for (const kind of ["claude", "codex", "cursor"]) {
@@ -83403,7 +83154,7 @@ function aggregateClaudeTargets(targets) {
83403
83154
  if (targets.length === 1 || worst.report.state === "signed-in") return worst.report;
83404
83155
  return {
83405
83156
  ...worst.report,
83406
- target: worst.configDir === void 0 ? "default profile" : path16.basename(worst.configDir)
83157
+ target: worst.configDir === void 0 ? "default profile" : path15.basename(worst.configDir)
83407
83158
  };
83408
83159
  }
83409
83160
  function probeClient(client, deps) {
@@ -83482,12 +83233,12 @@ var detectedClientsSchema = external_exports.object({
83482
83233
  )
83483
83234
  });
83484
83235
  function detectedClientsPath(homeDir) {
83485
- return path16.join(collectorStateDir(homeDir), "detected-clients.json");
83236
+ return path15.join(collectorStateDir(homeDir), "detected-clients.json");
83486
83237
  }
83487
83238
  function saveDetectedClients(clients, pathValue, homeDir) {
83488
83239
  try {
83489
83240
  const file2 = detectedClientsPath(homeDir);
83490
- mkdirSync7(path16.dirname(file2), { recursive: true });
83241
+ mkdirSync7(path15.dirname(file2), { recursive: true });
83491
83242
  const record2 = {
83492
83243
  detectedAt: (/* @__PURE__ */ new Date()).toISOString(),
83493
83244
  path: pathValue,
@@ -83560,7 +83311,7 @@ function runWithPath(pathValue, budget = UNLIMITED_TIME_BUDGET) {
83560
83311
  function whichAllWith(pathValue) {
83561
83312
  return (name) => {
83562
83313
  try {
83563
- return execFileSync6("which", ["-a", name], {
83314
+ return execFileSync5("which", ["-a", name], {
83564
83315
  encoding: "utf8",
83565
83316
  env: { ...process.env, PATH: pathValue }
83566
83317
  }).split("\n").map((line) => line.trim()).filter(Boolean);
@@ -83578,72 +83329,72 @@ function renderStatus(i) {
83578
83329
  const lines = [];
83579
83330
  lines.push(`Environment: ${i.config.appEnv} (API ${i.config.apiUrl})`);
83580
83331
  lines.push(
83581
- `CLI: powerplant ${i.cliVersion}` + (i.latestVersion !== null && i.latestVersion !== i.cliVersion ? ` \u2014 ${i.latestVersion} is available: powerplant update` : "")
83332
+ `CLI: powerplant ${i.cliVersion}` + (i.latestVersion !== null && i.latestVersion !== i.cliVersion ? `, ${i.latestVersion} is available: powerplant update` : "")
83582
83333
  );
83583
83334
  const unsupported = unsupportedVersionNotice(i.cliVersion, i.oldestSupportedVersion);
83584
83335
  if (unsupported !== null) lines.push(unsupported);
83585
83336
  if (i.credentialsError !== void 0) {
83586
83337
  lines.push(`\u26A0 ${i.credentialsError}`);
83587
83338
  } else if (!i.credentials) {
83588
- lines.push("Not enrolled \u2014 run: powerplant init");
83339
+ lines.push("Not enrolled, run: powerplant init");
83589
83340
  } else {
83590
- const orgLine = i.credentials.orgName ? ` into org "${i.credentials.orgName}"` : " (org not recorded \u2014 re-enroll to see it)";
83341
+ const orgLine = i.credentials.orgName ? ` into org "${i.credentials.orgName}"` : " (org not recorded, re-enroll to see it)";
83591
83342
  lines.push(
83592
83343
  `Enrolled as "${i.credentials.machineName}" (${i.credentials.machineId})${orgLine} on ${i.credentials.enrolledAt}.`
83593
83344
  );
83594
83345
  lines.push(`Syncing: ${describeStoredCapture(i.credentials)}.`);
83595
83346
  for (const entry of i.protectedSessions ?? []) {
83596
83347
  lines.push(
83597
- `\u26A0 Repository matching is not enabled for ${entry.sessionCount} recent agent session${entry.sessionCount === 1 ? "" : "s"} under ${entry.displayRoot}. Sessions outside folders you explicitly added are staying local \u2014 run \`powerplant init\` to review Git repository scanning.`
83348
+ `\u26A0 Repository matching is not enabled for ${entry.sessionCount} recent agent session${entry.sessionCount === 1 ? "" : "s"} under ${entry.displayRoot}. Sessions outside folders you explicitly added are staying local, run \`powerplant init\` to review Git repository scanning.`
83598
83349
  );
83599
83350
  }
83600
83351
  }
83601
83352
  switch (i.service) {
83602
83353
  case "unsupported":
83603
83354
  lines.push(
83604
- "Background service: unsupported on this platform (macOS-only for now) \u2014 run `powerplant sync` on a schedule instead."
83355
+ "Background sync: unsupported on this platform (macOS-only for now), run `powerplant sync` on a schedule instead."
83605
83356
  );
83606
83357
  break;
83607
83358
  case "not-installed":
83608
- lines.push("Background service: not installed \u2014 run: powerplant init");
83359
+ lines.push("Background sync: not installed, run: powerplant init");
83609
83360
  break;
83610
83361
  case "not-loaded":
83611
- lines.push("Background service: installed but not loaded \u2014 run: powerplant restart");
83362
+ lines.push("Background sync: installed but not loaded, run: powerplant restart");
83612
83363
  break;
83613
83364
  case "loaded":
83614
83365
  lines.push(...renderDaemon(i));
83615
83366
  break;
83616
83367
  }
83617
83368
  if (i.control.paused) {
83618
- lines.push("\u23F8 Syncing is paused \u2014 resume with: powerplant resume");
83369
+ lines.push("\u23F8 Syncing is paused, resume with: powerplant resume");
83619
83370
  }
83620
83371
  return lines;
83621
83372
  }
83622
83373
  function renderDaemon(i) {
83623
83374
  if (i.daemon.state === "unreadable") {
83624
83375
  return [
83625
- "Background service: loaded, but its status file is unreadable (written by a different version?) \u2014 run: powerplant restart"
83376
+ "Background sync: loaded, but its status file is unreadable (written by a different version?), run: powerplant restart"
83626
83377
  ];
83627
83378
  }
83628
83379
  if (i.daemon.state === "not-running") {
83629
83380
  return [
83630
- `Background service: loaded, but no sync service status is available \u2014 starting up, or running a version from before status reporting. If this persists: powerplant restart. Log: ${serviceLogPath(i.config.appEnv)}`
83381
+ `Background sync: loaded, but no background sync status is available, starting up, or running a version from before status reporting. If this persists: powerplant restart. Log: ${serviceLogPath(i.config.appEnv)}`
83631
83382
  ];
83632
83383
  }
83633
83384
  const status = i.daemon.status;
83634
83385
  const lines = [];
83635
83386
  if (i.daemon.state === "stalled") {
83636
83387
  lines.push(
83637
- `\u26A0 Sync service stalled \u2014 no heartbeat for ${duration3(i.daemon.staleMs)} (pid ${status.pid}). Run: powerplant restart`
83388
+ `\u26A0 Background sync stalled, no heartbeat for ${duration3(i.daemon.staleMs)} (pid ${status.pid}). Run: powerplant restart`
83638
83389
  );
83639
83390
  } else {
83640
83391
  lines.push(
83641
- `Sync service: running (version ${status.version}, pid ${status.pid}, started ${status.startedAt}).`
83392
+ `Background sync: running (version ${status.version}, pid ${status.pid}, started ${status.startedAt}).`
83642
83393
  );
83643
83394
  }
83644
83395
  if (status.version !== i.cliVersion) {
83645
83396
  lines.push(
83646
- ` The daemon is on ${status.version}, this CLI is ${i.cliVersion} \u2014 it restarts onto the installed version within minutes, or now via: powerplant restart`
83397
+ ` The daemon is on ${status.version}, this CLI is ${i.cliVersion}, it restarts onto the installed version within minutes, or now via: powerplant restart`
83647
83398
  );
83648
83399
  }
83649
83400
  lines.push(
@@ -83727,13 +83478,13 @@ function redactedLogTail(raw) {
83727
83478
  while (lines.length > 0 && lines[lines.length - 1]?.trim() === "") lines.pop();
83728
83479
  return lines.slice(-DOCTOR_LOG_TAIL_LINES);
83729
83480
  }
83730
- function readDoctorLogTail(path19) {
83481
+ function readDoctorLogTail(path18) {
83731
83482
  let fd;
83732
83483
  try {
83733
- fd = openSync2(path19, "r");
83484
+ fd = openSync2(path18, "r");
83734
83485
  } catch (error52) {
83735
- if (error52.code === "ENOENT") return { path: path19, lines: null };
83736
- return { path: path19, lines: null, readError: error52 instanceof Error ? error52.message : String(error52) };
83486
+ if (error52.code === "ENOENT") return { path: path18, lines: null };
83487
+ return { path: path18, lines: null, readError: error52 instanceof Error ? error52.message : String(error52) };
83737
83488
  }
83738
83489
  try {
83739
83490
  const size = fstatSync(fd).size;
@@ -83742,9 +83493,9 @@ function readDoctorLogTail(path19) {
83742
83493
  readSync2(fd, buffer, 0, buffer.length, offset);
83743
83494
  let text = buffer.toString("utf8");
83744
83495
  if (offset > 0) text = text.slice(text.indexOf("\n") + 1);
83745
- return { path: path19, lines: redactedLogTail(text) };
83496
+ return { path: path18, lines: redactedLogTail(text) };
83746
83497
  } catch (error52) {
83747
- return { path: path19, lines: null, readError: error52 instanceof Error ? error52.message : String(error52) };
83498
+ return { path: path18, lines: null, readError: error52 instanceof Error ? error52.message : String(error52) };
83748
83499
  } finally {
83749
83500
  closeSync2(fd);
83750
83501
  }
@@ -83752,7 +83503,7 @@ function readDoctorLogTail(path19) {
83752
83503
  function renderDoctorReport(i) {
83753
83504
  const lines = [];
83754
83505
  lines.push(
83755
- "Powerplant diagnostics \u2014 paste everything below into your email to support@forestwalk.ai."
83506
+ "Powerplant diagnostics, paste everything below into your email to support@forestwalk.ai."
83756
83507
  );
83757
83508
  lines.push(
83758
83509
  `Collected ${new Date(i.now).toISOString()}. This command only prints; nothing was uploaded.`
@@ -83774,7 +83525,7 @@ function renderDoctorReport(i) {
83774
83525
  }
83775
83526
  function enrollmentLine(i) {
83776
83527
  if (i.credentialsError !== void 0) {
83777
- return `Enrollment: credential store unreadable \u2014 ${i.credentialsError}`;
83528
+ return `Enrollment: credential store unreadable, ${i.credentialsError}`;
83778
83529
  }
83779
83530
  if (!i.credentials) return "Enrollment: not enrolled";
83780
83531
  return `Enrollment: machine ${i.credentials.machineId}, org ${i.credentials.orgId ?? "not recorded"}, since ${i.credentials.enrolledAt}`;
@@ -83799,28 +83550,28 @@ function serviceLines(i) {
83799
83550
  const status = i.daemon.status;
83800
83551
  const out = [];
83801
83552
  out.push(
83802
- i.daemon.state === "stalled" ? `Sync service: stalled \u2014 no heartbeat for ${duration3(i.daemon.staleMs)} (version ${status.version}, pid ${status.pid})` : `Sync service: running (version ${status.version}, pid ${status.pid}, started ${status.startedAt})`
83553
+ i.daemon.state === "stalled" ? `Sync service: stalled, no heartbeat for ${duration3(i.daemon.staleMs)} (version ${status.version}, pid ${status.pid})` : `Sync service: running (version ${status.version}, pid ${status.pid}, started ${status.startedAt})`
83803
83554
  );
83804
83555
  out.push(
83805
83556
  status.lastSyncAt !== void 0 ? `Last successful sync: ${ago(i.now - Date.parse(status.lastSyncAt))} (${status.lastSyncAt})` : "No successful sync yet in this daemon run."
83806
83557
  );
83807
83558
  if (status.lastPass) {
83808
83559
  out.push(
83809
- status.lastPass.ok ? `Last pass: ok (${status.lastPass.kind}, ${status.lastPass.sessions} sessions, ${status.lastPass.upserted} uploaded, at ${status.lastPass.at})` : `Last pass: failed at ${status.lastPass.at} \u2014 ${redactText(status.lastPass.error ?? "unknown error")} (${status.consecutiveFailures} consecutive failure${status.consecutiveFailures === 1 ? "" : "s"})`
83560
+ status.lastPass.ok ? `Last pass: ok (${status.lastPass.kind}, ${status.lastPass.sessions} sessions, ${status.lastPass.upserted} uploaded, at ${status.lastPass.at})` : `Last pass: failed at ${status.lastPass.at}, ${redactText(status.lastPass.error ?? "unknown error")} (${status.consecutiveFailures} consecutive failure${status.consecutiveFailures === 1 ? "" : "s"})`
83810
83561
  );
83811
83562
  }
83812
83563
  return out;
83813
83564
  }
83814
83565
  function logLines(tail) {
83815
83566
  if (tail.readError !== void 0) {
83816
- return [`Sync service log: could not read ${tail.path} \u2014 ${tail.readError}`];
83567
+ return [`Sync service log: could not read ${tail.path}, ${tail.readError}`];
83817
83568
  }
83818
83569
  if (tail.lines === null) {
83819
83570
  return [`Sync service log: no file at ${tail.path} (the background service may never have run).`];
83820
83571
  }
83821
83572
  if (tail.lines.length === 0) return [`Sync service log: ${tail.path} is empty.`];
83822
83573
  return [
83823
- `Sync service log \u2014 last ${tail.lines.length} line${tail.lines.length === 1 ? "" : "s"} of ${tail.path}, credentials redacted:`,
83574
+ `Sync service log, last ${tail.lines.length} line${tail.lines.length === 1 ? "" : "s"} of ${tail.path}, credentials redacted:`,
83824
83575
  ...tail.lines
83825
83576
  ];
83826
83577
  }
@@ -83864,13 +83615,13 @@ function isCliEnv(value) {
83864
83615
  }
83865
83616
  function describeEnvironment(config2, env, explicitEnv) {
83866
83617
  const steeredByEnvVar = explicitEnv === void 0 && env.POWERPLANT_ENV !== void 0;
83867
- return `Environment: ${config2.appEnv} (API ${config2.apiUrl})${steeredByEnvVar ? " \u2014 set by POWERPLANT_ENV" : ""}`;
83618
+ return `Environment: ${config2.appEnv} (API ${config2.apiUrl})${steeredByEnvVar ? ", set by POWERPLANT_ENV" : ""}`;
83868
83619
  }
83869
83620
  function resolveCliConfig(env, explicitEnv) {
83870
83621
  const name = explicitEnv ?? env.POWERPLANT_ENV ?? "production";
83871
83622
  if (!isCliEnv(name)) {
83872
83623
  throw new ExpectedCliError(
83873
- explicitEnv === void 0 ? `Unknown environment "${name}" (from POWERPLANT_ENV in your shell) \u2014 unset POWERPLANT_ENV to use production.` : `Unknown environment "${name}" \u2014 drop --env to use production.`
83624
+ explicitEnv === void 0 ? `Unknown environment "${name}" (from POWERPLANT_ENV in your shell), unset POWERPLANT_ENV to use production.` : `Unknown environment "${name}", drop --env to use production.`
83874
83625
  );
83875
83626
  }
83876
83627
  const base = CLI_ENVIRONMENTS[name];
@@ -83912,7 +83663,7 @@ async function runInit(deps) {
83912
83663
  let repoDiscoveryEnabled = false;
83913
83664
  let protectedFoldersNeedAttention = false;
83914
83665
  let installed = false;
83915
- log3("2/3 Start background syncing");
83666
+ log3("2/3 Start background sync");
83916
83667
  if (deps.platform === "darwin") {
83917
83668
  const protectedSessions = await deps.activity(
83918
83669
  "Checking recent session locations\u2026",
@@ -83967,29 +83718,29 @@ async function runInit(deps) {
83967
83718
  }
83968
83719
  if (deps.platform !== "darwin") {
83969
83720
  log3(
83970
- " The background service is macOS-only for now \u2014 run `powerplant sync` on a schedule of your choosing instead."
83721
+ " Background sync is macOS-only for now. Run `powerplant sync` on a schedule of your choosing instead."
83971
83722
  );
83972
83723
  } else if (deps.serviceUpToDate()) {
83973
- log3("\u2713 Background syncing is running");
83724
+ log3("\u2713 Background sync is running");
83974
83725
  } else {
83975
- await deps.activity("Installing the sync service\u2026", deps.installService);
83976
- log3(" \u2713 Sync service is running");
83726
+ await deps.activity("Installing background sync\u2026", deps.installService);
83727
+ log3(" \u2713 Background sync is running");
83977
83728
  log3(
83978
83729
  ` Runs quietly and only uploads sessions inside ${orgName ? `${orgName}\u2019s` : "your organization\u2019s"} boundary.`
83979
83730
  );
83980
83731
  installed = true;
83981
83732
  }
83982
83733
  log3("");
83983
- log3("3/3 Add MCP to your agents");
83734
+ log3("3/3 Give your agents Powerplant MCP access");
83984
83735
  let outcome = null;
83985
83736
  try {
83986
83737
  outcome = await deps.connect();
83987
83738
  } catch (error52) {
83988
- log3(` \u2717 Adding MCP failed \u2014 ${error52 instanceof Error ? error52.message : String(error52)}`);
83739
+ log3(` \u2717 Could not give your agents Powerplant MCP access, ${error52 instanceof Error ? error52.message : String(error52)}`);
83989
83740
  }
83990
83741
  if (outcome?.found === 0) {
83991
83742
  log3(
83992
- deps.platform === "darwin" ? ` This machine still syncs once one is installed \u2014 then run: ${deps.connectCommand}` : ` Once one is installed, run: ${deps.connectCommand}`
83743
+ deps.platform === "darwin" ? ` This machine still syncs once one is installed, then run: ${deps.connectCommand}` : ` Once one is installed, run: ${deps.connectCommand}`
83993
83744
  );
83994
83745
  }
83995
83746
  log3("");
@@ -84017,7 +83768,7 @@ async function runInit(deps) {
84017
83768
  log3(` Open Powerplant: ${deps.webUrl}`);
84018
83769
  log3("");
84019
83770
  log3(
84020
- deps.platform === "darwin" ? ` Start a coding session in ${repository} \u2014 watch it appear in Powerplant.` : ` Start a coding session in ${repository}, then run \`powerplant sync\` to see it in Powerplant.`
83771
+ deps.platform === "darwin" ? ` Start a coding session in ${repository}, watch it appear in Powerplant.` : ` Start a coding session in ${repository}, then run \`powerplant sync\` to see it in Powerplant.`
84021
83772
  );
84022
83773
  }
84023
83774
  async function confirmProtectedRepoDiscovery(deps) {
@@ -84049,10 +83800,10 @@ async function realPromptLine(question) {
84049
83800
  }
84050
83801
 
84051
83802
  // src/memberSessions.ts
84052
- import { execFileSync as execFileSync7 } from "node:child_process";
84053
- import { existsSync as existsSync6 } from "node:fs";
83803
+ import { execFileSync as execFileSync6 } from "node:child_process";
83804
+ import { existsSync as existsSync5 } from "node:fs";
84054
83805
  import os16 from "node:os";
84055
- import path17 from "node:path";
83806
+ import path16 from "node:path";
84056
83807
  var memberSessionSchema = external_exports.object({
84057
83808
  id: external_exports.string().min(1),
84058
83809
  source: external_exports.string().min(1),
@@ -84063,12 +83814,12 @@ var memberSessionSchema = external_exports.object({
84063
83814
  lastActivityAt: external_exports.string().min(1),
84064
83815
  providerUrl: external_exports.string().nullable()
84065
83816
  });
84066
- var FETCH_TIMEOUT_MS3 = 3e3;
83817
+ var FETCH_TIMEOUT_MS2 = 3e3;
84067
83818
  async function fetchMemberSessions(credentials, fetchImpl = fetch) {
84068
83819
  try {
84069
83820
  const response = await fetchImpl(`${credentials.apiUrl}/api/collector/member-sessions`, {
84070
83821
  headers: { authorization: `Bearer ${credentials.token}`, ...cliVersionHeaders() },
84071
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS3)
83822
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS2)
84072
83823
  });
84073
83824
  if (!response.ok) return null;
84074
83825
  const envelope = external_exports.object({ data: external_exports.object({ sessions: external_exports.array(memberSessionSchema) }) }).safeParse(await response.json());
@@ -84112,11 +83863,11 @@ function codexThreadId(externalId) {
84112
83863
  }
84113
83864
  var CODEX_APP_BUNDLES = ["ChatGPT.app", "Codex.app"];
84114
83865
  var urlSchemesSchema = external_exports.array(external_exports.object({ CFBundleURLSchemes: external_exports.array(external_exports.string()).optional() }));
84115
- function detectCodexDesktop(probe = { exists: existsSync6, readUrlSchemes: realReadUrlSchemes }) {
84116
- const roots = ["/Applications", path17.join(os16.homedir(), "Applications")];
83866
+ function detectCodexDesktop(probe = { exists: existsSync5, readUrlSchemes: realReadUrlSchemes }) {
83867
+ const roots = ["/Applications", path16.join(os16.homedir(), "Applications")];
84117
83868
  return roots.some(
84118
83869
  (root) => CODEX_APP_BUNDLES.some((bundle) => {
84119
- const bundlePath = path17.join(root, bundle);
83870
+ const bundlePath = path16.join(root, bundle);
84120
83871
  return probe.exists(bundlePath) && probe.readUrlSchemes(bundlePath).includes("codex");
84121
83872
  })
84122
83873
  );
@@ -84124,9 +83875,9 @@ function detectCodexDesktop(probe = { exists: existsSync6, readUrlSchemes: realR
84124
83875
  function realReadUrlSchemes(bundlePath) {
84125
83876
  if (process.platform !== "darwin") return [];
84126
83877
  try {
84127
- const json2 = execFileSync7(
83878
+ const json2 = execFileSync6(
84128
83879
  "plutil",
84129
- ["-extract", "CFBundleURLTypes", "json", "-o", "-", path17.join(bundlePath, "Contents", "Info.plist")],
83880
+ ["-extract", "CFBundleURLTypes", "json", "-o", "-", path16.join(bundlePath, "Contents", "Info.plist")],
84130
83881
  { stdio: ["ignore", "pipe", "ignore"] }
84131
83882
  ).toString();
84132
83883
  const parsed = urlSchemesSchema.safeParse(JSON.parse(json2));
@@ -84138,7 +83889,7 @@ function realReadUrlSchemes(bundlePath) {
84138
83889
  }
84139
83890
 
84140
83891
  // src/menu.ts
84141
- import path18 from "node:path";
83892
+ import path17 from "node:path";
84142
83893
  var MENU_CONTRACT = 1;
84143
83894
  var CLIENT_NAMES = { claude: "Claude Code", codex: "Codex", cursor: "Cursor" };
84144
83895
  function renderMenu(i) {
@@ -84184,7 +83935,7 @@ function renderMenu(i) {
84184
83935
  }
84185
83936
  if (i.connections.length > 0) {
84186
83937
  items.push({ type: "separator" });
84187
- items.push({ type: "section", title: "Connections" });
83938
+ items.push({ type: "section", title: "Agents authorized for MCP" });
84188
83939
  for (const connection of i.connections) {
84189
83940
  const { row, action, warns } = connectionRow(connection, envArgs);
84190
83941
  if (warns) attention = true;
@@ -84205,7 +83956,7 @@ function renderMenu(i) {
84205
83956
  items.push({ type: "separator" });
84206
83957
  items.push({ type: "action", title: "Open Powerplant", url: i.config.webUrl });
84207
83958
  if (i.credentials !== null && i.service === "loaded" && !i.control.paused) {
84208
- items.push({ type: "action", title: "Pause Syncing", run: ["pause", ...envArgs] });
83959
+ items.push({ type: "action", title: "Pause syncing", run: ["pause", ...envArgs] });
84209
83960
  }
84210
83961
  const icon = attention ? "attention" : i.control.paused ? "paused" : "running";
84211
83962
  return {
@@ -84226,12 +83977,12 @@ function updateAction(i) {
84226
83977
  function collectorBlock(i, envArgs, problem) {
84227
83978
  const restart = {
84228
83979
  type: "action",
84229
- title: "Restart Sync Service",
83980
+ title: "Restart background sync",
84230
83981
  run: ["restart", ...envArgs]
84231
83982
  };
84232
83983
  const viewLog = {
84233
83984
  type: "action",
84234
- title: "View Sync Service Log",
83985
+ title: "View background sync log",
84235
83986
  file: serviceLogPath(i.config.appEnv)
84236
83987
  };
84237
83988
  switch (i.service) {
@@ -84240,19 +83991,19 @@ function collectorBlock(i, envArgs, problem) {
84240
83991
  {
84241
83992
  type: "status",
84242
83993
  mark: "muted",
84243
- title: "Background service isn't supported on this platform",
83994
+ title: "Background sync isn't supported on this platform",
84244
83995
  subtitle: "Sessions upload when you run: powerplant sync"
84245
83996
  }
84246
83997
  ];
84247
83998
  case "not-installed":
84248
83999
  return [
84249
- problem("Not uploading \u2014 the background service isn't set up"),
84250
- { type: "action", title: "Set Up Service\u2026", terminal: ["init", ...envArgs] }
84000
+ problem("Not uploading, the background sync isn't set up"),
84001
+ { type: "action", title: "Set up background sync\u2026", terminal: ["init", ...envArgs] }
84251
84002
  ];
84252
84003
  case "not-loaded":
84253
84004
  return [
84254
- problem("Not uploading \u2014 the background service is stopped"),
84255
- { type: "action", title: "Start Service", run: ["restart", ...envArgs] }
84005
+ problem("Not uploading, the background sync is stopped"),
84006
+ { type: "action", title: "Start background sync", run: ["restart", ...envArgs] }
84256
84007
  ];
84257
84008
  case "loaded":
84258
84009
  break;
@@ -84261,15 +84012,15 @@ function collectorBlock(i, envArgs, problem) {
84261
84012
  case "unreadable":
84262
84013
  return [
84263
84014
  problem(
84264
- "Sync service status can't be read",
84265
- "Its report was written by a different version \u2014 restarting usually clears this."
84015
+ "Background sync status can't be read",
84016
+ "Its report was written by a different version, restarting usually clears this."
84266
84017
  ),
84267
84018
  restart
84268
84019
  ];
84269
84020
  case "not-running":
84270
84021
  return [
84271
84022
  problem(
84272
- "Not uploading \u2014 the sync service isn't running",
84023
+ "Not uploading, the background sync isn't running",
84273
84024
  "It may be starting up. If this lasts, restart it."
84274
84025
  ),
84275
84026
  restart
@@ -84277,7 +84028,7 @@ function collectorBlock(i, envArgs, problem) {
84277
84028
  case "stalled":
84278
84029
  return [
84279
84030
  problem(
84280
- `Sync service quiet for ${duration3(i.daemon.staleMs)} \u2014 it may be stuck`,
84031
+ `Background sync quiet for ${duration3(i.daemon.staleMs)}, it may be stuck`,
84281
84032
  lastUploadLine(i)
84282
84033
  ),
84283
84034
  restart
@@ -84291,9 +84042,9 @@ function collectorBlock(i, envArgs, problem) {
84291
84042
  type: "status",
84292
84043
  mark: "paused",
84293
84044
  title: "Syncing paused",
84294
- subtitle: "The sync service is running but uploads nothing."
84045
+ subtitle: "The background sync is running but uploads nothing."
84295
84046
  },
84296
- { type: "action", title: "Resume Syncing", run: ["resume", ...envArgs] }
84047
+ { type: "action", title: "Resume syncing", run: ["resume", ...envArgs] }
84297
84048
  ];
84298
84049
  }
84299
84050
  const status = i.daemon.status;
@@ -84307,7 +84058,7 @@ function collectorBlock(i, envArgs, problem) {
84307
84058
  ];
84308
84059
  }
84309
84060
  return [
84310
- { type: "status", mark: "ok", title: "Sync service running", subtitle: lastUploadLine(i) }
84061
+ { type: "status", mark: "ok", title: "Background sync running", subtitle: lastUploadLine(i) }
84311
84062
  ];
84312
84063
  }
84313
84064
  var MAX_ACTIVE_AGENTS = 8;
@@ -84358,15 +84109,15 @@ function connectionRow(connection, envArgs) {
84358
84109
  type: "connection",
84359
84110
  mark,
84360
84111
  name,
84361
- state: connection.target === void 0 ? state : `${state} \u2014 ${connection.target}`
84112
+ state: connection.target === void 0 ? state : `${state}, ${connection.target}`
84362
84113
  });
84363
84114
  switch (connection.state) {
84364
84115
  case "signed-in":
84365
- return { row: row("ok", "Signed in"), warns: false };
84116
+ return { row: row("ok", "MCP access granted"), warns: false };
84366
84117
  case "sign-in-needed":
84367
84118
  return {
84368
- row: row("warn", "Sign-in needed"),
84369
- action: fix(`Sign In to ${name}\u2026`),
84119
+ row: row("warn", "MCP sign-in needed"),
84120
+ action: fix(`Give ${name} MCP access\u2026`),
84370
84121
  warns: true
84371
84122
  };
84372
84123
  case "different-url":
@@ -84377,12 +84128,12 @@ function connectionRow(connection, envArgs) {
84377
84128
  };
84378
84129
  case "not-connected":
84379
84130
  return {
84380
- row: row("warn", connection.client === "cursor" ? "Not set up" : "Not connected"),
84381
- action: fix(connection.client === "cursor" ? "Set Up Cursor\u2026" : `Connect ${name}\u2026`),
84131
+ row: row("warn", connection.client === "cursor" ? "MCP not configured" : "Not connected"),
84132
+ action: fix(connection.client === "cursor" ? "Add Powerplant MCP to Cursor\u2026" : `Give ${name} MCP access\u2026`),
84382
84133
  warns: true
84383
84134
  };
84384
84135
  case "configured":
84385
- return { row: row("muted", "Set up in Cursor"), warns: false };
84136
+ return { row: row("muted", "MCP configured in Cursor"), warns: false };
84386
84137
  case "check-failed":
84387
84138
  return { row: row("muted", "Can't check right now"), warns: false };
84388
84139
  }
@@ -84402,13 +84153,13 @@ function moreItems(i) {
84402
84153
  muted(`Enrolled ${i.credentials.enrolledAt.slice(0, 10)}`),
84403
84154
  muted(`CLI ${i.cliVersion}`, daemonVersionNote(i))
84404
84155
  ];
84405
- more.push({ type: "submenu", title: "Sync Service Details", items: details });
84156
+ more.push({ type: "submenu", title: "Background sync details", items: details });
84406
84157
  }
84407
84158
  more.push({ type: "action", title: "Copy Diagnostics", diagnostics: true });
84408
84159
  if (i.config.appEnv !== "production") {
84409
84160
  more.push({
84410
84161
  type: "action",
84411
- title: "View Sync Service Log",
84162
+ title: "View background sync log",
84412
84163
  file: serviceLogPath(i.config.appEnv)
84413
84164
  });
84414
84165
  }
@@ -84420,18 +84171,18 @@ function captureLine(credentials) {
84420
84171
  return `Syncs sessions under ${(credentials.scopePaths ?? []).join(", ")}`;
84421
84172
  case "org-repos": {
84422
84173
  const owners = credentials.allowedOwners ?? [];
84423
- return owners.length > 0 ? `Syncs sessions in ${owners.join(", ")} repositories` : "Set to sync your organization's repositories, but none are linked yet \u2014 nothing uploads";
84174
+ return owners.length > 0 ? `Syncs sessions in ${owners.join(", ")} repositories` : "Set to sync your organization's repositories, but none are linked yet, nothing uploads";
84424
84175
  }
84425
84176
  }
84426
84177
  }
84427
84178
  function daemonVersionNote(i) {
84428
84179
  if (!("status" in i.daemon)) return void 0;
84429
84180
  const version2 = i.daemon.status.version;
84430
- return version2 === i.cliVersion ? void 0 : `Sync service ${version2}`;
84181
+ return version2 === i.cliVersion ? void 0 : `Background sync ${version2}`;
84431
84182
  }
84432
84183
  var VERSION_CACHE_TTL_MS = 60 * 6e4;
84433
84184
  function versionCachePath(homeDir) {
84434
- return path18.join(collectorStateDir(homeDir), "version-check.json");
84185
+ return path17.join(collectorStateDir(homeDir), "version-check.json");
84435
84186
  }
84436
84187
  async function cachedLatestVersion(options) {
84437
84188
  const raw = options.readTextFile(options.cacheFile);
@@ -84466,7 +84217,7 @@ function resumeSessionArgv(source, sessionId) {
84466
84217
  const command = RESUME_COMMANDS[source];
84467
84218
  if (command === void 0) {
84468
84219
  throw new ExpectedCliError(
84469
- `Sessions from "${source}" have no terminal to resume in \u2014 open them in Powerplant instead.`
84220
+ `Sessions from "${source}" have no terminal to resume in, open them in Powerplant instead.`
84470
84221
  );
84471
84222
  }
84472
84223
  return command(sessionId);
@@ -84479,7 +84230,7 @@ function runResumeSession(source, sessionId, spawn2 = spawnSync3) {
84479
84230
  const result = spawn2(binary, args, { stdio: "inherit" });
84480
84231
  if (result.error !== void 0) {
84481
84232
  throw new ExpectedCliError(
84482
- `Could not run ${binary} (${result.error.message}) \u2014 is the ${binary} CLI installed on this machine?`
84233
+ `Could not run ${binary} (${result.error.message}), is the ${binary} CLI installed on this machine?`
84483
84234
  );
84484
84235
  }
84485
84236
  if (result.status !== null && result.status !== 0) {
@@ -84612,7 +84363,7 @@ ${RESTART_NOTE}`;
84612
84363
  }
84613
84364
 
84614
84365
  // src/version.ts
84615
- var CLI_VERSION = true ? "0.4.0" : "0.0.0-checkout";
84366
+ var CLI_VERSION = true ? "0.4.1" : "0.0.0-checkout";
84616
84367
  var CLI_PACKAGE_NAME = "@usepowerplant/cli";
84617
84368
 
84618
84369
  // src/workspace.ts
@@ -84622,18 +84373,18 @@ var workspaceSchema = external_exports.object({
84622
84373
  role: external_exports.string().min(1),
84623
84374
  active: external_exports.boolean()
84624
84375
  });
84625
- var FETCH_TIMEOUT_MS4 = 1e4;
84626
- async function callApi(credentials, path19, init3, fetchImpl) {
84376
+ var FETCH_TIMEOUT_MS3 = 1e4;
84377
+ async function callApi(credentials, path18, init3, fetchImpl) {
84627
84378
  let response;
84628
84379
  try {
84629
- response = await fetchImpl(`${credentials.apiUrl}${path19}`, {
84380
+ response = await fetchImpl(`${credentials.apiUrl}${path18}`, {
84630
84381
  ...init3,
84631
84382
  headers: {
84632
84383
  authorization: `Bearer ${credentials.token}`,
84633
84384
  "content-type": "application/json",
84634
84385
  ...cliVersionHeaders()
84635
84386
  },
84636
- signal: AbortSignal.timeout(FETCH_TIMEOUT_MS4)
84387
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS3)
84637
84388
  });
84638
84389
  } catch (error52) {
84639
84390
  const detail = error52 instanceof Error ? error52.message : String(error52);
@@ -84641,11 +84392,11 @@ async function callApi(credentials, path19, init3, fetchImpl) {
84641
84392
  }
84642
84393
  if (response.status === 401) {
84643
84394
  throw new ExpectedCliError(
84644
- "Powerplant refused this machine's credentials \u2014 run `powerplant enroll` to re-enroll it."
84395
+ "Powerplant refused this machine's credentials, run `powerplant enroll` to re-enroll it."
84645
84396
  );
84646
84397
  }
84647
84398
  if (!response.ok) {
84648
- throw new ExpectedCliError(`Powerplant answered ${response.status} for ${path19}.`);
84399
+ throw new ExpectedCliError(`Powerplant answered ${response.status} for ${path18}.`);
84649
84400
  }
84650
84401
  return response.json();
84651
84402
  }
@@ -84653,7 +84404,7 @@ async function fetchWorkspaces(credentials, fetchImpl = fetch) {
84653
84404
  const envelope = external_exports.object({ data: external_exports.object({ workspaces: external_exports.array(workspaceSchema) }) }).safeParse(await callApi(credentials, "/api/collector/workspaces", {}, fetchImpl));
84654
84405
  if (!envelope.success) {
84655
84406
  throw new ExpectedCliError(
84656
- "Powerplant answered in a shape this CLI can't read \u2014 run `powerplant update`."
84407
+ "Powerplant answered in a shape this CLI can't read, run `powerplant update`."
84657
84408
  );
84658
84409
  }
84659
84410
  return envelope.data.data.workspaces;
@@ -84668,7 +84419,7 @@ async function selectWorkspace(credentials, orgId, fetchImpl = fetch) {
84668
84419
  }
84669
84420
  function renderWorkspaces(workspaces) {
84670
84421
  const lines = workspaces.map(
84671
- (workspace) => `${workspace.active ? "*" : " "} ${workspace.name} (${workspace.role})${workspace.active ? " \u2014 active" : ""}`
84422
+ (workspace) => `${workspace.active ? "*" : " "} ${workspace.name} (${workspace.role})${workspace.active ? ", active" : ""}`
84672
84423
  );
84673
84424
  if (workspaces.length > 1) {
84674
84425
  lines.push("", "Switch with: powerplant workspace <name>");
@@ -84687,7 +84438,7 @@ function matchWorkspace(workspaces, target) {
84687
84438
  }
84688
84439
  const ids = matches.map((workspace) => `${workspace.name} = ${workspace.id}`).join(", ");
84689
84440
  throw new ExpectedCliError(
84690
- `"${target}" names ${matches.length} of your workspaces \u2014 switch by id instead: ${ids}.`
84441
+ `"${target}" names ${matches.length} of your workspaces, switch by id instead: ${ids}.`
84691
84442
  );
84692
84443
  }
84693
84444
  async function runWorkspaceCommand(targetWords, credentials, print, fetchImpl = fetch) {
@@ -84708,39 +84459,39 @@ async function runWorkspaceCommand(targetWords, credentials, print, fetchImpl =
84708
84459
  }
84709
84460
 
84710
84461
  // src/cli.ts
84711
- var USAGE = `powerplant \u2014 the Powerplant sync service for this machine
84462
+ var USAGE = `powerplant, the Powerplant background sync for this machine
84712
84463
 
84713
84464
  Usage: powerplant <command> [options]
84714
84465
 
84715
84466
  Commands:
84716
- init Set up this machine: enroll it into your org, install the
84717
- background service, and add Powerplant MCP to your agents.
84718
- Safe to re-run \u2014 finished steps are skipped.
84719
- connect Add Powerplant MCP to installed agents (Claude Code, Codex,
84720
- Cursor) \u2014 also for later installs and re-authentication.
84467
+ init Enroll this machine, start background sync, and give your
84468
+ coding agents Powerplant MCP access.
84469
+ Safe to re-run, finished steps are skipped.
84470
+ connect Give installed coding agents Powerplant MCP access (Claude Code,
84471
+ Codex, Cursor), also for later installs and re-authentication.
84721
84472
  --client claude|codex|cursor adds just those (repeatable).
84722
84473
  disconnect The inverse of connect: remove the Powerplant MCP entry (and
84723
84474
  its sign-in) from every installed coding agent.
84724
84475
  enroll (Re-)enroll this machine into your org (browser approval).
84725
- status What the sync service is doing on this machine (--json for tools).
84476
+ status What the background sync is doing on this machine (--json for tools).
84726
84477
  doctor A diagnostics summary for support: status plus the redacted
84727
- tail of the sync service log. Prints only \u2014 nothing is uploaded.
84478
+ tail of the background sync log. Prints only, nothing is uploaded.
84728
84479
  Paste the output into your email to support@forestwalk.ai.
84729
84480
  update Update this CLI to the latest published version (via npm).
84730
- restart Restart the background service.
84731
- pause Pause syncing \u2014 the service keeps running, nothing uploads.
84481
+ restart Restart the background sync.
84482
+ pause Pause syncing, the service keeps running, nothing uploads.
84732
84483
  resume Resume syncing (runs a catch-up pass over the pause).
84733
84484
  sync Run one sync pass in the foreground [--since <days>] [--dry-run].
84734
84485
  folders The folders you explicitly sync on this machine:
84735
84486
  powerplant folders [add <path> | remove <path>]. Additions on
84736
- top of your org's allowlisted repos \u2014 no re-enroll needed.
84487
+ top of your org's allowlisted repos, no re-enroll needed.
84737
84488
  workspace Your workspaces, and which one Powerplant and your connected
84738
84489
  agents use: powerplant workspace [<name>] switches to <name>.
84739
84490
  resume-session Reopen a synced session in its own CLI, right here in
84740
84491
  this terminal: powerplant resume-session <claude-code|codex>
84741
84492
  <session-id>.
84742
- watch Run the sync service in the foreground.
84743
- uninstall Remove the background service [--forget also deletes this
84493
+ watch Run the background sync in the foreground.
84494
+ uninstall Remove the background sync [--forget also deletes this
84744
84495
  machine's stored credentials].
84745
84496
 
84746
84497
  Options:
@@ -84828,7 +84579,7 @@ ${USAGE}`);
84828
84579
  let clients = clientFilter === void 0 ? detected : detected.filter((client) => clientFilter.has(client.client));
84829
84580
  if (clientFilter !== void 0 && clients.length === 0) {
84830
84581
  log3(
84831
- `No ${[...clientFilter].join(" or ")} installation found on this machine \u2014 nothing to connect.`
84582
+ `No ${[...clientFilter].join(" or ")} installation found on this machine, nothing to connect.`
84832
84583
  );
84833
84584
  return {
84834
84585
  found: 0,
@@ -84845,7 +84596,7 @@ ${USAGE}`);
84845
84596
  clients = await pickAgents(clients, { log: log3, promptCheckboxes: realCheckboxPrompt });
84846
84597
  skipped = agentCount(detected) - agentCount(clients);
84847
84598
  if (clients.length === 0) {
84848
- log3(`MCP wasn't added \u2014 run any time: ${connectCommand}`);
84599
+ log3(`Powerplant MCP wasn't added to any agents. Run any time: ${connectCommand}`);
84849
84600
  return {
84850
84601
  found: agentCount(detected),
84851
84602
  connected: 0,
@@ -84903,7 +84654,7 @@ ${USAGE}`);
84903
84654
  case "connect": {
84904
84655
  const outcome = await connect3(console.log);
84905
84656
  if (outcome.pending > 0) {
84906
- console.log(`Some logins are unfinished \u2014 re-run \`${connectCommand}\` any time.`);
84657
+ console.log(`Some logins are unfinished, re-run \`${connectCommand}\` any time.`);
84907
84658
  }
84908
84659
  if (outcome.failed > 0) process.exitCode = 1;
84909
84660
  return;
@@ -84990,7 +84741,7 @@ The access you granted these agents stays on your Powerplant account until you r
84990
84741
  const clients = mergeDetectedClients(
84991
84742
  detectClients({ whichAll: whichAllWith(probePath), budget }),
84992
84743
  saved,
84993
- existsSync7
84744
+ existsSync6
84994
84745
  );
84995
84746
  const [latestVersion, oldestSupportedVersion, memberSessions, grantedClientIds] = await Promise.all([
84996
84747
  cachedLatestVersion({
@@ -85033,7 +84784,7 @@ The access you granted these agents stays on your Powerplant account until you r
85033
84784
  const stored = loadCredentialsSafely(config2);
85034
84785
  if (stored.credentials === null) {
85035
84786
  throw new ExpectedCliError(
85036
- `This machine isn't enrolled yet \u2014 run \`powerplant init\` first.${stored.credentialsError ? ` (${stored.credentialsError})` : ""}`
84787
+ `This machine isn't enrolled yet, run \`powerplant init\` first.${stored.credentialsError ? ` (${stored.credentialsError})` : ""}`
85037
84788
  );
85038
84789
  }
85039
84790
  await runWorkspaceCommand(positionals.slice(1), stored.credentials, console.log);
@@ -85048,31 +84799,31 @@ The access you granted these agents stays on your Powerplant account until you r
85048
84799
  const npm = spawnSync5("npm", ["install", "-g", CLI_PACKAGE_NAME], { stdio: "inherit" });
85049
84800
  if (npm.error) {
85050
84801
  throw new ExpectedCliError(
85051
- `Could not run npm (${npm.error.message}) \u2014 update by hand: npm install -g ${CLI_PACKAGE_NAME}`
84802
+ `Could not run npm (${npm.error.message}), update by hand: npm install -g ${CLI_PACKAGE_NAME}`
85052
84803
  );
85053
84804
  }
85054
84805
  if (npm.status !== 0) {
85055
- throw new ExpectedCliError("npm install failed \u2014 see the output above.");
84806
+ throw new ExpectedCliError("npm install failed, see the output above.");
85056
84807
  }
85057
84808
  console.log(updatedMessage(installedGlobalVersion(CLI_PACKAGE_NAME)));
85058
84809
  return;
85059
84810
  }
85060
84811
  case "restart": {
85061
84812
  if (restartService(config2) === "not-installed") {
85062
- throw new ExpectedCliError("No background service installed \u2014 run: powerplant init");
84813
+ throw new ExpectedCliError("No background sync installed, run: powerplant init");
85063
84814
  }
85064
- console.log("Background service restarted.");
84815
+ console.log("Background sync restarted.");
85065
84816
  return;
85066
84817
  }
85067
84818
  case "pause": {
85068
84819
  writeCollectorControl(config2.appEnv, { paused: true, pausedAt: (/* @__PURE__ */ new Date()).toISOString() });
85069
- console.log("Syncing paused \u2014 the sync service keeps running but uploads nothing.");
84820
+ console.log("Syncing paused, the background sync keeps running but uploads nothing.");
85070
84821
  console.log("Resume with: powerplant resume");
85071
84822
  return;
85072
84823
  }
85073
84824
  case "resume": {
85074
84825
  writeCollectorControl(config2.appEnv, { paused: false, resumedAt: (/* @__PURE__ */ new Date()).toISOString() });
85075
- console.log("Syncing resumed \u2014 the sync service runs a catch-up pass covering the pause.");
84826
+ console.log("Syncing resumed, the background sync runs a catch-up pass covering the pause.");
85076
84827
  return;
85077
84828
  }
85078
84829
  case "sync": {
@@ -85111,18 +84862,18 @@ The access you granted these agents stays on your Powerplant account until you r
85111
84862
  const removed = uninstallService(config2);
85112
84863
  clearCollectorStatus(config2.appEnv);
85113
84864
  clearCollectorControl(config2.appEnv);
85114
- console.log(removed ? "Background service removed." : "No background service was installed.");
84865
+ console.log(removed ? "Background sync removed." : "No background sync was installed.");
85115
84866
  if (values.forget) {
85116
84867
  deleteCredentials(config2.appEnv);
85117
- console.log("Stored credentials deleted \u2014 this machine is no longer enrolled.");
84868
+ console.log("Stored credentials deleted, this machine is no longer enrolled.");
85118
84869
  } else {
85119
84870
  console.log(
85120
- "Credentials kept \u2014 `powerplant init` re-installs without re-enrolling. (--forget deletes them.)"
84871
+ "Credentials kept, `powerplant init` re-installs without re-enrolling. (--forget deletes them.)"
85121
84872
  );
85122
84873
  }
85123
84874
  if (anyClientStillConnected(detectClients(), { run: realRun, readTextFile: realReadTextFile })) {
85124
84875
  console.log(
85125
- "Your coding agents are still connected to the Powerplant MCP server \u2014 remove those connections with: powerplant disconnect"
84876
+ "Your coding agents are still connected to the Powerplant MCP server, remove those connections with: powerplant disconnect"
85126
84877
  );
85127
84878
  }
85128
84879
  return;