@buildautomaton/cli 0.1.18 → 0.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2240,7 +2240,7 @@ var require_websocket = __commonJS({
2240
2240
  var http = __require("http");
2241
2241
  var net = __require("net");
2242
2242
  var tls = __require("tls");
2243
- var { randomBytes: randomBytes2, createHash: createHash2 } = __require("crypto");
2243
+ var { randomBytes: randomBytes2, createHash } = __require("crypto");
2244
2244
  var { Duplex, Readable: Readable2 } = __require("stream");
2245
2245
  var { URL: URL2 } = __require("url");
2246
2246
  var PerMessageDeflate = require_permessage_deflate();
@@ -2900,7 +2900,7 @@ var require_websocket = __commonJS({
2900
2900
  abortHandshake(websocket, socket, "Invalid Upgrade header");
2901
2901
  return;
2902
2902
  }
2903
- const digest = createHash2("sha1").update(key + GUID).digest("base64");
2903
+ const digest = createHash("sha1").update(key + GUID).digest("base64");
2904
2904
  if (res.headers["sec-websocket-accept"] !== digest) {
2905
2905
  abortHandshake(websocket, socket, "Invalid Sec-WebSocket-Accept header");
2906
2906
  return;
@@ -3267,7 +3267,7 @@ var require_websocket_server = __commonJS({
3267
3267
  var EventEmitter2 = __require("events");
3268
3268
  var http = __require("http");
3269
3269
  var { Duplex } = __require("stream");
3270
- var { createHash: createHash2 } = __require("crypto");
3270
+ var { createHash } = __require("crypto");
3271
3271
  var extension = require_extension();
3272
3272
  var PerMessageDeflate = require_permessage_deflate();
3273
3273
  var subprotocol = require_subprotocol();
@@ -3568,7 +3568,7 @@ var require_websocket_server = __commonJS({
3568
3568
  );
3569
3569
  }
3570
3570
  if (this._state > RUNNING) return abortHandshake(socket, 503);
3571
- const digest = createHash2("sha1").update(key + GUID).digest("base64");
3571
+ const digest = createHash("sha1").update(key + GUID).digest("base64");
3572
3572
  const headers = [
3573
3573
  "HTTP/1.1 101 Switching Protocols",
3574
3574
  "Upgrade: websocket",
@@ -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((resolve16) => {
20947
+ this.#abortController.signal.addEventListener("abort", () => resolve16());
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((resolve16, reject) => {
21097
+ this.#pendingResponses.set(id, { resolve: resolve16, reject });
21098
21098
  });
21099
21099
  await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
21100
21100
  return responsePromise;
@@ -21669,7 +21669,7 @@ var require_has_flag = __commonJS({
21669
21669
  var require_supports_color = __commonJS({
21670
21670
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
21671
21671
  "use strict";
21672
- var os6 = __require("os");
21672
+ var os7 = __require("os");
21673
21673
  var tty = __require("tty");
21674
21674
  var hasFlag = require_has_flag();
21675
21675
  var { env } = process;
@@ -21717,7 +21717,7 @@ var require_supports_color = __commonJS({
21717
21717
  return min;
21718
21718
  }
21719
21719
  if (process.platform === "win32") {
21720
- const osRelease = os6.release().split(".");
21720
+ const osRelease = os7.release().split(".");
21721
21721
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
21722
21722
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
21723
21723
  }
@@ -21963,10 +21963,10 @@ var require_src2 = __commonJS({
21963
21963
  var fs_1 = __require("fs");
21964
21964
  var debug_1 = __importDefault(require_src());
21965
21965
  var log2 = debug_1.default("@kwsites/file-exists");
21966
- function check2(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((resolve16, 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
+ resolve16(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((resolve17) => {
22467
+ pendingPermissionResolvers.set(requestId, resolve17);
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, resolve17] of [...pendingPermissionResolvers.entries()]) {
22576
22576
  pendingPermissionResolvers.delete(id);
22577
- resolve16({ outcome: { outcome: "cancelled" } });
22577
+ resolve17({ 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 resolve17 = pendingPermissionResolvers.get(requestId);
22594
+ if (!resolve17) return;
22595
22595
  pendingPermissionResolvers.delete(requestId);
22596
- resolve16(result);
22596
+ resolve17(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((resolve16) => {
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
+ resolve16({
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
+ resolve16({
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.20".length > 0 ? "0.1.20" : "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((resolve16, 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
+ resolve16(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((resolve16) => {
23783
+ resolveAuth = resolve16;
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((resolve16) => setImmediate(resolve16));
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(
@@ -28776,18 +28779,7 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
28776
28779
  }
28777
28780
  }
28778
28781
 
28779
- // ../types/dist/index.js
28780
- init_zod();
28781
- init_zod();
28782
- init_zod();
28783
- init_zod();
28784
- init_zod();
28785
- init_zod();
28786
- init_zod();
28787
- init_zod();
28788
- init_zod();
28789
- init_zod();
28790
- init_zod();
28782
+ // ../types/src/work-items.ts
28791
28783
  init_zod();
28792
28784
  var WorkItemStatusSchema = external_exports.enum(["backlog", "in-progress", "completed"]);
28793
28785
  var WorkItemProgressSchema = external_exports.object({
@@ -28828,6 +28820,9 @@ var WorkItemSchema = external_exports.object({
28828
28820
  dependencies: external_exports.array(WorkItemDependencySchema).default([]),
28829
28821
  assignedToUserId: external_exports.string().optional()
28830
28822
  });
28823
+
28824
+ // ../types/src/user-profiles.ts
28825
+ init_zod();
28831
28826
  var UserWorkspaceProfileSchema = external_exports.object({
28832
28827
  id: external_exports.string(),
28833
28828
  workspaceId: external_exports.string(),
@@ -28837,6 +28832,9 @@ var UserWorkspaceProfileSchema = external_exports.object({
28837
28832
  preferences: external_exports.record(external_exports.unknown()).optional(),
28838
28833
  learnings: external_exports.array(external_exports.string())
28839
28834
  });
28835
+
28836
+ // ../types/src/runtime.ts
28837
+ init_zod();
28840
28838
  var WorkspaceOwnerInfoSchema = external_exports.object({
28841
28839
  ownerId: external_exports.string(),
28842
28840
  ownerName: external_exports.string().optional(),
@@ -28850,6 +28848,9 @@ var WorkspaceRuntimeEntrySchema = external_exports.object({
28850
28848
  owner: WorkspaceOwnerInfoSchema.optional(),
28851
28849
  isOwner: external_exports.boolean().optional()
28852
28850
  });
28851
+
28852
+ // ../types/src/agent.ts
28853
+ init_zod();
28853
28854
  var ProjectContextSchema = external_exports.object({
28854
28855
  projectId: external_exports.string(),
28855
28856
  context: external_exports.record(external_exports.unknown()).default({}),
@@ -28874,6 +28875,9 @@ var WebSocketMessageSchema = external_exports.object({
28874
28875
  data: external_exports.any().optional(),
28875
28876
  error: external_exports.string().optional()
28876
28877
  });
28878
+
28879
+ // ../types/src/checkpoints.ts
28880
+ init_zod();
28877
28881
  var CheckpointKindSchema = external_exports.enum(["daily", "weekly", "overall"]);
28878
28882
  var CheckpointSummarySchema = external_exports.object({
28879
28883
  id: external_exports.string(),
@@ -28884,6 +28888,9 @@ var CheckpointSummarySchema = external_exports.object({
28884
28888
  createdAt: external_exports.string(),
28885
28889
  updatedAt: external_exports.string()
28886
28890
  });
28891
+
28892
+ // ../types/src/threads.ts
28893
+ init_zod();
28887
28894
  var ThreadMetaSchema = external_exports.object({
28888
28895
  threadId: external_exports.string(),
28889
28896
  workspaceId: external_exports.string(),
@@ -28911,6 +28918,9 @@ var ThreadMessageSchema = external_exports.object({
28911
28918
  var ThreadCheckpointSummarySchema = CheckpointSummarySchema.extend({
28912
28919
  threadId: external_exports.string()
28913
28920
  });
28921
+
28922
+ // ../types/src/content-items.ts
28923
+ init_zod();
28914
28924
  var ContentSourceSchema = external_exports.enum(["notion", "doc", "slack_thread", "other"]);
28915
28925
  var ContentItemMetaSchema = external_exports.object({
28916
28926
  contentId: external_exports.string(),
@@ -28932,6 +28942,9 @@ var ContentStorageRefSchema = external_exports.object({
28932
28942
  var ContentCheckpointSummarySchema = CheckpointSummarySchema.extend({
28933
28943
  contentId: external_exports.string()
28934
28944
  });
28945
+
28946
+ // ../types/src/stories.ts
28947
+ init_zod();
28935
28948
  var StoryMetaSchema = external_exports.object({
28936
28949
  storyId: external_exports.string(),
28937
28950
  workspaceId: external_exports.string(),
@@ -28954,6 +28967,9 @@ var StoryContentItemRefSchema = external_exports.object({
28954
28967
  var StoryCheckpointSummarySchema = CheckpointSummarySchema.extend({
28955
28968
  storyId: external_exports.string()
28956
28969
  });
28970
+
28971
+ // ../types/src/sessions.ts
28972
+ init_zod();
28957
28973
  var BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID = "__builtin_change_summary__";
28958
28974
  var SessionMetaSchema = external_exports.object({
28959
28975
  sessionId: external_exports.string(),
@@ -28996,6 +29012,8 @@ var SessionThreadRefSchema = external_exports.object({
28996
29012
  threadId: external_exports.string(),
28997
29013
  addedAt: external_exports.string()
28998
29014
  });
29015
+
29016
+ // ../types/src/change-summary-path.ts
28999
29017
  function normalizeRepoRelativePath(p) {
29000
29018
  let t = p.trim().replace(/\\/g, "/");
29001
29019
  while (t.startsWith("./")) t = t.slice(2);
@@ -29012,6 +29030,8 @@ function resolveChangeSummaryPathAgainstAllowed(rawPath, allowed) {
29012
29030
  }
29013
29031
  return null;
29014
29032
  }
29033
+
29034
+ // ../types/src/parse-change-summary-json.ts
29015
29035
  function clampSummaryToAtMostTwoLines(summary) {
29016
29036
  const lines = summary.split(/\r?\n/).map((l) => l.trim()).filter((l) => l.length > 0);
29017
29037
  return lines.slice(0, 2).join("\n");
@@ -29048,12 +29068,14 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
29048
29068
  const rawPath = typeof o.path === "string" ? o.path.trim() : "";
29049
29069
  const summary = typeof o.summary === "string" ? o.summary.trim() : "";
29050
29070
  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) });
29071
+ const path34 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
29072
+ if (!path34) continue;
29073
+ rows.push({ path: path34, summary: clampSummaryToAtMostTwoLines(summary) });
29054
29074
  }
29055
29075
  return rows;
29056
29076
  }
29077
+
29078
+ // ../types/src/build-change-summary-prompt.ts
29057
29079
  var PATCH_PREVIEW_MAX = 12e3;
29058
29080
  function clip(s, max) {
29059
29081
  if (s.length <= max) return s;
@@ -29111,6 +29133,8 @@ function buildSessionChangeSummaryPrompt(files) {
29111
29133
  }
29112
29134
  return lines.join("\n");
29113
29135
  }
29136
+
29137
+ // ../types/src/dedupe-session-file-changes-by-path.ts
29114
29138
  function defaultRichness(c) {
29115
29139
  const patch = typeof c.patchContent === "string" ? c.patchContent.length : 0;
29116
29140
  const nt = typeof c.newText === "string" ? c.newText.length : 0;
@@ -29128,6 +29152,9 @@ function dedupeSessionFileChangesByPath(items, richness = (item) => defaultRichn
29128
29152
  }
29129
29153
  return Array.from(byPath.entries()).sort(([a], [b]) => a.localeCompare(b)).map(([, v]) => v);
29130
29154
  }
29155
+
29156
+ // ../types/src/artifacts.ts
29157
+ init_zod();
29131
29158
  var ArtifactMetaSchema = external_exports.object({
29132
29159
  artifactId: external_exports.string(),
29133
29160
  workspaceId: external_exports.string(),
@@ -29141,6 +29168,9 @@ var ArtifactMetaSchema = external_exports.object({
29141
29168
  createdAt: external_exports.string(),
29142
29169
  updatedAt: external_exports.string()
29143
29170
  });
29171
+
29172
+ // ../types/src/templates.ts
29173
+ init_zod();
29144
29174
  var TemplateMetaSchema = external_exports.object({
29145
29175
  templateId: external_exports.string(),
29146
29176
  workspaceId: external_exports.string(),
@@ -29150,6 +29180,9 @@ var TemplateMetaSchema = external_exports.object({
29150
29180
  createdAt: external_exports.string(),
29151
29181
  updatedAt: external_exports.string()
29152
29182
  });
29183
+
29184
+ // ../types/src/git-repos.ts
29185
+ init_zod();
29153
29186
  var GitRepoMetaSchema = external_exports.object({
29154
29187
  /** Stable id for the repo (e.g. hash of normalized canonical URL). Used for DO idFromName. */
29155
29188
  repoId: external_exports.string(),
@@ -29165,9 +29198,9 @@ var GitRepoMetaSchema = external_exports.object({
29165
29198
  // src/agents/acp/put-summarize-change-summaries.ts
29166
29199
  async function putEncryptedChangeSummaryRows(params) {
29167
29200
  const base = params.apiBaseUrl.replace(/\/+$/, "");
29168
- const entries = params.rows.map(({ path: path32, summary }) => {
29201
+ const entries = params.rows.map(({ path: path34, summary }) => {
29169
29202
  const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
29170
- return { path: path32, summary: JSON.stringify(enc) };
29203
+ return { path: path34, summary: JSON.stringify(enc) };
29171
29204
  });
29172
29205
  const res = await fetch(
29173
29206
  `${base}/api/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
@@ -29510,7 +29543,7 @@ async function createCursorAcpClient(options) {
29510
29543
  });
29511
29544
  const stderrCapture = createStderrCapture(child);
29512
29545
  child.stderr?.on("data", (chunk) => stderrCapture.append(chunk));
29513
- return new Promise((resolve15, reject) => {
29546
+ return new Promise((resolve16, reject) => {
29514
29547
  child.on("error", (err) => {
29515
29548
  child.kill();
29516
29549
  reject(new Error(formatSpawnError2(err, command[0])));
@@ -29697,7 +29730,7 @@ async function createCursorAcpClient(options) {
29697
29730
  const newResult = await send("session/new", { cwd, mcpServers: [] });
29698
29731
  const sessionId = newResult?.sessionId ?? "";
29699
29732
  if (!sessionId) throw new Error("Cursor ACP session/new did not return sessionId");
29700
- resolve15({
29733
+ resolve16({
29701
29734
  sessionId,
29702
29735
  async sendPrompt(prompt, _options) {
29703
29736
  promptOutputBuffer = "";
@@ -30765,7 +30798,7 @@ async function createAcpManager(options) {
30765
30798
  }
30766
30799
 
30767
30800
  // src/worktrees/session-worktree-manager.ts
30768
- import * as path16 from "node:path";
30801
+ import * as path17 from "node:path";
30769
30802
  import os4 from "node:os";
30770
30803
 
30771
30804
  // src/worktrees/prepare-new-session-worktrees.ts
@@ -30814,10 +30847,15 @@ function saveWorktreeLayout(layout) {
30814
30847
  function baseNameSafe(abs) {
30815
30848
  return path11.basename(abs).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
30816
30849
  }
30817
- function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
30850
+ function getLauncherDirNameIfPresent(layout, launcherCwdAbs) {
30818
30851
  const norm = path11.resolve(launcherCwdAbs);
30819
30852
  const existing = layout.launcherCwds.find((e) => path11.resolve(e.absolutePath) === norm);
30820
- if (existing) return existing.dirName;
30853
+ return existing?.dirName;
30854
+ }
30855
+ function allocateDirNameForLauncherCwd(layout, launcherCwdAbs) {
30856
+ const existing = getLauncherDirNameIfPresent(layout, launcherCwdAbs);
30857
+ if (existing) return existing;
30858
+ const norm = path11.resolve(launcherCwdAbs);
30821
30859
  const base = baseNameSafe(norm);
30822
30860
  const used = new Set(layout.launcherCwds.map((e) => e.dirName));
30823
30861
  let name = base;
@@ -31595,11 +31633,88 @@ async function commitSessionWorktrees(options) {
31595
31633
  }
31596
31634
  }
31597
31635
 
31636
+ // src/worktrees/discover-session-worktree-on-disk.ts
31637
+ import * as fs17 from "node:fs";
31638
+ import * as path16 from "node:path";
31639
+ function isGitDir(abs) {
31640
+ try {
31641
+ return fs17.existsSync(path16.join(abs, ".git"));
31642
+ } catch {
31643
+ return false;
31644
+ }
31645
+ }
31646
+ function collectWorktreeRootsNamed(root, sessionId, maxDepth) {
31647
+ const out = [];
31648
+ const walk = (dir, depth) => {
31649
+ if (depth > maxDepth) return;
31650
+ let entries;
31651
+ try {
31652
+ entries = fs17.readdirSync(dir, { withFileTypes: true });
31653
+ } catch {
31654
+ return;
31655
+ }
31656
+ for (const e of entries) {
31657
+ if (e.name.startsWith(".")) continue;
31658
+ const full = path16.join(dir, e.name);
31659
+ if (!e.isDirectory()) continue;
31660
+ if (e.name === sessionId) {
31661
+ if (isGitDir(full)) out.push(path16.resolve(full));
31662
+ } else {
31663
+ walk(full, depth + 1);
31664
+ }
31665
+ }
31666
+ };
31667
+ walk(root, 0);
31668
+ return out;
31669
+ }
31670
+ function discoverSessionWorktreeOnDisk(options) {
31671
+ const { sessionId, worktreesRootAbs, layout, launcherCwd } = options;
31672
+ if (!sessionId.trim() || !fs17.existsSync(worktreesRootAbs)) return null;
31673
+ const preferredKey = getLauncherDirNameIfPresent(layout, launcherCwd);
31674
+ const keys = [];
31675
+ if (preferredKey) keys.push(preferredKey);
31676
+ try {
31677
+ for (const name of fs17.readdirSync(worktreesRootAbs)) {
31678
+ if (name.startsWith(".")) continue;
31679
+ const p = path16.join(worktreesRootAbs, name);
31680
+ if (!fs17.statSync(p).isDirectory()) continue;
31681
+ if (name !== preferredKey) keys.push(name);
31682
+ }
31683
+ } catch {
31684
+ return null;
31685
+ }
31686
+ for (const key of keys) {
31687
+ const mirrorRoot = path16.join(worktreesRootAbs, key);
31688
+ if (!fs17.existsSync(mirrorRoot) || !fs17.statSync(mirrorRoot).isDirectory()) continue;
31689
+ const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
31690
+ if (worktreePaths.length > 0) {
31691
+ return { agentCwd: path16.resolve(mirrorRoot), worktreePaths };
31692
+ }
31693
+ }
31694
+ return null;
31695
+ }
31696
+ function discoverSessionWorktreesUnderMirrorRoot(mirrorRootAbs, sessionId) {
31697
+ const mirrorRoot = path16.resolve(mirrorRootAbs);
31698
+ if (!sessionId.trim() || !fs17.existsSync(mirrorRoot)) return null;
31699
+ try {
31700
+ if (!fs17.statSync(mirrorRoot).isDirectory()) return null;
31701
+ } catch {
31702
+ return null;
31703
+ }
31704
+ const worktreePaths = collectWorktreeRootsNamed(mirrorRoot, sessionId, 24);
31705
+ if (worktreePaths.length === 0) return null;
31706
+ return { agentCwd: mirrorRoot, worktreePaths };
31707
+ }
31708
+
31598
31709
  // src/worktrees/session-worktree-manager.ts
31710
+ function parseSessionParent(v) {
31711
+ if (v === "bridge_root" || v === "worktrees_root") return v;
31712
+ if (v === "session_worktrees_root") return "worktrees_root";
31713
+ return null;
31714
+ }
31599
31715
  var SessionWorktreeManager = class {
31600
31716
  rootAbs;
31601
31717
  log;
31602
- bridgeWantsWorktrees = false;
31603
31718
  sessionPaths = /* @__PURE__ */ new Map();
31604
31719
  sessionAgentCwd = /* @__PURE__ */ new Map();
31605
31720
  layout;
@@ -31608,22 +31723,67 @@ var SessionWorktreeManager = class {
31608
31723
  this.log = options.log;
31609
31724
  this.layout = loadWorktreeLayout();
31610
31725
  }
31611
- setBridgeSessionWorktrees(enabled) {
31612
- this.bridgeWantsWorktrees = enabled;
31726
+ rememberWorktrees(sessionId, agentCwd, worktreePaths) {
31727
+ this.sessionPaths.set(sessionId, worktreePaths);
31728
+ this.sessionAgentCwd.set(sessionId, path17.resolve(agentCwd));
31613
31729
  }
31614
- effective() {
31615
- return this.bridgeWantsWorktrees;
31730
+ tryDiscoverFromDisk(sessionId) {
31731
+ return discoverSessionWorktreeOnDisk({
31732
+ sessionId,
31733
+ worktreesRootAbs: this.rootAbs,
31734
+ layout: this.layout,
31735
+ launcherCwd: getBridgeWorkspaceDirectory()
31736
+ });
31616
31737
  }
31617
31738
  /**
31618
31739
  * Returns cwd for the agent (mirror of launcher tree), or undefined to use the bridge workspace directory.
31619
31740
  */
31620
31741
  async resolveCwdForPrompt(sessionId, opts) {
31621
- if (!sessionId || !this.effective() || !opts.sessionWorktreesEnabled) {
31742
+ if (!sessionId) return void 0;
31743
+ const parentPathRaw = opts.sessionParentPath?.trim();
31744
+ if (parentPathRaw) {
31745
+ const agentCwd = path17.resolve(parentPathRaw);
31746
+ const sid = sessionId?.trim();
31747
+ if (sid && parseSessionParent(opts.sessionParent) === "worktrees_root") {
31748
+ const fromMirror = discoverSessionWorktreesUnderMirrorRoot(agentCwd, sid);
31749
+ if (fromMirror) this.rememberWorktrees(sid, fromMirror.agentCwd, fromMirror.worktreePaths);
31750
+ }
31751
+ return agentCwd;
31752
+ }
31753
+ const parentKind = parseSessionParent(opts.sessionParent);
31754
+ if (parentKind === "bridge_root") {
31622
31755
  return void 0;
31623
31756
  }
31757
+ if (parentKind === "worktrees_root") {
31758
+ if (!opts.isNewSession) {
31759
+ const cached2 = this.sessionAgentCwd.get(sessionId);
31760
+ if (cached2) return path17.resolve(cached2);
31761
+ const disc = this.tryDiscoverFromDisk(sessionId);
31762
+ if (disc) {
31763
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
31764
+ return path17.resolve(disc.agentCwd);
31765
+ }
31766
+ return void 0;
31767
+ }
31768
+ const prep2 = await prepareNewSessionWorktrees({
31769
+ rootAbs: this.rootAbs,
31770
+ launcherCwd: getBridgeWorkspaceDirectory(),
31771
+ sessionId,
31772
+ layout: this.layout,
31773
+ log: this.log
31774
+ });
31775
+ if (!prep2) return void 0;
31776
+ this.rememberWorktrees(sessionId, prep2.agentCwd, prep2.worktreePaths);
31777
+ return path17.resolve(prep2.agentCwd);
31778
+ }
31624
31779
  if (!opts.isNewSession) {
31625
- const agentCwd = this.sessionAgentCwd.get(sessionId);
31626
- if (agentCwd) return path16.resolve(agentCwd);
31780
+ const cached2 = this.sessionAgentCwd.get(sessionId);
31781
+ if (cached2) return path17.resolve(cached2);
31782
+ const disc = this.tryDiscoverFromDisk(sessionId);
31783
+ if (disc) {
31784
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
31785
+ return path17.resolve(disc.agentCwd);
31786
+ }
31627
31787
  return void 0;
31628
31788
  }
31629
31789
  const prep = await prepareNewSessionWorktrees({
@@ -31634,9 +31794,8 @@ var SessionWorktreeManager = class {
31634
31794
  log: this.log
31635
31795
  });
31636
31796
  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);
31797
+ this.rememberWorktrees(sessionId, prep.agentCwd, prep.worktreePaths);
31798
+ return path17.resolve(prep.agentCwd);
31640
31799
  }
31641
31800
  async renameSessionBranch(sessionId, newBranch) {
31642
31801
  const paths = this.sessionPaths.get(sessionId);
@@ -31657,7 +31816,7 @@ var SessionWorktreeManager = class {
31657
31816
  getAgentCwdForSession(sessionId) {
31658
31817
  if (!sessionId) return null;
31659
31818
  const c = this.sessionAgentCwd.get(sessionId);
31660
- return c ? path16.resolve(c) : null;
31819
+ return c ? path17.resolve(c) : null;
31661
31820
  }
31662
31821
  async removeSessionWorktrees(sessionId) {
31663
31822
  const paths = this.sessionPaths.get(sessionId);
@@ -31678,7 +31837,13 @@ var SessionWorktreeManager = class {
31678
31837
  }
31679
31838
  resolveCommitTargets(sessionId) {
31680
31839
  const paths = this.sessionPaths.get(sessionId);
31681
- return paths?.length ? paths : [getBridgeWorkspaceDirectory()];
31840
+ if (paths?.length) return paths;
31841
+ const disc = this.tryDiscoverFromDisk(sessionId);
31842
+ if (disc?.worktreePaths.length) {
31843
+ this.rememberWorktrees(sessionId, disc.agentCwd, disc.worktreePaths);
31844
+ return disc.worktreePaths;
31845
+ }
31846
+ return [getBridgeWorkspaceDirectory()];
31682
31847
  }
31683
31848
  async getSessionWorkingTreeStatus(sessionId) {
31684
31849
  return aggregateSessionPathsWorkingTreeStatus(this.resolveCommitTargets(sessionId));
@@ -31705,30 +31870,30 @@ var SessionWorktreeManager = class {
31705
31870
  }
31706
31871
  };
31707
31872
  function defaultWorktreesRootAbs() {
31708
- return path16.join(os4.homedir(), ".buildautomaton", "worktrees");
31873
+ return path17.join(os4.homedir(), ".buildautomaton", "worktrees");
31709
31874
  }
31710
31875
 
31711
31876
  // src/files/watch-file-index.ts
31712
31877
  import { watch } from "node:fs";
31713
- import path23 from "node:path";
31878
+ import path24 from "node:path";
31714
31879
 
31715
31880
  // src/files/index/build-file-index.ts
31716
- import path20 from "node:path";
31881
+ import path21 from "node:path";
31717
31882
 
31718
31883
  // src/runtime/yield-to-event-loop.ts
31719
31884
  function yieldToEventLoop() {
31720
- return new Promise((resolve15) => setImmediate(resolve15));
31885
+ return new Promise((resolve16) => setImmediate(resolve16));
31721
31886
  }
31722
31887
 
31723
31888
  // src/files/index/walk-workspace-tree.ts
31724
- import fs17 from "node:fs";
31725
- import path18 from "node:path";
31889
+ import fs18 from "node:fs";
31890
+ import path19 from "node:path";
31726
31891
 
31727
31892
  // src/files/index/constants.ts
31728
- import path17 from "node:path";
31893
+ import path18 from "node:path";
31729
31894
  import os5 from "node:os";
31730
31895
  var INDEX_WORK_YIELD_EVERY = 256;
31731
- var INDEX_DIR = path17.join(os5.homedir(), ".buildautomaton");
31896
+ var INDEX_DIR = path18.join(os5.homedir(), ".buildautomaton");
31732
31897
  var INDEX_HASH_LEN = 16;
31733
31898
  var INDEX_VERSION = 2;
31734
31899
  var INDEX_LOG_PREFIX = "[file-index]";
@@ -31737,20 +31902,20 @@ var INDEX_LOG_PREFIX = "[file-index]";
31737
31902
  function walkWorkspaceTreeSync(dir, baseDir, out) {
31738
31903
  let names;
31739
31904
  try {
31740
- names = fs17.readdirSync(dir);
31905
+ names = fs18.readdirSync(dir);
31741
31906
  } catch {
31742
31907
  return;
31743
31908
  }
31744
31909
  for (const name of names) {
31745
31910
  if (name.startsWith(".")) continue;
31746
- const full = path18.join(dir, name);
31911
+ const full = path19.join(dir, name);
31747
31912
  let stat2;
31748
31913
  try {
31749
- stat2 = fs17.statSync(full);
31914
+ stat2 = fs18.statSync(full);
31750
31915
  } catch {
31751
31916
  continue;
31752
31917
  }
31753
- const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
31918
+ const relative5 = path19.relative(baseDir, full).replace(/\\/g, "/");
31754
31919
  if (stat2.isDirectory()) {
31755
31920
  walkWorkspaceTreeSync(full, baseDir, out);
31756
31921
  } else if (stat2.isFile()) {
@@ -31761,7 +31926,7 @@ function walkWorkspaceTreeSync(dir, baseDir, out) {
31761
31926
  async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
31762
31927
  let names;
31763
31928
  try {
31764
- names = await fs17.promises.readdir(dir);
31929
+ names = await fs18.promises.readdir(dir);
31765
31930
  } catch {
31766
31931
  return;
31767
31932
  }
@@ -31771,14 +31936,14 @@ async function walkWorkspaceTreeAsync(dir, baseDir, out, state) {
31771
31936
  await yieldToEventLoop();
31772
31937
  }
31773
31938
  state.n++;
31774
- const full = path18.join(dir, name);
31939
+ const full = path19.join(dir, name);
31775
31940
  let stat2;
31776
31941
  try {
31777
- stat2 = await fs17.promises.stat(full);
31942
+ stat2 = await fs18.promises.stat(full);
31778
31943
  } catch {
31779
31944
  continue;
31780
31945
  }
31781
- const relative5 = path18.relative(baseDir, full).replace(/\\/g, "/");
31946
+ const relative5 = path19.relative(baseDir, full).replace(/\\/g, "/");
31782
31947
  if (stat2.isDirectory()) {
31783
31948
  await walkWorkspaceTreeAsync(full, baseDir, out, state);
31784
31949
  } else if (stat2.isFile()) {
@@ -31859,22 +32024,22 @@ async function buildTrigramMapForPathsAsync(paths) {
31859
32024
  }
31860
32025
 
31861
32026
  // src/files/index/write-index-file.ts
31862
- import fs18 from "node:fs";
32027
+ import fs19 from "node:fs";
31863
32028
 
31864
32029
  // src/files/index/paths.ts
31865
- import path19 from "node:path";
32030
+ import path20 from "node:path";
31866
32031
  import crypto2 from "node:crypto";
31867
32032
  function getIndexPathForCwd(resolvedCwd) {
31868
32033
  const hash = crypto2.createHash("sha256").update(resolvedCwd).digest("hex").slice(0, INDEX_HASH_LEN);
31869
- return path19.join(INDEX_DIR, `.file-index-${hash}.json`);
32034
+ return path20.join(INDEX_DIR, `.file-index-${hash}.json`);
31870
32035
  }
31871
32036
 
31872
32037
  // src/files/index/write-index-file.ts
31873
32038
  function writeIndexFileSync(resolvedCwd, data) {
31874
32039
  const indexPath = getIndexPathForCwd(resolvedCwd);
31875
32040
  try {
31876
- if (!fs18.existsSync(INDEX_DIR)) fs18.mkdirSync(INDEX_DIR, { recursive: true });
31877
- fs18.writeFileSync(indexPath, JSON.stringify(data), "utf8");
32041
+ if (!fs19.existsSync(INDEX_DIR)) fs19.mkdirSync(INDEX_DIR, { recursive: true });
32042
+ fs19.writeFileSync(indexPath, JSON.stringify(data), "utf8");
31878
32043
  } catch (e) {
31879
32044
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
31880
32045
  }
@@ -31882,8 +32047,8 @@ function writeIndexFileSync(resolvedCwd, data) {
31882
32047
  async function writeIndexFileAsync(resolvedCwd, data) {
31883
32048
  const indexPath = getIndexPathForCwd(resolvedCwd);
31884
32049
  try {
31885
- await fs18.promises.mkdir(INDEX_DIR, { recursive: true });
31886
- await fs18.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
32050
+ await fs19.promises.mkdir(INDEX_DIR, { recursive: true });
32051
+ await fs19.promises.writeFile(indexPath, JSON.stringify(data), "utf8");
31887
32052
  } catch (e) {
31888
32053
  console.error(`${INDEX_LOG_PREFIX} Failed to write index:`, e);
31889
32054
  }
@@ -31897,7 +32062,7 @@ function sortPaths(paths) {
31897
32062
  paths.sort((a, b) => a.localeCompare(b, void 0, { sensitivity: "base" }));
31898
32063
  }
31899
32064
  function buildFileIndex(cwd) {
31900
- const resolved = path20.resolve(cwd);
32065
+ const resolved = path21.resolve(cwd);
31901
32066
  const paths = [];
31902
32067
  walkWorkspaceTreeSync(resolved, resolved, paths);
31903
32068
  sortPaths(paths);
@@ -31907,7 +32072,7 @@ function buildFileIndex(cwd) {
31907
32072
  return data;
31908
32073
  }
31909
32074
  async function buildFileIndexAsync(cwd) {
31910
- const resolved = path20.resolve(cwd);
32075
+ const resolved = path21.resolve(cwd);
31911
32076
  const paths = [];
31912
32077
  await walkWorkspaceTreeAsync(resolved, resolved, paths, createWalkYieldState());
31913
32078
  await yieldToEventLoop();
@@ -31919,13 +32084,13 @@ async function buildFileIndexAsync(cwd) {
31919
32084
  }
31920
32085
 
31921
32086
  // src/files/index/load-file-index.ts
31922
- import fs19 from "node:fs";
31923
- import path21 from "node:path";
32087
+ import fs20 from "node:fs";
32088
+ import path22 from "node:path";
31924
32089
  function loadFileIndex(cwd) {
31925
- const resolved = path21.resolve(cwd);
32090
+ const resolved = path22.resolve(cwd);
31926
32091
  const indexPath = getIndexPathForCwd(resolved);
31927
32092
  try {
31928
- const raw = fs19.readFileSync(indexPath, "utf8");
32093
+ const raw = fs20.readFileSync(indexPath, "utf8");
31929
32094
  const parsed = JSON.parse(raw);
31930
32095
  if (parsed !== null && typeof parsed === "object" && Array.isArray(parsed.paths)) {
31931
32096
  const obj = parsed;
@@ -31944,9 +32109,9 @@ function loadFileIndex(cwd) {
31944
32109
  }
31945
32110
 
31946
32111
  // src/files/index/ensure-file-index.ts
31947
- import path22 from "node:path";
32112
+ import path23 from "node:path";
31948
32113
  async function ensureFileIndexAsync(cwd) {
31949
- const resolved = path22.resolve(cwd);
32114
+ const resolved = path23.resolve(cwd);
31950
32115
  const cached2 = loadFileIndex(resolved);
31951
32116
  if (cached2 !== null) return { data: cached2, fromCache: true };
31952
32117
  const data = await buildFileIndexAsync(resolved);
@@ -32029,7 +32194,7 @@ function createFsWatcher(resolved, schedule) {
32029
32194
  }
32030
32195
  }
32031
32196
  function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
32032
- const resolved = path23.resolve(cwd);
32197
+ const resolved = path24.resolve(cwd);
32033
32198
  void buildFileIndexAsync(resolved).catch((e) => {
32034
32199
  console.error("[file-index] Initial index build failed:", e);
32035
32200
  });
@@ -32056,6 +32221,9 @@ function startFileIndexWatcher(cwd = getBridgeWorkspaceDirectory()) {
32056
32221
  };
32057
32222
  }
32058
32223
 
32224
+ // src/bridge/connection/create-bridge-connection.ts
32225
+ import * as path33 from "node:path";
32226
+
32059
32227
  // src/dev-servers/manager/dev-server-manager.ts
32060
32228
  import { rm as rm2 } from "node:fs/promises";
32061
32229
 
@@ -32076,15 +32244,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
32076
32244
 
32077
32245
  // src/dev-servers/process/terminate-child-process.ts
32078
32246
  async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
32079
- const exited = new Promise((resolve15) => {
32080
- proc.once("exit", () => resolve15());
32247
+ const exited = new Promise((resolve16) => {
32248
+ proc.once("exit", () => resolve16());
32081
32249
  });
32082
32250
  log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
32083
32251
  try {
32084
32252
  proc.kill("SIGTERM");
32085
32253
  } catch {
32086
32254
  }
32087
- await Promise.race([exited, new Promise((resolve15) => setTimeout(resolve15, graceMs))]);
32255
+ await Promise.race([exited, new Promise((resolve16) => setTimeout(resolve16, graceMs))]);
32088
32256
  }
32089
32257
  function forceKillChild(proc, log2, shortId, graceMs) {
32090
32258
  log2(
@@ -32098,7 +32266,7 @@ function forceKillChild(proc, log2, shortId, graceMs) {
32098
32266
  }
32099
32267
 
32100
32268
  // src/dev-servers/process/wire-dev-server-child-process.ts
32101
- import fs20 from "node:fs";
32269
+ import fs21 from "node:fs";
32102
32270
 
32103
32271
  // src/dev-servers/manager/forward-pipe.ts
32104
32272
  function forwardChildPipe(childReadable, terminal, onData) {
@@ -32134,7 +32302,7 @@ function wireDevServerChildProcess(d) {
32134
32302
  d.setPollInterval(void 0);
32135
32303
  return;
32136
32304
  }
32137
- fs20.readFile(d.mergedLogPath, (err, buf) => {
32305
+ fs21.readFile(d.mergedLogPath, (err, buf) => {
32138
32306
  if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
32139
32307
  if (buf.length <= d.mergedReadPos.value) return;
32140
32308
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
@@ -32172,7 +32340,7 @@ ${errTail}` : ""}`);
32172
32340
  d.sendStatus(code === 0 || code == null ? "stopped" : "error", detail, tails);
32173
32341
  };
32174
32342
  if (mergedPath) {
32175
- fs20.readFile(mergedPath, (err, buf) => {
32343
+ fs21.readFile(mergedPath, (err, buf) => {
32176
32344
  if (!err && buf.length > d.mergedReadPos.value) {
32177
32345
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
32178
32346
  if (chunk.length > 0) {
@@ -32274,13 +32442,13 @@ function parseDevServerDefs(servers) {
32274
32442
  }
32275
32443
 
32276
32444
  // src/dev-servers/manager/shell-spawn/utils.ts
32277
- import fs21 from "node:fs";
32445
+ import fs22 from "node:fs";
32278
32446
  function isSpawnEbadf(e) {
32279
32447
  return typeof e === "object" && e !== null && "code" in e && e.code === "EBADF";
32280
32448
  }
32281
32449
  function rmDirQuiet(dir) {
32282
32450
  try {
32283
- fs21.rmSync(dir, { recursive: true, force: true });
32451
+ fs22.rmSync(dir, { recursive: true, force: true });
32284
32452
  } catch {
32285
32453
  }
32286
32454
  }
@@ -32288,7 +32456,7 @@ var cachedDevNullReadFd;
32288
32456
  function devNullReadFd() {
32289
32457
  if (cachedDevNullReadFd === void 0) {
32290
32458
  const devPath = process.platform === "win32" ? "nul" : "/dev/null";
32291
- cachedDevNullReadFd = fs21.openSync(devPath, "r");
32459
+ cachedDevNullReadFd = fs22.openSync(devPath, "r");
32292
32460
  }
32293
32461
  return cachedDevNullReadFd;
32294
32462
  }
@@ -32362,15 +32530,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
32362
32530
 
32363
32531
  // src/dev-servers/manager/shell-spawn/try-spawn-merged-log-file.ts
32364
32532
  import { spawn as spawn7 } from "node:child_process";
32365
- import fs22 from "node:fs";
32533
+ import fs23 from "node:fs";
32366
32534
  import { tmpdir } from "node:os";
32367
- import path24 from "node:path";
32535
+ import path25 from "node:path";
32368
32536
  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");
32537
+ const tmpRoot = fs23.mkdtempSync(path25.join(tmpdir(), "ba-devsrv-log-"));
32538
+ const logPath = path25.join(tmpRoot, "combined.log");
32371
32539
  let logFd;
32372
32540
  try {
32373
- logFd = fs22.openSync(logPath, "a");
32541
+ logFd = fs23.openSync(logPath, "a");
32374
32542
  } catch {
32375
32543
  rmDirQuiet(tmpRoot);
32376
32544
  return null;
@@ -32389,7 +32557,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
32389
32557
  } else {
32390
32558
  proc = spawn7("/bin/sh", ["-c", command], { env, cwd, stdio, ...signal ? { signal } : {} });
32391
32559
  }
32392
- fs22.closeSync(logFd);
32560
+ fs23.closeSync(logFd);
32393
32561
  return {
32394
32562
  proc,
32395
32563
  pipedStdoutStderr: true,
@@ -32398,7 +32566,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
32398
32566
  };
32399
32567
  } catch (e) {
32400
32568
  try {
32401
- fs22.closeSync(logFd);
32569
+ fs23.closeSync(logFd);
32402
32570
  } catch {
32403
32571
  }
32404
32572
  rmDirQuiet(tmpRoot);
@@ -32409,22 +32577,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
32409
32577
 
32410
32578
  // src/dev-servers/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
32411
32579
  import { spawn as spawn8 } from "node:child_process";
32412
- import fs23 from "node:fs";
32580
+ import fs24 from "node:fs";
32413
32581
  import { tmpdir as tmpdir2 } from "node:os";
32414
- import path25 from "node:path";
32582
+ import path26 from "node:path";
32415
32583
  function shSingleQuote(s) {
32416
32584
  return `'${s.replace(/'/g, `'\\''`)}'`;
32417
32585
  }
32418
32586
  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");
32587
+ const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir2(), "ba-devsrv-sh-"));
32588
+ const logPath = path26.join(tmpRoot, "combined.log");
32589
+ const innerPath = path26.join(tmpRoot, "_cmd.sh");
32590
+ const runnerPath = path26.join(tmpRoot, "_run.sh");
32423
32591
  try {
32424
- fs23.writeFileSync(innerPath, `#!/bin/sh
32592
+ fs24.writeFileSync(innerPath, `#!/bin/sh
32425
32593
  ${command}
32426
32594
  `);
32427
- fs23.writeFileSync(
32595
+ fs24.writeFileSync(
32428
32596
  runnerPath,
32429
32597
  `#!/bin/sh
32430
32598
  cd ${shSingleQuote(cwd)}
@@ -32450,13 +32618,13 @@ cd ${shSingleQuote(cwd)}
32450
32618
  }
32451
32619
  }
32452
32620
  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");
32621
+ const tmpRoot = fs24.mkdtempSync(path26.join(tmpdir2(), "ba-devsrv-sh-"));
32622
+ const logPath = path26.join(tmpRoot, "combined.log");
32623
+ const runnerPath = path26.join(tmpRoot, "_run.bat");
32456
32624
  const q = (p) => `"${p.replace(/"/g, '""')}"`;
32457
32625
  const com = process.env.ComSpec || "cmd.exe";
32458
32626
  try {
32459
- fs23.writeFileSync(
32627
+ fs24.writeFileSync(
32460
32628
  runnerPath,
32461
32629
  `@ECHO OFF\r
32462
32630
  CD /D ${q(cwd)}\r
@@ -33158,10 +33326,9 @@ function attachFirehoseAfterIdentified(ctx, params) {
33158
33326
 
33159
33327
  // src/bridge/connection/create-bridge-identified-handler.ts
33160
33328
  function createOnBridgeIdentified(opts) {
33161
- const { sessionWorktreeManager, devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
33329
+ const { devServerManager, firehoseServerUrl, workspaceId, state, logFn } = opts;
33162
33330
  const firehoseCtx = { state, devServerManager, logFn };
33163
33331
  return (msg) => {
33164
- sessionWorktreeManager.setBridgeSessionWorktrees(msg.sessionWorktreesEnabled === true);
33165
33332
  const bridgeName = msg.bridgeName;
33166
33333
  const proxyPorts = Array.isArray(msg.proxyPorts) ? msg.proxyPorts : [];
33167
33334
  const devServers = msg.devServers ?? [];
@@ -33180,30 +33347,30 @@ function createOnBridgeIdentified(opts) {
33180
33347
  }
33181
33348
 
33182
33349
  // src/skills/discover-local-agent-skills.ts
33183
- import fs24 from "node:fs";
33184
- import path26 from "node:path";
33350
+ import fs25 from "node:fs";
33351
+ import path27 from "node:path";
33185
33352
  var SKILL_DISCOVERY_ROOTS = [".agents/skills", ".claude/skills", ".cursor/skills", "skills"];
33186
33353
  function discoverLocalSkills(cwd) {
33187
33354
  const out = [];
33188
33355
  const seenKeys = /* @__PURE__ */ new Set();
33189
33356
  for (const rel of SKILL_DISCOVERY_ROOTS) {
33190
- const base = path26.join(cwd, rel);
33191
- if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
33357
+ const base = path27.join(cwd, rel);
33358
+ if (!fs25.existsSync(base) || !fs25.statSync(base).isDirectory()) continue;
33192
33359
  let entries = [];
33193
33360
  try {
33194
- entries = fs24.readdirSync(base);
33361
+ entries = fs25.readdirSync(base);
33195
33362
  } catch {
33196
33363
  continue;
33197
33364
  }
33198
33365
  for (const name of entries) {
33199
- const dir = path26.join(base, name);
33366
+ const dir = path27.join(base, name);
33200
33367
  try {
33201
- if (!fs24.statSync(dir).isDirectory()) continue;
33368
+ if (!fs25.statSync(dir).isDirectory()) continue;
33202
33369
  } catch {
33203
33370
  continue;
33204
33371
  }
33205
- const skillMd = path26.join(dir, "SKILL.md");
33206
- if (!fs24.existsSync(skillMd)) continue;
33372
+ const skillMd = path27.join(dir, "SKILL.md");
33373
+ if (!fs25.existsSync(skillMd)) continue;
33207
33374
  const key = `${rel}/${name}`;
33208
33375
  if (seenKeys.has(key)) continue;
33209
33376
  seenKeys.add(key);
@@ -33215,23 +33382,23 @@ function discoverLocalSkills(cwd) {
33215
33382
  function discoverSkillLayoutRoots(cwd) {
33216
33383
  const roots = [];
33217
33384
  for (const rel of SKILL_DISCOVERY_ROOTS) {
33218
- const base = path26.join(cwd, rel);
33219
- if (!fs24.existsSync(base) || !fs24.statSync(base).isDirectory()) continue;
33385
+ const base = path27.join(cwd, rel);
33386
+ if (!fs25.existsSync(base) || !fs25.statSync(base).isDirectory()) continue;
33220
33387
  let entries = [];
33221
33388
  try {
33222
- entries = fs24.readdirSync(base);
33389
+ entries = fs25.readdirSync(base);
33223
33390
  } catch {
33224
33391
  continue;
33225
33392
  }
33226
33393
  const skills2 = [];
33227
33394
  for (const name of entries) {
33228
- const dir = path26.join(base, name);
33395
+ const dir = path27.join(base, name);
33229
33396
  try {
33230
- if (!fs24.statSync(dir).isDirectory()) continue;
33397
+ if (!fs25.statSync(dir).isDirectory()) continue;
33231
33398
  } catch {
33232
33399
  continue;
33233
33400
  }
33234
- if (!fs24.existsSync(path26.join(dir, "SKILL.md"))) continue;
33401
+ if (!fs25.existsSync(path27.join(dir, "SKILL.md"))) continue;
33235
33402
  const relPath = `${rel}/${name}`.replace(/\\/g, "/");
33236
33403
  skills2.push({ name, relPath });
33237
33404
  }
@@ -33276,7 +33443,7 @@ function createSendLocalSkillsReport(getWs, logFn) {
33276
33443
  const socket = getWs();
33277
33444
  if (!socket || socket.readyState !== wrapper_default.OPEN) return;
33278
33445
  const skills2 = discoverLocalSkills(getBridgeWorkspaceDirectory());
33279
- socket.send(JSON.stringify({ type: "local_skills", skills: skills2 }));
33446
+ sendWsMessage(socket, { type: "local_skills", skills: skills2 });
33280
33447
  } catch (e) {
33281
33448
  logFn(
33282
33449
  `[Bridge service] Local skills report failed: ${e instanceof Error ? e.message : String(e)}`
@@ -33329,6 +33496,42 @@ function reportGitRepos(getWs, log2) {
33329
33496
  });
33330
33497
  }
33331
33498
 
33499
+ // src/types/api-to-bridge-messages.ts
33500
+ var API_TO_BRIDGE_MESSAGE_TYPES = [
33501
+ "auth_token",
33502
+ "bridge_identified",
33503
+ "dev_servers_config",
33504
+ "server_control",
33505
+ "agent_config",
33506
+ "prompt_queue_state",
33507
+ "prompt",
33508
+ "session_git_request",
33509
+ "rename_session_branch",
33510
+ "session_archived",
33511
+ "session_discarded",
33512
+ "revert_turn_snapshot",
33513
+ "cancel_run",
33514
+ "cursor_request_response",
33515
+ "skill_call",
33516
+ "file_browser_request",
33517
+ "file_browser_search",
33518
+ "skill_layout_request",
33519
+ "install_skills",
33520
+ "refresh_local_skills"
33521
+ ];
33522
+ var API_TO_BRIDGE_TYPE_SET = new Set(API_TO_BRIDGE_MESSAGE_TYPES);
33523
+ function parseApiToBridgeMessage(data, log2) {
33524
+ if (data === null || typeof data !== "object" || Array.isArray(data)) return null;
33525
+ const t = data.type;
33526
+ if (typeof t !== "string" || !API_TO_BRIDGE_TYPE_SET.has(t)) {
33527
+ if (typeof t === "string") {
33528
+ log2?.(`[Bridge service] unhandled message type: ${t}`);
33529
+ }
33530
+ return null;
33531
+ }
33532
+ return data;
33533
+ }
33534
+
33332
33535
  // src/bridge/routing/handlers/auth-token.ts
33333
33536
  var handleAuthToken = (msg, { log: log2 }) => {
33334
33537
  if (typeof msg.token !== "string") return;
@@ -33339,9 +33542,11 @@ var handleAuthToken = (msg, { log: log2 }) => {
33339
33542
  // src/bridge/routing/handlers/bridge-identified.ts
33340
33543
  var handleBridgeIdentified = (msg, deps) => {
33341
33544
  if (typeof msg.bridgeName !== "string") return;
33342
- deps.onBridgeIdentified(
33343
- msg
33344
- );
33545
+ deps.onBridgeIdentified({
33546
+ bridgeName: msg.bridgeName,
33547
+ proxyPorts: msg.proxyPorts,
33548
+ devServers: msg.devServers
33549
+ });
33345
33550
  setImmediate(() => {
33346
33551
  void (async () => {
33347
33552
  try {
@@ -33376,7 +33581,174 @@ var handleAgentConfigMessage = (msg, deps) => {
33376
33581
  };
33377
33582
 
33378
33583
  // src/agents/acp/from-bridge/handle-bridge-prompt.ts
33379
- import * as path28 from "node:path";
33584
+ import * as path29 from "node:path";
33585
+
33586
+ // src/prompt-turn-queue/client-report.ts
33587
+ function sendPromptQueueClientReport(ws, queues) {
33588
+ if (!ws) return false;
33589
+ sendWsMessage(ws, { type: "prompt_queue_client_report", queues });
33590
+ return true;
33591
+ }
33592
+
33593
+ // src/prompt-turn-queue/disk-store.ts
33594
+ import fs27 from "node:fs";
33595
+
33596
+ // src/prompt-turn-queue/paths.ts
33597
+ import crypto3 from "node:crypto";
33598
+ import fs26 from "node:fs";
33599
+ import path28 from "node:path";
33600
+ import os6 from "node:os";
33601
+ var QUEUE_KEY_HEX_64 = /^[a-f0-9]{64}$/i;
33602
+ function queueStateFileSlug(queueKey) {
33603
+ if (QUEUE_KEY_HEX_64.test(queueKey)) return queueKey.toLowerCase();
33604
+ return crypto3.createHash("sha256").update(queueKey, "utf8").digest("hex");
33605
+ }
33606
+ function getPromptQueuesDirectory() {
33607
+ const override = process.env.BUILDAMATON_PROMPT_QUEUES_DIR?.trim();
33608
+ if (override) return path28.resolve(override);
33609
+ return path28.join(os6.homedir(), ".buildautomaton", "queues");
33610
+ }
33611
+ function ensurePromptQueuesDirectory() {
33612
+ const dir = getPromptQueuesDirectory();
33613
+ if (!fs26.existsSync(dir)) fs26.mkdirSync(dir, { recursive: true });
33614
+ }
33615
+ function queueStateFilePath(queueKey) {
33616
+ return path28.join(getPromptQueuesDirectory(), `${queueStateFileSlug(queueKey)}.json`);
33617
+ }
33618
+
33619
+ // src/prompt-turn-queue/disk-store.ts
33620
+ function parsePersistedQueueFile(raw) {
33621
+ try {
33622
+ const o = JSON.parse(raw);
33623
+ const queueKey = typeof o.queueKey === "string" ? o.queueKey : typeof o.queueKeyHash === "string" ? o.queueKeyHash : null;
33624
+ if (!queueKey || typeof o.updatedAt !== "string" || !Array.isArray(o.turns)) return null;
33625
+ return { queueKey, updatedAt: o.updatedAt, turns: o.turns };
33626
+ } catch {
33627
+ return null;
33628
+ }
33629
+ }
33630
+ function readPersistedQueue(queueKey) {
33631
+ const p = queueStateFilePath(queueKey);
33632
+ try {
33633
+ return parsePersistedQueueFile(fs27.readFileSync(p, "utf8"));
33634
+ } catch {
33635
+ return null;
33636
+ }
33637
+ }
33638
+ function writePersistedQueue(file2) {
33639
+ ensurePromptQueuesDirectory();
33640
+ const p = queueStateFilePath(file2.queueKey);
33641
+ fs27.writeFileSync(p, JSON.stringify(file2, null, 2), "utf8");
33642
+ }
33643
+ function mergeServerQueueSnapshot(queueKey, serverTurns) {
33644
+ const prev = readPersistedQueue(queueKey);
33645
+ const turns = [];
33646
+ for (const raw of serverTurns) {
33647
+ if (!raw || typeof raw !== "object") continue;
33648
+ const o = raw;
33649
+ const turnId = typeof o.turnId === "string" ? o.turnId : "";
33650
+ const sessionId = typeof o.sessionId === "string" ? o.sessionId : "";
33651
+ const turnOrd = typeof o.turnOrd === "number" ? o.turnOrd : Number(o.turnOrd) || 0;
33652
+ const serverState = o.serverState;
33653
+ const lastClientState = o.lastClientState ?? null;
33654
+ const payload = o.payload && typeof o.payload === "object" ? o.payload : {};
33655
+ if (!turnId || !sessionId) continue;
33656
+ if (serverState !== "queued" && serverState !== "stopping" && serverState !== "discarded") continue;
33657
+ const old = prev?.turns.find((t) => t.turnId === turnId);
33658
+ const mergedClient = old?.lastClientState === "running" && lastClientState == null ? "running" : lastClientState;
33659
+ turns.push({
33660
+ turnId,
33661
+ sessionId,
33662
+ turnOrd,
33663
+ serverState,
33664
+ lastClientState: mergedClient,
33665
+ payload
33666
+ });
33667
+ }
33668
+ turns.sort((a, b) => a.turnOrd - b.turnOrd);
33669
+ return { queueKey, updatedAt: (/* @__PURE__ */ new Date()).toISOString(), turns };
33670
+ }
33671
+
33672
+ // src/prompt-turn-queue/runner.ts
33673
+ var runIdToQueueKey = /* @__PURE__ */ new Map();
33674
+ function pickNextRunnableTurn(turns) {
33675
+ for (const t of turns) {
33676
+ if (t.serverState === "discarded" || t.serverState === "stopping") continue;
33677
+ if (t.serverState !== "queued") continue;
33678
+ if (t.lastClientState === "running" || t.lastClientState === "stopped" || t.lastClientState === "failed") continue;
33679
+ return t;
33680
+ }
33681
+ return null;
33682
+ }
33683
+ function hasRunningTurn(turns) {
33684
+ return turns.some((t) => t.lastClientState === "running");
33685
+ }
33686
+ function dispatchLocalPrompt(next, deps) {
33687
+ const pl = next.payload;
33688
+ const msg = {
33689
+ type: "prompt",
33690
+ sessionId: next.sessionId,
33691
+ runId: next.turnId,
33692
+ prompt: pl.prompt,
33693
+ mode: typeof pl.mode === "string" ? pl.mode : "agent",
33694
+ isNewSession: pl.isNewSession === true,
33695
+ ...typeof pl.followUpCatalogPromptId === "string" ? { followUpCatalogPromptId: pl.followUpCatalogPromptId } : {},
33696
+ ...Array.isArray(pl.sessionChangeSummaryFilePaths) ? { sessionChangeSummaryFilePaths: pl.sessionChangeSummaryFilePaths } : {},
33697
+ ...Array.isArray(pl.sessionChangeSummaryFileSnapshots) ? { sessionChangeSummaryFileSnapshots: pl.sessionChangeSummaryFileSnapshots } : {},
33698
+ ...typeof pl.agentType === "string" && pl.agentType.trim() ? { agentType: pl.agentType.trim() } : {}
33699
+ };
33700
+ handleBridgePrompt(msg, deps);
33701
+ }
33702
+ function applyPromptQueueStateFromServer(msg, deps) {
33703
+ const raw = msg.queues;
33704
+ if (!raw || typeof raw !== "object") return;
33705
+ const getWs = deps.getWs;
33706
+ for (const [queueKey, serverTurns] of Object.entries(raw)) {
33707
+ if (!Array.isArray(serverTurns)) continue;
33708
+ const file2 = mergeServerQueueSnapshot(queueKey, serverTurns);
33709
+ writePersistedQueue(file2);
33710
+ }
33711
+ const report = {};
33712
+ const startedThisTick = /* @__PURE__ */ new Set();
33713
+ for (const [queueKey, serverTurns] of Object.entries(raw)) {
33714
+ if (!Array.isArray(serverTurns)) continue;
33715
+ const file2 = readPersistedQueue(queueKey);
33716
+ if (!file2) continue;
33717
+ if (hasRunningTurn(file2.turns)) continue;
33718
+ const next = pickNextRunnableTurn(file2.turns);
33719
+ if (!next) continue;
33720
+ next.lastClientState = "running";
33721
+ writePersistedQueue(file2);
33722
+ runIdToQueueKey.set(next.turnId, queueKey);
33723
+ startedThisTick.add(next.turnId);
33724
+ report[queueKey] = [{ turnId: next.turnId, clientState: "running" }];
33725
+ }
33726
+ if (Object.keys(report).length > 0) {
33727
+ sendPromptQueueClientReport(getWs(), report);
33728
+ }
33729
+ for (const [queueKey, serverTurns] of Object.entries(raw)) {
33730
+ if (!Array.isArray(serverTurns)) continue;
33731
+ const file2 = readPersistedQueue(queueKey);
33732
+ if (!file2) continue;
33733
+ const running = file2.turns.find((t) => t.lastClientState === "running");
33734
+ if (!running || !startedThisTick.has(running.turnId)) continue;
33735
+ if (runIdToQueueKey.get(running.turnId) !== queueKey) continue;
33736
+ dispatchLocalPrompt(running, deps);
33737
+ }
33738
+ }
33739
+ function finalizePromptTurnOnBridge(getWs, runId, success2) {
33740
+ if (!runId) return;
33741
+ const queueKey = runIdToQueueKey.get(runId);
33742
+ runIdToQueueKey.delete(runId);
33743
+ if (!queueKey) return;
33744
+ const f = readPersistedQueue(queueKey);
33745
+ if (!f) return;
33746
+ const t = f.turns.find((x) => x.turnId === runId);
33747
+ if (!t) return;
33748
+ t.lastClientState = success2 ? "stopped" : "failed";
33749
+ writePersistedQueue(f);
33750
+ sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, clientState: t.lastClientState }] });
33751
+ }
33380
33752
 
33381
33753
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
33382
33754
  function createBridgePromptSenders(deps, getWs) {
@@ -33391,6 +33763,9 @@ function createBridgePromptSenders(deps, getWs) {
33391
33763
  const skipEncryptForChangeSummaryFollowUp = result.type === "prompt_result" && result.followUpCatalogPromptId === BUILTIN_SESSION_CHANGE_SUMMARY_FOLLOW_UP_CATALOG_PROMPT_ID;
33392
33764
  const encryptedFields = result.type === "prompt_result" && !skipEncryptForChangeSummaryFollowUp ? ["output", "error"] : [];
33393
33765
  sendBridgeMessage(result, encryptedFields);
33766
+ if (result.type === "prompt_result") {
33767
+ finalizePromptTurnOnBridge(getWs, typeof result.runId === "string" ? result.runId : void 0, result.success === true);
33768
+ }
33394
33769
  };
33395
33770
  const sendSessionUpdate = (payload) => {
33396
33771
  const s = getWs();
@@ -33415,63 +33790,6 @@ function createBridgePromptSenders(deps, getWs) {
33415
33790
  // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
33416
33791
  import { execFile as execFile10 } from "node:child_process";
33417
33792
  import { promisify as promisify10 } from "node:util";
33418
-
33419
- // src/git/bridge-queue-key.ts
33420
- import * as path27 from "node:path";
33421
- import { createHash } from "node:crypto";
33422
- function normalizeCanonicalGitUrl(url2) {
33423
- let s = url2.trim();
33424
- if (!s) return s;
33425
- if (s.toLowerCase().endsWith(".git")) {
33426
- s = s.slice(0, -4);
33427
- }
33428
- s = s.replace(/\/+$/, "");
33429
- const httpsMatch = /^(https?):\/\/([^/]+)(\/.*)?$/i.exec(s);
33430
- if (httpsMatch) {
33431
- const host = httpsMatch[2].toLowerCase();
33432
- const p = httpsMatch[3] ?? "";
33433
- s = `${httpsMatch[1].toLowerCase()}://${host}${p}`;
33434
- } else {
33435
- const sshMatch = /^git@([^:]+):(.+)$/i.exec(s);
33436
- if (sshMatch) {
33437
- const host = sshMatch[1].toLowerCase();
33438
- s = `git@${host}:${sshMatch[2]}`;
33439
- }
33440
- }
33441
- return s;
33442
- }
33443
- function canonicalUrlToRepoIdSync(url2) {
33444
- const normalized = normalizeCanonicalGitUrl(url2);
33445
- return createHash("sha256").update(normalized).digest("hex").slice(0, 32);
33446
- }
33447
- function fallbackRepoIdFromPath(absPath) {
33448
- return createHash("sha256").update(path27.resolve(absPath)).digest("hex").slice(0, 32);
33449
- }
33450
- async function resolveBridgeQueueBindFields(options) {
33451
- const { effectiveCwd, worktreePaths, primaryRepoRoots, log: log2 } = options;
33452
- const cwdAbs = worktreePaths.length > 0 ? path27.resolve(worktreePaths[0]) : path27.resolve(effectiveCwd);
33453
- if (!primaryRepoRoots.length) {
33454
- log2("[Bridge service] Prompt queue bind skipped: no Git repository roots under the working directory.");
33455
- return null;
33456
- }
33457
- let primaryRoot = primaryRepoRoots[0];
33458
- let remote = await getRemoteOriginUrl(primaryRoot);
33459
- if (!remote) {
33460
- for (const r of primaryRepoRoots.slice(1)) {
33461
- const u = await getRemoteOriginUrl(r);
33462
- if (u) {
33463
- primaryRoot = r;
33464
- remote = u;
33465
- break;
33466
- }
33467
- }
33468
- }
33469
- const repoId = remote ? canonicalUrlToRepoIdSync(remote) : fallbackRepoIdFromPath(primaryRoot);
33470
- const canonicalQueueKey = `repo:${repoId}::cwd:${cwdAbs}`;
33471
- return { canonicalQueueKey, repoId, cwdAbs };
33472
- }
33473
-
33474
- // src/agents/acp/from-bridge/bridge-prompt-preamble.ts
33475
33793
  var execFileAsync9 = promisify10(execFile10);
33476
33794
  async function readGitBranch(cwd) {
33477
33795
  try {
@@ -33491,30 +33809,17 @@ async function runBridgePromptPreamble(params) {
33491
33809
  fallbackCwd: effectiveCwd,
33492
33810
  log: log2
33493
33811
  });
33494
- if (s && sessionId) {
33495
- const bind = await resolveBridgeQueueBindFields({
33496
- effectiveCwd,
33497
- worktreePaths,
33498
- primaryRepoRoots: repoRoots,
33499
- log: log2
33500
- });
33501
- if (bind) {
33502
- sendWsMessage(s, {
33503
- type: "bridge_queue_bind",
33504
- sessionId,
33505
- canonicalQueueKey: bind.canonicalQueueKey,
33506
- repoId: bind.repoId,
33507
- cwdAbs: bind.cwdAbs
33508
- });
33509
- }
33510
- }
33511
33812
  if (s && sessionId) {
33512
33813
  const cliGitBranch = await readGitBranch(effectiveCwd);
33814
+ const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
33815
+ const mirrorAbs = sessionWorktreeManager.getAgentCwdForSession(sessionId);
33513
33816
  sendWsMessage(s, {
33514
33817
  type: "session_git_context_report",
33515
33818
  sessionId,
33516
33819
  cliGitBranch,
33517
- agentUsesWorktree: sessionWorktreeManager.usesWorktreeSession(sessionId)
33820
+ agentUsesWorktree: usesWt,
33821
+ sessionParent: usesWt ? "worktrees_root" : "bridge_root",
33822
+ sessionParentPath: usesWt ? mirrorAbs : getBridgeWorkspaceDirectory()
33518
33823
  });
33519
33824
  }
33520
33825
  if (s && sessionId && runId) {
@@ -33533,9 +33838,9 @@ function parseChangeSummarySnapshots(raw) {
33533
33838
  for (const item of raw) {
33534
33839
  if (!item || typeof item !== "object") continue;
33535
33840
  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 };
33841
+ const path34 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
33842
+ if (!path34) continue;
33843
+ const row = { path: path34 };
33539
33844
  if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
33540
33845
  if (typeof o.oldText === "string") row.oldText = o.oldText;
33541
33846
  if (typeof o.newText === "string") row.newText = o.newText;
@@ -33660,12 +33965,14 @@ function handleBridgePrompt(msg, deps) {
33660
33965
  return;
33661
33966
  }
33662
33967
  const isNewSession = msg.isNewSession === true;
33663
- const sessionWorktreesEnabled = msg.sessionWorktreesEnabled === true;
33968
+ const rawParent = msg.sessionParent;
33969
+ const sessionParent = rawParent === "bridge_root" || rawParent === "worktrees_root" ? rawParent : rawParent === "session_worktrees_root" ? "worktrees_root" : null;
33970
+ const sessionParentPath = typeof msg.sessionParentPath === "string" && msg.sessionParentPath.trim() ? msg.sessionParentPath.trim() : null;
33664
33971
  const agentType = typeof msg.agentType === "string" && msg.agentType.trim() ? msg.agentType.trim() : void 0;
33665
33972
  const mode = typeof msg.mode === "string" && msg.mode.trim() ? msg.mode.trim() : void 0;
33666
33973
  acpManager.logPromptReceivedFromBridge({ agentType, mode });
33667
33974
  async function preambleAndPrompt(resolvedCwd) {
33668
- const effectiveCwd = path28.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
33975
+ const effectiveCwd = path29.resolve(resolvedCwd ?? getBridgeWorkspaceDirectory());
33669
33976
  await runBridgePromptPreamble({
33670
33977
  getWs,
33671
33978
  log: log2,
@@ -33708,7 +34015,7 @@ function handleBridgePrompt(msg, deps) {
33708
34015
  e2ee: deps.e2ee
33709
34016
  });
33710
34017
  }
33711
- void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionWorktreesEnabled }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
34018
+ void sessionWorktreeManager.resolveCwdForPrompt(sessionId, { isNewSession, sessionParent, sessionParentPath }).then((cwd) => preambleAndPrompt(cwd)).catch((err) => {
33712
34019
  log2(`[Agent] Worktree resolve failed: ${err instanceof Error ? err.message : String(err)}`);
33713
34020
  void preambleAndPrompt(void 0);
33714
34021
  });
@@ -33719,6 +34026,11 @@ var handlePromptMessage = (msg, deps) => {
33719
34026
  handleBridgePrompt(msg, deps);
33720
34027
  };
33721
34028
 
34029
+ // src/bridge/routing/handlers/prompt-queue-state.ts
34030
+ var handlePromptQueueStateMessage = (msg, deps) => {
34031
+ applyPromptQueueStateFromServer(msg, deps);
34032
+ };
34033
+
33722
34034
  // src/agents/acp/from-bridge/handle-bridge-cancel-run.ts
33723
34035
  async function handleBridgeCancelRun(msg, { log: log2, acpManager, getWs }) {
33724
34036
  const runId = msg.runId;
@@ -33738,6 +34050,7 @@ async function handleBridgeCancelRun(msg, { log: log2, acpManager, getWs }) {
33738
34050
  error: "Stopped by user",
33739
34051
  stopReason: "no_local_run"
33740
34052
  });
34053
+ finalizePromptTurnOnBridge(getWs, runId, false);
33741
34054
  }
33742
34055
 
33743
34056
  // src/bridge/routing/handlers/cancel-run.ts
@@ -33768,26 +34081,28 @@ function handleSkillCall(msg, socket, log2) {
33768
34081
 
33769
34082
  // src/bridge/routing/handlers/skill-call.ts
33770
34083
  var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
33771
- if (!msg.skillId || msg.operationId === void 0) return;
34084
+ const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
34085
+ const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
34086
+ if (!skillId || !operationId) return;
33772
34087
  const socket = getWs();
33773
34088
  if (!socket) return;
33774
34089
  handleSkillCall(
33775
- msg,
34090
+ { id: msg.id, skillId, operationId, params: msg.params },
33776
34091
  socket,
33777
34092
  log2
33778
34093
  );
33779
34094
  };
33780
34095
 
33781
34096
  // src/files/list-dir.ts
33782
- import fs25 from "node:fs";
33783
- import path30 from "node:path";
34097
+ import fs28 from "node:fs";
34098
+ import path31 from "node:path";
33784
34099
 
33785
34100
  // src/files/ensure-under-cwd.ts
33786
- import path29 from "node:path";
34101
+ import path30 from "node:path";
33787
34102
  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) {
34103
+ const normalized = path30.normalize(relativePath).replace(/^(\.\/)+/, "");
34104
+ const resolved = path30.resolve(cwd, normalized);
34105
+ if (!resolved.startsWith(cwd + path30.sep) && resolved !== cwd) {
33791
34106
  return null;
33792
34107
  }
33793
34108
  return resolved;
@@ -33801,7 +34116,7 @@ async function listDirAsync(relativePath) {
33801
34116
  return { error: "Path is outside working directory" };
33802
34117
  }
33803
34118
  try {
33804
- const names = await fs25.promises.readdir(resolved, { withFileTypes: true });
34119
+ const names = await fs28.promises.readdir(resolved, { withFileTypes: true });
33805
34120
  const visible = names.filter((d) => !d.name.startsWith("."));
33806
34121
  const entries = [];
33807
34122
  for (let i = 0; i < visible.length; i++) {
@@ -33809,12 +34124,12 @@ async function listDirAsync(relativePath) {
33809
34124
  await yieldToEventLoop();
33810
34125
  }
33811
34126
  const d = visible[i];
33812
- const entryPath = path30.join(relativePath || ".", d.name).replace(/\\/g, "/");
33813
- const fullPath = path30.join(resolved, d.name);
34127
+ const entryPath = path31.join(relativePath || ".", d.name).replace(/\\/g, "/");
34128
+ const fullPath = path31.join(resolved, d.name);
33814
34129
  let isDir = d.isDirectory();
33815
34130
  if (d.isSymbolicLink()) {
33816
34131
  try {
33817
- const targetStat = await fs25.promises.stat(fullPath);
34132
+ const targetStat = await fs28.promises.stat(fullPath);
33818
34133
  isDir = targetStat.isDirectory();
33819
34134
  } catch {
33820
34135
  isDir = false;
@@ -33839,25 +34154,25 @@ async function listDirAsync(relativePath) {
33839
34154
  }
33840
34155
 
33841
34156
  // src/files/read-file.ts
33842
- import fs26 from "node:fs";
34157
+ import fs29 from "node:fs";
33843
34158
  import { StringDecoder } from "node:string_decoder";
33844
34159
  function resolveFilePath(relativePath) {
33845
34160
  const resolved = ensureUnderCwd(relativePath, getBridgeWorkspaceDirectory());
33846
34161
  if (!resolved) return { error: "Path is outside working directory" };
33847
34162
  let real;
33848
34163
  try {
33849
- real = fs26.realpathSync(resolved);
34164
+ real = fs29.realpathSync(resolved);
33850
34165
  } catch {
33851
34166
  real = resolved;
33852
34167
  }
33853
- const stat2 = fs26.statSync(real);
34168
+ const stat2 = fs29.statSync(real);
33854
34169
  if (!stat2.isFile()) return { error: "Not a file" };
33855
34170
  return real;
33856
34171
  }
33857
34172
  var LINE_CHUNK_SIZE = 64 * 1024;
33858
34173
  function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
33859
- const fileSize = fs26.statSync(filePath).size;
33860
- const fd = fs26.openSync(filePath, "r");
34174
+ const fileSize = fs29.statSync(filePath).size;
34175
+ const fd = fs29.openSync(filePath, "r");
33861
34176
  const bufSize = 64 * 1024;
33862
34177
  const buf = Buffer.alloc(bufSize);
33863
34178
  const decoder = new StringDecoder("utf8");
@@ -33870,7 +34185,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
33870
34185
  let line0Accum = "";
33871
34186
  try {
33872
34187
  let bytesRead;
33873
- while (!done && (bytesRead = fs26.readSync(fd, buf, 0, bufSize, null)) > 0) {
34188
+ while (!done && (bytesRead = fs29.readSync(fd, buf, 0, bufSize, null)) > 0) {
33874
34189
  const text = partial2 + decoder.write(buf.subarray(0, bytesRead));
33875
34190
  partial2 = "";
33876
34191
  let lineStart = 0;
@@ -34005,7 +34320,7 @@ function readFileRange(filePath, startLine, endLine, lineOffsetIn, lineChunkSize
34005
34320
  }
34006
34321
  return { content: resultLines.join("\n"), size: fileSize };
34007
34322
  } finally {
34008
- fs26.closeSync(fd);
34323
+ fs29.closeSync(fd);
34009
34324
  }
34010
34325
  }
34011
34326
  function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE) {
@@ -34016,8 +34331,8 @@ function readFile2(relativePath, startLine, endLine, lineOffset, lineChunkSize =
34016
34331
  if (hasRange) {
34017
34332
  return readFileRange(result, startLine, endLine, lineOffset, lineChunkSize);
34018
34333
  }
34019
- const stat2 = fs26.statSync(result);
34020
- const raw = fs26.readFileSync(result, "utf8");
34334
+ const stat2 = fs29.statSync(result);
34335
+ const raw = fs29.readFileSync(result, "utf8");
34021
34336
  const lines = raw.split(/\r?\n/);
34022
34337
  return { content: raw, totalLines: lines.length, size: stat2.size };
34023
34338
  } catch (err) {
@@ -34129,12 +34444,14 @@ function handleSkillLayoutRequest(msg, deps) {
34129
34444
  const socket = deps.getWs();
34130
34445
  const id = typeof msg.id === "string" ? msg.id : "";
34131
34446
  const roots = discoverSkillLayoutRoots(getBridgeWorkspaceDirectory());
34132
- socket?.send(JSON.stringify({ type: "skill_layout_response", id, roots }));
34447
+ if (socket) {
34448
+ sendWsMessage(socket, { type: "skill_layout_response", id, roots });
34449
+ }
34133
34450
  }
34134
34451
 
34135
34452
  // src/skills/install-remote-skills.ts
34136
- import fs27 from "node:fs";
34137
- import path31 from "node:path";
34453
+ import fs30 from "node:fs";
34454
+ import path32 from "node:path";
34138
34455
  function installRemoteSkills(cwd, targetDir, items) {
34139
34456
  const installed2 = [];
34140
34457
  if (!Array.isArray(items)) {
@@ -34145,15 +34462,15 @@ function installRemoteSkills(cwd, targetDir, items) {
34145
34462
  if (typeof item.sourceId !== "string" || typeof item.skillName !== "string" || typeof item.versionHash !== "string" || !Array.isArray(item.files)) {
34146
34463
  continue;
34147
34464
  }
34148
- const skillDir = path31.join(cwd, targetDir, item.skillName);
34465
+ const skillDir = path32.join(cwd, targetDir, item.skillName);
34149
34466
  for (const f of item.files) {
34150
34467
  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 });
34468
+ const dest = path32.join(skillDir, f.path);
34469
+ fs30.mkdirSync(path32.dirname(dest), { recursive: true });
34153
34470
  if (f.text !== void 0) {
34154
- fs27.writeFileSync(dest, f.text, "utf8");
34471
+ fs30.writeFileSync(dest, f.text, "utf8");
34155
34472
  } else if (f.base64) {
34156
- fs27.writeFileSync(dest, Buffer.from(f.base64, "base64"));
34473
+ fs30.writeFileSync(dest, Buffer.from(f.base64, "base64"));
34157
34474
  }
34158
34475
  }
34159
34476
  installed2.push({
@@ -34179,10 +34496,14 @@ var handleInstallSkillsMessage = (msg, deps) => {
34179
34496
  if (!result.success) {
34180
34497
  const err = result.error ?? "Invalid items";
34181
34498
  deps.log(`[Bridge service] Install skills failed: ${err}`);
34182
- socket?.send(JSON.stringify({ type: "install_skills_result", id, success: false, error: err }));
34499
+ if (socket) {
34500
+ sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
34501
+ }
34183
34502
  return;
34184
34503
  }
34185
- socket?.send(JSON.stringify({ type: "install_skills_result", id, success: true, installed: result.installed }));
34504
+ if (socket) {
34505
+ sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
34506
+ }
34186
34507
  };
34187
34508
 
34188
34509
  // src/bridge/routing/handlers/refresh-local-skills.ts
@@ -34299,7 +34620,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
34299
34620
  };
34300
34621
 
34301
34622
  // src/bridge/routing/handlers/revert-turn-snapshot.ts
34302
- import * as fs28 from "node:fs";
34623
+ import * as fs31 from "node:fs";
34303
34624
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
34304
34625
  const id = typeof msg.id === "string" ? msg.id : "";
34305
34626
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -34311,7 +34632,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
34311
34632
  if (!s) return;
34312
34633
  const agentBase = sessionWorktreeManager.getAgentCwdForSession(sessionId) ?? getBridgeWorkspaceDirectory();
34313
34634
  const file2 = snapshotFilePath(agentBase, turnId);
34314
- if (!fs28.existsSync(file2)) {
34635
+ if (!fs31.existsSync(file2)) {
34315
34636
  sendWsMessage(s, {
34316
34637
  type: "revert_turn_snapshot_result",
34317
34638
  id,
@@ -34332,7 +34653,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
34332
34653
 
34333
34654
  // src/bridge/routing/handlers/dev-server-control.ts
34334
34655
  var handleDevServerControl = (msg, deps) => {
34335
- let wire = msg;
34656
+ let wire;
34336
34657
  try {
34337
34658
  wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
34338
34659
  } catch (e) {
@@ -34353,9 +34674,7 @@ var handleDevServersConfig = (msg, deps) => {
34353
34674
 
34354
34675
  // src/bridge/routing/dispatch-bridge-message.ts
34355
34676
  function dispatchBridgeMessage(msg, deps) {
34356
- const type = msg.type;
34357
- if (typeof type !== "string") return;
34358
- switch (type) {
34677
+ switch (msg.type) {
34359
34678
  case "auth_token":
34360
34679
  handleAuthToken(msg, deps);
34361
34680
  break;
@@ -34371,6 +34690,9 @@ function dispatchBridgeMessage(msg, deps) {
34371
34690
  case "agent_config":
34372
34691
  handleAgentConfigMessage(msg, deps);
34373
34692
  break;
34693
+ case "prompt_queue_state":
34694
+ handlePromptQueueStateMessage(msg, deps);
34695
+ break;
34374
34696
  case "prompt":
34375
34697
  handlePromptMessage(msg, deps);
34376
34698
  break;
@@ -34413,15 +34735,14 @@ function dispatchBridgeMessage(msg, deps) {
34413
34735
  case "refresh_local_skills":
34414
34736
  handleRefreshLocalSkills(msg, deps);
34415
34737
  break;
34416
- default:
34417
- deps.log?.(`[Bridge service] unhandled message type: ${type}`);
34418
34738
  }
34419
34739
  }
34420
34740
 
34421
34741
  // src/bridge/routing/handle-bridge-message.ts
34422
34742
  function handleBridgeMessage(data, deps) {
34423
- const msg = data;
34424
34743
  if (!deps.getWs()) return;
34744
+ const msg = parseApiToBridgeMessage(data, deps.log);
34745
+ if (!msg) return;
34425
34746
  setImmediate(() => {
34426
34747
  dispatchBridgeMessage(msg, deps);
34427
34748
  });
@@ -34467,7 +34788,8 @@ function createMainBridgeWebSocketLifecycle(params) {
34467
34788
  tokens,
34468
34789
  persistTokens,
34469
34790
  onAuthInvalid,
34470
- e2ee
34791
+ e2ee,
34792
+ identifyReportedPaths
34471
34793
  } = params;
34472
34794
  let authRefreshInFlight = false;
34473
34795
  function handleOpen() {
@@ -34480,7 +34802,14 @@ function createMainBridgeWebSocketLifecycle(params) {
34480
34802
  }
34481
34803
  const socket = getWs();
34482
34804
  if (socket) {
34483
- sendWsMessage(socket, { type: "identify", role: "cli", ...e2ee ? { e: e2ee.handshake } : {} });
34805
+ sendWsMessage(socket, {
34806
+ type: "identify",
34807
+ role: "cli",
34808
+ cliVersion: CLI_VERSION,
34809
+ bridgeRootPath: identifyReportedPaths.bridgeRootPath,
34810
+ worktreesRootPath: identifyReportedPaths.worktreesRootPath,
34811
+ ...e2ee ? { e: e2ee.handshake } : {}
34812
+ });
34484
34813
  reportGitRepos(getWs, logFn);
34485
34814
  }
34486
34815
  if (justAuthenticated && socket) {
@@ -34674,7 +35003,6 @@ async function createBridgeConnection(options) {
34674
35003
  const e2ee = options.e2eCertificate ? createCliE2eeRuntime(options.e2eCertificate) : void 0;
34675
35004
  const devServerManager = new DevServerManager({ getWs, log: logFn, getBridgeCwd: getBridgeWorkspaceDirectory, e2ee });
34676
35005
  const onBridgeIdentified = createOnBridgeIdentified({
34677
- sessionWorktreeManager,
34678
35006
  devServerManager,
34679
35007
  firehoseServerUrl,
34680
35008
  workspaceId,
@@ -34696,6 +35024,10 @@ async function createBridgeConnection(options) {
34696
35024
  cloudApiBaseUrl: apiUrl,
34697
35025
  getCloudAccessToken: () => tokens.accessToken
34698
35026
  };
35027
+ const identifyReportedPaths = {
35028
+ bridgeRootPath: path33.resolve(getBridgeWorkspaceDirectory()),
35029
+ worktreesRootPath: path33.resolve(worktreesRootAbs)
35030
+ };
34699
35031
  const { connect } = createMainBridgeWebSocketLifecycle({
34700
35032
  state,
34701
35033
  getWs,
@@ -34707,7 +35039,8 @@ async function createBridgeConnection(options) {
34707
35039
  tokens,
34708
35040
  persistTokens,
34709
35041
  onAuthInvalid,
34710
- e2ee
35042
+ e2ee,
35043
+ identifyReportedPaths
34711
35044
  });
34712
35045
  connect();
34713
35046
  const stopFileIndexWatcher = startFileIndexWatcher(getBridgeWorkspaceDirectory());