@buildautomaton/cli 0.1.13 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -972,10 +972,10 @@ var require_suggestSimilar = __commonJS({
972
972
  var require_command = __commonJS({
973
973
  "../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/lib/command.js"(exports) {
974
974
  var EventEmitter2 = __require("node:events").EventEmitter;
975
- var childProcess = __require("node:child_process");
976
- var path30 = __require("node:path");
977
- var fs23 = __require("node:fs");
978
- var process2 = __require("node:process");
975
+ var childProcess2 = __require("node:child_process");
976
+ var path33 = __require("node:path");
977
+ var fs30 = __require("node:fs");
978
+ var process8 = __require("node:process");
979
979
  var { Argument: Argument2, humanReadableArgName } = require_argument();
980
980
  var { CommanderError: CommanderError2 } = require_error();
981
981
  var { Help: Help2 } = require_help();
@@ -1021,10 +1021,10 @@ var require_command = __commonJS({
1021
1021
  this._showHelpAfterError = false;
1022
1022
  this._showSuggestionAfterError = true;
1023
1023
  this._outputConfiguration = {
1024
- writeOut: (str) => process2.stdout.write(str),
1025
- writeErr: (str) => process2.stderr.write(str),
1026
- getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
1027
- getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
1024
+ writeOut: (str) => process8.stdout.write(str),
1025
+ writeErr: (str) => process8.stderr.write(str),
1026
+ getOutHelpWidth: () => process8.stdout.isTTY ? process8.stdout.columns : void 0,
1027
+ getErrHelpWidth: () => process8.stderr.isTTY ? process8.stderr.columns : void 0,
1028
1028
  outputError: (str, write) => write(str)
1029
1029
  };
1030
1030
  this._hidden = false;
@@ -1403,7 +1403,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1403
1403
  if (this._exitCallback) {
1404
1404
  this._exitCallback(new CommanderError2(exitCode, code, message));
1405
1405
  }
1406
- process2.exit(exitCode);
1406
+ process8.exit(exitCode);
1407
1407
  }
1408
1408
  /**
1409
1409
  * Register callback `fn` for the command.
@@ -1801,16 +1801,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
1801
1801
  }
1802
1802
  parseOptions = parseOptions || {};
1803
1803
  if (argv === void 0 && parseOptions.from === void 0) {
1804
- if (process2.versions?.electron) {
1804
+ if (process8.versions?.electron) {
1805
1805
  parseOptions.from = "electron";
1806
1806
  }
1807
- const execArgv = process2.execArgv ?? [];
1807
+ const execArgv = process8.execArgv ?? [];
1808
1808
  if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
1809
1809
  parseOptions.from = "eval";
1810
1810
  }
1811
1811
  }
1812
1812
  if (argv === void 0) {
1813
- argv = process2.argv;
1813
+ argv = process8.argv;
1814
1814
  }
1815
1815
  this.rawArgs = argv.slice();
1816
1816
  let userArgs;
@@ -1821,7 +1821,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1821
1821
  userArgs = argv.slice(2);
1822
1822
  break;
1823
1823
  case "electron":
1824
- if (process2.defaultApp) {
1824
+ if (process8.defaultApp) {
1825
1825
  this._scriptPath = argv[1];
1826
1826
  userArgs = argv.slice(2);
1827
1827
  } else {
@@ -1906,11 +1906,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1906
1906
  let launchWithNode = false;
1907
1907
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1908
1908
  function findFile(baseDir, baseName) {
1909
- const localBin = path30.resolve(baseDir, baseName);
1910
- if (fs23.existsSync(localBin)) return localBin;
1911
- if (sourceExt.includes(path30.extname(baseName))) return void 0;
1909
+ const localBin = path33.resolve(baseDir, baseName);
1910
+ if (fs30.existsSync(localBin)) return localBin;
1911
+ if (sourceExt.includes(path33.extname(baseName))) return void 0;
1912
1912
  const foundExt = sourceExt.find(
1913
- (ext) => fs23.existsSync(`${localBin}${ext}`)
1913
+ (ext) => fs30.existsSync(`${localBin}${ext}`)
1914
1914
  );
1915
1915
  if (foundExt) return `${localBin}${foundExt}`;
1916
1916
  return void 0;
@@ -1922,21 +1922,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
1922
1922
  if (this._scriptPath) {
1923
1923
  let resolvedScriptPath;
1924
1924
  try {
1925
- resolvedScriptPath = fs23.realpathSync(this._scriptPath);
1925
+ resolvedScriptPath = fs30.realpathSync(this._scriptPath);
1926
1926
  } catch (err) {
1927
1927
  resolvedScriptPath = this._scriptPath;
1928
1928
  }
1929
- executableDir = path30.resolve(
1930
- path30.dirname(resolvedScriptPath),
1929
+ executableDir = path33.resolve(
1930
+ path33.dirname(resolvedScriptPath),
1931
1931
  executableDir
1932
1932
  );
1933
1933
  }
1934
1934
  if (executableDir) {
1935
1935
  let localFile = findFile(executableDir, executableFile);
1936
1936
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1937
- const legacyName = path30.basename(
1937
+ const legacyName = path33.basename(
1938
1938
  this._scriptPath,
1939
- path30.extname(this._scriptPath)
1939
+ path33.extname(this._scriptPath)
1940
1940
  );
1941
1941
  if (legacyName !== this._name) {
1942
1942
  localFile = findFile(
@@ -1947,25 +1947,25 @@ Expecting one of '${allowedValues.join("', '")}'`);
1947
1947
  }
1948
1948
  executableFile = localFile || executableFile;
1949
1949
  }
1950
- launchWithNode = sourceExt.includes(path30.extname(executableFile));
1950
+ launchWithNode = sourceExt.includes(path33.extname(executableFile));
1951
1951
  let proc;
1952
- if (process2.platform !== "win32") {
1952
+ if (process8.platform !== "win32") {
1953
1953
  if (launchWithNode) {
1954
1954
  args.unshift(executableFile);
1955
- args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1956
- proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
1955
+ args = incrementNodeInspectorPort(process8.execArgv).concat(args);
1956
+ proc = childProcess2.spawn(process8.argv[0], args, { stdio: "inherit" });
1957
1957
  } else {
1958
- proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1958
+ proc = childProcess2.spawn(executableFile, args, { stdio: "inherit" });
1959
1959
  }
1960
1960
  } else {
1961
1961
  args.unshift(executableFile);
1962
- args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1963
- proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
1962
+ args = incrementNodeInspectorPort(process8.execArgv).concat(args);
1963
+ proc = childProcess2.spawn(process8.execPath, args, { stdio: "inherit" });
1964
1964
  }
1965
1965
  if (!proc.killed) {
1966
1966
  const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
1967
1967
  signals.forEach((signal) => {
1968
- process2.on(signal, () => {
1968
+ process8.on(signal, () => {
1969
1969
  if (proc.killed === false && proc.exitCode === null) {
1970
1970
  proc.kill(signal);
1971
1971
  }
@@ -1976,7 +1976,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1976
1976
  proc.on("close", (code) => {
1977
1977
  code = code ?? 1;
1978
1978
  if (!exitCallback) {
1979
- process2.exit(code);
1979
+ process8.exit(code);
1980
1980
  } else {
1981
1981
  exitCallback(
1982
1982
  new CommanderError2(
@@ -1999,7 +1999,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1999
1999
  throw new Error(`'${executableFile}' not executable`);
2000
2000
  }
2001
2001
  if (!exitCallback) {
2002
- process2.exit(1);
2002
+ process8.exit(1);
2003
2003
  } else {
2004
2004
  const wrappedError = new CommanderError2(
2005
2005
  1,
@@ -2491,13 +2491,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
2491
2491
  */
2492
2492
  _parseOptionsEnv() {
2493
2493
  this.options.forEach((option) => {
2494
- if (option.envVar && option.envVar in process2.env) {
2494
+ if (option.envVar && option.envVar in process8.env) {
2495
2495
  const optionKey = option.attributeName();
2496
2496
  if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(
2497
2497
  this.getOptionValueSource(optionKey)
2498
2498
  )) {
2499
2499
  if (option.required || option.optional) {
2500
- this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
2500
+ this.emit(`optionEnv:${option.name()}`, process8.env[option.envVar]);
2501
2501
  } else {
2502
2502
  this.emit(`optionEnv:${option.name()}`);
2503
2503
  }
@@ -2787,7 +2787,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2787
2787
  * @return {Command}
2788
2788
  */
2789
2789
  nameFromFilename(filename) {
2790
- this._name = path30.basename(filename, path30.extname(filename));
2790
+ this._name = path33.basename(filename, path33.extname(filename));
2791
2791
  return this;
2792
2792
  }
2793
2793
  /**
@@ -2801,9 +2801,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
2801
2801
  * @param {string} [path]
2802
2802
  * @return {(string|null|Command)}
2803
2803
  */
2804
- executableDir(path31) {
2805
- if (path31 === void 0) return this._executableDir;
2806
- this._executableDir = path31;
2804
+ executableDir(path34) {
2805
+ if (path34 === void 0) return this._executableDir;
2806
+ this._executableDir = path34;
2807
2807
  return this;
2808
2808
  }
2809
2809
  /**
@@ -2926,7 +2926,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2926
2926
  */
2927
2927
  help(contextOptions) {
2928
2928
  this.outputHelp(contextOptions);
2929
- let exitCode = process2.exitCode || 0;
2929
+ let exitCode = process8.exitCode || 0;
2930
2930
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
2931
2931
  exitCode = 1;
2932
2932
  }
@@ -6175,7 +6175,7 @@ var require_stream = __commonJS({
6175
6175
  };
6176
6176
  duplex._final = function(callback) {
6177
6177
  if (ws.readyState === ws.CONNECTING) {
6178
- ws.once("open", function open() {
6178
+ ws.once("open", function open2() {
6179
6179
  duplex._final(callback);
6180
6180
  });
6181
6181
  return;
@@ -6196,7 +6196,7 @@ var require_stream = __commonJS({
6196
6196
  };
6197
6197
  duplex._write = function(chunk, encoding, callback) {
6198
6198
  if (ws.readyState === ws.CONNECTING) {
6199
- ws.once("open", function open() {
6199
+ ws.once("open", function open2() {
6200
6200
  duplex._write(chunk, encoding, callback);
6201
6201
  });
6202
6202
  return;
@@ -7129,7 +7129,7 @@ var require_has_flag = __commonJS({
7129
7129
  var require_supports_color = __commonJS({
7130
7130
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
7131
7131
  "use strict";
7132
- var os5 = __require("os");
7132
+ var os6 = __require("os");
7133
7133
  var tty = __require("tty");
7134
7134
  var hasFlag = require_has_flag();
7135
7135
  var { env } = process;
@@ -7177,7 +7177,7 @@ var require_supports_color = __commonJS({
7177
7177
  return min;
7178
7178
  }
7179
7179
  if (process.platform === "win32") {
7180
- const osRelease = os5.release().split(".");
7180
+ const osRelease = os6.release().split(".");
7181
7181
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
7182
7182
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
7183
7183
  }
@@ -7423,10 +7423,10 @@ var require_src2 = __commonJS({
7423
7423
  var fs_1 = __require("fs");
7424
7424
  var debug_1 = __importDefault(require_src());
7425
7425
  var log2 = debug_1.default("@kwsites/file-exists");
7426
- function check2(path30, isFile, isDirectory) {
7427
- log2(`checking %s`, path30);
7426
+ function check2(path33, isFile, isDirectory) {
7427
+ log2(`checking %s`, path33);
7428
7428
  try {
7429
- const stat2 = fs_1.statSync(path30);
7429
+ const stat2 = fs_1.statSync(path33);
7430
7430
  if (stat2.isFile() && isFile) {
7431
7431
  log2(`[OK] path represents a file`);
7432
7432
  return true;
@@ -7446,8 +7446,8 @@ var require_src2 = __commonJS({
7446
7446
  throw e;
7447
7447
  }
7448
7448
  }
7449
- function exists2(path30, type = exports.READABLE) {
7450
- return check2(path30, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
7449
+ function exists2(path33, type = exports.READABLE) {
7450
+ return check2(path33, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
7451
7451
  }
7452
7452
  exports.exists = exists2;
7453
7453
  exports.FILE = 1;
@@ -7922,8 +7922,8 @@ var init_parseUtil = __esm({
7922
7922
  init_errors();
7923
7923
  init_en();
7924
7924
  makeIssue = (params) => {
7925
- const { data, path: path30, errorMaps, issueData } = params;
7926
- const fullPath = [...path30, ...issueData.path || []];
7925
+ const { data, path: path33, errorMaps, issueData } = params;
7926
+ const fullPath = [...path33, ...issueData.path || []];
7927
7927
  const fullIssue = {
7928
7928
  ...issueData,
7929
7929
  path: fullPath
@@ -8231,11 +8231,11 @@ var init_types = __esm({
8231
8231
  init_parseUtil();
8232
8232
  init_util2();
8233
8233
  ParseInputLazyPath = class {
8234
- constructor(parent, value, path30, key) {
8234
+ constructor(parent, value, path33, key) {
8235
8235
  this._cachedPath = [];
8236
8236
  this.parent = parent;
8237
8237
  this.data = value;
8238
- this._path = path30;
8238
+ this._path = path33;
8239
8239
  this._key = key;
8240
8240
  }
8241
8241
  get path() {
@@ -11850,15 +11850,15 @@ function assignProp(target, prop, value) {
11850
11850
  configurable: true
11851
11851
  });
11852
11852
  }
11853
- function getElementAtPath(obj, path30) {
11854
- if (!path30)
11853
+ function getElementAtPath(obj, path33) {
11854
+ if (!path33)
11855
11855
  return obj;
11856
- return path30.reduce((acc, key) => acc?.[key], obj);
11856
+ return path33.reduce((acc, key) => acc?.[key], obj);
11857
11857
  }
11858
11858
  function promiseAllObject(promisesObj) {
11859
11859
  const keys = Object.keys(promisesObj);
11860
- const promises = keys.map((key) => promisesObj[key]);
11861
- return Promise.all(promises).then((results) => {
11860
+ const promises3 = keys.map((key) => promisesObj[key]);
11861
+ return Promise.all(promises3).then((results) => {
11862
11862
  const resolvedObj = {};
11863
11863
  for (let i = 0; i < keys.length; i++) {
11864
11864
  resolvedObj[keys[i]] = results[i];
@@ -12102,11 +12102,11 @@ function aborted(x, startIndex = 0) {
12102
12102
  }
12103
12103
  return false;
12104
12104
  }
12105
- function prefixIssues(path30, issues) {
12105
+ function prefixIssues(path33, issues) {
12106
12106
  return issues.map((iss) => {
12107
12107
  var _a2;
12108
12108
  (_a2 = iss).path ?? (_a2.path = []);
12109
- iss.path.unshift(path30);
12109
+ iss.path.unshift(path33);
12110
12110
  return iss;
12111
12111
  });
12112
12112
  }
@@ -12295,7 +12295,7 @@ function treeifyError(error40, _mapper) {
12295
12295
  return issue2.message;
12296
12296
  };
12297
12297
  const result = { errors: [] };
12298
- const processError = (error41, path30 = []) => {
12298
+ const processError = (error41, path33 = []) => {
12299
12299
  var _a2, _b;
12300
12300
  for (const issue2 of error41.issues) {
12301
12301
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -12305,7 +12305,7 @@ function treeifyError(error40, _mapper) {
12305
12305
  } else if (issue2.code === "invalid_element") {
12306
12306
  processError({ issues: issue2.issues }, issue2.path);
12307
12307
  } else {
12308
- const fullpath = [...path30, ...issue2.path];
12308
+ const fullpath = [...path33, ...issue2.path];
12309
12309
  if (fullpath.length === 0) {
12310
12310
  result.errors.push(mapper(issue2));
12311
12311
  continue;
@@ -12335,9 +12335,9 @@ function treeifyError(error40, _mapper) {
12335
12335
  processError(error40);
12336
12336
  return result;
12337
12337
  }
12338
- function toDotPath(path30) {
12338
+ function toDotPath(path33) {
12339
12339
  const segs = [];
12340
- for (const seg of path30) {
12340
+ for (const seg of path33) {
12341
12341
  if (typeof seg === "number")
12342
12342
  segs.push(`[${seg}]`);
12343
12343
  else if (typeof seg === "symbol")
@@ -24800,8 +24800,8 @@ var init_acp = __esm({
24800
24800
  this.#requestHandler = requestHandler;
24801
24801
  this.#notificationHandler = notificationHandler;
24802
24802
  this.#stream = stream;
24803
- this.#closedPromise = new Promise((resolve15) => {
24804
- this.#abortController.signal.addEventListener("abort", () => resolve15());
24803
+ this.#closedPromise = new Promise((resolve16) => {
24804
+ this.#abortController.signal.addEventListener("abort", () => resolve16());
24805
24805
  });
24806
24806
  this.#receive();
24807
24807
  }
@@ -24950,8 +24950,8 @@ var init_acp = __esm({
24950
24950
  }
24951
24951
  async sendRequest(method, params) {
24952
24952
  const id = this.#nextRequestId++;
24953
- const responsePromise = new Promise((resolve15, reject) => {
24954
- this.#pendingResponses.set(id, { resolve: resolve15, reject });
24953
+ const responsePromise = new Promise((resolve16, reject) => {
24954
+ this.#pendingResponses.set(id, { resolve: resolve16, reject });
24955
24955
  });
24956
24956
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
24957
24957
  return responsePromise;
@@ -25047,8 +25047,8 @@ var init_acp = __esm({
25047
25047
  });
25048
25048
 
25049
25049
  // src/cli.ts
25050
- import * as fs22 from "node:fs";
25051
- import * as path29 from "node:path";
25050
+ import * as fs29 from "node:fs";
25051
+ import * as path32 from "node:path";
25052
25052
 
25053
25053
  // ../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/esm.mjs
25054
25054
  var import_index = __toESM(require_commander(), 1);
@@ -25169,6 +25169,19 @@ function logImmediate(line) {
25169
25169
  `);
25170
25170
  }
25171
25171
 
25172
+ // src/process-bridge-resilience.ts
25173
+ var installed = false;
25174
+ function installBridgeProcessResilience() {
25175
+ if (installed) return;
25176
+ installed = true;
25177
+ process.on("uncaughtException", (err) => {
25178
+ logImmediate(`[bridge] uncaughtException \u2014 continuing: ${err.stack ?? String(err)}`);
25179
+ });
25180
+ process.on("unhandledRejection", (reason) => {
25181
+ logImmediate(`[bridge] unhandledRejection \u2014 continuing: ${reason instanceof Error ? reason.stack : String(reason)}`);
25182
+ });
25183
+ }
25184
+
25172
25185
  // ../../node_modules/.pnpm/ws@8.19.0/node_modules/ws/wrapper.mjs
25173
25186
  var import_stream = __toESM(require_stream(), 1);
25174
25187
  var import_receiver = __toESM(require_receiver(), 1);
@@ -25308,8 +25321,521 @@ function sendWsMessage(ws, payload) {
25308
25321
  }
25309
25322
  }
25310
25323
 
25324
+ // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
25325
+ import process7 from "node:process";
25326
+ import { Buffer as Buffer2 } from "node:buffer";
25327
+ import path3 from "node:path";
25328
+ import { fileURLToPath } from "node:url";
25329
+ import { promisify as promisify5 } from "node:util";
25330
+ import childProcess from "node:child_process";
25331
+ import fs6, { constants as fsConstants2 } from "node:fs/promises";
25332
+
25333
+ // ../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
25334
+ import process3 from "node:process";
25335
+ import fs5, { constants as fsConstants } from "node:fs/promises";
25336
+
25337
+ // ../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
25338
+ import process2 from "node:process";
25339
+ import os2 from "node:os";
25340
+ import fs4 from "node:fs";
25341
+
25342
+ // ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
25343
+ import fs3 from "node:fs";
25344
+
25345
+ // ../../node_modules/.pnpm/is-docker@3.0.0/node_modules/is-docker/index.js
25346
+ import fs2 from "node:fs";
25347
+ var isDockerCached;
25348
+ function hasDockerEnv() {
25349
+ try {
25350
+ fs2.statSync("/.dockerenv");
25351
+ return true;
25352
+ } catch {
25353
+ return false;
25354
+ }
25355
+ }
25356
+ function hasDockerCGroup() {
25357
+ try {
25358
+ return fs2.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
25359
+ } catch {
25360
+ return false;
25361
+ }
25362
+ }
25363
+ function isDocker() {
25364
+ if (isDockerCached === void 0) {
25365
+ isDockerCached = hasDockerEnv() || hasDockerCGroup();
25366
+ }
25367
+ return isDockerCached;
25368
+ }
25369
+
25370
+ // ../../node_modules/.pnpm/is-inside-container@1.0.0/node_modules/is-inside-container/index.js
25371
+ var cachedResult;
25372
+ var hasContainerEnv = () => {
25373
+ try {
25374
+ fs3.statSync("/run/.containerenv");
25375
+ return true;
25376
+ } catch {
25377
+ return false;
25378
+ }
25379
+ };
25380
+ function isInsideContainer() {
25381
+ if (cachedResult === void 0) {
25382
+ cachedResult = hasContainerEnv() || isDocker();
25383
+ }
25384
+ return cachedResult;
25385
+ }
25386
+
25387
+ // ../../node_modules/.pnpm/is-wsl@3.1.1/node_modules/is-wsl/index.js
25388
+ var isWsl = () => {
25389
+ if (process2.platform !== "linux") {
25390
+ return false;
25391
+ }
25392
+ if (os2.release().toLowerCase().includes("microsoft")) {
25393
+ if (isInsideContainer()) {
25394
+ return false;
25395
+ }
25396
+ return true;
25397
+ }
25398
+ try {
25399
+ if (fs4.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft")) {
25400
+ return !isInsideContainer();
25401
+ }
25402
+ } catch {
25403
+ }
25404
+ if (fs4.existsSync("/proc/sys/fs/binfmt_misc/WSLInterop") || fs4.existsSync("/run/WSL")) {
25405
+ return !isInsideContainer();
25406
+ }
25407
+ return false;
25408
+ };
25409
+ var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
25410
+
25411
+ // ../../node_modules/.pnpm/wsl-utils@0.1.0/node_modules/wsl-utils/index.js
25412
+ var wslDrivesMountPoint = /* @__PURE__ */ (() => {
25413
+ const defaultMountPoint = "/mnt/";
25414
+ let mountPoint;
25415
+ return async function() {
25416
+ if (mountPoint) {
25417
+ return mountPoint;
25418
+ }
25419
+ const configFilePath2 = "/etc/wsl.conf";
25420
+ let isConfigFileExists = false;
25421
+ try {
25422
+ await fs5.access(configFilePath2, fsConstants.F_OK);
25423
+ isConfigFileExists = true;
25424
+ } catch {
25425
+ }
25426
+ if (!isConfigFileExists) {
25427
+ return defaultMountPoint;
25428
+ }
25429
+ const configContent = await fs5.readFile(configFilePath2, { encoding: "utf8" });
25430
+ const configMountPoint = /(?<!#.*)root\s*=\s*(?<mountPoint>.*)/g.exec(configContent);
25431
+ if (!configMountPoint) {
25432
+ return defaultMountPoint;
25433
+ }
25434
+ mountPoint = configMountPoint.groups.mountPoint.trim();
25435
+ mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
25436
+ return mountPoint;
25437
+ };
25438
+ })();
25439
+ var powerShellPathFromWsl = async () => {
25440
+ const mountPoint = await wslDrivesMountPoint();
25441
+ return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
25442
+ };
25443
+ var powerShellPath = async () => {
25444
+ if (is_wsl_default) {
25445
+ return powerShellPathFromWsl();
25446
+ }
25447
+ return `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
25448
+ };
25449
+
25450
+ // ../../node_modules/.pnpm/define-lazy-prop@3.0.0/node_modules/define-lazy-prop/index.js
25451
+ function defineLazyProperty(object2, propertyName, valueGetter) {
25452
+ const define = (value) => Object.defineProperty(object2, propertyName, { value, enumerable: true, writable: true });
25453
+ Object.defineProperty(object2, propertyName, {
25454
+ configurable: true,
25455
+ enumerable: true,
25456
+ get() {
25457
+ const result = valueGetter();
25458
+ define(result);
25459
+ return result;
25460
+ },
25461
+ set(value) {
25462
+ define(value);
25463
+ }
25464
+ });
25465
+ return object2;
25466
+ }
25467
+
25468
+ // ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
25469
+ import { promisify as promisify4 } from "node:util";
25470
+ import process6 from "node:process";
25471
+ import { execFile as execFile4 } from "node:child_process";
25472
+
25473
+ // ../../node_modules/.pnpm/default-browser-id@5.0.1/node_modules/default-browser-id/index.js
25474
+ import { promisify } from "node:util";
25475
+ import process4 from "node:process";
25476
+ import { execFile } from "node:child_process";
25477
+ var execFileAsync = promisify(execFile);
25478
+ async function defaultBrowserId() {
25479
+ if (process4.platform !== "darwin") {
25480
+ throw new Error("macOS only");
25481
+ }
25482
+ const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
25483
+ const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
25484
+ const browserId = match?.groups.id ?? "com.apple.Safari";
25485
+ if (browserId === "com.apple.safari") {
25486
+ return "com.apple.Safari";
25487
+ }
25488
+ return browserId;
25489
+ }
25490
+
25491
+ // ../../node_modules/.pnpm/run-applescript@7.1.0/node_modules/run-applescript/index.js
25492
+ import process5 from "node:process";
25493
+ import { promisify as promisify2 } from "node:util";
25494
+ import { execFile as execFile2, execFileSync } from "node:child_process";
25495
+ var execFileAsync2 = promisify2(execFile2);
25496
+ async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
25497
+ if (process5.platform !== "darwin") {
25498
+ throw new Error("macOS only");
25499
+ }
25500
+ const outputArguments = humanReadableOutput ? [] : ["-ss"];
25501
+ const execOptions = {};
25502
+ if (signal) {
25503
+ execOptions.signal = signal;
25504
+ }
25505
+ const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
25506
+ return stdout.trim();
25507
+ }
25508
+
25509
+ // ../../node_modules/.pnpm/bundle-name@4.1.0/node_modules/bundle-name/index.js
25510
+ async function bundleName(bundleId) {
25511
+ return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
25512
+ tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
25513
+ }
25514
+
25515
+ // ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/windows.js
25516
+ import { promisify as promisify3 } from "node:util";
25517
+ import { execFile as execFile3 } from "node:child_process";
25518
+ var execFileAsync3 = promisify3(execFile3);
25519
+ var windowsBrowserProgIds = {
25520
+ MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
25521
+ // The missing `L` is correct.
25522
+ MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
25523
+ MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
25524
+ AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
25525
+ ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
25526
+ ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
25527
+ ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
25528
+ ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
25529
+ BraveHTML: { name: "Brave", id: "com.brave.Browser" },
25530
+ BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
25531
+ BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
25532
+ BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
25533
+ FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
25534
+ OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
25535
+ VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
25536
+ "IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
25537
+ };
25538
+ var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
25539
+ var UnknownBrowserError = class extends Error {
25540
+ };
25541
+ async function defaultBrowser(_execFileAsync = execFileAsync3) {
25542
+ const { stdout } = await _execFileAsync("reg", [
25543
+ "QUERY",
25544
+ " HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
25545
+ "/v",
25546
+ "ProgId"
25547
+ ]);
25548
+ const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
25549
+ if (!match) {
25550
+ throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
25551
+ }
25552
+ const { id } = match.groups;
25553
+ const dotIndex = id.lastIndexOf(".");
25554
+ const hyphenIndex = id.lastIndexOf("-");
25555
+ const baseIdByDot = dotIndex === -1 ? void 0 : id.slice(0, dotIndex);
25556
+ const baseIdByHyphen = hyphenIndex === -1 ? void 0 : id.slice(0, hyphenIndex);
25557
+ return windowsBrowserProgIds[id] ?? windowsBrowserProgIds[baseIdByDot] ?? windowsBrowserProgIds[baseIdByHyphen] ?? { name: id, id };
25558
+ }
25559
+
25560
+ // ../../node_modules/.pnpm/default-browser@5.5.0/node_modules/default-browser/index.js
25561
+ var execFileAsync4 = promisify4(execFile4);
25562
+ var titleize = (string4) => string4.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x) => x.toUpperCase());
25563
+ async function defaultBrowser2() {
25564
+ if (process6.platform === "darwin") {
25565
+ const id = await defaultBrowserId();
25566
+ const name = await bundleName(id);
25567
+ return { name, id };
25568
+ }
25569
+ if (process6.platform === "linux") {
25570
+ const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
25571
+ const id = stdout.trim();
25572
+ const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
25573
+ return { name, id };
25574
+ }
25575
+ if (process6.platform === "win32") {
25576
+ return defaultBrowser();
25577
+ }
25578
+ throw new Error("Only macOS, Linux, and Windows are supported");
25579
+ }
25580
+
25581
+ // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
25582
+ var execFile5 = promisify5(childProcess.execFile);
25583
+ var __dirname = path3.dirname(fileURLToPath(import.meta.url));
25584
+ var localXdgOpenPath = path3.join(__dirname, "xdg-open");
25585
+ var { platform, arch } = process7;
25586
+ async function getWindowsDefaultBrowserFromWsl() {
25587
+ const powershellPath = await powerShellPath();
25588
+ const rawCommand = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
25589
+ const encodedCommand = Buffer2.from(rawCommand, "utf16le").toString("base64");
25590
+ const { stdout } = await execFile5(
25591
+ powershellPath,
25592
+ [
25593
+ "-NoProfile",
25594
+ "-NonInteractive",
25595
+ "-ExecutionPolicy",
25596
+ "Bypass",
25597
+ "-EncodedCommand",
25598
+ encodedCommand
25599
+ ],
25600
+ { encoding: "utf8" }
25601
+ );
25602
+ const progId = stdout.trim();
25603
+ const browserMap = {
25604
+ ChromeHTML: "com.google.chrome",
25605
+ BraveHTML: "com.brave.Browser",
25606
+ MSEdgeHTM: "com.microsoft.edge",
25607
+ FirefoxURL: "org.mozilla.firefox"
25608
+ };
25609
+ return browserMap[progId] ? { id: browserMap[progId] } : {};
25610
+ }
25611
+ var pTryEach = async (array2, mapper) => {
25612
+ let latestError;
25613
+ for (const item of array2) {
25614
+ try {
25615
+ return await mapper(item);
25616
+ } catch (error40) {
25617
+ latestError = error40;
25618
+ }
25619
+ }
25620
+ throw latestError;
25621
+ };
25622
+ var baseOpen = async (options) => {
25623
+ options = {
25624
+ wait: false,
25625
+ background: false,
25626
+ newInstance: false,
25627
+ allowNonzeroExitCode: false,
25628
+ ...options
25629
+ };
25630
+ if (Array.isArray(options.app)) {
25631
+ return pTryEach(options.app, (singleApp) => baseOpen({
25632
+ ...options,
25633
+ app: singleApp
25634
+ }));
25635
+ }
25636
+ let { name: app, arguments: appArguments = [] } = options.app ?? {};
25637
+ appArguments = [...appArguments];
25638
+ if (Array.isArray(app)) {
25639
+ return pTryEach(app, (appName) => baseOpen({
25640
+ ...options,
25641
+ app: {
25642
+ name: appName,
25643
+ arguments: appArguments
25644
+ }
25645
+ }));
25646
+ }
25647
+ if (app === "browser" || app === "browserPrivate") {
25648
+ const ids = {
25649
+ "com.google.chrome": "chrome",
25650
+ "google-chrome.desktop": "chrome",
25651
+ "com.brave.Browser": "brave",
25652
+ "org.mozilla.firefox": "firefox",
25653
+ "firefox.desktop": "firefox",
25654
+ "com.microsoft.msedge": "edge",
25655
+ "com.microsoft.edge": "edge",
25656
+ "com.microsoft.edgemac": "edge",
25657
+ "microsoft-edge.desktop": "edge"
25658
+ };
25659
+ const flags = {
25660
+ chrome: "--incognito",
25661
+ brave: "--incognito",
25662
+ firefox: "--private-window",
25663
+ edge: "--inPrivate"
25664
+ };
25665
+ const browser = is_wsl_default ? await getWindowsDefaultBrowserFromWsl() : await defaultBrowser2();
25666
+ if (browser.id in ids) {
25667
+ const browserName = ids[browser.id];
25668
+ if (app === "browserPrivate") {
25669
+ appArguments.push(flags[browserName]);
25670
+ }
25671
+ return baseOpen({
25672
+ ...options,
25673
+ app: {
25674
+ name: apps[browserName],
25675
+ arguments: appArguments
25676
+ }
25677
+ });
25678
+ }
25679
+ throw new Error(`${browser.name} is not supported as a default browser`);
25680
+ }
25681
+ let command;
25682
+ const cliArguments = [];
25683
+ const childProcessOptions = {};
25684
+ if (platform === "darwin") {
25685
+ command = "open";
25686
+ if (options.wait) {
25687
+ cliArguments.push("--wait-apps");
25688
+ }
25689
+ if (options.background) {
25690
+ cliArguments.push("--background");
25691
+ }
25692
+ if (options.newInstance) {
25693
+ cliArguments.push("--new");
25694
+ }
25695
+ if (app) {
25696
+ cliArguments.push("-a", app);
25697
+ }
25698
+ } else if (platform === "win32" || is_wsl_default && !isInsideContainer() && !app) {
25699
+ command = await powerShellPath();
25700
+ cliArguments.push(
25701
+ "-NoProfile",
25702
+ "-NonInteractive",
25703
+ "-ExecutionPolicy",
25704
+ "Bypass",
25705
+ "-EncodedCommand"
25706
+ );
25707
+ if (!is_wsl_default) {
25708
+ childProcessOptions.windowsVerbatimArguments = true;
25709
+ }
25710
+ const encodedArguments = ["Start"];
25711
+ if (options.wait) {
25712
+ encodedArguments.push("-Wait");
25713
+ }
25714
+ if (app) {
25715
+ encodedArguments.push(`"\`"${app}\`""`);
25716
+ if (options.target) {
25717
+ appArguments.push(options.target);
25718
+ }
25719
+ } else if (options.target) {
25720
+ encodedArguments.push(`"${options.target}"`);
25721
+ }
25722
+ if (appArguments.length > 0) {
25723
+ appArguments = appArguments.map((argument) => `"\`"${argument}\`""`);
25724
+ encodedArguments.push("-ArgumentList", appArguments.join(","));
25725
+ }
25726
+ options.target = Buffer2.from(encodedArguments.join(" "), "utf16le").toString("base64");
25727
+ } else {
25728
+ if (app) {
25729
+ command = app;
25730
+ } else {
25731
+ const isBundled = !__dirname || __dirname === "/";
25732
+ let exeLocalXdgOpen = false;
25733
+ try {
25734
+ await fs6.access(localXdgOpenPath, fsConstants2.X_OK);
25735
+ exeLocalXdgOpen = true;
25736
+ } catch {
25737
+ }
25738
+ const useSystemXdgOpen = process7.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
25739
+ command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
25740
+ }
25741
+ if (appArguments.length > 0) {
25742
+ cliArguments.push(...appArguments);
25743
+ }
25744
+ if (!options.wait) {
25745
+ childProcessOptions.stdio = "ignore";
25746
+ childProcessOptions.detached = true;
25747
+ }
25748
+ }
25749
+ if (platform === "darwin" && appArguments.length > 0) {
25750
+ cliArguments.push("--args", ...appArguments);
25751
+ }
25752
+ if (options.target) {
25753
+ cliArguments.push(options.target);
25754
+ }
25755
+ const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
25756
+ if (options.wait) {
25757
+ return new Promise((resolve16, reject) => {
25758
+ subprocess.once("error", reject);
25759
+ subprocess.once("close", (exitCode) => {
25760
+ if (!options.allowNonzeroExitCode && exitCode > 0) {
25761
+ reject(new Error(`Exited with code ${exitCode}`));
25762
+ return;
25763
+ }
25764
+ resolve16(subprocess);
25765
+ });
25766
+ });
25767
+ }
25768
+ subprocess.unref();
25769
+ return subprocess;
25770
+ };
25771
+ var open = (target, options) => {
25772
+ if (typeof target !== "string") {
25773
+ throw new TypeError("Expected a `target`");
25774
+ }
25775
+ return baseOpen({
25776
+ ...options,
25777
+ target
25778
+ });
25779
+ };
25780
+ function detectArchBinary(binary) {
25781
+ if (typeof binary === "string" || Array.isArray(binary)) {
25782
+ return binary;
25783
+ }
25784
+ const { [arch]: archBinary } = binary;
25785
+ if (!archBinary) {
25786
+ throw new Error(`${arch} is not supported`);
25787
+ }
25788
+ return archBinary;
25789
+ }
25790
+ function detectPlatformBinary({ [platform]: platformBinary }, { wsl }) {
25791
+ if (wsl && is_wsl_default) {
25792
+ return detectArchBinary(wsl);
25793
+ }
25794
+ if (!platformBinary) {
25795
+ throw new Error(`${platform} is not supported`);
25796
+ }
25797
+ return detectArchBinary(platformBinary);
25798
+ }
25799
+ var apps = {};
25800
+ defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
25801
+ darwin: "google chrome",
25802
+ win32: "chrome",
25803
+ linux: ["google-chrome", "google-chrome-stable", "chromium"]
25804
+ }, {
25805
+ wsl: {
25806
+ ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
25807
+ x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
25808
+ }
25809
+ }));
25810
+ defineLazyProperty(apps, "brave", () => detectPlatformBinary({
25811
+ darwin: "brave browser",
25812
+ win32: "brave",
25813
+ linux: ["brave-browser", "brave"]
25814
+ }, {
25815
+ wsl: {
25816
+ ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
25817
+ x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
25818
+ }
25819
+ }));
25820
+ defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
25821
+ darwin: "firefox",
25822
+ win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
25823
+ linux: "firefox"
25824
+ }, {
25825
+ wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
25826
+ }));
25827
+ defineLazyProperty(apps, "edge", () => detectPlatformBinary({
25828
+ darwin: "microsoft edge",
25829
+ win32: "msedge",
25830
+ linux: ["microsoft-edge", "microsoft-edge-dev"]
25831
+ }, {
25832
+ wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
25833
+ }));
25834
+ defineLazyProperty(apps, "browser", () => "browser");
25835
+ defineLazyProperty(apps, "browserPrivate", () => "browserPrivate");
25836
+ var open_default = open;
25837
+
25311
25838
  // src/auth/open-browser.ts
25312
- import { execSync } from "node:child_process";
25313
25839
  function isLocalApiUrl(apiUrl) {
25314
25840
  try {
25315
25841
  const u = new URL(apiUrl);
@@ -25319,7 +25845,7 @@ function isLocalApiUrl(apiUrl) {
25319
25845
  return false;
25320
25846
  }
25321
25847
  }
25322
- function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
25848
+ async function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn = log) {
25323
25849
  const appUrl = apiUrl && isLocalApiUrl(apiUrl) ? process.env.BUILDAUTOMATON_APP_URL ?? "http://localhost:3000" : process.env.BUILDAUTOMATON_APP_URL ?? "https://app.buildautomaton.com";
25324
25850
  let connectCliUrl = `${appUrl.replace(/\/$/, "")}/bridges/connect?connectionId=${connectionId}`;
25325
25851
  if (initialWorkspaceId) {
@@ -25333,10 +25859,11 @@ function openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiU
25333
25859
  connectCliUrl += `&bridgeName=${encodeURIComponent(preferredBridgeName.trim())}`;
25334
25860
  }
25335
25861
  logFn("Opening browser to link this CLI\u2026");
25336
- logFn("If you\u2019re already signed in with one workspace, the CLI will connect automatically. Otherwise sign in and link to a workspace.");
25862
+ logFn(
25863
+ "If you\u2019re already signed in with one workspace, the CLI will connect automatically. Otherwise sign in and link to a workspace."
25864
+ );
25337
25865
  try {
25338
- const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
25339
- execSync(`${cmd} "${connectCliUrl}"`, { stdio: "ignore" });
25866
+ await open_default(connectCliUrl, { wait: false });
25340
25867
  } catch {
25341
25868
  logFn("Could not open browser. Open this URL manually:");
25342
25869
  logFn(connectCliUrl);
@@ -25527,8 +26054,8 @@ function runPendingAuth(options) {
25527
26054
  let hasOpenedBrowser = false;
25528
26055
  let resolved = false;
25529
26056
  let resolveAuth;
25530
- const authPromise = new Promise((resolve15) => {
25531
- resolveAuth = resolve15;
26057
+ const authPromise = new Promise((resolve16) => {
26058
+ resolveAuth = resolve16;
25532
26059
  });
25533
26060
  let reconnectAttempt = 0;
25534
26061
  const signInQuiet = createEmptyReconnectQuietSlot();
@@ -25591,7 +26118,7 @@ function runPendingAuth(options) {
25591
26118
  }
25592
26119
  if (!hasOpenedBrowser) {
25593
26120
  hasOpenedBrowser = true;
25594
- openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
26121
+ void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
25595
26122
  }
25596
26123
  },
25597
26124
  onClose: (code, reason) => {
@@ -25633,7 +26160,7 @@ function runPendingAuth(options) {
25633
26160
  browserFallback = null;
25634
26161
  if (!hasOpenedBrowser) {
25635
26162
  hasOpenedBrowser = true;
25636
- openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
26163
+ void openBrowser(connectionId, initialWorkspaceId, preferredBridgeName, apiUrl, logFn);
25637
26164
  }
25638
26165
  }, BROWSER_OPEN_FALLBACK_MS);
25639
26166
  connect();
@@ -25650,7 +26177,7 @@ function runPendingAuth(options) {
25650
26177
  async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
25651
26178
  const say = log2 ?? logImmediate;
25652
26179
  say("Cleaning up connections\u2026");
25653
- await new Promise((resolve15) => setImmediate(resolve15));
26180
+ await new Promise((resolve16) => setImmediate(resolve16));
25654
26181
  state.closedByUser = true;
25655
26182
  clearReconnectQuietTimer(state.mainQuiet);
25656
26183
  clearReconnectQuietTimer(state.firehoseQuiet);
@@ -25720,27 +26247,27 @@ function localAgentErrorSuggestsAuth(agentType, errorText) {
25720
26247
  }
25721
26248
 
25722
26249
  // src/git/session-git-queue.ts
25723
- import { execFile as execFile2 } from "node:child_process";
26250
+ import { execFile as execFile7 } from "node:child_process";
25724
26251
  import { readFile, stat } from "node:fs/promises";
25725
- import { promisify as promisify2 } from "node:util";
25726
- import * as path5 from "node:path";
26252
+ import { promisify as promisify7 } from "node:util";
26253
+ import * as path6 from "node:path";
25727
26254
 
25728
26255
  // src/git/pre-turn-snapshot.ts
25729
- import * as fs3 from "node:fs";
25730
- import * as path4 from "node:path";
25731
- import { execFile } from "node:child_process";
25732
- import { promisify } from "node:util";
26256
+ import * as fs8 from "node:fs";
26257
+ import * as path5 from "node:path";
26258
+ import { execFile as execFile6 } from "node:child_process";
26259
+ import { promisify as promisify6 } from "node:util";
25733
26260
 
25734
26261
  // src/git/discover-repos.ts
25735
- import * as fs2 from "node:fs";
25736
- import * as path3 from "node:path";
26262
+ import * as fs7 from "node:fs";
26263
+ import * as path4 from "node:path";
25737
26264
 
25738
26265
  // ../../node_modules/.pnpm/simple-git@3.32.3/node_modules/simple-git/dist/esm/index.js
25739
26266
  var import_file_exists = __toESM(require_dist(), 1);
25740
26267
  var import_debug = __toESM(require_src(), 1);
25741
26268
  var import_promise_deferred = __toESM(require_dist2(), 1);
25742
26269
  var import_promise_deferred2 = __toESM(require_dist2(), 1);
25743
- import { Buffer as Buffer2 } from "node:buffer";
26270
+ import { Buffer as Buffer22 } from "node:buffer";
25744
26271
  import { spawn } from "child_process";
25745
26272
  import { normalize } from "node:path";
25746
26273
  import { EventEmitter } from "node:events";
@@ -25772,8 +26299,8 @@ function pathspec(...paths) {
25772
26299
  cache.set(key, paths);
25773
26300
  return key;
25774
26301
  }
25775
- function isPathSpec(path30) {
25776
- return path30 instanceof String && cache.has(path30);
26302
+ function isPathSpec(path33) {
26303
+ return path33 instanceof String && cache.has(path33);
25777
26304
  }
25778
26305
  function toPaths(pathSpec) {
25779
26306
  return cache.get(pathSpec) || [];
@@ -25862,8 +26389,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
25862
26389
  function forEachLineWithContent(input, callback) {
25863
26390
  return toLinesWithContent(input, true).map((line) => callback(line));
25864
26391
  }
25865
- function folderExists(path30) {
25866
- return (0, import_file_exists.exists)(path30, import_file_exists.FOLDER);
26392
+ function folderExists(path33) {
26393
+ return (0, import_file_exists.exists)(path33, import_file_exists.FOLDER);
25867
26394
  }
25868
26395
  function append(target, item) {
25869
26396
  if (Array.isArray(target)) {
@@ -25920,7 +26447,7 @@ function prefixedArray(input, prefix) {
25920
26447
  return output;
25921
26448
  }
25922
26449
  function bufferToString(input) {
25923
- return (Array.isArray(input) ? Buffer2.concat(input) : input).toString("utf-8");
26450
+ return (Array.isArray(input) ? Buffer22.concat(input) : input).toString("utf-8");
25924
26451
  }
25925
26452
  function pick(source, properties) {
25926
26453
  const out = {};
@@ -26267,8 +26794,8 @@ function checkIsRepoRootTask() {
26267
26794
  commands,
26268
26795
  format: "utf-8",
26269
26796
  onError,
26270
- parser(path30) {
26271
- return /^\.(git)?$/.test(path30.trim());
26797
+ parser(path33) {
26798
+ return /^\.(git)?$/.test(path33.trim());
26272
26799
  }
26273
26800
  };
26274
26801
  }
@@ -26702,11 +27229,11 @@ function parseGrep(grep) {
26702
27229
  const paths = /* @__PURE__ */ new Set();
26703
27230
  const results = {};
26704
27231
  forEachLineWithContent(grep, (input) => {
26705
- const [path30, line, preview] = input.split(NULL);
26706
- paths.add(path30);
26707
- (results[path30] = results[path30] || []).push({
27232
+ const [path33, line, preview] = input.split(NULL);
27233
+ paths.add(path33);
27234
+ (results[path33] = results[path33] || []).push({
26708
27235
  line: asNumber(line),
26709
- path: path30,
27236
+ path: path33,
26710
27237
  preview
26711
27238
  });
26712
27239
  });
@@ -27471,14 +27998,14 @@ var init_hash_object = __esm2({
27471
27998
  init_task();
27472
27999
  }
27473
28000
  });
27474
- function parseInit(bare, path30, text) {
28001
+ function parseInit(bare, path33, text) {
27475
28002
  const response = String(text).trim();
27476
28003
  let result;
27477
28004
  if (result = initResponseRegex.exec(response)) {
27478
- return new InitSummary(bare, path30, false, result[1]);
28005
+ return new InitSummary(bare, path33, false, result[1]);
27479
28006
  }
27480
28007
  if (result = reInitResponseRegex.exec(response)) {
27481
- return new InitSummary(bare, path30, true, result[1]);
28008
+ return new InitSummary(bare, path33, true, result[1]);
27482
28009
  }
27483
28010
  let gitDir = "";
27484
28011
  const tokens = response.split(" ");
@@ -27489,7 +28016,7 @@ function parseInit(bare, path30, text) {
27489
28016
  break;
27490
28017
  }
27491
28018
  }
27492
- return new InitSummary(bare, path30, /^re/i.test(response), gitDir);
28019
+ return new InitSummary(bare, path33, /^re/i.test(response), gitDir);
27493
28020
  }
27494
28021
  var InitSummary;
27495
28022
  var initResponseRegex;
@@ -27498,9 +28025,9 @@ var init_InitSummary = __esm2({
27498
28025
  "src/lib/responses/InitSummary.ts"() {
27499
28026
  "use strict";
27500
28027
  InitSummary = class {
27501
- constructor(bare, path30, existing, gitDir) {
28028
+ constructor(bare, path33, existing, gitDir) {
27502
28029
  this.bare = bare;
27503
- this.path = path30;
28030
+ this.path = path33;
27504
28031
  this.existing = existing;
27505
28032
  this.gitDir = gitDir;
27506
28033
  }
@@ -27512,7 +28039,7 @@ var init_InitSummary = __esm2({
27512
28039
  function hasBareCommand(command) {
27513
28040
  return command.includes(bareCommand);
27514
28041
  }
27515
- function initTask(bare = false, path30, customArgs) {
28042
+ function initTask(bare = false, path33, customArgs) {
27516
28043
  const commands = ["init", ...customArgs];
27517
28044
  if (bare && !hasBareCommand(commands)) {
27518
28045
  commands.splice(1, 0, bareCommand);
@@ -27521,7 +28048,7 @@ function initTask(bare = false, path30, customArgs) {
27521
28048
  commands,
27522
28049
  format: "utf-8",
27523
28050
  parser(text) {
27524
- return parseInit(commands.includes("--bare"), path30, text);
28051
+ return parseInit(commands.includes("--bare"), path33, text);
27525
28052
  }
27526
28053
  };
27527
28054
  }
@@ -28337,12 +28864,12 @@ var init_FileStatusSummary = __esm2({
28337
28864
  "use strict";
28338
28865
  fromPathRegex = /^(.+)\0(.+)$/;
28339
28866
  FileStatusSummary = class {
28340
- constructor(path30, index, working_dir) {
28341
- this.path = path30;
28867
+ constructor(path33, index, working_dir) {
28868
+ this.path = path33;
28342
28869
  this.index = index;
28343
28870
  this.working_dir = working_dir;
28344
28871
  if (index === "R" || working_dir === "R") {
28345
- const detail = fromPathRegex.exec(path30) || [null, path30, path30];
28872
+ const detail = fromPathRegex.exec(path33) || [null, path33, path33];
28346
28873
  this.from = detail[2] || "";
28347
28874
  this.path = detail[1] || "";
28348
28875
  }
@@ -28373,14 +28900,14 @@ function splitLine(result, lineStr) {
28373
28900
  default:
28374
28901
  return;
28375
28902
  }
28376
- function data(index, workingDir, path30) {
28903
+ function data(index, workingDir, path33) {
28377
28904
  const raw = `${index}${workingDir}`;
28378
28905
  const handler = parsers6.get(raw);
28379
28906
  if (handler) {
28380
- handler(result, path30);
28907
+ handler(result, path33);
28381
28908
  }
28382
28909
  if (raw !== "##" && raw !== "!!") {
28383
- result.files.push(new FileStatusSummary(path30, index, workingDir));
28910
+ result.files.push(new FileStatusSummary(path33, index, workingDir));
28384
28911
  }
28385
28912
  }
28386
28913
  }
@@ -28551,14 +29078,14 @@ var init_status = __esm2({
28551
29078
  ignoredOptions = ["--null", "-z"];
28552
29079
  }
28553
29080
  });
28554
- function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed = true) {
29081
+ function versionResponse(major = 0, minor = 0, patch = 0, agent = "", installed2 = true) {
28555
29082
  return Object.defineProperty(
28556
29083
  {
28557
29084
  major,
28558
29085
  minor,
28559
29086
  patch,
28560
29087
  agent,
28561
- installed
29088
+ installed: installed2
28562
29089
  },
28563
29090
  "toString",
28564
29091
  {
@@ -28689,9 +29216,9 @@ var init_simple_git_api = __esm2({
28689
29216
  next
28690
29217
  );
28691
29218
  }
28692
- hashObject(path30, write) {
29219
+ hashObject(path33, write) {
28693
29220
  return this._runTask(
28694
- hashObjectTask(path30, write === true),
29221
+ hashObjectTask(path33, write === true),
28695
29222
  trailingFunctionArgument(arguments)
28696
29223
  );
28697
29224
  }
@@ -29044,8 +29571,8 @@ var init_branch = __esm2({
29044
29571
  }
29045
29572
  });
29046
29573
  function toPath(input) {
29047
- const path30 = input.trim().replace(/^["']|["']$/g, "");
29048
- return path30 && normalize(path30);
29574
+ const path33 = input.trim().replace(/^["']|["']$/g, "");
29575
+ return path33 && normalize(path33);
29049
29576
  }
29050
29577
  var parseCheckIgnore;
29051
29578
  var init_CheckIgnore = __esm2({
@@ -29359,8 +29886,8 @@ __export2(sub_module_exports, {
29359
29886
  subModuleTask: () => subModuleTask,
29360
29887
  updateSubModuleTask: () => updateSubModuleTask
29361
29888
  });
29362
- function addSubModuleTask(repo, path30) {
29363
- return subModuleTask(["add", repo, path30]);
29889
+ function addSubModuleTask(repo, path33) {
29890
+ return subModuleTask(["add", repo, path33]);
29364
29891
  }
29365
29892
  function initSubModuleTask(customArgs) {
29366
29893
  return subModuleTask(["init", ...customArgs]);
@@ -29693,8 +30220,8 @@ var require_git = __commonJS2({
29693
30220
  }
29694
30221
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
29695
30222
  };
29696
- Git2.prototype.submoduleAdd = function(repo, path30, then) {
29697
- return this._runTask(addSubModuleTask2(repo, path30), trailingFunctionArgument2(arguments));
30223
+ Git2.prototype.submoduleAdd = function(repo, path33, then) {
30224
+ return this._runTask(addSubModuleTask2(repo, path33), trailingFunctionArgument2(arguments));
29698
30225
  };
29699
30226
  Git2.prototype.submoduleUpdate = function(args, then) {
29700
30227
  return this._runTask(
@@ -30320,20 +30847,20 @@ async function isGitRepoDirectory(dirPath) {
30320
30847
  // src/git/discover-repos.ts
30321
30848
  async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
30322
30849
  const result = [];
30323
- const cwdResolved = path3.resolve(cwd);
30850
+ const cwdResolved = path4.resolve(cwd);
30324
30851
  if (await isGitRepoDirectory(cwdResolved)) {
30325
30852
  const remoteUrl = await getRemoteOriginUrl(cwdResolved);
30326
30853
  result.push({ absolutePath: cwdResolved, remoteUrl });
30327
30854
  }
30328
30855
  let entries;
30329
30856
  try {
30330
- entries = fs2.readdirSync(cwdResolved, { withFileTypes: true });
30857
+ entries = fs7.readdirSync(cwdResolved, { withFileTypes: true });
30331
30858
  } catch {
30332
30859
  return result;
30333
30860
  }
30334
30861
  for (const ent of entries) {
30335
30862
  if (!ent.isDirectory()) continue;
30336
- const childPath = path3.join(cwdResolved, ent.name);
30863
+ const childPath = path4.join(cwdResolved, ent.name);
30337
30864
  if (await isGitRepoDirectory(childPath)) {
30338
30865
  const remoteUrl = await getRemoteOriginUrl(childPath);
30339
30866
  result.push({ absolutePath: childPath, remoteUrl });
@@ -30342,22 +30869,22 @@ async function discoverGitRepos(cwd = getBridgeWorkspaceDirectory()) {
30342
30869
  return result;
30343
30870
  }
30344
30871
  async function discoverGitReposUnderRoot(rootAbs) {
30345
- const root = path3.resolve(rootAbs);
30872
+ const root = path4.resolve(rootAbs);
30346
30873
  const roots = [];
30347
30874
  async function walk(dir) {
30348
30875
  if (await isGitRepoDirectory(dir)) {
30349
- roots.push(path3.resolve(dir));
30876
+ roots.push(path4.resolve(dir));
30350
30877
  return;
30351
30878
  }
30352
30879
  let entries;
30353
30880
  try {
30354
- entries = fs2.readdirSync(dir, { withFileTypes: true });
30881
+ entries = fs7.readdirSync(dir, { withFileTypes: true });
30355
30882
  } catch {
30356
30883
  return;
30357
30884
  }
30358
30885
  for (const ent of entries) {
30359
30886
  if (!ent.isDirectory() || ent.name === ".git") continue;
30360
- await walk(path3.join(dir, ent.name));
30887
+ await walk(path4.join(dir, ent.name));
30361
30888
  }
30362
30889
  }
30363
30890
  await walk(root);
@@ -30371,13 +30898,13 @@ async function discoverGitReposUnderRoot(rootAbs) {
30371
30898
  }
30372
30899
 
30373
30900
  // src/git/pre-turn-snapshot.ts
30374
- var execFileAsync = promisify(execFile);
30901
+ var execFileAsync5 = promisify6(execFile6);
30375
30902
  function snapshotsDirForCwd(agentCwd) {
30376
- return path4.join(agentCwd, ".buildautomaton", "snapshots");
30903
+ return path5.join(agentCwd, ".buildautomaton", "snapshots");
30377
30904
  }
30378
30905
  async function gitStashCreate(repoRoot, log2) {
30379
30906
  try {
30380
- const { stdout } = await execFileAsync("git", ["stash", "create"], {
30907
+ const { stdout } = await execFileAsync5("git", ["stash", "create"], {
30381
30908
  cwd: repoRoot,
30382
30909
  maxBuffer: 10 * 1024 * 1024
30383
30910
  });
@@ -30391,7 +30918,7 @@ async function gitStashCreate(repoRoot, log2) {
30391
30918
  }
30392
30919
  async function gitRun(repoRoot, args, log2, label) {
30393
30920
  try {
30394
- await execFileAsync("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
30921
+ await execFileAsync5("git", args, { cwd: repoRoot, maxBuffer: 10 * 1024 * 1024 });
30395
30922
  return { ok: true };
30396
30923
  } catch (e) {
30397
30924
  const msg = e instanceof Error ? e.message : String(e);
@@ -30402,7 +30929,7 @@ async function gitRun(repoRoot, args, log2, label) {
30402
30929
  async function resolveSnapshotRepoRoots(options) {
30403
30930
  const { worktreePaths, fallbackCwd, log: log2 } = options;
30404
30931
  if (worktreePaths?.length) {
30405
- const uniq = [...new Set(worktreePaths.map((p) => path4.resolve(p)))];
30932
+ const uniq = [...new Set(worktreePaths.map((p) => path5.resolve(p)))];
30406
30933
  return uniq;
30407
30934
  }
30408
30935
  try {
@@ -30425,7 +30952,7 @@ async function capturePreTurnSnapshot(options) {
30425
30952
  }
30426
30953
  const dir = snapshotsDirForCwd(agentCwd);
30427
30954
  try {
30428
- fs3.mkdirSync(dir, { recursive: true });
30955
+ fs8.mkdirSync(dir, { recursive: true });
30429
30956
  } catch (e) {
30430
30957
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
30431
30958
  }
@@ -30434,9 +30961,9 @@ async function capturePreTurnSnapshot(options) {
30434
30961
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
30435
30962
  repos
30436
30963
  };
30437
- const filePath = path4.join(dir, `${runId}.json`);
30964
+ const filePath = path5.join(dir, `${runId}.json`);
30438
30965
  try {
30439
- fs3.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
30966
+ fs8.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
30440
30967
  } catch (e) {
30441
30968
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
30442
30969
  }
@@ -30449,7 +30976,7 @@ async function capturePreTurnSnapshot(options) {
30449
30976
  async function applyPreTurnSnapshot(filePath, log2) {
30450
30977
  let data;
30451
30978
  try {
30452
- const raw = fs3.readFileSync(filePath, "utf8");
30979
+ const raw = fs8.readFileSync(filePath, "utf8");
30453
30980
  data = JSON.parse(raw);
30454
30981
  } catch (e) {
30455
30982
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
@@ -30472,11 +30999,11 @@ async function applyPreTurnSnapshot(filePath, log2) {
30472
30999
  return { ok: true };
30473
31000
  }
30474
31001
  function snapshotFilePath(agentCwd, runId) {
30475
- return path4.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
31002
+ return path5.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
30476
31003
  }
30477
31004
 
30478
31005
  // src/git/session-git-queue.ts
30479
- var execFileAsync2 = promisify2(execFile2);
31006
+ var execFileAsync6 = promisify7(execFile7);
30480
31007
  var MAX_FULL_FILE_TEXT_BYTES = 512 * 1024;
30481
31008
  async function readWorkspaceFileAsUtf8(absPath) {
30482
31009
  try {
@@ -30509,7 +31036,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
30509
31036
  if (!repo.stashSha) continue;
30510
31037
  let namesRaw;
30511
31038
  try {
30512
- const { stdout } = await execFileAsync2("git", ["diff", "--name-only", repo.stashSha], {
31039
+ const { stdout } = await execFileAsync6("git", ["diff", "--name-only", repo.stashSha], {
30513
31040
  cwd: repo.path,
30514
31041
  maxBuffer: 10 * 1024 * 1024
30515
31042
  });
@@ -30521,11 +31048,11 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
30521
31048
  continue;
30522
31049
  }
30523
31050
  const lines = namesRaw.split("\n").map((l) => l.trim()).filter(Boolean);
30524
- const slug = path5.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
31051
+ const slug = path6.basename(repo.path).replace(/[^\w.-]+/g, "_") || "repo";
30525
31052
  for (const rel of lines) {
30526
31053
  if (rel.includes("..")) continue;
30527
31054
  try {
30528
- const { stdout: patchContent } = await execFileAsync2(
31055
+ const { stdout: patchContent } = await execFileAsync6(
30529
31056
  "git",
30530
31057
  ["diff", "--no-color", repo.stashSha, "--", rel],
30531
31058
  {
@@ -30535,7 +31062,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
30535
31062
  );
30536
31063
  if (!patchContent.trim()) continue;
30537
31064
  const displayPath = multiRepo ? `${slug}/${rel}` : rel;
30538
- const absFile = path5.join(repo.path, rel);
31065
+ const absFile = path6.join(repo.path, rel);
30539
31066
  const newText = await readWorkspaceFileAsUtf8(absFile);
30540
31067
  sendSessionUpdate({
30541
31068
  type: "session_file_change",
@@ -30597,7 +31124,9 @@ async function sendPromptToAgent(options) {
30597
31124
  ...augmentAuthFields(errStr)
30598
31125
  });
30599
31126
  if (!result.success) {
30600
- log2(`[Agent] ${result.error ?? "Error"}`);
31127
+ log2(
31128
+ `[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
31129
+ );
30601
31130
  }
30602
31131
  } catch (err) {
30603
31132
  const errMsg = err instanceof Error ? err.message : String(err);
@@ -30615,8 +31144,8 @@ async function sendPromptToAgent(options) {
30615
31144
  }
30616
31145
 
30617
31146
  // src/agents/acp/ensure-acp-client.ts
30618
- import * as fs4 from "node:fs";
30619
- import * as path9 from "node:path";
31147
+ import * as fs9 from "node:fs";
31148
+ import * as path10 from "node:path";
30620
31149
 
30621
31150
  // src/error-message.ts
30622
31151
  function errorMessage(err) {
@@ -30636,16 +31165,16 @@ __export(claude_code_acp_client_exports, {
30636
31165
  createClaudeCodeAcpClient: () => createClaudeCodeAcpClient,
30637
31166
  detectLocalAgentPresence: () => detectLocalAgentPresence
30638
31167
  });
30639
- import { execFile as execFile4 } from "node:child_process";
30640
- import { promisify as promisify4 } from "node:util";
31168
+ import { execFile as execFile9 } from "node:child_process";
31169
+ import { promisify as promisify9 } from "node:util";
30641
31170
 
30642
31171
  // src/agents/acp/clients/detect-command-on-path.ts
30643
- import { execFile as execFile3 } from "node:child_process";
30644
- import { promisify as promisify3 } from "node:util";
30645
- var execFileAsync3 = promisify3(execFile3);
31172
+ import { execFile as execFile8 } from "node:child_process";
31173
+ import { promisify as promisify8 } from "node:util";
31174
+ var execFileAsync7 = promisify8(execFile8);
30646
31175
  async function isCommandOnPath(command, timeoutMs = 4e3) {
30647
31176
  try {
30648
- await execFileAsync3("which", [command], { timeout: timeoutMs });
31177
+ await execFileAsync7("which", [command], { timeout: timeoutMs });
30649
31178
  return true;
30650
31179
  } catch {
30651
31180
  return false;
@@ -30705,21 +31234,21 @@ function editSnippetToUnifiedDiff(filePath, oldText, newText) {
30705
31234
  }
30706
31235
 
30707
31236
  // src/agents/acp/safe-fs-path.ts
30708
- import * as path6 from "node:path";
31237
+ import * as path7 from "node:path";
30709
31238
  function resolveSafePathUnderCwd(cwd, filePath) {
30710
31239
  const trimmed2 = filePath.trim();
30711
31240
  if (!trimmed2) return null;
30712
- const normalizedCwd = path6.resolve(cwd);
30713
- const resolved = path6.isAbsolute(trimmed2) ? path6.normalize(trimmed2) : path6.resolve(normalizedCwd, trimmed2);
30714
- const rel = path6.relative(normalizedCwd, resolved);
30715
- if (rel.startsWith("..") || path6.isAbsolute(rel)) return null;
31241
+ const normalizedCwd = path7.resolve(cwd);
31242
+ const resolved = path7.isAbsolute(trimmed2) ? path7.normalize(trimmed2) : path7.resolve(normalizedCwd, trimmed2);
31243
+ const rel = path7.relative(normalizedCwd, resolved);
31244
+ if (rel.startsWith("..") || path7.isAbsolute(rel)) return null;
30716
31245
  return resolved;
30717
31246
  }
30718
31247
  function toDisplayPathRelativeToCwd(cwd, absolutePath) {
30719
- const normalizedCwd = path6.resolve(cwd);
30720
- const rel = path6.relative(normalizedCwd, path6.resolve(absolutePath));
30721
- if (!rel || rel === "") return path6.basename(absolutePath);
30722
- return rel.split(path6.sep).join("/");
31248
+ const normalizedCwd = path7.resolve(cwd);
31249
+ const rel = path7.relative(normalizedCwd, path7.resolve(absolutePath));
31250
+ if (!rel || rel === "") return path7.basename(absolutePath);
31251
+ return rel.split(path7.sep).join("/");
30723
31252
  }
30724
31253
 
30725
31254
  // src/agents/acp/clients/agent-stderr-capture.ts
@@ -30839,7 +31368,7 @@ async function createSdkStdioAcpClient(options) {
30839
31368
  child.once("close", (code, signal) => {
30840
31369
  onAgentSubprocessExit?.({ code, signal });
30841
31370
  });
30842
- return new Promise((resolve15, reject) => {
31371
+ return new Promise((resolve16, reject) => {
30843
31372
  let initSettled = false;
30844
31373
  const settleReject = (err) => {
30845
31374
  if (initSettled) return;
@@ -30853,7 +31382,7 @@ async function createSdkStdioAcpClient(options) {
30853
31382
  const settleResolve = (handle) => {
30854
31383
  if (initSettled) return;
30855
31384
  initSettled = true;
30856
- resolve15(handle);
31385
+ resolve16(handle);
30857
31386
  };
30858
31387
  child.on("error", (err) => {
30859
31388
  settleReject(new Error(formatSpawnError(err, command[0])));
@@ -30889,8 +31418,8 @@ async function createSdkStdioAcpClient(options) {
30889
31418
  });
30890
31419
  } catch {
30891
31420
  }
30892
- return await new Promise((resolve16) => {
30893
- pendingPermissionResolvers.set(requestId, resolve16);
31421
+ return await new Promise((resolve17) => {
31422
+ pendingPermissionResolvers.set(requestId, resolve17);
30894
31423
  });
30895
31424
  },
30896
31425
  async readTextFile(params) {
@@ -30998,9 +31527,9 @@ async function createSdkStdioAcpClient(options) {
30998
31527
  }
30999
31528
  },
31000
31529
  async cancel() {
31001
- for (const [id, resolve16] of [...pendingPermissionResolvers.entries()]) {
31530
+ for (const [id, resolve17] of [...pendingPermissionResolvers.entries()]) {
31002
31531
  pendingPermissionResolvers.delete(id);
31003
- resolve16({ outcome: { outcome: "cancelled" } });
31532
+ resolve17({ outcome: { outcome: "cancelled" } });
31004
31533
  }
31005
31534
  try {
31006
31535
  await connection.cancel({ sessionId });
@@ -31016,10 +31545,10 @@ async function createSdkStdioAcpClient(options) {
31016
31545
  }
31017
31546
  },
31018
31547
  resolveRequest(requestId, result) {
31019
- const resolve16 = pendingPermissionResolvers.get(requestId);
31020
- if (!resolve16) return;
31548
+ const resolve17 = pendingPermissionResolvers.get(requestId);
31549
+ if (!resolve17) return;
31021
31550
  pendingPermissionResolvers.delete(requestId);
31022
- resolve16(result);
31551
+ resolve17(result);
31023
31552
  },
31024
31553
  disconnect() {
31025
31554
  child.kill();
@@ -31040,12 +31569,12 @@ async function createSdkStdioAcpClient(options) {
31040
31569
  }
31041
31570
 
31042
31571
  // src/agents/acp/clients/claude-code-acp-client.ts
31043
- var execFileAsync4 = promisify4(execFile4);
31572
+ var execFileAsync8 = promisify9(execFile9);
31044
31573
  var BACKEND_LOCAL_AGENT_TYPE = "claude-code";
31045
31574
  async function detectLocalAgentPresence() {
31046
31575
  if (await isCommandOnPath("claude")) return true;
31047
31576
  try {
31048
- await execFileAsync4("npx", ["--yes", "@anthropic-ai/claude-code", "--version"], { timeout: 25e3 });
31577
+ await execFileAsync8("npx", ["--yes", "@anthropic-ai/claude-code", "--version"], { timeout: 25e3 });
31049
31578
  return true;
31050
31579
  } catch {
31051
31580
  return false;
@@ -31170,7 +31699,7 @@ async function createCursorAcpClient(options) {
31170
31699
  });
31171
31700
  const stderrCapture = createStderrCapture(child);
31172
31701
  child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
31173
- return new Promise((resolve15, reject) => {
31702
+ return new Promise((resolve16, reject) => {
31174
31703
  child.on("error", (err) => {
31175
31704
  child.kill();
31176
31705
  reject(new Error(formatSpawnError2(err, command[0])));
@@ -31357,7 +31886,7 @@ async function createCursorAcpClient(options) {
31357
31886
  const newResult = await send("session/new", { cwd, mcpServers: [] });
31358
31887
  const sessionId = newResult?.sessionId ?? "";
31359
31888
  if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
31360
- resolve15({
31889
+ resolve16({
31361
31890
  sessionId,
31362
31891
  async sendPrompt(prompt, _options) {
31363
31892
  promptOutputBuffer = "";
@@ -31543,48 +32072,48 @@ function resolveAgentCommand(preferredAgentType) {
31543
32072
  }
31544
32073
 
31545
32074
  // src/agents/acp/session-file-change-path-kind.ts
31546
- import { execFileSync as execFileSync3 } from "node:child_process";
32075
+ import { execFileSync as execFileSync4 } from "node:child_process";
31547
32076
  import { existsSync, statSync } from "node:fs";
31548
32077
 
31549
32078
  // src/git/get-git-repo-root-sync.ts
31550
- import { execFileSync } from "node:child_process";
31551
- import * as path7 from "node:path";
32079
+ import { execFileSync as execFileSync2 } from "node:child_process";
32080
+ import * as path8 from "node:path";
31552
32081
  function getGitRepoRootSync(startDir) {
31553
32082
  try {
31554
- const out = execFileSync("git", ["rev-parse", "--show-toplevel"], {
31555
- cwd: path7.resolve(startDir),
32083
+ const out = execFileSync2("git", ["rev-parse", "--show-toplevel"], {
32084
+ cwd: path8.resolve(startDir),
31556
32085
  encoding: "utf8",
31557
32086
  stdio: ["ignore", "pipe", "ignore"],
31558
32087
  maxBuffer: 1024 * 1024
31559
32088
  }).trim();
31560
- return out ? path7.resolve(out) : null;
32089
+ return out ? path8.resolve(out) : null;
31561
32090
  } catch {
31562
32091
  return null;
31563
32092
  }
31564
32093
  }
31565
32094
 
31566
32095
  // src/agents/acp/workspace-files.ts
31567
- import { execFileSync as execFileSync2 } from "node:child_process";
32096
+ import { execFileSync as execFileSync3 } from "node:child_process";
31568
32097
  import { readFileSync as readFileSync4 } from "node:fs";
31569
- import * as path8 from "node:path";
32098
+ import * as path9 from "node:path";
31570
32099
  function resolveWorkspaceFilePath(cwd, rawPath) {
31571
32100
  const trimmed2 = rawPath.trim();
31572
32101
  if (!trimmed2) return null;
31573
- const normalizedCwd = path8.resolve(cwd);
32102
+ const normalizedCwd = path9.resolve(cwd);
31574
32103
  let abs = resolveSafePathUnderCwd(cwd, trimmed2);
31575
32104
  if (!abs) {
31576
- const candidate = path8.isAbsolute(trimmed2) ? path8.normalize(trimmed2) : path8.normalize(path8.resolve(normalizedCwd, trimmed2));
32105
+ const candidate = path9.isAbsolute(trimmed2) ? path9.normalize(trimmed2) : path9.normalize(path9.resolve(normalizedCwd, trimmed2));
31577
32106
  const gitRoot2 = getGitRepoRootSync(cwd);
31578
32107
  if (!gitRoot2) return null;
31579
- const rel = path8.relative(gitRoot2, candidate);
31580
- if (rel.startsWith("..") || path8.isAbsolute(rel)) return null;
32108
+ const rel = path9.relative(gitRoot2, candidate);
32109
+ if (rel.startsWith("..") || path9.isAbsolute(rel)) return null;
31581
32110
  abs = candidate;
31582
32111
  }
31583
32112
  const gitRoot = getGitRepoRootSync(cwd);
31584
32113
  if (gitRoot) {
31585
- const relFromRoot = path8.relative(gitRoot, abs);
31586
- if (!relFromRoot.startsWith("..") && !path8.isAbsolute(relFromRoot)) {
31587
- return { abs, display: relFromRoot.split(path8.sep).join("/") };
32114
+ const relFromRoot = path9.relative(gitRoot, abs);
32115
+ if (!relFromRoot.startsWith("..") && !path9.isAbsolute(relFromRoot)) {
32116
+ return { abs, display: relFromRoot.split(path9.sep).join("/") };
31588
32117
  }
31589
32118
  }
31590
32119
  return { abs, display: toDisplayPathRelativeToCwd(cwd, abs) };
@@ -31593,9 +32122,9 @@ function readUtf8WorkspaceFile(cwd, displayPath) {
31593
32122
  if (!displayPath || displayPath.includes("..")) return "";
31594
32123
  const gitRoot = getGitRepoRootSync(cwd);
31595
32124
  if (gitRoot) {
31596
- const abs2 = path8.resolve(gitRoot, displayPath);
31597
- const rel = path8.relative(gitRoot, abs2);
31598
- if (!rel.startsWith("..") && !path8.isAbsolute(rel)) {
32125
+ const abs2 = path9.resolve(gitRoot, displayPath);
32126
+ const rel = path9.relative(gitRoot, abs2);
32127
+ if (!rel.startsWith("..") && !path9.isAbsolute(rel)) {
31599
32128
  try {
31600
32129
  return readFileSync4(abs2, "utf8");
31601
32130
  } catch {
@@ -31614,9 +32143,9 @@ function tryWorkspaceDisplayToAbs(cwd, displayPath) {
31614
32143
  if (!displayPath || displayPath.includes("..")) return null;
31615
32144
  const gitRoot = getGitRepoRootSync(cwd);
31616
32145
  if (gitRoot) {
31617
- const abs = path8.resolve(gitRoot, displayPath);
31618
- const rel = path8.relative(gitRoot, abs);
31619
- if (!rel.startsWith("..") && !path8.isAbsolute(rel)) return abs;
32146
+ const abs = path9.resolve(gitRoot, displayPath);
32147
+ const rel = path9.relative(gitRoot, abs);
32148
+ if (!rel.startsWith("..") && !path9.isAbsolute(rel)) return abs;
31620
32149
  }
31621
32150
  return resolveSafePathUnderCwd(cwd, displayPath);
31622
32151
  }
@@ -31625,7 +32154,7 @@ function readGitHeadBlob(cwd, displayPath) {
31625
32154
  const gitRoot = getGitRepoRootSync(cwd);
31626
32155
  const execCwd = gitRoot ?? cwd;
31627
32156
  try {
31628
- return execFileSync2("git", ["show", `HEAD:${displayPath}`], {
32157
+ return execFileSync3("git", ["show", `HEAD:${displayPath}`], {
31629
32158
  cwd: execCwd,
31630
32159
  encoding: "utf8",
31631
32160
  maxBuffer: 50 * 1024 * 1024
@@ -31641,7 +32170,7 @@ function gitHeadPathObjectType(cwd, displayPath) {
31641
32170
  const gitRoot = getGitRepoRootSync(cwd);
31642
32171
  if (!gitRoot) return null;
31643
32172
  try {
31644
- return execFileSync3("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
32173
+ return execFileSync4("git", ["cat-file", "-t", `HEAD:${displayPath}`], {
31645
32174
  cwd: gitRoot,
31646
32175
  encoding: "utf8"
31647
32176
  }).trim();
@@ -31732,7 +32261,7 @@ function createBridgeOnRequest(opts) {
31732
32261
  }
31733
32262
 
31734
32263
  // src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
31735
- import { fileURLToPath } from "node:url";
32264
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
31736
32265
  function readOptionalTextField(v) {
31737
32266
  if (v === null || v === void 0) return "";
31738
32267
  if (typeof v === "string") return v;
@@ -31742,7 +32271,7 @@ function normalizePathField(raw) {
31742
32271
  const t = raw.trim();
31743
32272
  if (t.startsWith("file://")) {
31744
32273
  try {
31745
- return fileURLToPath(t);
32274
+ return fileURLToPath2(t);
31746
32275
  } catch {
31747
32276
  return t;
31748
32277
  }
@@ -32184,10 +32713,10 @@ function buildAcpSessionBridgeHooks(opts) {
32184
32713
  // src/agents/acp/ensure-acp-client.ts
32185
32714
  async function ensureAcpClient(options) {
32186
32715
  const { state, preferredAgentType, mode, cwd, routing, sendSessionUpdate, sendRequest, log: log2 } = options;
32187
- const targetCwd = path9.resolve(
32716
+ const targetCwd = path10.resolve(
32188
32717
  cwd != null && String(cwd).trim() !== "" ? String(cwd).trim() : getBridgeWorkspaceDirectory()
32189
32718
  );
32190
- if (state.acpHandle && state.lastAcpCwd != null && path9.resolve(state.lastAcpCwd) !== path9.resolve(targetCwd)) {
32719
+ if (state.acpHandle && state.lastAcpCwd != null && path10.resolve(state.lastAcpCwd) !== path10.resolve(targetCwd)) {
32191
32720
  try {
32192
32721
  state.acpHandle.disconnect();
32193
32722
  } catch {
@@ -32219,7 +32748,7 @@ async function ensureAcpClient(options) {
32219
32748
  if (!state.acpStartPromise) {
32220
32749
  let statOk = false;
32221
32750
  try {
32222
- const st = fs4.statSync(targetCwd);
32751
+ const st = fs9.statSync(targetCwd);
32223
32752
  statOk = st.isDirectory();
32224
32753
  if (!statOk) {
32225
32754
  state.lastAcpStartError = `Agent cwd is not a directory: ${targetCwd}`;
@@ -32415,12 +32944,12 @@ async function createAcpManager(options) {
32415
32944
  }
32416
32945
 
32417
32946
  // src/worktrees/session-worktree-manager.ts
32418
- import * as path13 from "node:path";
32419
- import os3 from "node:os";
32947
+ import * as path16 from "node:path";
32948
+ import os4 from "node:os";
32420
32949
 
32421
32950
  // src/worktrees/prepare-new-session-worktrees.ts
32422
- import * as fs6 from "node:fs";
32423
- import * as path11 from "node:path";
32951
+ import * as fs11 from "node:fs";
32952
+ import * as path12 from "node:path";
32424
32953
 
32425
32954
  // src/git/worktree-add.ts
32426
32955
  async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
@@ -32429,12 +32958,12 @@ async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch) {
32429
32958
  }
32430
32959
 
32431
32960
  // src/worktrees/worktree-layout-file.ts
32432
- import * as fs5 from "node:fs";
32433
- import * as path10 from "node:path";
32434
- import os2 from "node:os";
32961
+ import * as fs10 from "node:fs";
32962
+ import * as path11 from "node:path";
32963
+ import os3 from "node:os";
32435
32964
  var LAYOUT_FILENAME = "worktree-launcher-layout.json";
32436
32965
  function defaultWorktreeLayoutPath() {
32437
- return path10.join(os2.homedir(), ".buildautomaton", LAYOUT_FILENAME);
32966
+ return path11.join(os3.homedir(), ".buildautomaton", LAYOUT_FILENAME);
32438
32967
  }
32439
32968
  function normalizeLoadedLayout(raw) {
32440
32969
  if (raw && typeof raw === "object" && "launcherCwds" in raw) {
@@ -32446,8 +32975,8 @@ function normalizeLoadedLayout(raw) {
32446
32975
  function loadWorktreeLayout() {
32447
32976
  try {
32448
32977
  const p = defaultWorktreeLayoutPath();
32449
- if (!fs5.existsSync(p)) return { launcherCwds: [] };
32450
- const raw = JSON.parse(fs5.readFileSync(p, "utf8"));
32978
+ if (!fs10.existsSync(p)) return { launcherCwds: [] };
32979
+ const raw = JSON.parse(fs10.readFileSync(p, "utf8"));
32451
32980
  return normalizeLoadedLayout(raw);
32452
32981
  } catch {
32453
32982
  return { launcherCwds: [] };
@@ -32455,18 +32984,18 @@ function loadWorktreeLayout() {
32455
32984
  }
32456
32985
  function saveWorktreeLayout(layout) {
32457
32986
  try {
32458
- const dir = path10.dirname(defaultWorktreeLayoutPath());
32459
- fs5.mkdirSync(dir, { recursive: true });
32460
- fs5.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
32987
+ const dir = path11.dirname(defaultWorktreeLayoutPath());
32988
+ fs10.mkdirSync(dir, { recursive: true });
32989
+ fs10.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
32461
32990
  } catch {
32462
32991
  }
32463
32992
  }
32464
32993
  function baseNameSafe(abs) {
32465
- return path10.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
32994
+ return path11.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
32466
32995
  }
32467
32996
  function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
32468
- const norm = path10.resolve(launcherCwdAbs);
32469
- const existing = layout.launcherCwds.find((e) => path10.resolve(e.absolutePath) === norm);
32997
+ const norm = path11.resolve(launcherCwdAbs);
32998
+ const existing = layout.launcherCwds.find((e) => path11.resolve(e.absolutePath) === norm);
32470
32999
  if (existing) return existing.dirName;
32471
33000
  const base = baseNameSafe(norm);
32472
33001
  const used = new Set(layout.launcherCwds.map((e) => e.dirName));
@@ -32484,9 +33013,9 @@ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
32484
33013
  // src/worktrees/prepare-new-session-worktrees.ts
32485
33014
  async function prepareNewSessionWorktrees(options) {
32486
33015
  const { rootAbs, launcherCwd, sessionId, layout, log: log2 } = options;
32487
- const launcherResolved = path11.resolve(launcherCwd);
33016
+ const launcherResolved = path12.resolve(launcherCwd);
32488
33017
  const cwdKey = allocateDirNameForLauncherCwd(layout, launcherResolved);
32489
- const agentMirrorRoot = path11.join(rootAbs, cwdKey);
33018
+ const agentMirrorRoot = path12.join(rootAbs, cwdKey);
32490
33019
  const repos = await discoverGitReposUnderRoot(launcherResolved);
32491
33020
  if (repos.length === 0) {
32492
33021
  log2("[worktrees] No Git repositories under launcher working directory; skipping worktree creation.");
@@ -32494,13 +33023,13 @@ async function prepareNewSessionWorktrees(options) {
32494
33023
  }
32495
33024
  const branch = `session-${sessionId}`;
32496
33025
  const worktreePaths = [];
32497
- fs6.mkdirSync(agentMirrorRoot, { recursive: true });
33026
+ fs11.mkdirSync(agentMirrorRoot, { recursive: true });
32498
33027
  for (const repo of repos) {
32499
- let rel = path11.relative(launcherResolved, repo.absolutePath);
32500
- if (rel.startsWith("..") || path11.isAbsolute(rel)) continue;
33028
+ let rel = path12.relative(launcherResolved, repo.absolutePath);
33029
+ if (rel.startsWith("..") || path12.isAbsolute(rel)) continue;
32501
33030
  const relNorm = rel === "" ? "." : rel;
32502
- const wtPath = path11.join(agentMirrorRoot, relNorm, sessionId);
32503
- fs6.mkdirSync(path11.dirname(wtPath), { recursive: true });
33031
+ const wtPath = path12.join(agentMirrorRoot, relNorm, sessionId);
33032
+ fs11.mkdirSync(path12.dirname(wtPath), { recursive: true });
32504
33033
  try {
32505
33034
  await gitWorktreeAddBranch(repo.absolutePath, wtPath, branch);
32506
33035
  log2(`[worktrees] Added worktree ${wtPath} (branch ${branch}).`);
@@ -32537,23 +33066,23 @@ async function renameSessionWorktreeBranches(paths, newBranch, log2) {
32537
33066
  }
32538
33067
 
32539
33068
  // src/worktrees/remove-session-worktrees.ts
32540
- import * as fs9 from "node:fs";
33069
+ import * as fs14 from "node:fs";
32541
33070
 
32542
33071
  // src/git/worktree-remove.ts
32543
- import * as fs8 from "node:fs";
33072
+ import * as fs13 from "node:fs";
32544
33073
 
32545
33074
  // src/git/resolve-main-repo-from-git-file.ts
32546
- import * as fs7 from "node:fs";
32547
- import * as path12 from "node:path";
33075
+ import * as fs12 from "node:fs";
33076
+ import * as path13 from "node:path";
32548
33077
  function resolveMainRepoFromWorktreeGitFile(wt) {
32549
- const gitDirFile = path12.join(wt, ".git");
32550
- if (!fs7.existsSync(gitDirFile) || !fs7.statSync(gitDirFile).isFile()) return "";
32551
- const first2 = fs7.readFileSync(gitDirFile, "utf8").trim();
33078
+ const gitDirFile = path13.join(wt, ".git");
33079
+ if (!fs12.existsSync(gitDirFile) || !fs12.statSync(gitDirFile).isFile()) return "";
33080
+ const first2 = fs12.readFileSync(gitDirFile, "utf8").trim();
32552
33081
  const m = first2.match(/^gitdir:\s*(.+)$/im);
32553
33082
  if (!m) return "";
32554
- const gitWorktreePath = path12.resolve(wt, m[1].trim());
32555
- const gitDir = path12.dirname(path12.dirname(gitWorktreePath));
32556
- return path12.dirname(gitDir);
33083
+ const gitWorktreePath = path13.resolve(wt, m[1].trim());
33084
+ const gitDir = path13.dirname(path13.dirname(gitWorktreePath));
33085
+ return path13.dirname(gitDir);
32557
33086
  }
32558
33087
 
32559
33088
  // src/git/worktree-remove.ts
@@ -32562,7 +33091,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
32562
33091
  if (mainRepo) {
32563
33092
  await simpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
32564
33093
  } else {
32565
- fs8.rmSync(worktreePath, { recursive: true, force: true });
33094
+ fs13.rmSync(worktreePath, { recursive: true, force: true });
32566
33095
  }
32567
33096
  }
32568
33097
 
@@ -32575,14 +33104,14 @@ async function removeSessionWorktrees(paths, log2) {
32575
33104
  } catch (e) {
32576
33105
  log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
32577
33106
  try {
32578
- fs9.rmSync(wt, { recursive: true, force: true });
33107
+ fs14.rmSync(wt, { recursive: true, force: true });
32579
33108
  } catch {
32580
33109
  }
32581
33110
  }
32582
33111
  }
32583
33112
  }
32584
33113
 
32585
- // src/git/working-tree-status.ts
33114
+ // src/git/working-directory/status/working-tree-status.ts
32586
33115
  async function tryConfigGet(g, key) {
32587
33116
  try {
32588
33117
  const out = await g.raw(["config", "--get", key]);
@@ -32592,11 +33121,24 @@ async function tryConfigGet(g, key) {
32592
33121
  return null;
32593
33122
  }
32594
33123
  }
33124
+ async function revParseSafe(g, ref) {
33125
+ try {
33126
+ const v = (await g.raw(["rev-parse", ref])).trim();
33127
+ return v || null;
33128
+ } catch {
33129
+ return null;
33130
+ }
33131
+ }
32595
33132
  async function resolveRemoteTrackingRefForAhead(g) {
32596
33133
  try {
32597
- await g.raw(["rev-parse", "--verify", "@{u}"]);
32598
- return "@{u}";
33134
+ await g.raw(["rev-parse", "--verify", "HEAD@{upstream}"]);
33135
+ return "HEAD@{upstream}";
32599
33136
  } catch {
33137
+ try {
33138
+ await g.raw(["rev-parse", "--verify", "@{u}"]);
33139
+ return "@{u}";
33140
+ } catch {
33141
+ }
32600
33142
  }
32601
33143
  const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
32602
33144
  if (!branch || branch === "HEAD") return null;
@@ -32619,16 +33161,76 @@ async function resolveRemoteTrackingRefForAhead(g) {
32619
33161
  return null;
32620
33162
  }
32621
33163
  }
33164
+ async function remoteForCurrentBranch(g) {
33165
+ const branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim();
33166
+ if (!branch || branch === "HEAD") return "origin";
33167
+ return await tryConfigGet(g, `branch.${branch}.remote`) ?? "origin";
33168
+ }
33169
+ async function resolveDefaultRemoteBranchRef(g, remote) {
33170
+ const headSym = `refs/remotes/${remote}/HEAD`;
33171
+ try {
33172
+ const resolved = (await g.raw(["symbolic-ref", "-q", "--verify", headSym])).trim();
33173
+ if (resolved.startsWith("refs/remotes/")) return resolved;
33174
+ } catch {
33175
+ }
33176
+ for (const name of ["main", "master", "trunk", "develop"]) {
33177
+ const r = `refs/remotes/${remote}/${name}`;
33178
+ try {
33179
+ await g.raw(["rev-parse", "--verify", r]);
33180
+ return r;
33181
+ } catch {
33182
+ }
33183
+ }
33184
+ return null;
33185
+ }
33186
+ async function resolveBaseShaForUnpushedCommits(g) {
33187
+ const trackingRef = await resolveRemoteTrackingRefForAhead(g);
33188
+ if (trackingRef) {
33189
+ const sha = await revParseSafe(g, trackingRef);
33190
+ if (sha) return sha;
33191
+ }
33192
+ const remote = await remoteForCurrentBranch(g);
33193
+ const defaultRef = await resolveDefaultRemoteBranchRef(g, remote);
33194
+ if (!defaultRef) return null;
33195
+ return revParseSafe(g, defaultRef);
33196
+ }
33197
+ function parseLogShaDateSubjectLines(raw) {
33198
+ const out = [];
33199
+ for (const line of String(raw).split("\n")) {
33200
+ const l = line.trimEnd();
33201
+ if (!l.trim()) continue;
33202
+ const parts = l.split(" ");
33203
+ if (parts.length < 3) continue;
33204
+ const sha = parts[0].trim();
33205
+ const committedAt = parts[1].trim();
33206
+ const subject = parts.slice(2).join(" ").trim();
33207
+ if (!/^[0-9a-f]{7,40}$/i.test(sha)) continue;
33208
+ out.push({ sha, shortSha: sha.slice(0, 7), subject, committedAt });
33209
+ }
33210
+ return out;
33211
+ }
33212
+ async function gitLogNotReachableFromBase(g, baseSha, headSha) {
33213
+ if (baseSha === headSha) return [];
33214
+ try {
33215
+ const logOut = await g.raw(["log", "--format=%H %cI %s", `${baseSha}..${headSha}`]);
33216
+ return parseLogShaDateSubjectLines(logOut);
33217
+ } catch {
33218
+ return [];
33219
+ }
33220
+ }
32622
33221
  async function commitsAheadOfRemoteTracking(repoDir) {
32623
33222
  const g = simpleGit(repoDir);
32624
- const trackingRef = await resolveRemoteTrackingRefForAhead(g);
32625
- if (!trackingRef) return 0;
32626
- const localSha = (await g.raw(["rev-parse", "HEAD"])).trim();
32627
- const remoteSha = (await g.raw(["rev-parse", trackingRef])).trim();
32628
- if (localSha === remoteSha) return 0;
32629
- const out = await g.raw(["rev-list", "--count", `${trackingRef}..HEAD`]);
32630
- const n = parseInt(String(out).trim(), 10);
32631
- return Number.isNaN(n) ? 0 : n;
33223
+ const headSha = await revParseSafe(g, "HEAD");
33224
+ if (!headSha) return 0;
33225
+ const baseSha = await resolveBaseShaForUnpushedCommits(g);
33226
+ if (!baseSha || baseSha === headSha) return 0;
33227
+ try {
33228
+ const out = await g.raw(["rev-list", "--count", `${baseSha}..${headSha}`]);
33229
+ const n = parseInt(String(out).trim(), 10);
33230
+ return Number.isNaN(n) ? 0 : n;
33231
+ } catch {
33232
+ return 0;
33233
+ }
32632
33234
  }
32633
33235
  async function getRepoWorkingTreeStatus(repoDir) {
32634
33236
  const g = simpleGit(repoDir);
@@ -32637,6 +33239,14 @@ async function getRepoWorkingTreeStatus(repoDir) {
32637
33239
  const ahead = await commitsAheadOfRemoteTracking(repoDir);
32638
33240
  return { hasUncommittedChanges, hasUnpushedCommits: ahead > 0 };
32639
33241
  }
33242
+ async function listUnpushedCommits(repoDir) {
33243
+ const g = simpleGit(repoDir);
33244
+ const headSha = await revParseSafe(g, "HEAD");
33245
+ if (!headSha) return [];
33246
+ const baseSha = await resolveBaseShaForUnpushedCommits(g);
33247
+ if (!baseSha) return [];
33248
+ return gitLogNotReachableFromBase(g, baseSha, headSha);
33249
+ }
32640
33250
  async function aggregateSessionPathsWorkingTreeStatus(paths) {
32641
33251
  let hasUncommittedChanges = false;
32642
33252
  let hasUnpushedCommits = false;
@@ -32656,6 +33266,477 @@ async function pushAheadOfUpstreamForPaths(paths) {
32656
33266
  }
32657
33267
  }
32658
33268
 
33269
+ // src/git/working-directory/changes/types.ts
33270
+ var MAX_PATCH_CHARS = 35e4;
33271
+
33272
+ // src/git/working-directory/changes/repo-format.ts
33273
+ function posixJoinDirFile(dir, file2) {
33274
+ const d = dir === "." || dir === "" ? "" : dir.replace(/\\/g, "/").replace(/\/+$/, "");
33275
+ const f = file2.replace(/\\/g, "/").replace(/^\/+/, "");
33276
+ return d ? `${d}/${f}` : f;
33277
+ }
33278
+ function formatRepoShortTitle(remoteUrl, repoRelPath) {
33279
+ const u = remoteUrl.trim();
33280
+ if (u) {
33281
+ try {
33282
+ if (u.startsWith("git@")) {
33283
+ const colon = u.indexOf(":");
33284
+ if (colon > 0) {
33285
+ const pathPart = u.slice(colon + 1).replace(/\.git$/i, "").replace(/\/+$/, "");
33286
+ if (pathPart.includes("/")) return pathPart;
33287
+ }
33288
+ } else {
33289
+ const parsed = new URL(u);
33290
+ const p = parsed.pathname.replace(/^\//, "").replace(/\.git$/i, "");
33291
+ const parts = p.split("/").filter(Boolean);
33292
+ if (parts.length >= 2) {
33293
+ return `${parts[parts.length - 2]}/${parts[parts.length - 1]}`;
33294
+ }
33295
+ if (parts.length === 1) return parts[0];
33296
+ }
33297
+ } catch {
33298
+ }
33299
+ }
33300
+ if (repoRelPath && repoRelPath !== ".") {
33301
+ const segments = repoRelPath.split("/").filter(Boolean);
33302
+ const last2 = segments[segments.length - 1];
33303
+ if (last2) return last2;
33304
+ }
33305
+ return "Repository";
33306
+ }
33307
+ function formatRemoteDisplayLabel(remoteUrl) {
33308
+ const u = remoteUrl.trim();
33309
+ if (!u) return "";
33310
+ let hostPath = u;
33311
+ try {
33312
+ if (u.startsWith("git@")) {
33313
+ const rest = u.slice("git@".length);
33314
+ const slash = rest.indexOf(":");
33315
+ if (slash > 0) hostPath = `${rest.slice(0, slash)}/${rest.slice(slash + 1)}`;
33316
+ } else {
33317
+ const parsed = new URL(u);
33318
+ hostPath = `${parsed.hostname}${parsed.pathname}`.replace(/\/\.git$/i, "").replace(/\.git$/i, "");
33319
+ }
33320
+ } catch {
33321
+ hostPath = u.replace(/^https?:\/\//i, "").replace(/\.git$/i, "");
33322
+ }
33323
+ return `origin \xB7 ${hostPath}`;
33324
+ }
33325
+
33326
+ // src/git/working-directory/changes/get-working-tree-change-repo-details.ts
33327
+ import * as path15 from "node:path";
33328
+
33329
+ // src/git/working-directory/changes/parse-git-status.ts
33330
+ function parseNameStatusLines(lines) {
33331
+ const m = /* @__PURE__ */ new Map();
33332
+ for (const line of lines) {
33333
+ if (!line.trim()) continue;
33334
+ const tabParts = line.split(" ");
33335
+ if (tabParts.length < 2) continue;
33336
+ const status = tabParts[0].trim();
33337
+ const code = status[0];
33338
+ if (code === "A") {
33339
+ m.set(tabParts[tabParts.length - 1], "added");
33340
+ } else if (code === "D") {
33341
+ m.set(tabParts[tabParts.length - 1], "removed");
33342
+ } else if (code === "R" || code === "C") {
33343
+ if (tabParts.length >= 3) m.set(tabParts[tabParts.length - 1], "modified");
33344
+ } else if (code === "M" || code === "U" || code === "T") {
33345
+ m.set(tabParts[tabParts.length - 1], "modified");
33346
+ }
33347
+ }
33348
+ return m;
33349
+ }
33350
+ function parseNumstatFirstLine(line) {
33351
+ const parts = line.split(" ");
33352
+ if (parts.length < 3) return null;
33353
+ const [a, d] = parts;
33354
+ const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
33355
+ const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
33356
+ return { additions, deletions };
33357
+ }
33358
+ function parseNumstat(lines) {
33359
+ const m = /* @__PURE__ */ new Map();
33360
+ for (const line of lines) {
33361
+ if (!line.trim()) continue;
33362
+ const parts = line.split(" ");
33363
+ if (parts.length < 3) continue;
33364
+ const [a, d, p] = parts;
33365
+ const additions = a === "-" ? 0 : parseInt(String(a), 10) || 0;
33366
+ const deletions = d === "-" ? 0 : parseInt(String(d), 10) || 0;
33367
+ m.set(p, { additions, deletions });
33368
+ }
33369
+ return m;
33370
+ }
33371
+ async function numstatFromGitNoIndex(g, pathInRepo) {
33372
+ const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
33373
+ try {
33374
+ const out = await g.raw(["diff", "--numstat", "--no-index", "--", devNull, pathInRepo]);
33375
+ const first2 = String(out).split("\n").find((l) => l.trim()) ?? "";
33376
+ return parseNumstatFirstLine(first2);
33377
+ } catch {
33378
+ return null;
33379
+ }
33380
+ }
33381
+
33382
+ // src/git/working-directory/changes/patch-truncate.ts
33383
+ function truncatePatch(s) {
33384
+ if (s.length <= MAX_PATCH_CHARS) return s;
33385
+ return `${s.slice(0, MAX_PATCH_CHARS)}
33386
+
33387
+ \u2026 (diff truncated)`;
33388
+ }
33389
+
33390
+ // src/git/working-directory/changes/list-changed-files-for-commit.ts
33391
+ var EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
33392
+ async function parentForCommitDiff(g, sha) {
33393
+ try {
33394
+ return (await g.raw(["rev-parse", `${sha}^1`])).trim();
33395
+ } catch {
33396
+ try {
33397
+ return (await g.raw(["rev-parse", `${sha}^`])).trim();
33398
+ } catch {
33399
+ return EMPTY_TREE;
33400
+ }
33401
+ }
33402
+ }
33403
+ async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha) {
33404
+ const g = simpleGit(repoGitCwd);
33405
+ const parent = await parentForCommitDiff(g, commitSha);
33406
+ const range = `${parent}..${commitSha}`;
33407
+ const [nameStatusRaw, numstatRaw] = await Promise.all([
33408
+ g.raw(["diff", "--name-status", range]).catch(() => ""),
33409
+ g.raw(["diff", "--numstat", range]).catch(() => "")
33410
+ ]);
33411
+ const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
33412
+ const numByPath = parseNumstat(String(numstatRaw).split("\n"));
33413
+ const paths = new Set([...kindByPath.keys(), ...numByPath.keys()].filter(Boolean));
33414
+ const rows = [];
33415
+ const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
33416
+ for (const pathInRepo of paths) {
33417
+ const relLauncher = posixJoinDirFile(normRel, pathInRepo.replace(/\\/g, "/"));
33418
+ const nums = numByPath.get(pathInRepo);
33419
+ let additions = nums?.additions ?? 0;
33420
+ let deletions = nums?.deletions ?? 0;
33421
+ let change = kindByPath.get(pathInRepo) ?? "modified";
33422
+ if (!kindByPath.has(pathInRepo) && nums) {
33423
+ if (additions > 0 && deletions === 0) change = "added";
33424
+ else if (deletions > 0 && additions === 0) change = "removed";
33425
+ else change = "modified";
33426
+ }
33427
+ rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
33428
+ }
33429
+ for (const row of rows) {
33430
+ let pathInRepo;
33431
+ if (normRel === ".") {
33432
+ pathInRepo = row.pathRelLauncher;
33433
+ } else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
33434
+ pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
33435
+ } else {
33436
+ pathInRepo = row.pathRelLauncher;
33437
+ }
33438
+ const raw = await g.raw(["diff", "-U20000", range, "--", pathInRepo]).catch(() => "");
33439
+ const t = String(raw).trim();
33440
+ row.patchContent = t ? truncatePatch(t) : void 0;
33441
+ }
33442
+ rows.sort((a, b) => a.pathRelLauncher.localeCompare(b.pathRelLauncher));
33443
+ return rows;
33444
+ }
33445
+
33446
+ // src/git/working-directory/changes/list-changed-files-for-repo.ts
33447
+ import * as fs16 from "node:fs";
33448
+ import * as path14 from "node:path";
33449
+
33450
+ // src/git/working-directory/changes/count-lines.ts
33451
+ import { createReadStream } from "node:fs";
33452
+ import * as readline2 from "node:readline";
33453
+ async function countTextFileLines(absFile) {
33454
+ let bytes = 0;
33455
+ const maxBytes = 512e3;
33456
+ let lines = 0;
33457
+ const stream = createReadStream(absFile, { encoding: "utf8" });
33458
+ const rl = readline2.createInterface({ input: stream, crlfDelay: Infinity });
33459
+ for await (const _line of rl) {
33460
+ lines += 1;
33461
+ bytes += Buffer.byteLength(String(_line), "utf8") + 1;
33462
+ if (bytes > maxBytes) {
33463
+ rl.close();
33464
+ stream.destroy();
33465
+ return lines;
33466
+ }
33467
+ }
33468
+ return lines;
33469
+ }
33470
+
33471
+ // src/git/working-directory/changes/hydrate-patch.ts
33472
+ import * as fs15 from "node:fs";
33473
+ var UNIFIED_HUNK_HEADER_RE = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
33474
+ var MAX_HYDRATE_LINES_PER_GAP = 8e3;
33475
+ var MAX_HYDRATE_LINES_PER_FILE = 8e4;
33476
+ async function readGitBlobLines(repoCwd, pathInRepo) {
33477
+ try {
33478
+ const rel = pathInRepo.replace(/\\/g, "/");
33479
+ const raw = await simpleGit(repoCwd).show([`HEAD:${rel}`]);
33480
+ return String(raw).split(/\r?\n/);
33481
+ } catch {
33482
+ return null;
33483
+ }
33484
+ }
33485
+ async function readWorktreeFileLines(abs) {
33486
+ try {
33487
+ const raw = await fs15.promises.readFile(abs, "utf8");
33488
+ return raw.split(/\r?\n/);
33489
+ } catch {
33490
+ return null;
33491
+ }
33492
+ }
33493
+ async function hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, change) {
33494
+ if (!patch.trim() || patch.includes("Binary files")) return patch;
33495
+ const all = patch.split("\n");
33496
+ const out = [];
33497
+ let prevOldEnd = 0;
33498
+ let prevNewEnd = 0;
33499
+ let injectedTotal = 0;
33500
+ let i = 0;
33501
+ let blobCache;
33502
+ let diskCache;
33503
+ const blobLines = async () => {
33504
+ if (blobCache !== void 0) return blobCache;
33505
+ blobCache = await readGitBlobLines(repoGitCwd, pathInRepo);
33506
+ return blobCache;
33507
+ };
33508
+ const diskLines = async () => {
33509
+ if (diskCache !== void 0) return diskCache;
33510
+ diskCache = await readWorktreeFileLines(absFile);
33511
+ return diskCache;
33512
+ };
33513
+ while (i < all.length) {
33514
+ const line = all[i];
33515
+ const hm = line.match(UNIFIED_HUNK_HEADER_RE);
33516
+ if (!hm) {
33517
+ out.push(line);
33518
+ i++;
33519
+ continue;
33520
+ }
33521
+ const oldStart = parseInt(hm[1], 10) || 0;
33522
+ const newStart = parseInt(hm[3], 10) || 0;
33523
+ const gapOldStart = prevOldEnd + 1;
33524
+ const gapOldEnd = oldStart - 1;
33525
+ const gapNewStart = prevNewEnd + 1;
33526
+ const gapNewEnd = newStart - 1;
33527
+ if (injectedTotal < MAX_HYDRATE_LINES_PER_FILE) {
33528
+ let inject = null;
33529
+ if (gapNewEnd >= gapNewStart && change !== "removed") {
33530
+ const nNew = gapNewEnd - gapNewStart + 1;
33531
+ if (gapOldEnd < gapOldStart || gapOldEnd - gapOldStart + 1 === nNew) {
33532
+ const cap = Math.min(nNew, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
33533
+ const dl = await diskLines();
33534
+ if (dl && cap > 0) {
33535
+ inject = dl.slice(gapNewStart - 1, gapNewStart - 1 + cap);
33536
+ }
33537
+ }
33538
+ } else if (gapOldEnd >= gapOldStart && change === "removed") {
33539
+ const nOld = gapOldEnd - gapOldStart + 1;
33540
+ const cap = Math.min(nOld, MAX_HYDRATE_LINES_PER_GAP, MAX_HYDRATE_LINES_PER_FILE - injectedTotal);
33541
+ const bl = await blobLines();
33542
+ if (bl && cap > 0) {
33543
+ inject = bl.slice(gapOldStart - 1, gapOldStart - 1 + cap);
33544
+ }
33545
+ }
33546
+ if (inject && inject.length > 0) {
33547
+ for (const t of inject) {
33548
+ out.push(` ${t}`);
33549
+ injectedTotal++;
33550
+ }
33551
+ }
33552
+ }
33553
+ out.push(line);
33554
+ i++;
33555
+ let oldConsumed = 0;
33556
+ let newConsumed = 0;
33557
+ while (i < all.length) {
33558
+ const bl = all[i];
33559
+ if (UNIFIED_HUNK_HEADER_RE.test(bl)) break;
33560
+ out.push(bl);
33561
+ i++;
33562
+ if (bl.startsWith("\\")) continue;
33563
+ const ch = bl[0];
33564
+ if (ch === " ") {
33565
+ oldConsumed++;
33566
+ newConsumed++;
33567
+ } else if (ch === "-") {
33568
+ oldConsumed++;
33569
+ } else if (ch === "+") {
33570
+ newConsumed++;
33571
+ }
33572
+ }
33573
+ if (oldStart > 0) {
33574
+ prevOldEnd = oldStart + oldConsumed - 1;
33575
+ } else {
33576
+ prevOldEnd = 0;
33577
+ }
33578
+ if (newStart > 0) {
33579
+ prevNewEnd = newStart + newConsumed - 1;
33580
+ } else {
33581
+ prevNewEnd = 0;
33582
+ }
33583
+ }
33584
+ return truncatePatch(out.join("\n"));
33585
+ }
33586
+
33587
+ // src/git/working-directory/changes/unified-diff-for-file.ts
33588
+ async function unifiedDiffForFile(repoCwd, pathInRepo, change) {
33589
+ const g = simpleGit(repoCwd);
33590
+ try {
33591
+ let raw;
33592
+ if (change === "added") {
33593
+ const devNull = process.platform === "win32" ? "NUL" : "/dev/null";
33594
+ raw = await g.raw(["diff", "--no-index", "--", devNull, pathInRepo]);
33595
+ } else {
33596
+ raw = await g.raw(["diff", "HEAD", "--", pathInRepo]);
33597
+ }
33598
+ const t = String(raw).trim();
33599
+ if (!t) return void 0;
33600
+ return truncatePatch(t);
33601
+ } catch {
33602
+ return void 0;
33603
+ }
33604
+ }
33605
+
33606
+ // src/git/working-directory/changes/list-changed-files-for-repo.ts
33607
+ async function listChangedFilesForRepo(repoGitCwd, repoRelPath) {
33608
+ const g = simpleGit(repoGitCwd);
33609
+ const [nameStatusRaw, numstatRaw, untrackedRaw] = await Promise.all([
33610
+ g.raw(["diff", "--name-status", "HEAD"]).catch(() => ""),
33611
+ g.raw(["diff", "HEAD", "--numstat"]).catch(() => ""),
33612
+ g.raw(["ls-files", "--others", "--exclude-standard"]).catch(() => "")
33613
+ ]);
33614
+ const kindByPath = parseNameStatusLines(String(nameStatusRaw).split("\n"));
33615
+ const numByPath = parseNumstat(String(numstatRaw).split("\n"));
33616
+ const paths = /* @__PURE__ */ new Set([...kindByPath.keys(), ...numByPath.keys()]);
33617
+ const untracked = String(untrackedRaw).split("\n").map((s) => s.trim()).filter(Boolean);
33618
+ for (const p of untracked) paths.add(p);
33619
+ const rows = [];
33620
+ for (const pathInRepo of paths) {
33621
+ const relLauncher = posixJoinDirFile(repoRelPath, pathInRepo.replace(/\\/g, "/"));
33622
+ const abs = path14.join(repoGitCwd, pathInRepo);
33623
+ const nums = numByPath.get(pathInRepo);
33624
+ let additions = nums?.additions ?? 0;
33625
+ let deletions = nums?.deletions ?? 0;
33626
+ let change = kindByPath.get(pathInRepo) ?? "modified";
33627
+ if (untracked.includes(pathInRepo) && !kindByPath.has(pathInRepo)) {
33628
+ change = "added";
33629
+ const fromGit = await numstatFromGitNoIndex(g, pathInRepo);
33630
+ if (fromGit) {
33631
+ additions = fromGit.additions;
33632
+ deletions = fromGit.deletions;
33633
+ } else {
33634
+ try {
33635
+ const st = await fs16.promises.stat(abs);
33636
+ if (st.isFile()) additions = await countTextFileLines(abs);
33637
+ else additions = 0;
33638
+ } catch {
33639
+ additions = 0;
33640
+ }
33641
+ deletions = 0;
33642
+ }
33643
+ }
33644
+ if (!kindByPath.has(pathInRepo) && nums) {
33645
+ if (additions > 0 && deletions === 0) change = "added";
33646
+ else if (deletions > 0 && additions === 0) change = "removed";
33647
+ else change = "modified";
33648
+ }
33649
+ rows.push({ pathRelLauncher: relLauncher, additions, deletions, change });
33650
+ }
33651
+ const normRel = repoRelPath === "." || repoRelPath === "" ? "." : repoRelPath;
33652
+ for (const row of rows) {
33653
+ let pathInRepo;
33654
+ if (normRel === ".") {
33655
+ pathInRepo = row.pathRelLauncher;
33656
+ } else if (row.pathRelLauncher.startsWith(`${normRel}/`)) {
33657
+ pathInRepo = row.pathRelLauncher.slice(normRel.length + 1);
33658
+ } else {
33659
+ pathInRepo = row.pathRelLauncher;
33660
+ }
33661
+ const absFile = path14.join(repoGitCwd, pathInRepo);
33662
+ let patch = await unifiedDiffForFile(repoGitCwd, pathInRepo, row.change);
33663
+ if (patch) {
33664
+ patch = await hydrateUnifiedPatchWithFileContext(patch, absFile, repoGitCwd, pathInRepo, row.change);
33665
+ }
33666
+ row.patchContent = patch;
33667
+ }
33668
+ return rows;
33669
+ }
33670
+
33671
+ // src/git/working-directory/changes/get-working-tree-change-repo-details.ts
33672
+ function normRepoRel(p) {
33673
+ const x = p.replace(/\\/g, "/").trim();
33674
+ return x === "" ? "." : x;
33675
+ }
33676
+ async function getWorkingTreeChangeRepoDetails(options) {
33677
+ const launcher = path15.resolve(getBridgeWorkspaceDirectory());
33678
+ const mirror = options.agentMirrorRootAbs ? path15.resolve(options.agentMirrorRootAbs) : null;
33679
+ const out = [];
33680
+ const filter = options.repoFilterRelPath != null ? normRepoRel(options.repoFilterRelPath) : null;
33681
+ const basisInput = options.basis ?? { kind: "working" };
33682
+ if (basisInput.kind === "commit" && !filter) {
33683
+ throw new Error("repoFilterRelPath is required for commit changes");
33684
+ }
33685
+ if (basisInput.kind === "commit" && !basisInput.sha.trim()) {
33686
+ throw new Error("commit sha is required for commit changes");
33687
+ }
33688
+ const basis = filter == null && basisInput.kind === "commit" ? { kind: "working" } : basisInput;
33689
+ for (const target of options.commitTargetAbsDirs) {
33690
+ const t = path15.resolve(target);
33691
+ if (!await isGitRepoDirectory(t)) continue;
33692
+ const g = simpleGit(t);
33693
+ let branch = "HEAD";
33694
+ try {
33695
+ branch = (await g.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim() || "HEAD";
33696
+ } catch {
33697
+ branch = "HEAD";
33698
+ }
33699
+ const remoteUrl = await getRemoteOriginUrl(t);
33700
+ const remoteDisplay = formatRemoteDisplayLabel(remoteUrl);
33701
+ let repoRelPath;
33702
+ if (mirror) {
33703
+ const relNorm = path15.relative(mirror, path15.dirname(t));
33704
+ repoRelPath = relNorm === "" ? "." : relNorm.replace(/\\/g, "/");
33705
+ } else {
33706
+ let top = t;
33707
+ try {
33708
+ top = (await g.raw(["rev-parse", "--show-toplevel"])).trim();
33709
+ } catch {
33710
+ top = t;
33711
+ }
33712
+ const rel = path15.relative(launcher, path15.resolve(top)).replace(/\\/g, "/") || ".";
33713
+ repoRelPath = rel.startsWith("..") ? path15.basename(path15.resolve(top)) : rel;
33714
+ }
33715
+ const norm = normRepoRel(repoRelPath === "" ? "." : repoRelPath);
33716
+ if (filter && norm !== filter) continue;
33717
+ const repoDisplayName = formatRepoShortTitle(remoteUrl, norm === "." ? "." : norm);
33718
+ const relForList = norm === "." ? "." : norm;
33719
+ const files = basis.kind === "commit" ? await listChangedFilesForCommit(t, relForList, basis.sha.trim()) : await listChangedFilesForRepo(t, relForList);
33720
+ const st = await g.status();
33721
+ const hasUncommittedChanges = (st.files?.length ?? 0) > 0;
33722
+ const unpushedCommits = await listUnpushedCommits(t);
33723
+ out.push({
33724
+ repoRelPath: norm,
33725
+ repoDisplayName,
33726
+ branch,
33727
+ remoteUrl,
33728
+ remoteDisplay,
33729
+ files,
33730
+ hasUncommittedChanges,
33731
+ unpushedCommits,
33732
+ changesView: basis.kind === "commit" ? "commit" : "working",
33733
+ changesCommitSha: basis.kind === "commit" ? basis.sha.trim() : null
33734
+ });
33735
+ if (filter) return out;
33736
+ }
33737
+ return out;
33738
+ }
33739
+
32659
33740
  // src/git/commit-and-push.ts
32660
33741
  async function gitCommitAllIfDirty(repoDir, message, options) {
32661
33742
  const g = simpleGit(repoDir);
@@ -32721,7 +33802,7 @@ var SessionWorktreeManager = class {
32721
33802
  }
32722
33803
  if (!opts.isNewSession) {
32723
33804
  const agentCwd = this.sessionAgentCwd.get(sessionId);
32724
- if (agentCwd) return path13.resolve(agentCwd);
33805
+ if (agentCwd) return path16.resolve(agentCwd);
32725
33806
  return void 0;
32726
33807
  }
32727
33808
  const prep = await prepareNewSessionWorktrees({
@@ -32734,7 +33815,7 @@ var SessionWorktreeManager = class {
32734
33815
  if (!prep) return void 0;
32735
33816
  this.sessionPaths.set(sessionId, prep.worktreePaths);
32736
33817
  this.sessionAgentCwd.set(sessionId, prep.agentCwd);
32737
- return path13.resolve(prep.agentCwd);
33818
+ return path16.resolve(prep.agentCwd);
32738
33819
  }
32739
33820
  async renameSessionBranch(sessionId, newBranch) {
32740
33821
  const paths = this.sessionPaths.get(sessionId);
@@ -32755,7 +33836,7 @@ var SessionWorktreeManager = class {
32755
33836
  getAgentCwdForSession(sessionId) {
32756
33837
  if (!sessionId) return null;
32757
33838
  const c = this.sessionAgentCwd.get(sessionId);
32758
- return c ? path13.resolve(c) : null;
33839
+ return c ? path16.resolve(c) : null;
32759
33840
  }
32760
33841
  async removeSessionWorktrees(sessionId) {
32761
33842
  const paths = this.sessionPaths.get(sessionId);
@@ -32781,6 +33862,17 @@ var SessionWorktreeManager = class {
32781
33862
  async getSessionWorkingTreeStatus(sessionId) {
32782
33863
  return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
32783
33864
  }
33865
+ /** Per-repo changed files vs HEAD (or a single commit vs parent) for the same git roots used for commit/push. */
33866
+ async getSessionWorkingTreeChangeDetails(sessionId, opts) {
33867
+ const targets = this.resolveCommitTargets(sessionId);
33868
+ const mirror = this.getAgentCwdForSession(sessionId);
33869
+ return getWorkingTreeChangeRepoDetails({
33870
+ commitTargetAbsDirs: targets,
33871
+ agentMirrorRootAbs: mirror,
33872
+ repoFilterRelPath: opts?.repoRelPath?.trim() ? opts.repoRelPath.trim() : null,
33873
+ basis: opts?.basis
33874
+ });
33875
+ }
32784
33876
  async pushSessionUpstream(sessionId) {
32785
33877
  try {
32786
33878
  await pushAheadOfUpstreamForPaths(this.resolveCommitTargets(sessionId));
@@ -32792,30 +33884,30 @@ var SessionWorktreeManager = class {
32792
33884
  }
32793
33885
  };
32794
33886
  function defaultWorktreesRootAbs() {
32795
- return path13.join(os3.homedir(), ".buildautomaton", "worktrees");
33887
+ return path16.join(os4.homedir(), ".buildautomaton", "worktrees");
32796
33888
  }
32797
33889
 
32798
33890
  // src/files/watch-file-index.ts
32799
33891
  import { watch } from "node:fs";
32800
- import path20 from "node:path";
33892
+ import path23 from "node:path";
32801
33893
 
32802
33894
  // src/files/index/build-file-index.ts
32803
- import path17 from "node:path";
33895
+ import path20 from "node:path";
32804
33896
 
32805
33897
  // src/runtime/yield-to-event-loop.ts
32806
33898
  function yieldToEventLoop() {
32807
- return new Promise((resolve15) => setImmediate(resolve15));
33899
+ return new Promise((resolve16) => setImmediate(resolve16));
32808
33900
  }
32809
33901
 
32810
33902
  // src/files/index/walk-workspace-tree.ts
32811
- import fs10 from "node:fs";
32812
- import path15 from "node:path";
33903
+ import fs17 from "node:fs";
33904
+ import path18 from "node:path";
32813
33905
 
32814
33906
  // src/files/index/constants.ts
32815
- import path14 from "node:path";
32816
- import os4 from "node:os";
33907
+ import path17 from "node:path";
33908
+ import os5 from "node:os";
32817
33909
  var INDEX_WORK_YIELD_EVERY = 256;
32818
- var INDEX_DIR = path14.join(os4.homedir(), ".buildautomaton");
33910
+ var INDEX_DIR = path17.join(os5.homedir(), ".buildautomaton");
32819
33911
  var INDEX_HASH_LEN = 16;
32820
33912
  var INDEX_VERSION = 2;
32821
33913
  var INDEX_LOG_PREFIX = "[file-index]";
@@ -32824,31 +33916,31 @@ var INDEX_LOG_PREFIX = "[file-index]";
32824
33916
  function walkWorkspaceTreeSync(dir, baseDir, out) {
32825
33917
  let names;
32826
33918
  try {
32827
- names = fs10.readdirSync(dir);
33919
+ names = fs17.readdirSync(dir);
32828
33920
  } catch {
32829
33921
  return;
32830
33922
  }
32831
33923
  for (const name of names) {
32832
33924
  if (name.startsWith(".")) continue;
32833
- const full = path15.join(dir, name);
33925
+ const full = path18.join(dir, name);
32834
33926
  let stat2;
32835
33927
  try {
32836
- stat2 = fs10.statSync(full);
33928
+ stat2 = fs17.statSync(full);
32837
33929
  } catch {
32838
33930
  continue;
32839
33931
  }
32840
- const relative4 = path15.relative(baseDir, full).replace(/\\/g, "/");
33932
+ const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
32841
33933
  if (stat2.isDirectory()) {
32842
33934
  walkWorkspaceTreeSync(full, baseDir, out);
32843
33935
  } else if (stat2.isFile()) {
32844
- out.push(relative4);
33936
+ out.push(relative5);
32845
33937
  }
32846
33938
  }
32847
33939
  }
32848
33940
  async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
32849
33941
  let names;
32850
33942
  try {
32851
- names = await fs10.promises.readdir(dir);
33943
+ names = await fs17.promises.readdir(dir);
32852
33944
  } catch {
32853
33945
  return;
32854
33946
  }
@@ -32858,18 +33950,18 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
32858
33950
  await yieldToEventLoop();
32859
33951
  }
32860
33952
  state.n++;
32861
- const full = path15.join(dir, name);
33953
+ const full = path18.join(dir, name);
32862
33954
  let stat2;
32863
33955
  try {
32864
- stat2 = await fs10.promises.stat(full);
33956
+ stat2 = await fs17.promises.stat(full);
32865
33957
  } catch {
32866
33958
  continue;
32867
33959
  }
32868
- const relative4 = path15.relative(baseDir, full).replace(/\\/g, "/");
33960
+ const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
32869
33961
  if (stat2.isDirectory()) {
32870
33962
  await walkWorkspaceTreeAsync(full, baseDir, out, state);
32871
33963
  } else if (stat2.isFile()) {
32872
- out.push(relative4);
33964
+ out.push(relative5);
32873
33965
  }
32874
33966
  }
32875
33967
  }
@@ -32946,22 +34038,22 @@ async function buildTrigramMapForPathsAsync(paths) {
32946
34038
  }
32947
34039
 
32948
34040
  // src/files/index/write-index-file.ts
32949
- import fs11 from "node:fs";
34041
+ import fs18 from "node:fs";
32950
34042
 
32951
34043
  // src/files/index/paths.ts
32952
- import path16 from "node:path";
34044
+ import path19 from "node:path";
32953
34045
  import crypto2 from "node:crypto";
32954
34046
  function getIndexPathForCwd(resolvedCwd) {
32955
34047
  const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
32956
- return path16.join(INDEX_DIR, `.file-index-${hash}.json`);
34048
+ return path19.join(INDEX_DIR, `.file-index-${hash}.json`);
32957
34049
  }
32958
34050
 
32959
34051
  // src/files/index/write-index-file.ts
32960
34052
  function writeIndexFileSync(resolvedCwd, data) {
32961
34053
  const indexPath = getIndexPathForCwd(resolvedCwd);
32962
34054
  try {
32963
- if (!fs11.existsSync(INDEX_DIR)) fs11.mkdirSync(INDEX_DIR, { recursive: true });
32964
- fs11.writeFileSync(indexPath, JSON.stringify(data), "utf8");
34055
+ if (!fs18.existsSync(INDEX_DIR)) fs18.mkdirSync(INDEX_DIR, { recursive: true });
34056
+ fs18.writeFileSync(indexPath, JSON.stringify(data), "utf8");
32965
34057
  } catch (e) {
32966
34058
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
32967
34059
  }
@@ -32969,8 +34061,8 @@ function writeIndexFileSync(resolvedCwd, data) {
32969
34061
  async function writeIndexFileAsync(resolvedCwd, data) {
32970
34062
  const indexPath = getIndexPathForCwd(resolvedCwd);
32971
34063
  try {
32972
- await fs11.promises.mkdir(INDEX_DIR, { recursive: true });
32973
- await fs11.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
34064
+ await fs18.promises.mkdir(INDEX_DIR, { recursive: true });
34065
+ await fs18.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
32974
34066
  } catch (e) {
32975
34067
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
32976
34068
  }
@@ -32984,7 +34076,7 @@ function sortPaths(paths) {
32984
34076
  paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
32985
34077
  }
32986
34078
  function buildFileIndex(cwd) {
32987
- const resolved = path17.resolve(cwd);
34079
+ const resolved = path20.resolve(cwd);
32988
34080
  const paths = [];
32989
34081
  walkWorkspaceTreeSync(resolved, resolved, paths);
32990
34082
  sortPaths(paths);
@@ -32994,7 +34086,7 @@ function buildFileIndex(cwd) {
32994
34086
  return data;
32995
34087
  }
32996
34088
  async function buildFileIndexAsync(cwd) {
32997
- const resolved = path17.resolve(cwd);
34089
+ const resolved = path20.resolve(cwd);
32998
34090
  const paths = [];
32999
34091
  await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
33000
34092
  await yieldToEventLoop();
@@ -33006,13 +34098,13 @@ async function buildFileIndexAsync(cwd) {
33006
34098
  }
33007
34099
 
33008
34100
  // src/files/index/load-file-index.ts
33009
- import fs12 from "node:fs";
33010
- import path18 from "node:path";
34101
+ import fs19 from "node:fs";
34102
+ import path21 from "node:path";
33011
34103
  function loadFileIndex(cwd) {
33012
- const resolved = path18.resolve(cwd);
34104
+ const resolved = path21.resolve(cwd);
33013
34105
  const indexPath = getIndexPathForCwd(resolved);
33014
34106
  try {
33015
- const raw = fs12.readFileSync(indexPath, "utf8");
34107
+ const raw = fs19.readFileSync(indexPath, "utf8");
33016
34108
  const parsed = JSON.parse(raw);
33017
34109
  if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
33018
34110
  const obj = parsed;
@@ -33031,9 +34123,9 @@ function loadFileIndex(cwd) {
33031
34123
  }
33032
34124
 
33033
34125
  // src/files/index/ensure-file-index.ts
33034
- import path19 from "node:path";
34126
+ import path22 from "node:path";
33035
34127
  async function ensureFileIndexAsync(cwd) {
33036
- const resolved = path19.resolve(cwd);
34128
+ const resolved = path22.resolve(cwd);
33037
34129
  const cached2 = loadFileIndex(resolved);
33038
34130
  if (cached2 !== null) return { data: cached2, fromCache: true };
33039
34131
  const data = await buildFileIndexAsync(resolved);
@@ -33116,7 +34208,7 @@ function createFsWatcher(resolved, schedule) {
33116
34208
  }
33117
34209
  }
33118
34210
  function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
33119
- const resolved = path20.resolve(cwd);
34211
+ const resolved = path23.resolve(cwd);
33120
34212
  void buildFileIndexAsync(resolved).catch((e) => {
33121
34213
  console.error("[file-index] Initial index build failed:", e);
33122
34214
  });
@@ -33163,15 +34255,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
33163
34255
 
33164
34256
  // src/dev-servers/process/terminate-child-process.ts
33165
34257
  async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
33166
- const exited = new Promise((resolve15) => {
33167
- proc.once("exit", () => resolve15());
34258
+ const exited = new Promise((resolve16) => {
34259
+ proc.once("exit", () => resolve16());
33168
34260
  });
33169
34261
  log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
33170
34262
  try {
33171
34263
  proc.kill("SIGTERM");
33172
34264
  } catch {
33173
34265
  }
33174
- await Promise.race([exited, new Promise((resolve15) => setTimeout(resolve15, graceMs))]);
34266
+ await Promise.race([exited, new Promise((resolve16) => setTimeout(resolve16, graceMs))]);
33175
34267
  }
33176
34268
  function forceKillChild(proc, log2, shortId, graceMs) {
33177
34269
  log2(
@@ -33185,7 +34277,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
33185
34277
  }
33186
34278
 
33187
34279
  // src/dev-servers/process/wire-dev-server-child-process.ts
33188
- import fs13 from "node:fs";
34280
+ import fs20 from "node:fs";
33189
34281
 
33190
34282
  // src/dev-servers/manager/forward-pipe.ts
33191
34283
  function forwardChildPipe(childReadable, terminal, onData) {
@@ -33221,7 +34313,7 @@ function wireDevServerChildProcess(d) {
33221
34313
  d.setPollInterval(void 0);
33222
34314
  return;
33223
34315
  }
33224
- fs13.readFile(d.mergedLogPath, (err, buf) => {
34316
+ fs20.readFile(d.mergedLogPath, (err, buf) => {
33225
34317
  if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
33226
34318
  if (buf.length <= d.mergedReadPos.value) return;
33227
34319
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
@@ -33259,7 +34351,7 @@ ${errTail}` : ""}`);
33259
34351
  d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
33260
34352
  };
33261
34353
  if (mergedPath) {
33262
- fs13.readFile(mergedPath, (err, buf) => {
34354
+ fs20.readFile(mergedPath, (err, buf) => {
33263
34355
  if (!err && buf.length > d.mergedReadPos.value) {
33264
34356
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
33265
34357
  if (chunk.length > 0) {
@@ -33361,13 +34453,13 @@ function parseDevServerDefs(servers) {
33361
34453
  }
33362
34454
 
33363
34455
  // src/dev-servers/manager/shell-spawn/utils.ts
33364
- import fs14 from "node:fs";
34456
+ import fs21 from "node:fs";
33365
34457
  function isSpawnEbadf(e) {
33366
34458
  return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
33367
34459
  }
33368
34460
  function rmDirQuiet(dir) {
33369
34461
  try {
33370
- fs14.rmSync(dir, { recursive: true, force: true });
34462
+ fs21.rmSync(dir, { recursive: true, force: true });
33371
34463
  } catch {
33372
34464
  }
33373
34465
  }
@@ -33375,7 +34467,7 @@ var cachedDevNullReadFd;
33375
34467
  function devNullReadFd() {
33376
34468
  if (cachedDevNullReadFd === void 0) {
33377
34469
  const devPath = process.platform === "win32" ? "nul" : "/dev/null";
33378
- cachedDevNullReadFd = fs14.openSync(devPath, "r");
34470
+ cachedDevNullReadFd = fs21.openSync(devPath, "r");
33379
34471
  }
33380
34472
  return cachedDevNullReadFd;
33381
34473
  }
@@ -33449,15 +34541,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
33449
34541
 
33450
34542
  // src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
33451
34543
  import { spawn as spawn6 } from "node:child_process";
33452
- import fs15 from "node:fs";
34544
+ import fs22 from "node:fs";
33453
34545
  import { tmpdir } from "node:os";
33454
- import path21 from "node:path";
34546
+ import path24 from "node:path";
33455
34547
  function trySpawnMergedLogFile(command, env, cwd, signal) {
33456
- const tmpRoot = fs15.mkdtempSync(path21.join(tmpdir(), "ba-devsrv-log-"));
33457
- const logPath = path21.join(tmpRoot, "combined.log");
34548
+ const tmpRoot = fs22.mkdtempSync(path24.join(tmpdir(), "ba-devsrv-log-"));
34549
+ const logPath = path24.join(tmpRoot, "combined.log");
33458
34550
  let logFd;
33459
34551
  try {
33460
- logFd = fs15.openSync(logPath, "a");
34552
+ logFd = fs22.openSync(logPath, "a");
33461
34553
  } catch {
33462
34554
  rmDirQuiet(tmpRoot);
33463
34555
  return null;
@@ -33476,7 +34568,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
33476
34568
  } else {
33477
34569
  proc = spawn6("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
33478
34570
  }
33479
- fs15.closeSync(logFd);
34571
+ fs22.closeSync(logFd);
33480
34572
  return {
33481
34573
  proc,
33482
34574
  pipedStdoutStderr: true,
@@ -33485,7 +34577,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
33485
34577
  };
33486
34578
  } catch (e) {
33487
34579
  try {
33488
- fs15.closeSync(logFd);
34580
+ fs22.closeSync(logFd);
33489
34581
  } catch {
33490
34582
  }
33491
34583
  rmDirQuiet(tmpRoot);
@@ -33496,22 +34588,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
33496
34588
 
33497
34589
  // src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
33498
34590
  import { spawn as spawn7 } from "node:child_process";
33499
- import fs16 from "node:fs";
34591
+ import fs23 from "node:fs";
33500
34592
  import { tmpdir as tmpdir2 } from "node:os";
33501
- import path22 from "node:path";
34593
+ import path25 from "node:path";
33502
34594
  function shSingleQuote(s) {
33503
34595
  return `'${s.replace(/'/g, `'\\''`)}'`;
33504
34596
  }
33505
34597
  function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
33506
- const tmpRoot = fs16.mkdtempSync(path22.join(tmpdir2(), "ba-devsrv-sh-"));
33507
- const logPath = path22.join(tmpRoot, "combined.log");
33508
- const innerPath = path22.join(tmpRoot, "_cmd.sh");
33509
- const runnerPath = path22.join(tmpRoot, "_run.sh");
34598
+ const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
34599
+ const logPath = path25.join(tmpRoot, "combined.log");
34600
+ const innerPath = path25.join(tmpRoot, "_cmd.sh");
34601
+ const runnerPath = path25.join(tmpRoot, "_run.sh");
33510
34602
  try {
33511
- fs16.writeFileSync(innerPath, `#!/bin/sh
34603
+ fs23.writeFileSync(innerPath, `#!/bin/sh
33512
34604
  ${command}
33513
34605
  `);
33514
- fs16.writeFileSync(
34606
+ fs23.writeFileSync(
33515
34607
  runnerPath,
33516
34608
  `#!/bin/sh
33517
34609
  cd ${shSingleQuote(cwd)}
@@ -33537,13 +34629,13 @@ cd ${shSingleQuote(cwd)}
33537
34629
  }
33538
34630
  }
33539
34631
  function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
33540
- const tmpRoot = fs16.mkdtempSync(path22.join(tmpdir2(), "ba-devsrv-sh-"));
33541
- const logPath = path22.join(tmpRoot, "combined.log");
33542
- const runnerPath = path22.join(tmpRoot, "_run.bat");
34632
+ const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
34633
+ const logPath = path25.join(tmpRoot, "combined.log");
34634
+ const runnerPath = path25.join(tmpRoot, "_run.bat");
33543
34635
  const q = (p) => `"${p.replace(/"/g, '""')}"`;
33544
34636
  const com = process.env.ComSpec || "cmd.exe";
33545
34637
  try {
33546
- fs16.writeFileSync(
34638
+ fs23.writeFileSync(
33547
34639
  runnerPath,
33548
34640
  `@ECHO OFF\r
33549
34641
  CD /D ${q(cwd)}\r
@@ -34012,7 +35104,7 @@ async function proxyToLocal(request) {
34012
35104
  };
34013
35105
  const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
34014
35106
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
34015
- const once = await new Promise((resolve15) => {
35107
+ const once = await new Promise((resolve16) => {
34016
35108
  const req = mod.request(opts, (res) => {
34017
35109
  const chunks = [];
34018
35110
  res.on("data", (c) => chunks.push(c));
@@ -34023,7 +35115,7 @@ async function proxyToLocal(request) {
34023
35115
  if (typeof v === "string") headers[k] = v;
34024
35116
  else if (Array.isArray(v) && v[0]) headers[k] = v[0];
34025
35117
  }
34026
- resolve15({
35118
+ resolve16({
34027
35119
  id: request.id,
34028
35120
  statusCode: res.statusCode ?? 0,
34029
35121
  headers,
@@ -34032,7 +35124,7 @@ async function proxyToLocal(request) {
34032
35124
  });
34033
35125
  });
34034
35126
  req.on("error", (err) => {
34035
- resolve15({
35127
+ resolve16({
34036
35128
  id: request.id,
34037
35129
  statusCode: 0,
34038
35130
  headers: {},
@@ -34393,30 +35485,30 @@ function createOnBridgeIdentified(opts) {
34393
35485
  }
34394
35486
 
34395
35487
  // src/skills/discover-local-agent-skills.ts
34396
- import fs17 from "node:fs";
34397
- import path23 from "node:path";
35488
+ import fs24 from "node:fs";
35489
+ import path26 from "node:path";
34398
35490
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
34399
35491
  function discoverLocalSkills(cwd) {
34400
35492
  const out = [];
34401
35493
  const seenKeys = /* @__PURE__ */ new Set();
34402
35494
  for (const rel of SKILL_DISCOVERY_ROOTS) {
34403
- const base = path23.join(cwd, rel);
34404
- if (!fs17.existsSync(base) || !fs17.statSync(base).isDirectory()) continue;
35495
+ const base = path26.join(cwd, rel);
35496
+ if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
34405
35497
  let entries = [];
34406
35498
  try {
34407
- entries = fs17.readdirSync(base);
35499
+ entries = fs24.readdirSync(base);
34408
35500
  } catch {
34409
35501
  continue;
34410
35502
  }
34411
35503
  for (const name of entries) {
34412
- const dir = path23.join(base, name);
35504
+ const dir = path26.join(base, name);
34413
35505
  try {
34414
- if (!fs17.statSync(dir).isDirectory()) continue;
35506
+ if (!fs24.statSync(dir).isDirectory()) continue;
34415
35507
  } catch {
34416
35508
  continue;
34417
35509
  }
34418
- const skillMd = path23.join(dir, "SKILL.md");
34419
- if (!fs17.existsSync(skillMd)) continue;
35510
+ const skillMd = path26.join(dir, "SKILL.md");
35511
+ if (!fs24.existsSync(skillMd)) continue;
34420
35512
  const key = `${rel}/${name}`;
34421
35513
  if (seenKeys.has(key)) continue;
34422
35514
  seenKeys.add(key);
@@ -34428,23 +35520,23 @@ function discoverLocalSkills(cwd) {
34428
35520
  function discoverSkillLayoutRoots(cwd) {
34429
35521
  const roots = [];
34430
35522
  for (const rel of SKILL_DISCOVERY_ROOTS) {
34431
- const base = path23.join(cwd, rel);
34432
- if (!fs17.existsSync(base) || !fs17.statSync(base).isDirectory()) continue;
35523
+ const base = path26.join(cwd, rel);
35524
+ if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
34433
35525
  let entries = [];
34434
35526
  try {
34435
- entries = fs17.readdirSync(base);
35527
+ entries = fs24.readdirSync(base);
34436
35528
  } catch {
34437
35529
  continue;
34438
35530
  }
34439
35531
  const skills2 = [];
34440
35532
  for (const name of entries) {
34441
- const dir = path23.join(base, name);
35533
+ const dir = path26.join(base, name);
34442
35534
  try {
34443
- if (!fs17.statSync(dir).isDirectory()) continue;
35535
+ if (!fs24.statSync(dir).isDirectory()) continue;
34444
35536
  } catch {
34445
35537
  continue;
34446
35538
  }
34447
- if (!fs17.existsSync(path23.join(dir, "SKILL.md"))) continue;
35539
+ if (!fs24.existsSync(path26.join(dir, "SKILL.md"))) continue;
34448
35540
  const relPath = `${rel}/${name}`.replace(/\\/g, "/");
34449
35541
  skills2.push({ name, relPath });
34450
35542
  }
@@ -34589,12 +35681,12 @@ var handleAgentConfigMessage = (msg, deps) => {
34589
35681
  };
34590
35682
 
34591
35683
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
34592
- import * as path25 from "node:path";
34593
- import { execFile as execFile5 } from "node:child_process";
34594
- import { promisify as promisify5 } from "node:util";
35684
+ import * as path28 from "node:path";
35685
+ import { execFile as execFile10 } from "node:child_process";
35686
+ import { promisify as promisify10 } from "node:util";
34595
35687
 
34596
35688
  // src/git/bridge-queue-key.ts
34597
- import * as path24 from "node:path";
35689
+ import * as path27 from "node:path";
34598
35690
  import { createHash } from "node:crypto";
34599
35691
  function normalizeCanonicalGitUrl(url2) {
34600
35692
  let s = url2.trim();
@@ -34622,11 +35714,11 @@ function canonicalUrlToRepoIdSync(url2) {
34622
35714
  return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
34623
35715
  }
34624
35716
  function fallbackRepoIdFromPath(absPath) {
34625
- return createHash("sha256").update(path24.resolve(absPath)).digest("hex").slice(0, 32);
35717
+ return createHash("sha256").update(path27.resolve(absPath)).digest("hex").slice(0, 32);
34626
35718
  }
34627
35719
  async function resolveBridgeQueueBindFields(options) {
34628
35720
  const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
34629
- const cwdAbs = worktreePaths.length > 0 ? path24.resolve(worktreePaths[0]) : path24.resolve(effectiveCwd);
35721
+ const cwdAbs = worktreePaths.length > 0 ? path27.resolve(worktreePaths[0]) : path27.resolve(effectiveCwd);
34630
35722
  if (!primaryRepoRoots.length) {
34631
35723
  log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
34632
35724
  return null;
@@ -34649,10 +35741,10 @@ async function resolveBridgeQueueBindFields(options) {
34649
35741
  }
34650
35742
 
34651
35743
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
34652
- var execFileAsync5 = promisify5(execFile5);
35744
+ var execFileAsync9 = promisify10(execFile10);
34653
35745
  async function readGitBranch(cwd) {
34654
35746
  try {
34655
- const { stdout } = await execFileAsync5("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
35747
+ const { stdout } = await execFileAsync9("git", ["branch", "--show-current"], { cwd, maxBuffer: 64 * 1024 });
34656
35748
  const b = stdout.trim();
34657
35749
  return b || null;
34658
35750
  } catch {
@@ -34663,17 +35755,29 @@ function handleBridgePrompt(msg, deps) {
34663
35755
  const { getWs, log: log2, acpManager, sessionWorktreeManager } = deps;
34664
35756
  const rawPrompt = msg.prompt;
34665
35757
  const promptText = typeof rawPrompt === "string" ? rawPrompt : rawPrompt != null ? String(rawPrompt) : "";
35758
+ const sessionId = msg.sessionId;
35759
+ const runId = typeof msg.runId === "string" ? msg.runId : void 0;
35760
+ const promptId = typeof msg.id === "string" ? msg.id : void 0;
34666
35761
  if (!promptText.trim()) {
34667
35762
  log2(
34668
35763
  `[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).`
34669
35764
  );
35765
+ const s = getWs();
35766
+ if (s) {
35767
+ sendWsMessage(s, {
35768
+ type: "prompt_result",
35769
+ ...promptId ? { id: promptId } : {},
35770
+ ...sessionId ? { sessionId } : {},
35771
+ ...runId ? { runId } : {},
35772
+ success: false,
35773
+ error: "Empty or missing prompt text from the bridge; this turn was not sent to the agent."
35774
+ });
35775
+ }
34670
35776
  return;
34671
35777
  }
34672
- const sessionId = msg.sessionId;
34673
35778
  const isNewSession = msg.isNewSession === true;
34674
35779
  const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
34675
35780
  const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
34676
- const runId = typeof msg.runId === "string" ? msg.runId : void 0;
34677
35781
  const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
34678
35782
  acpManager.logPromptReceivedFromBridge({ agentType, mode });
34679
35783
  const sendResult2 = (result) => {
@@ -34691,7 +35795,7 @@ function handleBridgePrompt(msg, deps) {
34691
35795
  };
34692
35796
  async function preambleAndPrompt(resolvedCwd) {
34693
35797
  const s = getWs();
34694
- const effectiveCwd = path25.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
35798
+ const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
34695
35799
  const worktreePaths = sessionWorktreeManager.getWorktreePathsForSession(sessionId) ?? [];
34696
35800
  const repoRoots = await resolveSnapshotRepoRoots({
34697
35801
  worktreePaths,
@@ -34814,8 +35918,8 @@ function randomSecret() {
34814
35918
  }
34815
35919
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
34816
35920
  }
34817
- async function requestPreviewApi(port, secret, method, path30, body) {
34818
- const url2 = `http://127.0.0.1:${port}${path30}`;
35921
+ async function requestPreviewApi(port, secret, method, path33, body) {
35922
+ const url2 = `http://127.0.0.1:${port}${path33}`;
34819
35923
  const headers = {
34820
35924
  [PREVIEW_SECRET_HEADER]: secret,
34821
35925
  "Content-Type": "application/json"
@@ -34827,7 +35931,7 @@ async function requestPreviewApi(port, secret, method, path30, body) {
34827
35931
  });
34828
35932
  const data = await res.json().catch(() => ({}));
34829
35933
  if (!res.ok) {
34830
- throw new Error(data?.error ?? `Preview API ${method} ${path30}: ${res.status}`);
35934
+ throw new Error(data?.error ?? `Preview API ${method} ${path33}: ${res.status}`);
34831
35935
  }
34832
35936
  return data;
34833
35937
  }
@@ -34990,15 +36094,15 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
34990
36094
  };
34991
36095
 
34992
36096
  // src/files/list-dir.ts
34993
- import fs18 from "node:fs";
34994
- import path27 from "node:path";
36097
+ import fs25 from "node:fs";
36098
+ import path30 from "node:path";
34995
36099
 
34996
36100
  // src/files/ensure-under-cwd.ts
34997
- import path26 from "node:path";
36101
+ import path29 from "node:path";
34998
36102
  function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
34999
- const normalized = path26.normalize(relativePath).replace(/^(\.\/)+/, "");
35000
- const resolved = path26.resolve(cwd, normalized);
35001
- if (!resolved.startsWith(cwd + path26.sep) && resolved !== cwd) {
36103
+ const normalized = path29.normalize(relativePath).replace(/^(\.\/)+/, "");
36104
+ const resolved = path29.resolve(cwd, normalized);
36105
+ if (!resolved.startsWith(cwd + path29.sep) && resolved !== cwd) {
35002
36106
  return null;
35003
36107
  }
35004
36108
  return resolved;
@@ -35012,7 +36116,7 @@ async function listDirAsync(relativePath) {
35012
36116
  return { error: "Path is outside working directory" };
35013
36117
  }
35014
36118
  try {
35015
- const names = await fs18.promises.readdir(resolved, { withFileTypes: true });
36119
+ const names = await fs25.promises.readdir(resolved, { withFileTypes: true });
35016
36120
  const visible = names.filter((d) => !d.name.startsWith("."));
35017
36121
  const entries = [];
35018
36122
  for (let i = 0; i < visible.length; i++) {
@@ -35020,12 +36124,12 @@ async function listDirAsync(relativePath) {
35020
36124
  await yieldToEventLoop();
35021
36125
  }
35022
36126
  const d = visible[i];
35023
- const entryPath = path27.join(relativePath || ".", d.name).replace(/\\/g, "/");
35024
- const fullPath = path27.join(resolved, d.name);
36127
+ const entryPath = path30.join(relativePath || ".", d.name).replace(/\\/g, "/");
36128
+ const fullPath = path30.join(resolved, d.name);
35025
36129
  let isDir = d.isDirectory();
35026
36130
  if (d.isSymbolicLink()) {
35027
36131
  try {
35028
- const targetStat = await fs18.promises.stat(fullPath);
36132
+ const targetStat = await fs25.promises.stat(fullPath);
35029
36133
  isDir = targetStat.isDirectory();
35030
36134
  } catch {
35031
36135
  isDir = false;
@@ -35050,25 +36154,25 @@ async function listDirAsync(relativePath) {
35050
36154
  }
35051
36155
 
35052
36156
  // src/files/read-file.ts
35053
- import fs19 from "node:fs";
36157
+ import fs26 from "node:fs";
35054
36158
  import { StringDecoder } from "node:string_decoder";
35055
36159
  function resolveFilePath(relativePath) {
35056
36160
  const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
35057
36161
  if (!resolved) return { error: "Path is outside working directory" };
35058
36162
  let real;
35059
36163
  try {
35060
- real = fs19.realpathSync(resolved);
36164
+ real = fs26.realpathSync(resolved);
35061
36165
  } catch {
35062
36166
  real = resolved;
35063
36167
  }
35064
- const stat2 = fs19.statSync(real);
36168
+ const stat2 = fs26.statSync(real);
35065
36169
  if (!stat2.isFile()) return { error: "Not a file" };
35066
36170
  return real;
35067
36171
  }
35068
36172
  var LINE_CHUNK_SIZE = 64 * 1024;
35069
36173
  function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
35070
- const fileSize = fs19.statSync(filePath).size;
35071
- const fd = fs19.openSync(filePath, "r");
36174
+ const fileSize = fs26.statSync(filePath).size;
36175
+ const fd = fs26.openSync(filePath, "r");
35072
36176
  const bufSize = 64 * 1024;
35073
36177
  const buf = Buffer.alloc(bufSize);
35074
36178
  const decoder = new StringDecoder("utf8");
@@ -35081,7 +36185,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
35081
36185
  let line0Accum = "";
35082
36186
  try {
35083
36187
  let bytesRead;
35084
- while (!done && (bytesRead = fs19.readSync(fd, buf, 0, bufSize, null)) > 0) {
36188
+ while (!done && (bytesRead = fs26.readSync(fd, buf, 0, bufSize, null)) > 0) {
35085
36189
  const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
35086
36190
  partial2 = "";
35087
36191
  let lineStart = 0;
@@ -35216,7 +36320,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
35216
36320
  }
35217
36321
  return { content: resultLines.join("\n"), size: fileSize };
35218
36322
  } finally {
35219
- fs19.closeSync(fd);
36323
+ fs26.closeSync(fd);
35220
36324
  }
35221
36325
  }
35222
36326
  function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
@@ -35227,8 +36331,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
35227
36331
  if (hasRange) {
35228
36332
  return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
35229
36333
  }
35230
- const stat2 = fs19.statSync(result);
35231
- const raw = fs19.readFileSync(result, "utf8");
36334
+ const stat2 = fs26.statSync(result);
36335
+ const raw = fs26.readFileSync(result, "utf8");
35232
36336
  const lines = raw.split(/\r?\n/);
35233
36337
  return { content: raw, totalLines: lines.length, size: stat2.size };
35234
36338
  } catch (err) {
@@ -35338,10 +36442,10 @@ function handleSkillLayoutRequest(msg, deps) {
35338
36442
  }
35339
36443
 
35340
36444
  // src/skills/install-remote-skills.ts
35341
- import fs20 from "node:fs";
35342
- import path28 from "node:path";
36445
+ import fs27 from "node:fs";
36446
+ import path31 from "node:path";
35343
36447
  function installRemoteSkills(cwd, targetDir, items) {
35344
- const installed = [];
36448
+ const installed2 = [];
35345
36449
  if (!Array.isArray(items)) {
35346
36450
  return { success: false, error: "Invalid items" };
35347
36451
  }
@@ -35350,24 +36454,24 @@ function installRemoteSkills(cwd, targetDir, items) {
35350
36454
  if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
35351
36455
  continue;
35352
36456
  }
35353
- const skillDir = path28.join(cwd, targetDir, item.skillName);
36457
+ const skillDir = path31.join(cwd, targetDir, item.skillName);
35354
36458
  for (const f of item.files) {
35355
36459
  if (typeof f.path !== "string" || !f.text && !f.base64) continue;
35356
- const dest = path28.join(skillDir, f.path);
35357
- fs20.mkdirSync(path28.dirname(dest), { recursive: true });
36460
+ const dest = path31.join(skillDir, f.path);
36461
+ fs27.mkdirSync(path31.dirname(dest), { recursive: true });
35358
36462
  if (f.text !== void 0) {
35359
- fs20.writeFileSync(dest, f.text, "utf8");
36463
+ fs27.writeFileSync(dest, f.text, "utf8");
35360
36464
  } else if (f.base64) {
35361
- fs20.writeFileSync(dest, Buffer.from(f.base64, "base64"));
36465
+ fs27.writeFileSync(dest, Buffer.from(f.base64, "base64"));
35362
36466
  }
35363
36467
  }
35364
- installed.push({
36468
+ installed2.push({
35365
36469
  sourceId: item.sourceId,
35366
36470
  skillName: item.skillName,
35367
36471
  versionHash: item.versionHash
35368
36472
  });
35369
36473
  }
35370
- return { success: true, installed };
36474
+ return { success: true, installed: installed2 };
35371
36475
  } catch (e) {
35372
36476
  return { success: false, error: e instanceof Error ? e.message : String(e) };
35373
36477
  }
@@ -35404,7 +36508,8 @@ var handleSessionGitRequestMessage = (msg, deps) => {
35404
36508
  if (typeof msg.id !== "string") return;
35405
36509
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
35406
36510
  const action = msg.action;
35407
- if (!sessionId || action !== "status" && action !== "push" && action !== "commit") return;
36511
+ if (!sessionId || action !== "status" && action !== "push" && action !== "commit" && action !== "list_changes")
36512
+ return;
35408
36513
  void (async () => {
35409
36514
  const ws = deps.getWs();
35410
36515
  const reply = (payload) => sendResult(ws, msg.id, payload);
@@ -35418,6 +36523,24 @@ var handleSessionGitRequestMessage = (msg, deps) => {
35418
36523
  });
35419
36524
  return;
35420
36525
  }
36526
+ if (action === "list_changes") {
36527
+ const repoRel = typeof msg.changesRepoRelPath === "string" ? msg.changesRepoRelPath.trim() : "";
36528
+ const view = msg.changesView === "commit" ? "commit" : "working";
36529
+ const commitSha = typeof msg.changesCommitSha === "string" ? msg.changesCommitSha.trim() : "";
36530
+ if (view === "commit") {
36531
+ if (!repoRel || !commitSha) {
36532
+ reply({ ok: false, error: "changesRepoRelPath and changesCommitSha are required for commit view" });
36533
+ return;
36534
+ }
36535
+ }
36536
+ const opts = repoRel && view === "commit" && commitSha ? { repoRelPath: repoRel, basis: { kind: "commit", sha: commitSha } } : repoRel ? { repoRelPath: repoRel, basis: { kind: "working" } } : void 0;
36537
+ const repos = await deps.sessionWorktreeManager.getSessionWorkingTreeChangeDetails(sessionId, opts);
36538
+ reply({
36539
+ ok: true,
36540
+ repos
36541
+ });
36542
+ return;
36543
+ }
35421
36544
  if (action === "push") {
35422
36545
  const pushRes = await deps.sessionWorktreeManager.pushSessionUpstream(sessionId);
35423
36546
  if (!pushRes.ok) {
@@ -35484,7 +36607,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
35484
36607
  };
35485
36608
 
35486
36609
  // src/bridge/routing/handlers/revert-turn-snapshot.ts
35487
- import * as fs21 from "node:fs";
36610
+ import * as fs28 from "node:fs";
35488
36611
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
35489
36612
  const id = typeof msg.id === "string" ? msg.id : "";
35490
36613
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -35496,7 +36619,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
35496
36619
  if (!s) return;
35497
36620
  const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
35498
36621
  const file2 = snapshotFilePath(agentBase, turnId);
35499
- if (!fs21.existsSync(file2)) {
36622
+ if (!fs28.existsSync(file2)) {
35500
36623
  sendWsMessage(s, {
35501
36624
  type: "revert_turn_snapshot_result",
35502
36625
  id,
@@ -35825,6 +36948,7 @@ async function createBridgeConnection(options) {
35825
36948
 
35826
36949
  // src/run-bridge.ts
35827
36950
  async function runBridge(options) {
36951
+ installBridgeProcessResilience();
35828
36952
  const { apiUrl, workspaceId, authToken, refreshToken, bridgeName, justAuthenticated, worktreesRootAbs } = options;
35829
36953
  const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
35830
36954
  const hasAuth = workspaceId && authToken;
@@ -35936,9 +37060,9 @@ async function main() {
35936
37060
  let authToken = opts.token;
35937
37061
  const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAMATON_FIREHOSE_URL ?? process.env.BUILDAMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
35938
37062
  if (opts.cwd && typeof opts.cwd === "string" && opts.cwd.trim()) {
35939
- const resolvedCwd = path29.resolve(process.cwd(), opts.cwd.trim());
37063
+ const resolvedCwd = path32.resolve(process.cwd(), opts.cwd.trim());
35940
37064
  try {
35941
- const st = fs22.statSync(resolvedCwd);
37065
+ const st = fs29.statSync(resolvedCwd);
35942
37066
  if (!st.isDirectory()) {
35943
37067
  console.error(`--cwd is not a directory: ${resolvedCwd}`);
35944
37068
  process.exit(1);
@@ -35952,7 +37076,7 @@ async function main() {
35952
37076
  initBridgeWorkspaceDirectory();
35953
37077
  let worktreesRootAbs;
35954
37078
  if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
35955
- worktreesRootAbs = path29.resolve(opts.worktreesRoot.trim());
37079
+ worktreesRootAbs = path32.resolve(opts.worktreesRoot.trim());
35956
37080
  }
35957
37081
  let refreshToken;
35958
37082
  if ((!workspaceId || !authToken) && opts.config !== false) {