@buildautomaton/cli 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2240,7 +2240,7 @@ var require_websocket = __commonJS({
2240
2240
  var http = __require("http");
2241
2241
  var net = __require("net");
2242
2242
  var tls = __require("tls");
2243
- var { randomBytes, createHash: createHash2 } = __require("crypto");
2243
+ var { randomBytes: randomBytes2, createHash: createHash2 } = __require("crypto");
2244
2244
  var { Duplex, Readable: Readable2 } = __require("stream");
2245
2245
  var { URL: URL2 } = __require("url");
2246
2246
  var PerMessageDeflate = require_permessage_deflate();
@@ -2770,7 +2770,7 @@ var require_websocket = __commonJS({
2770
2770
  }
2771
2771
  }
2772
2772
  const defaultPort = isSecure ? 443 : 80;
2773
- const key = randomBytes(16).toString("base64");
2773
+ const key = randomBytes2(16).toString("base64");
2774
2774
  const request = isSecure ? https2.request : http.request;
2775
2775
  const protocolSet = /* @__PURE__ */ new Set();
2776
2776
  let perMessageDeflate;
@@ -3179,7 +3179,7 @@ var require_stream = __commonJS({
3179
3179
  };
3180
3180
  duplex._final = function(callback) {
3181
3181
  if (ws.readyState === ws.CONNECTING) {
3182
- ws.once("open", function open() {
3182
+ ws.once("open", function open2() {
3183
3183
  duplex._final(callback);
3184
3184
  });
3185
3185
  return;
@@ -3200,7 +3200,7 @@ var require_stream = __commonJS({
3200
3200
  };
3201
3201
  duplex._write = function(chunk, encoding, callback) {
3202
3202
  if (ws.readyState === ws.CONNECTING) {
3203
- ws.once("open", function open() {
3203
+ ws.once("open", function open2() {
3204
3204
  duplex._write(chunk, encoding, callback);
3205
3205
  });
3206
3206
  return;
@@ -4065,8 +4065,8 @@ var init_parseUtil = __esm({
4065
4065
  init_errors();
4066
4066
  init_en();
4067
4067
  makeIssue = (params) => {
4068
- const { data, path: path31, errorMaps, issueData } = params;
4069
- const fullPath = [...path31, ...issueData.path || []];
4068
+ const { data, path: path32, errorMaps, issueData } = params;
4069
+ const fullPath = [...path32, ...issueData.path || []];
4070
4070
  const fullIssue = {
4071
4071
  ...issueData,
4072
4072
  path: fullPath
@@ -4374,11 +4374,11 @@ var init_types = __esm({
4374
4374
  init_parseUtil();
4375
4375
  init_util();
4376
4376
  ParseInputLazyPath = class {
4377
- constructor(parent, value, path31, key) {
4377
+ constructor(parent, value, path32, key) {
4378
4378
  this._cachedPath = [];
4379
4379
  this.parent = parent;
4380
4380
  this.data = value;
4381
- this._path = path31;
4381
+ this._path = path32;
4382
4382
  this._key = key;
4383
4383
  }
4384
4384
  get path() {
@@ -7993,10 +7993,10 @@ function assignProp(target, prop, value) {
7993
7993
  configurable: true
7994
7994
  });
7995
7995
  }
7996
- function getElementAtPath(obj, path31) {
7997
- if (!path31)
7996
+ function getElementAtPath(obj, path32) {
7997
+ if (!path32)
7998
7998
  return obj;
7999
- return path31.reduce((acc, key) => acc?.[key], obj);
7999
+ return path32.reduce((acc, key) => acc?.[key], obj);
8000
8000
  }
8001
8001
  function promiseAllObject(promisesObj) {
8002
8002
  const keys = Object.keys(promisesObj);
@@ -8245,11 +8245,11 @@ function aborted(x, startIndex = 0) {
8245
8245
  }
8246
8246
  return false;
8247
8247
  }
8248
- function prefixIssues(path31, issues) {
8248
+ function prefixIssues(path32, issues) {
8249
8249
  return issues.map((iss) => {
8250
8250
  var _a2;
8251
8251
  (_a2 = iss).path ?? (_a2.path = []);
8252
- iss.path.unshift(path31);
8252
+ iss.path.unshift(path32);
8253
8253
  return iss;
8254
8254
  });
8255
8255
  }
@@ -8438,7 +8438,7 @@ function treeifyError(error40, _mapper) {
8438
8438
  return issue2.message;
8439
8439
  };
8440
8440
  const result = { errors: [] };
8441
- const processError = (error41, path31 = []) => {
8441
+ const processError = (error41, path32 = []) => {
8442
8442
  var _a2, _b;
8443
8443
  for (const issue2 of error41.issues) {
8444
8444
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -8448,7 +8448,7 @@ function treeifyError(error40, _mapper) {
8448
8448
  } else if (issue2.code === "invalid_element") {
8449
8449
  processError({ issues: issue2.issues }, issue2.path);
8450
8450
  } else {
8451
- const fullpath = [...path31, ...issue2.path];
8451
+ const fullpath = [...path32, ...issue2.path];
8452
8452
  if (fullpath.length === 0) {
8453
8453
  result.errors.push(mapper(issue2));
8454
8454
  continue;
@@ -8478,9 +8478,9 @@ function treeifyError(error40, _mapper) {
8478
8478
  processError(error40);
8479
8479
  return result;
8480
8480
  }
8481
- function toDotPath(path31) {
8481
+ function toDotPath(path32) {
8482
8482
  const segs = [];
8483
- for (const seg of path31) {
8483
+ for (const seg of path32) {
8484
8484
  if (typeof seg === "number")
8485
8485
  segs.push(`[${seg}]`);
8486
8486
  else if (typeof seg === "symbol")
@@ -21669,7 +21669,7 @@ var require_has_flag = __commonJS({
21669
21669
  var require_supports_color = __commonJS({
21670
21670
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
21671
21671
  "use strict";
21672
- var os5 = __require("os");
21672
+ var os6 = __require("os");
21673
21673
  var tty = __require("tty");
21674
21674
  var hasFlag = require_has_flag();
21675
21675
  var { env } = process;
@@ -21717,7 +21717,7 @@ var require_supports_color = __commonJS({
21717
21717
  return min;
21718
21718
  }
21719
21719
  if (process.platform === "win32") {
21720
- const osRelease = os5.release().split(".");
21720
+ const osRelease = os6.release().split(".");
21721
21721
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
21722
21722
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
21723
21723
  }
@@ -21963,10 +21963,10 @@ var require_src2 = __commonJS({
21963
21963
  var fs_1 = __require("fs");
21964
21964
  var debug_1 = __importDefault(require_src());
21965
21965
  var log2 = debug_1.default("@kwsites/file-exists");
21966
- function check2(path31, isFile, isDirectory) {
21967
- log2(`checking %s`, path31);
21966
+ function check2(path32, isFile, isDirectory) {
21967
+ log2(`checking %s`, path32);
21968
21968
  try {
21969
- const stat2 = fs_1.statSync(path31);
21969
+ const stat2 = fs_1.statSync(path32);
21970
21970
  if (stat2.isFile() && isFile) {
21971
21971
  log2(`[OK] path represents a file`);
21972
21972
  return true;
@@ -21986,8 +21986,8 @@ var require_src2 = __commonJS({
21986
21986
  throw e;
21987
21987
  }
21988
21988
  }
21989
- function exists2(path31, type = exports.READABLE) {
21990
- return check2(path31, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
21989
+ function exists2(path32, type = exports.READABLE) {
21990
+ return check2(path32, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
21991
21991
  }
21992
21992
  exports.exists = exists2;
21993
21993
  exports.FILE = 1;
@@ -22787,8 +22787,8 @@ var PREVIEW_API_BASE_PATH = "/__preview";
22787
22787
  var PREVIEW_SECRET_HEADER = "X-Preview-Secret";
22788
22788
  var DEFAULT_PORT = 3e3;
22789
22789
  var DEFAULT_COMMAND = "npm run preview";
22790
- var PREVIEW_COMMAND_ENV = "BUILDAMATON_PREVIEW_COMMAND";
22791
- var PREVIEW_PORT_ENV = "BUILDAMATON_PREVIEW_PORT";
22790
+ var PREVIEW_COMMAND_ENV = "BUILDAUTOMATON_PREVIEW_COMMAND";
22791
+ var PREVIEW_PORT_ENV = "BUILDAUTOMATON_PREVIEW_PORT";
22792
22792
  var previewProcess = null;
22793
22793
  var previewPort = DEFAULT_PORT;
22794
22794
  var previewSecret = "";
@@ -22802,8 +22802,8 @@ function randomSecret() {
22802
22802
  }
22803
22803
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
22804
22804
  }
22805
- async function requestPreviewApi(port, secret, method, path31, body) {
22806
- const url2 = `http://127.0.0.1:${port}${path31}`;
22805
+ async function requestPreviewApi(port, secret, method, path32, body) {
22806
+ const url2 = `http://127.0.0.1:${port}${path32}`;
22807
22807
  const headers = {
22808
22808
  [PREVIEW_SECRET_HEADER]: secret,
22809
22809
  "Content-Type": "application/json"
@@ -22815,7 +22815,7 @@ async function requestPreviewApi(port, secret, method, path31, body) {
22815
22815
  });
22816
22816
  const data = await res.json().catch(() => ({}));
22817
22817
  if (!res.ok) {
22818
- throw new Error(data?.error ?? `Preview API ${method} ${path31}: ${res.status}`);
22818
+ throw new Error(data?.error ?? `Preview API ${method} ${path32}: ${res.status}`);
22819
22819
  }
22820
22820
  return data;
22821
22821
  }
@@ -22841,7 +22841,7 @@ var OPERATIONS = [
22841
22841
  var previewSkill = {
22842
22842
  id: "preview",
22843
22843
  name: "Preview",
22844
- description: "Start and manage a local preview server that implements the BuildAutomaton Preview Server API. Configure the command with BUILDAMATON_PREVIEW_COMMAND (default: npm run preview). The server receives PORT and PREVIEW_SECRET and must expose /__preview/status and /__preview/stop.",
22844
+ description: "Start and manage a local preview server that implements the BuildAutomaton Preview Server API. Configure the command with BUILDAUTOMATON_PREVIEW_COMMAND (default: npm run preview). The server receives PORT and PREVIEW_SECRET and must expose /__preview/status and /__preview/stop.",
22845
22845
  operations: OPERATIONS,
22846
22846
  async execute(operationId, params) {
22847
22847
  const command = getPreviewCommand();
@@ -23040,8 +23040,521 @@ function installBridgeProcessResilience() {
23040
23040
  });
23041
23041
  }
23042
23042
 
23043
+ // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
23044
+ import process7 from "node:process";
23045
+ import { Buffer as Buffer2 } from "node:buffer";
23046
+ import path4 from "node:path";
23047
+ import { fileURLToPath } from "node:url";
23048
+ import { promisify as promisify5 } from "node:util";
23049
+ import childProcess from "node:child_process";
23050
+ import fs6, { constants as fsConstants2 } from "node:fs/promises";
23051
+
23052
+ // ../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
23053
+ import process3 from "node:process";
23054
+ import fs5, { constants as fsConstants } from "node:fs/promises";
23055
+
23056
+ // ../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
23057
+ import process2 from "node:process";
23058
+ import os2 from "node:os";
23059
+ import fs4 from "node:fs";
23060
+
23061
+ // ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
23062
+ import fs3 from "node:fs";
23063
+
23064
+ // ../../node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
23065
+ import fs2 from "node:fs";
23066
+ var isDockerCached;
23067
+ function hasDockerEnv() {
23068
+ try {
23069
+ fs2.statSync("/.dockerenv");
23070
+ return true;
23071
+ } catch {
23072
+ return false;
23073
+ }
23074
+ }
23075
+ function hasDockerCGroup() {
23076
+ try {
23077
+ return fs2.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
23078
+ } catch {
23079
+ return false;
23080
+ }
23081
+ }
23082
+ function isDocker() {
23083
+ if (isDockerCached === void 0) {
23084
+ isDockerCached = hasDockerEnv() || hasDockerCGroup();
23085
+ }
23086
+ return isDockerCached;
23087
+ }
23088
+
23089
+ // ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
23090
+ var cachedResult;
23091
+ var hasContainerEnv = () => {
23092
+ try {
23093
+ fs3.statSync("/run/.containerenv");
23094
+ return true;
23095
+ } catch {
23096
+ return false;
23097
+ }
23098
+ };
23099
+ function isInsideContainer() {
23100
+ if (cachedResult === void 0) {
23101
+ cachedResult = hasContainerEnv() || isDocker();
23102
+ }
23103
+ return cachedResult;
23104
+ }
23105
+
23106
+ // ../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
23107
+ var isWsl = () => {
23108
+ if (process2.platform !== "linux") {
23109
+ return false;
23110
+ }
23111
+ if (os2.release().toLowerCase().includes("microsoft")) {
23112
+ if (isInsideContainer()) {
23113
+ return false;
23114
+ }
23115
+ return true;
23116
+ }
23117
+ try {
23118
+ if (fs4.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
23119
+ return !isInsideContainer();
23120
+ }
23121
+ } catch {
23122
+ }
23123
+ if (fs4.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs4.existsSync("/run/WSL")) {
23124
+ return !isInsideContainer();
23125
+ }
23126
+ return false;
23127
+ };
23128
+ var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
23129
+
23130
+ // ../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
23131
+ var wslDrivesMountPoint = /* @__PURE__ */ (() => {
23132
+ const defaultMountPoint = "/mnt/";
23133
+ let mountPoint;
23134
+ return async function() {
23135
+ if (mountPoint) {
23136
+ return mountPoint;
23137
+ }
23138
+ const configFilePath2 = "/etc/wsl.conf";
23139
+ let isConfigFileExists = false;
23140
+ try {
23141
+ await fs5.access(configFilePath2, fsConstants.F_OK);
23142
+ isConfigFileExists = true;
23143
+ } catch {
23144
+ }
23145
+ if (!isConfigFileExists) {
23146
+ return defaultMountPoint;
23147
+ }
23148
+ const configContent = await fs5.readFile(configFilePath2, { encoding: "utf8" });
23149
+ const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
23150
+ if (!configMountPoint) {
23151
+ return defaultMountPoint;
23152
+ }
23153
+ mountPoint = configMountPoint.groups.mountPoint.trim();
23154
+ mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
23155
+ return mountPoint;
23156
+ };
23157
+ })();
23158
+ var powerShellPathFromWsl = async () => {
23159
+ const mountPoint = await wslDrivesMountPoint();
23160
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
23161
+ };
23162
+ var powerShellPath = async () => {
23163
+ if (is_wsl_default) {
23164
+ return powerShellPathFromWsl();
23165
+ }
23166
+ return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
23167
+ };
23168
+
23169
+ // ../../node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
23170
+ function defineLazyProperty(object2, propertyName, valueGetter) {
23171
+ const define = (value) => Object.defineProperty(object2, propertyName, { value, enumerable: true, writable: true });
23172
+ Object.defineProperty(object2, propertyName, {
23173
+ configurable: true,
23174
+ enumerable: true,
23175
+ get() {
23176
+ const result = valueGetter();
23177
+ define(result);
23178
+ return result;
23179
+ },
23180
+ set(value) {
23181
+ define(value);
23182
+ }
23183
+ });
23184
+ return object2;
23185
+ }
23186
+
23187
+ // ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
23188
+ import { promisify as promisify4 } from "node:util";
23189
+ import process6 from "node:process";
23190
+ import { execFile as execFile4 } from "node:child_process";
23191
+
23192
+ // ../../node_modules/.pnpm/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
23193
+ import { promisify } from "node:util";
23194
+ import process4 from "node:process";
23195
+ import { execFile } from "node:child_process";
23196
+ var execFileAsync = promisify(execFile);
23197
+ async function defaultBrowserId() {
23198
+ if (process4.platform !== "darwin") {
23199
+ throw new Error("macOS only");
23200
+ }
23201
+ const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
23202
+ const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
23203
+ const browserId = match?.groups.id ?? "com.apple.Safari";
23204
+ if (browserId === "com.apple.safari") {
23205
+ return "com.apple.Safari";
23206
+ }
23207
+ return browserId;
23208
+ }
23209
+
23210
+ // ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
23211
+ import process5 from "node:process";
23212
+ import { promisify as promisify2 } from "node:util";
23213
+ import { execFile as execFile2, execFileSync } from "node:child_process";
23214
+ var execFileAsync2 = promisify2(execFile2);
23215
+ async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
23216
+ if (process5.platform !== "darwin") {
23217
+ throw new Error("macOS only");
23218
+ }
23219
+ const outputArguments = humanReadableOutput ? [] : ["-ss"];
23220
+ const execOptions = {};
23221
+ if (signal) {
23222
+ execOptions.signal = signal;
23223
+ }
23224
+ const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
23225
+ return stdout.trim();
23226
+ }
23227
+
23228
+ // ../../node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js
23229
+ async function bundleName(bundleId) {
23230
+ return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
23231
+ tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
23232
+ }
23233
+
23234
+ // ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/windows.js
23235
+ import { promisify as promisify3 } from "node:util";
23236
+ import { execFile as execFile3 } from "node:child_process";
23237
+ var execFileAsync3 = promisify3(execFile3);
23238
+ var windowsBrowserProgIds = {
23239
+ MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
23240
+ // The missing `L` is correct.
23241
+ MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
23242
+ MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
23243
+ AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
23244
+ ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
23245
+ ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
23246
+ ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
23247
+ ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
23248
+ BraveHTML: { name: "Brave", id: "com.brave.Browser" },
23249
+ BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
23250
+ BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
23251
+ BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
23252
+ FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
23253
+ OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
23254
+ VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
23255
+ "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
23256
+ };
23257
+ var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
23258
+ var UnknownBrowserError = class extends Error {
23259
+ };
23260
+ async function defaultBrowser(_execFileAsync = execFileAsync3) {
23261
+ const { stdout } = await _execFileAsync("reg", [
23262
+ "QUERY",
23263
+ " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
23264
+ "/v",
23265
+ "ProgId"
23266
+ ]);
23267
+ const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
23268
+ if (!match) {
23269
+ throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
23270
+ }
23271
+ const { id } = match.groups;
23272
+ const dotIndex = id.lastIndexOf(".");
23273
+ const hyphenIndex = id.lastIndexOf("-");
23274
+ const baseIdByDot = dotIndex === -1 ? void 0 : id.slice(0, dotIndex);
23275
+ const baseIdByHyphen = hyphenIndex === -1 ? void 0 : id.slice(0, hyphenIndex);
23276
+ return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
23277
+ }
23278
+
23279
+ // ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
23280
+ var execFileAsync4 = promisify4(execFile4);
23281
+ var titleize = (string4) => string4.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
23282
+ async function defaultBrowser2() {
23283
+ if (process6.platform === "darwin") {
23284
+ const id = await defaultBrowserId();
23285
+ const name = await bundleName(id);
23286
+ return { name, id };
23287
+ }
23288
+ if (process6.platform === "linux") {
23289
+ const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
23290
+ const id = stdout.trim();
23291
+ const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
23292
+ return { name, id };
23293
+ }
23294
+ if (process6.platform === "win32") {
23295
+ return defaultBrowser();
23296
+ }
23297
+ throw new Error("Only macOS, Linux, and Windows are supported");
23298
+ }
23299
+
23300
+ // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
23301
+ var execFile5 = promisify5(childProcess.execFile);
23302
+ var __dirname = path4.dirname(fileURLToPath(import.meta.url));
23303
+ var localXdgOpenPath = path4.join(__dirname, "xdg-open");
23304
+ var { platform, arch } = process7;
23305
+ async function getWindowsDefaultBrowserFromWsl() {
23306
+ const powershellPath = await powerShellPath();
23307
+ const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
23308
+ const encodedCommand = Buffer2.from(rawCommand, "utf16le").toString("base64");
23309
+ const { stdout } = await execFile5(
23310
+ powershellPath,
23311
+ [
23312
+ "-NoProfile",
23313
+ "-NonInteractive",
23314
+ "-ExecutionPolicy",
23315
+ "Bypass",
23316
+ "-EncodedCommand",
23317
+ encodedCommand
23318
+ ],
23319
+ { encoding: "utf8" }
23320
+ );
23321
+ const progId = stdout.trim();
23322
+ const browserMap = {
23323
+ ChromeHTML: "com.google.chrome",
23324
+ BraveHTML: "com.brave.Browser",
23325
+ MSEdgeHTM: "com.microsoft.edge",
23326
+ FirefoxURL: "org.mozilla.firefox"
23327
+ };
23328
+ return browserMap[progId] ? { id: browserMap[progId] } : {};
23329
+ }
23330
+ var pTryEach = async (array2, mapper) => {
23331
+ let latestError;
23332
+ for (const item of array2) {
23333
+ try {
23334
+ return await mapper(item);
23335
+ } catch (error40) {
23336
+ latestError = error40;
23337
+ }
23338
+ }
23339
+ throw latestError;
23340
+ };
23341
+ var baseOpen = async (options) => {
23342
+ options = {
23343
+ wait: false,
23344
+ background: false,
23345
+ newInstance: false,
23346
+ allowNonzeroExitCode: false,
23347
+ ...options
23348
+ };
23349
+ if (Array.isArray(options.app)) {
23350
+ return pTryEach(options.app, (singleApp) => baseOpen({
23351
+ ...options,
23352
+ app: singleApp
23353
+ }));
23354
+ }
23355
+ let { name: app, arguments: appArguments = [] } = options.app ?? {};
23356
+ appArguments = [...appArguments];
23357
+ if (Array.isArray(app)) {
23358
+ return pTryEach(app, (appName) => baseOpen({
23359
+ ...options,
23360
+ app: {
23361
+ name: appName,
23362
+ arguments: appArguments
23363
+ }
23364
+ }));
23365
+ }
23366
+ if (app === "browser" || app === "browserPrivate") {
23367
+ const ids = {
23368
+ "com.google.chrome": "chrome",
23369
+ "google-chrome.desktop": "chrome",
23370
+ "com.brave.Browser": "brave",
23371
+ "org.mozilla.firefox": "firefox",
23372
+ "firefox.desktop": "firefox",
23373
+ "com.microsoft.msedge": "edge",
23374
+ "com.microsoft.edge": "edge",
23375
+ "com.microsoft.edgemac": "edge",
23376
+ "microsoft-edge.desktop": "edge"
23377
+ };
23378
+ const flags = {
23379
+ chrome: "--incognito",
23380
+ brave: "--incognito",
23381
+ firefox: "--private-window",
23382
+ edge: "--inPrivate"
23383
+ };
23384
+ const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
23385
+ if (browser.id in ids) {
23386
+ const browserName = ids[browser.id];
23387
+ if (app === "browserPrivate") {
23388
+ appArguments.push(flags[browserName]);
23389
+ }
23390
+ return baseOpen({
23391
+ ...options,
23392
+ app: {
23393
+ name: apps[browserName],
23394
+ arguments: appArguments
23395
+ }
23396
+ });
23397
+ }
23398
+ throw new Error(`${browser.name} is not supported as a default browser`);
23399
+ }
23400
+ let command;
23401
+ const cliArguments = [];
23402
+ const childProcessOptions = {};
23403
+ if (platform === "darwin") {
23404
+ command = "open";
23405
+ if (options.wait) {
23406
+ cliArguments.push("--wait-apps");
23407
+ }
23408
+ if (options.background) {
23409
+ cliArguments.push("--background");
23410
+ }
23411
+ if (options.newInstance) {
23412
+ cliArguments.push("--new");
23413
+ }
23414
+ if (app) {
23415
+ cliArguments.push("-a", app);
23416
+ }
23417
+ } else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
23418
+ command = await powerShellPath();
23419
+ cliArguments.push(
23420
+ "-NoProfile",
23421
+ "-NonInteractive",
23422
+ "-ExecutionPolicy",
23423
+ "Bypass",
23424
+ "-EncodedCommand"
23425
+ );
23426
+ if (!is_wsl_default) {
23427
+ childProcessOptions.windowsVerbatimArguments = true;
23428
+ }
23429
+ const encodedArguments = ["Start"];
23430
+ if (options.wait) {
23431
+ encodedArguments.push("-Wait");
23432
+ }
23433
+ if (app) {
23434
+ encodedArguments.push(`"\`"${app}\`""`);
23435
+ if (options.target) {
23436
+ appArguments.push(options.target);
23437
+ }
23438
+ } else if (options.target) {
23439
+ encodedArguments.push(`"${options.target}"`);
23440
+ }
23441
+ if (appArguments.length > 0) {
23442
+ appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
23443
+ encodedArguments.push("-ArgumentList", appArguments.join(","));
23444
+ }
23445
+ options.target = Buffer2.from(encodedArguments.join(" "), "utf16le").toString("base64");
23446
+ } else {
23447
+ if (app) {
23448
+ command = app;
23449
+ } else {
23450
+ const isBundled = !__dirname || __dirname === "/";
23451
+ let exeLocalXdgOpen = false;
23452
+ try {
23453
+ await fs6.access(localXdgOpenPath, fsConstants2.X_OK);
23454
+ exeLocalXdgOpen = true;
23455
+ } catch {
23456
+ }
23457
+ const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
23458
+ command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
23459
+ }
23460
+ if (appArguments.length > 0) {
23461
+ cliArguments.push(...appArguments);
23462
+ }
23463
+ if (!options.wait) {
23464
+ childProcessOptions.stdio = "ignore";
23465
+ childProcessOptions.detached = true;
23466
+ }
23467
+ }
23468
+ if (platform === "darwin" && appArguments.length > 0) {
23469
+ cliArguments.push("--args", ...appArguments);
23470
+ }
23471
+ if (options.target) {
23472
+ cliArguments.push(options.target);
23473
+ }
23474
+ const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
23475
+ if (options.wait) {
23476
+ return new Promise((resolve15, reject) => {
23477
+ subprocess.once("error", reject);
23478
+ subprocess.once("close", (exitCode) => {
23479
+ if (!options.allowNonzeroExitCode && exitCode > 0) {
23480
+ reject(new Error(`Exited with code ${exitCode}`));
23481
+ return;
23482
+ }
23483
+ resolve15(subprocess);
23484
+ });
23485
+ });
23486
+ }
23487
+ subprocess.unref();
23488
+ return subprocess;
23489
+ };
23490
+ var open = (target, options) => {
23491
+ if (typeof target !== "string") {
23492
+ throw new TypeError("Expected a `target`");
23493
+ }
23494
+ return baseOpen({
23495
+ ...options,
23496
+ target
23497
+ });
23498
+ };
23499
+ function detectArchBinary(binary) {
23500
+ if (typeof binary === "string" || Array.isArray(binary)) {
23501
+ return binary;
23502
+ }
23503
+ const { [arch]: archBinary } = binary;
23504
+ if (!archBinary) {
23505
+ throw new Error(`${arch} is not supported`);
23506
+ }
23507
+ return archBinary;
23508
+ }
23509
+ function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
23510
+ if (wsl && is_wsl_default) {
23511
+ return detectArchBinary(wsl);
23512
+ }
23513
+ if (!platformBinary) {
23514
+ throw new Error(`${platform} is not supported`);
23515
+ }
23516
+ return detectArchBinary(platformBinary);
23517
+ }
23518
+ var apps = {};
23519
+ defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
23520
+ darwin: "google chrome",
23521
+ win32: "chrome",
23522
+ linux: ["google-chrome", "google-chrome-stable", "chromium"]
23523
+ }, {
23524
+ wsl: {
23525
+ ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
23526
+ x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
23527
+ }
23528
+ }));
23529
+ defineLazyProperty(apps, "brave", () => detectPlatformBinary({
23530
+ darwin: "brave browser",
23531
+ win32: "brave",
23532
+ linux: ["brave-browser", "brave"]
23533
+ }, {
23534
+ wsl: {
23535
+ ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
23536
+ x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
23537
+ }
23538
+ }));
23539
+ defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
23540
+ darwin: "firefox",
23541
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
23542
+ linux: "firefox"
23543
+ }, {
23544
+ wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
23545
+ }));
23546
+ defineLazyProperty(apps, "edge", () => detectPlatformBinary({
23547
+ darwin: "microsoft edge",
23548
+ win32: "msedge",
23549
+ linux: ["microsoft-edge", "microsoft-edge-dev"]
23550
+ }, {
23551
+ wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
23552
+ }));
23553
+ defineLazyProperty(apps, "browser", () => "browser");
23554
+ defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
23555
+ var open_default = open;
23556
+
23043
23557
  // src/auth/open-browser.ts
23044
- import { execSync } from "node:child_process";
23045
23558
  function isLocalApiUrl(apiUrl) {
23046
23559
  try {
23047
23560
  const u = new URL(apiUrl);
@@ -23051,8 +23564,11 @@ function isLocalApiUrl(apiUrl) {
23051
23564
  return false;
23052
23565
  }
23053
23566
  }
23054
- function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
23055
- const appUrl = apiUrl && isLocalApiUrl(apiUrl) ? process.env.BUILDAUTOMATON_APP_URL ?? "http://localhost:3000" : process.env.BUILDAUTOMATON_APP_URL ?? "https://app.buildautomaton.com";
23567
+ function appUrlForApiUrl(apiUrl) {
23568
+ return apiUrl && isLocalApiUrl(apiUrl) ? process.env.BUILDAUTOMATON_APP_URL ?? "http://localhost:3000" : process.env.BUILDAUTOMATON_APP_URL ?? "https://app.buildautomaton.com";
23569
+ }
23570
+ async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
23571
+ const appUrl = appUrlForApiUrl(apiUrl);
23056
23572
  let connectCliUrl = `${appUrl.replace(/\/$/, "")}/bridges/connect?connectionId=${connectionId}`;
23057
23573
  if (initialWorkspaceId) {
23058
23574
  try {
@@ -23065,10 +23581,11 @@ function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiU
23065
23581
  connectCliUrl += `&bridgeName=${encodeURIComponent(preferredBridgeName.trim())}`;
23066
23582
  }
23067
23583
  logFn("Opening browser to link this CLI\u2026");
23068
- logFn("If you\u2019re already signed in with one workspace, the CLI will connect automatically. Otherwise sign in and link to a workspace.");
23584
+ logFn(
23585
+ "If you\u2019re already signed in with one workspace, the CLI will connect automatically. Otherwise sign in and link to a workspace."
23586
+ );
23069
23587
  try {
23070
- const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
23071
- execSync(`${cmd} "${connectCliUrl}"`, { stdio: "ignore" });
23588
+ await open_default(connectCliUrl, { wait: false });
23072
23589
  } catch {
23073
23590
  logFn("Could not open browser. Open this URL manually:");
23074
23591
  logFn(connectCliUrl);
@@ -23323,7 +23840,7 @@ function runPendingAuth(options) {
23323
23840
  }
23324
23841
  if (!hasOpenedBrowser) {
23325
23842
  hasOpenedBrowser = true;
23326
- openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
23843
+ void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
23327
23844
  }
23328
23845
  },
23329
23846
  onClose: (code, reason) => {
@@ -23365,7 +23882,7 @@ function runPendingAuth(options) {
23365
23882
  browserFallback = null;
23366
23883
  if (!hasOpenedBrowser) {
23367
23884
  hasOpenedBrowser = true;
23368
- openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
23885
+ void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
23369
23886
  }
23370
23887
  }, BROWSER_OPEN_FALLBACK_MS);
23371
23888
  connect();
@@ -23425,27 +23942,27 @@ async function closeBridgeConnection(state, acpManager, devServerManager, log2)
23425
23942
  }
23426
23943
 
23427
23944
  // src/git/session-git-queue.ts
23428
- import { execFile as execFile2 } from "node:child_process";
23945
+ import { execFile as execFile7 } from "node:child_process";
23429
23946
  import { readFile, stat } from "node:fs/promises";
23430
- import { promisify as promisify2 } from "node:util";
23431
- import * as path6 from "node:path";
23947
+ import { promisify as promisify7 } from "node:util";
23948
+ import * as path7 from "node:path";
23432
23949
 
23433
23950
  // src/git/pre-turn-snapshot.ts
23434
- import * as fs3 from "node:fs";
23435
- import * as path5 from "node:path";
23436
- import { execFile } from "node:child_process";
23437
- import { promisify } from "node:util";
23951
+ import * as fs8 from "node:fs";
23952
+ import * as path6 from "node:path";
23953
+ import { execFile as execFile6 } from "node:child_process";
23954
+ import { promisify as promisify6 } from "node:util";
23438
23955
 
23439
23956
  // src/git/discover-repos.ts
23440
- import * as fs2 from "node:fs";
23441
- import * as path4 from "node:path";
23957
+ import * as fs7 from "node:fs";
23958
+ import * as path5 from "node:path";
23442
23959
 
23443
23960
  // ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
23444
23961
  var import_file_exists = __toESM(require_dist(), 1);
23445
23962
  var import_debug = __toESM(require_src(), 1);
23446
23963
  var import_promise_deferred = __toESM(require_dist2(), 1);
23447
23964
  var import_promise_deferred2 = __toESM(require_dist2(), 1);
23448
- import { Buffer as Buffer2 } from "node:buffer";
23965
+ import { Buffer as Buffer22 } from "node:buffer";
23449
23966
  import { spawn as spawn3 } from "child_process";
23450
23967
  import { normalize as normalize2 } from "node:path";
23451
23968
  import { EventEmitter } from "node:events";
@@ -23477,8 +23994,8 @@ function pathspec(...paths) {
23477
23994
  cache.set(key, paths);
23478
23995
  return key;
23479
23996
  }
23480
- function isPathSpec(path31) {
23481
- return path31 instanceof String && cache.has(path31);
23997
+ function isPathSpec(path32) {
23998
+ return path32 instanceof String && cache.has(path32);
23482
23999
  }
23483
24000
  function toPaths(pathSpec) {
23484
24001
  return cache.get(pathSpec) || [];
@@ -23567,8 +24084,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
23567
24084
  function forEachLineWithContent(input, callback) {
23568
24085
  return toLinesWithContent(input, true).map((line) => callback(line));
23569
24086
  }
23570
- function folderExists(path31) {
23571
- return (0, import_file_exists.exists)(path31, import_file_exists.FOLDER);
24087
+ function folderExists(path32) {
24088
+ return (0, import_file_exists.exists)(path32, import_file_exists.FOLDER);
23572
24089
  }
23573
24090
  function append(target, item) {
23574
24091
  if (Array.isArray(target)) {
@@ -23625,7 +24142,7 @@ function prefixedArray(input, prefix) {
23625
24142
  return output;
23626
24143
  }
23627
24144
  function bufferToString(input) {
23628
- return (Array.isArray(input) ? Buffer2.concat(input) : input).toString("utf-8");
24145
+ return (Array.isArray(input) ? Buffer22.concat(input) : input).toString("utf-8");
23629
24146
  }
23630
24147
  function pick2(source, properties) {
23631
24148
  const out = {};
@@ -23972,8 +24489,8 @@ function checkIsRepoRootTask() {
23972
24489
  commands,
23973
24490
  format: "utf-8",
23974
24491
  onError,
23975
- parser(path31) {
23976
- return /^\.(git)?$/.test(path31.trim());
24492
+ parser(path32) {
24493
+ return /^\.(git)?$/.test(path32.trim());
23977
24494
  }
23978
24495
  };
23979
24496
  }
@@ -24407,11 +24924,11 @@ function parseGrep(grep) {
24407
24924
  const paths = /* @__PURE__ */ new Set();
24408
24925
  const results = {};
24409
24926
  forEachLineWithContent(grep, (input) => {
24410
- const [path31, line, preview] = input.split(NULL);
24411
- paths.add(path31);
24412
- (results[path31] = results[path31] || []).push({
24927
+ const [path32, line, preview] = input.split(NULL);
24928
+ paths.add(path32);
24929
+ (results[path32] = results[path32] || []).push({
24413
24930
  line: asNumber(line),
24414
- path: path31,
24931
+ path: path32,
24415
24932
  preview
24416
24933
  });
24417
24934
  });
@@ -25176,14 +25693,14 @@ var init_hash_object = __esm2({
25176
25693
  init_task();
25177
25694
  }
25178
25695
  });
25179
- function parseInit(bare, path31, text) {
25696
+ function parseInit(bare, path32, text) {
25180
25697
  const response = String(text).trim();
25181
25698
  let result;
25182
25699
  if (result = initResponseRegex.exec(response)) {
25183
- return new InitSummary(bare, path31, false, result[1]);
25700
+ return new InitSummary(bare, path32, false, result[1]);
25184
25701
  }
25185
25702
  if (result = reInitResponseRegex.exec(response)) {
25186
- return new InitSummary(bare, path31, true, result[1]);
25703
+ return new InitSummary(bare, path32, true, result[1]);
25187
25704
  }
25188
25705
  let gitDir = "";
25189
25706
  const tokens = response.split(" ");
@@ -25194,7 +25711,7 @@ function parseInit(bare, path31, text) {
25194
25711
  break;
25195
25712
  }
25196
25713
  }
25197
- return new InitSummary(bare, path31, /^re/i.test(response), gitDir);
25714
+ return new InitSummary(bare, path32, /^re/i.test(response), gitDir);
25198
25715
  }
25199
25716
  var InitSummary;
25200
25717
  var initResponseRegex;
@@ -25203,9 +25720,9 @@ var init_InitSummary = __esm2({
25203
25720
  "src/lib/responses/InitSummary.ts"() {
25204
25721
  "use strict";
25205
25722
  InitSummary = class {
25206
- constructor(bare, path31, existing, gitDir) {
25723
+ constructor(bare, path32, existing, gitDir) {
25207
25724
  this.bare = bare;
25208
- this.path = path31;
25725
+ this.path = path32;
25209
25726
  this.existing = existing;
25210
25727
  this.gitDir = gitDir;
25211
25728
  }
@@ -25217,7 +25734,7 @@ var init_InitSummary = __esm2({
25217
25734
  function hasBareCommand(command) {
25218
25735
  return command.includes(bareCommand);
25219
25736
  }
25220
- function initTask(bare = false, path31, customArgs) {
25737
+ function initTask(bare = false, path32, customArgs) {
25221
25738
  const commands = ["init", ...customArgs];
25222
25739
  if (bare && !hasBareCommand(commands)) {
25223
25740
  commands.splice(1, 0, bareCommand);
@@ -25226,7 +25743,7 @@ function initTask(bare = false, path31, customArgs) {
25226
25743
  commands,
25227
25744
  format: "utf-8",
25228
25745
  parser(text) {
25229
- return parseInit(commands.includes("--bare"), path31, text);
25746
+ return parseInit(commands.includes("--bare"), path32, text);
25230
25747
  }
25231
25748
  };
25232
25749
  }
@@ -26042,12 +26559,12 @@ var init_FileStatusSummary = __esm2({
26042
26559
  "use strict";
26043
26560
  fromPathRegex = /^(.+)\0(.+)$/;
26044
26561
  FileStatusSummary = class {
26045
- constructor(path31, index, working_dir) {
26046
- this.path = path31;
26562
+ constructor(path32, index, working_dir) {
26563
+ this.path = path32;
26047
26564
  this.index = index;
26048
26565
  this.working_dir = working_dir;
26049
26566
  if (index === "R" || working_dir === "R") {
26050
- const detail = fromPathRegex.exec(path31) || [null, path31, path31];
26567
+ const detail = fromPathRegex.exec(path32) || [null, path32, path32];
26051
26568
  this.from = detail[2] || "";
26052
26569
  this.path = detail[1] || "";
26053
26570
  }
@@ -26078,14 +26595,14 @@ function splitLine(result, lineStr) {
26078
26595
  default:
26079
26596
  return;
26080
26597
  }
26081
- function data(index, workingDir, path31) {
26598
+ function data(index, workingDir, path32) {
26082
26599
  const raw = `${index}${workingDir}`;
26083
26600
  const handler = parsers6.get(raw);
26084
26601
  if (handler) {
26085
- handler(result, path31);
26602
+ handler(result, path32);
26086
26603
  }
26087
26604
  if (raw !== "##" && raw !== "!!") {
26088
- result.files.push(new FileStatusSummary(path31, index, workingDir));
26605
+ result.files.push(new FileStatusSummary(path32, index, workingDir));
26089
26606
  }
26090
26607
  }
26091
26608
  }
@@ -26394,9 +26911,9 @@ var init_simple_git_api = __esm2({
26394
26911
  next
26395
26912
  );
26396
26913
  }
26397
- hashObject(path31, write) {
26914
+ hashObject(path32, write) {
26398
26915
  return this._runTask(
26399
- hashObjectTask(path31, write === true),
26916
+ hashObjectTask(path32, write === true),
26400
26917
  trailingFunctionArgument(arguments)
26401
26918
  );
26402
26919
  }
@@ -26749,8 +27266,8 @@ var init_branch = __esm2({
26749
27266
  }
26750
27267
  });
26751
27268
  function toPath(input) {
26752
- const path31 = input.trim().replace(/^["']|["']$/g, "");
26753
- return path31 && normalize2(path31);
27269
+ const path32 = input.trim().replace(/^["']|["']$/g, "");
27270
+ return path32 && normalize2(path32);
26754
27271
  }
26755
27272
  var parseCheckIgnore;
26756
27273
  var init_CheckIgnore = __esm2({
@@ -27064,8 +27581,8 @@ __export2(sub_module_exports, {
27064
27581
  subModuleTask: () => subModuleTask,
27065
27582
  updateSubModuleTask: () => updateSubModuleTask
27066
27583
  });
27067
- function addSubModuleTask(repo, path31) {
27068
- return subModuleTask(["add", repo, path31]);
27584
+ function addSubModuleTask(repo, path32) {
27585
+ return subModuleTask(["add", repo, path32]);
27069
27586
  }
27070
27587
  function initSubModuleTask(customArgs) {
27071
27588
  return subModuleTask(["init", ...customArgs]);
@@ -27398,8 +27915,8 @@ var require_git = __commonJS2({
27398
27915
  }
27399
27916
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
27400
27917
  };
27401
- Git2.prototype.submoduleAdd = function(repo, path31, then) {
27402
- return this._runTask(addSubModuleTask2(repo, path31), trailingFunctionArgument2(arguments));
27918
+ Git2.prototype.submoduleAdd = function(repo, path32, then) {
27919
+ return this._runTask(addSubModuleTask2(repo, path32), trailingFunctionArgument2(arguments));
27403
27920
  };
27404
27921
  Git2.prototype.submoduleUpdate = function(args, then) {
27405
27922
  return this._runTask(
@@ -28025,20 +28542,20 @@ async function isGitRepoDirectory(dirPath) {
28025
28542
  // src/git/discover-repos.ts
28026
28543
  async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
28027
28544
  const result = [];
28028
- const cwdResolved = path4.resolve(cwd);
28545
+ const cwdResolved = path5.resolve(cwd);
28029
28546
  if (await isGitRepoDirectory(cwdResolved)) {
28030
28547
  const remoteUrl = await getRemoteOriginUrl(cwdResolved);
28031
28548
  result.push({ absolutePath: cwdResolved, remoteUrl });
28032
28549
  }
28033
28550
  let entries;
28034
28551
  try {
28035
- entries = fs2.readdirSync(cwdResolved, { withFileTypes: true });
28552
+ entries = fs7.readdirSync(cwdResolved, { withFileTypes: true });
28036
28553
  } catch {
28037
28554
  return result;
28038
28555
  }
28039
28556
  for (const ent of entries) {
28040
28557
  if (!ent.isDirectory()) continue;
28041
- const childPath = path4.join(cwdResolved, ent.name);
28558
+ const childPath = path5.join(cwdResolved, ent.name);
28042
28559
  if (await isGitRepoDirectory(childPath)) {
28043
28560
  const remoteUrl = await getRemoteOriginUrl(childPath);
28044
28561
  result.push({ absolutePath: childPath, remoteUrl });
@@ -28047,22 +28564,22 @@ async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
28047
28564
  return result;
28048
28565
  }
28049
28566
  async function discoverGitReposUnderRoot(rootAbs) {
28050
- const root = path4.resolve(rootAbs);
28567
+ const root = path5.resolve(rootAbs);
28051
28568
  const roots = [];
28052
28569
  async function walk(dir) {
28053
28570
  if (await isGitRepoDirectory(dir)) {
28054
- roots.push(path4.resolve(dir));
28571
+ roots.push(path5.resolve(dir));
28055
28572
  return;
28056
28573
  }
28057
28574
  let entries;
28058
28575
  try {
28059
- entries = fs2.readdirSync(dir, { withFileTypes: true });
28576
+ entries = fs7.readdirSync(dir, { withFileTypes: true });
28060
28577
  } catch {
28061
28578
  return;
28062
28579
  }
28063
28580
  for (const ent of entries) {
28064
28581
  if (!ent.isDirectory() || ent.name === ".git") continue;
28065
- await walk(path4.join(dir, ent.name));
28582
+ await walk(path5.join(dir, ent.name));
28066
28583
  }
28067
28584
  }
28068
28585
  await walk(root);
@@ -28076,13 +28593,13 @@ async function discoverGitReposUnderRoot(rootAbs) {
28076
28593
  }
28077
28594
 
28078
28595
  // src/git/pre-turn-snapshot.ts
28079
- var execFileAsync = promisify(execFile);
28596
+ var execFileAsync5 = promisify6(execFile6);
28080
28597
  function snapshotsDirForCwd(agentCwd) {
28081
- return path5.join(agentCwd, ".buildautomaton", "snapshots");
28598
+ return path6.join(agentCwd, ".buildautomaton", "snapshots");
28082
28599
  }
28083
28600
  async function gitStashCreate(repoRoot, log2) {
28084
28601
  try {
28085
- const { stdout } = await execFileAsync("git", ["stash", "create"], {
28602
+ const { stdout } = await execFileAsync5("git", ["stash", "create"], {
28086
28603
  cwd: repoRoot,
28087
28604
  maxBuffer: 10 * 1024 * 1024
28088
28605
  });
@@ -28096,7 +28613,7 @@ async function gitStashCreate(repoRoot, log2) {
28096
28613
  }
28097
28614
  async function gitRun(repoRoot, args, log2, label) {
28098
28615
  try {
28099
- await execFileAsync("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
28616
+ await execFileAsync5("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
28100
28617
  return { ok: true };
28101
28618
  } catch (e) {
28102
28619
  const msg = e instanceof Error ? e.message : String(e);
@@ -28107,7 +28624,7 @@ async function gitRun(repoRoot, args, log2, label) {
28107
28624
  async function resolveSnapshotRepoRoots(options) {
28108
28625
  const { worktreePaths, fallbackCwd, log: log2 } = options;
28109
28626
  if (worktreePaths?.length) {
28110
- const uniq = [...new Set(worktreePaths.map((p) => path5.resolve(p)))];
28627
+ const uniq = [...new Set(worktreePaths.map((p) => path6.resolve(p)))];
28111
28628
  return uniq;
28112
28629
  }
28113
28630
  try {
@@ -28130,7 +28647,7 @@ async function capturePreTurnSnapshot(options) {
28130
28647
  }
28131
28648
  const dir = snapshotsDirForCwd(agentCwd);
28132
28649
  try {
28133
- fs3.mkdirSync(dir, { recursive: true });
28650
+ fs8.mkdirSync(dir, { recursive: true });
28134
28651
  } catch (e) {
28135
28652
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
28136
28653
  }
@@ -28139,9 +28656,9 @@ async function capturePreTurnSnapshot(options) {
28139
28656
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
28140
28657
  repos
28141
28658
  };
28142
- const filePath = path5.join(dir, `${runId}.json`);
28659
+ const filePath = path6.join(dir, `${runId}.json`);
28143
28660
  try {
28144
- fs3.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
28661
+ fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
28145
28662
  } catch (e) {
28146
28663
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
28147
28664
  }
@@ -28154,7 +28671,7 @@ async function capturePreTurnSnapshot(options) {
28154
28671
  async function applyPreTurnSnapshot(filePath, log2) {
28155
28672
  let data;
28156
28673
  try {
28157
- const raw = fs3.readFileSync(filePath, "utf8");
28674
+ const raw = fs8.readFileSync(filePath, "utf8");
28158
28675
  data = JSON.parse(raw);
28159
28676
  } catch (e) {
28160
28677
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
@@ -28177,11 +28694,11 @@ async function applyPreTurnSnapshot(filePath, log2) {
28177
28694
  return { ok: true };
28178
28695
  }
28179
28696
  function snapshotFilePath(agentCwd, runId) {
28180
- return path5.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
28697
+ return path6.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
28181
28698
  }
28182
28699
 
28183
28700
  // src/git/session-git-queue.ts
28184
- var execFileAsync2 = promisify2(execFile2);
28701
+ var execFileAsync6 = promisify7(execFile7);
28185
28702
  var MAX_FULL_FILE_TEXT_BYTES = 512 * 1024;
28186
28703
  async function readWorkspaceFileAsUtf8(absPath) {
28187
28704
  try {
@@ -28214,7 +28731,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
28214
28731
  if (!repo.stashSha) continue;
28215
28732
  let namesRaw;
28216
28733
  try {
28217
- const { stdout } = await execFileAsync2("git", ["diff", "--name-only", repo.stashSha], {
28734
+ const { stdout } = await execFileAsync6("git", ["diff", "--name-only", repo.stashSha], {
28218
28735
  cwd: repo.path,
28219
28736
  maxBuffer: 10 * 1024 * 1024
28220
28737
  });
@@ -28226,11 +28743,11 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
28226
28743
  continue;
28227
28744
  }
28228
28745
  const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
28229
- const slug = path6.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
28746
+ const slug = path7.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
28230
28747
  for (const rel of lines) {
28231
28748
  if (rel.includes("..")) continue;
28232
28749
  try {
28233
- const { stdout: patchContent } = await execFileAsync2(
28750
+ const { stdout: patchContent } = await execFileAsync6(
28234
28751
  "git",
28235
28752
  ["diff", "--no-color", repo.stashSha, "--", rel],
28236
28753
  {
@@ -28240,7 +28757,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
28240
28757
  );
28241
28758
  if (!patchContent.trim()) continue;
28242
28759
  const displayPath = multiRepo ? `${slug}/${rel}` : rel;
28243
- const absFile = path6.join(repo.path, rel);
28760
+ const absFile = path7.join(repo.path, rel);
28244
28761
  const newText = await readWorkspaceFileAsUtf8(absFile);
28245
28762
  sendSessionUpdate({
28246
28763
  type: "session_file_change",
@@ -28302,7 +28819,9 @@ async function sendPromptToAgent(options) {
28302
28819
  ...augmentAuthFields(errStr)
28303
28820
  });
28304
28821
  if (!result.success) {
28305
- log2(`[Agent] ${result.error ?? "Error"}`);
28822
+ log2(
28823
+ `[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
28824
+ );
28306
28825
  }
28307
28826
  } catch (err) {
28308
28827
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -28320,8 +28839,8 @@ async function sendPromptToAgent(options) {
28320
28839
  }
28321
28840
 
28322
28841
  // src/agents/acp/ensure-acp-client.ts
28323
- import * as fs4 from "node:fs";
28324
- import * as path9 from "node:path";
28842
+ import * as fs9 from "node:fs";
28843
+ import * as path10 from "node:path";
28325
28844
 
28326
28845
  // src/error-message.ts
28327
28846
  function errorMessage(err) {
@@ -28341,16 +28860,16 @@ __export(claude_code_acp_client_exports, {
28341
28860
  createClaudeCodeAcpClient: () => createClaudeCodeAcpClient,
28342
28861
  detectLocalAgentPresence: () => detectLocalAgentPresence
28343
28862
  });
28344
- import { execFile as execFile4 } from "node:child_process";
28345
- import { promisify as promisify4 } from "node:util";
28863
+ import { execFile as execFile9 } from "node:child_process";
28864
+ import { promisify as promisify9 } from "node:util";
28346
28865
 
28347
28866
  // src/agents/acp/clients/detect-command-on-path.ts
28348
- import { execFile as execFile3 } from "node:child_process";
28349
- import { promisify as promisify3 } from "node:util";
28350
- var execFileAsync3 = promisify3(execFile3);
28867
+ import { execFile as execFile8 } from "node:child_process";
28868
+ import { promisify as promisify8 } from "node:util";
28869
+ var execFileAsync7 = promisify8(execFile8);
28351
28870
  async function isCommandOnPath(command, timeoutMs = 4e3) {
28352
28871
  try {
28353
- await execFileAsync3("which", [command], { timeout: timeoutMs });
28872
+ await execFileAsync7("which", [command], { timeout: timeoutMs });
28354
28873
  return true;
28355
28874
  } catch {
28356
28875
  return false;
@@ -28358,12 +28877,12 @@ async function isCommandOnPath(command, timeoutMs = 4e3) {
28358
28877
  }
28359
28878
 
28360
28879
  // src/agents/acp/clients/claude-code-acp-client.ts
28361
- var execFileAsync4 = promisify4(execFile4);
28880
+ var execFileAsync8 = promisify9(execFile9);
28362
28881
  var BACKEND_LOCAL_AGENT_TYPE = "claude-code";
28363
28882
  async function detectLocalAgentPresence() {
28364
28883
  if (await isCommandOnPath("claude")) return true;
28365
28884
  try {
28366
- await execFileAsync4("npx", ["--yes", "@anthropic-ai/claude-code", "--version"], { timeout: 25e3 });
28885
+ await execFileAsync8("npx", ["--yes", "@anthropic-ai/claude-code", "--version"], { timeout: 25e3 });
28367
28886
  return true;
28368
28887
  } catch {
28369
28888
  return false;
@@ -28478,7 +28997,7 @@ async function createCursorAcpClient(options) {
28478
28997
  onRequest,
28479
28998
  onFileChange
28480
28999
  } = options;
28481
- const dbgFs = process.env.BUILDAMATON_DEBUG_ACP_FS === "1";
29000
+ const dbgFs = process.env.BUILDAUTOMATON_DEBUG_ACP_FS === "1";
28482
29001
  const isWindows = process.platform === "win32";
28483
29002
  const child = spawn4(command[0], command.slice(1), {
28484
29003
  cwd,
@@ -28861,48 +29380,48 @@ function resolveAgentCommand(preferredAgentType) {
28861
29380
  }
28862
29381
 
28863
29382
  // src/agents/acp/session-file-change-path-kind.ts
28864
- import { execFileSync as execFileSync3 } from "node:child_process";
29383
+ import { execFileSync as execFileSync4 } from "node:child_process";
28865
29384
  import { existsSync, statSync } from "node:fs";
28866
29385
 
28867
29386
  // src/git/get-git-repo-root-sync.ts
28868
- import { execFileSync } from "node:child_process";
28869
- import * as path7 from "node:path";
29387
+ import { execFileSync as execFileSync2 } from "node:child_process";
29388
+ import * as path8 from "node:path";
28870
29389
  function getGitRepoRootSync(startDir) {
28871
29390
  try {
28872
- const out = execFileSync("git", ["rev-parse", "--show-toplevel"], {
28873
- cwd: path7.resolve(startDir),
29391
+ const out = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
29392
+ cwd: path8.resolve(startDir),
28874
29393
  encoding: "utf8",
28875
29394
  stdio: ["ignore", "pipe", "ignore"],
28876
29395
  maxBuffer: 1024 * 1024
28877
29396
  }).trim();
28878
- return out ? path7.resolve(out) : null;
29397
+ return out ? path8.resolve(out) : null;
28879
29398
  } catch {
28880
29399
  return null;
28881
29400
  }
28882
29401
  }
28883
29402
 
28884
29403
  // src/agents/acp/workspace-files.ts
28885
- import { execFileSync as execFileSync2 } from "node:child_process";
29404
+ import { execFileSync as execFileSync3 } from "node:child_process";
28886
29405
  import { readFileSync as readFileSync4 } from "node:fs";
28887
- import * as path8 from "node:path";
29406
+ import * as path9 from "node:path";
28888
29407
  function resolveWorkspaceFilePath(cwd, rawPath) {
28889
29408
  const trimmed2 = rawPath.trim();
28890
29409
  if (!trimmed2) return null;
28891
- const normalizedCwd = path8.resolve(cwd);
29410
+ const normalizedCwd = path9.resolve(cwd);
28892
29411
  let abs = resolveSafePathUnderCwd(cwd, trimmed2);
28893
29412
  if (!abs) {
28894
- const candidate = path8.isAbsolute(trimmed2) ? path8.normalize(trimmed2) : path8.normalize(path8.resolve(normalizedCwd, trimmed2));
29413
+ const candidate = path9.isAbsolute(trimmed2) ? path9.normalize(trimmed2) : path9.normalize(path9.resolve(normalizedCwd, trimmed2));
28895
29414
  const gitRoot2 = getGitRepoRootSync(cwd);
28896
29415
  if (!gitRoot2) return null;
28897
- const rel = path8.relative(gitRoot2, candidate);
28898
- if (rel.startsWith("..") || path8.isAbsolute(rel)) return null;
29416
+ const rel = path9.relative(gitRoot2, candidate);
29417
+ if (rel.startsWith("..") || path9.isAbsolute(rel)) return null;
28899
29418
  abs = candidate;
28900
29419
  }
28901
29420
  const gitRoot = getGitRepoRootSync(cwd);
28902
29421
  if (gitRoot) {
28903
- const relFromRoot = path8.relative(gitRoot, abs);
28904
- if (!relFromRoot.startsWith("..") && !path8.isAbsolute(relFromRoot)) {
28905
- return { abs, display: relFromRoot.split(path8.sep).join("/") };
29422
+ const relFromRoot = path9.relative(gitRoot, abs);
29423
+ if (!relFromRoot.startsWith("..") && !path9.isAbsolute(relFromRoot)) {
29424
+ return { abs, display: relFromRoot.split(path9.sep).join("/") };
28906
29425
  }
28907
29426
  }
28908
29427
  return { abs, display: toDisplayPathRelativeToCwd(cwd, abs) };
@@ -28911,9 +29430,9 @@ function readUtf8WorkspaceFile(cwd, displayPath) {
28911
29430
  if (!displayPath || displayPath.includes("..")) return "";
28912
29431
  const gitRoot = getGitRepoRootSync(cwd);
28913
29432
  if (gitRoot) {
28914
- const abs2 = path8.resolve(gitRoot, displayPath);
28915
- const rel = path8.relative(gitRoot, abs2);
28916
- if (!rel.startsWith("..") && !path8.isAbsolute(rel)) {
29433
+ const abs2 = path9.resolve(gitRoot, displayPath);
29434
+ const rel = path9.relative(gitRoot, abs2);
29435
+ if (!rel.startsWith("..") && !path9.isAbsolute(rel)) {
28917
29436
  try {
28918
29437
  return readFileSync4(abs2, "utf8");
28919
29438
  } catch {
@@ -28932,9 +29451,9 @@ function tryWorkspaceDisplayToAbs(cwd, displayPath) {
28932
29451
  if (!displayPath || displayPath.includes("..")) return null;
28933
29452
  const gitRoot = getGitRepoRootSync(cwd);
28934
29453
  if (gitRoot) {
28935
- const abs = path8.resolve(gitRoot, displayPath);
28936
- const rel = path8.relative(gitRoot, abs);
28937
- if (!rel.startsWith("..") && !path8.isAbsolute(rel)) return abs;
29454
+ const abs = path9.resolve(gitRoot, displayPath);
29455
+ const rel = path9.relative(gitRoot, abs);
29456
+ if (!rel.startsWith("..") && !path9.isAbsolute(rel)) return abs;
28938
29457
  }
28939
29458
  return resolveSafePathUnderCwd(cwd, displayPath);
28940
29459
  }
@@ -28943,7 +29462,7 @@ function readGitHeadBlob(cwd, displayPath) {
28943
29462
  const gitRoot = getGitRepoRootSync(cwd);
28944
29463
  const execCwd = gitRoot ?? cwd;
28945
29464
  try {
28946
- return execFileSync2("git", ["show", `HEAD:${displayPath}`], {
29465
+ return execFileSync3("git", ["show", `HEAD:${displayPath}`], {
28947
29466
  cwd: execCwd,
28948
29467
  encoding: "utf8",
28949
29468
  maxBuffer: 50 * 1024 * 1024
@@ -28959,7 +29478,7 @@ function gitHeadPathObjectType(cwd, displayPath) {
28959
29478
  const gitRoot = getGitRepoRootSync(cwd);
28960
29479
  if (!gitRoot) return null;
28961
29480
  try {
28962
- return execFileSync3("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
29481
+ return execFileSync4("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
28963
29482
  cwd: gitRoot,
28964
29483
  encoding: "utf8"
28965
29484
  }).trim();
@@ -29050,7 +29569,7 @@ function createBridgeOnRequest(opts) {
29050
29569
  }
29051
29570
 
29052
29571
  // src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
29053
- import { fileURLToPath } from "node:url";
29572
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
29054
29573
  function readOptionalTextField(v) {
29055
29574
  if (v === null || v === void 0) return "";
29056
29575
  if (typeof v === "string") return v;
@@ -29060,7 +29579,7 @@ function normalizePathField(raw) {
29060
29579
  const t = raw.trim();
29061
29580
  if (t.startsWith("file://")) {
29062
29581
  try {
29063
- return fileURLToPath(t);
29582
+ return fileURLToPath2(t);
29064
29583
  } catch {
29065
29584
  return t;
29066
29585
  }
@@ -29502,10 +30021,10 @@ function buildAcpSessionBridgeHooks(opts) {
29502
30021
  // src/agents/acp/ensure-acp-client.ts
29503
30022
  async function ensureAcpClient(options) {
29504
30023
  const { state, preferredAgentType, mode, cwd, routing, sendSessionUpdate, sendRequest, log: log2 } = options;
29505
- const targetCwd = path9.resolve(
30024
+ const targetCwd = path10.resolve(
29506
30025
  cwd != null && String(cwd).trim() !== "" ? String(cwd).trim() : getBridgeWorkspaceDirectory()
29507
30026
  );
29508
- if (state.acpHandle && state.lastAcpCwd != null && path9.resolve(state.lastAcpCwd) !== path9.resolve(targetCwd)) {
30027
+ if (state.acpHandle && state.lastAcpCwd != null && path10.resolve(state.lastAcpCwd) !== path10.resolve(targetCwd)) {
29509
30028
  try {
29510
30029
  state.acpHandle.disconnect();
29511
30030
  } catch {
@@ -29537,7 +30056,7 @@ async function ensureAcpClient(options) {
29537
30056
  if (!state.acpStartPromise) {
29538
30057
  let statOk = false;
29539
30058
  try {
29540
- const st = fs4.statSync(targetCwd);
30059
+ const st = fs9.statSync(targetCwd);
29541
30060
  statOk = st.isDirectory();
29542
30061
  if (!statOk) {
29543
30062
  state.lastAcpStartError = `Agent cwd is not a directory: ${targetCwd}`;
@@ -29733,12 +30252,12 @@ async function createAcpManager(options) {
29733
30252
  }
29734
30253
 
29735
30254
  // src/worktrees/session-worktree-manager.ts
29736
- import * as path15 from "node:path";
29737
- import os3 from "node:os";
30255
+ import * as path16 from "node:path";
30256
+ import os4 from "node:os";
29738
30257
 
29739
30258
  // src/worktrees/prepare-new-session-worktrees.ts
29740
- import * as fs6 from "node:fs";
29741
- import * as path11 from "node:path";
30259
+ import * as fs11 from "node:fs";
30260
+ import * as path12 from "node:path";
29742
30261
 
29743
30262
  // src/git/worktree-add.ts
29744
30263
  async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
@@ -29747,12 +30266,12 @@ async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
29747
30266
  }
29748
30267
 
29749
30268
  // src/worktrees/worktree-layout-file.ts
29750
- import * as fs5 from "node:fs";
29751
- import * as path10 from "node:path";
29752
- import os2 from "node:os";
30269
+ import * as fs10 from "node:fs";
30270
+ import * as path11 from "node:path";
30271
+ import os3 from "node:os";
29753
30272
  var LAYOUT_FILENAME = "worktree-launcher-layout.json";
29754
30273
  function defaultWorktreeLayoutPath() {
29755
- return path10.join(os2.homedir(), ".buildautomaton", LAYOUT_FILENAME);
30274
+ return path11.join(os3.homedir(), ".buildautomaton", LAYOUT_FILENAME);
29756
30275
  }
29757
30276
  function normalizeLoadedLayout(raw) {
29758
30277
  if (raw && typeof raw === "object" && "launcherCwds" in raw) {
@@ -29764,8 +30283,8 @@ function normalizeLoadedLayout(raw) {
29764
30283
  function loadWorktreeLayout() {
29765
30284
  try {
29766
30285
  const p = defaultWorktreeLayoutPath();
29767
- if (!fs5.existsSync(p)) return { launcherCwds: [] };
29768
- const raw = JSON.parse(fs5.readFileSync(p, "utf8"));
30286
+ if (!fs10.existsSync(p)) return { launcherCwds: [] };
30287
+ const raw = JSON.parse(fs10.readFileSync(p, "utf8"));
29769
30288
  return normalizeLoadedLayout(raw);
29770
30289
  } catch {
29771
30290
  return { launcherCwds: [] };
@@ -29773,18 +30292,18 @@ function loadWorktreeLayout() {
29773
30292
  }
29774
30293
  function saveWorktreeLayout(layout) {
29775
30294
  try {
29776
- const dir = path10.dirname(defaultWorktreeLayoutPath());
29777
- fs5.mkdirSync(dir, { recursive: true });
29778
- fs5.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
30295
+ const dir = path11.dirname(defaultWorktreeLayoutPath());
30296
+ fs10.mkdirSync(dir, { recursive: true });
30297
+ fs10.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
29779
30298
  } catch {
29780
30299
  }
29781
30300
  }
29782
30301
  function baseNameSafe(abs) {
29783
- return path10.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
30302
+ return path11.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
29784
30303
  }
29785
30304
  function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
29786
- const norm = path10.resolve(launcherCwdAbs);
29787
- const existing = layout.launcherCwds.find((e) => path10.resolve(e.absolutePath) === norm);
30305
+ const norm = path11.resolve(launcherCwdAbs);
30306
+ const existing = layout.launcherCwds.find((e) => path11.resolve(e.absolutePath) === norm);
29788
30307
  if (existing) return existing.dirName;
29789
30308
  const base = baseNameSafe(norm);
29790
30309
  const used = new Set(layout.launcherCwds.map((e) => e.dirName));
@@ -29802,9 +30321,9 @@ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
29802
30321
  // src/worktrees/prepare-new-session-worktrees.ts
29803
30322
  async function prepareNewSessionWorktrees(options) {
29804
30323
  const { rootAbs, launcherCwd, sessionId, layout, log: log2 } = options;
29805
- const launcherResolved = path11.resolve(launcherCwd);
30324
+ const launcherResolved = path12.resolve(launcherCwd);
29806
30325
  const cwdKey = allocateDirNameForLauncherCwd(layout, launcherResolved);
29807
- const agentMirrorRoot = path11.join(rootAbs, cwdKey);
30326
+ const agentMirrorRoot = path12.join(rootAbs, cwdKey);
29808
30327
  const repos = await discoverGitReposUnderRoot(launcherResolved);
29809
30328
  if (repos.length === 0) {
29810
30329
  log2("[worktrees] No Git repositories under launcher working directory; skipping worktree creation.");
@@ -29812,13 +30331,13 @@ async function prepareNewSessionWorktrees(options) {
29812
30331
  }
29813
30332
  const branch = `session-${sessionId}`;
29814
30333
  const worktreePaths = [];
29815
- fs6.mkdirSync(agentMirrorRoot, { recursive: true });
30334
+ fs11.mkdirSync(agentMirrorRoot, { recursive: true });
29816
30335
  for (const repo of repos) {
29817
- let rel = path11.relative(launcherResolved, repo.absolutePath);
29818
- if (rel.startsWith("..") || path11.isAbsolute(rel)) continue;
30336
+ let rel = path12.relative(launcherResolved, repo.absolutePath);
30337
+ if (rel.startsWith("..") || path12.isAbsolute(rel)) continue;
29819
30338
  const relNorm = rel === "" ? "." : rel;
29820
- const wtPath = path11.join(agentMirrorRoot, relNorm, sessionId);
29821
- fs6.mkdirSync(path11.dirname(wtPath), { recursive: true });
30339
+ const wtPath = path12.join(agentMirrorRoot, relNorm, sessionId);
30340
+ fs11.mkdirSync(path12.dirname(wtPath), { recursive: true });
29822
30341
  try {
29823
30342
  await gitWorktreeAddBranch(repo.absolutePath, wtPath, branch);
29824
30343
  log2(`[worktrees] Added worktree ${wtPath} (branch ${branch}).`);
@@ -29855,23 +30374,23 @@ async function renameSessionWorktreeBranches(paths, newBranch, log2) {
29855
30374
  }
29856
30375
 
29857
30376
  // src/worktrees/remove-session-worktrees.ts
29858
- import * as fs9 from "node:fs";
30377
+ import * as fs14 from "node:fs";
29859
30378
 
29860
30379
  // src/git/worktree-remove.ts
29861
- import * as fs8 from "node:fs";
30380
+ import * as fs13 from "node:fs";
29862
30381
 
29863
30382
  // src/git/resolve-main-repo-from-git-file.ts
29864
- import * as fs7 from "node:fs";
29865
- import * as path12 from "node:path";
30383
+ import * as fs12 from "node:fs";
30384
+ import * as path13 from "node:path";
29866
30385
  function resolveMainRepoFromWorktreeGitFile(wt) {
29867
- const gitDirFile = path12.join(wt, ".git");
29868
- if (!fs7.existsSync(gitDirFile) || !fs7.statSync(gitDirFile).isFile()) return "";
29869
- const first2 = fs7.readFileSync(gitDirFile, "utf8").trim();
30386
+ const gitDirFile = path13.join(wt, ".git");
30387
+ if (!fs12.existsSync(gitDirFile) || !fs12.statSync(gitDirFile).isFile()) return "";
30388
+ const first2 = fs12.readFileSync(gitDirFile, "utf8").trim();
29870
30389
  const m = first2.match(/^gitdir:\s*(.+)$/im);
29871
30390
  if (!m) return "";
29872
- const gitWorktreePath = path12.resolve(wt, m[1].trim());
29873
- const gitDir = path12.dirname(path12.dirname(gitWorktreePath));
29874
- return path12.dirname(gitDir);
30391
+ const gitWorktreePath = path13.resolve(wt, m[1].trim());
30392
+ const gitDir = path13.dirname(path13.dirname(gitWorktreePath));
30393
+ return path13.dirname(gitDir);
29875
30394
  }
29876
30395
 
29877
30396
  // src/git/worktree-remove.ts
@@ -29880,7 +30399,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
29880
30399
  if (mainRepo) {
29881
30400
  await simpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
29882
30401
  } else {
29883
- fs8.rmSync(worktreePath, { recursive: true, force: true });
30402
+ fs13.rmSync(worktreePath, { recursive: true, force: true });
29884
30403
  }
29885
30404
  }
29886
30405
 
@@ -29893,7 +30412,7 @@ async function removeSessionWorktrees(paths, log2) {
29893
30412
  } catch (e) {
29894
30413
  log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
29895
30414
  try {
29896
- fs9.rmSync(wt, { recursive: true, force: true });
30415
+ fs14.rmSync(wt, { recursive: true, force: true });
29897
30416
  } catch {
29898
30417
  }
29899
30418
  }
@@ -30113,7 +30632,7 @@ function formatRemoteDisplayLabel(remoteUrl) {
30113
30632
  }
30114
30633
 
30115
30634
  // src/git/working-directory/changes/get-working-tree-change-repo-details.ts
30116
- import * as path14 from "node:path";
30635
+ import * as path15 from "node:path";
30117
30636
 
30118
30637
  // src/git/working-directory/changes/parse-git-status.ts
30119
30638
  function parseNameStatusLines(lines) {
@@ -30233,8 +30752,8 @@ async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
30233
30752
  }
30234
30753
 
30235
30754
  // src/git/working-directory/changes/list-changed-files-for-repo.ts
30236
- import * as fs11 from "node:fs";
30237
- import * as path13 from "node:path";
30755
+ import * as fs16 from "node:fs";
30756
+ import * as path14 from "node:path";
30238
30757
 
30239
30758
  // src/git/working-directory/changes/count-lines.ts
30240
30759
  import { createReadStream } from "node:fs";
@@ -30258,7 +30777,7 @@ async function countTextFileLines(absFile) {
30258
30777
  }
30259
30778
 
30260
30779
  // src/git/working-directory/changes/hydrate-patch.ts
30261
- import * as fs10 from "node:fs";
30780
+ import * as fs15 from "node:fs";
30262
30781
  var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
30263
30782
  var MAX_HYDRATE_LINES_PER_GAP = 8e3;
30264
30783
  var MAX_HYDRATE_LINES_PER_FILE = 8e4;
@@ -30273,7 +30792,7 @@ async function readGitBlobLines(repoCwd, pathInRepo) {
30273
30792
  }
30274
30793
  async function readWorktreeFileLines(abs) {
30275
30794
  try {
30276
- const raw = await fs10.promises.readFile(abs, "utf8");
30795
+ const raw = await fs15.promises.readFile(abs, "utf8");
30277
30796
  return raw.split(/\r?\n/);
30278
30797
  } catch {
30279
30798
  return null;
@@ -30408,7 +30927,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
30408
30927
  const rows = [];
30409
30928
  for (const pathInRepo of paths) {
30410
30929
  const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
30411
- const abs = path13.join(repoGitCwd, pathInRepo);
30930
+ const abs = path14.join(repoGitCwd, pathInRepo);
30412
30931
  const nums = numByPath.get(pathInRepo);
30413
30932
  let additions = nums?.additions ?? 0;
30414
30933
  let deletions = nums?.deletions ?? 0;
@@ -30421,7 +30940,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
30421
30940
  deletions = fromGit.deletions;
30422
30941
  } else {
30423
30942
  try {
30424
- const st = await fs11.promises.stat(abs);
30943
+ const st = await fs16.promises.stat(abs);
30425
30944
  if (st.isFile()) additions = await countTextFileLines(abs);
30426
30945
  else additions = 0;
30427
30946
  } catch {
@@ -30447,7 +30966,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
30447
30966
  } else {
30448
30967
  pathInRepo = row.pathRelLauncher;
30449
30968
  }
30450
- const absFile = path13.join(repoGitCwd, pathInRepo);
30969
+ const absFile = path14.join(repoGitCwd, pathInRepo);
30451
30970
  let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
30452
30971
  if (patch) {
30453
30972
  patch = await hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, row.change);
@@ -30463,8 +30982,8 @@ function normRepoRel(p) {
30463
30982
  return x === "" ? "." : x;
30464
30983
  }
30465
30984
  async function getWorkingTreeChangeRepoDetails(options) {
30466
- const launcher = path14.resolve(getBridgeWorkspaceDirectory());
30467
- const mirror = options.agentMirrorRootAbs ? path14.resolve(options.agentMirrorRootAbs) : null;
30985
+ const launcher = path15.resolve(getBridgeWorkspaceDirectory());
30986
+ const mirror = options.agentMirrorRootAbs ? path15.resolve(options.agentMirrorRootAbs) : null;
30468
30987
  const out = [];
30469
30988
  const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
30470
30989
  const basisInput = options.basis ?? { kind: "working" };
@@ -30476,7 +30995,7 @@ async function getWorkingTreeChangeRepoDetails(options) {
30476
30995
  }
30477
30996
  const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
30478
30997
  for (const target of options.commitTargetAbsDirs) {
30479
- const t = path14.resolve(target);
30998
+ const t = path15.resolve(target);
30480
30999
  if (!await isGitRepoDirectory(t)) continue;
30481
31000
  const g = simpleGit(t);
30482
31001
  let branch = "HEAD";
@@ -30489,7 +31008,7 @@ async function getWorkingTreeChangeRepoDetails(options) {
30489
31008
  const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
30490
31009
  let repoRelPath;
30491
31010
  if (mirror) {
30492
- const relNorm = path14.relative(mirror, path14.dirname(t));
31011
+ const relNorm = path15.relative(mirror, path15.dirname(t));
30493
31012
  repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
30494
31013
  } else {
30495
31014
  let top = t;
@@ -30498,8 +31017,8 @@ async function getWorkingTreeChangeRepoDetails(options) {
30498
31017
  } catch {
30499
31018
  top = t;
30500
31019
  }
30501
- const rel = path14.relative(launcher, path14.resolve(top)).replace(/\\/g, "/") || ".";
30502
- repoRelPath = rel.startsWith("..") ? path14.basename(path14.resolve(top)) : rel;
31020
+ const rel = path15.relative(launcher, path15.resolve(top)).replace(/\\/g, "/") || ".";
31021
+ repoRelPath = rel.startsWith("..") ? path15.basename(path15.resolve(top)) : rel;
30503
31022
  }
30504
31023
  const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
30505
31024
  if (filter && norm !== filter) continue;
@@ -30591,7 +31110,7 @@ var SessionWorktreeManager = class {
30591
31110
  }
30592
31111
  if (!opts.isNewSession) {
30593
31112
  const agentCwd = this.sessionAgentCwd.get(sessionId);
30594
- if (agentCwd) return path15.resolve(agentCwd);
31113
+ if (agentCwd) return path16.resolve(agentCwd);
30595
31114
  return void 0;
30596
31115
  }
30597
31116
  const prep = await prepareNewSessionWorktrees({
@@ -30604,7 +31123,7 @@ var SessionWorktreeManager = class {
30604
31123
  if (!prep) return void 0;
30605
31124
  this.sessionPaths.set(sessionId, prep.worktreePaths);
30606
31125
  this.sessionAgentCwd.set(sessionId, prep.agentCwd);
30607
- return path15.resolve(prep.agentCwd);
31126
+ return path16.resolve(prep.agentCwd);
30608
31127
  }
30609
31128
  async renameSessionBranch(sessionId, newBranch) {
30610
31129
  const paths = this.sessionPaths.get(sessionId);
@@ -30625,7 +31144,7 @@ var SessionWorktreeManager = class {
30625
31144
  getAgentCwdForSession(sessionId) {
30626
31145
  if (!sessionId) return null;
30627
31146
  const c = this.sessionAgentCwd.get(sessionId);
30628
- return c ? path15.resolve(c) : null;
31147
+ return c ? path16.resolve(c) : null;
30629
31148
  }
30630
31149
  async removeSessionWorktrees(sessionId) {
30631
31150
  const paths = this.sessionPaths.get(sessionId);
@@ -30673,15 +31192,15 @@ var SessionWorktreeManager = class {
30673
31192
  }
30674
31193
  };
30675
31194
  function defaultWorktreesRootAbs() {
30676
- return path15.join(os3.homedir(), ".buildautomaton", "worktrees");
31195
+ return path16.join(os4.homedir(), ".buildautomaton", "worktrees");
30677
31196
  }
30678
31197
 
30679
31198
  // src/files/watch-file-index.ts
30680
31199
  import { watch } from "node:fs";
30681
- import path22 from "node:path";
31200
+ import path23 from "node:path";
30682
31201
 
30683
31202
  // src/files/index/build-file-index.ts
30684
- import path19 from "node:path";
31203
+ import path20 from "node:path";
30685
31204
 
30686
31205
  // src/runtime/yield-to-event-loop.ts
30687
31206
  function yieldToEventLoop() {
@@ -30689,14 +31208,14 @@ function yieldToEventLoop() {
30689
31208
  }
30690
31209
 
30691
31210
  // src/files/index/walk-workspace-tree.ts
30692
- import fs12 from "node:fs";
30693
- import path17 from "node:path";
31211
+ import fs17 from "node:fs";
31212
+ import path18 from "node:path";
30694
31213
 
30695
31214
  // src/files/index/constants.ts
30696
- import path16 from "node:path";
30697
- import os4 from "node:os";
31215
+ import path17 from "node:path";
31216
+ import os5 from "node:os";
30698
31217
  var INDEX_WORK_YIELD_EVERY = 256;
30699
- var INDEX_DIR = path16.join(os4.homedir(), ".buildautomaton");
31218
+ var INDEX_DIR = path17.join(os5.homedir(), ".buildautomaton");
30700
31219
  var INDEX_HASH_LEN = 16;
30701
31220
  var INDEX_VERSION = 2;
30702
31221
  var INDEX_LOG_PREFIX = "[file-index]";
@@ -30705,20 +31224,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
30705
31224
  function walkWorkspaceTreeSync(dir, baseDir, out) {
30706
31225
  let names;
30707
31226
  try {
30708
- names = fs12.readdirSync(dir);
31227
+ names = fs17.readdirSync(dir);
30709
31228
  } catch {
30710
31229
  return;
30711
31230
  }
30712
31231
  for (const name of names) {
30713
31232
  if (name.startsWith(".")) continue;
30714
- const full = path17.join(dir, name);
31233
+ const full = path18.join(dir, name);
30715
31234
  let stat2;
30716
31235
  try {
30717
- stat2 = fs12.statSync(full);
31236
+ stat2 = fs17.statSync(full);
30718
31237
  } catch {
30719
31238
  continue;
30720
31239
  }
30721
- const relative5 = path17.relative(baseDir, full).replace(/\\/g, "/");
31240
+ const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
30722
31241
  if (stat2.isDirectory()) {
30723
31242
  walkWorkspaceTreeSync(full, baseDir, out);
30724
31243
  } else if (stat2.isFile()) {
@@ -30729,7 +31248,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
30729
31248
  async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
30730
31249
  let names;
30731
31250
  try {
30732
- names = await fs12.promises.readdir(dir);
31251
+ names = await fs17.promises.readdir(dir);
30733
31252
  } catch {
30734
31253
  return;
30735
31254
  }
@@ -30739,14 +31258,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
30739
31258
  await yieldToEventLoop();
30740
31259
  }
30741
31260
  state.n++;
30742
- const full = path17.join(dir, name);
31261
+ const full = path18.join(dir, name);
30743
31262
  let stat2;
30744
31263
  try {
30745
- stat2 = await fs12.promises.stat(full);
31264
+ stat2 = await fs17.promises.stat(full);
30746
31265
  } catch {
30747
31266
  continue;
30748
31267
  }
30749
- const relative5 = path17.relative(baseDir, full).replace(/\\/g, "/");
31268
+ const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
30750
31269
  if (stat2.isDirectory()) {
30751
31270
  await walkWorkspaceTreeAsync(full, baseDir, out, state);
30752
31271
  } else if (stat2.isFile()) {
@@ -30827,22 +31346,22 @@ async function buildTrigramMapForPathsAsync(paths) {
30827
31346
  }
30828
31347
 
30829
31348
  // src/files/index/write-index-file.ts
30830
- import fs13 from "node:fs";
31349
+ import fs18 from "node:fs";
30831
31350
 
30832
31351
  // src/files/index/paths.ts
30833
- import path18 from "node:path";
31352
+ import path19 from "node:path";
30834
31353
  import crypto2 from "node:crypto";
30835
31354
  function getIndexPathForCwd(resolvedCwd) {
30836
31355
  const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
30837
- return path18.join(INDEX_DIR, `.file-index-${hash}.json`);
31356
+ return path19.join(INDEX_DIR, `.file-index-${hash}.json`);
30838
31357
  }
30839
31358
 
30840
31359
  // src/files/index/write-index-file.ts
30841
31360
  function writeIndexFileSync(resolvedCwd, data) {
30842
31361
  const indexPath = getIndexPathForCwd(resolvedCwd);
30843
31362
  try {
30844
- if (!fs13.existsSync(INDEX_DIR)) fs13.mkdirSync(INDEX_DIR, { recursive: true });
30845
- fs13.writeFileSync(indexPath, JSON.stringify(data), "utf8");
31363
+ if (!fs18.existsSync(INDEX_DIR)) fs18.mkdirSync(INDEX_DIR, { recursive: true });
31364
+ fs18.writeFileSync(indexPath, JSON.stringify(data), "utf8");
30846
31365
  } catch (e) {
30847
31366
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
30848
31367
  }
@@ -30850,8 +31369,8 @@ function writeIndexFileSync(resolvedCwd, data) {
30850
31369
  async function writeIndexFileAsync(resolvedCwd, data) {
30851
31370
  const indexPath = getIndexPathForCwd(resolvedCwd);
30852
31371
  try {
30853
- await fs13.promises.mkdir(INDEX_DIR, { recursive: true });
30854
- await fs13.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
31372
+ await fs18.promises.mkdir(INDEX_DIR, { recursive: true });
31373
+ await fs18.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
30855
31374
  } catch (e) {
30856
31375
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
30857
31376
  }
@@ -30865,7 +31384,7 @@ function sortPaths(paths) {
30865
31384
  paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
30866
31385
  }
30867
31386
  function buildFileIndex(cwd) {
30868
- const resolved = path19.resolve(cwd);
31387
+ const resolved = path20.resolve(cwd);
30869
31388
  const paths = [];
30870
31389
  walkWorkspaceTreeSync(resolved, resolved, paths);
30871
31390
  sortPaths(paths);
@@ -30875,7 +31394,7 @@ function buildFileIndex(cwd) {
30875
31394
  return data;
30876
31395
  }
30877
31396
  async function buildFileIndexAsync(cwd) {
30878
- const resolved = path19.resolve(cwd);
31397
+ const resolved = path20.resolve(cwd);
30879
31398
  const paths = [];
30880
31399
  await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
30881
31400
  await yieldToEventLoop();
@@ -30887,13 +31406,13 @@ async function buildFileIndexAsync(cwd) {
30887
31406
  }
30888
31407
 
30889
31408
  // src/files/index/load-file-index.ts
30890
- import fs14 from "node:fs";
30891
- import path20 from "node:path";
31409
+ import fs19 from "node:fs";
31410
+ import path21 from "node:path";
30892
31411
  function loadFileIndex(cwd) {
30893
- const resolved = path20.resolve(cwd);
31412
+ const resolved = path21.resolve(cwd);
30894
31413
  const indexPath = getIndexPathForCwd(resolved);
30895
31414
  try {
30896
- const raw = fs14.readFileSync(indexPath, "utf8");
31415
+ const raw = fs19.readFileSync(indexPath, "utf8");
30897
31416
  const parsed = JSON.parse(raw);
30898
31417
  if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
30899
31418
  const obj = parsed;
@@ -30912,9 +31431,9 @@ function loadFileIndex(cwd) {
30912
31431
  }
30913
31432
 
30914
31433
  // src/files/index/ensure-file-index.ts
30915
- import path21 from "node:path";
31434
+ import path22 from "node:path";
30916
31435
  async function ensureFileIndexAsync(cwd) {
30917
- const resolved = path21.resolve(cwd);
31436
+ const resolved = path22.resolve(cwd);
30918
31437
  const cached2 = loadFileIndex(resolved);
30919
31438
  if (cached2 !== null) return { data: cached2, fromCache: true };
30920
31439
  const data = await buildFileIndexAsync(resolved);
@@ -30997,7 +31516,7 @@ function createFsWatcher(resolved, schedule) {
30997
31516
  }
30998
31517
  }
30999
31518
  function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
31000
- const resolved = path22.resolve(cwd);
31519
+ const resolved = path23.resolve(cwd);
31001
31520
  void buildFileIndexAsync(resolved).catch((e) => {
31002
31521
  console.error("[file-index] Initial index build failed:", e);
31003
31522
  });
@@ -31025,7 +31544,7 @@ function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
31025
31544
  }
31026
31545
 
31027
31546
  // src/dev-servers/manager/dev-server-manager.ts
31028
- import { rm } from "node:fs/promises";
31547
+ import { rm as rm2 } from "node:fs/promises";
31029
31548
 
31030
31549
  // src/dev-servers/process/send-server-status.ts
31031
31550
  function sendDevServerStatus(getWs, serverId, status, options) {
@@ -31066,7 +31585,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
31066
31585
  }
31067
31586
 
31068
31587
  // src/dev-servers/process/wire-dev-server-child-process.ts
31069
- import fs15 from "node:fs";
31588
+ import fs20 from "node:fs";
31070
31589
 
31071
31590
  // src/dev-servers/manager/forward-pipe.ts
31072
31591
  function forwardChildPipe(childReadable, terminal, onData) {
@@ -31102,7 +31621,7 @@ function wireDevServerChildProcess(d) {
31102
31621
  d.setPollInterval(void 0);
31103
31622
  return;
31104
31623
  }
31105
- fs15.readFile(d.mergedLogPath, (err, buf) => {
31624
+ fs20.readFile(d.mergedLogPath, (err, buf) => {
31106
31625
  if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
31107
31626
  if (buf.length <= d.mergedReadPos.value) return;
31108
31627
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
@@ -31140,7 +31659,7 @@ ${errTail}` : ""}`);
31140
31659
  d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
31141
31660
  };
31142
31661
  if (mergedPath) {
31143
- fs15.readFile(mergedPath, (err, buf) => {
31662
+ fs20.readFile(mergedPath, (err, buf) => {
31144
31663
  if (!err && buf.length > d.mergedReadPos.value) {
31145
31664
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
31146
31665
  if (chunk.length > 0) {
@@ -31242,13 +31761,13 @@ function parseDevServerDefs(servers) {
31242
31761
  }
31243
31762
 
31244
31763
  // src/dev-servers/manager/shell-spawn/utils.ts
31245
- import fs16 from "node:fs";
31764
+ import fs21 from "node:fs";
31246
31765
  function isSpawnEbadf(e) {
31247
31766
  return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
31248
31767
  }
31249
31768
  function rmDirQuiet(dir) {
31250
31769
  try {
31251
- fs16.rmSync(dir, { recursive: true, force: true });
31770
+ fs21.rmSync(dir, { recursive: true, force: true });
31252
31771
  } catch {
31253
31772
  }
31254
31773
  }
@@ -31256,7 +31775,7 @@ var cachedDevNullReadFd;
31256
31775
  function devNullReadFd() {
31257
31776
  if (cachedDevNullReadFd === void 0) {
31258
31777
  const devPath = process.platform === "win32" ? "nul" : "/dev/null";
31259
- cachedDevNullReadFd = fs16.openSync(devPath, "r");
31778
+ cachedDevNullReadFd = fs21.openSync(devPath, "r");
31260
31779
  }
31261
31780
  return cachedDevNullReadFd;
31262
31781
  }
@@ -31330,15 +31849,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
31330
31849
 
31331
31850
  // src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
31332
31851
  import { spawn as spawn7 } from "node:child_process";
31333
- import fs17 from "node:fs";
31852
+ import fs22 from "node:fs";
31334
31853
  import { tmpdir } from "node:os";
31335
- import path23 from "node:path";
31854
+ import path24 from "node:path";
31336
31855
  function trySpawnMergedLogFile(command, env, cwd, signal) {
31337
- const tmpRoot = fs17.mkdtempSync(path23.join(tmpdir(), "ba-devsrv-log-"));
31338
- const logPath = path23.join(tmpRoot, "combined.log");
31856
+ const tmpRoot = fs22.mkdtempSync(path24.join(tmpdir(), "ba-devsrv-log-"));
31857
+ const logPath = path24.join(tmpRoot, "combined.log");
31339
31858
  let logFd;
31340
31859
  try {
31341
- logFd = fs17.openSync(logPath, "a");
31860
+ logFd = fs22.openSync(logPath, "a");
31342
31861
  } catch {
31343
31862
  rmDirQuiet(tmpRoot);
31344
31863
  return null;
@@ -31357,7 +31876,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
31357
31876
  } else {
31358
31877
  proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
31359
31878
  }
31360
- fs17.closeSync(logFd);
31879
+ fs22.closeSync(logFd);
31361
31880
  return {
31362
31881
  proc,
31363
31882
  pipedStdoutStderr: true,
@@ -31366,7 +31885,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
31366
31885
  };
31367
31886
  } catch (e) {
31368
31887
  try {
31369
- fs17.closeSync(logFd);
31888
+ fs22.closeSync(logFd);
31370
31889
  } catch {
31371
31890
  }
31372
31891
  rmDirQuiet(tmpRoot);
@@ -31377,22 +31896,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
31377
31896
 
31378
31897
  // src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
31379
31898
  import { spawn as spawn8 } from "node:child_process";
31380
- import fs18 from "node:fs";
31899
+ import fs23 from "node:fs";
31381
31900
  import { tmpdir as tmpdir2 } from "node:os";
31382
- import path24 from "node:path";
31901
+ import path25 from "node:path";
31383
31902
  function shSingleQuote(s) {
31384
31903
  return `'${s.replace(/'/g, `'\\''`)}'`;
31385
31904
  }
31386
31905
  function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
31387
- const tmpRoot = fs18.mkdtempSync(path24.join(tmpdir2(), "ba-devsrv-sh-"));
31388
- const logPath = path24.join(tmpRoot, "combined.log");
31389
- const innerPath = path24.join(tmpRoot, "_cmd.sh");
31390
- const runnerPath = path24.join(tmpRoot, "_run.sh");
31906
+ const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
31907
+ const logPath = path25.join(tmpRoot, "combined.log");
31908
+ const innerPath = path25.join(tmpRoot, "_cmd.sh");
31909
+ const runnerPath = path25.join(tmpRoot, "_run.sh");
31391
31910
  try {
31392
- fs18.writeFileSync(innerPath, `#!/bin/sh
31911
+ fs23.writeFileSync(innerPath, `#!/bin/sh
31393
31912
  ${command}
31394
31913
  `);
31395
- fs18.writeFileSync(
31914
+ fs23.writeFileSync(
31396
31915
  runnerPath,
31397
31916
  `#!/bin/sh
31398
31917
  cd ${shSingleQuote(cwd)}
@@ -31418,13 +31937,13 @@ cd ${shSingleQuote(cwd)}
31418
31937
  }
31419
31938
  }
31420
31939
  function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
31421
- const tmpRoot = fs18.mkdtempSync(path24.join(tmpdir2(), "ba-devsrv-sh-"));
31422
- const logPath = path24.join(tmpRoot, "combined.log");
31423
- const runnerPath = path24.join(tmpRoot, "_run.bat");
31940
+ const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
31941
+ const logPath = path25.join(tmpRoot, "combined.log");
31942
+ const runnerPath = path25.join(tmpRoot, "_run.bat");
31424
31943
  const q = (p) => `"${p.replace(/"/g, '""')}"`;
31425
31944
  const com = process.env.ComSpec || "cmd.exe";
31426
31945
  try {
31427
- fs18.writeFileSync(
31946
+ fs23.writeFileSync(
31428
31947
  runnerPath,
31429
31948
  `@ECHO OFF\r
31430
31949
  CD /D ${q(cwd)}\r
@@ -31534,8 +32053,90 @@ var StreamTail = class {
31534
32053
  }
31535
32054
  };
31536
32055
 
31537
- // src/dev-servers/manager/dev-server-manager.ts
32056
+ // src/dev-servers/manager/dev-server-constants.ts
31538
32057
  var BRIDGE_SHUTDOWN_GRACE_MS = 8e3;
32058
+
32059
+ // src/dev-servers/manager/dev-server-firehose-messages.ts
32060
+ function buildFirehoseSnapshotMessage(params) {
32061
+ const payload = {
32062
+ type: "log_snapshot",
32063
+ serverId: params.serverId,
32064
+ viewerId: params.viewerId,
32065
+ stdoutTail: params.tails.stdout,
32066
+ stderrTail: params.tails.stderr
32067
+ };
32068
+ return params.e2ee ? params.e2ee.encryptFields(payload, ["stdoutTail", "stderrTail"]) : payload;
32069
+ }
32070
+ function buildFirehoseLogChunkMessage(params) {
32071
+ const payload = {
32072
+ type: "log_chunk",
32073
+ serverId: params.serverId,
32074
+ stream: params.stream,
32075
+ text: params.text
32076
+ };
32077
+ return params.e2ee ? params.e2ee.encryptFields(payload, ["text"]) : payload;
32078
+ }
32079
+
32080
+ // src/dev-servers/manager/dev-server-firehose-sink.ts
32081
+ var DevServerFirehoseSink = class {
32082
+ constructor(options) {
32083
+ this.options = options;
32084
+ }
32085
+ logViewerRefCountByServerId = /* @__PURE__ */ new Map();
32086
+ firehoseSend = null;
32087
+ attach(send) {
32088
+ this.firehoseSend = send;
32089
+ }
32090
+ detach() {
32091
+ this.firehoseSend = null;
32092
+ this.logViewerRefCountByServerId.clear();
32093
+ }
32094
+ openLogViewer(serverId, viewerId) {
32095
+ const next = (this.logViewerRefCountByServerId.get(serverId) ?? 0) + 1;
32096
+ this.logViewerRefCountByServerId.set(serverId, next);
32097
+ this.sendSnapshot(serverId, viewerId);
32098
+ }
32099
+ closeLogViewer(serverId) {
32100
+ const n = (this.logViewerRefCountByServerId.get(serverId) ?? 0) - 1;
32101
+ if (n <= 0) this.logViewerRefCountByServerId.delete(serverId);
32102
+ else this.logViewerRefCountByServerId.set(serverId, n);
32103
+ }
32104
+ pushLogChunk(serverId, stream, chunk) {
32105
+ if ((this.logViewerRefCountByServerId.get(serverId) ?? 0) <= 0) return;
32106
+ if (!this.options.isPipedCaptureEnabled(serverId)) return;
32107
+ if (!this.firehoseSend) return;
32108
+ const text = chunk.toString("utf8");
32109
+ setImmediate(() => {
32110
+ if (!this.firehoseSend) return;
32111
+ this.firehoseSend(buildFirehoseLogChunkMessage({ serverId, stream, text, e2ee: this.options.e2ee }));
32112
+ });
32113
+ }
32114
+ sendSnapshot(serverId, viewerId) {
32115
+ const payload = buildFirehoseSnapshotMessage({
32116
+ serverId,
32117
+ viewerId,
32118
+ tails: this.options.getTails(serverId),
32119
+ e2ee: this.options.e2ee
32120
+ });
32121
+ setImmediate(() => {
32122
+ const send = this.firehoseSend;
32123
+ if (!send) return;
32124
+ send(payload);
32125
+ });
32126
+ }
32127
+ };
32128
+
32129
+ // src/dev-servers/manager/cleanup-merged-log-dir.ts
32130
+ import { rm } from "node:fs/promises";
32131
+ function cleanupMergedLogDirForServer(map2, serverId) {
32132
+ const mergedDir = map2.get(serverId);
32133
+ if (!mergedDir) return;
32134
+ map2.delete(serverId);
32135
+ void rm(mergedDir, { recursive: true, force: true }).catch(() => {
32136
+ });
32137
+ }
32138
+
32139
+ // src/dev-servers/manager/dev-server-manager.ts
31539
32140
  var emptyTails = () => ({ stdout: [], stderr: [] });
31540
32141
  var DevServerManager = class {
31541
32142
  defsById = /* @__PURE__ */ new Map();
@@ -31543,66 +32144,36 @@ var DevServerManager = class {
31543
32144
  streamTailsByServerId = /* @__PURE__ */ new Map();
31544
32145
  spawnGenerationByServerId = /* @__PURE__ */ new Map();
31545
32146
  pipedCaptureByServerId = /* @__PURE__ */ new Map();
31546
- logViewerRefCountByServerId = /* @__PURE__ */ new Map();
31547
- firehoseSend = null;
31548
32147
  mergedLogPollByServerId = /* @__PURE__ */ new Map();
31549
32148
  mergedLogCleanupDirByServerId = /* @__PURE__ */ new Map();
31550
32149
  abortControllersByServerId = /* @__PURE__ */ new Map();
31551
32150
  getWs;
31552
32151
  log;
31553
32152
  getBridgeCwd;
32153
+ e2ee;
32154
+ firehoseSink;
31554
32155
  constructor(options) {
31555
32156
  this.getWs = options.getWs;
31556
32157
  this.log = options.log;
31557
32158
  this.getBridgeCwd = options.getBridgeCwd ?? (() => process.cwd());
32159
+ this.e2ee = options.e2ee;
32160
+ this.firehoseSink = new DevServerFirehoseSink({
32161
+ getTails: (serverId) => this.snapshotTails(serverId),
32162
+ isPipedCaptureEnabled: (serverId) => this.pipedCaptureByServerId.get(serverId) === true,
32163
+ e2ee: this.e2ee
32164
+ });
31558
32165
  }
31559
32166
  attachFirehose(send) {
31560
- this.firehoseSend = send;
32167
+ this.firehoseSink.attach(send);
31561
32168
  }
31562
32169
  detachFirehose() {
31563
- this.firehoseSend = null;
31564
- this.logViewerRefCountByServerId.clear();
32170
+ this.firehoseSink.detach();
31565
32171
  }
31566
32172
  handleFirehoseLogViewerOpen(serverId, _viewerId) {
31567
- const next = (this.logViewerRefCountByServerId.get(serverId) ?? 0) + 1;
31568
- this.logViewerRefCountByServerId.set(serverId, next);
31569
- this.sendSnapshotToFirehose(serverId, _viewerId);
32173
+ this.firehoseSink.openLogViewer(serverId, _viewerId);
31570
32174
  }
31571
32175
  handleFirehoseLogViewerClose(serverId, _viewerId) {
31572
- const n = (this.logViewerRefCountByServerId.get(serverId) ?? 0) - 1;
31573
- if (n <= 0) this.logViewerRefCountByServerId.delete(serverId);
31574
- else this.logViewerRefCountByServerId.set(serverId, n);
31575
- }
31576
- sendSnapshotToFirehose(serverId, viewerId) {
31577
- const tails = this.streamTailsByServerId.get(serverId);
31578
- const payload = {
31579
- type: "log_snapshot",
31580
- serverId,
31581
- viewerId,
31582
- stdoutTail: tails?.stdout.getTail() ?? [],
31583
- stderrTail: tails?.stderr.getTail() ?? []
31584
- };
31585
- setImmediate(() => {
31586
- const send = this.firehoseSend;
31587
- if (!send) return;
31588
- send(payload);
31589
- });
31590
- }
31591
- pushRemoteLogChunk(serverId, stream, chunk) {
31592
- if ((this.logViewerRefCountByServerId.get(serverId) ?? 0) <= 0) return;
31593
- if (!this.pipedCaptureByServerId.get(serverId)) return;
31594
- const send = this.firehoseSend;
31595
- if (!send) return;
31596
- const text = chunk.toString("utf8");
31597
- setImmediate(() => {
31598
- if (!this.firehoseSend) return;
31599
- this.firehoseSend({
31600
- type: "log_chunk",
31601
- serverId,
31602
- stream,
31603
- text
31604
- });
31605
- });
32176
+ this.firehoseSink.closeLogViewer(serverId);
31606
32177
  }
31607
32178
  applyConfig(servers) {
31608
32179
  this.defsById.clear();
@@ -31655,12 +32226,7 @@ var DevServerManager = class {
31655
32226
  }
31656
32227
  this.clearTails(serverId);
31657
32228
  this.pipedCaptureByServerId.delete(serverId);
31658
- const mergedDir = this.mergedLogCleanupDirByServerId.get(serverId);
31659
- if (mergedDir) {
31660
- this.mergedLogCleanupDirByServerId.delete(serverId);
31661
- void rm(mergedDir, { recursive: true, force: true }).catch(() => {
31662
- });
31663
- }
32229
+ cleanupMergedLogDirForServer(this.mergedLogCleanupDirByServerId, serverId);
31664
32230
  this.sendStatus(serverId, "stopped", void 0, tails);
31665
32231
  }
31666
32232
  start(serverId) {
@@ -31743,7 +32309,7 @@ var DevServerManager = class {
31743
32309
  log: this.log,
31744
32310
  stdoutTail,
31745
32311
  stderrTail,
31746
- pushRemoteLogChunk: (sid, stream, chunk) => this.pushRemoteLogChunk(sid, stream, chunk),
32312
+ pushRemoteLogChunk: (sid, stream, chunk) => this.firehoseSink.pushLogChunk(sid, stream, chunk),
31747
32313
  sendStatus: (status, detail, tails) => this.sendStatus(serverId, status, detail, tails),
31748
32314
  setPollInterval: (iv) => {
31749
32315
  if (iv) this.mergedLogPollByServerId.set(serverId, iv);
@@ -31757,7 +32323,7 @@ var DevServerManager = class {
31757
32323
  this.mergedLogCleanupDirByServerId.delete(serverId);
31758
32324
  },
31759
32325
  rmMergedCleanupDir: (dir) => {
31760
- void rm(dir, { recursive: true, force: true }).catch(() => {
32326
+ void rm2(dir, { recursive: true, force: true }).catch(() => {
31761
32327
  });
31762
32328
  },
31763
32329
  clearTailBuffers: () => this.clearTails(serverId)
@@ -31794,12 +32360,7 @@ var DevServerManager = class {
31794
32360
  this.processes.delete(serverId);
31795
32361
  this.clearPoll(serverId);
31796
32362
  this.pipedCaptureByServerId.delete(serverId);
31797
- const mergedDir = this.mergedLogCleanupDirByServerId.get(serverId);
31798
- if (mergedDir) {
31799
- this.mergedLogCleanupDirByServerId.delete(serverId);
31800
- void rm(mergedDir, { recursive: true, force: true }).catch(() => {
31801
- });
31802
- }
32363
+ cleanupMergedLogDirForServer(this.mergedLogCleanupDirByServerId, serverId);
31803
32364
  const tails = this.snapshotTails(serverId);
31804
32365
  this.clearTails(serverId);
31805
32366
  this.sendStatus(serverId, "unknown", "Bridge closed before process exited", tails);
@@ -32106,30 +32667,30 @@ function createOnBridgeIdentified(opts) {
32106
32667
  }
32107
32668
 
32108
32669
  // src/skills/discover-local-agent-skills.ts
32109
- import fs19 from "node:fs";
32110
- import path25 from "node:path";
32670
+ import fs24 from "node:fs";
32671
+ import path26 from "node:path";
32111
32672
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
32112
32673
  function discoverLocalSkills(cwd) {
32113
32674
  const out = [];
32114
32675
  const seenKeys = /* @__PURE__ */ new Set();
32115
32676
  for (const rel of SKILL_DISCOVERY_ROOTS) {
32116
- const base = path25.join(cwd, rel);
32117
- if (!fs19.existsSync(base) || !fs19.statSync(base).isDirectory()) continue;
32677
+ const base = path26.join(cwd, rel);
32678
+ if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
32118
32679
  let entries = [];
32119
32680
  try {
32120
- entries = fs19.readdirSync(base);
32681
+ entries = fs24.readdirSync(base);
32121
32682
  } catch {
32122
32683
  continue;
32123
32684
  }
32124
32685
  for (const name of entries) {
32125
- const dir = path25.join(base, name);
32686
+ const dir = path26.join(base, name);
32126
32687
  try {
32127
- if (!fs19.statSync(dir).isDirectory()) continue;
32688
+ if (!fs24.statSync(dir).isDirectory()) continue;
32128
32689
  } catch {
32129
32690
  continue;
32130
32691
  }
32131
- const skillMd = path25.join(dir, "SKILL.md");
32132
- if (!fs19.existsSync(skillMd)) continue;
32692
+ const skillMd = path26.join(dir, "SKILL.md");
32693
+ if (!fs24.existsSync(skillMd)) continue;
32133
32694
  const key = `${rel}/${name}`;
32134
32695
  if (seenKeys.has(key)) continue;
32135
32696
  seenKeys.add(key);
@@ -32141,23 +32702,23 @@ function discoverLocalSkills(cwd) {
32141
32702
  function discoverSkillLayoutRoots(cwd) {
32142
32703
  const roots = [];
32143
32704
  for (const rel of SKILL_DISCOVERY_ROOTS) {
32144
- const base = path25.join(cwd, rel);
32145
- if (!fs19.existsSync(base) || !fs19.statSync(base).isDirectory()) continue;
32705
+ const base = path26.join(cwd, rel);
32706
+ if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
32146
32707
  let entries = [];
32147
32708
  try {
32148
- entries = fs19.readdirSync(base);
32709
+ entries = fs24.readdirSync(base);
32149
32710
  } catch {
32150
32711
  continue;
32151
32712
  }
32152
32713
  const skills2 = [];
32153
32714
  for (const name of entries) {
32154
- const dir = path25.join(base, name);
32715
+ const dir = path26.join(base, name);
32155
32716
  try {
32156
- if (!fs19.statSync(dir).isDirectory()) continue;
32717
+ if (!fs24.statSync(dir).isDirectory()) continue;
32157
32718
  } catch {
32158
32719
  continue;
32159
32720
  }
32160
- if (!fs19.existsSync(path25.join(dir, "SKILL.md"))) continue;
32721
+ if (!fs24.existsSync(path26.join(dir, "SKILL.md"))) continue;
32161
32722
  const relPath = `${rel}/${name}`.replace(/\\/g, "/");
32162
32723
  skills2.push({ name, relPath });
32163
32724
  }
@@ -32259,7 +32820,7 @@ function reportGitRepos(getWs, log2) {
32259
32820
  var handleAuthToken = (msg, { log: log2 }) => {
32260
32821
  if (typeof msg.token !== "string") return;
32261
32822
  log2("Received auth token. Save it for future runs:");
32262
- log2(` export BUILDAMATON_AUTH_TOKEN="${msg.token}"`);
32823
+ log2(` export BUILDAUTOMATON_AUTH_TOKEN="${msg.token}"`);
32263
32824
  };
32264
32825
 
32265
32826
  // src/bridge/routing/handlers/bridge-identified.ts
@@ -32302,12 +32863,12 @@ var handleAgentConfigMessage = (msg, deps) => {
32302
32863
  };
32303
32864
 
32304
32865
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
32305
- import * as path27 from "node:path";
32306
- import { execFile as execFile5 } from "node:child_process";
32307
- import { promisify as promisify5 } from "node:util";
32866
+ import * as path28 from "node:path";
32867
+ import { execFile as execFile10 } from "node:child_process";
32868
+ import { promisify as promisify10 } from "node:util";
32308
32869
 
32309
32870
  // src/git/bridge-queue-key.ts
32310
- import * as path26 from "node:path";
32871
+ import * as path27 from "node:path";
32311
32872
  import { createHash } from "node:crypto";
32312
32873
  function normalizeCanonicalGitUrl(url2) {
32313
32874
  let s = url2.trim();
@@ -32335,11 +32896,11 @@ function canonicalUrlToRepoIdSync(url2) {
32335
32896
  return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
32336
32897
  }
32337
32898
  function fallbackRepoIdFromPath(absPath) {
32338
- return createHash("sha256").update(path26.resolve(absPath)).digest("hex").slice(0, 32);
32899
+ return createHash("sha256").update(path27.resolve(absPath)).digest("hex").slice(0, 32);
32339
32900
  }
32340
32901
  async function resolveBridgeQueueBindFields(options) {
32341
32902
  const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
32342
- const cwdAbs = worktreePaths.length > 0 ? path26.resolve(worktreePaths[0]) : path26.resolve(effectiveCwd);
32903
+ const cwdAbs = worktreePaths.length > 0 ? path27.resolve(worktreePaths[0]) : path27.resolve(effectiveCwd);
32343
32904
  if (!primaryRepoRoots.length) {
32344
32905
  log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
32345
32906
  return null;
@@ -32362,10 +32923,10 @@ async function resolveBridgeQueueBindFields(options) {
32362
32923
  }
32363
32924
 
32364
32925
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
32365
- var execFileAsync5 = promisify5(execFile5);
32926
+ var execFileAsync9 = promisify10(execFile10);
32366
32927
  async function readGitBranch(cwd) {
32367
32928
  try {
32368
- const { stdout } = await execFileAsync5("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
32929
+ const { stdout } = await execFileAsync9("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
32369
32930
  const b = stdout.trim();
32370
32931
  return b || null;
32371
32932
  } catch {
@@ -32376,22 +32937,40 @@ function handleBridgePrompt(msg, deps) {
32376
32937
  const { getWs, log: log2, acpManager, sessionWorktreeManager } = deps;
32377
32938
  const rawPrompt = msg.prompt;
32378
32939
  const promptText = typeof rawPrompt === "string" ? rawPrompt : rawPrompt != null ? String(rawPrompt) : "";
32940
+ const sessionId = msg.sessionId;
32941
+ const runId = typeof msg.runId === "string" ? msg.runId : void 0;
32942
+ const promptId = typeof msg.id === "string" ? msg.id : void 0;
32943
+ const sendBridgeMessage = (message, encryptedFields = []) => {
32944
+ const s = getWs();
32945
+ if (!s) return false;
32946
+ const wire = deps.e2ee && encryptedFields.length > 0 ? deps.e2ee.encryptFields(message, encryptedFields) : message;
32947
+ sendWsMessage(s, wire);
32948
+ return true;
32949
+ };
32379
32950
  if (!promptText.trim()) {
32380
32951
  log2(
32381
32952
  `[Bridge service] Prompt ignored: empty or missing prompt text (session ${typeof msg.sessionId === "string" ? msg.sessionId.slice(0, 8) : "\u2014"}\u2026, run ${typeof msg.runId === "string" ? msg.runId.slice(0, 8) : "\u2014"}\u2026).`
32382
32953
  );
32954
+ sendBridgeMessage(
32955
+ {
32956
+ type: "prompt_result",
32957
+ ...promptId ? { id: promptId } : {},
32958
+ ...sessionId ? { sessionId } : {},
32959
+ ...runId ? { runId } : {},
32960
+ success: false,
32961
+ error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
32962
+ },
32963
+ ["error"]
32964
+ );
32383
32965
  return;
32384
32966
  }
32385
- const sessionId = msg.sessionId;
32386
32967
  const isNewSession = msg.isNewSession === true;
32387
32968
  const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
32388
32969
  const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
32389
- const runId = typeof msg.runId === "string" ? msg.runId : void 0;
32390
32970
  const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
32391
32971
  acpManager.logPromptReceivedFromBridge({ agentType, mode });
32392
32972
  const sendResult2 = (result) => {
32393
- const s = getWs();
32394
- if (s) sendWsMessage(s, result);
32973
+ sendBridgeMessage(result, result.type === "prompt_result" ? ["output", "error"] : []);
32395
32974
  };
32396
32975
  const sendSessionUpdate = (payload) => {
32397
32976
  const s = getWs();
@@ -32400,11 +32979,19 @@ function handleBridgePrompt(msg, deps) {
32400
32979
  return;
32401
32980
  }
32402
32981
  const p = payload;
32403
- sendWsMessage(s, payload);
32982
+ const wire = p.type === "session_update" && deps.e2ee ? deps.e2ee.encryptFields(payload, ["payload"]) : p.type === "session_file_change" && deps.e2ee ? deps.e2ee.encryptFields(payload, [
32983
+ "path",
32984
+ "oldText",
32985
+ "newText",
32986
+ "patchContent",
32987
+ "isDirectory",
32988
+ "directoryRemoved"
32989
+ ]) : payload;
32990
+ sendWsMessage(s, wire);
32404
32991
  };
32405
32992
  async function preambleAndPrompt(resolvedCwd) {
32406
32993
  const s = getWs();
32407
- const effectiveCwd = path27.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
32994
+ const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
32408
32995
  const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
32409
32996
  const repoRoots = await resolveSnapshotRepoRoots({
32410
32997
  worktreePaths,
@@ -32529,15 +33116,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
32529
33116
  };
32530
33117
 
32531
33118
  // src/files/list-dir.ts
32532
- import fs20 from "node:fs";
32533
- import path29 from "node:path";
33119
+ import fs25 from "node:fs";
33120
+ import path30 from "node:path";
32534
33121
 
32535
33122
  // src/files/ensure-under-cwd.ts
32536
- import path28 from "node:path";
33123
+ import path29 from "node:path";
32537
33124
  function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
32538
- const normalized = path28.normalize(relativePath).replace(/^(\.\/)+/, "");
32539
- const resolved = path28.resolve(cwd, normalized);
32540
- if (!resolved.startsWith(cwd + path28.sep) && resolved !== cwd) {
33125
+ const normalized = path29.normalize(relativePath).replace(/^(\.\/)+/, "");
33126
+ const resolved = path29.resolve(cwd, normalized);
33127
+ if (!resolved.startsWith(cwd + path29.sep) && resolved !== cwd) {
32541
33128
  return null;
32542
33129
  }
32543
33130
  return resolved;
@@ -32551,7 +33138,7 @@ async function listDirAsync(relativePath) {
32551
33138
  return { error: "Path is outside working directory" };
32552
33139
  }
32553
33140
  try {
32554
- const names = await fs20.promises.readdir(resolved, { withFileTypes: true });
33141
+ const names = await fs25.promises.readdir(resolved, { withFileTypes: true });
32555
33142
  const visible = names.filter((d) => !d.name.startsWith("."));
32556
33143
  const entries = [];
32557
33144
  for (let i = 0; i < visible.length; i++) {
@@ -32559,12 +33146,12 @@ async function listDirAsync(relativePath) {
32559
33146
  await yieldToEventLoop();
32560
33147
  }
32561
33148
  const d = visible[i];
32562
- const entryPath = path29.join(relativePath || ".", d.name).replace(/\\/g, "/");
32563
- const fullPath = path29.join(resolved, d.name);
33149
+ const entryPath = path30.join(relativePath || ".", d.name).replace(/\\/g, "/");
33150
+ const fullPath = path30.join(resolved, d.name);
32564
33151
  let isDir = d.isDirectory();
32565
33152
  if (d.isSymbolicLink()) {
32566
33153
  try {
32567
- const targetStat = await fs20.promises.stat(fullPath);
33154
+ const targetStat = await fs25.promises.stat(fullPath);
32568
33155
  isDir = targetStat.isDirectory();
32569
33156
  } catch {
32570
33157
  isDir = false;
@@ -32589,25 +33176,25 @@ async function listDirAsync(relativePath) {
32589
33176
  }
32590
33177
 
32591
33178
  // src/files/read-file.ts
32592
- import fs21 from "node:fs";
33179
+ import fs26 from "node:fs";
32593
33180
  import { StringDecoder } from "node:string_decoder";
32594
33181
  function resolveFilePath(relativePath) {
32595
33182
  const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
32596
33183
  if (!resolved) return { error: "Path is outside working directory" };
32597
33184
  let real;
32598
33185
  try {
32599
- real = fs21.realpathSync(resolved);
33186
+ real = fs26.realpathSync(resolved);
32600
33187
  } catch {
32601
33188
  real = resolved;
32602
33189
  }
32603
- const stat2 = fs21.statSync(real);
33190
+ const stat2 = fs26.statSync(real);
32604
33191
  if (!stat2.isFile()) return { error: "Not a file" };
32605
33192
  return real;
32606
33193
  }
32607
33194
  var LINE_CHUNK_SIZE = 64 * 1024;
32608
33195
  function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
32609
- const fileSize = fs21.statSync(filePath).size;
32610
- const fd = fs21.openSync(filePath, "r");
33196
+ const fileSize = fs26.statSync(filePath).size;
33197
+ const fd = fs26.openSync(filePath, "r");
32611
33198
  const bufSize = 64 * 1024;
32612
33199
  const buf = Buffer.alloc(bufSize);
32613
33200
  const decoder = new StringDecoder("utf8");
@@ -32620,7 +33207,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
32620
33207
  let line0Accum = "";
32621
33208
  try {
32622
33209
  let bytesRead;
32623
- while (!done && (bytesRead = fs21.readSync(fd, buf, 0, bufSize, null)) > 0) {
33210
+ while (!done && (bytesRead = fs26.readSync(fd, buf, 0, bufSize, null)) > 0) {
32624
33211
  const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
32625
33212
  partial2 = "";
32626
33213
  let lineStart = 0;
@@ -32755,7 +33342,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
32755
33342
  }
32756
33343
  return { content: resultLines.join("\n"), size: fileSize };
32757
33344
  } finally {
32758
- fs21.closeSync(fd);
33345
+ fs26.closeSync(fd);
32759
33346
  }
32760
33347
  }
32761
33348
  function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
@@ -32766,8 +33353,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
32766
33353
  if (hasRange) {
32767
33354
  return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
32768
33355
  }
32769
- const stat2 = fs21.statSync(result);
32770
- const raw = fs21.readFileSync(result, "utf8");
33356
+ const stat2 = fs26.statSync(result);
33357
+ const raw = fs26.readFileSync(result, "utf8");
32771
33358
  const lines = raw.split(/\r?\n/);
32772
33359
  return { content: raw, totalLines: lines.length, size: stat2.size };
32773
33360
  } catch (err) {
@@ -32781,28 +33368,30 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
32781
33368
 
32782
33369
  // src/files/handle-file-browser-search.ts
32783
33370
  var SEARCH_LIMIT = 100;
32784
- function handleFileBrowserSearch(msg, socket) {
33371
+ function handleFileBrowserSearch(msg, socket, e2ee) {
32785
33372
  void (async () => {
32786
33373
  await yieldToEventLoop();
32787
33374
  const q = typeof msg.q === "string" ? msg.q : "";
32788
33375
  const cwd = getBridgeWorkspaceDirectory();
32789
33376
  const index = loadFileIndex(cwd);
32790
33377
  if (index === null) {
32791
- sendWsMessage(socket, {
33378
+ const payload2 = {
32792
33379
  type: "file_browser_search_response",
32793
33380
  id: msg.id,
32794
33381
  paths: [],
32795
33382
  indexReady: false
32796
- });
33383
+ };
33384
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
32797
33385
  return;
32798
33386
  }
32799
33387
  const results = await searchFileIndexAsync(index, q, SEARCH_LIMIT);
32800
- sendWsMessage(socket, {
33388
+ const payload = {
32801
33389
  type: "file_browser_search_response",
32802
33390
  id: msg.id,
32803
33391
  paths: results,
32804
33392
  indexReady: true
32805
- });
33393
+ };
33394
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
32806
33395
  })();
32807
33396
  }
32808
33397
  function triggerFileIndexBuild() {
@@ -32814,7 +33403,10 @@ function triggerFileIndexBuild() {
32814
33403
  }
32815
33404
 
32816
33405
  // src/files/handle-file-browser-request.ts
32817
- function handleFileBrowserRequest(msg, socket) {
33406
+ function sendFileBrowserMessage(socket, e2ee, payload) {
33407
+ sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
33408
+ }
33409
+ function handleFileBrowserRequest(msg, socket, e2ee) {
32818
33410
  void (async () => {
32819
33411
  const reqPath = msg.path.replace(/^\/+/, "") || ".";
32820
33412
  const op = msg.op === "read" ? "read" : "list";
@@ -32823,7 +33415,7 @@ function handleFileBrowserRequest(msg, socket) {
32823
33415
  if ("error" in result) {
32824
33416
  sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
32825
33417
  } else {
32826
- sendWsMessage(socket, { type: "file_browser_response", id: msg.id, entries: result.entries });
33418
+ sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id: msg.id, entries: result.entries });
32827
33419
  if (reqPath === "." || reqPath === "") {
32828
33420
  triggerFileIndexBuild();
32829
33421
  }
@@ -32845,27 +33437,28 @@ function handleFileBrowserRequest(msg, socket) {
32845
33437
  size: result.size
32846
33438
  };
32847
33439
  if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
32848
- sendWsMessage(socket, payload);
33440
+ sendFileBrowserMessage(socket, e2ee, payload);
32849
33441
  }
32850
33442
  }
32851
33443
  })();
32852
33444
  }
32853
33445
 
32854
33446
  // src/bridge/routing/handlers/file-browser-messages.ts
32855
- function handleFileBrowserRequestMessage(msg, { getWs }) {
33447
+ function handleFileBrowserRequestMessage(msg, { getWs, e2ee }) {
32856
33448
  if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
32857
33449
  const socket = getWs();
32858
33450
  if (!socket) return;
32859
33451
  handleFileBrowserRequest(
32860
33452
  msg,
32861
- socket
33453
+ socket,
33454
+ e2ee
32862
33455
  );
32863
33456
  }
32864
- function handleFileBrowserSearchMessage(msg, { getWs }) {
33457
+ function handleFileBrowserSearchMessage(msg, { getWs, e2ee }) {
32865
33458
  if (typeof msg.id !== "string") return;
32866
33459
  const socket = getWs();
32867
33460
  if (!socket) return;
32868
- handleFileBrowserSearch(msg, socket);
33461
+ handleFileBrowserSearch(msg, socket, e2ee);
32869
33462
  }
32870
33463
 
32871
33464
  // src/bridge/routing/handlers/skill-layout-request.ts
@@ -32877,8 +33470,8 @@ function handleSkillLayoutRequest(msg, deps) {
32877
33470
  }
32878
33471
 
32879
33472
  // src/skills/install-remote-skills.ts
32880
- import fs22 from "node:fs";
32881
- import path30 from "node:path";
33473
+ import fs27 from "node:fs";
33474
+ import path31 from "node:path";
32882
33475
  function installRemoteSkills(cwd, targetDir, items) {
32883
33476
  const installed2 = [];
32884
33477
  if (!Array.isArray(items)) {
@@ -32889,15 +33482,15 @@ function installRemoteSkills(cwd, targetDir, items) {
32889
33482
  if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
32890
33483
  continue;
32891
33484
  }
32892
- const skillDir = path30.join(cwd, targetDir, item.skillName);
33485
+ const skillDir = path31.join(cwd, targetDir, item.skillName);
32893
33486
  for (const f of item.files) {
32894
33487
  if (typeof f.path !== "string" || !f.text && !f.base64) continue;
32895
- const dest = path30.join(skillDir, f.path);
32896
- fs22.mkdirSync(path30.dirname(dest), { recursive: true });
33488
+ const dest = path31.join(skillDir, f.path);
33489
+ fs27.mkdirSync(path31.dirname(dest), { recursive: true });
32897
33490
  if (f.text !== void 0) {
32898
- fs22.writeFileSync(dest, f.text, "utf8");
33491
+ fs27.writeFileSync(dest, f.text, "utf8");
32899
33492
  } else if (f.base64) {
32900
- fs22.writeFileSync(dest, Buffer.from(f.base64, "base64"));
33493
+ fs27.writeFileSync(dest, Buffer.from(f.base64, "base64"));
32901
33494
  }
32902
33495
  }
32903
33496
  installed2.push({
@@ -32935,9 +33528,10 @@ var handleRefreshLocalSkills = (_msg, deps) => {
32935
33528
  };
32936
33529
 
32937
33530
  // src/bridge/routing/handlers/session-git-request.ts
32938
- function sendResult(ws, id, payload) {
33531
+ function sendResult(ws, id, payload, e2ee, encryptedFields = []) {
32939
33532
  if (!ws) return;
32940
- sendWsMessage(ws, { type: "session_git_result", id, ...payload });
33533
+ const message = { type: "session_git_result", id, ...payload };
33534
+ sendWsMessage(ws, e2ee && encryptedFields.length > 0 ? e2ee.encryptFields(message, encryptedFields) : message);
32941
33535
  }
32942
33536
  var handleSessionGitRequestMessage = (msg, deps) => {
32943
33537
  if (typeof msg.id !== "string") return;
@@ -32947,7 +33541,7 @@ var handleSessionGitRequestMessage = (msg, deps) => {
32947
33541
  return;
32948
33542
  void (async () => {
32949
33543
  const ws = deps.getWs();
32950
- const reply = (payload) => sendResult(ws, msg.id, payload);
33544
+ const reply = (payload, encryptedFields = []) => sendResult(ws, msg.id, payload, deps.e2ee, encryptedFields);
32951
33545
  try {
32952
33546
  if (action === "status") {
32953
33547
  const r = await deps.sessionWorktreeManager.getSessionWorkingTreeStatus(sessionId);
@@ -32973,7 +33567,7 @@ var handleSessionGitRequestMessage = (msg, deps) => {
32973
33567
  reply({
32974
33568
  ok: true,
32975
33569
  repos
32976
- });
33570
+ }, ["repos"]);
32977
33571
  return;
32978
33572
  }
32979
33573
  if (action === "push") {
@@ -33042,7 +33636,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
33042
33636
  };
33043
33637
 
33044
33638
  // src/bridge/routing/handlers/revert-turn-snapshot.ts
33045
- import * as fs23 from "node:fs";
33639
+ import * as fs28 from "node:fs";
33046
33640
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
33047
33641
  const id = typeof msg.id === "string" ? msg.id : "";
33048
33642
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -33054,7 +33648,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
33054
33648
  if (!s) return;
33055
33649
  const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
33056
33650
  const file2 = snapshotFilePath(agentBase, turnId);
33057
- if (!fs23.existsSync(file2)) {
33651
+ if (!fs28.existsSync(file2)) {
33058
33652
  sendWsMessage(s, {
33059
33653
  type: "revert_turn_snapshot_result",
33060
33654
  id,
@@ -33075,8 +33669,15 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
33075
33669
 
33076
33670
  // src/bridge/routing/handlers/dev-server-control.ts
33077
33671
  var handleDevServerControl = (msg, deps) => {
33078
- const serverId = typeof msg.serverId === "string" ? msg.serverId : "";
33079
- const action = msg.action === "start" || msg.action === "stop" ? msg.action : null;
33672
+ let wire = msg;
33673
+ try {
33674
+ wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
33675
+ } catch (e) {
33676
+ deps.log(`[E2EE] Could not decrypt dev server command: ${e instanceof Error ? e.message : String(e)}`);
33677
+ return;
33678
+ }
33679
+ const serverId = typeof wire.serverId === "string" ? wire.serverId : "";
33680
+ const action = wire.action === "start" || wire.action === "stop" ? wire.action : null;
33080
33681
  if (!serverId || !action) return;
33081
33682
  deps.devServerManager?.handleControl(serverId, action);
33082
33683
  };
@@ -33202,7 +33803,8 @@ function createMainBridgeWebSocketLifecycle(params) {
33202
33803
  messageDeps,
33203
33804
  tokens,
33204
33805
  persistTokens,
33205
- onAuthInvalid
33806
+ onAuthInvalid,
33807
+ e2ee
33206
33808
  } = params;
33207
33809
  let authRefreshInFlight = false;
33208
33810
  function handleOpen() {
@@ -33215,15 +33817,15 @@ function createMainBridgeWebSocketLifecycle(params) {
33215
33817
  }
33216
33818
  const socket = getWs();
33217
33819
  if (socket) {
33218
- sendWsMessage(socket, { type: "identify", role: "cli" });
33820
+ sendWsMessage(socket, { type: "identify", role: "cli", ...e2ee ? { e: e2ee.handshake } : {} });
33219
33821
  reportGitRepos(getWs, logFn);
33220
33822
  }
33221
33823
  if (justAuthenticated && socket) {
33222
33824
  logFn(
33223
33825
  "Save these for future runs (access token may rotate; refresh token is stored in ~/.buildautomaton/config.json when you use browser auth):"
33224
33826
  );
33225
- logFn(` export BUILDAMATON_AUTH_TOKEN="${tokens.accessToken}"`);
33226
- logFn(` export BUILDAMATON_WORKSPACE_ID="${workspaceId}"`);
33827
+ logFn(` export BUILDAUTOMATON_AUTH_TOKEN="${tokens.accessToken}"`);
33828
+ logFn(` export BUILDAUTOMATON_WORKSPACE_ID="${workspaceId}"`);
33227
33829
  }
33228
33830
  }
33229
33831
  function handleClose(code, reason) {
@@ -33305,6 +33907,100 @@ function createMainBridgeWebSocketLifecycle(params) {
33305
33907
  return { connect };
33306
33908
  }
33307
33909
 
33910
+ // ../e2ee/src/constants.ts
33911
+ var E2EE_NONCE_BYTES = 12;
33912
+
33913
+ // ../e2ee/src/types.ts
33914
+ function isE2eeEnvelope(value) {
33915
+ if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
33916
+ const o = value;
33917
+ return typeof o.k === "string" && typeof o.n === "string" && typeof o.c === "string";
33918
+ }
33919
+
33920
+ // ../e2ee/src/encoding.ts
33921
+ function base64UrlEncode(bytes) {
33922
+ let binary = "";
33923
+ for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
33924
+ const b64 = btoa(binary);
33925
+ return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
33926
+ }
33927
+ function base64UrlDecode(value) {
33928
+ const b64 = value.replace(/-/g, "+").replace(/_/g, "/");
33929
+ const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
33930
+ const binary = atob(padded);
33931
+ const out = new Uint8Array(binary.length);
33932
+ for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
33933
+ return out;
33934
+ }
33935
+
33936
+ // src/lib/e2ee/cli-e2ee-runtime.ts
33937
+ import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
33938
+ function nonceFromCounter(prefix, counter) {
33939
+ const nonce = Buffer.alloc(E2EE_NONCE_BYTES);
33940
+ prefix.copy(nonce, 0);
33941
+ nonce.writeBigUInt64BE(counter, 4);
33942
+ return nonce;
33943
+ }
33944
+ function createCliE2eeRuntime(key) {
33945
+ const rawKey = Buffer.from(base64UrlDecode(key.k));
33946
+ const prefix = randomBytes(4);
33947
+ let counter = 0n;
33948
+ function nextNonce() {
33949
+ counter += 1n;
33950
+ return nonceFromCounter(prefix, counter);
33951
+ }
33952
+ function encryptObject(messageWithoutSensitiveFields, plaintext) {
33953
+ const nonce = nextNonce();
33954
+ const cipher = createCipheriv("aes-256-gcm", rawKey, nonce);
33955
+ const ciphertext = Buffer.concat([cipher.update(JSON.stringify(plaintext), "utf8"), cipher.final()]);
33956
+ const tag = cipher.getAuthTag();
33957
+ return {
33958
+ k: key.id,
33959
+ n: base64UrlEncode(nonce),
33960
+ c: base64UrlEncode(Buffer.concat([ciphertext, tag]))
33961
+ };
33962
+ }
33963
+ return {
33964
+ keyId: key.id,
33965
+ handshake: { k: key.id, a: key.a },
33966
+ encryptFields(message, fields) {
33967
+ const plaintext = {};
33968
+ const stripped = { ...message };
33969
+ let hasPlaintext = false;
33970
+ for (const field of fields) {
33971
+ if (Object.prototype.hasOwnProperty.call(stripped, field) && stripped[field] !== void 0) {
33972
+ plaintext[field] = stripped[field];
33973
+ delete stripped[field];
33974
+ hasPlaintext = true;
33975
+ }
33976
+ }
33977
+ if (!hasPlaintext) return message;
33978
+ stripped.ee = encryptObject(stripped, plaintext);
33979
+ return stripped;
33980
+ },
33981
+ decryptMessage(message) {
33982
+ const envelope = message.ee;
33983
+ if (!isE2eeEnvelope(envelope)) return message;
33984
+ if (envelope.k !== key.id) throw new Error(`E2EE key mismatch: ${envelope.k}`);
33985
+ const sealed = Buffer.from(base64UrlDecode(envelope.c));
33986
+ if (sealed.length < 16) throw new Error("Invalid E2EE payload.");
33987
+ const ciphertext = sealed.subarray(0, sealed.length - 16);
33988
+ const tag = sealed.subarray(sealed.length - 16);
33989
+ const nonce = Buffer.from(base64UrlDecode(envelope.n));
33990
+ const decipher = createDecipheriv("aes-256-gcm", rawKey, nonce);
33991
+ decipher.setAuthTag(tag);
33992
+ const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
33993
+ const parsed = JSON.parse(decrypted);
33994
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
33995
+ throw new Error("E2EE payload did not decode to an object.");
33996
+ }
33997
+ const merged = { ...message, ...parsed };
33998
+ delete merged.ee;
33999
+ return merged;
34000
+ }
34001
+ };
34002
+ }
34003
+
33308
34004
  // src/bridge/connection/create-bridge-connection.ts
33309
34005
  async function createBridgeConnection(options) {
33310
34006
  const { apiUrl, workspaceId, justAuthenticated, onAuthInvalid, persistTokens } = options;
@@ -33338,7 +34034,8 @@ async function createBridgeConnection(options) {
33338
34034
  function getWs() {
33339
34035
  return state.currentWs;
33340
34036
  }
33341
- const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory });
34037
+ const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
34038
+ const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory, e2ee });
33342
34039
  const onBridgeIdentified = createOnBridgeIdentified({
33343
34040
  sessionWorktreeManager,
33344
34041
  devServerManager,
@@ -33357,7 +34054,8 @@ async function createBridgeConnection(options) {
33357
34054
  onBridgeIdentified,
33358
34055
  sendLocalSkillsReport,
33359
34056
  reportAutoDetectedAgents,
33360
- devServerManager
34057
+ devServerManager,
34058
+ e2ee
33361
34059
  };
33362
34060
  const { connect } = createMainBridgeWebSocketLifecycle({
33363
34061
  state,
@@ -33369,7 +34067,8 @@ async function createBridgeConnection(options) {
33369
34067
  messageDeps,
33370
34068
  tokens,
33371
34069
  persistTokens,
33372
- onAuthInvalid
34070
+ onAuthInvalid,
34071
+ e2ee
33373
34072
  });
33374
34073
  connect();
33375
34074
  const stopFileIndexWatcher = startFileIndexWatcher(getBridgeWorkspaceDirectory());
@@ -33381,56 +34080,72 @@ async function createBridgeConnection(options) {
33381
34080
  };
33382
34081
  }
33383
34082
 
33384
- // src/run-bridge.ts
33385
- async function runBridge(options) {
33386
- installBridgeProcessResilience();
33387
- const { apiUrl, workspaceId, authToken, refreshToken, bridgeName, justAuthenticated, worktreesRootAbs } = options;
33388
- const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
33389
- const hasAuth = workspaceId && authToken;
33390
- if (!hasAuth) {
33391
- const handle2 = runPendingAuth({
33392
- apiUrl,
33393
- initialWorkspaceId: workspaceId,
33394
- preferredBridgeName: bridgeName,
33395
- log,
33396
- onAuth: (_auth) => {
33397
- }
33398
- });
33399
- const onSignal2 = (kind) => {
33400
- logImmediate(
33401
- kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
33402
- );
33403
- setImmediate(() => {
33404
- handle2.close();
33405
- process.exit(0);
33406
- });
34083
+ // src/e2e-certificates/key-command.ts
34084
+ import * as readline3 from "node:readline";
34085
+ function installE2eCertificateKeyCommand({
34086
+ log: log2,
34087
+ onOpenCertificate,
34088
+ onInterrupt
34089
+ }) {
34090
+ if (!process.stdin.isTTY || typeof process.stdin.setRawMode !== "function") {
34091
+ log2("[E2EE] Press c to import the E2EE key in a browser when running in an interactive terminal.");
34092
+ return () => {
33407
34093
  };
33408
- const onSigInt2 = () => onSignal2("interrupt");
33409
- const onSigTerm2 = () => onSignal2("stop");
33410
- process.on("SIGINT", onSigInt2);
33411
- process.on("SIGTERM", onSigTerm2);
33412
- const auth = await handle2.authPromise;
33413
- process.off("SIGINT", onSigInt2);
33414
- process.off("SIGTERM", onSigTerm2);
33415
- handle2.close();
33416
- if (!auth) return;
33417
- writeConfigForApi(apiUrl, {
33418
- workspaceId: auth.workspaceId,
33419
- token: auth.token,
33420
- refreshToken: auth.refreshToken
33421
- });
33422
- await runBridge({
33423
- apiUrl,
33424
- workspaceId: auth.workspaceId,
33425
- authToken: auth.token,
33426
- refreshToken: auth.refreshToken,
33427
- firehoseServerUrl,
33428
- bridgeName,
33429
- justAuthenticated: true,
33430
- worktreesRootAbs
33431
- });
33432
- return;
33433
34094
  }
34095
+ readline3.emitKeypressEvents(process.stdin);
34096
+ process.stdin.setRawMode(true);
34097
+ process.stdin.resume();
34098
+ const onKeypress = (str, key) => {
34099
+ if (key?.ctrl && key.name === "c") {
34100
+ onInterrupt();
34101
+ return;
34102
+ }
34103
+ if (!key?.ctrl && !key?.meta && (key?.name === "c" || str === "c")) {
34104
+ onOpenCertificate();
34105
+ }
34106
+ };
34107
+ process.stdin.on("keypress", onKeypress);
34108
+ log2("[E2EE] Press c to import the active E2EE key into the browser.");
34109
+ return () => {
34110
+ process.stdin.off("keypress", onKeypress);
34111
+ if (process.stdin.isTTY && typeof process.stdin.setRawMode === "function") {
34112
+ process.stdin.setRawMode(false);
34113
+ }
34114
+ };
34115
+ }
34116
+
34117
+ // src/e2e-certificates/open-import-url.ts
34118
+ async function openE2eCertificateImportUrl({
34119
+ apiUrl,
34120
+ workspaceId,
34121
+ certificate,
34122
+ log: log2
34123
+ }) {
34124
+ const appUrl = appUrlForApiUrl(apiUrl);
34125
+ const payload = encodeURIComponent(certificate.pemBundle);
34126
+ const url2 = `${appUrl.replace(/\/$/, "")}/w/${encodeURIComponent(workspaceId)}/settings/e2e-encryption?certificate=${payload}`;
34127
+ log2(`[E2EE] Opening browser to import key "${certificate.name}" (${certificate.id})...`);
34128
+ try {
34129
+ await open_default(url2, { wait: false });
34130
+ } catch {
34131
+ log2("[E2EE] Could not open browser. Open this URL manually:");
34132
+ log2(url2);
34133
+ }
34134
+ }
34135
+
34136
+ // src/run-bridge-connected.ts
34137
+ async function runConnectedBridge(options, restartWithoutAuth) {
34138
+ const {
34139
+ apiUrl,
34140
+ workspaceId,
34141
+ authToken,
34142
+ refreshToken,
34143
+ justAuthenticated,
34144
+ worktreesRootAbs,
34145
+ e2eCertificate
34146
+ } = options;
34147
+ const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
34148
+ let cleanupKeyCommand;
33434
34149
  const handle = await createBridgeConnection({
33435
34150
  apiUrl,
33436
34151
  workspaceId,
@@ -33439,6 +34154,7 @@ async function runBridge(options) {
33439
34154
  firehoseServerUrl,
33440
34155
  justAuthenticated,
33441
34156
  worktreesRootAbs,
34157
+ e2eCertificate,
33442
34158
  log,
33443
34159
  persistTokens: (t) => {
33444
34160
  writeConfigForApi(apiUrl, {
@@ -33448,14 +34164,16 @@ async function runBridge(options) {
33448
34164
  });
33449
34165
  },
33450
34166
  onAuthInvalid: () => {
34167
+ cleanupKeyCommand?.();
33451
34168
  log("[Bridge service] Access token invalid or revoked; re-authenticating\u2026");
33452
34169
  clearConfigForApi(apiUrl);
33453
34170
  void handle.close().then(() => {
33454
- void runBridge({ apiUrl, firehoseServerUrl, worktreesRootAbs });
34171
+ void restartWithoutAuth({ apiUrl, firehoseServerUrl, worktreesRootAbs, e2eCertificate });
33455
34172
  });
33456
34173
  }
33457
34174
  });
33458
34175
  const onSignal = (kind) => {
34176
+ cleanupKeyCommand?.();
33459
34177
  logImmediate(
33460
34178
  kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
33461
34179
  );
@@ -33469,6 +34187,86 @@ async function runBridge(options) {
33469
34187
  const onSigTerm = () => onSignal("stop");
33470
34188
  process.on("SIGINT", onSigInt);
33471
34189
  process.on("SIGTERM", onSigTerm);
34190
+ if (e2eCertificate) {
34191
+ let openingCertificate = false;
34192
+ cleanupKeyCommand = installE2eCertificateKeyCommand({
34193
+ log,
34194
+ onInterrupt: onSigInt,
34195
+ onOpenCertificate: () => {
34196
+ if (openingCertificate) return;
34197
+ openingCertificate = true;
34198
+ void openE2eCertificateImportUrl({
34199
+ apiUrl,
34200
+ workspaceId,
34201
+ certificate: e2eCertificate,
34202
+ log
34203
+ }).finally(() => {
34204
+ openingCertificate = false;
34205
+ });
34206
+ }
34207
+ });
34208
+ }
34209
+ }
34210
+
34211
+ // src/run-bridge.ts
34212
+ async function runBridge(options) {
34213
+ installBridgeProcessResilience();
34214
+ const {
34215
+ apiUrl,
34216
+ workspaceId,
34217
+ authToken,
34218
+ bridgeName,
34219
+ worktreesRootAbs,
34220
+ e2eCertificate
34221
+ } = options;
34222
+ const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
34223
+ const hasAuth = workspaceId && authToken;
34224
+ if (!hasAuth) {
34225
+ const handle = runPendingAuth({
34226
+ apiUrl,
34227
+ initialWorkspaceId: workspaceId,
34228
+ preferredBridgeName: bridgeName,
34229
+ log,
34230
+ onAuth: (_auth) => {
34231
+ }
34232
+ });
34233
+ const onSignal = (kind) => {
34234
+ logImmediate(
34235
+ kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
34236
+ );
34237
+ setImmediate(() => {
34238
+ handle.close();
34239
+ process.exit(0);
34240
+ });
34241
+ };
34242
+ const onSigInt = () => onSignal("interrupt");
34243
+ const onSigTerm = () => onSignal("stop");
34244
+ process.on("SIGINT", onSigInt);
34245
+ process.on("SIGTERM", onSigTerm);
34246
+ const auth = await handle.authPromise;
34247
+ process.off("SIGINT", onSigInt);
34248
+ process.off("SIGTERM", onSigTerm);
34249
+ handle.close();
34250
+ if (!auth) return;
34251
+ writeConfigForApi(apiUrl, {
34252
+ workspaceId: auth.workspaceId,
34253
+ token: auth.token,
34254
+ refreshToken: auth.refreshToken
34255
+ });
34256
+ await runBridge({
34257
+ apiUrl,
34258
+ workspaceId: auth.workspaceId,
34259
+ authToken: auth.token,
34260
+ refreshToken: auth.refreshToken,
34261
+ firehoseServerUrl,
34262
+ bridgeName,
34263
+ justAuthenticated: true,
34264
+ worktreesRootAbs,
34265
+ e2eCertificate
34266
+ });
34267
+ return;
34268
+ }
34269
+ await runConnectedBridge(options, runBridge);
33472
34270
  }
33473
34271
  export {
33474
34272
  callSkill,