@buildautomaton/cli 0.1.18 → 0.1.19

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
@@ -973,8 +973,8 @@ 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
975
  var childProcess2 = __require("node:child_process");
976
- var path34 = __require("node:path");
977
- var fs31 = __require("node:fs");
976
+ var path36 = __require("node:path");
977
+ var fs32 = __require("node:fs");
978
978
  var process8 = __require("node:process");
979
979
  var { Argument: Argument2, humanReadableArgName } = require_argument();
980
980
  var { CommanderError: CommanderError2 } = require_error();
@@ -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 = path34.resolve(baseDir, baseName);
1910
- if (fs31.existsSync(localBin)) return localBin;
1911
- if (sourceExt.includes(path34.extname(baseName))) return void 0;
1909
+ const localBin = path36.resolve(baseDir, baseName);
1910
+ if (fs32.existsSync(localBin)) return localBin;
1911
+ if (sourceExt.includes(path36.extname(baseName))) return void 0;
1912
1912
  const foundExt = sourceExt.find(
1913
- (ext) => fs31.existsSync(`${localBin}${ext}`)
1913
+ (ext) => fs32.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 = fs31.realpathSync(this._scriptPath);
1925
+ resolvedScriptPath = fs32.realpathSync(this._scriptPath);
1926
1926
  } catch (err) {
1927
1927
  resolvedScriptPath = this._scriptPath;
1928
1928
  }
