@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/index.js CHANGED
@@ -4065,8 +4065,8 @@ var init_parseUtil = __esm({
4065
4065
  init_errors();
4066
4066
  init_en();
4067
4067
  makeIssue = (params) => {
4068
- const { data, path: path32, errorMaps, issueData } = params;
4069
- const fullPath = [...path32, ...issueData.path || []];
4068
+ const { data, path: path34, errorMaps, issueData } = params;
4069
+ const fullPath = [...path34, ...issueData.path || []];
4070
4070
  const fullIssue = {
4071
4071
  ...issueData,
4072
4072
  path: fullPath
@@ -4374,11 +4374,11 @@ var init_types = __esm({
4374
4374
  init_parseUtil();
4375
4375
  init_util();
4376
4376
  ParseInputLazyPath = class {
4377
- constructor(parent, value, path32, key) {
4377
+ constructor(parent, value, path34, key) {
4378
4378
  this._cachedPath = [];
4379
4379
  this.parent = parent;
4380
4380
  this.data = value;
4381
- this._path = path32;
4381
+ this._path = path34;
4382
4382
  this._key = key;
4383
4383
  }
4384
4384
  get path() {
@@ -7993,10 +7993,10 @@ function assignProp(target, prop, value) {
7993
7993
  configurable: true
7994
7994
  });
7995
7995
  }
7996
- function getElementAtPath(obj, path32) {
7997
- if (!path32)
7996
+ function getElementAtPath(obj, path34) {
7997
+ if (!path34)
7998
7998
  return obj;
7999
- return path32.reduce((acc, key) => acc?.[key], obj);
7999
+ return path34.reduce((acc, key) => acc?.[key], obj);
8000
8000
  }
8001
8001
  function promiseAllObject(promisesObj) {
8002
8002
  const keys = Object.keys(promisesObj);
@@ -8245,11 +8245,11 @@ function aborted(x, startIndex = 0) {
8245
8245
  }
8246
8246
  return false;
8247
8247
  }
8248
- function prefixIssues(path32, issues) {
8248
+ function prefixIssues(path34, issues) {
8249
8249
  return issues.map((iss) => {
8250
8250
  var _a2;
8251
8251
  (_a2 = iss).path ?? (_a2.path = []);
8252
- iss.path.unshift(path32);
8252
+ iss.path.unshift(path34);
8253
8253
  return iss;
8254
8254
  });
8255
8255
  }
@@ -8438,7 +8438,7 @@ function treeifyError(error40, _mapper) {
8438
8438
  return issue2.message;
8439
8439
  };
8440
8440
  const result = { errors: [] };
8441
- const processError = (error41, path32 = []) => {
8441
+ const processError = (error41, path34 = []) => {
8442
8442
  var _a2, _b;
8443
8443
  for (const issue2 of error41.issues) {
8444
8444
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -8448,7 +8448,7 @@ function treeifyError(error40, _mapper) {
8448
8448
  } else if (issue2.code === "invalid_element") {
8449
8449
  processError({ issues: issue2.issues }, issue2.path);
8450
8450
  } else {
8451
- const fullpath = [...path32, ...issue2.path];
8451
+ const fullpath = [...path34, ...issue2.path];
8452
8452
  if (fullpath.length === 0) {
8453
8453
  result.errors.push(mapper(issue2));
8454
8454
  continue;
@@ -8478,9 +8478,9 @@ function treeifyError(error40, _mapper) {
8478
8478
  processError(error40);
8479
8479
  return result;
8480
8480
  }
8481
- function toDotPath(path32) {
8481
+ function toDotPath(path34) {
8482
8482
  const segs = [];
8483
- for (const seg of path32) {
8483
+ for (const seg of path34) {
8484
8484
  if (typeof seg === "number")
8485
8485
  segs.push(`[${seg}]`);
8486
8486
  else if (typeof seg === "symbol")
@@ -20943,8 +20943,8 @@ var init_acp = __esm({
20943
20943
  this.#requestHandler = requestHandler;
20944
20944
  this.#notificationHandler = notificationHandler;
20945
20945
  this.#stream = stream;
20946
- this.#closedPromise = new Promise((resolve15) => {
20947
- this.#abortController.signal.addEventListener("abort", () => resolve15());
20946
+ this.#closedPromise = new Promise((resolve17) => {
20947
+ this.#abortController.signal.addEventListener("abort", () => resolve17());
20948
20948
  });
20949
20949
  this.#receive();
20950
20950
  }
@@ -21093,8 +21093,8 @@ var init_acp = __esm({
21093
21093
  }
21094
21094
  async sendRequest(method, params) {
21095
21095
  const id = this.#nextRequestId++;
21096
- const responsePromise = new Promise((resolve15, reject) => {
21097
- this.#pendingResponses.set(id, { resolve: resolve15, reject });
21096
+ const responsePromise = new Promise((resolve17, reject) => {
21097
+ this.#pendingResponses.set(id, { resolve: resolve17, reject });
21098
21098
  });
21099
21099
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
21100
21100
  return responsePromise;
@@ -21963,10 +21963,10 @@ var require_src2 = __commonJS({
21963
21963
  var fs_1 = __require("fs");
21964
21964
  var debug_1 = __importDefault(require_src());
21965
21965
  var log2 = debug_1.default("@kwsites/file-exists");
21966
- function check2(path32, isFile, isDirectory) {
21967
- log2(`checking %s`, path32);
21966
+ function check2(path34, isFile, isDirectory) {
21967
+ log2(`checking %s`, path34);
21968
21968
  try {
21969
- const stat2 = fs_1.statSync(path32);
21969
+ const stat2 = fs_1.statSync(path34);
21970
21970
  if (stat2.isFile() && isFile) {
21971
21971
  log2(`[OK] path represents a file`);
21972
21972
  return true;
@@ -21986,8 +21986,8 @@ var require_src2 = __commonJS({
21986
21986
  throw e;
21987
21987
  }
21988
21988
  }
21989
- function exists2(path32, type = exports.READABLE) {
21990
- return check2(path32, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
21989
+ function exists2(path34, type = exports.READABLE) {
21990
+ return check2(path34, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
21991
21991
  }
21992
21992
  exports.exists = exists2;
21993
21993
  exports.FILE = 1;
@@ -22413,7 +22413,7 @@ async function createSdkStdioAcpClient(options) {
22413
22413
  child.once("close", (code, signal) => {
22414
22414
  onAgentSubprocessExit?.({ code, signal });
22415
22415
  });
22416
- return new Promise((resolve15, reject) => {
22416
+ return new Promise((resolve17, reject) => {
22417
22417
  let initSettled = false;
22418
22418
  const settleReject = (err) => {
22419
22419
  if (initSettled) return;
@@ -22427,7 +22427,7 @@ async function createSdkStdioAcpClient(options) {
22427
22427
  const settleResolve = (handle) => {
22428
22428
  if (initSettled) return;
22429
22429
  initSettled = true;
22430
- resolve15(handle);
22430
+ resolve17(handle);
22431
22431
  };
22432
22432
  child.on("error", (err) => {
22433
22433
  settleReject(new Error(formatSpawnError(err, command[0])));
@@ -22463,8 +22463,8 @@ async function createSdkStdioAcpClient(options) {
22463
22463
  });
22464
22464
  } catch {
22465
22465
  }
22466
- return await new Promise((resolve16) => {
22467
- pendingPermissionResolvers.set(requestId, resolve16);
22466
+ return await new Promise((resolve18) => {
22467
+ pendingPermissionResolvers.set(requestId, resolve18);
22468
22468
  });
22469
22469
  },
22470
22470
  async readTextFile(params) {
@@ -22572,9 +22572,9 @@ async function createSdkStdioAcpClient(options) {
22572
22572
  }
22573
22573
  },
22574
22574
  async cancel() {
22575
- for (const [id, resolve16] of [...pendingPermissionResolvers.entries()]) {
22575
+ for (const [id, resolve18] of [...pendingPermissionResolvers.entries()]) {
22576
22576
  pendingPermissionResolvers.delete(id);
22577
- resolve16({ outcome: { outcome: "cancelled" } });
22577
+ resolve18({ outcome: { outcome: "cancelled" } });
22578
22578
  }
22579
22579
  try {
22580
22580
  await connection.cancel({ sessionId });
@@ -22590,10 +22590,10 @@ async function createSdkStdioAcpClient(options) {
22590
22590
  }
22591
22591
  },
22592
22592
  resolveRequest(requestId, result) {
22593
- const resolve16 = pendingPermissionResolvers.get(requestId);
22594
- if (!resolve16) return;
22593
+ const resolve18 = pendingPermissionResolvers.get(requestId);
22594
+ if (!resolve18) return;
22595
22595
  pendingPermissionResolvers.delete(requestId);
22596
- resolve16(result);
22596
+ resolve18(result);
22597
22597
  },
22598
22598
  disconnect() {
22599
22599
  child.kill();
@@ -22700,7 +22700,7 @@ async function proxyToLocal(request) {
22700
22700
  };
22701
22701
  const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
22702
22702
  for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
22703
- const once = await new Promise((resolve15) => {
22703
+ const once = await new Promise((resolve17) => {
22704
22704
  const req = mod.request(opts, (res) => {
22705
22705
  const chunks = [];
22706
22706
  res.on("data", (c) => chunks.push(c));
@@ -22711,7 +22711,7 @@ async function proxyToLocal(request) {
22711
22711
  if (typeof v === "string") headers[k] = v;
22712
22712
  else if (Array.isArray(v) && v[0]) headers[k] = v[0];
22713
22713
  }
22714
- resolve15({
22714
+ resolve17({
22715
22715
  id: request.id,
22716
22716
  statusCode: res.statusCode ?? 0,
22717
22717
  headers,
@@ -22720,7 +22720,7 @@ async function proxyToLocal(request) {
22720
22720
  });
22721
22721
  });
22722
22722
  req.on("error", (err) => {
22723
- resolve15({
22723
+ resolve17({
22724
22724
  id: request.id,
22725
22725
  statusCode: 0,
22726
22726
  headers: {},
@@ -22802,8 +22802,8 @@ function randomSecret() {
22802
22802
  }
22803
22803
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
22804
22804
  }
22805
- async function requestPreviewApi(port, secret, method, path32, body) {
22806
- const url2 = `http://127.0.0.1:${port}${path32}`;
22805
+ async function requestPreviewApi(port, secret, method, path34, body) {
22806
+ const url2 = `http://127.0.0.1:${port}${path34}`;
22807
22807
  const headers = {
22808
22808
  [PREVIEW_SECRET_HEADER]: secret,
22809
22809
  "Content-Type": "application/json"
@@ -22815,7 +22815,7 @@ async function requestPreviewApi(port, secret, method, path32, body) {
22815
22815
  });
22816
22816
  const data = await res.json().catch(() => ({}));
22817
22817
  if (!res.ok) {
22818
- throw new Error(data?.error ?? `Preview API ${method} ${path32}: ${res.status}`);
22818
+ throw new Error(data?.error ?? `Preview API ${method} ${path34}: ${res.status}`);
22819
22819
  }
22820
22820
  return data;
22821
22821
  }
@@ -23040,6 +23040,9 @@ function installBridgeProcessResilience() {
23040
23040
  });
23041
23041
  }
23042
23042
 
23043
+ // src/cli-version.ts
23044
+ var CLI_VERSION = "0.1.19".length > 0 ? "0.1.19" : "0.0.0-dev";
23045
+
23043
23046
  // ../../node_modules/.pnpm/open@10.2.0/node_modules/open/index.js
23044
23047
  import process7 from "node:process";
23045
23048
  import { Buffer as Buffer2 } from "node:buffer";
@@ -23473,14 +23476,14 @@ var baseOpen = async (options) => {
23473
23476
  }
23474
23477
  const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
23475
23478
  if (options.wait) {
23476
- return new Promise((resolve15, reject) => {
23479
+ return new Promise((resolve17, reject) => {
23477
23480
  subprocess.once("error", reject);
23478
23481
  subprocess.once("close", (exitCode) => {
23479
23482
  if (!options.allowNonzeroExitCode && exitCode > 0) {
23480
23483
  reject(new Error(`Exited with code ${exitCode}`));
23481
23484
  return;
23482
23485
  }
23483
- resolve15(subprocess);
23486
+ resolve17(subprocess);
23484
23487
  });
23485
23488
  });
23486
23489
  }
@@ -23776,8 +23779,8 @@ function runPendingAuth(options) {
23776
23779
  let hasOpenedBrowser = false;
23777
23780
  let resolved = false;
23778
23781
  let resolveAuth;
23779
- const authPromise = new Promise((resolve15) => {
23780
- resolveAuth = resolve15;
23782
+ const authPromise = new Promise((resolve17) => {
23783
+ resolveAuth = resolve17;
23781
23784
  });
23782
23785
  let reconnectAttempt = 0;
23783
23786
  const signInQuiet = createEmptyReconnectQuietSlot();
@@ -23829,7 +23832,7 @@ function runPendingAuth(options) {
23829
23832
  url: url2,
23830
23833
  onOpen: () => {
23831
23834
  clearQuietOnOpen();
23832
- sendWsMessage(ws, { type: "identify", role: "cli" });
23835
+ sendWsMessage(ws, { type: "identify", role: "cli", cliVersion: CLI_VERSION });
23833
23836
  keepaliveInterval = setInterval(() => {
23834
23837
  if (resolved || !ws || ws.readyState !== 1) return;
23835
23838
  sendWsMessage(ws, { type: "ping", timestamp: Date.now() });
@@ -23899,7 +23902,7 @@ function runPendingAuth(options) {
23899
23902
  async function closeBridgeConnection(state, acpManager, devServerManager, log2) {
23900
23903
  const say = log2 ?? logImmediate;
23901
23904
  say("Cleaning up connections\u2026");
23902
- await new Promise((resolve15) => setImmediate(resolve15));
23905
+ await new Promise((resolve17) => setImmediate(resolve17));
23903
23906
  state.closedByUser = true;
23904
23907
  clearReconnectQuietTimer(state.mainQuiet);
23905
23908
  clearReconnectQuietTimer(state.firehoseQuiet);
@@ -23994,8 +23997,8 @@ function pathspec(...paths) {
23994
23997
  cache.set(key, paths);
23995
23998
  return key;
23996
23999
  }
23997
- function isPathSpec(path32) {
23998
- return path32 instanceof String && cache.has(path32);
24000
+ function isPathSpec(path34) {
24001
+ return path34 instanceof String && cache.has(path34);
23999
24002
  }
24000
24003
  function toPaths(pathSpec) {
24001
24004
  return cache.get(pathSpec) || [];
@@ -24084,8 +24087,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
24084
24087
  function forEachLineWithContent(input, callback) {
24085
24088
  return toLinesWithContent(input, true).map((line) => callback(line));
24086
24089
  }
24087
- function folderExists(path32) {
24088
- return (0, import_file_exists.exists)(path32, import_file_exists.FOLDER);
24090
+ function folderExists(path34) {
24091
+ return (0, import_file_exists.exists)(path34, import_file_exists.FOLDER);
24089
24092
  }
24090
24093
  function append(target, item) {
24091
24094
  if (Array.isArray(target)) {
@@ -24489,8 +24492,8 @@ function checkIsRepoRootTask() {
24489
24492
  commands,
24490
24493
  format: "utf-8",
24491
24494
  onError,
24492
- parser(path32) {
24493
- return /^\.(git)?$/.test(path32.trim());
24495
+ parser(path34) {
24496
+ return /^\.(git)?$/.test(path34.trim());
24494
24497
  }
24495
24498
  };
24496
24499
  }
@@ -24924,11 +24927,11 @@ function parseGrep(grep) {
24924
24927
  const paths = /* @__PURE__ */ new Set();
24925
24928
  const results = {};
24926
24929
  forEachLineWithContent(grep, (input) => {
24927
- const [path32, line, preview] = input.split(NULL);
24928
- paths.add(path32);
24929
- (results[path32] = results[path32] || []).push({
24930
+ const [path34, line, preview] = input.split(NULL);
24931
+ paths.add(path34);
24932
+ (results[path34] = results[path34] || []).push({
24930
24933
  line: asNumber(line),
24931
- path: path32,
24934
+ path: path34,
24932
24935
  preview
24933
24936
  });
24934
24937
  });
@@ -25693,14 +25696,14 @@ var init_hash_object = __esm2({
25693
25696
  init_task();
25694
25697
  }
25695
25698
  });
25696
- function parseInit(bare, path32, text) {
25699
+ function parseInit(bare, path34, text) {
25697
25700
  const response = String(text).trim();
25698
25701
  let result;
25699
25702
  if (result = initResponseRegex.exec(response)) {
25700
- return new InitSummary(bare, path32, false, result[1]);
25703
+ return new InitSummary(bare, path34, false, result[1]);
25701
25704
  }
25702
25705
  if (result = reInitResponseRegex.exec(response)) {
25703
- return new InitSummary(bare, path32, true, result[1]);
25706
+ return new InitSummary(bare, path34, true, result[1]);
25704
25707
  }
25705
25708
  let gitDir = "";
25706
25709
  const tokens = response.split(" ");
@@ -25711,7 +25714,7 @@ function parseInit(bare, path32, text) {
25711
25714
  break;
25712
25715
  }
25713
25716
  }
25714
- return new InitSummary(bare, path32, /^re/i.test(response), gitDir);
25717
+ return new InitSummary(bare, path34, /^re/i.test(response), gitDir);
25715
25718
  }
25716
25719
  var InitSummary;
25717
25720
  var initResponseRegex;
@@ -25720,9 +25723,9 @@ var init_InitSummary = __esm2({
25720
25723
  "src/lib/responses/InitSummary.ts"() {
25721
25724
  "use strict";
25722
25725
  InitSummary = class {
25723
- constructor(bare, path32, existing, gitDir) {
25726
+ constructor(bare, path34, existing, gitDir) {
25724
25727
  this.bare = bare;
25725
- this.path = path32;
25728
+ this.path = path34;
25726
25729
  this.existing = existing;
25727
25730
  this.gitDir = gitDir;
25728
25731
  }
@@ -25734,7 +25737,7 @@ var init_InitSummary = __esm2({
25734
25737
  function hasBareCommand(command) {
25735
25738
  return command.includes(bareCommand);
25736
25739
  }
25737
- function initTask(bare = false, path32, customArgs) {
25740
+ function initTask(bare = false, path34, customArgs) {
25738
25741
  const commands = ["init", ...customArgs];
25739
25742
  if (bare && !hasBareCommand(commands)) {
25740
25743
  commands.splice(1, 0, bareCommand);
@@ -25743,7 +25746,7 @@ function initTask(bare = false, path32, customArgs) {
25743
25746
  commands,
25744
25747
  format: "utf-8",
25745
25748
  parser(text) {
25746
- return parseInit(commands.includes("--bare"), path32, text);
25749
+ return parseInit(commands.includes("--bare"), path34, text);
25747
25750
  }
25748
25751
  };
25749
25752
  }
@@ -26559,12 +26562,12 @@ var init_FileStatusSummary = __esm2({
26559
26562
  "use strict";
26560
26563
  fromPathRegex = /^(.+)\0(.+)$/;
26561
26564
  FileStatusSummary = class {
26562
- constructor(path32, index, working_dir) {
26563
- this.path = path32;
26565
+ constructor(path34, index, working_dir) {
26566
+ this.path = path34;
26564
26567
  this.index = index;
26565
26568
  this.working_dir = working_dir;
26566
26569
  if (index === "R" || working_dir === "R") {
26567
- const detail = fromPathRegex.exec(path32) || [null, path32, path32];
26570
+ const detail = fromPathRegex.exec(path34) || [null, path34, path34];
26568
26571
  this.from = detail[2] || "";
26569
26572
  this.path = detail[1] || "";
26570
26573
  }
@@ -26595,14 +26598,14 @@ function splitLine(result, lineStr) {
26595
26598
  default:
26596
26599
  return;
26597
26600
  }
26598
- function data(index, workingDir, path32) {
26601
+ function data(index, workingDir, path34) {
26599
26602
  const raw = `${index}${workingDir}`;
26600
26603
  const handler = parsers6.get(raw);
26601
26604
  if (handler) {
26602
- handler(result, path32);
26605
+ handler(result, path34);
26603
26606
  }
26604
26607
  if (raw !== "##" && raw !== "!!") {
26605
- result.files.push(new FileStatusSummary(path32, index, workingDir));
26608
+ result.files.push(new FileStatusSummary(path34, index, workingDir));
26606
26609
  }
26607
26610
  }
26608
26611
  }
@@ -26911,9 +26914,9 @@ var init_simple_git_api = __esm2({
26911
26914
  next
26912
26915
  );
26913
26916
  }
26914
- hashObject(path32, write) {
26917
+ hashObject(path34, write) {
26915
26918
  return this._runTask(
26916
- hashObjectTask(path32, write === true),
26919
+ hashObjectTask(path34, write === true),
26917
26920
  trailingFunctionArgument(arguments)
26918
26921
  );
26919
26922
  }
@@ -27266,8 +27269,8 @@ var init_branch = __esm2({
27266
27269
  }
27267
27270
  });
27268
27271
  function toPath(input) {
27269
- const path32 = input.trim().replace(/^["']|["']$/g, "");
27270
- return path32 && normalize2(path32);
27272
+ const path34 = input.trim().replace(/^["']|["']$/g, "");
27273
+ return path34 && normalize2(path34);
27271
27274
  }
27272
27275
  var parseCheckIgnore;
27273
27276
  var init_CheckIgnore = __esm2({
@@ -27581,8 +27584,8 @@ __export2(sub_module_exports, {
27581
27584
  subModuleTask: () => subModuleTask,
27582
27585
  updateSubModuleTask: () => updateSubModuleTask
27583
27586
  });
27584
- function addSubModuleTask(repo, path32) {
27585
- return subModuleTask(["add", repo, path32]);
27587
+ function addSubModuleTask(repo, path34) {
27588
+ return subModuleTask(["add", repo, path34]);
27586
27589
  }
27587
27590
  function initSubModuleTask(customArgs) {
27588
27591
  return subModuleTask(["init", ...customArgs]);
@@ -27915,8 +27918,8 @@ var require_git = __commonJS2({
27915
27918
  }
27916
27919
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
27917
27920
  };
27918
- Git2.prototype.submoduleAdd = function(repo, path32, then) {
27919
- return this._runTask(addSubModuleTask2(repo, path32), trailingFunctionArgument2(arguments));
27921
+ Git2.prototype.submoduleAdd = function(repo, path34, then) {
27922
+ return this._runTask(addSubModuleTask2(repo, path34), trailingFunctionArgument2(arguments));
27920
27923
  };
27921
27924
  Git2.prototype.submoduleUpdate = function(args, then) {
27922
27925
  return this._runTask(
@@ -29048,9 +29051,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
29048
29051
  const rawPath = typeof o.path === "string" ? o.path.trim() : "";
29049
29052
  const summary = typeof o.summary === "string" ? o.summary.trim() : "";
29050
29053
  if (!rawPath || !summary) continue;
29051
- const path32 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
29052
- if (!path32) continue;
29053
- rows.push({ path: path32, summary: clampSummaryToAtMostTwoLines(summary) });
29054
+ const path34 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
29055
+ if (!path34) continue;
29056
+ rows.push({ path: path34, summary: clampSummaryToAtMostTwoLines(summary) });
29054
29057
  }
29055
29058
  return rows;
29056
29059
  }
@@ -29165,9 +29168,9 @@ var GitRepoMetaSchema = external_exports.object({
29165
29168
  // src/agents/acp/put-summarize-change-summaries.ts
29166
29169
  async function putEncryptedChangeSummaryRows(params) {
29167
29170
  const base = params.apiBaseUrl.replace(/\/+$/, "");
29168
- const entries = params.rows.map(({ path: path32, summary }) => {
29171
+ const entries = params.rows.map(({ path: path34, summary }) => {
29169
29172
  const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
29170
- return { path: path32, summary: JSON.stringify(enc) };
29173
+ return { path: path34, summary: JSON.stringify(enc) };
29171
29174
  });
29172
29175
  const res = await fetch(
29173
29176
  `${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
@@ -29510,7 +29513,7 @@ async function createCursorAcpClient(options) {
29510
29513
  });
29511
29514
  const stderrCapture = createStderrCapture(child);
29512
29515
  child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
29513
- return new Promise((resolve15, reject) => {
29516
+ return new Promise((resolve17, reject) => {
29514
29517
  child.on("error", (err) => {
29515
29518
  child.kill();
29516
29519
  reject(new Error(formatSpawnError2(err, command[0])));
@@ -29697,7 +29700,7 @@ async function createCursorAcpClient(options) {
29697
29700
  const newResult = await send("session/new", { cwd, mcpServers: [] });
29698
29701
  const sessionId = newResult?.sessionId ?? "";
29699
29702
  if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
29700
- resolve15({
29703
+ resolve17({
29701
29704
  sessionId,
29702
29705
  async sendPrompt(prompt, _options) {
29703
29706
  promptOutputBuffer = "";
@@ -30765,7 +30768,7 @@ async function createAcpManager(options) {
30765
30768
  }
30766
30769
 
30767
30770
  // src/worktrees/session-worktree-manager.ts
30768
- import * as path16 from "node:path";
30771
+ import * as path17 from "node:path";
30769
30772
  import os4 from "node:os";
30770
30773
 
30771
30774
  // src/worktrees/prepare-new-session-worktrees.ts
@@ -30814,10 +30817,15 @@ function saveWorktreeLayout(layout) {
30814
30817
  function baseNameSafe(abs) {
30815
30818
  return path11.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
30816
30819
  }
30817
- function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
30820
+ function getLauncherDirNameIfPresent(layout, launcherCwdAbs) {
30818
30821
  const norm = path11.resolve(launcherCwdAbs);
30819
30822
  const existing = layout.launcherCwds.find((e) => path11.resolve(e.absolutePath) === norm);
30820
- if (existing) return existing.dirName;
30823
+ return existing?.dirName;
30824
+ }
30825
+ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
30826
+ const existing = getLauncherDirNameIfPresent(layout, launcherCwdAbs);
30827
+ if (existing) return existing;
30828
+ const norm = path11.resolve(launcherCwdAbs);
30821
30829
  const base = baseNameSafe(norm);
30822
30830
  const used = new Set(layout.launcherCwds.map((e) => e.dirName));
30823
30831
  let name = base;
@@ -31595,11 +31603,88 @@ async function commitSessionWorktrees(options) {
31595
31603
  }
31596
31604
  }
31597
31605
 
31606
+ // src/worktrees/discover-session-worktree-on-disk.ts
31607
+ import * as fs17 from "node:fs";
31608
+ import * as path16 from "node:path";
31609
+ function isGitDir(abs) {
31610
+ try {
31611
+ return fs17.existsSync(path16.join(abs, ".git"));
31612
+ } catch {
31613
+ return false;
31614
+ }
31615
+ }
31616
+ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
31617
+ const out = [];
31618
+ const walk = (dir, depth) => {
31619
+ if (depth > maxDepth) return;
31620
+ let entries;
31621
+ try {
31622
+ entries = fs17.readdirSync(dir, { withFileTypes: true });
31623
+ } catch {
31624
+ return;
31625
+ }
31626
+ for (const e of entries) {
31627
+ if (e.name.startsWith(".")) continue;
31628
+ const full = path16.join(dir, e.name);
31629
+ if (!e.isDirectory()) continue;
31630
+ if (e.name === sessionId) {
31631
+ if (isGitDir(full)) out.push(path16.resolve(full));
31632
+ } else {
31633
+ walk(full, depth + 1);
31634
+ }
31635
+ }
31636
+ };
31637
+ walk(root, 0);
31638
+ return out;
31639
+ }
31640
+ function discoverSessionWorktreeOnDisk(options) {
31641
+ const { sessionId, worktreesRootAbs, layout, launcherCwd } = options;
31642
+ if (!sessionId.trim() || !fs17.existsSync(worktreesRootAbs)) return null;
31643
+ const preferredKey = getLauncherDirNameIfPresent(layout, launcherCwd);
31644
+ const keys = [];
31645
+ if (preferredKey) keys.push(preferredKey);
31646
+ try {
31647
+ for (const name of fs17.readdirSync(worktreesRootAbs)) {
31648
+ if (name.startsWith(".")) continue;
31649
+ const p = path16.join(worktreesRootAbs, name);
31650
+ if (!fs17.statSync(p).isDirectory()) continue;
31651
+ if (name !== preferredKey) keys.push(name);
31652
+ }
31653
+ } catch {
31654
+ return null;
31655
+ }
31656
+ for (const key of keys) {
31657
+ const mirrorRoot = path16.join(worktreesRootAbs, key);
31658
+ if (!fs17.existsSync(mirrorRoot) || !fs17.statSync(mirrorRoot).isDirectory()) continue;
31659
+ const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
31660
+ if (worktreePaths.length > 0) {
31661
+ return { agentCwd: path16.resolve(mirrorRoot), worktreePaths };
31662
+ }
31663
+ }
31664
+ return null;
31665
+ }
31666
+ function discoverSessionWorktreesUnderMirrorRoot(mirrorRootAbs, sessionId) {
31667
+ const mirrorRoot = path16.resolve(mirrorRootAbs);
31668
+ if (!sessionId.trim() || !fs17.existsSync(mirrorRoot)) return null;
31669
+ try {
31670
+ if (!fs17.statSync(mirrorRoot).isDirectory()) return null;
31671
+ } catch {
31672
+ return null;
31673
+ }
31674
+ const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
31675
+ if (worktreePaths.length === 0) return null;
31676
+ return { agentCwd: mirrorRoot, worktreePaths };
31677
+ }
31678
+
31598
31679
  // src/worktrees/session-worktree-manager.ts
31680
+ function parseSessionParent(v) {
31681
+ if (v === "bridge_root" || v === "worktrees_root") return v;
31682
+ if (v === "session_worktrees_root") return "worktrees_root";
31683
+ return null;
31684
+ }
31599
31685
  var SessionWorktreeManager = class {
31600
31686
  rootAbs;
31601
31687
  log;
31602
- bridgeWantsWorktrees = false;
31603
31688
  sessionPaths = /* @__PURE__ */ new Map();
31604
31689
  sessionAgentCwd = /* @__PURE__ */ new Map();
31605
31690
  layout;
@@ -31608,22 +31693,67 @@ var SessionWorktreeManager = class {
31608
31693
  this.log = options.log;
31609
31694
  this.layout = loadWorktreeLayout();
31610
31695
  }
31611
- setBridgeSessionWorktrees(enabled) {
31612
- this.bridgeWantsWorktrees = enabled;
31696
+ rememberWorktrees(sessionId, agentCwd, worktreePaths) {
31697
+ this.sessionPaths.set(sessionId, worktreePaths);
31698
+ this.sessionAgentCwd.set(sessionId, path17.resolve(agentCwd));
31613
31699
  }
31614
- effective() {
31615
- return this.bridgeWantsWorktrees;
31700
+ tryDiscoverFromDisk(sessionId) {
31701
+ return discoverSessionWorktreeOnDisk({
31702
+ sessionId,
31703
+ worktreesRootAbs: this.rootAbs,
31704
+ layout: this.layout,
31705
+ launcherCwd: getBridgeWorkspaceDirectory()
31706
+ });
31616
31707
  }
31617
31708
  /**
31618
31709
  * Returns cwd for the agent (mirror of launcher tree), or undefined to use the bridge workspace directory.
31619
31710
  */
31620
31711
  async resolveCwdForPrompt(sessionId, opts) {
31621
- if (!sessionId || !this.effective() || !opts.sessionWorktreesEnabled) {
31712
+ if (!sessionId) return void 0;
31713
+ const parentPathRaw = opts.sessionParentPath?.trim();
31714
+ if (parentPathRaw) {
31715
+ const agentCwd = path17.resolve(parentPathRaw);
31716
+ const sid = sessionId?.trim();
31717
+ if (sid && parseSessionParent(opts.sessionParent) === "worktrees_root") {
31718
+ const fromMirror = discoverSessionWorktreesUnderMirrorRoot(agentCwd, sid);
31719
+ if (fromMirror) this.rememberWorktrees(sid, fromMirror.agentCwd, fromMirror.worktreePaths);
31720
+ }
31721
+ return agentCwd;
31722
+ }
31723
+ const parentKind = parseSessionParent(opts.sessionParent);
31724
+ if (parentKind === "bridge_root") {
31622
31725
  return void 0;
31623
31726
  }
31727
+ if (parentKind === "worktrees_root") {
31728
+ if (!opts.isNewSession) {
31729
+ const cached2 = this.sessionAgentCwd.get(sessionId);
31730
+ if (cached2) return path17.resolve(cached2);
31731
+ const disc = this.tryDiscoverFromDisk(sessionId);
31732
+ if (disc) {
31733
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
31734
+ return path17.resolve(disc.agentCwd);
31735
+ }
31736
+ return void 0;
31737
+ }
31738
+ const prep2 = await prepareNewSessionWorktrees({
31739
+ rootAbs: this.rootAbs,
31740
+ launcherCwd: getBridgeWorkspaceDirectory(),
31741
+ sessionId,
31742
+ layout: this.layout,
31743
+ log: this.log
31744
+ });
31745
+ if (!prep2) return void 0;
31746
+ this.rememberWorktrees(sessionId, prep2.agentCwd, prep2.worktreePaths);
31747
+ return path17.resolve(prep2.agentCwd);
31748
+ }
31624
31749
  if (!opts.isNewSession) {
31625
- const agentCwd = this.sessionAgentCwd.get(sessionId);
31626
- if (agentCwd) return path16.resolve(agentCwd);
31750
+ const cached2 = this.sessionAgentCwd.get(sessionId);
31751
+ if (cached2) return path17.resolve(cached2);
31752
+ const disc = this.tryDiscoverFromDisk(sessionId);
31753
+ if (disc) {
31754
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
31755
+ return path17.resolve(disc.agentCwd);
31756
+ }
31627
31757
  return void 0;
31628
31758
  }
31629
31759
  const prep = await prepareNewSessionWorktrees({
@@ -31634,9 +31764,8 @@ var SessionWorktreeManager = class {
31634
31764
  log: this.log
31635
31765
  });
31636
31766
  if (!prep) return void 0;
31637
- this.sessionPaths.set(sessionId, prep.worktreePaths);
31638
- this.sessionAgentCwd.set(sessionId, prep.agentCwd);
31639
- return path16.resolve(prep.agentCwd);
31767
+ this.rememberWorktrees(sessionId, prep.agentCwd, prep.worktreePaths);
31768
+ return path17.resolve(prep.agentCwd);
31640
31769
  }
31641
31770
  async renameSessionBranch(sessionId, newBranch) {
31642
31771
  const paths = this.sessionPaths.get(sessionId);
@@ -31657,7 +31786,7 @@ var SessionWorktreeManager = class {
31657
31786
  getAgentCwdForSession(sessionId) {
31658
31787
  if (!sessionId) return null;
31659
31788
  const c = this.sessionAgentCwd.get(sessionId);
31660
- return c ? path16.resolve(c) : null;
31789
+ return c ? path17.resolve(c) : null;
31661
31790
  }
31662
31791
  async removeSessionWorktrees(sessionId) {
31663
31792
  const paths = this.sessionPaths.get(sessionId);
@@ -31678,7 +31807,13 @@ var SessionWorktreeManager = class {
31678
31807
  }
31679
31808
  resolveCommitTargets(sessionId) {
31680
31809
  const paths = this.sessionPaths.get(sessionId);
31681
- return paths?.length ? paths : [getBridgeWorkspaceDirectory()];
31810
+ if (paths?.length) return paths;
31811
+ const disc = this.tryDiscoverFromDisk(sessionId);
31812
+ if (disc?.worktreePaths.length) {
31813
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
31814
+ return disc.worktreePaths;
31815
+ }
31816
+ return [getBridgeWorkspaceDirectory()];
31682
31817
  }
31683
31818
  async getSessionWorkingTreeStatus(sessionId) {
31684
31819
  return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
@@ -31705,30 +31840,30 @@ var SessionWorktreeManager = class {
31705
31840
  }
31706
31841
  };
31707
31842
  function defaultWorktreesRootAbs() {
31708
- return path16.join(os4.homedir(), ".buildautomaton", "worktrees");
31843
+ return path17.join(os4.homedir(), ".buildautomaton", "worktrees");
31709
31844
  }
31710
31845
 
31711
31846
  // src/files/watch-file-index.ts
31712
31847
  import { watch } from "node:fs";
31713
- import path23 from "node:path";
31848
+ import path24 from "node:path";
31714
31849
 
31715
31850
  // src/files/index/build-file-index.ts
31716
- import path20 from "node:path";
31851
+ import path21 from "node:path";
31717
31852
 
31718
31853
  // src/runtime/yield-to-event-loop.ts
31719
31854
  function yieldToEventLoop() {
31720
- return new Promise((resolve15) => setImmediate(resolve15));
31855
+ return new Promise((resolve17) => setImmediate(resolve17));
31721
31856
  }
31722
31857
 
31723
31858
  // src/files/index/walk-workspace-tree.ts
31724
- import fs17 from "node:fs";
31725
- import path18 from "node:path";
31859
+ import fs18 from "node:fs";
31860
+ import path19 from "node:path";
31726
31861
 
31727
31862
  // src/files/index/constants.ts
31728
- import path17 from "node:path";
31863
+ import path18 from "node:path";
31729
31864
  import os5 from "node:os";
31730
31865
  var INDEX_WORK_YIELD_EVERY = 256;
31731
- var INDEX_DIR = path17.join(os5.homedir(), ".buildautomaton");
31866
+ var INDEX_DIR = path18.join(os5.homedir(), ".buildautomaton");
31732
31867
  var INDEX_HASH_LEN = 16;
31733
31868
  var INDEX_VERSION = 2;
31734
31869
  var INDEX_LOG_PREFIX = "[file-index]";
@@ -31737,20 +31872,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
31737
31872
  function walkWorkspaceTreeSync(dir, baseDir, out) {
31738
31873
  let names;
31739
31874
  try {
31740
- names = fs17.readdirSync(dir);
31875
+ names = fs18.readdirSync(dir);
31741
31876
  } catch {
31742
31877
  return;
31743
31878
  }
31744
31879
  for (const name of names) {
31745
31880
  if (name.startsWith(".")) continue;
31746
- const full = path18.join(dir, name);
31881
+ const full = path19.join(dir, name);
31747
31882
  let stat2;
31748
31883
  try {
31749
- stat2 = fs17.statSync(full);
31884
+ stat2 = fs18.statSync(full);
31750
31885
  } catch {
31751
31886
  continue;
31752
31887
  }
31753
- const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
31888
+ const relative5 = path19.relative(baseDir, full).replace(/\\/g, "/");
31754
31889
  if (stat2.isDirectory()) {
31755
31890
  walkWorkspaceTreeSync(full, baseDir, out);
31756
31891
  } else if (stat2.isFile()) {
@@ -31761,7 +31896,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
31761
31896
  async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
31762
31897
  let names;
31763
31898
  try {
31764
- names = await fs17.promises.readdir(dir);
31899
+ names = await fs18.promises.readdir(dir);
31765
31900
  } catch {
31766
31901
  return;
31767
31902
  }
@@ -31771,14 +31906,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
31771
31906
  await yieldToEventLoop();
31772
31907
  }
31773
31908
  state.n++;
31774
- const full = path18.join(dir, name);
31909
+ const full = path19.join(dir, name);
31775
31910
  let stat2;
31776
31911
  try {
31777
- stat2 = await fs17.promises.stat(full);
31912
+ stat2 = await fs18.promises.stat(full);
31778
31913
  } catch {
31779
31914
  continue;
31780
31915
  }
31781
- const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
31916
+ const relative5 = path19.relative(baseDir, full).replace(/\\/g, "/");
31782
31917
  if (stat2.isDirectory()) {
31783
31918
  await walkWorkspaceTreeAsync(full, baseDir, out, state);
31784
31919
  } else if (stat2.isFile()) {
@@ -31859,22 +31994,22 @@ async function buildTrigramMapForPathsAsync(paths) {
31859
31994
  }
31860
31995
 
31861
31996
  // src/files/index/write-index-file.ts
31862
- import fs18 from "node:fs";
31997
+ import fs19 from "node:fs";
31863
31998
 
31864
31999
  // src/files/index/paths.ts
31865
- import path19 from "node:path";
32000
+ import path20 from "node:path";
31866
32001
  import crypto2 from "node:crypto";
31867
32002
  function getIndexPathForCwd(resolvedCwd) {
31868
32003
  const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
31869
- return path19.join(INDEX_DIR, `.file-index-${hash}.json`);
32004
+ return path20.join(INDEX_DIR, `.file-index-${hash}.json`);
31870
32005
  }
31871
32006
 
31872
32007
  // src/files/index/write-index-file.ts
31873
32008
  function writeIndexFileSync(resolvedCwd, data) {
31874
32009
  const indexPath = getIndexPathForCwd(resolvedCwd);
31875
32010
  try {
31876
- if (!fs18.existsSync(INDEX_DIR)) fs18.mkdirSync(INDEX_DIR, { recursive: true });
31877
- fs18.writeFileSync(indexPath, JSON.stringify(data), "utf8");
32011
+ if (!fs19.existsSync(INDEX_DIR)) fs19.mkdirSync(INDEX_DIR, { recursive: true });
32012
+ fs19.writeFileSync(indexPath, JSON.stringify(data), "utf8");
31878
32013
  } catch (e) {
31879
32014
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
31880
32015
  }
@@ -31882,8 +32017,8 @@ function writeIndexFileSync(resolvedCwd, data) {
31882
32017
  async function writeIndexFileAsync(resolvedCwd, data) {
31883
32018
  const indexPath = getIndexPathForCwd(resolvedCwd);
31884
32019
  try {
31885
- await fs18.promises.mkdir(INDEX_DIR, { recursive: true });
31886
- await fs18.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
32020
+ await fs19.promises.mkdir(INDEX_DIR, { recursive: true });
32021
+ await fs19.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
31887
32022
  } catch (e) {
31888
32023
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
31889
32024
  }
@@ -31897,7 +32032,7 @@ function sortPaths(paths) {
31897
32032
  paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
31898
32033
  }
31899
32034
  function buildFileIndex(cwd) {
31900
- const resolved = path20.resolve(cwd);
32035
+ const resolved = path21.resolve(cwd);
31901
32036
  const paths = [];
31902
32037
  walkWorkspaceTreeSync(resolved, resolved, paths);
31903
32038
  sortPaths(paths);
@@ -31907,7 +32042,7 @@ function buildFileIndex(cwd) {
31907
32042
  return data;
31908
32043
  }
31909
32044
  async function buildFileIndexAsync(cwd) {
31910
- const resolved = path20.resolve(cwd);
32045
+ const resolved = path21.resolve(cwd);
31911
32046
  const paths = [];
31912
32047
  await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
31913
32048
  await yieldToEventLoop();
@@ -31919,13 +32054,13 @@ async function buildFileIndexAsync(cwd) {
31919
32054
  }
31920
32055
 
31921
32056
  // src/files/index/load-file-index.ts
31922
- import fs19 from "node:fs";
31923
- import path21 from "node:path";
32057
+ import fs20 from "node:fs";
32058
+ import path22 from "node:path";
31924
32059
  function loadFileIndex(cwd) {
31925
- const resolved = path21.resolve(cwd);
32060
+ const resolved = path22.resolve(cwd);
31926
32061
  const indexPath = getIndexPathForCwd(resolved);
31927
32062
  try {
31928
- const raw = fs19.readFileSync(indexPath, "utf8");
32063
+ const raw = fs20.readFileSync(indexPath, "utf8");
31929
32064
  const parsed = JSON.parse(raw);
31930
32065
  if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
31931
32066
  const obj = parsed;
@@ -31944,9 +32079,9 @@ function loadFileIndex(cwd) {
31944
32079
  }
31945
32080
 
31946
32081
  // src/files/index/ensure-file-index.ts
31947
- import path22 from "node:path";
32082
+ import path23 from "node:path";
31948
32083
  async function ensureFileIndexAsync(cwd) {
31949
- const resolved = path22.resolve(cwd);
32084
+ const resolved = path23.resolve(cwd);
31950
32085
  const cached2 = loadFileIndex(resolved);
31951
32086
  if (cached2 !== null) return { data: cached2, fromCache: true };
31952
32087
  const data = await buildFileIndexAsync(resolved);
@@ -32029,7 +32164,7 @@ function createFsWatcher(resolved, schedule) {
32029
32164
  }
32030
32165
  }
32031
32166
  function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
32032
- const resolved = path23.resolve(cwd);
32167
+ const resolved = path24.resolve(cwd);
32033
32168
  void buildFileIndexAsync(resolved).catch((e) => {
32034
32169
  console.error("[file-index] Initial index build failed:", e);
32035
32170
  });
@@ -32056,6 +32191,9 @@ function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
32056
32191
  };
32057
32192
  }
32058
32193
 
32194
+ // src/bridge/connection/create-bridge-connection.ts
32195
+ import * as path33 from "node:path";
32196
+
32059
32197
  // src/dev-servers/manager/dev-server-manager.ts
32060
32198
  import { rm as rm2 } from "node:fs/promises";
32061
32199
 
@@ -32076,15 +32214,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
32076
32214
 
32077
32215
  // src/dev-servers/process/terminate-child-process.ts
32078
32216
  async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
32079
- const exited = new Promise((resolve15) => {
32080
- proc.once("exit", () => resolve15());
32217
+ const exited = new Promise((resolve17) => {
32218
+ proc.once("exit", () => resolve17());
32081
32219
  });
32082
32220
  log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
32083
32221
  try {
32084
32222
  proc.kill("SIGTERM");
32085
32223
  } catch {
32086
32224
  }
32087
- await Promise.race([exited, new Promise((resolve15) => setTimeout(resolve15, graceMs))]);
32225
+ await Promise.race([exited, new Promise((resolve17) => setTimeout(resolve17, graceMs))]);
32088
32226
  }
32089
32227
  function forceKillChild(proc, log2, shortId, graceMs) {
32090
32228
  log2(
@@ -32098,7 +32236,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
32098
32236
  }
32099
32237
 
32100
32238
  // src/dev-servers/process/wire-dev-server-child-process.ts
32101
- import fs20 from "node:fs";
32239
+ import fs21 from "node:fs";
32102
32240
 
32103
32241
  // src/dev-servers/manager/forward-pipe.ts
32104
32242
  function forwardChildPipe(childReadable, terminal, onData) {
@@ -32134,7 +32272,7 @@ function wireDevServerChildProcess(d) {
32134
32272
  d.setPollInterval(void 0);
32135
32273
  return;
32136
32274
  }
32137
- fs20.readFile(d.mergedLogPath, (err, buf) => {
32275
+ fs21.readFile(d.mergedLogPath, (err, buf) => {
32138
32276
  if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
32139
32277
  if (buf.length <= d.mergedReadPos.value) return;
32140
32278
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
@@ -32172,7 +32310,7 @@ ${errTail}` : ""}`);
32172
32310
  d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
32173
32311
  };
32174
32312
  if (mergedPath) {
32175
- fs20.readFile(mergedPath, (err, buf) => {
32313
+ fs21.readFile(mergedPath, (err, buf) => {
32176
32314
  if (!err && buf.length > d.mergedReadPos.value) {
32177
32315
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
32178
32316
  if (chunk.length > 0) {
@@ -32274,13 +32412,13 @@ function parseDevServerDefs(servers) {
32274
32412
  }
32275
32413
 
32276
32414
  // src/dev-servers/manager/shell-spawn/utils.ts
32277
- import fs21 from "node:fs";
32415
+ import fs22 from "node:fs";
32278
32416
  function isSpawnEbadf(e) {
32279
32417
  return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
32280
32418
  }
32281
32419
  function rmDirQuiet(dir) {
32282
32420
  try {
32283
- fs21.rmSync(dir, { recursive: true, force: true });
32421
+ fs22.rmSync(dir, { recursive: true, force: true });
32284
32422
  } catch {
32285
32423
  }
32286
32424
  }
@@ -32288,7 +32426,7 @@ var cachedDevNullReadFd;
32288
32426
  function devNullReadFd() {
32289
32427
  if (cachedDevNullReadFd === void 0) {
32290
32428
  const devPath = process.platform === "win32" ? "nul" : "/dev/null";
32291
- cachedDevNullReadFd = fs21.openSync(devPath, "r");
32429
+ cachedDevNullReadFd = fs22.openSync(devPath, "r");
32292
32430
  }
32293
32431
  return cachedDevNullReadFd;
32294
32432
  }
@@ -32362,15 +32500,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
32362
32500
 
32363
32501
  // src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
32364
32502
  import { spawn as spawn7 } from "node:child_process";
32365
- import fs22 from "node:fs";
32503
+ import fs23 from "node:fs";
32366
32504
  import { tmpdir } from "node:os";
32367
- import path24 from "node:path";
32505
+ import path25 from "node:path";
32368
32506
  function trySpawnMergedLogFile(command, env, cwd, signal) {
32369
- const tmpRoot = fs22.mkdtempSync(path24.join(tmpdir(), "ba-devsrv-log-"));
32370
- const logPath = path24.join(tmpRoot, "combined.log");
32507
+ const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir(), "ba-devsrv-log-"));
32508
+ const logPath = path25.join(tmpRoot, "combined.log");
32371
32509
  let logFd;
32372
32510
  try {
32373
- logFd = fs22.openSync(logPath, "a");
32511
+ logFd = fs23.openSync(logPath, "a");
32374
32512
  } catch {
32375
32513
  rmDirQuiet(tmpRoot);
32376
32514
  return null;
@@ -32389,7 +32527,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
32389
32527
  } else {
32390
32528
  proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
32391
32529
  }
32392
- fs22.closeSync(logFd);
32530
+ fs23.closeSync(logFd);
32393
32531
  return {
32394
32532
  proc,
32395
32533
  pipedStdoutStderr: true,
@@ -32398,7 +32536,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
32398
32536
  };
32399
32537
  } catch (e) {
32400
32538
  try {
32401
- fs22.closeSync(logFd);
32539
+ fs23.closeSync(logFd);
32402
32540
  } catch {
32403
32541
  }
32404
32542
  rmDirQuiet(tmpRoot);
@@ -32409,22 +32547,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
32409
32547
 
32410
32548
  // src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
32411
32549
  import { spawn as spawn8 } from "node:child_process";
32412
- import fs23 from "node:fs";
32550
+ import fs24 from "node:fs";
32413
32551
  import { tmpdir as tmpdir2 } from "node:os";
32414
- import path25 from "node:path";
32552
+ import path26 from "node:path";
32415
32553
  function shSingleQuote(s) {
32416
32554
  return `'${s.replace(/'/g, `'\\''`)}'`;
32417
32555
  }
32418
32556
  function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
32419
- const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
32420
- const logPath = path25.join(tmpRoot, "combined.log");
32421
- const innerPath = path25.join(tmpRoot, "_cmd.sh");
32422
- const runnerPath = path25.join(tmpRoot, "_run.sh");
32557
+ const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir2(), "ba-devsrv-sh-"));
32558
+ const logPath = path26.join(tmpRoot, "combined.log");
32559
+ const innerPath = path26.join(tmpRoot, "_cmd.sh");
32560
+ const runnerPath = path26.join(tmpRoot, "_run.sh");
32423
32561
  try {
32424
- fs23.writeFileSync(innerPath, `#!/bin/sh
32562
+ fs24.writeFileSync(innerPath, `#!/bin/sh
32425
32563
  ${command}
32426
32564
  `);
32427
- fs23.writeFileSync(
32565
+ fs24.writeFileSync(
32428
32566
  runnerPath,
32429
32567
  `#!/bin/sh
32430
32568
  cd ${shSingleQuote(cwd)}
@@ -32450,13 +32588,13 @@ cd ${shSingleQuote(cwd)}
32450
32588
  }
32451
32589
  }
32452
32590
  function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
32453
- const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir2(), "ba-devsrv-sh-"));
32454
- const logPath = path25.join(tmpRoot, "combined.log");
32455
- const runnerPath = path25.join(tmpRoot, "_run.bat");
32591
+ const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir2(), "ba-devsrv-sh-"));
32592
+ const logPath = path26.join(tmpRoot, "combined.log");
32593
+ const runnerPath = path26.join(tmpRoot, "_run.bat");
32456
32594
  const q = (p) => `"${p.replace(/"/g, '""')}"`;
32457
32595
  const com = process.env.ComSpec || "cmd.exe";
32458
32596
  try {
32459
- fs23.writeFileSync(
32597
+ fs24.writeFileSync(
32460
32598
  runnerPath,
32461
32599
  `@ECHO OFF\r
32462
32600
  CD /D ${q(cwd)}\r
@@ -33158,10 +33296,9 @@ function attachFirehoseAfterIdentified(ctx, params) {
33158
33296
 
33159
33297
  // src/bridge/connection/create-bridge-identified-handler.ts
33160
33298
  function createOnBridgeIdentified(opts) {
33161
- const { sessionWorktreeManager, devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
33299
+ const { devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
33162
33300
  const firehoseCtx = { state, devServerManager, logFn };
33163
33301
  return (msg) => {
33164
- sessionWorktreeManager.setBridgeSessionWorktrees(msg.sessionWorktreesEnabled === true);
33165
33302
  const bridgeName = msg.bridgeName;
33166
33303
  const proxyPorts = Array.isArray(msg.proxyPorts) ? msg.proxyPorts : [];
33167
33304
  const devServers = msg.devServers ?? [];
@@ -33180,30 +33317,30 @@ function createOnBridgeIdentified(opts) {
33180
33317
  }
33181
33318
 
33182
33319
  // src/skills/discover-local-agent-skills.ts
33183
- import fs24 from "node:fs";
33184
- import path26 from "node:path";
33320
+ import fs25 from "node:fs";
33321
+ import path27 from "node:path";
33185
33322
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
33186
33323
  function discoverLocalSkills(cwd) {
33187
33324
  const out = [];
33188
33325
  const seenKeys = /* @__PURE__ */ new Set();
33189
33326
  for (const rel of SKILL_DISCOVERY_ROOTS) {
33190
- const base = path26.join(cwd, rel);
33191
- if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
33327
+ const base = path27.join(cwd, rel);
33328
+ if (!fs25.existsSync(base) || !fs25.statSync(base).isDirectory()) continue;
33192
33329
  let entries = [];
33193
33330
  try {
33194
- entries = fs24.readdirSync(base);
33331
+ entries = fs25.readdirSync(base);
33195
33332
  } catch {
33196
33333
  continue;
33197
33334
  }
33198
33335
  for (const name of entries) {
33199
- const dir = path26.join(base, name);
33336
+ const dir = path27.join(base, name);
33200
33337
  try {
33201
- if (!fs24.statSync(dir).isDirectory()) continue;
33338
+ if (!fs25.statSync(dir).isDirectory()) continue;
33202
33339
  } catch {
33203
33340
  continue;
33204
33341
  }
33205
- const skillMd = path26.join(dir, "SKILL.md");
33206
- if (!fs24.existsSync(skillMd)) continue;
33342
+ const skillMd = path27.join(dir, "SKILL.md");
33343
+ if (!fs25.existsSync(skillMd)) continue;
33207
33344
  const key = `${rel}/${name}`;
33208
33345
  if (seenKeys.has(key)) continue;
33209
33346
  seenKeys.add(key);
@@ -33215,23 +33352,23 @@ function discoverLocalSkills(cwd) {
33215
33352
  function discoverSkillLayoutRoots(cwd) {
33216
33353
  const roots = [];
33217
33354
  for (const rel of SKILL_DISCOVERY_ROOTS) {
33218
- const base = path26.join(cwd, rel);
33219
- if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
33355
+ const base = path27.join(cwd, rel);
33356
+ if (!fs25.existsSync(base) || !fs25.statSync(base).isDirectory()) continue;
33220
33357
  let entries = [];
33221
33358
  try {
33222
- entries = fs24.readdirSync(base);
33359
+ entries = fs25.readdirSync(base);
33223
33360
  } catch {
33224
33361
  continue;
33225
33362
  }
33226
33363
  const skills2 = [];
33227
33364
  for (const name of entries) {
33228
- const dir = path26.join(base, name);
33365
+ const dir = path27.join(base, name);
33229
33366
  try {
33230
- if (!fs24.statSync(dir).isDirectory()) continue;
33367
+ if (!fs25.statSync(dir).isDirectory()) continue;
33231
33368
  } catch {
33232
33369
  continue;
33233
33370
  }
33234
- if (!fs24.existsSync(path26.join(dir, "SKILL.md"))) continue;
33371
+ if (!fs25.existsSync(path27.join(dir, "SKILL.md"))) continue;
33235
33372
  const relPath = `${rel}/${name}`.replace(/\\/g, "/");
33236
33373
  skills2.push({ name, relPath });
33237
33374
  }
@@ -33276,7 +33413,7 @@ function createSendLocalSkillsReport(getWs, logFn) {
33276
33413
  const socket = getWs();
33277
33414
  if (!socket || socket.readyState !== wrapper_default.OPEN) return;
33278
33415
  const skills2 = discoverLocalSkills(getBridgeWorkspaceDirectory());
33279
- socket.send(JSON.stringify({ type: "local_skills", skills: skills2 }));
33416
+ sendWsMessage(socket, { type: "local_skills", skills: skills2 });
33280
33417
  } catch (e) {
33281
33418
  logFn(
33282
33419
  `[Bridge service] Local skills report failed: ${e instanceof Error ? e.message : String(e)}`
@@ -33329,6 +33466,41 @@ function reportGitRepos(getWs, log2) {
33329
33466
  });
33330
33467
  }
33331
33468
 
33469
+ // src/types/api-to-bridge-messages.ts
33470
+ var API_TO_BRIDGE_MESSAGE_TYPES = [
33471
+ "auth_token",
33472
+ "bridge_identified",
33473
+ "dev_servers_config",
33474
+ "server_control",
33475
+ "agent_config",
33476
+ "prompt",
33477
+ "session_git_request",
33478
+ "rename_session_branch",
33479
+ "session_archived",
33480
+ "session_discarded",
33481
+ "revert_turn_snapshot",
33482
+ "cancel_run",
33483
+ "cursor_request_response",
33484
+ "skill_call",
33485
+ "file_browser_request",
33486
+ "file_browser_search",
33487
+ "skill_layout_request",
33488
+ "install_skills",
33489
+ "refresh_local_skills"
33490
+ ];
33491
+ var API_TO_BRIDGE_TYPE_SET = new Set(API_TO_BRIDGE_MESSAGE_TYPES);
33492
+ function parseApiToBridgeMessage(data, log2) {
33493
+ if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
33494
+ const t = data.type;
33495
+ if (typeof t !== "string" || !API_TO_BRIDGE_TYPE_SET.has(t)) {
33496
+ if (typeof t === "string") {
33497
+ log2?.(`[Bridge service] unhandled message type: ${t}`);
33498
+ }
33499
+ return null;
33500
+ }
33501
+ return data;
33502
+ }
33503
+
33332
33504
  // src/bridge/routing/handlers/auth-token.ts
33333
33505
  var handleAuthToken = (msg, { log: log2 }) => {
33334
33506
  if (typeof msg.token !== "string") return;
@@ -33339,9 +33511,11 @@ var handleAuthToken = (msg, { log: log2 }) => {
33339
33511
  // src/bridge/routing/handlers/bridge-identified.ts
33340
33512
  var handleBridgeIdentified = (msg, deps) => {
33341
33513
  if (typeof msg.bridgeName !== "string") return;
33342
- deps.onBridgeIdentified(
33343
- msg
33344
- );
33514
+ deps.onBridgeIdentified({
33515
+ bridgeName: msg.bridgeName,
33516
+ proxyPorts: msg.proxyPorts,
33517
+ devServers: msg.devServers
33518
+ });
33345
33519
  setImmediate(() => {
33346
33520
  void (async () => {
33347
33521
  try {
@@ -33376,7 +33550,7 @@ var handleAgentConfigMessage = (msg, deps) => {
33376
33550
  };
33377
33551
 
33378
33552
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
33379
- import * as path28 from "node:path";
33553
+ import * as path29 from "node:path";
33380
33554
 
33381
33555
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
33382
33556
  function createBridgePromptSenders(deps, getWs) {
@@ -33417,7 +33591,7 @@ import { execFile as execFile10 } from "node:child_process";
33417
33591
  import { promisify as promisify10 } from "node:util";
33418
33592
 
33419
33593
  // src/git/bridge-queue-key.ts
33420
- import * as path27 from "node:path";
33594
+ import * as path28 from "node:path";
33421
33595
  import { createHash } from "node:crypto";
33422
33596
  function normalizeCanonicalGitUrl(url2) {
33423
33597
  let s = url2.trim();
@@ -33445,11 +33619,11 @@ function canonicalUrlToRepoIdSync(url2) {
33445
33619
  return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
33446
33620
  }
33447
33621
  function fallbackRepoIdFromPath(absPath) {
33448
- return createHash("sha256").update(path27.resolve(absPath)).digest("hex").slice(0, 32);
33622
+ return createHash("sha256").update(path28.resolve(absPath)).digest("hex").slice(0, 32);
33449
33623
  }
33450
33624
  async function resolveBridgeQueueBindFields(options) {
33451
33625
  const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
33452
- const cwdAbs = worktreePaths.length > 0 ? path27.resolve(worktreePaths[0]) : path27.resolve(effectiveCwd);
33626
+ const cwdAbs = worktreePaths.length > 0 ? path28.resolve(worktreePaths[0]) : path28.resolve(effectiveCwd);
33453
33627
  if (!primaryRepoRoots.length) {
33454
33628
  log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
33455
33629
  return null;
@@ -33510,11 +33684,15 @@ async function runBridgePromptPreamble(params) {
33510
33684
  }
33511
33685
  if (s && sessionId) {
33512
33686
  const cliGitBranch = await readGitBranch(effectiveCwd);
33687
+ const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
33688
+ const mirrorAbs = sessionWorktreeManager.getAgentCwdForSession(sessionId);
33513
33689
  sendWsMessage(s, {
33514
33690
  type: "session_git_context_report",
33515
33691
  sessionId,
33516
33692
  cliGitBranch,
33517
- agentUsesWorktree: sessionWorktreeManager.usesWorktreeSession(sessionId)
33693
+ agentUsesWorktree: usesWt,
33694
+ sessionParent: usesWt ? "worktrees_root" : "bridge_root",
33695
+ sessionParentPath: usesWt ? mirrorAbs : getBridgeWorkspaceDirectory()
33518
33696
  });
33519
33697
  }
33520
33698
  if (s && sessionId && runId) {
@@ -33533,9 +33711,9 @@ function parseChangeSummarySnapshots(raw) {
33533
33711
  for (const item of raw) {
33534
33712
  if (!item || typeof item !== "object") continue;
33535
33713
  const o = item;
33536
- const path32 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
33537
- if (!path32) continue;
33538
- const row = { path: path32 };
33714
+ const path34 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
33715
+ if (!path34) continue;
33716
+ const row = { path: path34 };
33539
33717
  if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
33540
33718
  if (typeof o.oldText === "string") row.oldText = o.oldText;
33541
33719
  if (typeof o.newText === "string") row.newText = o.newText;
@@ -33660,12 +33838,14 @@ function handleBridgePrompt(msg, deps) {
33660
33838
  return;
33661
33839
  }
33662
33840
  const isNewSession = msg.isNewSession === true;
33663
- const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
33841
+ const rawParent = msg.sessionParent;
33842
+ const sessionParent = rawParent === "bridge_root" || rawParent === "worktrees_root" ? rawParent : rawParent === "session_worktrees_root" ? "worktrees_root" : null;
33843
+ const sessionParentPath = typeof msg.sessionParentPath === "string" && msg.sessionParentPath.trim() ? msg.sessionParentPath.trim() : null;
33664
33844
  const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
33665
33845
  const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
33666
33846
  acpManager.logPromptReceivedFromBridge({ agentType, mode });
33667
33847
  async function preambleAndPrompt(resolvedCwd) {
33668
- const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
33848
+ const effectiveCwd = path29.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
33669
33849
  await runBridgePromptPreamble({
33670
33850
  getWs,
33671
33851
  log: log2,
@@ -33708,7 +33888,7 @@ function handleBridgePrompt(msg, deps) {
33708
33888
  e2ee: deps.e2ee
33709
33889
  });
33710
33890
  }
33711
- void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionWorktreesEnabled }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
33891
+ void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionParent, sessionParentPath }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
33712
33892
  log2(`[Agent] Worktree resolve failed: ${err instanceof Error ? err.message : String(err)}`);
33713
33893
  void preambleAndPrompt(void 0);
33714
33894
  });
@@ -33768,26 +33948,28 @@ function handleSkillCall(msg, socket, log2) {
33768
33948
 
33769
33949
  // src/bridge/routing/handlers/skill-call.ts
33770
33950
  var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
33771
- if (!msg.skillId || msg.operationId === void 0) return;
33951
+ const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
33952
+ const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
33953
+ if (!skillId || !operationId) return;
33772
33954
  const socket = getWs();
33773
33955
  if (!socket) return;
33774
33956
  handleSkillCall(
33775
- msg,
33957
+ { id: msg.id, skillId, operationId, params: msg.params },
33776
33958
  socket,
33777
33959
  log2
33778
33960
  );
33779
33961
  };
33780
33962
 
33781
33963
  // src/files/list-dir.ts
33782
- import fs25 from "node:fs";
33783
- import path30 from "node:path";
33964
+ import fs26 from "node:fs";
33965
+ import path31 from "node:path";
33784
33966
 
33785
33967
  // src/files/ensure-under-cwd.ts
33786
- import path29 from "node:path";
33968
+ import path30 from "node:path";
33787
33969
  function ensureUnderCwd(relativePath, cwd = getBridgeWorkspaceDirectory()) {
33788
- const normalized = path29.normalize(relativePath).replace(/^(\.\/)+/, "");
33789
- const resolved = path29.resolve(cwd, normalized);
33790
- if (!resolved.startsWith(cwd + path29.sep) && resolved !== cwd) {
33970
+ const normalized = path30.normalize(relativePath).replace(/^(\.\/)+/, "");
33971
+ const resolved = path30.resolve(cwd, normalized);
33972
+ if (!resolved.startsWith(cwd + path30.sep) && resolved !== cwd) {
33791
33973
  return null;
33792
33974
  }
33793
33975
  return resolved;
@@ -33801,7 +33983,7 @@ async function listDirAsync(relativePath) {
33801
33983
  return { error: "Path is outside working directory" };
33802
33984
  }
33803
33985
  try {
33804
- const names = await fs25.promises.readdir(resolved, { withFileTypes: true });
33986
+ const names = await fs26.promises.readdir(resolved, { withFileTypes: true });
33805
33987
  const visible = names.filter((d) => !d.name.startsWith("."));
33806
33988
  const entries = [];
33807
33989
  for (let i = 0; i < visible.length; i++) {
@@ -33809,12 +33991,12 @@ async function listDirAsync(relativePath) {
33809
33991
  await yieldToEventLoop();
33810
33992
  }
33811
33993
  const d = visible[i];
33812
- const entryPath = path30.join(relativePath || ".", d.name).replace(/\\/g, "/");
33813
- const fullPath = path30.join(resolved, d.name);
33994
+ const entryPath = path31.join(relativePath || ".", d.name).replace(/\\/g, "/");
33995
+ const fullPath = path31.join(resolved, d.name);
33814
33996
  let isDir = d.isDirectory();
33815
33997
  if (d.isSymbolicLink()) {
33816
33998
  try {
33817
- const targetStat = await fs25.promises.stat(fullPath);
33999
+ const targetStat = await fs26.promises.stat(fullPath);
33818
34000
  isDir = targetStat.isDirectory();
33819
34001
  } catch {
33820
34002
  isDir = false;
@@ -33839,25 +34021,25 @@ async function listDirAsync(relativePath) {
33839
34021
  }
33840
34022
 
33841
34023
  // src/files/read-file.ts
33842
- import fs26 from "node:fs";
34024
+ import fs27 from "node:fs";
33843
34025
  import { StringDecoder } from "node:string_decoder";
33844
34026
  function resolveFilePath(relativePath) {
33845
34027
  const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
33846
34028
  if (!resolved) return { error: "Path is outside working directory" };
33847
34029
  let real;
33848
34030
  try {
33849
- real = fs26.realpathSync(resolved);
34031
+ real = fs27.realpathSync(resolved);
33850
34032
  } catch {
33851
34033
  real = resolved;
33852
34034
  }
33853
- const stat2 = fs26.statSync(real);
34035
+ const stat2 = fs27.statSync(real);
33854
34036
  if (!stat2.isFile()) return { error: "Not a file" };
33855
34037
  return real;
33856
34038
  }
33857
34039
  var LINE_CHUNK_SIZE = 64 * 1024;
33858
34040
  function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
33859
- const fileSize = fs26.statSync(filePath).size;
33860
- const fd = fs26.openSync(filePath, "r");
34041
+ const fileSize = fs27.statSync(filePath).size;
34042
+ const fd = fs27.openSync(filePath, "r");
33861
34043
  const bufSize = 64 * 1024;
33862
34044
  const buf = Buffer.alloc(bufSize);
33863
34045
  const decoder = new StringDecoder("utf8");
@@ -33870,7 +34052,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
33870
34052
  let line0Accum = "";
33871
34053
  try {
33872
34054
  let bytesRead;
33873
- while (!done && (bytesRead = fs26.readSync(fd, buf, 0, bufSize, null)) > 0) {
34055
+ while (!done && (bytesRead = fs27.readSync(fd, buf, 0, bufSize, null)) > 0) {
33874
34056
  const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
33875
34057
  partial2 = "";
33876
34058
  let lineStart = 0;
@@ -34005,7 +34187,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
34005
34187
  }
34006
34188
  return { content: resultLines.join("\n"), size: fileSize };
34007
34189
  } finally {
34008
- fs26.closeSync(fd);
34190
+ fs27.closeSync(fd);
34009
34191
  }
34010
34192
  }
34011
34193
  function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
@@ -34016,8 +34198,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
34016
34198
  if (hasRange) {
34017
34199
  return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
34018
34200
  }
34019
- const stat2 = fs26.statSync(result);
34020
- const raw = fs26.readFileSync(result, "utf8");
34201
+ const stat2 = fs27.statSync(result);
34202
+ const raw = fs27.readFileSync(result, "utf8");
34021
34203
  const lines = raw.split(/\r?\n/);
34022
34204
  return { content: raw, totalLines: lines.length, size: stat2.size };
34023
34205
  } catch (err) {
@@ -34129,12 +34311,14 @@ function handleSkillLayoutRequest(msg, deps) {
34129
34311
  const socket = deps.getWs();
34130
34312
  const id = typeof msg.id === "string" ? msg.id : "";
34131
34313
  const roots = discoverSkillLayoutRoots(getBridgeWorkspaceDirectory());
34132
- socket?.send(JSON.stringify({ type: "skill_layout_response", id, roots }));
34314
+ if (socket) {
34315
+ sendWsMessage(socket, { type: "skill_layout_response", id, roots });
34316
+ }
34133
34317
  }
34134
34318
 
34135
34319
  // src/skills/install-remote-skills.ts
34136
- import fs27 from "node:fs";
34137
- import path31 from "node:path";
34320
+ import fs28 from "node:fs";
34321
+ import path32 from "node:path";
34138
34322
  function installRemoteSkills(cwd, targetDir, items) {
34139
34323
  const installed2 = [];
34140
34324
  if (!Array.isArray(items)) {
@@ -34145,15 +34329,15 @@ function installRemoteSkills(cwd, targetDir, items) {
34145
34329
  if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
34146
34330
  continue;
34147
34331
  }
34148
- const skillDir = path31.join(cwd, targetDir, item.skillName);
34332
+ const skillDir = path32.join(cwd, targetDir, item.skillName);
34149
34333
  for (const f of item.files) {
34150
34334
  if (typeof f.path !== "string" || !f.text && !f.base64) continue;
34151
- const dest = path31.join(skillDir, f.path);
34152
- fs27.mkdirSync(path31.dirname(dest), { recursive: true });
34335
+ const dest = path32.join(skillDir, f.path);
34336
+ fs28.mkdirSync(path32.dirname(dest), { recursive: true });
34153
34337
  if (f.text !== void 0) {
34154
- fs27.writeFileSync(dest, f.text, "utf8");
34338
+ fs28.writeFileSync(dest, f.text, "utf8");
34155
34339
  } else if (f.base64) {
34156
- fs27.writeFileSync(dest, Buffer.from(f.base64, "base64"));
34340
+ fs28.writeFileSync(dest, Buffer.from(f.base64, "base64"));
34157
34341
  }
34158
34342
  }
34159
34343
  installed2.push({
@@ -34179,10 +34363,14 @@ var handleInstallSkillsMessage = (msg, deps) => {
34179
34363
  if (!result.success) {
34180
34364
  const err = result.error ?? "Invalid items";
34181
34365
  deps.log(`[Bridge service] Install skills failed: ${err}`);
34182
- socket?.send(JSON.stringify({ type: "install_skills_result", id, success: false, error: err }));
34366
+ if (socket) {
34367
+ sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
34368
+ }
34183
34369
  return;
34184
34370
  }
34185
- socket?.send(JSON.stringify({ type: "install_skills_result", id, success: true, installed: result.installed }));
34371
+ if (socket) {
34372
+ sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
34373
+ }
34186
34374
  };
34187
34375
 
34188
34376
  // src/bridge/routing/handlers/refresh-local-skills.ts
@@ -34299,7 +34487,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
34299
34487
  };
34300
34488
 
34301
34489
  // src/bridge/routing/handlers/revert-turn-snapshot.ts
34302
- import * as fs28 from "node:fs";
34490
+ import * as fs29 from "node:fs";
34303
34491
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
34304
34492
  const id = typeof msg.id === "string" ? msg.id : "";
34305
34493
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -34311,7 +34499,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
34311
34499
  if (!s) return;
34312
34500
  const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
34313
34501
  const file2 = snapshotFilePath(agentBase, turnId);
34314
- if (!fs28.existsSync(file2)) {
34502
+ if (!fs29.existsSync(file2)) {
34315
34503
  sendWsMessage(s, {
34316
34504
  type: "revert_turn_snapshot_result",
34317
34505
  id,
@@ -34332,7 +34520,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
34332
34520
 
34333
34521
  // src/bridge/routing/handlers/dev-server-control.ts
34334
34522
  var handleDevServerControl = (msg, deps) => {
34335
- let wire = msg;
34523
+ let wire;
34336
34524
  try {
34337
34525
  wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
34338
34526
  } catch (e) {
@@ -34353,9 +34541,7 @@ var handleDevServersConfig = (msg, deps) => {
34353
34541
 
34354
34542
  // src/bridge/routing/dispatch-bridge-message.ts
34355
34543
  function dispatchBridgeMessage(msg, deps) {
34356
- const type = msg.type;
34357
- if (typeof type !== "string") return;
34358
- switch (type) {
34544
+ switch (msg.type) {
34359
34545
  case "auth_token":
34360
34546
  handleAuthToken(msg, deps);
34361
34547
  break;
@@ -34413,15 +34599,14 @@ function dispatchBridgeMessage(msg, deps) {
34413
34599
  case "refresh_local_skills":
34414
34600
  handleRefreshLocalSkills(msg, deps);
34415
34601
  break;
34416
- default:
34417
- deps.log?.(`[Bridge service] unhandled message type: ${type}`);
34418
34602
  }
34419
34603
  }
34420
34604
 
34421
34605
  // src/bridge/routing/handle-bridge-message.ts
34422
34606
  function handleBridgeMessage(data, deps) {
34423
- const msg = data;
34424
34607
  if (!deps.getWs()) return;
34608
+ const msg = parseApiToBridgeMessage(data, deps.log);
34609
+ if (!msg) return;
34425
34610
  setImmediate(() => {
34426
34611
  dispatchBridgeMessage(msg, deps);
34427
34612
  });
@@ -34467,7 +34652,8 @@ function createMainBridgeWebSocketLifecycle(params) {
34467
34652
  tokens,
34468
34653
  persistTokens,
34469
34654
  onAuthInvalid,
34470
- e2ee
34655
+ e2ee,
34656
+ identifyReportedPaths
34471
34657
  } = params;
34472
34658
  let authRefreshInFlight = false;
34473
34659
  function handleOpen() {
@@ -34480,7 +34666,14 @@ function createMainBridgeWebSocketLifecycle(params) {
34480
34666
  }
34481
34667
  const socket = getWs();
34482
34668
  if (socket) {
34483
- sendWsMessage(socket, { type: "identify", role: "cli", ...e2ee ? { e: e2ee.handshake } : {} });
34669
+ sendWsMessage(socket, {
34670
+ type: "identify",
34671
+ role: "cli",
34672
+ cliVersion: CLI_VERSION,
34673
+ bridgeRootPath: identifyReportedPaths.bridgeRootPath,
34674
+ worktreesRootPath: identifyReportedPaths.worktreesRootPath,
34675
+ ...e2ee ? { e: e2ee.handshake } : {}
34676
+ });
34484
34677
  reportGitRepos(getWs, logFn);
34485
34678
  }
34486
34679
  if (justAuthenticated && socket) {
@@ -34674,7 +34867,6 @@ async function createBridgeConnection(options) {
34674
34867
  const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
34675
34868
  const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory, e2ee });
34676
34869
  const onBridgeIdentified = createOnBridgeIdentified({
34677
- sessionWorktreeManager,
34678
34870
  devServerManager,
34679
34871
  firehoseServerUrl,
34680
34872
  workspaceId,
@@ -34696,6 +34888,10 @@ async function createBridgeConnection(options) {
34696
34888
  cloudApiBaseUrl: apiUrl,
34697
34889
  getCloudAccessToken: () => tokens.accessToken
34698
34890
  };
34891
+ const identifyReportedPaths = {
34892
+ bridgeRootPath: path33.resolve(getBridgeWorkspaceDirectory()),
34893
+ worktreesRootPath: path33.resolve(worktreesRootAbs)
34894
+ };
34699
34895
  const { connect } = createMainBridgeWebSocketLifecycle({
34700
34896
  state,
34701
34897
  getWs,
@@ -34707,7 +34903,8 @@ async function createBridgeConnection(options) {
34707
34903
  tokens,
34708
34904
  persistTokens,
34709
34905
  onAuthInvalid,
34710
- e2ee
34906
+ e2ee,
34907
+ identifyReportedPaths
34711
34908
  });
34712
34909
  connect();
34713
34910
  const stopFileIndexWatcher = startFileIndexWatcher(getBridgeWorkspaceDirectory());