1929
- executableDir = path34.resolve(
1930
- path34.dirname(resolvedScriptPath),
1929
+ executableDir = path36.resolve(
1930
+ path36.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 = path34.basename(
1937
+ const legacyName = path36.basename(
1938
1938
  this._scriptPath,
1939
- path34.extname(this._scriptPath)
1939
+ path36.extname(this._scriptPath)
1940
1940
  );
1941
1941
  if (legacyName !== this._name) {
1942
1942
  localFile = findFile(
@@ -1947,7 +1947,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1947
1947
  }
1948
1948
  executableFile = localFile || executableFile;
1949
1949
  }
1950
- launchWithNode = sourceExt.includes(path34.extname(executableFile));
1950
+ launchWithNode = sourceExt.includes(path36.extname(executableFile));
1951
1951
  let proc;
1952
1952
  if (process8.platform !== "win32") {
1953
1953
  if (launchWithNode) {
@@ -2787,7 +2787,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2787
2787
  * @return {Command}
2788
2788
  */
2789
2789
  nameFromFilename(filename) {
2790
- this._name = path34.basename(filename, path34.extname(filename));
2790
+ this._name = path36.basename(filename, path36.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(path35) {
2805
- if (path35 === void 0) return this._executableDir;
2806
- this._executableDir = path35;
2804
+ executableDir(path37) {
2805
+ if (path37 === void 0) return this._executableDir;
2806
+ this._executableDir = path37;
2807
2807
  return this;
2808
2808
  }
2809
2809
  /**
@@ -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(path34, isFile, isDirectory) {
7427
- log2(`checking %s`, path34);
7426
+ function check2(path36, isFile, isDirectory) {
7427
+ log2(`checking %s`, path36);
7428
7428
  try {
7429
- const stat3 = fs_1.statSync(path34);
7429
+ const stat3 = fs_1.statSync(path36);
7430
7430
  if (stat3.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(path34, type = exports.READABLE) {
7450
- return check2(path34, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
7449
+ function exists2(path36, type = exports.READABLE) {
7450
+ return check2(path36, (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: path34, errorMaps, issueData } = params;
7926
- const fullPath = [...path34, ...issueData.path || []];
7925
+ const { data, path: path36, errorMaps, issueData } = params;
7926
+ const fullPath = [...path36, ...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, path34, key) {
8234
+ constructor(parent, value, path36, key) {
8235
8235
  this._cachedPath = [];
8236
8236
  this.parent = parent;
8237
8237
  this.data = value;
8238
- this._path = path34;
8238
+ this._path = path36;
8239
8239
  this._key = key;
8240
8240
  }
8241
8241
  get path() {
@@ -11850,10 +11850,10 @@ function assignProp(target, prop, value) {
11850
11850
  configurable: true
11851
11851
  });
11852
11852
  }
11853
- function getElementAtPath(obj, path34) {
11854
- if (!path34)
11853
+ function getElementAtPath(obj, path36) {
11854
+ if (!path36)
11855
11855
  return obj;
11856
- return path34.reduce((acc, key) => acc?.[key], obj);
11856
+ return path36.reduce((acc, key) => acc?.[key], obj);
11857
11857
  }
11858
11858
  function promiseAllObject(promisesObj) {
11859
11859
  const keys = Object.keys(promisesObj);
@@ -12102,11 +12102,11 @@ function aborted(x, startIndex = 0) {
12102
12102
  }
12103
12103
  return false;
12104
12104
  }
12105
- function prefixIssues(path34, issues) {
12105
+ function prefixIssues(path36, issues) {
12106
12106
  return issues.map((iss) => {
12107
12107
  var _a2;
12108
12108
  (_a2 = iss).path ?? (_a2.path = []);
12109
- iss.path.unshift(path34);
12109
+ iss.path.unshift(path36);
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, path34 = []) => {
12298
+ const processError = (error41, path36 = []) => {
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 = [...path34, ...issue2.path];
12308
+ const fullpath = [...path36, ...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(path34) {
12338
+ function toDotPath(path36) {
12339
12339
  const segs = [];
12340
- for (const seg of path34) {
12340
+ for (const seg of path36) {
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((resolve17) => {
24804
- this.#abortController.signal.addEventListener("abort", () => resolve17());
24803
+ this.#closedPromise = new Promise((resolve19) => {
24804
+ this.#abortController.signal.addEventListener("abort", () => resolve19());
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((resolve17, reject) => {
24954
- this.#pendingResponses.set(id, { resolve: resolve17, reject });
24953
+ const responsePromise = new Promise((resolve19, reject) => {
24954
+ this.#pendingResponses.set(id, { resolve: resolve19, reject });
24955
24955
  });
24956
24956
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
24957
24957
  return responsePromise;
@@ -25063,13 +25063,16 @@ var {
25063
25063
  Help
25064
25064
  } = import_index.default;
25065
25065
 
25066
+ // src/cli-version.ts
25067
+ var CLI_VERSION = "0.1.19".length > 0 ? "0.1.19" : "0.0.0-dev";
25068
+
25066
25069
  // src/cli/defaults.ts
25067
25070
  var DEFAULT_API_URL = process.env.BUILDAUTOMATON_API_URL ?? "https://api.buildautomaton.com";
25068
25071
  var DEFAULT_FIREHOSE_URL = "https://buildautomaton-firehose.fly.dev";
25069
25072
 
25070
25073
  // src/cli/run-cli-action.ts
25071
- import * as fs30 from "node:fs";
25072
- import * as path33 from "node:path";
25074
+ import * as fs31 from "node:fs";
25075
+ import * as path35 from "node:path";
25073
25076
 
25074
25077
  // src/config.ts
25075
25078
  import fs from "node:fs";
@@ -26034,14 +26037,14 @@ var baseOpen = async (options) => {
26034
26037
  }
26035
26038
  const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
26036
26039
  if (options.wait) {
26037
- return new Promise((resolve17, reject) => {
26040
+ return new Promise((resolve19, reject) => {
26038
26041
  subprocess.once("error", reject);
26039
26042
  subprocess.once("close", (exitCode) => {
26040
26043
  if (!options.allowNonzeroExitCode && exitCode > 0) {
26041
26044
  reject(new Error(`Exited with code ${exitCode}`));
26042
26045
  return;
26043
26046
  }
26044
- resolve17(subprocess);
26047
+ resolve19(subprocess);
26045
26048
  });
26046
26049
  });
26047
26050
  }
@@ -26337,8 +26340,8 @@ function runPendingAuth(options) {
26337
26340
  let hasOpenedBrowser = false;
26338
26341
  let resolved = false;
26339
26342
  let resolveAuth;
26340
- const authPromise = new Promise((resolve17) => {
26341
- resolveAuth = resolve17;
26343
+ const authPromise = new Promise((resolve19) => {
26344
+ resolveAuth = resolve19;
26342
26345
  });
26343
26346
  let reconnectAttempt = 0;
26344
26347
  const signInQuiet = createEmptyReconnectQuietSlot();
@@ -26390,7 +26393,7 @@ function runPendingAuth(options) {
26390
26393
  url: url2,
26391
26394
  onOpen: () => {
26392
26395
  clearQuietOnOpen();
26393
- sendWsMessage(ws, { type: "identify", role: "cli" });
26396
+ sendWsMessage(ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
26394
26397
  keepaliveInterval = setInterval(() => {
26395
26398
  if (resolved || !ws || ws.readyState !== 1) return;
26396
26399
  sendWsMessage(ws, { type: "ping", timestamp: Date.now() });
@@ -26460,7 +26463,7 @@ function runPendingAuth(options) {
26460
26463
  async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
26461
26464
  const say = log2 ?? logImmediate;
26462
26465
  say("Cleaning up connections\u2026");
26463
- await new Promise((resolve17) => setImmediate(resolve17));
26466
+ await new Promise((resolve19) => setImmediate(resolve19));
26464
26467
  state.closedByUser = true;
26465
26468
  clearReconnectQuietTimer(state.mainQuiet);
26466
26469
  clearReconnectQuietTimer(state.firehoseQuiet);
@@ -26582,8 +26585,8 @@ function pathspec(...paths) {
26582
26585
  cache.set(key, paths);
26583
26586
  return key;
26584
26587
  }
26585
- function isPathSpec(path34) {
26586
- return path34 instanceof String && cache.has(path34);
26588
+ function isPathSpec(path36) {
26589
+ return path36 instanceof String && cache.has(path36);
26587
26590
  }
26588
26591
  function toPaths(pathSpec) {
26589
26592
  return cache.get(pathSpec) || [];
@@ -26672,8 +26675,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
26672
26675
  function forEachLineWithContent(input, callback) {
26673
26676
  return toLinesWithContent(input, true).map((line) => callback(line));
26674
26677
  }
26675
- function folderExists(path34) {
26676
- return (0, import_file_exists.exists)(path34, import_file_exists.FOLDER);
26678
+ function folderExists(path36) {
26679
+ return (0, import_file_exists.exists)(path36, import_file_exists.FOLDER);
26677
26680
  }
26678
26681
  function append(target, item) {
26679
26682
  if (Array.isArray(target)) {
@@ -27077,8 +27080,8 @@ function checkIsRepoRootTask() {
27077
27080
  commands,
27078
27081
  format: "utf-8",
27079
27082
  onError,
27080
- parser(path34) {
27081
- return /^\.(git)?$/.test(path34.trim());
27083
+ parser(path36) {
27084
+ return /^\.(git)?$/.test(path36.trim());
27082
27085
  }
27083
27086
  };
27084
27087
  }
@@ -27512,11 +27515,11 @@ function parseGrep(grep) {
27512
27515
  const paths = /* @__PURE__ */ new Set();
27513
27516
  const results = {};
27514
27517
  forEachLineWithContent(grep, (input) => {
27515
- const [path34, line, preview] = input.split(NULL);
27516
- paths.add(path34);
27517
- (results[path34] = results[path34] || []).push({
27518
+ const [path36, line, preview] = input.split(NULL);
27519
+ paths.add(path36);
27520
+ (results[path36] = results[path36] || []).push({
27518
27521
  line: asNumber(line),
27519
- path: path34,
27522
+ path: path36,
27520
27523
  preview
27521
27524
  });
27522
27525
  });
@@ -28281,14 +28284,14 @@ var init_hash_object = __esm2({
28281
28284
  init_task();
28282
28285
  }
28283
28286
  });
28284
- function parseInit(bare, path34, text) {
28287
+ function parseInit(bare, path36, text) {
28285
28288
  const response = String(text).trim();
28286
28289
  let result;
28287
28290
  if (result = initResponseRegex.exec(response)) {
28288
- return new InitSummary(bare, path34, false, result[1]);
28291
+ return new InitSummary(bare, path36, false, result[1]);
28289
28292
  }
28290
28293
  if (result = reInitResponseRegex.exec(response)) {
28291
- return new InitSummary(bare, path34, true, result[1]);
28294
+ return new InitSummary(bare, path36, true, result[1]);
28292
28295
  }
28293
28296
  let gitDir = "";
28294
28297
  const tokens = response.split(" ");
@@ -28299,7 +28302,7 @@ function parseInit(bare, path34, text) {
28299
28302
  break;
28300
28303
  }
28301
28304
  }
28302
- return new InitSummary(bare, path34, /^re/i.test(response), gitDir);
28305
+ return new InitSummary(bare, path36, /^re/i.test(response), gitDir);
28303
28306
  }
28304
28307
  var InitSummary;
28305
28308
  var initResponseRegex;
@@ -28308,9 +28311,9 @@ var init_InitSummary = __esm2({
28308
28311
  "src/lib/responses/InitSummary.ts"() {
28309
28312
  "use strict";
28310
28313
  InitSummary = class {
28311
- constructor(bare, path34, existing, gitDir) {
28314
+ constructor(bare, path36, existing, gitDir) {
28312
28315
  this.bare = bare;
28313
- this.path = path34;
28316
+ this.path = path36;
28314
28317
  this.existing = existing;
28315
28318
  this.gitDir = gitDir;
28316
28319
  }
@@ -28322,7 +28325,7 @@ var init_InitSummary = __esm2({
28322
28325
  function hasBareCommand(command) {
28323
28326
  return command.includes(bareCommand);
28324
28327
  }
28325
- function initTask(bare = false, path34, customArgs) {
28328
+ function initTask(bare = false, path36, customArgs) {
28326
28329
  const commands = ["init", ...customArgs];
28327
28330
  if (bare && !hasBareCommand(commands)) {
28328
28331
  commands.splice(1, 0, bareCommand);
@@ -28331,7 +28334,7 @@ function initTask(bare = false, path34, customArgs) {
28331
28334
  commands,
28332
28335
  format: "utf-8",
28333
28336
  parser(text) {
28334
- return parseInit(commands.includes("--bare"), path34, text);
28337
+ return parseInit(commands.includes("--bare"), path36, text);
28335
28338
  }
28336
28339
  };
28337
28340
  }
@@ -29147,12 +29150,12 @@ var init_FileStatusSummary = __esm2({
29147
29150
  "use strict";
29148
29151
  fromPathRegex = /^(.+)\0(.+)$/;
29149
29152
  FileStatusSummary = class {
29150
- constructor(path34, index, working_dir) {
29151
- this.path = path34;
29153
+ constructor(path36, index, working_dir) {
29154
+ this.path = path36;
29152
29155
  this.index = index;
29153
29156
  this.working_dir = working_dir;
29154
29157
  if (index === "R" || working_dir === "R") {
29155
- const detail = fromPathRegex.exec(path34) || [null, path34, path34];
29158
+ const detail = fromPathRegex.exec(path36) || [null, path36, path36];
29156
29159
  this.from = detail[2] || "";
29157
29160
  this.path = detail[1] || "";
29158
29161
  }
@@ -29183,14 +29186,14 @@ function splitLine(result, lineStr) {
29183
29186
  default:
29184
29187
  return;
29185
29188
  }
29186
- function data(index, workingDir, path34) {
29189
+ function data(index, workingDir, path36) {
29187
29190
  const raw = `${index}${workingDir}`;
29188
29191
  const handler = parsers6.get(raw);
29189
29192
  if (handler) {
29190
- handler(result, path34);
29193
+ handler(result, path36);
29191
29194
  }
29192
29195
  if (raw !== "##" && raw !== "!!") {
29193
- result.files.push(new FileStatusSummary(path34, index, workingDir));
29196
+ result.files.push(new FileStatusSummary(path36, index, workingDir));
29194
29197
  }
29195
29198
  }
29196
29199
  }
@@ -29499,9 +29502,9 @@ var init_simple_git_api = __esm2({
29499
29502
  next
29500
29503
  );
29501
29504
  }
29502
- hashObject(path34, write) {
29505
+ hashObject(path36, write) {
29503
29506
  return this._runTask(
29504
- hashObjectTask(path34, write === true),
29507
+ hashObjectTask(path36, write === true),
29505
29508
  trailingFunctionArgument(arguments)
29506
29509
  );
29507
29510
  }
@@ -29854,8 +29857,8 @@ var init_branch = __esm2({
29854
29857
  }
29855
29858
  });
29856
29859
  function toPath(input) {
29857
- const path34 = input.trim().replace(/^["']|["']$/g, "");
29858
- return path34 && normalize(path34);
29860
+ const path36 = input.trim().replace(/^["']|["']$/g, "");
29861
+ return path36 && normalize(path36);
29859
29862
  }
29860
29863
  var parseCheckIgnore;
29861
29864
  var init_CheckIgnore = __esm2({
@@ -30169,8 +30172,8 @@ __export2(sub_module_exports, {
30169
30172
  subModuleTask: () => subModuleTask,
30170
30173
  updateSubModuleTask: () => updateSubModuleTask
30171
30174
  });
30172
- function addSubModuleTask(repo, path34) {
30173
- return subModuleTask(["add", repo, path34]);
30175
+ function addSubModuleTask(repo, path36) {
30176
+ return subModuleTask(["add", repo, path36]);
30174
30177
  }
30175
30178
  function initSubModuleTask(customArgs) {
30176
30179
  return subModuleTask(["init", ...customArgs]);
@@ -30503,8 +30506,8 @@ var require_git = __commonJS2({
30503
30506
  }
30504
30507
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
30505
30508
  };
30506
- Git2.prototype.submoduleAdd = function(repo, path34, then) {
30507
- return this._runTask(addSubModuleTask2(repo, path34), trailingFunctionArgument2(arguments));
30509
+ Git2.prototype.submoduleAdd = function(repo, path36, then) {
30510
+ return this._runTask(addSubModuleTask2(repo, path36), trailingFunctionArgument2(arguments));
30508
30511
  };
30509
30512
  Git2.prototype.submoduleUpdate = function(args, then) {
30510
30513
  return this._runTask(
@@ -31636,9 +31639,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
31636
31639
  const rawPath = typeof o.path === "string" ? o.path.trim() : "";
31637
31640
  const summary = typeof o.summary === "string" ? o.summary.trim() : "";
31638
31641
  if (!rawPath || !summary) continue;
31639
- const path34 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
31640
- if (!path34) continue;
31641
- rows.push({ path: path34, summary: clampSummaryToAtMostTwoLines(summary) });
31642
+ const path36 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
31643
+ if (!path36) continue;
31644
+ rows.push({ path: path36, summary: clampSummaryToAtMostTwoLines(summary) });
31642
31645
  }
31643
31646
  return rows;
31644
31647
  }
@@ -31753,9 +31756,9 @@ var GitRepoMetaSchema = external_exports.object({
31753
31756
  // src/agents/acp/put-summarize-change-summaries.ts
31754
31757
  async function putEncryptedChangeSummaryRows(params) {
31755
31758
  const base = params.apiBaseUrl.replace(/\/+$/, "");
31756
- const entries = params.rows.map(({ path: path34, summary }) => {
31759
+ const entries = params.rows.map(({ path: path36, summary }) => {
31757
31760
  const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
31758
- return { path: path34, summary: JSON.stringify(enc) };
31761
+ return { path: path36, summary: JSON.stringify(enc) };
31759
31762
  });
31760
31763
  const res = await fetch(
31761
31764
  `${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
@@ -32154,7 +32157,7 @@ async function createSdkStdioAcpClient(options) {
32154
32157
  child.once("close", (code, signal) => {
32155
32158
  onAgentSubprocessExit?.({ code, signal });
32156
32159
  });
32157
- return new Promise((resolve17, reject) => {
32160
+ return new Promise((resolve19, reject) => {
32158
32161
  let initSettled = false;
32159
32162
  const settleReject = (err) => {
32160
32163
  if (initSettled) return;
@@ -32168,7 +32171,7 @@ async function createSdkStdioAcpClient(options) {
32168
32171
  const settleResolve = (handle) => {
32169
32172
  if (initSettled) return;
32170
32173
  initSettled = true;
32171
- resolve17(handle);
32174
+ resolve19(handle);
32172
32175
  };
32173
32176
  child.on("error", (err) => {
32174
32177
  settleReject(new Error(formatSpawnError(err, command[0])));
@@ -32204,8 +32207,8 @@ async function createSdkStdioAcpClient(options) {
32204
32207
  });
32205
32208
  } catch {
32206
32209
  }
32207
- return await new Promise((resolve18) => {
32208
- pendingPermissionResolvers.set(requestId, resolve18);
32210
+ return await new Promise((resolve20) => {
32211
+ pendingPermissionResolvers.set(requestId, resolve20);
32209
32212
  });
32210
32213
  },
32211
32214
  async readTextFile(params) {
@@ -32313,9 +32316,9 @@ async function createSdkStdioAcpClient(options) {
32313
32316
  }
32314
32317
  },
32315
32318
  async cancel() {
32316
- for (const [id, resolve18] of [...pendingPermissionResolvers.entries()]) {
32319
+ for (const [id, resolve20] of [...pendingPermissionResolvers.entries()]) {
32317
32320
  pendingPermissionResolvers.delete(id);
32318
- resolve18({ outcome: { outcome: "cancelled" } });
32321
+ resolve20({ outcome: { outcome: "cancelled" } });
32319
32322
  }
32320
32323
  try {
32321
32324
  await connection.cancel({ sessionId });
@@ -32331,10 +32334,10 @@ async function createSdkStdioAcpClient(options) {
32331
32334
  }
32332
32335
  },
32333
32336
  resolveRequest(requestId, result) {
32334
- const resolve18 = pendingPermissionResolvers.get(requestId);
32335
- if (!resolve18) return;
32337
+ const resolve20 = pendingPermissionResolvers.get(requestId);
32338
+ if (!resolve20) return;
32336
32339
  pendingPermissionResolvers.delete(requestId);
32337
- resolve18(result);
32340
+ resolve20(result);
32338
32341
  },
32339
32342
  disconnect() {
32340
32343
  child.kill();
@@ -32485,7 +32488,7 @@ async function createCursorAcpClient(options) {
32485
32488
  });
32486
32489
  const stderrCapture = createStderrCapture(child);
32487
32490
  child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
32488
- return new Promise((resolve17, reject) => {
32491
+ return new Promise((resolve19, reject) => {
32489
32492
  child.on("error", (err) => {
32490
32493
  child.kill();
32491
32494
  reject(new Error(formatSpawnError2(err, command[0])));
@@ -32672,7 +32675,7 @@ async function createCursorAcpClient(options) {
32672
32675
  const newResult = await send("session/new", { cwd, mcpServers: [] });
32673
32676
  const sessionId = newResult?.sessionId ?? "";
32674
32677
  if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
32675
- resolve17({
32678
+ resolve19({
32676
32679
  sessionId,
32677
32680
  async sendPrompt(prompt, _options) {
32678
32681
  promptOutputBuffer = "";
@@ -33740,7 +33743,7 @@ async function createAcpManager(options) {
33740
33743
  }
33741
33744
 
33742
33745
  // src/worktrees/session-worktree-manager.ts
33743
- import * as path17 from "node:path";
33746
+ import * as path18 from "node:path";
33744
33747
  import os4 from "node:os";
33745
33748
 
33746
33749
  // src/worktrees/prepare-new-session-worktrees.ts
@@ -33789,10 +33792,15 @@ function saveWorktreeLayout(layout) {
33789
33792
  function baseNameSafe(abs) {
33790
33793
  return path12.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
33791
33794
  }
33792
- function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
33795
+ function getLauncherDirNameIfPresent(layout, launcherCwdAbs) {
33793
33796
  const norm = path12.resolve(launcherCwdAbs);
33794
33797
  const existing = layout.launcherCwds.find((e) => path12.resolve(e.absolutePath) === norm);
33795
- if (existing) return existing.dirName;
33798
+ return existing?.dirName;
33799
+ }
33800
+ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
33801
+ const existing = getLauncherDirNameIfPresent(layout, launcherCwdAbs);
33802
+ if (existing) return existing;
33803
+ const norm = path12.resolve(launcherCwdAbs);
33796
33804
  const base = baseNameSafe(norm);
33797
33805
  const used = new Set(layout.launcherCwds.map((e) => e.dirName));
33798
33806
  let name = base;
@@ -34570,11 +34578,88 @@ async function commitSessionWorktrees(options) {
34570
34578
  }
34571
34579
  }
34572
34580
 
34581
+ // src/worktrees/discover-session-worktree-on-disk.ts
34582
+ import * as fs18 from "node:fs";
34583
+ import * as path17 from "node:path";
34584
+ function isGitDir(abs) {
34585
+ try {
34586
+ return fs18.existsSync(path17.join(abs, ".git"));
34587
+ } catch {
34588
+ return false;
34589
+ }
34590
+ }
34591
+ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
34592
+ const out = [];
34593
+ const walk = (dir, depth) => {
34594
+ if (depth > maxDepth) return;
34595
+ let entries;
34596
+ try {
34597
+ entries = fs18.readdirSync(dir, { withFileTypes: true });
34598
+ } catch {
34599
+ return;
34600
+ }
34601
+ for (const e of entries) {
34602
+ if (e.name.startsWith(".")) continue;
34603
+ const full = path17.join(dir, e.name);
34604
+ if (!e.isDirectory()) continue;
34605
+ if (e.name === sessionId) {
34606
+ if (isGitDir(full)) out.push(path17.resolve(full));
34607
+ } else {
34608
+ walk(full, depth + 1);
34609
+ }
34610
+ }
34611
+ };
34612
+ walk(root, 0);
34613
+ return out;
34614
+ }
34615
+ function discoverSessionWorktreeOnDisk(options) {
34616
+ const { sessionId, worktreesRootAbs, layout, launcherCwd } = options;
34617
+ if (!sessionId.trim() || !fs18.existsSync(worktreesRootAbs)) return null;
34618
+ const preferredKey = getLauncherDirNameIfPresent(layout, launcherCwd);
34619
+ const keys = [];
34620
+ if (preferredKey) keys.push(preferredKey);
34621
+ try {
34622
+ for (const name of fs18.readdirSync(worktreesRootAbs)) {
34623
+ if (name.startsWith(".")) continue;
34624
+ const p = path17.join(worktreesRootAbs, name);
34625
+ if (!fs18.statSync(p).isDirectory()) continue;
34626
+ if (name !== preferredKey) keys.push(name);
34627
+ }
34628
+ } catch {
34629
+ return null;
34630
+ }
34631
+ for (const key of keys) {
34632
+ const mirrorRoot = path17.join(worktreesRootAbs, key);
34633
+ if (!fs18.existsSync(mirrorRoot) || !fs18.statSync(mirrorRoot).isDirectory()) continue;
34634
+ const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
34635
+ if (worktreePaths.length > 0) {
34636
+ return { agentCwd: path17.resolve(mirrorRoot), worktreePaths };
34637
+ }
34638
+ }
34639
+ return null;
34640
+ }
34641
+ function discoverSessionWorktreesUnderMirrorRoot(mirrorRootAbs, sessionId) {
34642
+ const mirrorRoot = path17.resolve(mirrorRootAbs);
34643
+ if (!sessionId.trim() || !fs18.existsSync(mirrorRoot)) return null;
34644
+ try {
34645
+ if (!fs18.statSync(mirrorRoot).isDirectory()) return null;
34646
+ } catch {
34647
+ return null;
34648
+ }
34649
+ const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
34650
+ if (worktreePaths.length === 0) return null;
34651
+ return { agentCwd: mirrorRoot, worktreePaths };
34652
+ }
34653
+
34573
34654
  // src/worktrees/session-worktree-manager.ts
34655
+ function parseSessionParent(v) {
34656
+ if (v === "bridge_root" || v === "worktrees_root") return v;
34657
+ if (v === "session_worktrees_root") return "worktrees_root";
34658
+ return null;
34659
+ }
34574
34660
  var SessionWorktreeManager = class {
34575
34661
  rootAbs;
34576
34662
  log;
34577
- bridgeWantsWorktrees = false;
34578
34663
  sessionPaths = /* @__PURE__ */ new Map();
34579
34664
  sessionAgentCwd = /* @__PURE__ */ new Map();
34580
34665
  layout;
@@ -34583,22 +34668,67 @@ var SessionWorktreeManager = class {
34583
34668
  this.log = options.log;
34584
34669
  this.layout = loadWorktreeLayout();
34585
34670
  }
34586
- setBridgeSessionWorktrees(enabled) {
34587
- this.bridgeWantsWorktrees = enabled;
34671
+ rememberWorktrees(sessionId, agentCwd, worktreePaths) {
34672
+ this.sessionPaths.set(sessionId, worktreePaths);
34673
+ this.sessionAgentCwd.set(sessionId, path18.resolve(agentCwd));
34588
34674
  }
34589
- effective() {
34590
- return this.bridgeWantsWorktrees;
34675
+ tryDiscoverFromDisk(sessionId) {
34676
+ return discoverSessionWorktreeOnDisk({
34677
+ sessionId,
34678
+ worktreesRootAbs: this.rootAbs,
34679
+ layout: this.layout,
34680
+ launcherCwd: getBridgeWorkspaceDirectory()
34681
+ });
34591
34682
  }
34592
34683
  /**
34593
34684
  * Returns cwd for the agent (mirror of launcher tree), or undefined to use the bridge workspace directory.
34594
34685
  */
34595
34686
  async resolveCwdForPrompt(sessionId, opts) {
34596
- if (!sessionId || !this.effective() || !opts.sessionWorktreesEnabled) {
34687
+ if (!sessionId) return void 0;
34688
+ const parentPathRaw = opts.sessionParentPath?.trim();
34689
+ if (parentPathRaw) {
34690
+ const agentCwd = path18.resolve(parentPathRaw);
34691
+ const sid = sessionId?.trim();
34692
+ if (sid && parseSessionParent(opts.sessionParent) === "worktrees_root") {
34693
+ const fromMirror = discoverSessionWorktreesUnderMirrorRoot(agentCwd, sid);
34694
+ if (fromMirror) this.rememberWorktrees(sid, fromMirror.agentCwd, fromMirror.worktreePaths);
34695
+ }
34696
+ return agentCwd;
34697
+ }
34698
+ const parentKind = parseSessionParent(opts.sessionParent);
34699
+ if (parentKind === "bridge_root") {
34597
34700
  return void 0;
34598
34701
  }
34702
+ if (parentKind === "worktrees_root") {
34703
+ if (!opts.isNewSession) {
34704
+ const cached2 = this.sessionAgentCwd.get(sessionId);
34705
+ if (cached2) return path18.resolve(cached2);
34706
+ const disc = this.tryDiscoverFromDisk(sessionId);
34707
+ if (disc) {
34708
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
34709
+ return path18.resolve(disc.agentCwd);
34710
+ }
34711
+ return void 0;
34712
+ }
34713
+ const prep2 = await prepareNewSessionWorktrees({
34714
+ rootAbs: this.rootAbs,
34715
+ launcherCwd: getBridgeWorkspaceDirectory(),
34716
+ sessionId,
34717
+ layout: this.layout,
34718
+ log: this.log
34719
+ });
34720
+ if (!prep2) return void 0;
34721
+ this.rememberWorktrees(sessionId, prep2.agentCwd, prep2.worktreePaths);
34722
+ return path18.resolve(prep2.agentCwd);
34723
+ }
34599
34724
  if (!opts.isNewSession) {
34600
- const agentCwd = this.sessionAgentCwd.get(sessionId);
34601
- if (agentCwd) return path17.resolve(agentCwd);
34725
+ const cached2 = this.sessionAgentCwd.get(sessionId);
34726
+ if (cached2) return path18.resolve(cached2);
34727
+ const disc = this.tryDiscoverFromDisk(sessionId);
34728
+ if (disc) {
34729
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
34730
+ return path18.resolve(disc.agentCwd);
34731
+ }
34602
34732
  return void 0;
34603
34733
  }
34604
34734
  const prep = await prepareNewSessionWorktrees({
@@ -34609,9 +34739,8 @@ var SessionWorktreeManager = class {
34609
34739
  log: this.log
34610
34740
  });
34611
34741
  if (!prep) return void 0;
34612
- this.sessionPaths.set(sessionId, prep.worktreePaths);
34613
- this.sessionAgentCwd.set(sessionId, prep.agentCwd);
34614
- return path17.resolve(prep.agentCwd);
34742
+ this.rememberWorktrees(sessionId, prep.agentCwd, prep.worktreePaths);
34743
+ return path18.resolve(prep.agentCwd);
34615
34744
  }
34616
34745
  async renameSessionBranch(sessionId, newBranch) {
34617
34746
  const paths = this.sessionPaths.get(sessionId);
@@ -34632,7 +34761,7 @@ var SessionWorktreeManager = class {
34632
34761
  getAgentCwdForSession(sessionId) {
34633
34762
  if (!sessionId) return null;
34634
34763
  const c = this.sessionAgentCwd.get(sessionId);
34635
- return c ? path17.resolve(c) : null;
34764
+ return c ? path18.resolve(c) : null;
34636
34765
  }
34637
34766
  async removeSessionWorktrees(sessionId) {
34638
34767
  const paths = this.sessionPaths.get(sessionId);
@@ -34653,7 +34782,13 @@ var SessionWorktreeManager = class {
34653
34782
  }
34654
34783
  resolveCommitTargets(sessionId) {
34655
34784
  const paths = this.sessionPaths.get(sessionId);
34656
- return paths?.length ? paths : [getBridgeWorkspaceDirectory()];
34785
+ if (paths?.length) return paths;
34786
+ const disc = this.tryDiscoverFromDisk(sessionId);
34787
+ if (disc?.worktreePaths.length) {
34788
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
34789
+ return disc.worktreePaths;
34790
+ }
34791
+ return [getBridgeWorkspaceDirectory()];
34657
34792
  }
34658
34793
  async getSessionWorkingTreeStatus(sessionId) {
34659
34794
  return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
@@ -34680,30 +34815,30 @@ var SessionWorktreeManager = class {
34680
34815
  }
34681
34816
  };
34682
34817
  function defaultWorktreesRootAbs() {
34683
- return path17.join(os4.homedir(), ".buildautomaton", "worktrees");
34818
+ return path18.join(os4.homedir(), ".buildautomaton", "worktrees");
34684
34819
  }
34685
34820
 
34686
34821
  // src/files/watch-file-index.ts
34687
34822
  import { watch } from "node:fs";
34688
- import path24 from "node:path";
34823
+ import path25 from "node:path";
34689
34824
 
34690
34825
  // src/files/index/build-file-index.ts
34691
- import path21 from "node:path";
34826
+ import path22 from "node:path";
34692
34827
 
34693
34828
  // src/runtime/yield-to-event-loop.ts
34694
34829
  function yieldToEventLoop() {
34695
- return new Promise((resolve17) => setImmediate(resolve17));
34830
+ return new Promise((resolve19) => setImmediate(resolve19));
34696
34831
  }
34697
34832
 
34698
34833
  // src/files/index/walk-workspace-tree.ts
34699
- import fs18 from "node:fs";
34700
- import path19 from "node:path";
34834
+ import fs19 from "node:fs";
34835
+ import path20 from "node:path";
34701
34836
 
34702
34837
  // src/files/index/constants.ts
34703
- import path18 from "node:path";
34838
+ import path19 from "node:path";
34704
34839
  import os5 from "node:os";
34705
34840
  var INDEX_WORK_YIELD_EVERY = 256;
34706
- var INDEX_DIR = path18.join(os5.homedir(), ".buildautomaton");
34841
+ var INDEX_DIR = path19.join(os5.homedir(), ".buildautomaton");
34707
34842
  var INDEX_HASH_LEN = 16;
34708
34843
  var INDEX_VERSION = 2;
34709
34844
  var INDEX_LOG_PREFIX = "[file-index]";
@@ -34712,20 +34847,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
34712
34847
  function walkWorkspaceTreeSync(dir, baseDir, out) {
34713
34848
  let names;
34714
34849
  try {
34715
- names = fs18.readdirSync(dir);
34850
+ names = fs19.readdirSync(dir);
34716
34851
  } catch {
34717
34852
  return;
34718
34853
  }
34719
34854
  for (const name of names) {
34720
34855
  if (name.startsWith(".")) continue;
34721
- const full = path19.join(dir, name);
34856
+ const full = path20.join(dir, name);
34722
34857
  let stat3;
34723
34858
  try {
34724
- stat3 = fs18.statSync(full);
34859
+ stat3 = fs19.statSync(full);
34725
34860
  } catch {
34726
34861
  continue;
34727
34862
  }
34728
- const relative5 = path19.relative(baseDir, full).replace(/\\/g, "/");
34863
+ const relative5 = path20.relative(baseDir, full).replace(/\\/g, "/");
34729
34864
  if (stat3.isDirectory()) {
34730
34865
  walkWorkspaceTreeSync(full, baseDir, out);
34731
34866
  } else if (stat3.isFile()) {
@@ -34736,7 +34871,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
34736
34871
  async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
34737
34872
  let names;
34738
34873
  try {
34739
- names = await fs18.promises.readdir(dir);
34874
+ names = await fs19.promises.readdir(dir);
34740
34875
  } catch {
34741
34876
  return;
34742
34877
  }
@@ -34746,14 +34881,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
34746
34881
  await yieldToEventLoop();
34747
34882
  }
34748
34883
  state.n++;
34749
- const full = path19.join(dir, name);
34884
+ const full = path20.join(dir, name);
34750
34885
  let stat3;
34751
34886
  try {
34752
- stat3 = await fs18.promises.stat(full);
34887
+ stat3 = await fs19.promises.stat(full);
34753
34888
  } catch {
34754
34889
  continue;
34755
34890
  }
34756
- const relative5 = path19.relative(baseDir, full).replace(/\\/g, "/");
34891
+ const relative5 = path20.relative(baseDir, full).replace(/\\/g, "/");
34757
34892
  if (stat3.isDirectory()) {
34758
34893
  await walkWorkspaceTreeAsync(full, baseDir, out, state);
34759
34894
  } else if (stat3.isFile()) {
@@ -34834,22 +34969,22 @@ async function buildTrigramMapForPathsAsync(paths) {
34834
34969
  }
34835
34970
 
34836
34971
  // src/files/index/write-index-file.ts
34837
- import fs19 from "node:fs";
34972
+ import fs20 from "node:fs";
34838
34973
 
34839
34974
  // src/files/index/paths.ts
34840
- import path20 from "node:path";
34975
+ import path21 from "node:path";
34841
34976
  import crypto2 from "node:crypto";
34842
34977
  function getIndexPathForCwd(resolvedCwd) {
34843
34978
  const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
34844
- return path20.join(INDEX_DIR, `.file-index-${hash}.json`);
34979
+ return path21.join(INDEX_DIR, `.file-index-${hash}.json`);
34845
34980
  }
34846
34981
 
34847
34982
  // src/files/index/write-index-file.ts
34848
34983
  function writeIndexFileSync(resolvedCwd, data) {
34849
34984
  const indexPath = getIndexPathForCwd(resolvedCwd);
34850
34985
  try {
34851
- if (!fs19.existsSync(INDEX_DIR)) fs19.mkdirSync(INDEX_DIR, { recursive: true });
34852
- fs19.writeFileSync(indexPath, JSON.stringify(data), "utf8");
34986
+ if (!fs20.existsSync(INDEX_DIR)) fs20.mkdirSync(INDEX_DIR, { recursive: true });
34987
+ fs20.writeFileSync(indexPath, JSON.stringify(data), "utf8");
34853
34988
  } catch (e) {
34854
34989
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
34855
34990
  }
@@ -34857,8 +34992,8 @@ function writeIndexFileSync(resolvedCwd, data) {
34857
34992
  async function writeIndexFileAsync(resolvedCwd, data) {
34858
34993
  const indexPath = getIndexPathForCwd(resolvedCwd);
34859
34994
  try {
34860
- await fs19.promises.mkdir(INDEX_DIR, { recursive: true });
34861
- await fs19.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
34995
+ await fs20.promises.mkdir(INDEX_DIR, { recursive: true });
34996
+ await fs20.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
34862
34997
  } catch (e) {
34863
34998
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
34864
34999
  }
@@ -34872,7 +35007,7 @@ function sortPaths(paths) {
34872
35007
  paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
34873
35008
  }
34874
35009
  function buildFileIndex(cwd) {
34875
- const resolved = path21.resolve(cwd);
35010
+ const resolved = path22.resolve(cwd);
34876
35011
  const paths = [];
34877
35012
  walkWorkspaceTreeSync(resolved, resolved, paths);
34878
35013
  sortPaths(paths);
@@ -34882,7 +35017,7 @@ function buildFileIndex(cwd) {
34882
35017
  return data;
34883
35018
  }
34884
35019
  async function buildFileIndexAsync(cwd) {
34885
- const resolved = path21.resolve(cwd);
35020
+ const resolved = path22.resolve(cwd);
34886
35021
  const paths = [];
34887
35022
  await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
34888
35023
  await yieldToEventLoop();
@@ -34894,13 +35029,13 @@ async function buildFileIndexAsync(cwd) {
34894
35029
  }
34895
35030
 
34896
35031
  // src/files/index/load-file-index.ts
34897
- import fs20 from "node:fs";
34898
- import path22 from "node:path";
35032
+ import fs21 from "node:fs";
35033
+ import path23 from "node:path";
34899
35034
  function loadFileIndex(cwd) {
34900
- const resolved = path22.resolve(cwd);
35035
+ const resolved = path23.resolve(cwd);
34901
35036
  const indexPath = getIndexPathForCwd(resolved);
34902
35037
  try {
34903
- const raw = fs20.readFileSync(indexPath, "utf8");
35038
+ const raw = fs21.readFileSync(indexPath, "utf8");
34904
35039
  const parsed = JSON.parse(raw);
34905
35040
  if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
34906
35041
  const obj = parsed;
@@ -34919,9 +35054,9 @@ function loadFileIndex(cwd) {
34919
35054
  }
34920
35055
 
34921
35056
  // src/files/index/ensure-file-index.ts
34922
- import path23 from "node:path";
35057
+ import path24 from "node:path";
34923
35058
  async function ensureFileIndexAsync(cwd) {
34924
- const resolved = path23.resolve(cwd);
35059
+ const resolved = path24.resolve(cwd);
34925
35060
  const cached2 = loadFileIndex(resolved);
34926
35061
  if (cached2 !== null) return { data: cached2, fromCache: true };
34927
35062
  const data = await buildFileIndexAsync(resolved);
@@ -35004,7 +35139,7 @@ function createFsWatcher(resolved, schedule) {
35004
35139
  }
35005
35140
  }
35006
35141
  function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
35007
- const resolved = path24.resolve(cwd);
35142
+ const resolved = path25.resolve(cwd);
35008
35143
  void buildFileIndexAsync(resolved).catch((e) => {
35009
35144
  console.error("[file-index] Initial index build failed:", e);
35010
35145
  });
@@ -35031,6 +35166,9 @@ function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
35031
35166
  };
35032
35167
  }
35033
35168
 
35169
+ // src/bridge/connection/create-bridge-connection.ts
35170
+ import * as path34 from "node:path";
35171
+
35034
35172
  // src/dev-servers/manager/dev-server-manager.ts
35035
35173
  import { rm as rm2 } from "node:fs/promises";
35036
35174
 
@@ -35051,15 +35189,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
35051
35189
 
35052
35190
  // src/dev-servers/process/terminate-child-process.ts
35053
35191
  async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
35054
- const exited = new Promise((resolve17) => {
35055
- proc.once("exit", () => resolve17());
35192
+ const exited = new Promise((resolve19) => {
35193
+ proc.once("exit", () => resolve19());
35056
35194
  });
35057
35195
  log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
35058
35196
  try {
35059
35197
  proc.kill("SIGTERM");
35060
35198
  } catch {
35061
35199
  }
35062
- await Promise.race([exited, new Promise((resolve17) => setTimeout(resolve17, graceMs))]);
35200
+ await Promise.race([exited, new Promise((resolve19) => setTimeout(resolve19, graceMs))]);
35063
35201
  }
35064
35202
  function forceKillChild(proc, log2, shortId, graceMs) {
35065
35203
  log2(
@@ -35073,7 +35211,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
35073
35211
  }
35074
35212
 
35075
35213
  // src/dev-servers/process/wire-dev-server-child-process.ts
35076
- import fs21 from "node:fs";
35214
+ import fs22 from "node:fs";
35077
35215
 
35078
35216
  // src/dev-servers/manager/forward-pipe.ts
35079
35217
  function forwardChildPipe(childReadable, terminal, onData) {
@@ -35109,7 +35247,7 @@ function wireDevServerChildProcess(d) {
35109
35247
  d.setPollInterval(void 0);
35110
35248
  return;
35111
35249
  }
35112
- fs21.readFile(d.mergedLogPath, (err, buf) => {
35250
+ fs22.readFile(d.mergedLogPath, (err, buf) => {
35113
35251
  if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
35114
35252
  if (buf.length <= d.mergedReadPos.value) return;
35115
35253
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
@@ -35147,7 +35285,7 @@ ${errTail}` : ""}`);
35147
35285
  d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
35148
35286
  };
35149
35287
  if (mergedPath) {
35150
- fs21.readFile(mergedPath, (err, buf) => {
35288
+ fs22.readFile(mergedPath, (err, buf) => {
35151
35289
  if (!err && buf.length > d.mergedReadPos.value) {
35152
35290
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
35153
35291
  if (chunk.length > 0) {
@@ -35249,13 +35387,13 @@ function parseDevServerDefs(servers) {
35249
35387
  }
35250
35388
 
35251
35389
  // src/dev-servers/manager/shell-spawn/utils.ts
35252
- import fs22 from "node:fs";
35390
+ import fs23 from "node:fs";
35253
35391
  function isSpawnEbadf(e) {
35254
35392
  return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
35255
35393
  }
35256
35394
  function rmDirQuiet(dir) {
35257
35395
  try {
35258
- fs22.rmSync(dir, { recursive: true, force: true });
35396
+ fs23.rmSync(dir, { recursive: true, force: true });
35259
35397
  } catch {
35260
35398
  }
35261
35399
  }
@@ -35263,7 +35401,7 @@ var cachedDevNullReadFd;
35263
35401
  function devNullReadFd() {
35264
35402
  if (cachedDevNullReadFd === void 0) {
35265
35403
  const devPath = process.platform === "win32" ? "nul" : "/dev/null";
35266
- cachedDevNullReadFd = fs22.openSync(devPath, "r");
35404
+ cachedDevNullReadFd = fs23.openSync(devPath, "r");
35267
35405
  }
35268
35406
  return cachedDevNullReadFd;
35269
35407
  }
@@ -35337,15 +35475,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
35337
35475
 
35338
35476
  // src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
35339
35477
  import { spawn as spawn6 } from "node:child_process";
35340
- import fs23 from "node:fs";
35478
+ import fs24 from "node:fs";
35341
35479
  import { tmpdir } from "node:os";
35342
- import path25 from "node:path";
35480
+ import path26 from "node:path";
35343
35481
  function trySpawnMergedLogFile(command, env, cwd, signal) {
35344
- const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir(), "ba-devsrv-log-"));
35345
- const logPath = path25.join(tmpRoot, "combined.log");
35482
+ const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir(), "ba-devsrv-log-"));
35483
+ const logPath = path26.join(tmpRoot, "combined.log");
35346
35484
  let logFd;
35347
35485
  try {
35348
- logFd = fs23.openSync(logPath, "a");
35486
+ logFd = fs24.openSync(logPath, "a");
35349
35487
  } catch {
35350
35488
  rmDirQuiet(tmpRoot);
35351
35489
  return null;
@@ -35364,7 +35502,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
35364
35502
  } else {
35365
35503
  proc = spawn6("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
35366
35504
  }
35367
- fs23.closeSync(logFd);
35505
+ fs24.closeSync(logFd);
35368
35506
  return {
35369
35507
  proc,
35370
35508
  pipedStdoutStderr: true,
@@ -35373,7 +35511,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
35373
35511
  };
35374
35512
  } catch (e) {
35375
35513
  try {
35376
- fs23.closeSync(logFd);
35514
+ fs24.closeSync(logFd);
35377
35515
  } catch {
35378
35516
  }
35379
35517
  rmDirQuiet(tmpRoot);
@@ -35384,22 +35522,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
35384
35522
 
35385
35523
  // src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
35386
35524
  import { spawn as spawn7 } from "node:child_process";
35387
- import fs24 from "node:fs";
35525
+ import fs25 from "node:fs";
35388
35526
  import { tmpdir as tmpdir2 } from "node:os";
35389
- import path26 from "node:path";
35527
+ import path27 from "node:path";
35390
35528
  function shSingleQuote(s) {
35391
35529
  return `'${s.replace(/'/g, `'\\''`)}'`;
35392
35530
  }
35393
35531
  function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
35394
- const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir2(), "ba-devsrv-sh-"));
35395
- const logPath = path26.join(tmpRoot, "combined.log");
35396
- const innerPath = path26.join(tmpRoot, "_cmd.sh");
35397
- const runnerPath = path26.join(tmpRoot, "_run.sh");
35532
+ const tmpRoot = fs25.mkdtempSync(path27.join(tmpdir2(), "ba-devsrv-sh-"));
35533
+ const logPath = path27.join(tmpRoot, "combined.log");
35534
+ const innerPath = path27.join(tmpRoot, "_cmd.sh");
35535
+ const runnerPath = path27.join(tmpRoot, "_run.sh");
35398
35536
  try {
35399
- fs24.writeFileSync(innerPath, `#!/bin/sh
35537
+ fs25.writeFileSync(innerPath, `#!/bin/sh
35400
35538
  ${command}
35401
35539
  `);
35402
- fs24.writeFileSync(
35540
+ fs25.writeFileSync(
35403
35541
  runnerPath,
35404
35542
  `#!/bin/sh
35405
35543
  cd ${shSingleQuote(cwd)}
@@ -35425,13 +35563,13 @@ cd ${shSingleQuote(cwd)}
35425
35563
  }
35426
35564
  }
35427
35565
  function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
35428
- const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir2(), "ba-devsrv-sh-"));
35429
- const logPath = path26.join(tmpRoot, "combined.log");
35430
- const runnerPath = path26.join(tmpRoot, "_run.bat");
35566
+ const tmpRoot = fs25.mkdtempSync(path27.join(tmpdir2(), "ba-devsrv-sh-"));
35567
+ const logPath = path27.join(tmpRoot, "combined.log");
35568
+ const runnerPath = path27.join(tmpRoot, "_run.bat");
35431
35569
  const q = (p) => `"${p.replace(/"/g, '""')}"`;
35432
35570
  const com = process.env.ComSpec || "cmd.exe";
35433
35571
  try {
35434
- fs24.writeFileSync(
35572
+ fs25.writeFileSync(
35435
35573
  runnerPath,
35436
35574
  `@ECHO OFF\r
35437
35575
  CD /D ${q(cwd)}\r
@@ -35942,7 +36080,7 @@ async function proxyToLocal(request) {
35942
36080
  };
35943
36081
  const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
35944
36082
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
35945
- const once = await new Promise((resolve17) => {
36083
+ const once = await new Promise((resolve19) => {
35946
36084
  const req = mod.request(opts, (res) => {
35947
36085
  const chunks = [];
35948
36086
  res.on("data", (c) => chunks.push(c));
@@ -35953,7 +36091,7 @@ async function proxyToLocal(request) {
35953
36091
  if (typeof v === "string") headers[k] = v;
35954
36092
  else if (Array.isArray(v) && v[0]) headers[k] = v[0];
35955
36093
  }
35956
- resolve17({
36094
+ resolve19({
35957
36095
  id: request.id,
35958
36096
  statusCode: res.statusCode ?? 0,
35959
36097
  headers,
@@ -35962,7 +36100,7 @@ async function proxyToLocal(request) {
35962
36100
  });
35963
36101
  });
35964
36102
  req.on("error", (err) => {
35965
- resolve17({
36103
+ resolve19({
35966
36104
  id: request.id,
35967
36105
  statusCode: 0,
35968
36106
  headers: {},
@@ -36301,10 +36439,9 @@ function attachFirehoseAfterIdentified(ctx, params) {
36301
36439
 
36302
36440
  // src/bridge/connection/create-bridge-identified-handler.ts
36303
36441
  function createOnBridgeIdentified(opts) {
36304
- const { sessionWorktreeManager, devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
36442
+ const { devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
36305
36443
  const firehoseCtx = { state, devServerManager, logFn };
36306
36444
  return (msg) => {
36307
- sessionWorktreeManager.setBridgeSessionWorktrees(msg.sessionWorktreesEnabled === true);
36308
36445
  const bridgeName = msg.bridgeName;
36309
36446
  const proxyPorts = Array.isArray(msg.proxyPorts) ? msg.proxyPorts : [];
36310
36447
  const devServers = msg.devServers ?? [];
@@ -36323,30 +36460,30 @@ function createOnBridgeIdentified(opts) {
36323
36460
  }
36324
36461
 
36325
36462
  // src/skills/discover-local-agent-skills.ts
36326
- import fs25 from "node:fs";
36327
- import path27 from "node:path";
36463
+ import fs26 from "node:fs";
36464
+ import path28 from "node:path";
36328
36465
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
36329
36466
  function discoverLocalSkills(cwd) {
36330
36467
  const out = [];
36331
36468
  const seenKeys = /* @__PURE__ */ new Set();
36332
36469
  for (const rel of SKILL_DISCOVERY_ROOTS) {
36333
- const base = path27.join(cwd, rel);
36334
- if (!fs25.existsSync(base) || !fs25.statSync(base).isDirectory()) continue;
36470
+ const base = path28.join(cwd, rel);
36471
+ if (!fs26.existsSync(base) || !fs26.statSync(base).isDirectory()) continue;
36335
36472
  let entries = [];
36336
36473
  try {
36337
- entries = fs25.readdirSync(base);
36474
+ entries = fs26.readdirSync(base);
36338
36475
  } catch {
36339
36476
  continue;
36340
36477
  }
36341
36478
  for (const name of entries) {
36342
- const dir = path27.join(base, name);
36479
+ const dir = path28.join(base, name);
36343
36480
  try {
36344
- if (!fs25.statSync(dir).isDirectory()) continue;
36481
+ if (!fs26.statSync(dir).isDirectory()) continue;
36345
36482
  } catch {
36346
36483
  continue;
36347
36484
  }
36348
- const skillMd = path27.join(dir, "SKILL.md");
36349
- if (!fs25.existsSync(skillMd)) continue;
36485
+ const skillMd = path28.join(dir, "SKILL.md");
36486
+ if (!fs26.existsSync(skillMd)) continue;
36350
36487
  const key = `${rel}/${name}`;
36351
36488
  if (seenKeys.has(key)) continue;
36352
36489
  seenKeys.add(key);
@@ -36358,23 +36495,23 @@ function discoverLocalSkills(cwd) {
36358
36495
  function discoverSkillLayoutRoots(cwd) {
36359
36496
  const roots = [];
36360
36497
  for (const rel of SKILL_DISCOVERY_ROOTS) {
36361
- const base = path27.join(cwd, rel);
36362
- if (!fs25.existsSync(base) || !fs25.statSync(base).isDirectory()) continue;
36498
+ const base = path28.join(cwd, rel);
36499
+ if (!fs26.existsSync(base) || !fs26.statSync(base).isDirectory()) continue;
36363
36500
  let entries = [];
36364
36501
  try {
36365
- entries = fs25.readdirSync(base);
36502
+ entries = fs26.readdirSync(base);
36366
36503
  } catch {
36367
36504
  continue;
36368
36505
  }
36369
36506
  const skills2 = [];
36370
36507
  for (const name of entries) {
36371
- const dir = path27.join(base, name);
36508
+ const dir = path28.join(base, name);
36372
36509
  try {
36373
- if (!fs25.statSync(dir).isDirectory()) continue;
36510
+ if (!fs26.statSync(dir).isDirectory()) continue;
36374
36511
  } catch {
36375
36512
  continue;
36376
36513
  }
36377
- if (!fs25.existsSync(path27.join(dir, "SKILL.md"))) continue;
36514
+ if (!fs26.existsSync(path28.join(dir, "SKILL.md"))) continue;
36378
36515
  const relPath = `${rel}/${name}`.replace(/\\/g, "/");
36379
36516
  skills2.push({ name, relPath });
36380
36517
  }
@@ -36419,7 +36556,7 @@ function createSendLocalSkillsReport(getWs, logFn) {
36419
36556
  const socket = getWs();
36420
36557
  if (!socket || socket.readyState !== wrapper_default.OPEN) return;
36421
36558
  const skills2 = discoverLocalSkills(getBridgeWorkspaceDirectory());
36422
- socket.send(JSON.stringify({ type: "local_skills", skills: skills2 }));
36559
+ sendWsMessage(socket, { type: "local_skills", skills: skills2 });
36423
36560
  } catch (e) {
36424
36561
  logFn(
36425
36562
  `[Bridge service] Local skills report failed: ${e instanceof Error ? e.message : String(e)}`
@@ -36472,6 +36609,41 @@ function reportGitRepos(getWs, log2) {
36472
36609
  });
36473
36610
  }
36474
36611
 
36612
+ // src/types/api-to-bridge-messages.ts
36613
+ var API_TO_BRIDGE_MESSAGE_TYPES = [
36614
+ "auth_token",
36615
+ "bridge_identified",
36616
+ "dev_servers_config",
36617
+ "server_control",
36618
+ "agent_config",
36619
+ "prompt",
36620
+ "session_git_request",
36621
+ "rename_session_branch",
36622
+ "session_archived",
36623
+ "session_discarded",
36624
+ "revert_turn_snapshot",
36625
+ "cancel_run",
36626
+ "cursor_request_response",
36627
+ "skill_call",
36628
+ "file_browser_request",
36629
+ "file_browser_search",
36630
+ "skill_layout_request",
36631
+ "install_skills",
36632
+ "refresh_local_skills"
36633
+ ];
36634
+ var API_TO_BRIDGE_TYPE_SET = new Set(API_TO_BRIDGE_MESSAGE_TYPES);
36635
+ function parseApiToBridgeMessage(data, log2) {
36636
+ if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
36637
+ const t = data.type;
36638
+ if (typeof t !== "string" || !API_TO_BRIDGE_TYPE_SET.has(t)) {
36639
+ if (typeof t === "string") {
36640
+ log2?.(`[Bridge service] unhandled message type: ${t}`);
36641
+ }
36642
+ return null;
36643
+ }
36644
+ return data;
36645
+ }
36646
+
36475
36647
  // src/bridge/routing/handlers/auth-token.ts
36476
36648
  var handleAuthToken = (msg, { log: log2 }) => {
36477
36649
  if (typeof msg.token !== "string") return;
@@ -36482,9 +36654,11 @@ var handleAuthToken = (msg, { log: log2 }) => {
36482
36654
  // src/bridge/routing/handlers/bridge-identified.ts
36483
36655
  var handleBridgeIdentified = (msg, deps) => {
36484
36656
  if (typeof msg.bridgeName !== "string") return;
36485
- deps.onBridgeIdentified(
36486
- msg
36487
- );
36657
+ deps.onBridgeIdentified({
36658
+ bridgeName: msg.bridgeName,
36659
+ proxyPorts: msg.proxyPorts,
36660
+ devServers: msg.devServers
36661
+ });
36488
36662
  setImmediate(() => {
36489
36663
  void (async () => {
36490
36664
  try {
@@ -36519,7 +36693,7 @@ var handleAgentConfigMessage = (msg, deps) => {
36519
36693
  };
36520
36694
 
36521
36695
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
36522
- import * as path29 from "node:path";
36696
+ import * as path30 from "node:path";
36523
36697
 
36524
36698
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
36525
36699
  function createBridgePromptSenders(deps, getWs) {
@@ -36560,7 +36734,7 @@ import { execFile as execFile10 } from "node:child_process";
36560
36734
  import { promisify as promisify10 } from "node:util";
36561
36735
 
36562
36736
  // src/git/bridge-queue-key.ts
36563
- import * as path28 from "node:path";
36737
+ import * as path29 from "node:path";
36564
36738
  import { createHash as createHash2 } from "node:crypto";
36565
36739
  function normalizeCanonicalGitUrl(url2) {
36566
36740
  let s = url2.trim();
@@ -36588,11 +36762,11 @@ function canonicalUrlToRepoIdSync(url2) {
36588
36762
  return createHash2("sha256").update(normalized).digest("hex").slice(0, 32);
36589
36763
  }
36590
36764
  function fallbackRepoIdFromPath(absPath) {
36591
- return createHash2("sha256").update(path28.resolve(absPath)).digest("hex").slice(0, 32);
36765
+ return createHash2("sha256").update(path29.resolve(absPath)).digest("hex").slice(0, 32);
36592
36766
  }
36593
36767
  async function resolveBridgeQueueBindFields(options) {
36594
36768
  const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
36595
- const cwdAbs = worktreePaths.length > 0 ? path28.resolve(worktreePaths[0]) : path28.resolve(effectiveCwd);
36769
+ const cwdAbs = worktreePaths.length > 0 ? path29.resolve(worktreePaths[0]) : path29.resolve(effectiveCwd);
36596
36770
  if (!primaryRepoRoots.length) {
36597
36771
  log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
36598
36772
  return null;
@@ -36653,11 +36827,15 @@ async function runBridgePromptPreamble(params) {
36653
36827
  }
36654
36828
  if (s && sessionId) {
36655
36829
  const cliGitBranch = await readGitBranch(effectiveCwd);
36830
+ const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
36831
+ const mirrorAbs = sessionWorktreeManager.getAgentCwdForSession(sessionId);
36656
36832
  sendWsMessage(s, {
36657
36833
  type: "session_git_context_report",
36658
36834
  sessionId,
36659
36835
  cliGitBranch,
36660
- agentUsesWorktree: sessionWorktreeManager.usesWorktreeSession(sessionId)
36836
+ agentUsesWorktree: usesWt,
36837
+ sessionParent: usesWt ? "worktrees_root" : "bridge_root",
36838
+ sessionParentPath: usesWt ? mirrorAbs : getBridgeWorkspaceDirectory()
36661
36839
  });
36662
36840
  }
36663
36841
  if (s && sessionId && runId) {
@@ -36676,9 +36854,9 @@ function parseChangeSummarySnapshots(raw) {
36676
36854
  for (const item of raw) {
36677
36855
  if (!item || typeof item !== "object") continue;
36678
36856
  const o = item;
36679
- const path34 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
36680
- if (!path34) continue;
36681
- const row = { path: path34 };
36857
+ const path36 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
36858
+ if (!path36) continue;
36859
+ const row = { path: path36 };
36682
36860
  if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
36683
36861
  if (typeof o.oldText === "string") row.oldText = o.oldText;
36684
36862
  if (typeof o.newText === "string") row.newText = o.newText;
@@ -36777,12 +36955,14 @@ function handleBridgePrompt(msg, deps) {
36777
36955
  return;
36778
36956
  }
36779
36957
  const isNewSession = msg.isNewSession === true;
36780
- const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
36958
+ const rawParent = msg.sessionParent;
36959
+ const sessionParent = rawParent === "bridge_root" || rawParent === "worktrees_root" ? rawParent : rawParent === "session_worktrees_root" ? "worktrees_root" : null;
36960
+ const sessionParentPath = typeof msg.sessionParentPath === "string" && msg.sessionParentPath.trim() ? msg.sessionParentPath.trim() : null;
36781
36961
  const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
36782
36962
  const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
36783
36963
  acpManager.logPromptReceivedFromBridge({ agentType, mode });
36784
36964
  async function preambleAndPrompt(resolvedCwd) {
36785
- const effectiveCwd = path29.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
36965
+ const effectiveCwd = path30.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
36786
36966
  await runBridgePromptPreamble({
36787
36967
  getWs,
36788
36968
  log: log2,
@@ -36825,7 +37005,7 @@ function handleBridgePrompt(msg, deps) {
36825
37005
  e2ee: deps.e2ee
36826
37006
  });
36827
37007
  }
36828
- void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionWorktreesEnabled }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
37008
+ void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionParent, sessionParentPath }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
36829
37009
  log2(`[Agent] Worktree resolve failed: ${err instanceof Error ? err.message : String(err)}`);
36830
37010
  void preambleAndPrompt(void 0);
36831
37011
  });
@@ -36894,8 +37074,8 @@ function randomSecret() {
36894
37074
  }
36895
37075
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
36896
37076
  }
36897
- async function requestPreviewApi(port, secret, method, path34, body) {
36898
- const url2 = `http://127.0.0.1:${port}${path34}`;
37077
+ async function requestPreviewApi(port, secret, method, path36, body) {
37078
+ const url2 = `http://127.0.0.1:${port}${path36}`;
36899
37079
  const headers = {
36900
37080
  [PREVIEW_SECRET_HEADER]: secret,
36901
37081
  "Content-Type": "application/json"
@@ -36907,7 +37087,7 @@ async function requestPreviewApi(port, secret, method, path34, body) {
36907
37087
  });
36908
37088
  const data = await res.json().catch(() => ({}));
36909
37089
  if (!res.ok) {
36910
- throw new Error(data?.error ?? `Preview API ${method} ${path34}: ${res.status}`);
37090
+ throw new Error(data?.error ?? `Preview API ${method} ${path36}: ${res.status}`);
36911
37091
  }
36912
37092
  return data;
36913
37093
  }
@@ -37059,26 +37239,28 @@ function handleSkillCall(msg, socket, log2) {
37059
37239
 
37060
37240
  // src/bridge/routing/handlers/skill-call.ts
37061
37241
  var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
37062
- if (!msg.skillId || msg.operationId === void 0) return;
37242
+ const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
37243
+ const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
37244
+ if (!skillId || !operationId) return;
37063
37245
  const socket = getWs();
37064
37246
  if (!socket) return;
37065
37247
  handleSkillCall(
37066
- msg,
37248
+ { id: msg.id, skillId, operationId, params: msg.params },
37067
37249
  socket,
37068
37250
  log2
37069
37251
  );
37070
37252
  };
37071
37253
 
37072
37254
  // src/files/list-dir.ts
37073
- import fs26 from "node:fs";
37074
- import path31 from "node:path";
37255
+ import fs27 from "node:fs";
37256
+ import path32 from "node:path";
37075
37257
 
37076
37258
  // src/files/ensure-under-cwd.ts
37077
- import path30 from "node:path";
37259
+ import path31 from "node:path";
37078
37260
  function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
37079
- const normalized = path30.normalize(relativePath).replace(/^(\.\/)+/, "");
37080
- const resolved = path30.resolve(cwd, normalized);
37081
- if (!resolved.startsWith(cwd + path30.sep) && resolved !== cwd) {
37261
+ const normalized = path31.normalize(relativePath).replace(/^(\.\/)+/, "");
37262
+ const resolved = path31.resolve(cwd, normalized);
37263
+ if (!resolved.startsWith(cwd + path31.sep) && resolved !== cwd) {
37082
37264
  return null;
37083
37265
  }
37084
37266
  return resolved;
@@ -37092,7 +37274,7 @@ async function listDirAsync(relativePath) {
37092
37274
  return { error: "Path is outside working directory" };
37093
37275
  }
37094
37276
  try {
37095
- const names = await fs26.promises.readdir(resolved, { withFileTypes: true });
37277
+ const names = await fs27.promises.readdir(resolved, { withFileTypes: true });
37096
37278
  const visible = names.filter((d) => !d.name.startsWith("."));
37097
37279
  const entries = [];
37098
37280
  for (let i = 0; i < visible.length; i++) {
@@ -37100,12 +37282,12 @@ async function listDirAsync(relativePath) {
37100
37282
  await yieldToEventLoop();
37101
37283
  }
37102
37284
  const d = visible[i];
37103
- const entryPath = path31.join(relativePath || ".", d.name).replace(/\\/g, "/");
37104
- const fullPath = path31.join(resolved, d.name);
37285
+ const entryPath = path32.join(relativePath || ".", d.name).replace(/\\/g, "/");
37286
+ const fullPath = path32.join(resolved, d.name);
37105
37287
  let isDir = d.isDirectory();
37106
37288
  if (d.isSymbolicLink()) {
37107
37289
  try {
37108
- const targetStat = await fs26.promises.stat(fullPath);
37290
+ const targetStat = await fs27.promises.stat(fullPath);
37109
37291
  isDir = targetStat.isDirectory();
37110
37292
  } catch {
37111
37293
  isDir = false;
@@ -37130,25 +37312,25 @@ async function listDirAsync(relativePath) {
37130
37312
  }
37131
37313
 
37132
37314
  // src/files/read-file.ts
37133
- import fs27 from "node:fs";
37315
+ import fs28 from "node:fs";
37134
37316
  import { StringDecoder } from "node:string_decoder";
37135
37317
  function resolveFilePath(relativePath) {
37136
37318
  const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
37137
37319
  if (!resolved) return { error: "Path is outside working directory" };
37138
37320
  let real;
37139
37321
  try {
37140
- real = fs27.realpathSync(resolved);
37322
+ real = fs28.realpathSync(resolved);
37141
37323
  } catch {
37142
37324
  real = resolved;
37143
37325
  }
37144
- const stat3 = fs27.statSync(real);
37326
+ const stat3 = fs28.statSync(real);
37145
37327
  if (!stat3.isFile()) return { error: "Not a file" };
37146
37328
  return real;
37147
37329
  }
37148
37330
  var LINE_CHUNK_SIZE = 64 * 1024;
37149
37331
  function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
37150
- const fileSize = fs27.statSync(filePath).size;
37151
- const fd = fs27.openSync(filePath, "r");
37332
+ const fileSize = fs28.statSync(filePath).size;
37333
+ const fd = fs28.openSync(filePath, "r");
37152
37334
  const bufSize = 64 * 1024;
37153
37335
  const buf = Buffer.alloc(bufSize);
37154
37336
  const decoder = new StringDecoder("utf8");
@@ -37161,7 +37343,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
37161
37343
  let line0Accum = "";
37162
37344
  try {
37163
37345
  let bytesRead;
37164
- while (!done && (bytesRead = fs27.readSync(fd, buf, 0, bufSize, null)) > 0) {
37346
+ while (!done && (bytesRead = fs28.readSync(fd, buf, 0, bufSize, null)) > 0) {
37165
37347
  const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
37166
37348
  partial2 = "";
37167
37349
  let lineStart = 0;
@@ -37296,7 +37478,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
37296
37478
  }
37297
37479
  return { content: resultLines.join("\n"), size: fileSize };
37298
37480
  } finally {
37299
- fs27.closeSync(fd);
37481
+ fs28.closeSync(fd);
37300
37482
  }
37301
37483
  }
37302
37484
  function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
@@ -37307,8 +37489,8 @@ function readFile3(relativePath, startLine, endLine, lineOffset, lineChunkSize =
37307
37489
  if (hasRange) {
37308
37490
  return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
37309
37491
  }
37310
- const stat3 = fs27.statSync(result);
37311
- const raw = fs27.readFileSync(result, "utf8");
37492
+ const stat3 = fs28.statSync(result);
37493
+ const raw = fs28.readFileSync(result, "utf8");
37312
37494
  const lines = raw.split(/\r?\n/);
37313
37495
  return { content: raw, totalLines: lines.length, size: stat3.size };
37314
37496
  } catch (err) {
@@ -37420,12 +37602,14 @@ function handleSkillLayoutRequest(msg, deps) {
37420
37602
  const socket = deps.getWs();
37421
37603
  const id = typeof msg.id === "string" ? msg.id : "";
37422
37604
  const roots = discoverSkillLayoutRoots(getBridgeWorkspaceDirectory());
37423
- socket?.send(JSON.stringify({ type: "skill_layout_response", id, roots }));
37605
+ if (socket) {
37606
+ sendWsMessage(socket, { type: "skill_layout_response", id, roots });
37607
+ }
37424
37608
  }
37425
37609
 
37426
37610
  // src/skills/install-remote-skills.ts
37427
- import fs28 from "node:fs";
37428
- import path32 from "node:path";
37611
+ import fs29 from "node:fs";
37612
+ import path33 from "node:path";
37429
37613
  function installRemoteSkills(cwd, targetDir, items) {
37430
37614
  const installed2 = [];
37431
37615
  if (!Array.isArray(items)) {
@@ -37436,15 +37620,15 @@ function installRemoteSkills(cwd, targetDir, items) {
37436
37620
  if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
37437
37621
  continue;
37438
37622
  }
37439
- const skillDir = path32.join(cwd, targetDir, item.skillName);
37623
+ const skillDir = path33.join(cwd, targetDir, item.skillName);
37440
37624
  for (const f of item.files) {
37441
37625
  if (typeof f.path !== "string" || !f.text && !f.base64) continue;
37442
- const dest = path32.join(skillDir, f.path);
37443
- fs28.mkdirSync(path32.dirname(dest), { recursive: true });
37626
+ const dest = path33.join(skillDir, f.path);
37627
+ fs29.mkdirSync(path33.dirname(dest), { recursive: true });
37444
37628
  if (f.text !== void 0) {
37445
- fs28.writeFileSync(dest, f.text, "utf8");
37629
+ fs29.writeFileSync(dest, f.text, "utf8");
37446
37630
  } else if (f.base64) {
37447
- fs28.writeFileSync(dest, Buffer.from(f.base64, "base64"));
37631
+ fs29.writeFileSync(dest, Buffer.from(f.base64, "base64"));
37448
37632
  }
37449
37633
  }
37450
37634
  installed2.push({
@@ -37470,10 +37654,14 @@ var handleInstallSkillsMessage = (msg, deps) => {
37470
37654
  if (!result.success) {
37471
37655
  const err = result.error ?? "Invalid items";
37472
37656
  deps.log(`[Bridge service] Install skills failed: ${err}`);
37473
- socket?.send(JSON.stringify({ type: "install_skills_result", id, success: false, error: err }));
37657
+ if (socket) {
37658
+ sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
37659
+ }
37474
37660
  return;
37475
37661
  }
37476
- socket?.send(JSON.stringify({ type: "install_skills_result", id, success: true, installed: result.installed }));
37662
+ if (socket) {
37663
+ sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
37664
+ }
37477
37665
  };
37478
37666
 
37479
37667
  // src/bridge/routing/handlers/refresh-local-skills.ts
@@ -37590,7 +37778,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
37590
37778
  };
37591
37779
 
37592
37780
  // src/bridge/routing/handlers/revert-turn-snapshot.ts
37593
- import * as fs29 from "node:fs";
37781
+ import * as fs30 from "node:fs";
37594
37782
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
37595
37783
  const id = typeof msg.id === "string" ? msg.id : "";
37596
37784
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -37602,7 +37790,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
37602
37790
  if (!s) return;
37603
37791
  const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
37604
37792
  const file2 = snapshotFilePath(agentBase, turnId);
37605
- if (!fs29.existsSync(file2)) {
37793
+ if (!fs30.existsSync(file2)) {
37606
37794
  sendWsMessage(s, {
37607
37795
  type: "revert_turn_snapshot_result",
37608
37796
  id,
@@ -37623,7 +37811,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
37623
37811
 
37624
37812
  // src/bridge/routing/handlers/dev-server-control.ts
37625
37813
  var handleDevServerControl = (msg, deps) => {
37626
- let wire = msg;
37814
+ let wire;
37627
37815
  try {
37628
37816
  wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
37629
37817
  } catch (e) {
@@ -37644,9 +37832,7 @@ var handleDevServersConfig = (msg, deps) => {
37644
37832
 
37645
37833
  // src/bridge/routing/dispatch-bridge-message.ts
37646
37834
  function dispatchBridgeMessage(msg, deps) {
37647
- const type = msg.type;
37648
- if (typeof type !== "string") return;
37649
- switch (type) {
37835
+ switch (msg.type) {
37650
37836
  case "auth_token":
37651
37837
  handleAuthToken(msg, deps);
37652
37838
  break;
@@ -37704,15 +37890,14 @@ function dispatchBridgeMessage(msg, deps) {
37704
37890
  case "refresh_local_skills":
37705
37891
  handleRefreshLocalSkills(msg, deps);
37706
37892
  break;
37707
- default:
37708
- deps.log?.(`[Bridge service] unhandled message type: ${type}`);
37709
37893
  }
37710
37894
  }
37711
37895
 
37712
37896
  // src/bridge/routing/handle-bridge-message.ts
37713
37897
  function handleBridgeMessage(data, deps) {
37714
- const msg = data;
37715
37898
  if (!deps.getWs()) return;
37899
+ const msg = parseApiToBridgeMessage(data, deps.log);
37900
+ if (!msg) return;
37716
37901
  setImmediate(() => {
37717
37902
  dispatchBridgeMessage(msg, deps);
37718
37903
  });
@@ -37758,7 +37943,8 @@ function createMainBridgeWebSocketLifecycle(params) {
37758
37943
  tokens,
37759
37944
  persistTokens,
37760
37945
  onAuthInvalid,
37761
- e2ee
37946
+ e2ee,
37947
+ identifyReportedPaths
37762
37948
  } = params;
37763
37949
  let authRefreshInFlight = false;
37764
37950
  function handleOpen() {
@@ -37771,7 +37957,14 @@ function createMainBridgeWebSocketLifecycle(params) {
37771
37957
  }
37772
37958
  const socket = getWs();
37773
37959
  if (socket) {
37774
- sendWsMessage(socket, { type: "identify", role: "cli", ...e2ee ? { e: e2ee.handshake } : {} });
37960
+ sendWsMessage(socket, {
37961
+ type: "identify",
37962
+ role: "cli",
37963
+ cliVersion: CLI_VERSION,
37964
+ bridgeRootPath: identifyReportedPaths.bridgeRootPath,
37965
+ worktreesRootPath: identifyReportedPaths.worktreesRootPath,
37966
+ ...e2ee ? { e: e2ee.handshake } : {}
37967
+ });
37775
37968
  reportGitRepos(getWs, logFn);
37776
37969
  }
37777
37970
  if (justAuthenticated && socket) {
@@ -37897,7 +38090,6 @@ async function createBridgeConnection(options) {
37897
38090
  const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
37898
38091
  const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory, e2ee });
37899
38092
  const onBridgeIdentified = createOnBridgeIdentified({
37900
- sessionWorktreeManager,
37901
38093
  devServerManager,
37902
38094
  firehoseServerUrl,
37903
38095
  workspaceId,
@@ -37919,6 +38111,10 @@ async function createBridgeConnection(options) {
37919
38111
  cloudApiBaseUrl: apiUrl,
37920
38112
  getCloudAccessToken: () => tokens.accessToken
37921
38113
  };
38114
+ const identifyReportedPaths = {
38115
+ bridgeRootPath: path34.resolve(getBridgeWorkspaceDirectory()),
38116
+ worktreesRootPath: path34.resolve(worktreesRootAbs)
38117
+ };
37922
38118
  const { connect } = createMainBridgeWebSocketLifecycle({
37923
38119
  state,
37924
38120
  getWs,
@@ -37930,7 +38126,8 @@ async function createBridgeConnection(options) {
37930
38126
  tokens,
37931
38127
  persistTokens,
37932
38128
  onAuthInvalid,
37933
- e2ee
38129
+ e2ee,
38130
+ identifyReportedPaths
37934
38131
  });
37935
38132
  connect();
37936
38133
  const stopFileIndexWatcher = startFileIndexWatcher(getBridgeWorkspaceDirectory());
@@ -38148,9 +38345,9 @@ async function runCliAction(program2, opts) {
38148
38345
  let authToken = opts.token;
38149
38346
  const firehoseServerUrl = opts.firehoseUrl ?? opts.proxyUrl ?? process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL;
38150
38347
  if (opts.cwd && typeof opts.cwd === "string" && opts.cwd.trim()) {
38151
- const resolvedCwd = path33.resolve(process.cwd(), opts.cwd.trim());
38348
+ const resolvedCwd = path35.resolve(process.cwd(), opts.cwd.trim());
38152
38349
  try {
38153
- const st = fs30.statSync(resolvedCwd);
38350
+ const st = fs31.statSync(resolvedCwd);
38154
38351
  if (!st.isDirectory()) {
38155
38352
  console.error(`--cwd is not a directory: ${resolvedCwd}`);
38156
38353
  process.exit(1);
@@ -38170,7 +38367,7 @@ async function runCliAction(program2, opts) {
38170
38367
  );
38171
38368
  let worktreesRootAbs;
38172
38369
  if (opts.worktreesRoot && opts.worktreesRoot.trim()) {
38173
- worktreesRootAbs = path33.resolve(opts.worktreesRoot.trim());
38370
+ worktreesRootAbs = path35.resolve(opts.worktreesRoot.trim());
38174
38371
  }
38175
38372
  const e2eCertificates = opts.e2eeCertificatesDir?.trim() ? await loadOrCreateE2eCertificates(opts.e2eeCertificatesDir.trim()) : void 0;
38176
38373
  if (e2eCertificates) {
@@ -38213,7 +38410,7 @@ async function runCliAction(program2, opts) {
38213
38410
  // src/cli.ts
38214
38411
  async function main() {
38215
38412
  const program2 = new Command();
38216
- program2.name("buildautomaton").description("CLI for BuildAutomaton: ACP client, WebSocket bridge to backend, and skills (e.g. preview)").version("0.1.0").option("-u, --api-url <url>", "Backend API URL", process.env.BUILDAUTOMATON_API_URL ?? DEFAULT_API_URL).option("-w, --workspace-id <id>", "Workspace ID (or set BUILDAUTOMATON_WORKSPACE_ID)", process.env.BUILDAUTOMATON_WORKSPACE_ID).option("-t, --token <token>", "Auth token (or set BUILDAUTOMATON_AUTH_TOKEN)", process.env.BUILDAUTOMATON_AUTH_TOKEN).option(
38413
+ program2.name("buildautomaton").description("CLI for BuildAutomaton: ACP client, WebSocket bridge to backend, and skills (e.g. preview)").version(CLI_VERSION).option("-u, --api-url <url>", "Backend API URL", process.env.BUILDAUTOMATON_API_URL ?? DEFAULT_API_URL).option("-w, --workspace-id <id>", "Workspace ID (or set BUILDAUTOMATON_WORKSPACE_ID)", process.env.BUILDAUTOMATON_WORKSPACE_ID).option("-t, --token <token>", "Auth token (or set BUILDAUTOMATON_AUTH_TOKEN)", process.env.BUILDAUTOMATON_AUTH_TOKEN).option(
38217
38414
  "--firehose-url <url>",
38218
38415
  "Firehose server URL (default: Fly app; or BUILDAUTOMATON_FIREHOSE_URL / legacy BUILDAUTOMATON_PROXY_URL)",
38219
38416
  process.env.BUILDAUTOMATON_FIREHOSE_URL ?? process.env.BUILDAUTOMATON_PROXY_URL ?? DEFAULT_FIREHOSE_URL
@@ -38222,7 +38419,7 @@ async function main() {
38222
38419
  "Working directory for the bridge (absolute or relative to the current directory); affects skills, git, file index, and agent cwd"
38223
38420
  ).option("-n, --name <name>", "Bridge name when creating via browser (alphanumeric and underscores only)").option(
38224
38421
  "--worktrees-root <path>",
38225
- "Root directory for per-session git worktrees (default: ~/.buildautomaton/worktrees). Whether worktrees are used is controlled in the cloud for each bridge token."
38422
+ "Root directory for per-session git worktrees (default: ~/.buildautomaton/worktrees)."
38226
38423
  ).option(
38227
38424
  "--e2ee-certificates-dir <path>",
38228
38425
  "Directory to load or generate E2EE keys for sessions, files, and logs",