@buildautomaton/cli 0.1.73 → 0.1.75

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
@@ -4208,8 +4208,8 @@ var init_parseUtil = __esm({
4208
4208
  init_errors();
4209
4209
  init_en();
4210
4210
  makeIssue = (params) => {
4211
- const { data, path: path82, errorMaps, issueData } = params;
4212
- const fullPath = [...path82, ...issueData.path || []];
4211
+ const { data, path: path84, errorMaps, issueData } = params;
4212
+ const fullPath = [...path84, ...issueData.path || []];
4213
4213
  const fullIssue = {
4214
4214
  ...issueData,
4215
4215
  path: fullPath
@@ -4517,11 +4517,11 @@ var init_types = __esm({
4517
4517
  init_parseUtil();
4518
4518
  init_util();
4519
4519
  ParseInputLazyPath = class {
4520
- constructor(parent, value, path82, key) {
4520
+ constructor(parent, value, path84, key) {
4521
4521
  this._cachedPath = [];
4522
4522
  this.parent = parent;
4523
4523
  this.data = value;
4524
- this._path = path82;
4524
+ this._path = path84;
4525
4525
  this._key = key;
4526
4526
  }
4527
4527
  get path() {
@@ -8182,15 +8182,15 @@ function assignProp(target, prop, value) {
8182
8182
  configurable: true
8183
8183
  });
8184
8184
  }
8185
- function getElementAtPath(obj, path82) {
8186
- if (!path82)
8185
+ function getElementAtPath(obj, path84) {
8186
+ if (!path84)
8187
8187
  return obj;
8188
- return path82.reduce((acc, key) => acc?.[key], obj);
8188
+ return path84.reduce((acc, key) => acc?.[key], obj);
8189
8189
  }
8190
8190
  function promiseAllObject(promisesObj) {
8191
8191
  const keys = Object.keys(promisesObj);
8192
- const promises12 = keys.map((key) => promisesObj[key]);
8193
- return Promise.all(promises12).then((results) => {
8192
+ const promises13 = keys.map((key) => promisesObj[key]);
8193
+ return Promise.all(promises13).then((results) => {
8194
8194
  const resolvedObj = {};
8195
8195
  for (let i = 0; i < keys.length; i++) {
8196
8196
  resolvedObj[keys[i]] = results[i];
@@ -8434,11 +8434,11 @@ function aborted(x, startIndex = 0) {
8434
8434
  }
8435
8435
  return false;
8436
8436
  }
8437
- function prefixIssues(path82, issues) {
8437
+ function prefixIssues(path84, issues) {
8438
8438
  return issues.map((iss) => {
8439
8439
  var _a2;
8440
8440
  (_a2 = iss).path ?? (_a2.path = []);
8441
- iss.path.unshift(path82);
8441
+ iss.path.unshift(path84);
8442
8442
  return iss;
8443
8443
  });
8444
8444
  }
@@ -8627,7 +8627,7 @@ function treeifyError(error40, _mapper) {
8627
8627
  return issue2.message;
8628
8628
  };
8629
8629
  const result = { errors: [] };
8630
- const processError = (error41, path82 = []) => {
8630
+ const processError = (error41, path84 = []) => {
8631
8631
  var _a2, _b;
8632
8632
  for (const issue2 of error41.issues) {
8633
8633
  if (issue2.code === "invalid_union" && issue2.errors.length) {
@@ -8637,7 +8637,7 @@ function treeifyError(error40, _mapper) {
8637
8637
  } else if (issue2.code === "invalid_element") {
8638
8638
  processError({ issues: issue2.issues }, issue2.path);
8639
8639
  } else {
8640
- const fullpath = [...path82, ...issue2.path];
8640
+ const fullpath = [...path84, ...issue2.path];
8641
8641
  if (fullpath.length === 0) {
8642
8642
  result.errors.push(mapper(issue2));
8643
8643
  continue;
@@ -8667,9 +8667,9 @@ function treeifyError(error40, _mapper) {
8667
8667
  processError(error40);
8668
8668
  return result;
8669
8669
  }
8670
- function toDotPath(path82) {
8670
+ function toDotPath(path84) {
8671
8671
  const segs = [];
8672
- for (const seg of path82) {
8672
+ for (const seg of path84) {
8673
8673
  if (typeof seg === "number")
8674
8674
  segs.push(`[${seg}]`);
8675
8675
  else if (typeof seg === "symbol")
@@ -22376,7 +22376,7 @@ function readMigrationSql(filename, ...searchSubdirs) {
22376
22376
  join2(moduleDir, "..", sub, filename),
22377
22377
  join2(moduleDir, "..", "..", "dist", sub, filename)
22378
22378
  ]);
22379
- const resolved = candidates.find((path82) => existsSync(path82));
22379
+ const resolved = candidates.find((path84) => existsSync(path84));
22380
22380
  if (!resolved) {
22381
22381
  throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
22382
22382
  }
@@ -23447,7 +23447,7 @@ var require_ignore = __commonJS({
23447
23447
  // path matching.
23448
23448
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
23449
23449
  // @returns {TestResult} true if a file is ignored
23450
- test(path82, checkUnignored, mode) {
23450
+ test(path84, checkUnignored, mode) {
23451
23451
  let ignored = false;
23452
23452
  let unignored = false;
23453
23453
  let matchedRule;
@@ -23456,7 +23456,7 @@ var require_ignore = __commonJS({
23456
23456
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
23457
23457
  return;
23458
23458
  }
23459
- const matched = rule[mode].test(path82);
23459
+ const matched = rule[mode].test(path84);
23460
23460
  if (!matched) {
23461
23461
  return;
23462
23462
  }
@@ -23477,17 +23477,17 @@ var require_ignore = __commonJS({
23477
23477
  var throwError = (message, Ctor) => {
23478
23478
  throw new Ctor(message);
23479
23479
  };
23480
- var checkPath = (path82, originalPath, doThrow) => {
23481
- if (!isString(path82)) {
23480
+ var checkPath = (path84, originalPath, doThrow) => {
23481
+ if (!isString(path84)) {
23482
23482
  return doThrow(
23483
23483
  `path must be a string, but got \`${originalPath}\``,
23484
23484
  TypeError
23485
23485
  );
23486
23486
  }
23487
- if (!path82) {
23487
+ if (!path84) {
23488
23488
  return doThrow(`path must not be empty`, TypeError);
23489
23489
  }
23490
- if (checkPath.isNotRelative(path82)) {
23490
+ if (checkPath.isNotRelative(path84)) {
23491
23491
  const r = "`path.relative()`d";
23492
23492
  return doThrow(
23493
23493
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -23496,7 +23496,7 @@ var require_ignore = __commonJS({
23496
23496
  }
23497
23497
  return true;
23498
23498
  };
23499
- var isNotRelative = (path82) => REGEX_TEST_INVALID_PATH.test(path82);
23499
+ var isNotRelative = (path84) => REGEX_TEST_INVALID_PATH.test(path84);
23500
23500
  checkPath.isNotRelative = isNotRelative;
23501
23501
  checkPath.convert = (p) => p;
23502
23502
  var Ignore = class {
@@ -23526,19 +23526,19 @@ var require_ignore = __commonJS({
23526
23526
  }
23527
23527
  // @returns {TestResult}
23528
23528
  _test(originalPath, cache2, checkUnignored, slices) {
23529
- const path82 = originalPath && checkPath.convert(originalPath);
23529
+ const path84 = originalPath && checkPath.convert(originalPath);
23530
23530
  checkPath(
23531
- path82,
23531
+ path84,
23532
23532
  originalPath,
23533
23533
  this._strictPathCheck ? throwError : RETURN_FALSE
23534
23534
  );
23535
- return this._t(path82, cache2, checkUnignored, slices);
23535
+ return this._t(path84, cache2, checkUnignored, slices);
23536
23536
  }
23537
- checkIgnore(path82) {
23538
- if (!REGEX_TEST_TRAILING_SLASH.test(path82)) {
23539
- return this.test(path82);
23537
+ checkIgnore(path84) {
23538
+ if (!REGEX_TEST_TRAILING_SLASH.test(path84)) {
23539
+ return this.test(path84);
23540
23540
  }
23541
- const slices = path82.split(SLASH).filter(Boolean);
23541
+ const slices = path84.split(SLASH).filter(Boolean);
23542
23542
  slices.pop();
23543
23543
  if (slices.length) {
23544
23544
  const parent = this._t(
@@ -23551,18 +23551,18 @@ var require_ignore = __commonJS({
23551
23551
  return parent;
23552
23552
  }
23553
23553
  }
23554
- return this._rules.test(path82, false, MODE_CHECK_IGNORE);
23554
+ return this._rules.test(path84, false, MODE_CHECK_IGNORE);
23555
23555
  }
23556
- _t(path82, cache2, checkUnignored, slices) {
23557
- if (path82 in cache2) {
23558
- return cache2[path82];
23556
+ _t(path84, cache2, checkUnignored, slices) {
23557
+ if (path84 in cache2) {
23558
+ return cache2[path84];
23559
23559
  }
23560
23560
  if (!slices) {
23561
- slices = path82.split(SLASH).filter(Boolean);
23561
+ slices = path84.split(SLASH).filter(Boolean);
23562
23562
  }
23563
23563
  slices.pop();
23564
23564
  if (!slices.length) {
23565
- return cache2[path82] = this._rules.test(path82, checkUnignored, MODE_IGNORE);
23565
+ return cache2[path84] = this._rules.test(path84, checkUnignored, MODE_IGNORE);
23566
23566
  }
23567
23567
  const parent = this._t(
23568
23568
  slices.join(SLASH) + SLASH,
@@ -23570,29 +23570,29 @@ var require_ignore = __commonJS({
23570
23570
  checkUnignored,
23571
23571
  slices
23572
23572
  );
23573
- return cache2[path82] = parent.ignored ? parent : this._rules.test(path82, checkUnignored, MODE_IGNORE);
23573
+ return cache2[path84] = parent.ignored ? parent : this._rules.test(path84, checkUnignored, MODE_IGNORE);
23574
23574
  }
23575
- ignores(path82) {
23576
- return this._test(path82, this._ignoreCache, false).ignored;
23575
+ ignores(path84) {
23576
+ return this._test(path84, this._ignoreCache, false).ignored;
23577
23577
  }
23578
23578
  createFilter() {
23579
- return (path82) => !this.ignores(path82);
23579
+ return (path84) => !this.ignores(path84);
23580
23580
  }
23581
23581
  filter(paths) {
23582
23582
  return makeArray(paths).filter(this.createFilter());
23583
23583
  }
23584
23584
  // @returns {TestResult}
23585
- test(path82) {
23586
- return this._test(path82, this._testCache, true);
23585
+ test(path84) {
23586
+ return this._test(path84, this._testCache, true);
23587
23587
  }
23588
23588
  };
23589
23589
  var factory = (options) => new Ignore(options);
23590
- var isPathValid = (path82) => checkPath(path82 && checkPath.convert(path82), path82, RETURN_FALSE);
23590
+ var isPathValid = (path84) => checkPath(path84 && checkPath.convert(path84), path84, RETURN_FALSE);
23591
23591
  var setupWindows = () => {
23592
23592
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
23593
23593
  checkPath.convert = makePosix;
23594
23594
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
23595
- checkPath.isNotRelative = (path82) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path82) || isNotRelative(path82);
23595
+ checkPath.isNotRelative = (path84) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path84) || isNotRelative(path84);
23596
23596
  };
23597
23597
  if (
23598
23598
  // Detect `process` so that it can run in browsers.
@@ -26497,8 +26497,8 @@ var init_task_queue_types = __esm({
26497
26497
  });
26498
26498
 
26499
26499
  // src/code-nav/symbol-index/scheduler/task-queue-store.ts
26500
- function setSymbolIndexWorkerRunning(running) {
26501
- symbolIndexWorkerRunning = running;
26500
+ function setSymbolIndexWorkerRunning(running2) {
26501
+ symbolIndexWorkerRunning = running2;
26502
26502
  }
26503
26503
  function taskMatchesCurrentPending(task) {
26504
26504
  const current = pendingSymbolIndexTasks.get(symbolIndexTaskKey(task.parentPath, task.filePath));
@@ -27960,10 +27960,10 @@ var require_src2 = __commonJS({
27960
27960
  var fs_1 = __require("fs");
27961
27961
  var debug_1 = __importDefault(require_src());
27962
27962
  var log2 = debug_1.default("@kwsites/file-exists");
27963
- function check2(path82, isFile, isDirectory) {
27964
- log2(`checking %s`, path82);
27963
+ function check2(path84, isFile, isDirectory) {
27964
+ log2(`checking %s`, path84);
27965
27965
  try {
27966
- const stat2 = fs_1.statSync(path82);
27966
+ const stat2 = fs_1.statSync(path84);
27967
27967
  if (stat2.isFile() && isFile) {
27968
27968
  log2(`[OK] path represents a file`);
27969
27969
  return true;
@@ -27983,8 +27983,8 @@ var require_src2 = __commonJS({
27983
27983
  throw e;
27984
27984
  }
27985
27985
  }
27986
- function exists2(path82, type = exports.READABLE) {
27987
- return check2(path82, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
27986
+ function exists2(path84, type = exports.READABLE) {
27987
+ return check2(path84, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
27988
27988
  }
27989
27989
  exports.exists = exists2;
27990
27990
  exports.FILE = 1;
@@ -30370,8 +30370,8 @@ function randomSecret() {
30370
30370
  }
30371
30371
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
30372
30372
  }
30373
- async function requestPreviewApi(port, secret, method, path82, body) {
30374
- const url2 = `http://127.0.0.1:${port}${path82}`;
30373
+ async function requestPreviewApi(port, secret, method, path84, body) {
30374
+ const url2 = `http://127.0.0.1:${port}${path84}`;
30375
30375
  const headers = {
30376
30376
  [PREVIEW_SECRET_HEADER]: secret,
30377
30377
  "Content-Type": "application/json"
@@ -30383,7 +30383,7 @@ async function requestPreviewApi(port, secret, method, path82, body) {
30383
30383
  });
30384
30384
  const data = await res.json().catch(() => ({}));
30385
30385
  if (!res.ok) {
30386
- throw new Error(data?.error ?? `Preview API ${method} ${path82}: ${res.status}`);
30386
+ throw new Error(data?.error ?? `Preview API ${method} ${path84}: ${res.status}`);
30387
30387
  }
30388
30388
  return data;
30389
30389
  }
@@ -30606,7 +30606,7 @@ function installBridgeProcessResilience() {
30606
30606
  }
30607
30607
 
30608
30608
  // src/cli-version.ts
30609
- var CLI_VERSION = "0.1.73".length > 0 ? "0.1.73" : "0.0.0-dev";
30609
+ var CLI_VERSION = "0.1.75".length > 0 ? "0.1.75" : "0.0.0-dev";
30610
30610
 
30611
30611
  // src/connection/heartbeat/constants.ts
30612
30612
  var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
@@ -34524,6 +34524,7 @@ function extractSessionUpdateMessageText(params) {
34524
34524
  }
34525
34525
 
34526
34526
  // src/agents/planning/planning-session-turn-buffer.ts
34527
+ var MAX_PLANNING_BUFFER_CHARS = 512 * 1024;
34527
34528
  var buffersByRunId = /* @__PURE__ */ new Map();
34528
34529
  function registerPlanningSessionTurn(runId) {
34529
34530
  buffersByRunId.set(runId, { messageBuffer: "" });
@@ -34541,7 +34542,10 @@ function capturePlanningSessionUpdate(params) {
34541
34542
  });
34542
34543
  if (bucket !== "message") return false;
34543
34544
  const text = extractSessionUpdateMessageText(params.payload);
34544
- if (text) state.messageBuffer += text;
34545
+ if (text && state.messageBuffer.length < MAX_PLANNING_BUFFER_CHARS) {
34546
+ const room = MAX_PLANNING_BUFFER_CHARS - state.messageBuffer.length;
34547
+ state.messageBuffer += room >= text.length ? text : text.slice(0, room);
34548
+ }
34545
34549
  return true;
34546
34550
  }
34547
34551
  function getPlanningSessionTurnOutput(runId) {
@@ -35080,8 +35084,8 @@ async function execGitFile(args, options) {
35080
35084
  }
35081
35085
 
35082
35086
  // src/git/changes/parse/normalize-git-diff-path.ts
35083
- function normalizeGitDiffPath(path82) {
35084
- return path82.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
35087
+ function normalizeGitDiffPath(path84) {
35088
+ return path84.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
35085
35089
  }
35086
35090
 
35087
35091
  // src/git/changes/parse/parse-name-status-entries.ts
@@ -36606,11 +36610,30 @@ function closeHttpServer(server) {
36606
36610
  }
36607
36611
 
36608
36612
  // src/mcp/bridge-access/read-json-body.ts
36613
+ var MAX_JSON_BODY_BYTES = 1024 * 1024;
36614
+ var RequestBodyTooLargeError = class extends Error {
36615
+ constructor() {
36616
+ super(`Request body exceeds ${MAX_JSON_BODY_BYTES} bytes`);
36617
+ }
36618
+ };
36609
36619
  function readJsonBody(req) {
36610
36620
  return new Promise((resolve35, reject) => {
36611
36621
  const chunks = [];
36612
- req.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
36622
+ let total = 0;
36623
+ let tooLarge = false;
36624
+ req.on("data", (chunk) => {
36625
+ if (tooLarge) return;
36626
+ const buf = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
36627
+ total += buf.length;
36628
+ if (total > MAX_JSON_BODY_BYTES) {
36629
+ tooLarge = true;
36630
+ reject(new RequestBodyTooLargeError());
36631
+ return;
36632
+ }
36633
+ chunks.push(buf);
36634
+ });
36613
36635
  req.on("end", () => {
36636
+ if (tooLarge) return;
36614
36637
  try {
36615
36638
  const raw = Buffer.concat(chunks).toString("utf8").trim();
36616
36639
  if (!raw) {
@@ -36667,7 +36690,7 @@ function createBridgeAccessRequestHandler(registry2) {
36667
36690
  sendJsonResponse(res, 404, { ok: false, error: "Not found" });
36668
36691
  } catch (err) {
36669
36692
  const message = err instanceof Error ? err.message : String(err);
36670
- sendJsonResponse(res, 500, { ok: false, error: message });
36693
+ sendJsonResponse(res, err instanceof RequestBodyTooLargeError ? 413 : 500, { ok: false, error: message });
36671
36694
  }
36672
36695
  })();
36673
36696
  };
@@ -39291,8 +39314,8 @@ function pathspec(...paths) {
39291
39314
  cache.set(key, paths);
39292
39315
  return key;
39293
39316
  }
39294
- function isPathSpec(path82) {
39295
- return path82 instanceof String && cache.has(path82);
39317
+ function isPathSpec(path84) {
39318
+ return path84 instanceof String && cache.has(path84);
39296
39319
  }
39297
39320
  function toPaths(pathSpec) {
39298
39321
  return cache.get(pathSpec) || [];
@@ -39381,8 +39404,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
39381
39404
  function forEachLineWithContent(input, callback) {
39382
39405
  return toLinesWithContent(input, true).map((line) => callback(line));
39383
39406
  }
39384
- function folderExists(path82) {
39385
- return (0, import_file_exists.exists)(path82, import_file_exists.FOLDER);
39407
+ function folderExists(path84) {
39408
+ return (0, import_file_exists.exists)(path84, import_file_exists.FOLDER);
39386
39409
  }
39387
39410
  function append(target, item) {
39388
39411
  if (Array.isArray(target)) {
@@ -39786,8 +39809,8 @@ function checkIsRepoRootTask() {
39786
39809
  commands,
39787
39810
  format: "utf-8",
39788
39811
  onError,
39789
- parser(path82) {
39790
- return /^\.(git)?$/.test(path82.trim());
39812
+ parser(path84) {
39813
+ return /^\.(git)?$/.test(path84.trim());
39791
39814
  }
39792
39815
  };
39793
39816
  }
@@ -40221,11 +40244,11 @@ function parseGrep(grep) {
40221
40244
  const paths = /* @__PURE__ */ new Set();
40222
40245
  const results = {};
40223
40246
  forEachLineWithContent(grep, (input) => {
40224
- const [path82, line, preview] = input.split(NULL);
40225
- paths.add(path82);
40226
- (results[path82] = results[path82] || []).push({
40247
+ const [path84, line, preview] = input.split(NULL);
40248
+ paths.add(path84);
40249
+ (results[path84] = results[path84] || []).push({
40227
40250
  line: asNumber(line),
40228
- path: path82,
40251
+ path: path84,
40229
40252
  preview
40230
40253
  });
40231
40254
  });
@@ -40990,14 +41013,14 @@ var init_hash_object = __esm2({
40990
41013
  init_task();
40991
41014
  }
40992
41015
  });
40993
- function parseInit(bare, path82, text) {
41016
+ function parseInit(bare, path84, text) {
40994
41017
  const response = String(text).trim();
40995
41018
  let result;
40996
41019
  if (result = initResponseRegex.exec(response)) {
40997
- return new InitSummary(bare, path82, false, result[1]);
41020
+ return new InitSummary(bare, path84, false, result[1]);
40998
41021
  }
40999
41022
  if (result = reInitResponseRegex.exec(response)) {
41000
- return new InitSummary(bare, path82, true, result[1]);
41023
+ return new InitSummary(bare, path84, true, result[1]);
41001
41024
  }
41002
41025
  let gitDir = "";
41003
41026
  const tokens = response.split(" ");
@@ -41008,7 +41031,7 @@ function parseInit(bare, path82, text) {
41008
41031
  break;
41009
41032
  }
41010
41033
  }
41011
- return new InitSummary(bare, path82, /^re/i.test(response), gitDir);
41034
+ return new InitSummary(bare, path84, /^re/i.test(response), gitDir);
41012
41035
  }
41013
41036
  var InitSummary;
41014
41037
  var initResponseRegex;
@@ -41017,9 +41040,9 @@ var init_InitSummary = __esm2({
41017
41040
  "src/lib/responses/InitSummary.ts"() {
41018
41041
  "use strict";
41019
41042
  InitSummary = class {
41020
- constructor(bare, path82, existing, gitDir) {
41043
+ constructor(bare, path84, existing, gitDir) {
41021
41044
  this.bare = bare;
41022
- this.path = path82;
41045
+ this.path = path84;
41023
41046
  this.existing = existing;
41024
41047
  this.gitDir = gitDir;
41025
41048
  }
@@ -41031,7 +41054,7 @@ var init_InitSummary = __esm2({
41031
41054
  function hasBareCommand(command) {
41032
41055
  return command.includes(bareCommand);
41033
41056
  }
41034
- function initTask(bare = false, path82, customArgs) {
41057
+ function initTask(bare = false, path84, customArgs) {
41035
41058
  const commands = ["init", ...customArgs];
41036
41059
  if (bare && !hasBareCommand(commands)) {
41037
41060
  commands.splice(1, 0, bareCommand);
@@ -41040,7 +41063,7 @@ function initTask(bare = false, path82, customArgs) {
41040
41063
  commands,
41041
41064
  format: "utf-8",
41042
41065
  parser(text) {
41043
- return parseInit(commands.includes("--bare"), path82, text);
41066
+ return parseInit(commands.includes("--bare"), path84, text);
41044
41067
  }
41045
41068
  };
41046
41069
  }
@@ -41856,12 +41879,12 @@ var init_FileStatusSummary = __esm2({
41856
41879
  "use strict";
41857
41880
  fromPathRegex = /^(.+)\0(.+)$/;
41858
41881
  FileStatusSummary = class {
41859
- constructor(path82, index, working_dir) {
41860
- this.path = path82;
41882
+ constructor(path84, index, working_dir) {
41883
+ this.path = path84;
41861
41884
  this.index = index;
41862
41885
  this.working_dir = working_dir;
41863
41886
  if (index === "R" || working_dir === "R") {
41864
- const detail = fromPathRegex.exec(path82) || [null, path82, path82];
41887
+ const detail = fromPathRegex.exec(path84) || [null, path84, path84];
41865
41888
  this.from = detail[2] || "";
41866
41889
  this.path = detail[1] || "";
41867
41890
  }
@@ -41892,14 +41915,14 @@ function splitLine(result, lineStr) {
41892
41915
  default:
41893
41916
  return;
41894
41917
  }
41895
- function data(index, workingDir, path82) {
41918
+ function data(index, workingDir, path84) {
41896
41919
  const raw = `${index}${workingDir}`;
41897
41920
  const handler = parsers6.get(raw);
41898
41921
  if (handler) {
41899
- handler(result, path82);
41922
+ handler(result, path84);
41900
41923
  }
41901
41924
  if (raw !== "##" && raw !== "!!") {
41902
- result.files.push(new FileStatusSummary(path82, index, workingDir));
41925
+ result.files.push(new FileStatusSummary(path84, index, workingDir));
41903
41926
  }
41904
41927
  }
41905
41928
  }
@@ -42208,9 +42231,9 @@ var init_simple_git_api = __esm2({
42208
42231
  next
42209
42232
  );
42210
42233
  }
42211
- hashObject(path82, write) {
42234
+ hashObject(path84, write) {
42212
42235
  return this._runTask(
42213
- hashObjectTask(path82, write === true),
42236
+ hashObjectTask(path84, write === true),
42214
42237
  trailingFunctionArgument(arguments)
42215
42238
  );
42216
42239
  }
@@ -42563,8 +42586,8 @@ var init_branch = __esm2({
42563
42586
  }
42564
42587
  });
42565
42588
  function toPath(input) {
42566
- const path82 = input.trim().replace(/^["']|["']$/g, "");
42567
- return path82 && normalize3(path82);
42589
+ const path84 = input.trim().replace(/^["']|["']$/g, "");
42590
+ return path84 && normalize3(path84);
42568
42591
  }
42569
42592
  var parseCheckIgnore;
42570
42593
  var init_CheckIgnore = __esm2({
@@ -42878,8 +42901,8 @@ __export2(sub_module_exports, {
42878
42901
  subModuleTask: () => subModuleTask,
42879
42902
  updateSubModuleTask: () => updateSubModuleTask
42880
42903
  });
42881
- function addSubModuleTask(repo, path82) {
42882
- return subModuleTask(["add", repo, path82]);
42904
+ function addSubModuleTask(repo, path84) {
42905
+ return subModuleTask(["add", repo, path84]);
42883
42906
  }
42884
42907
  function initSubModuleTask(customArgs) {
42885
42908
  return subModuleTask(["init", ...customArgs]);
@@ -43212,8 +43235,8 @@ var require_git = __commonJS2({
43212
43235
  }
43213
43236
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
43214
43237
  };
43215
- Git2.prototype.submoduleAdd = function(repo, path82, then) {
43216
- return this._runTask(addSubModuleTask2(repo, path82), trailingFunctionArgument2(arguments));
43238
+ Git2.prototype.submoduleAdd = function(repo, path84, then) {
43239
+ return this._runTask(addSubModuleTask2(repo, path84), trailingFunctionArgument2(arguments));
43217
43240
  };
43218
43241
  Git2.prototype.submoduleUpdate = function(args, then) {
43219
43242
  return this._runTask(
@@ -43952,8 +43975,8 @@ function parseNumstatEntries(lines) {
43952
43975
  }
43953
43976
  function parseNumstat(lines) {
43954
43977
  const m = /* @__PURE__ */ new Map();
43955
- for (const [path82, entry] of parseNumstatEntries(lines)) {
43956
- m.set(path82, { additions: entry.additions, deletions: entry.deletions });
43978
+ for (const [path84, entry] of parseNumstatEntries(lines)) {
43979
+ m.set(path84, { additions: entry.additions, deletions: entry.deletions });
43957
43980
  }
43958
43981
  return m;
43959
43982
  }
@@ -44236,23 +44259,26 @@ function formatRemoteDisplayLabel(remoteUrl) {
44236
44259
  }
44237
44260
 
44238
44261
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
44239
- import * as path51 from "node:path";
44262
+ import * as path52 from "node:path";
44240
44263
 
44241
44264
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
44242
- import * as path50 from "node:path";
44265
+ import * as path51 from "node:path";
44243
44266
 
44244
44267
  // src/git/is-git-repo.ts
44268
+ import * as fs32 from "node:fs";
44269
+ import * as path43 from "node:path";
44245
44270
  async function isGitRepoDirectory(dirPath) {
44246
44271
  try {
44247
- return await cliSimpleGit(dirPath).checkIsRepo();
44272
+ await fs32.promises.access(path43.join(dirPath, ".git"));
44273
+ return true;
44248
44274
  } catch {
44249
44275
  return false;
44250
44276
  }
44251
44277
  }
44252
44278
 
44253
44279
  // src/git/changes/listing/apply-untracked-file-stats.ts
44254
- import * as fs32 from "node:fs";
44255
- import * as path43 from "node:path";
44280
+ import * as fs33 from "node:fs";
44281
+ import * as path44 from "node:path";
44256
44282
 
44257
44283
  // src/git/changes/lines/count-lines.ts
44258
44284
  import { createReadStream } from "node:fs";
@@ -44284,7 +44310,7 @@ function createUntrackedStatsApplier(options) {
44284
44310
  if (!options.untrackedSet.has(pathInRepo)) return;
44285
44311
  if (options.nameByPath.has(pathInRepo)) return;
44286
44312
  if (row.change === "moved") return;
44287
- const repoFilePath = path43.join(options.repoGitCwd, pathInRepo);
44313
+ const repoFilePath = path44.join(options.repoGitCwd, pathInRepo);
44288
44314
  const fromGit = await numstatFromGitNoIndex(options.g, pathInRepo);
44289
44315
  if (fromGit) {
44290
44316
  row.additions = fromGit.additions;
@@ -44292,7 +44318,7 @@ function createUntrackedStatsApplier(options) {
44292
44318
  return;
44293
44319
  }
44294
44320
  try {
44295
- const st = await fs32.promises.stat(repoFilePath);
44321
+ const st = await fs33.promises.stat(repoFilePath);
44296
44322
  row.additions = st.isFile() ? await countTextFileLines(repoFilePath) : 0;
44297
44323
  } catch {
44298
44324
  row.additions = 0;
@@ -44369,7 +44395,7 @@ async function buildChangedFileRowsFromPaths(options) {
44369
44395
  }
44370
44396
 
44371
44397
  // src/git/changes/listing/enrich-working-tree-file-rows.ts
44372
- import * as path45 from "node:path";
44398
+ import * as path46 from "node:path";
44373
44399
 
44374
44400
  // src/git/changes/patch/patch-truncate.ts
44375
44401
  function truncatePatch(s) {
@@ -44457,10 +44483,10 @@ async function readGitBlobLines(repoCwd, pathInRepo) {
44457
44483
  }
44458
44484
 
44459
44485
  // src/git/changes/patch/hydrate/read-worktree-file-lines.ts
44460
- import * as fs33 from "node:fs";
44486
+ import * as fs34 from "node:fs";
44461
44487
  async function readWorktreeFileLines(filePath) {
44462
44488
  try {
44463
- const raw = await fs33.promises.readFile(filePath, "utf8");
44489
+ const raw = await fs34.promises.readFile(filePath, "utf8");
44464
44490
  return raw.split(/\r?\n/);
44465
44491
  } catch {
44466
44492
  return null;
@@ -44598,8 +44624,8 @@ async function unifiedDiffForFileInRange(repoCwd, range, pathInRepo, change, mov
44598
44624
  }
44599
44625
 
44600
44626
  // src/git/changes/total-lines/resolve-changed-file-total-lines.ts
44601
- import * as fs34 from "node:fs";
44602
- import * as path44 from "node:path";
44627
+ import * as fs35 from "node:fs";
44628
+ import * as path45 from "node:path";
44603
44629
  var MAX_BYTES = 512e3;
44604
44630
  async function countLinesInGitRef(repoGitCwd, ref, pathInRepo) {
44605
44631
  const spec = `${ref}:${pathInRepo}`;
@@ -44619,13 +44645,13 @@ async function countLinesInGitRef(repoGitCwd, ref, pathInRepo) {
44619
44645
  }
44620
44646
  async function resolveWorkingTreeFileTotalLines(options) {
44621
44647
  if (options.isBinary) return null;
44622
- const filePath = path44.join(options.repoGitCwd, options.pathInRepo);
44648
+ const filePath = path45.join(options.repoGitCwd, options.pathInRepo);
44623
44649
  if (options.change === "removed") {
44624
44650
  return countLinesInGitRef(options.repoGitCwd, "HEAD", options.pathInRepo);
44625
44651
  }
44626
44652
  if (options.change === "moved" || options.change === "modified") {
44627
44653
  try {
44628
- const st = await fs34.promises.stat(filePath);
44654
+ const st = await fs35.promises.stat(filePath);
44629
44655
  if (!st.isFile()) return null;
44630
44656
  return await countTextFileLines(filePath);
44631
44657
  } catch {
@@ -44668,7 +44694,7 @@ async function enrichWorkingTreeFileRows(options) {
44668
44694
  row.workspaceRelPath,
44669
44695
  options.repoPathRelativeToWorkspaceRoot
44670
44696
  );
44671
- const filePath = path45.join(options.repoGitCwd, filePathRelativeToRepoRoot);
44697
+ const filePath = path46.join(options.repoGitCwd, filePathRelativeToRepoRoot);
44672
44698
  const hydrateKind = row.change === "moved" ? "modified" : row.change;
44673
44699
  let patch = await unifiedDiffForFile(
44674
44700
  options.repoGitCwd,
@@ -44826,7 +44852,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoPathRelativeToWorkspaceRo
44826
44852
  }
44827
44853
 
44828
44854
  // src/git/changes/listing/list-changed-files-for-commit.ts
44829
- import * as path46 from "node:path";
44855
+ import * as path47 from "node:path";
44830
44856
 
44831
44857
  // src/git/changes/listing/enrich-commit-file-rows.ts
44832
44858
  async function enrichCommitFileRows(options) {
@@ -44871,7 +44897,7 @@ async function parentForCommitDiff(g, sha) {
44871
44897
  var COMMIT_FILES_CACHE_TTL_MS = 5 * 6e4;
44872
44898
  var commitFilesCache = /* @__PURE__ */ new Map();
44873
44899
  function commitFilesCacheKey(repoGitCwd, commitSha) {
44874
- return `${path46.resolve(repoGitCwd)}:${commitSha}`;
44900
+ return `${path47.resolve(repoGitCwd)}:${commitSha}`;
44875
44901
  }
44876
44902
  async function listChangedFilesForCommit(repoGitCwd, repoPathRelativeToWorkspaceRoot, commitSha, options = {}) {
44877
44903
  const cacheKey = commitFilesCacheKey(repoGitCwd, commitSha);
@@ -44926,7 +44952,7 @@ async function listChangedFilesForCommit(repoGitCwd, repoPathRelativeToWorkspace
44926
44952
  }
44927
44953
 
44928
44954
  // src/git/commits/list-unpushed-commits.ts
44929
- import * as path47 from "node:path";
44955
+ import * as path48 from "node:path";
44930
44956
 
44931
44957
  // src/git/commits/lib/parse-log-lines.ts
44932
44958
  function parseLogShaDateSubjectLines(raw) {
@@ -44961,7 +44987,7 @@ async function gitLogNotReachableFromBase(g, baseSha, headSha) {
44961
44987
  }
44962
44988
  }
44963
44989
  async function listUnpushedCommits(repoDir) {
44964
- const key = path47.resolve(repoDir);
44990
+ const key = path48.resolve(repoDir);
44965
44991
  const now = Date.now();
44966
44992
  const cached2 = unpushedCache.get(key);
44967
44993
  if (cached2 && cached2.expiresAt > now) return cached2.commits;
@@ -45022,7 +45048,7 @@ async function loadRecentAndUnpushedCommitsForRepoDetail(repoDir, recentCommitsL
45022
45048
  }
45023
45049
 
45024
45050
  // src/git/changes/repo/load-working-tree-change-repo-git-info.ts
45025
- import * as path48 from "node:path";
45051
+ import * as path49 from "node:path";
45026
45052
 
45027
45053
  // src/git/remote-origin-url.ts
45028
45054
  async function getRemoteOriginUrl(gitDir) {
@@ -45037,7 +45063,7 @@ async function getRemoteOriginUrl(gitDir) {
45037
45063
 
45038
45064
  // src/git/changes/repo/load-working-tree-change-repo-git-info.ts
45039
45065
  async function loadWorkingTreeChangeRepoGitInfo(checkoutPath) {
45040
- const resolvedCheckoutPath = path48.resolve(checkoutPath);
45066
+ const resolvedCheckoutPath = path49.resolve(checkoutPath);
45041
45067
  const git = cliSimpleGit(resolvedCheckoutPath);
45042
45068
  await yieldToEventLoop2();
45043
45069
  const [branch, remoteUrl] = await Promise.all([
@@ -45052,14 +45078,14 @@ async function loadWorkingTreeChangeRepoGitInfo(checkoutPath) {
45052
45078
  }
45053
45079
 
45054
45080
  // src/git/changes/repo/resolve-repo-path-relative-to-workspace-root.ts
45055
- import * as path49 from "node:path";
45081
+ import * as path50 from "node:path";
45056
45082
  async function resolveRepoPathRelativeToWorkspaceRoot(options) {
45057
- const checkoutPath = path49.resolve(options.checkoutPath);
45083
+ const checkoutPath = path50.resolve(options.checkoutPath);
45058
45084
  const git = cliSimpleGit(checkoutPath);
45059
- const sessionParentPath = options.sessionParentPath ? path49.resolve(options.sessionParentPath) : null;
45085
+ const sessionParentPath = options.sessionParentPath ? path50.resolve(options.sessionParentPath) : null;
45060
45086
  let repoPathRelativeToWorkspaceRoot;
45061
45087
  if (sessionParentPath) {
45062
- const checkoutPathRelativeToSessionParent = path49.relative(sessionParentPath, checkoutPath);
45088
+ const checkoutPathRelativeToSessionParent = path50.relative(sessionParentPath, checkoutPath);
45063
45089
  repoPathRelativeToWorkspaceRoot = checkoutPathRelativeToSessionParent === "" ? "." : checkoutPathRelativeToSessionParent.replace(/\\/g, "/");
45064
45090
  } else {
45065
45091
  let gitTopLevel = checkoutPath;
@@ -45069,8 +45095,8 @@ async function resolveRepoPathRelativeToWorkspaceRoot(options) {
45069
45095
  } catch {
45070
45096
  gitTopLevel = checkoutPath;
45071
45097
  }
45072
- const gitTopLevelRelativeToBridgeRoot = path49.relative(options.bridgeRoot, path49.resolve(gitTopLevel)).replace(/\\/g, "/") || ".";
45073
- repoPathRelativeToWorkspaceRoot = gitTopLevelRelativeToBridgeRoot.startsWith("..") ? path49.basename(path49.resolve(gitTopLevel)) : gitTopLevelRelativeToBridgeRoot;
45098
+ const gitTopLevelRelativeToBridgeRoot = path50.relative(options.bridgeRoot, path50.resolve(gitTopLevel)).replace(/\\/g, "/") || ".";
45099
+ repoPathRelativeToWorkspaceRoot = gitTopLevelRelativeToBridgeRoot.startsWith("..") ? path50.basename(path50.resolve(gitTopLevel)) : gitTopLevelRelativeToBridgeRoot;
45074
45100
  }
45075
45101
  return normalizeRepoPathRelativeToWorkspaceRoot(
45076
45102
  repoPathRelativeToWorkspaceRoot === "" ? "." : repoPathRelativeToWorkspaceRoot
@@ -45079,10 +45105,10 @@ async function resolveRepoPathRelativeToWorkspaceRoot(options) {
45079
45105
 
45080
45106
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
45081
45107
  async function buildWorkingTreeChangeRepoDetail(options) {
45082
- const checkoutPath = path50.resolve(options.targetPath);
45108
+ const checkoutPath = path51.resolve(options.targetPath);
45083
45109
  if (!await isGitRepoDirectory(checkoutPath)) return null;
45084
45110
  const isCommitView = options.basis.kind === "commit";
45085
- const sessionParentPath = options.sessionParentPath ? path50.resolve(options.sessionParentPath) : null;
45111
+ const sessionParentPath = options.sessionParentPath ? path51.resolve(options.sessionParentPath) : null;
45086
45112
  const git = cliSimpleGit(checkoutPath);
45087
45113
  const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
45088
45114
  checkoutPath,
@@ -45130,8 +45156,8 @@ async function buildWorkingTreeChangeRepoDetail(options) {
45130
45156
 
45131
45157
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
45132
45158
  async function getWorkingTreeChangeRepoDetails(options) {
45133
- const bridgeRoot = path51.resolve(getBridgeRoot());
45134
- const sessionParentPath = options.sessionParentPath ? path51.resolve(options.sessionParentPath) : null;
45159
+ const bridgeRoot = path52.resolve(getBridgeRoot());
45160
+ const sessionParentPath = options.sessionParentPath ? path52.resolve(options.sessionParentPath) : null;
45135
45161
  const out = [];
45136
45162
  const filter = options.repoFilterRelPath != null ? normalizeRepoPathRelativeToWorkspaceRoot(options.repoFilterRelPath) : null;
45137
45163
  const basisInput = options.basis ?? { kind: "working" };
@@ -45162,9 +45188,9 @@ async function getWorkingTreeChangeRepoDetails(options) {
45162
45188
  }
45163
45189
 
45164
45190
  // src/git/changes/repo/get-working-tree-change-file-patch.ts
45165
- import * as path52 from "node:path";
45191
+ import * as path53 from "node:path";
45166
45192
  async function getWorkingTreeChangeFilePatch(options) {
45167
- const repoGitCwd = path52.resolve(options.repoGitCwd);
45193
+ const repoGitCwd = path53.resolve(options.repoGitCwd);
45168
45194
  if (!await isGitRepoDirectory(repoGitCwd)) {
45169
45195
  throw new Error("Not a git repository");
45170
45196
  }
@@ -45203,7 +45229,7 @@ async function getWorkingTreeChangeFilePatch(options) {
45203
45229
  });
45204
45230
  return { patchContent: patchContent2, totalLines: totalLines2 };
45205
45231
  }
45206
- const filePath = path52.join(repoGitCwd, filePathRelativeToRepoRoot);
45232
+ const filePath = path53.join(repoGitCwd, filePathRelativeToRepoRoot);
45207
45233
  const hydrateKind = options.change === "moved" ? "modified" : options.change;
45208
45234
  let patchContent = await unifiedDiffForFile(
45209
45235
  repoGitCwd,
@@ -45249,18 +45275,18 @@ function parseWorkingTreeChangeKind(value) {
45249
45275
  }
45250
45276
 
45251
45277
  // src/worktrees/manager/git/get-session-working-tree-change-file-patch.ts
45252
- import * as path53 from "node:path";
45278
+ import * as path54 from "node:path";
45253
45279
  async function getSessionWorkingTreeChangeFilePatch(cache2, sessionId, discover, opts) {
45254
45280
  const targets = await resolveCommitTargetsAsync(sessionId, cache2, discover);
45255
- const bridgeRoot = path53.resolve(getBridgeRoot());
45256
- const sessionParentPath = cache2.getSessionParentPath(sessionId) ? path53.resolve(cache2.getSessionParentPath(sessionId)) : null;
45281
+ const bridgeRoot = path54.resolve(getBridgeRoot());
45282
+ const sessionParentPath = cache2.getSessionParentPath(sessionId) ? path54.resolve(cache2.getSessionParentPath(sessionId)) : null;
45257
45283
  const repoPathRelativeToWorkspaceRootFilter = normalizeRepoPathRelativeToWorkspaceRoot(
45258
45284
  opts.repoRelPath.trim()
45259
45285
  );
45260
45286
  let result = null;
45261
45287
  await forEachWithGitYield(targets, async (targetPath) => {
45262
45288
  if (result) return;
45263
- const checkoutPath = path53.resolve(targetPath);
45289
+ const checkoutPath = path54.resolve(targetPath);
45264
45290
  if (!await isGitRepoDirectory(checkoutPath)) return;
45265
45291
  const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
45266
45292
  checkoutPath,
@@ -45293,13 +45319,13 @@ async function pushSessionUpstream(cache2, sessionId, discover) {
45293
45319
  }
45294
45320
 
45295
45321
  // src/worktrees/remove-session-worktrees.ts
45296
- import * as fs37 from "node:fs";
45322
+ import * as fs38 from "node:fs";
45297
45323
 
45298
45324
  // src/git/worktrees/worktree-remove.ts
45299
- import * as fs36 from "node:fs";
45325
+ import * as fs37 from "node:fs";
45300
45326
 
45301
45327
  // src/worktrees/is-removable-session-worktree-checkout-path.ts
45302
- import path54 from "node:path";
45328
+ import path55 from "node:path";
45303
45329
  init_normalize_resolved_path();
45304
45330
  function isBridgeRootCheckoutPath(checkoutPath) {
45305
45331
  return normalizeResolvedPath(checkoutPath) === normalizeResolvedPath(getBridgeRoot());
@@ -45308,23 +45334,23 @@ function isRemovableSessionWorktreeCheckoutPath(checkoutPath, worktreesRootPath)
45308
45334
  if (isBridgeRootCheckoutPath(checkoutPath)) return false;
45309
45335
  const normalized = normalizeResolvedPath(checkoutPath);
45310
45336
  const worktreesRoot = normalizeResolvedPath(worktreesRootPath);
45311
- const rel = path54.relative(worktreesRoot, normalized);
45312
- if (rel === "" || rel.startsWith("..") || path54.isAbsolute(rel)) return false;
45337
+ const rel = path55.relative(worktreesRoot, normalized);
45338
+ if (rel === "" || rel.startsWith("..") || path55.isAbsolute(rel)) return false;
45313
45339
  return true;
45314
45340
  }
45315
45341
 
45316
45342
  // src/git/worktrees/resolve-main-repo-from-git-file.ts
45317
- import * as fs35 from "node:fs";
45318
- import * as path55 from "node:path";
45343
+ import * as fs36 from "node:fs";
45344
+ import * as path56 from "node:path";
45319
45345
  function resolveMainRepoFromWorktreeGitFile(wt) {
45320
- const gitDirFile = path55.join(wt, ".git");
45321
- if (!fs35.existsSync(gitDirFile) || !fs35.statSync(gitDirFile).isFile()) return "";
45322
- const first2 = fs35.readFileSync(gitDirFile, "utf8").trim();
45346
+ const gitDirFile = path56.join(wt, ".git");
45347
+ if (!fs36.existsSync(gitDirFile) || !fs36.statSync(gitDirFile).isFile()) return "";
45348
+ const first2 = fs36.readFileSync(gitDirFile, "utf8").trim();
45323
45349
  const m = first2.match(/^gitdir:\s*(.+)$/im);
45324
45350
  if (!m) return "";
45325
- const gitWorktreePath = path55.resolve(wt, m[1].trim());
45326
- const gitDir = path55.dirname(path55.dirname(gitWorktreePath));
45327
- return path55.dirname(gitDir);
45351
+ const gitWorktreePath = path56.resolve(wt, m[1].trim());
45352
+ const gitDir = path56.dirname(path56.dirname(gitWorktreePath));
45353
+ return path56.dirname(gitDir);
45328
45354
  }
45329
45355
 
45330
45356
  // src/git/worktrees/worktree-remove.ts
@@ -45335,7 +45361,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
45335
45361
  return true;
45336
45362
  }
45337
45363
  if (isBridgeRootCheckoutPath(worktreePath)) return false;
45338
- fs36.rmSync(worktreePath, { recursive: true, force: true });
45364
+ fs37.rmSync(worktreePath, { recursive: true, force: true });
45339
45365
  return true;
45340
45366
  }
45341
45367
 
@@ -45357,7 +45383,7 @@ async function removeSessionWorktrees(paths, worktreesRootPath, log2) {
45357
45383
  log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
45358
45384
  if (isRemovableSessionWorktreeCheckoutPath(wt, worktreesRootPath)) {
45359
45385
  try {
45360
- fs37.rmSync(wt, { recursive: true, force: true });
45386
+ fs38.rmSync(wt, { recursive: true, force: true });
45361
45387
  } catch {
45362
45388
  }
45363
45389
  }
@@ -45382,6 +45408,7 @@ async function gitRenameCurrentBranch(repoDir, newName) {
45382
45408
  async function renameSessionWorktreeBranches(paths, newBranch, log2) {
45383
45409
  const safe = newBranch.replace(/[^a-zA-Z0-9/_-]+/g, "-").slice(0, 80) || "session-branch";
45384
45410
  await forEachWithGitYield(paths, async (wt) => {
45411
+ if (!await isGitRepoDirectory(wt)) return;
45385
45412
  try {
45386
45413
  await gitRenameCurrentBranch(wt, safe);
45387
45414
  log2(`[worktrees] Renamed branch in ${wt} \u2192 ${safe}`);
@@ -45403,12 +45430,12 @@ async function renameSessionWorktreeBranch(cache2, sessionId, newBranch, log2) {
45403
45430
  // src/worktrees/discovery/discover-session-worktree-on-disk.ts
45404
45431
  init_cli_process_interrupt();
45405
45432
  init_yield_to_event_loop();
45406
- import * as fs41 from "node:fs";
45407
- import * as path60 from "node:path";
45433
+ import * as fs42 from "node:fs";
45434
+ import * as path61 from "node:path";
45408
45435
 
45409
45436
  // src/worktrees/discovery/collect-worktree-paths.ts
45410
- import * as fs39 from "node:fs";
45411
- import * as path57 from "node:path";
45437
+ import * as fs40 from "node:fs";
45438
+ import * as path58 from "node:path";
45412
45439
 
45413
45440
  // src/worktrees/discovery/disk-walk-constants.ts
45414
45441
  var DISK_WALK_YIELD_EVERY = 64;
@@ -45438,8 +45465,8 @@ function shouldSkipDiskWalkEntry(name) {
45438
45465
  // src/worktrees/discovery/disk-walk-utils.ts
45439
45466
  init_cli_process_interrupt();
45440
45467
  init_yield_to_event_loop();
45441
- import * as fs38 from "node:fs";
45442
- import * as path56 from "node:path";
45468
+ import * as fs39 from "node:fs";
45469
+ import * as path57 from "node:path";
45443
45470
  async function yieldDuringDiskWalk(state) {
45444
45471
  state.entries++;
45445
45472
  if (state.entries % DISK_WALK_YIELD_EVERY !== 0) return true;
@@ -45449,7 +45476,7 @@ async function yieldDuringDiskWalk(state) {
45449
45476
  }
45450
45477
  async function isGitDir(dirPath) {
45451
45478
  try {
45452
- await fs38.promises.access(path56.join(dirPath, ".git"));
45479
+ await fs39.promises.access(path57.join(dirPath, ".git"));
45453
45480
  return true;
45454
45481
  } catch {
45455
45482
  return false;
@@ -45463,23 +45490,23 @@ async function collectGitRepoRootsUnderDirectory(rootPath) {
45463
45490
  const walk = async (dir) => {
45464
45491
  if (!await yieldDuringDiskWalk(state)) return;
45465
45492
  if (await isGitDir(dir)) {
45466
- out.push(path57.resolve(dir));
45493
+ out.push(path58.resolve(dir));
45467
45494
  return;
45468
45495
  }
45469
45496
  let entries;
45470
45497
  try {
45471
- entries = await fs39.promises.readdir(dir, { withFileTypes: true });
45498
+ entries = await fs40.promises.readdir(dir, { withFileTypes: true });
45472
45499
  } catch {
45473
45500
  return;
45474
45501
  }
45475
45502
  for (const e of entries) {
45476
45503
  if (shouldSkipDiskWalkEntry(e.name)) continue;
45477
- const full = path57.join(dir, e.name);
45504
+ const full = path58.join(dir, e.name);
45478
45505
  if (!e.isDirectory()) continue;
45479
45506
  await walk(full);
45480
45507
  }
45481
45508
  };
45482
- await walk(path57.resolve(rootPath));
45509
+ await walk(path58.resolve(rootPath));
45483
45510
  return { paths: [...new Set(out)], entriesVisited: state.entries };
45484
45511
  }
45485
45512
  async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK_MAX_DEPTH) {
@@ -45490,16 +45517,16 @@ async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK
45490
45517
  if (!await yieldDuringDiskWalk(state)) return;
45491
45518
  let entries;
45492
45519
  try {
45493
- entries = await fs39.promises.readdir(dir, { withFileTypes: true });
45520
+ entries = await fs40.promises.readdir(dir, { withFileTypes: true });
45494
45521
  } catch {
45495
45522
  return;
45496
45523
  }
45497
45524
  for (const e of entries) {
45498
45525
  if (shouldSkipDiskWalkEntry(e.name)) continue;
45499
- const full = path57.join(dir, e.name);
45526
+ const full = path58.join(dir, e.name);
45500
45527
  if (!e.isDirectory()) continue;
45501
45528
  if (e.name === sessionId) {
45502
- if (await isGitDir(full)) out.push(path57.resolve(full));
45529
+ if (await isGitDir(full)) out.push(path58.resolve(full));
45503
45530
  continue;
45504
45531
  }
45505
45532
  if (await isGitDir(full)) continue;
@@ -45511,14 +45538,14 @@ async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK
45511
45538
  }
45512
45539
 
45513
45540
  // src/worktrees/discovery/layout-keys-for-bridge-root.ts
45514
- import * as path58 from "node:path";
45541
+ import * as path59 from "node:path";
45515
45542
  function layoutKeysForBridgeRoot(layout, bridgeRoot, keysOnDisk) {
45516
- const bridge = path58.resolve(bridgeRoot);
45543
+ const bridge = path59.resolve(bridgeRoot);
45517
45544
  const preferred = getLauncherDirNameIfPresent(layout, bridgeRoot);
45518
45545
  const relevant = layout.launcherCwds.filter((e) => {
45519
- const entry = path58.resolve(e.absolutePath);
45520
- return bridge === entry || bridge.startsWith(entry + path58.sep) || entry.startsWith(bridge + path58.sep);
45521
- }).sort((a, b) => path58.resolve(b.absolutePath).length - path58.resolve(a.absolutePath).length).map((e) => e.dirName).filter((name) => keysOnDisk.includes(name));
45546
+ const entry = path59.resolve(e.absolutePath);
45547
+ return bridge === entry || bridge.startsWith(entry + path59.sep) || entry.startsWith(bridge + path59.sep);
45548
+ }).sort((a, b) => path59.resolve(b.absolutePath).length - path59.resolve(a.absolutePath).length).map((e) => e.dirName).filter((name) => keysOnDisk.includes(name));
45522
45549
  const ordered = [];
45523
45550
  const seen = /* @__PURE__ */ new Set();
45524
45551
  const add = (k) => {
@@ -45536,19 +45563,19 @@ function layoutKeysForBridgeRoot(layout, bridgeRoot, keysOnDisk) {
45536
45563
  }
45537
45564
 
45538
45565
  // src/worktrees/discovery/try-binding-from-isolated-directory.ts
45539
- import * as fs40 from "node:fs";
45540
- import * as path59 from "node:path";
45566
+ import * as fs41 from "node:fs";
45567
+ import * as path60 from "node:path";
45541
45568
  async function tryBindingFromIsolatedDirectory(scopeDir) {
45542
45569
  let st;
45543
45570
  try {
45544
- st = await fs40.promises.stat(scopeDir);
45571
+ st = await fs41.promises.stat(scopeDir);
45545
45572
  } catch {
45546
45573
  return null;
45547
45574
  }
45548
45575
  if (!st.isDirectory()) return null;
45549
45576
  const { paths: worktreePaths } = await collectGitRepoRootsUnderDirectory(scopeDir);
45550
45577
  if (worktreePaths.length === 0) return null;
45551
- const abs = path59.resolve(scopeDir);
45578
+ const abs = path60.resolve(scopeDir);
45552
45579
  return {
45553
45580
  parentPath: abs,
45554
45581
  repoCheckoutPaths: worktreePaths
@@ -45571,7 +45598,7 @@ async function discoverSessionWorktreeOnDisk(options) {
45571
45598
  const sid = sessionId.trim();
45572
45599
  if (!sid) return null;
45573
45600
  try {
45574
- await fs41.promises.access(worktreesRootPath);
45601
+ await fs42.promises.access(worktreesRootPath);
45575
45602
  } catch {
45576
45603
  return null;
45577
45604
  }
@@ -45580,13 +45607,13 @@ async function discoverSessionWorktreeOnDisk(options) {
45580
45607
  if (preferredKey) keysOnDisk.push(preferredKey);
45581
45608
  const scanState = { entries: 0 };
45582
45609
  try {
45583
- for (const name of await fs41.promises.readdir(worktreesRootPath)) {
45610
+ for (const name of await fs42.promises.readdir(worktreesRootPath)) {
45584
45611
  if (!await yieldDuringDiskWalk(scanState)) break;
45585
45612
  if (name.startsWith(".")) continue;
45586
- const p = path60.join(worktreesRootPath, name);
45613
+ const p = path61.join(worktreesRootPath, name);
45587
45614
  let st;
45588
45615
  try {
45589
- st = await fs41.promises.stat(p);
45616
+ st = await fs42.promises.stat(p);
45590
45617
  } catch {
45591
45618
  continue;
45592
45619
  }
@@ -45600,23 +45627,23 @@ async function discoverSessionWorktreeOnDisk(options) {
45600
45627
  for (const key of keys) {
45601
45628
  if (isCliImmediateShutdownRequested()) return null;
45602
45629
  await yieldToEventLoop();
45603
- const layoutRoot = path60.join(worktreesRootPath, key);
45630
+ const layoutRoot = path61.join(worktreesRootPath, key);
45604
45631
  let layoutSt;
45605
45632
  try {
45606
- layoutSt = await fs41.promises.stat(layoutRoot);
45633
+ layoutSt = await fs42.promises.stat(layoutRoot);
45607
45634
  } catch {
45608
45635
  continue;
45609
45636
  }
45610
45637
  if (!layoutSt.isDirectory()) continue;
45611
- const sessionDir = path60.join(layoutRoot, sid);
45638
+ const sessionDir = path61.join(layoutRoot, sid);
45612
45639
  const nested = await tryBindingFromSessionDirectory(sessionDir);
45613
45640
  if (nested) return nested;
45614
45641
  const legacy = await collectWorktreeRootsNamed(layoutRoot, sid);
45615
45642
  if (legacy.paths.length > 0) {
45616
- const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacy.paths) ?? path60.resolve(legacy.paths[0]);
45643
+ const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacy.paths) ?? path61.resolve(legacy.paths[0]);
45617
45644
  return {
45618
- sessionParentPath: path60.resolve(isolated),
45619
- repoCheckoutPaths: legacy.paths.map((p) => path60.resolve(p))
45645
+ sessionParentPath: path61.resolve(isolated),
45646
+ repoCheckoutPaths: legacy.paths.map((p) => path61.resolve(p))
45620
45647
  };
45621
45648
  }
45622
45649
  }
@@ -45624,31 +45651,31 @@ async function discoverSessionWorktreeOnDisk(options) {
45624
45651
  }
45625
45652
 
45626
45653
  // src/worktrees/discovery/discover-session-worktrees-under-session-worktree-root.ts
45627
- import * as fs42 from "node:fs";
45628
- import * as path62 from "node:path";
45654
+ import * as fs43 from "node:fs";
45655
+ import * as path63 from "node:path";
45629
45656
 
45630
45657
  // src/worktrees/discovery/discover-legacy-binding-ascending-from-checkout.ts
45631
45658
  init_cli_process_interrupt();
45632
45659
  init_yield_to_event_loop();
45633
- import * as path61 from "node:path";
45660
+ import * as path62 from "node:path";
45634
45661
  async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
45635
45662
  const sid = sessionId.trim();
45636
45663
  if (!sid) return null;
45637
- const hintR = path61.resolve(checkoutPath);
45664
+ const hintR = path62.resolve(checkoutPath);
45638
45665
  let best = null;
45639
- let cur = path61.dirname(hintR);
45666
+ let cur = path62.dirname(hintR);
45640
45667
  for (let i = 0; i < 40; i++) {
45641
45668
  if (isCliImmediateShutdownRequested()) return best;
45642
45669
  await yieldToEventLoop();
45643
45670
  const paths = await collectWorktreeRootsNamed(cur, sid);
45644
- if (paths.paths.some((p) => path61.resolve(p) === hintR)) {
45645
- const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths.paths) ?? path61.resolve(paths.paths[0]);
45671
+ if (paths.paths.some((p) => path62.resolve(p) === hintR)) {
45672
+ const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths.paths) ?? path62.resolve(paths.paths[0]);
45646
45673
  best = {
45647
- sessionParentPath: path61.resolve(isolated),
45648
- repoCheckoutPaths: paths.paths.map((p) => path61.resolve(p))
45674
+ sessionParentPath: path62.resolve(isolated),
45675
+ repoCheckoutPaths: paths.paths.map((p) => path62.resolve(p))
45649
45676
  };
45650
45677
  }
45651
- const next = path61.dirname(cur);
45678
+ const next = path62.dirname(cur);
45652
45679
  if (next === cur) break;
45653
45680
  cur = next;
45654
45681
  }
@@ -45659,12 +45686,12 @@ async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPat
45659
45686
  async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionParentPathOrHint, sessionId) {
45660
45687
  const sid = sessionId.trim();
45661
45688
  if (!sid) return null;
45662
- const hint = path62.resolve(sessionParentPathOrHint);
45663
- const underHint = await tryBindingFromSessionDirectory(path62.join(hint, sid));
45689
+ const hint = path63.resolve(sessionParentPathOrHint);
45690
+ const underHint = await tryBindingFromSessionDirectory(path63.join(hint, sid));
45664
45691
  if (underHint) return underHint;
45665
45692
  const direct = await tryBindingFromSessionDirectory(hint);
45666
45693
  if (direct) {
45667
- if (path62.basename(hint) === sid && await isGitDir(hint)) {
45694
+ if (path63.basename(hint) === sid && await isGitDir(hint)) {
45668
45695
  const legacyFromCheckout = await discoverLegacyBindingAscendingFromCheckout(sid, hint);
45669
45696
  if (legacyFromCheckout && legacyFromCheckout.repoCheckoutPaths.length > direct.repoCheckoutPaths.length) {
45670
45697
  return legacyFromCheckout;
@@ -45672,23 +45699,23 @@ async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionParentPat
45672
45699
  }
45673
45700
  return direct;
45674
45701
  }
45675
- if (path62.basename(hint) === sid && await isGitDir(hint)) {
45702
+ if (path63.basename(hint) === sid && await isGitDir(hint)) {
45676
45703
  const legacyFromCheckout = await discoverLegacyBindingAscendingFromCheckout(sid, hint);
45677
45704
  if (legacyFromCheckout) return legacyFromCheckout;
45678
45705
  }
45679
45706
  let st;
45680
45707
  try {
45681
- st = await fs42.promises.stat(hint);
45708
+ st = await fs43.promises.stat(hint);
45682
45709
  } catch {
45683
45710
  return null;
45684
45711
  }
45685
45712
  if (!st.isDirectory()) return null;
45686
45713
  const legacyPaths = await collectWorktreeRootsNamed(hint, sid);
45687
45714
  if (legacyPaths.paths.length === 0) return null;
45688
- const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths.paths) ?? path62.resolve(legacyPaths.paths[0]);
45715
+ const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths.paths) ?? path63.resolve(legacyPaths.paths[0]);
45689
45716
  return {
45690
- sessionParentPath: path62.resolve(isolated),
45691
- repoCheckoutPaths: legacyPaths.paths.map((p) => path62.resolve(p))
45717
+ sessionParentPath: path63.resolve(isolated),
45718
+ repoCheckoutPaths: legacyPaths.paths.map((p) => path63.resolve(p))
45692
45719
  };
45693
45720
  }
45694
45721
 
@@ -45749,11 +45776,11 @@ function parseSessionParent(v) {
45749
45776
  }
45750
45777
 
45751
45778
  // src/worktrees/prepare/prepare-new-isolated-worktrees.ts
45752
- import * as fs46 from "node:fs";
45779
+ import * as fs47 from "node:fs";
45753
45780
 
45754
45781
  // src/git/discover-repos.ts
45755
- import * as fs43 from "node:fs";
45756
- import * as path63 from "node:path";
45782
+ import * as fs44 from "node:fs";
45783
+ import * as path64 from "node:path";
45757
45784
  init_yield_to_event_loop();
45758
45785
  var GIT_DISCOVER_YIELD_EVERY = 32;
45759
45786
  async function yieldGitDiscoverWork(entryCount) {
@@ -45763,14 +45790,14 @@ async function yieldGitDiscoverWork(entryCount) {
45763
45790
  }
45764
45791
  async function discoverGitRepos(cwd = getBridgeRoot()) {
45765
45792
  const result = [];
45766
- const cwdResolved = path63.resolve(cwd);
45793
+ const cwdResolved = path64.resolve(cwd);
45767
45794
  if (await isGitRepoDirectory(cwdResolved)) {
45768
45795
  const remoteUrl = await getRemoteOriginUrl(cwdResolved);
45769
45796
  result.push({ absolutePath: cwdResolved, remoteUrl });
45770
45797
  }
45771
45798
  let entries;
45772
45799
  try {
45773
- entries = fs43.readdirSync(cwdResolved, { withFileTypes: true });
45800
+ entries = fs44.readdirSync(cwdResolved, { withFileTypes: true });
45774
45801
  } catch {
45775
45802
  return result;
45776
45803
  }
@@ -45778,7 +45805,7 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
45778
45805
  await yieldGitDiscoverWork(i + 1);
45779
45806
  const ent = entries[i];
45780
45807
  if (!ent.isDirectory()) continue;
45781
- const childPath2 = path63.join(cwdResolved, ent.name);
45808
+ const childPath2 = path64.join(cwdResolved, ent.name);
45782
45809
  if (await isGitRepoDirectory(childPath2)) {
45783
45810
  const remoteUrl = await getRemoteOriginUrl(childPath2);
45784
45811
  result.push({ absolutePath: childPath2, remoteUrl });
@@ -45787,17 +45814,17 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
45787
45814
  return result;
45788
45815
  }
45789
45816
  async function discoverGitReposUnderRoot(rootPath) {
45790
- const root = path63.resolve(rootPath);
45817
+ const root = path64.resolve(rootPath);
45791
45818
  const roots = [];
45792
45819
  let walkEntries = 0;
45793
45820
  async function walk(dir) {
45794
45821
  if (await isGitRepoDirectory(dir)) {
45795
- roots.push(path63.resolve(dir));
45822
+ roots.push(path64.resolve(dir));
45796
45823
  return;
45797
45824
  }
45798
45825
  let entries;
45799
45826
  try {
45800
- entries = fs43.readdirSync(dir, { withFileTypes: true });
45827
+ entries = fs44.readdirSync(dir, { withFileTypes: true });
45801
45828
  } catch {
45802
45829
  return;
45803
45830
  }
@@ -45805,7 +45832,7 @@ async function discoverGitReposUnderRoot(rootPath) {
45805
45832
  await yieldGitDiscoverWork(++walkEntries);
45806
45833
  const ent = entries[i];
45807
45834
  if (!ent.isDirectory() || ent.name === ".git") continue;
45808
- await walk(path63.join(dir, ent.name));
45835
+ await walk(path64.join(dir, ent.name));
45809
45836
  }
45810
45837
  }
45811
45838
  await walk(root);
@@ -45821,8 +45848,8 @@ async function discoverGitReposUnderRoot(rootPath) {
45821
45848
  }
45822
45849
 
45823
45850
  // src/worktrees/prepare/add-isolated-repo-worktree.ts
45824
- import * as fs45 from "node:fs";
45825
- import * as path65 from "node:path";
45851
+ import * as fs46 from "node:fs";
45852
+ import * as path66 from "node:path";
45826
45853
 
45827
45854
  // src/git/worktrees/worktree-add.ts
45828
45855
  async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch, baseRef = "HEAD") {
@@ -45838,8 +45865,8 @@ async function gitWorktreeAddExistingBranch(mainRepoPath, worktreePath, branch)
45838
45865
  }
45839
45866
 
45840
45867
  // src/worktrees/prepare/copy-bridge-files-along-worktree-path.ts
45841
- import * as fs44 from "node:fs";
45842
- import * as path64 from "node:path";
45868
+ import * as fs45 from "node:fs";
45869
+ import * as path65 from "node:path";
45843
45870
  var BRIDGE_FILES_ALONG_WORKTREE_PATH = ["AGENTS.md"];
45844
45871
  function copyBridgeFilesAlongWorktreePath(options) {
45845
45872
  const { bridgeRoot, scopeDir, repoPathRelativeToBridgeRoot, log: log2 } = options;
@@ -45848,19 +45875,19 @@ function copyBridgeFilesAlongWorktreePath(options) {
45848
45875
  const segments = repoPathRelativeToBridgeRoot.split("/").filter(Boolean);
45849
45876
  for (let i = 0; i < segments.length; i++) {
45850
45877
  const prefix = segments.slice(0, i).join("/");
45851
- const bridgeDir = prefix ? path64.join(bridgeRoot, prefix) : bridgeRoot;
45852
- const destDir = prefix ? path64.join(scopeDir, prefix) : scopeDir;
45878
+ const bridgeDir = prefix ? path65.join(bridgeRoot, prefix) : bridgeRoot;
45879
+ const destDir = prefix ? path65.join(scopeDir, prefix) : scopeDir;
45853
45880
  for (const fileName of fileNames) {
45854
45881
  copyFileIfPresent(bridgeDir, destDir, fileName, log2);
45855
45882
  }
45856
45883
  }
45857
45884
  }
45858
45885
  function copyFileIfPresent(srcDir, destDir, fileName, log2) {
45859
- const src = path64.join(srcDir, fileName);
45860
- if (!fs44.existsSync(src)) return;
45861
- const dest = path64.join(destDir, fileName);
45886
+ const src = path65.join(srcDir, fileName);
45887
+ if (!fs45.existsSync(src)) return;
45888
+ const dest = path65.join(destDir, fileName);
45862
45889
  try {
45863
- fs44.copyFileSync(src, dest);
45890
+ fs45.copyFileSync(src, dest);
45864
45891
  log2?.(`[worktrees] Copied ${fileName} to ${dest}`);
45865
45892
  } catch (e) {
45866
45893
  log2?.(
@@ -45892,16 +45919,16 @@ async function addIsolatedRepoWorktree(options) {
45892
45919
  worktreeBaseBranches,
45893
45920
  log: log2
45894
45921
  } = options;
45895
- const repoPathRelativeToBridgeRootRaw = path65.relative(bridgeResolved, repoAbsolutePath);
45896
- if (repoPathRelativeToBridgeRootRaw.startsWith("..") || path65.isAbsolute(repoPathRelativeToBridgeRootRaw)) {
45922
+ const repoPathRelativeToBridgeRootRaw = path66.relative(bridgeResolved, repoAbsolutePath);
45923
+ if (repoPathRelativeToBridgeRootRaw.startsWith("..") || path66.isAbsolute(repoPathRelativeToBridgeRootRaw)) {
45897
45924
  return null;
45898
45925
  }
45899
45926
  const repoPathRelativeToBridgeRoot = normalizeRepoPathRelativeToWorkspaceRoot(
45900
45927
  repoPathRelativeToBridgeRootRaw === "" ? "." : repoPathRelativeToBridgeRootRaw
45901
45928
  );
45902
- const worktreePath = repoPathRelativeToBridgeRoot === "." ? scopeDir : path65.join(scopeDir, repoPathRelativeToBridgeRoot);
45929
+ const worktreePath = repoPathRelativeToBridgeRoot === "." ? scopeDir : path66.join(scopeDir, repoPathRelativeToBridgeRoot);
45903
45930
  if (repoPathRelativeToBridgeRoot !== ".") {
45904
- fs45.mkdirSync(path65.dirname(worktreePath), { recursive: true });
45931
+ fs46.mkdirSync(path66.dirname(worktreePath), { recursive: true });
45905
45932
  copyBridgeFilesAlongWorktreePath({
45906
45933
  bridgeRoot: bridgeResolved,
45907
45934
  scopeDir,
@@ -45929,7 +45956,7 @@ async function addIsolatedRepoWorktree(options) {
45929
45956
  }
45930
45957
 
45931
45958
  // src/worktrees/prepare/resolve-isolated-scope-dir.ts
45932
- import * as path66 from "node:path";
45959
+ import * as path67 from "node:path";
45933
45960
 
45934
45961
  // src/worktrees/worktree-layout-kind.ts
45935
45962
  function sanitizeWorktreeBranchSegment(value) {
@@ -45959,10 +45986,10 @@ function previewDeployBranchName(environmentId) {
45959
45986
 
45960
45987
  // src/worktrees/prepare/resolve-isolated-scope-dir.ts
45961
45988
  function resolveIsolatedScopeDir(options) {
45962
- const bridgeResolved = path66.resolve(options.bridgeRoot);
45989
+ const bridgeResolved = path67.resolve(options.bridgeRoot);
45963
45990
  const cwdKey = allocateDirNameForLauncherCwd(options.layout, bridgeResolved);
45964
- const bridgeKeyDir = path66.join(options.worktreesRootPath, cwdKey);
45965
- const scopeDir = path66.join(bridgeKeyDir, ...layoutDirSegments(options.kind, options.scopeId));
45991
+ const bridgeKeyDir = path67.join(options.worktreesRootPath, cwdKey);
45992
+ const scopeDir = path67.join(bridgeKeyDir, ...layoutDirSegments(options.kind, options.scopeId));
45966
45993
  return { bridgeResolved, scopeDir };
45967
45994
  }
45968
45995
 
@@ -45992,7 +46019,7 @@ async function prepareNewIsolatedWorktrees(options) {
45992
46019
  return null;
45993
46020
  }
45994
46021
  const worktreePaths = [];
45995
- fs46.mkdirSync(scopeDir, { recursive: true });
46022
+ fs47.mkdirSync(scopeDir, { recursive: true });
45996
46023
  await forEachWithGitYield(repos, async (repo) => {
45997
46024
  const worktreePath = await addIsolatedRepoWorktree({
45998
46025
  kind,
@@ -46064,10 +46091,10 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
46064
46091
  }
46065
46092
 
46066
46093
  // src/worktrees/manager/resolve-explicit-session-parent-path.ts
46067
- import * as path67 from "node:path";
46094
+ import * as path68 from "node:path";
46068
46095
  init_yield_to_event_loop();
46069
46096
  async function resolveExplicitSessionParentPath(params) {
46070
- const resolved = path67.resolve(params.parentPathRaw);
46097
+ const resolved = path68.resolve(params.parentPathRaw);
46071
46098
  if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
46072
46099
  return resolved;
46073
46100
  }
@@ -46084,7 +46111,7 @@ async function resolveExplicitSessionParentPath(params) {
46084
46111
  await yieldToEventLoop();
46085
46112
  const tryRoot = await discoverSessionWorktreesUnderSessionWorktreeRoot(cur, params.sessionId);
46086
46113
  if (tryRoot) return rememberAndReturn(tryRoot);
46087
- const next = path67.dirname(cur);
46114
+ const next = path68.dirname(cur);
46088
46115
  if (next === cur) break;
46089
46116
  cur = next;
46090
46117
  }
@@ -46232,15 +46259,15 @@ var SessionWorktreeManager = class {
46232
46259
  };
46233
46260
 
46234
46261
  // src/worktrees/discovery/discover-preview-worktree-on-disk.ts
46235
- import * as fs47 from "node:fs";
46236
- import * as path68 from "node:path";
46262
+ import * as fs48 from "node:fs";
46263
+ import * as path69 from "node:path";
46237
46264
  init_yield_to_event_loop();
46238
46265
  async function discoverPreviewWorktreeOnDisk(options) {
46239
46266
  const { environmentId, worktreesRootPath, layout, bridgeRoot } = options;
46240
46267
  const eid = environmentId.trim();
46241
46268
  if (!eid) return null;
46242
46269
  try {
46243
- await fs47.promises.access(worktreesRootPath);
46270
+ await fs48.promises.access(worktreesRootPath);
46244
46271
  } catch {
46245
46272
  return null;
46246
46273
  }
@@ -46249,13 +46276,13 @@ async function discoverPreviewWorktreeOnDisk(options) {
46249
46276
  if (preferredKey) keysOnDisk.push(preferredKey);
46250
46277
  const scanState = { entries: 0 };
46251
46278
  try {
46252
- for (const name of await fs47.promises.readdir(worktreesRootPath)) {
46279
+ for (const name of await fs48.promises.readdir(worktreesRootPath)) {
46253
46280
  if (!await yieldDuringDiskWalk(scanState)) break;
46254
46281
  if (name.startsWith(".")) continue;
46255
- const p = path68.join(worktreesRootPath, name);
46282
+ const p = path69.join(worktreesRootPath, name);
46256
46283
  let st;
46257
46284
  try {
46258
- st = await fs47.promises.stat(p);
46285
+ st = await fs48.promises.stat(p);
46259
46286
  } catch {
46260
46287
  continue;
46261
46288
  }
@@ -46269,7 +46296,7 @@ async function discoverPreviewWorktreeOnDisk(options) {
46269
46296
  const previewDirRel = layoutDirSegments("preview_environment", eid);
46270
46297
  for (const key of keys) {
46271
46298
  await yieldToEventLoop();
46272
- const previewDir = path68.join(worktreesRootPath, key, ...previewDirRel);
46299
+ const previewDir = path69.join(worktreesRootPath, key, ...previewDirRel);
46273
46300
  const binding = await tryBindingFromIsolatedDirectory(previewDir);
46274
46301
  if (binding) return binding;
46275
46302
  }
@@ -46396,7 +46423,7 @@ var PreviewWorktreeManager = class {
46396
46423
  };
46397
46424
 
46398
46425
  // src/worktrees/deploy/deploy-session-to-preview-environment.ts
46399
- import * as path72 from "node:path";
46426
+ import * as path73 from "node:path";
46400
46427
 
46401
46428
  // src/git/worktrees/reset-worktree-to-branch.ts
46402
46429
  async function gitResetWorktreeToBranch(worktreePath, branch) {
@@ -46407,8 +46434,8 @@ async function gitResetWorktreeToBranch(worktreePath, branch) {
46407
46434
  }
46408
46435
 
46409
46436
  // src/worktrees/deploy/capture-and-apply-wip.ts
46410
- import * as fs48 from "node:fs";
46411
- import * as path69 from "node:path";
46437
+ import * as fs49 from "node:fs";
46438
+ import * as path70 from "node:path";
46412
46439
 
46413
46440
  // src/git/snapshot/git.ts
46414
46441
  async function gitStashCreate(repoRoot, log2) {
@@ -46456,12 +46483,12 @@ async function applyWorkingTreeWip(targetRepoPath, sourceRepoPath, wip, log2) {
46456
46483
  if (!ap.ok) return ap;
46457
46484
  }
46458
46485
  await forEachWithGitYield(wip.untrackedPaths, async (rel) => {
46459
- const src = path69.join(sourceRepoPath, rel);
46460
- const dst = path69.join(targetRepoPath, rel);
46486
+ const src = path70.join(sourceRepoPath, rel);
46487
+ const dst = path70.join(targetRepoPath, rel);
46461
46488
  try {
46462
- if (!fs48.existsSync(src)) return;
46463
- fs48.mkdirSync(path69.dirname(dst), { recursive: true });
46464
- fs48.copyFileSync(src, dst);
46489
+ if (!fs49.existsSync(src)) return;
46490
+ fs49.mkdirSync(path70.dirname(dst), { recursive: true });
46491
+ fs49.copyFileSync(src, dst);
46465
46492
  } catch (e) {
46466
46493
  log2(
46467
46494
  `[worktrees] Failed to copy untracked ${rel}: ${e instanceof Error ? e.message : String(e)}`
@@ -46472,14 +46499,14 @@ async function applyWorkingTreeWip(targetRepoPath, sourceRepoPath, wip, log2) {
46472
46499
  }
46473
46500
 
46474
46501
  // src/worktrees/deploy/resolve-isolated-checkout-for-repo-path-relative-to-workspace-root.ts
46475
- import * as path70 from "node:path";
46502
+ import * as path71 from "node:path";
46476
46503
  async function resolveIsolatedCheckoutForRepoPathRelativeToWorkspaceRoot(options) {
46477
46504
  const { checkoutPaths, sessionParentPath, bridgeRoot, repoPathRelativeToWorkspaceRoot } = options;
46478
- const resolvedSessionParentPath = sessionParentPath ? path70.resolve(sessionParentPath) : null;
46505
+ const resolvedSessionParentPath = sessionParentPath ? path71.resolve(sessionParentPath) : null;
46479
46506
  let match = null;
46480
46507
  await forEachWithGitYield(checkoutPaths, async (checkoutPath) => {
46481
46508
  if (match) return;
46482
- const resolvedCheckoutPath = path70.resolve(checkoutPath);
46509
+ const resolvedCheckoutPath = path71.resolve(checkoutPath);
46483
46510
  if (!await isGitRepoDirectory(resolvedCheckoutPath)) return;
46484
46511
  const resolvedRepoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
46485
46512
  checkoutPath: resolvedCheckoutPath,
@@ -46533,7 +46560,7 @@ async function applySessionWipToPreviewCheckouts(options) {
46533
46560
  }
46534
46561
 
46535
46562
  // src/worktrees/deploy/collect-session-repo-deploy-states.ts
46536
- import * as path71 from "node:path";
46563
+ import * as path72 from "node:path";
46537
46564
 
46538
46565
  // src/git/branches/create-or-update-branch.ts
46539
46566
  async function gitCreateOrUpdateBranch(repoPath, branch, startRef, options) {
@@ -46570,19 +46597,19 @@ async function collectSessionRepoDeployStates(options) {
46570
46597
  const sessionParentPath = sessionWorktreeManager.getSessionParentPath(sid);
46571
46598
  const states = [];
46572
46599
  await forEachWithGitYield(sessionTargets, async (sessionCheckout) => {
46573
- const checkoutPath = path71.resolve(sessionCheckout);
46600
+ const checkoutPath = path72.resolve(sessionCheckout);
46574
46601
  if (!await isGitRepoDirectory(checkoutPath)) return;
46575
46602
  const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
46576
46603
  checkoutPath,
46577
46604
  bridgeRoot,
46578
- sessionParentPath: sessionParentPath ? path71.resolve(sessionParentPath) : null
46605
+ sessionParentPath: sessionParentPath ? path72.resolve(sessionParentPath) : null
46579
46606
  });
46580
46607
  if (!repoPathRelativeToWorkspaceRoot) return;
46581
46608
  const mainRepoPath = resolveMainRepoPath(checkoutPath);
46582
46609
  const headSha = (await cliSimpleGit(checkoutPath).revparse(["HEAD"])).trim();
46583
46610
  const previewCheckout = previewCheckoutPaths.length > 0 ? await resolveIsolatedCheckoutForRepoPathRelativeToWorkspaceRoot({
46584
46611
  checkoutPaths: previewCheckoutPaths,
46585
- sessionParentPath: previewParentPath ? path71.resolve(previewParentPath) : null,
46612
+ sessionParentPath: previewParentPath ? path72.resolve(previewParentPath) : null,
46586
46613
  bridgeRoot,
46587
46614
  repoPathRelativeToWorkspaceRoot
46588
46615
  }) : null;
@@ -46602,7 +46629,7 @@ async function deploySessionToPreviewEnvironment(options) {
46602
46629
  const eid = options.environmentId.trim();
46603
46630
  if (!sid || !eid) return { ok: false, error: "sessionId and environmentId are required" };
46604
46631
  const deployBranch = previewDeployBranchName(eid);
46605
- const bridgeRoot = path72.resolve(getBridgeRoot());
46632
+ const bridgeRoot = path73.resolve(getBridgeRoot());
46606
46633
  await previewWorktreeManager.ensureCached(eid);
46607
46634
  const existingPreviewParentPath = previewWorktreeManager.getPreviewParentPath(eid) ?? null;
46608
46635
  const existingPreviewCheckoutPaths = previewWorktreeManager.getRepoCheckoutPaths(eid) ?? [];
@@ -46642,10 +46669,10 @@ async function deploySessionToPreviewEnvironment(options) {
46642
46669
  }
46643
46670
 
46644
46671
  // src/worktrees/manager/default-worktrees-root-path.ts
46645
- import * as path73 from "node:path";
46672
+ import * as path74 from "node:path";
46646
46673
  import os9 from "node:os";
46647
46674
  function defaultWorktreesRootPath() {
46648
- return path73.join(os9.homedir(), ".buildautomaton", "worktrees");
46675
+ return path74.join(os9.homedir(), ".buildautomaton", "worktrees");
46649
46676
  }
46650
46677
 
46651
46678
  // src/connection/create-bridge-worktree-managers.ts
@@ -46775,14 +46802,14 @@ function assertBridgeWorkspace(ctx) {
46775
46802
  }
46776
46803
 
46777
46804
  // src/files/list-dir/index.ts
46778
- import fs50 from "node:fs";
46805
+ import fs51 from "node:fs";
46779
46806
 
46780
46807
  // src/files/ensure-under-cwd.ts
46781
- import path74 from "node:path";
46808
+ import path75 from "node:path";
46782
46809
  function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
46783
- const normalized = path74.normalize(relativePath).replace(/^(\.\/)+/, "");
46784
- const resolved = path74.resolve(cwd, normalized);
46785
- if (!resolved.startsWith(cwd + path74.sep) && resolved !== cwd) {
46810
+ const normalized = path75.normalize(relativePath).replace(/^(\.\/)+/, "");
46811
+ const resolved = path75.resolve(cwd, normalized);
46812
+ if (!resolved.startsWith(cwd + path75.sep) && resolved !== cwd) {
46786
46813
  return null;
46787
46814
  }
46788
46815
  return resolved;
@@ -46795,15 +46822,15 @@ init_yield_to_event_loop();
46795
46822
  var LIST_DIR_YIELD_EVERY = 256;
46796
46823
 
46797
46824
  // src/files/list-dir/map-dir-entry.ts
46798
- import path75 from "node:path";
46799
- import fs49 from "node:fs";
46825
+ import path76 from "node:path";
46826
+ import fs50 from "node:fs";
46800
46827
  async function mapDirEntry(d, relativePath, resolved) {
46801
- const entryPath = path75.join(relativePath || ".", d.name).replace(/\\/g, "/");
46802
- const fullPath = path75.join(resolved, d.name);
46828
+ const entryPath = path76.join(relativePath || ".", d.name).replace(/\\/g, "/");
46829
+ const fullPath = path76.join(resolved, d.name);
46803
46830
  let isDir = d.isDirectory();
46804
46831
  if (d.isSymbolicLink()) {
46805
46832
  try {
46806
- const targetStat = await fs49.promises.stat(fullPath);
46833
+ const targetStat = await fs50.promises.stat(fullPath);
46807
46834
  isDir = targetStat.isDirectory();
46808
46835
  } catch {
46809
46836
  isDir = false;
@@ -46833,7 +46860,7 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
46833
46860
  return { error: "Path is outside working directory" };
46834
46861
  }
46835
46862
  try {
46836
- const names = await fs50.promises.readdir(resolved, { withFileTypes: true });
46863
+ const names = await fs51.promises.readdir(resolved, { withFileTypes: true });
46837
46864
  const entries = [];
46838
46865
  for (let i = 0; i < names.length; i++) {
46839
46866
  if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
@@ -46849,13 +46876,13 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
46849
46876
  }
46850
46877
 
46851
46878
  // src/git/tree/resolve-repo-abs-path.ts
46852
- import * as path76 from "node:path";
46879
+ import * as path77 from "node:path";
46853
46880
  function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
46854
- const bridgeResolved = path76.resolve(bridgeRoot);
46881
+ const bridgeResolved = path77.resolve(bridgeRoot);
46855
46882
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
46856
- const repoPath = rel === "" ? bridgeResolved : path76.join(bridgeResolved, rel);
46857
- const resolved = path76.resolve(repoPath);
46858
- if (!resolved.startsWith(bridgeResolved + path76.sep) && resolved !== bridgeResolved) {
46883
+ const repoPath = rel === "" ? bridgeResolved : path77.join(bridgeResolved, rel);
46884
+ const resolved = path77.resolve(repoPath);
46885
+ if (!resolved.startsWith(bridgeResolved + path77.sep) && resolved !== bridgeResolved) {
46859
46886
  return null;
46860
46887
  }
46861
46888
  return resolved;
@@ -46941,7 +46968,7 @@ init_yield_to_event_loop();
46941
46968
 
46942
46969
  // src/files/read/types.ts
46943
46970
  var LINE_CHUNK_SIZE = 64 * 1024;
46944
- var READ_RANGE_YIELD_EVERY_BYTES = 256 * 1024;
46971
+ var READ_RANGE_YIELD_EVERY_BYTES = 64 * 1024;
46945
46972
 
46946
46973
  // src/files/read/guess-mime-type.ts
46947
46974
  var MIME_BY_EXT = {
@@ -47336,25 +47363,25 @@ async function GET2(ctx) {
47336
47363
  init_in_flight();
47337
47364
 
47338
47365
  // src/files/read/read-file-async.ts
47339
- import fs56 from "node:fs";
47366
+ import fs57 from "node:fs";
47340
47367
  init_yield_to_event_loop();
47341
47368
 
47342
47369
  // src/files/read/resolve-file-cache.ts
47343
- import fs51 from "node:fs";
47344
- import path77 from "node:path";
47370
+ import fs52 from "node:fs";
47371
+ import path78 from "node:path";
47345
47372
  var RESOLVE_CACHE_MAX = 4096;
47346
47373
  var resolveCache = /* @__PURE__ */ new Map();
47347
47374
  function resolveCacheKey(sessionParentPath, relativePath) {
47348
47375
  return `${sessionParentPath}\0${relativePath}`;
47349
47376
  }
47350
47377
  function pathStaysUnderParent(filePath, sessionParentPath) {
47351
- const parent = path77.resolve(sessionParentPath);
47352
- const resolved = path77.resolve(filePath);
47353
- return resolved === parent || resolved.startsWith(`${parent}${path77.sep}`);
47378
+ const parent = path78.resolve(sessionParentPath);
47379
+ const resolved = path78.resolve(filePath);
47380
+ return resolved === parent || resolved.startsWith(`${parent}${path78.sep}`);
47354
47381
  }
47355
47382
  function statMatchesCacheSync(entry) {
47356
47383
  try {
47357
- const stat2 = fs51.statSync(entry.path);
47384
+ const stat2 = fs52.statSync(entry.path);
47358
47385
  return stat2.isFile() && stat2.mtimeMs === entry.mtimeMs && stat2.size === entry.size;
47359
47386
  } catch {
47360
47387
  return false;
@@ -47387,7 +47414,7 @@ function joinInflightResolve(cacheKey, factory) {
47387
47414
  }
47388
47415
 
47389
47416
  // src/files/read/resolve-file-for-read-core.ts
47390
- import fs52 from "node:fs";
47417
+ import fs53 from "node:fs";
47391
47418
  import { isMainThread as isMainThread4 } from "node:worker_threads";
47392
47419
  function resolveFileForReadImplSync(relativePath, sessionParentPath) {
47393
47420
  const cacheKey = resolveCacheKey(sessionParentPath, relativePath);
@@ -47397,13 +47424,13 @@ function resolveFileForReadImplSync(relativePath, sessionParentPath) {
47397
47424
  let size;
47398
47425
  let mtimeMs;
47399
47426
  try {
47400
- const lstat = fs52.lstatSync(resolved);
47427
+ const lstat = fs53.lstatSync(resolved);
47401
47428
  if (lstat.isSymbolicLink()) {
47402
- real = fs52.realpathSync(resolved);
47429
+ real = fs53.realpathSync(resolved);
47403
47430
  if (!pathStaysUnderParent(real, sessionParentPath)) {
47404
47431
  return { error: "Path is outside working directory" };
47405
47432
  }
47406
- const stat2 = fs52.statSync(real);
47433
+ const stat2 = fs53.statSync(real);
47407
47434
  if (!stat2.isFile()) return { error: "Not a file" };
47408
47435
  size = stat2.size;
47409
47436
  mtimeMs = stat2.mtimeMs;
@@ -47431,13 +47458,13 @@ async function resolveFileForReadImpl(relativePath, sessionParentPath) {
47431
47458
  let size;
47432
47459
  let mtimeMs;
47433
47460
  try {
47434
- const lstat = await fs52.promises.lstat(resolved);
47461
+ const lstat = await fs53.promises.lstat(resolved);
47435
47462
  if (lstat.isSymbolicLink()) {
47436
- real = await fs52.promises.realpath(resolved);
47463
+ real = await fs53.promises.realpath(resolved);
47437
47464
  if (!pathStaysUnderParent(real, sessionParentPath)) {
47438
47465
  return { error: "Path is outside working directory" };
47439
47466
  }
47440
- const stat2 = await fs52.promises.stat(real);
47467
+ const stat2 = await fs53.promises.stat(real);
47441
47468
  if (!stat2.isFile()) return { error: "Not a file" };
47442
47469
  size = stat2.size;
47443
47470
  mtimeMs = stat2.mtimeMs;
@@ -47486,7 +47513,7 @@ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeR
47486
47513
 
47487
47514
  // src/files/read/read-file-range-async.ts
47488
47515
  init_yield_to_event_loop();
47489
- import fs53 from "node:fs";
47516
+ import fs54 from "node:fs";
47490
47517
  import { StringDecoder as StringDecoder2 } from "node:string_decoder";
47491
47518
 
47492
47519
  // src/files/read/read-file-range-line-zero.ts
@@ -47600,8 +47627,8 @@ function finishLineZeroTail(state, tail, resultLines, fileSize, lineChunkSize, l
47600
47627
 
47601
47628
  // src/files/read/read-file-range-async.ts
47602
47629
  async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE, fileSizeIn) {
47603
- const fileSize = fileSizeIn ?? (await fs53.promises.stat(filePath)).size;
47604
- const fd = await fs53.promises.open(filePath, "r");
47630
+ const fileSize = fileSizeIn ?? (await fs54.promises.stat(filePath)).size;
47631
+ const fd = await fs54.promises.open(filePath, "r");
47605
47632
  const bufSize = 64 * 1024;
47606
47633
  const buf = Buffer.alloc(bufSize);
47607
47634
  const decoder = new StringDecoder2("utf8");
@@ -47702,7 +47729,7 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
47702
47729
  }
47703
47730
 
47704
47731
  // src/files/read/read-small-file-range-async.ts
47705
- import fs54 from "node:fs";
47732
+ import fs55 from "node:fs";
47706
47733
  import { isMainThread as isMainThread5 } from "node:worker_threads";
47707
47734
  var SMALL_FILE_RANGE_MAX_BYTES = 512 * 1024;
47708
47735
  function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize) {
@@ -47732,7 +47759,7 @@ function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize,
47732
47759
  };
47733
47760
  }
47734
47761
  function readSmallFileRangeSync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
47735
- const raw = fs54.readFileSync(filePath, "utf8");
47762
+ const raw = fs55.readFileSync(filePath, "utf8");
47736
47763
  const lines = raw.split(/\r?\n/);
47737
47764
  return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
47738
47765
  }
@@ -47740,28 +47767,28 @@ async function readSmallFileRangeAsync(filePath, fileSize, startLine, endLine, l
47740
47767
  if (isMainThread5) {
47741
47768
  return readSmallFileRangeSync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize);
47742
47769
  }
47743
- const raw = await fs54.promises.readFile(filePath, "utf8");
47770
+ const raw = await fs55.promises.readFile(filePath, "utf8");
47744
47771
  const lines = raw.split(/\r?\n/);
47745
47772
  return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
47746
47773
  }
47747
47774
 
47748
47775
  // src/files/read/read-file-buffer-full-async.ts
47749
47776
  init_yield_to_event_loop();
47750
- import fs55 from "node:fs";
47777
+ import fs56 from "node:fs";
47751
47778
  import { isMainThread as isMainThread6 } from "node:worker_threads";
47752
47779
  var READ_CHUNK_BYTES = 256 * 1024;
47753
47780
  var MAIN_THREAD_SYNC_READ_MAX_BYTES = 512 * 1024;
47754
47781
  async function readFileBufferFullAsync(filePath, knownSize) {
47755
47782
  if (isMainThread6) {
47756
- const size2 = knownSize ?? fs55.statSync(filePath).size;
47783
+ const size2 = knownSize ?? fs56.statSync(filePath).size;
47757
47784
  if (size2 <= MAIN_THREAD_SYNC_READ_MAX_BYTES) {
47758
47785
  await yieldToEventLoop();
47759
- const buffer = fs55.readFileSync(filePath);
47786
+ const buffer = fs56.readFileSync(filePath);
47760
47787
  return { buffer, size: buffer.length };
47761
47788
  }
47762
47789
  }
47763
- const size = knownSize ?? (await fs55.promises.stat(filePath)).size;
47764
- const fd = await fs55.promises.open(filePath, "r");
47790
+ const size = knownSize ?? (await fs56.promises.stat(filePath)).size;
47791
+ const fd = await fs56.promises.open(filePath, "r");
47765
47792
  const chunks = [];
47766
47793
  let position = 0;
47767
47794
  let bytesSinceYield = 0;
@@ -47864,7 +47891,7 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
47864
47891
  }
47865
47892
  if (hasRange) {
47866
47893
  if (fileSize == null) {
47867
- const stat2 = await fs56.promises.stat(resolvedPath);
47894
+ const stat2 = await fs57.promises.stat(resolvedPath);
47868
47895
  fileSize = stat2.size;
47869
47896
  }
47870
47897
  const read2 = fileSize <= SMALL_FILE_RANGE_MAX_BYTES ? await readSmallFileRangeAsync(
@@ -48162,12 +48189,12 @@ function parseOptionalInt2(raw) {
48162
48189
  return Number.isInteger(parsed) ? parsed : void 0;
48163
48190
  }
48164
48191
  function parseCodeNavParams(url2) {
48165
- const path82 = url2.searchParams.get("path") ?? "";
48192
+ const path84 = url2.searchParams.get("path") ?? "";
48166
48193
  const opRaw = url2.searchParams.get("op")?.trim();
48167
48194
  const op = opRaw === "references" ? "references" : opRaw === "symbols" ? "symbols" : opRaw === "definitions" ? "definitions" : "definition";
48168
48195
  const line = parseOptionalInt2(url2.searchParams.get("line")) ?? 1;
48169
48196
  const column = parseOptionalInt2(url2.searchParams.get("column")) ?? 0;
48170
- return { path: path82, op, line, column };
48197
+ return { path: path84, op, line, column };
48171
48198
  }
48172
48199
  function parseCodeNavPath(url2) {
48173
48200
  const raw = url2.searchParams.get("path")?.trim();
@@ -48747,16 +48774,8 @@ var handleAgentConfigMessage = (msg, deps) => {
48747
48774
  handleBridgeAgentConfig(msg, deps);
48748
48775
  };
48749
48776
 
48750
- // src/prompt-turn-queue/client-report.ts
48751
- function sendPromptQueueClientReport(ws, queues) {
48752
- if (!ws) return false;
48753
- const wireQueues = {};
48754
- for (const [queueKey, rows] of Object.entries(queues)) {
48755
- wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
48756
- }
48757
- sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
48758
- return true;
48759
- }
48777
+ // src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
48778
+ init_yield_to_event_loop();
48760
48779
 
48761
48780
  // src/prompt-turn-queue/disk-store.ts
48762
48781
  init_cli_database();
@@ -48848,23 +48867,6 @@ function dispatchLocalPrompt(next, deps) {
48848
48867
  handleBridgePrompt(msg, deps);
48849
48868
  }
48850
48869
 
48851
- // src/prompt-turn-queue/runner/queue-selection.ts
48852
- function pickNextRunnableTurn(turns) {
48853
- for (const t of turns) {
48854
- if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
48855
- if (t.bridgeServerState === "cancel_requested") continue;
48856
- if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
48857
- if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
48858
- continue;
48859
- }
48860
- return t;
48861
- }
48862
- return null;
48863
- }
48864
- function hasRunningTurn(turns) {
48865
- return turns.some((t) => t.lastCliState === "running");
48866
- }
48867
-
48868
48870
  // src/prompt-turn-queue/runner/run-id-queue-key-map.ts
48869
48871
  var runIdToQueueKey = /* @__PURE__ */ new Map();
48870
48872
  function getRunIdQueueKey(runId) {
@@ -48879,37 +48881,184 @@ function deleteRunIdQueueKey(runId) {
48879
48881
  return queueKey;
48880
48882
  }
48881
48883
  function syncRunningTurnQueueKeys(turns, queueKey) {
48882
- for (const running of turns.filter((t) => t.lastCliState === "running")) {
48883
- runIdToQueueKey.set(running.turnId, queueKey);
48884
+ for (const running2 of turns.filter((t) => t.lastCliState === "running")) {
48885
+ runIdToQueueKey.set(running2.turnId, queueKey);
48884
48886
  }
48885
48887
  }
48886
48888
 
48889
+ // src/prompt-turn-queue/runner/dispatch-started-prompt-queue-runs.ts
48890
+ async function dispatchStartedPromptQueueRuns(entries, started, deps) {
48891
+ for (const [queueKey] of entries) {
48892
+ const file2 = await readPersistedQueue(queueKey);
48893
+ const running2 = file2?.turns.find((turn) => turn.lastCliState === "running");
48894
+ if (running2 && started.has(running2.turnId) && getRunIdQueueKey(running2.turnId) === queueKey) {
48895
+ dispatchLocalPrompt(running2, deps);
48896
+ }
48897
+ await yieldToEventLoop();
48898
+ }
48899
+ }
48900
+
48901
+ // src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
48902
+ init_yield_to_event_loop();
48903
+
48904
+ // src/prompt-turn-queue/client-report.ts
48905
+ function sendPromptQueueClientReport(ws, queues) {
48906
+ if (!ws) return false;
48907
+ const wireQueues = {};
48908
+ for (const [queueKey, rows] of Object.entries(queues)) {
48909
+ wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
48910
+ }
48911
+ sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
48912
+ return true;
48913
+ }
48914
+
48915
+ // src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
48916
+ async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
48917
+ if (!runId) return false;
48918
+ const queueKey = deleteRunIdQueueKey(runId);
48919
+ if (!queueKey) return false;
48920
+ const f = await readPersistedQueue(queueKey);
48921
+ if (!f) return false;
48922
+ const t = f.turns.find((x) => x.turnId === runId);
48923
+ if (!t) return false;
48924
+ t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
48925
+ await writePersistedQueue(f);
48926
+ sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
48927
+ return true;
48928
+ }
48929
+
48930
+ // src/prompt-turn-queue/runner/handle-prompt-queue-cancellations.ts
48931
+ async function handlePromptQueueCancellations(entries, deps) {
48932
+ for (const [queueKey] of entries) {
48933
+ const file2 = await readPersistedQueue(queueKey);
48934
+ const turn = file2?.turns.find((row) => row.bridgeServerState === "cancel_requested" && row.lastCliState === "running");
48935
+ if (!turn) {
48936
+ await yieldToEventLoop();
48937
+ continue;
48938
+ }
48939
+ deps.log(`[Queue] Cancellation request received for turn ${turn.turnId.slice(0, 8)}\u2026`);
48940
+ if (await deps.acpManager.cancelRun(turn.turnId)) {
48941
+ await yieldToEventLoop();
48942
+ continue;
48943
+ }
48944
+ deps.log(`[Queue] cancel_requested for ${turn.turnId.slice(0, 8)}\u2026 with no local run; marking cancelled.`);
48945
+ await finalizePromptTurnOnBridge(deps.getWs, turn.turnId, false, { terminalCliState: "cancelled" });
48946
+ const ws = deps.getWs();
48947
+ if (ws && turn.sessionId) {
48948
+ sendWsMessage(ws, {
48949
+ type: "prompt_result",
48950
+ sessionId: turn.sessionId,
48951
+ runId: turn.turnId,
48952
+ success: false,
48953
+ error: "Stopped by user",
48954
+ stopReason: "cancelled"
48955
+ });
48956
+ }
48957
+ await yieldToEventLoop();
48958
+ }
48959
+ }
48960
+
48961
+ // src/prompt-turn-queue/runner/persist-prompt-queue-snapshot.ts
48962
+ init_yield_to_event_loop();
48963
+ async function persistPromptQueueSnapshot(entries) {
48964
+ for (const [queueKey, serverTurns] of entries) {
48965
+ const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
48966
+ await writePersistedQueue(file2);
48967
+ await yieldToEventLoop();
48968
+ }
48969
+ for (const [queueKey] of entries) {
48970
+ const file2 = await readPersistedQueue(queueKey);
48971
+ if (file2) syncRunningTurnQueueKeys(file2.turns, queueKey);
48972
+ await yieldToEventLoop();
48973
+ }
48974
+ }
48975
+
48976
+ // src/prompt-turn-queue/runner/prompt-queue-snapshot-types.ts
48977
+ function promptQueueSnapshotEntries(queues) {
48978
+ return Object.entries(queues).filter((entry) => Array.isArray(entry[1]));
48979
+ }
48980
+
48981
+ // src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
48982
+ init_yield_to_event_loop();
48983
+
48984
+ // src/prompt-turn-queue/runner/queue-selection.ts
48985
+ function pickNextRunnableTurn(turns) {
48986
+ for (const t of turns) {
48987
+ if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
48988
+ if (t.bridgeServerState === "cancel_requested") continue;
48989
+ if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
48990
+ if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
48991
+ continue;
48992
+ }
48993
+ return t;
48994
+ }
48995
+ return null;
48996
+ }
48997
+ function hasRunningTurn(turns) {
48998
+ return turns.some((t) => t.lastCliState === "running");
48999
+ }
49000
+
48887
49001
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
48888
- import fs58 from "node:fs";
49002
+ import fs60 from "node:fs";
48889
49003
 
48890
49004
  // src/git/snapshot/capture.ts
48891
- import * as fs57 from "node:fs";
48892
- import * as path78 from "node:path";
49005
+ import * as fs59 from "node:fs";
49006
+ import * as path80 from "node:path";
49007
+
49008
+ // src/git/snapshot/apply-pre-turn-snapshot.ts
49009
+ import * as fs58 from "node:fs";
49010
+ async function applyPreTurnSnapshot(filePath, log2) {
49011
+ let data;
49012
+ try {
49013
+ data = JSON.parse(fs58.readFileSync(filePath, "utf8"));
49014
+ } catch (error40) {
49015
+ return { ok: false, error: error40 instanceof Error ? error40.message : String(error40) };
49016
+ }
49017
+ if (!Array.isArray(data.repos)) return { ok: false, error: "Invalid snapshot file" };
49018
+ let applyError = null;
49019
+ await forEachWithGitYield(data.repos, async (repo) => {
49020
+ if (applyError || !repo.path) return;
49021
+ const reset = await gitRun(repo.path, ["reset", "--hard", "HEAD"], log2, "reset --hard");
49022
+ if (!reset.ok) {
49023
+ applyError = reset;
49024
+ return;
49025
+ }
49026
+ const clean = await gitRun(repo.path, ["clean", "-fd"], log2, "clean -fd");
49027
+ if (!clean.ok) {
49028
+ applyError = clean;
49029
+ return;
49030
+ }
49031
+ if (repo.stashSha) {
49032
+ const applied = await gitRun(repo.path, ["stash", "apply", repo.stashSha], log2, "stash apply");
49033
+ if (!applied.ok) applyError = applied;
49034
+ }
49035
+ });
49036
+ if (applyError) return applyError;
49037
+ log2(`[snapshot] Restored pre-turn state for ${data.runId.slice(0, 8)}\u2026`);
49038
+ return { ok: true };
49039
+ }
49040
+
49041
+ // src/git/snapshot/resolve-repo-roots.ts
49042
+ import * as path79 from "node:path";
48893
49043
  async function resolveSnapshotRepoRoots(options) {
48894
49044
  const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
48895
49045
  if (worktreePaths?.length) {
48896
- const uniq = [...new Set(worktreePaths.map((p) => path78.resolve(p)))];
48897
- return uniq;
49046
+ const paths = [...new Set(worktreePaths.map((p) => path79.resolve(p)))];
49047
+ return (await Promise.all(paths.map(async (p) => await isGitRepoDirectory(p) ? p : null))).filter((p) => p != null);
48898
49048
  }
48899
49049
  try {
48900
- const repos = await discoverGitReposUnderRoot(fallbackCwd);
48901
- const mapped = repos.map((r) => r.absolutePath);
49050
+ const roots = (await discoverGitReposUnderRoot(fallbackCwd)).map((repo) => repo.absolutePath);
48902
49051
  const sid = sessionId?.trim();
48903
- if (sid) {
48904
- const filtered = mapped.filter((root) => path78.basename(root) === sid);
48905
- if (filtered.length > 0) return filtered;
48906
- }
48907
- return mapped;
48908
- } catch (e) {
48909
- log2(`[snapshot] Discover repositories failed: ${e instanceof Error ? e.message : String(e)}`);
49052
+ if (!sid) return roots;
49053
+ const sessionRoots = roots.filter((root) => path79.basename(root) === sid);
49054
+ return sessionRoots.length > 0 ? sessionRoots : roots;
49055
+ } catch (error40) {
49056
+ log2(`[snapshot] Discover repositories failed: ${error40 instanceof Error ? error40.message : String(error40)}`);
48910
49057
  return [];
48911
49058
  }
48912
49059
  }
49060
+
49061
+ // src/git/snapshot/capture.ts
48913
49062
  async function capturePreTurnSnapshot(options) {
48914
49063
  const { runId, repoRoots, agentCwd, log: log2 } = options;
48915
49064
  if (!runId || !repoRoots.length) {
@@ -48923,7 +49072,7 @@ async function capturePreTurnSnapshot(options) {
48923
49072
  });
48924
49073
  const dir = snapshotsDirForCwd(agentCwd);
48925
49074
  try {
48926
- fs57.mkdirSync(dir, { recursive: true });
49075
+ fs59.mkdirSync(dir, { recursive: true });
48927
49076
  } catch (e) {
48928
49077
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
48929
49078
  }
@@ -48932,9 +49081,9 @@ async function capturePreTurnSnapshot(options) {
48932
49081
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
48933
49082
  repos
48934
49083
  };
48935
- const filePath = path78.join(dir, `${runId}.json`);
49084
+ const filePath = path80.join(dir, `${runId}.json`);
48936
49085
  try {
48937
- fs57.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
49086
+ fs59.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
48938
49087
  } catch (e) {
48939
49088
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
48940
49089
  }
@@ -48944,39 +49093,6 @@ async function capturePreTurnSnapshot(options) {
48944
49093
  );
48945
49094
  return { ok: true, filePath, repos };
48946
49095
  }
48947
- async function applyPreTurnSnapshot(filePath, log2) {
48948
- let data;
48949
- try {
48950
- const raw = fs57.readFileSync(filePath, "utf8");
48951
- data = JSON.parse(raw);
48952
- } catch (e) {
48953
- return { ok: false, error: e instanceof Error ? e.message : String(e) };
48954
- }
48955
- if (!Array.isArray(data.repos)) {
48956
- return { ok: false, error: "Invalid snapshot file" };
48957
- }
48958
- let applyError = null;
48959
- await forEachWithGitYield(data.repos, async (r) => {
48960
- if (applyError || !r.path) return;
48961
- const reset = await gitRun(r.path, ["reset", "--hard", "HEAD"], log2, "reset --hard");
48962
- if (!reset.ok) {
48963
- applyError = reset;
48964
- return;
48965
- }
48966
- const clean = await gitRun(r.path, ["clean", "-fd"], log2, "clean -fd");
48967
- if (!clean.ok) {
48968
- applyError = clean;
48969
- return;
48970
- }
48971
- if (r.stashSha) {
48972
- const ap = await gitRun(r.path, ["stash", "apply", r.stashSha], log2, "stash apply");
48973
- if (!ap.ok) applyError = ap;
48974
- }
48975
- });
48976
- if (applyError) return applyError;
48977
- log2(`[snapshot] Restored pre-turn state for ${data.runId.slice(0, 8)}\u2026`);
48978
- return { ok: true };
48979
- }
48980
49096
 
48981
49097
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
48982
49098
  async function runLocalRevertBeforeQueuedPrompt(next, deps) {
@@ -48987,7 +49103,7 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
48987
49103
  const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
48988
49104
  const file2 = snapshotFilePath(agentBase, tid);
48989
49105
  try {
48990
- await fs58.promises.access(file2, fs58.constants.F_OK);
49106
+ await fs60.promises.access(file2, fs60.constants.F_OK);
48991
49107
  } catch {
48992
49108
  deps.log(
48993
49109
  `[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
@@ -49001,96 +49117,41 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
49001
49117
  return res.ok;
49002
49118
  }
49003
49119
 
49004
- // src/prompt-turn-queue/runner/finalize-prompt-turn-on-bridge.ts
49005
- async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
49006
- if (!runId) return false;
49007
- const queueKey = deleteRunIdQueueKey(runId);
49008
- if (!queueKey) return false;
49009
- const f = await readPersistedQueue(queueKey);
49010
- if (!f) return false;
49011
- const t = f.turns.find((x) => x.turnId === runId);
49012
- if (!t) return false;
49013
- t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
49014
- await writePersistedQueue(f);
49015
- sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
49016
- return true;
49017
- }
49018
-
49019
- // src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
49020
- async function applyPromptQueueStateFromServer(msg, deps) {
49021
- const raw = msg.queues;
49022
- if (!raw || typeof raw !== "object") return;
49023
- const getWs = deps.getWs;
49024
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49025
- if (!Array.isArray(serverTurns)) continue;
49026
- const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
49027
- await writePersistedQueue(file2);
49028
- }
49029
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49030
- if (!Array.isArray(serverTurns)) continue;
49031
- const file2 = await readPersistedQueue(queueKey);
49032
- if (!file2) continue;
49033
- syncRunningTurnQueueKeys(file2.turns, queueKey);
49034
- }
49035
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49036
- if (!Array.isArray(serverTurns)) continue;
49037
- const file2 = await readPersistedQueue(queueKey);
49038
- if (!file2) continue;
49039
- const cancelRow = file2.turns.find((t) => t.bridgeServerState === "cancel_requested" && t.lastCliState === "running");
49040
- if (cancelRow) {
49041
- const localCancelHandled = await deps.acpManager.cancelRun(cancelRow.turnId);
49042
- if (!localCancelHandled) {
49043
- deps.log(
49044
- `[Queue] bridge server cancel_requested for ${cancelRow.turnId.slice(0, 8)}\u2026 but no local agent run is active (e.g. after CLI restart); marking cancelled and notifying bridge.`
49045
- );
49046
- await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalCliState: "cancelled" });
49047
- const ws = deps.getWs();
49048
- if (ws && cancelRow.sessionId) {
49049
- sendWsMessage(ws, {
49050
- type: "prompt_result",
49051
- sessionId: cancelRow.sessionId,
49052
- runId: cancelRow.turnId,
49053
- success: false,
49054
- error: "Stopped by user",
49055
- stopReason: "cancelled"
49056
- });
49057
- }
49058
- }
49059
- }
49060
- }
49120
+ // src/prompt-turn-queue/runner/start-prompt-queue-runs.ts
49121
+ async function startPromptQueueRuns(entries, deps) {
49061
49122
  const report = {};
49062
- const startedThisTick = /* @__PURE__ */ new Set();
49063
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49064
- if (!Array.isArray(serverTurns)) continue;
49123
+ const started = /* @__PURE__ */ new Set();
49124
+ for (const [queueKey] of entries) {
49065
49125
  const file2 = await readPersistedQueue(queueKey);
49066
- if (!file2) continue;
49067
- if (hasRunningTurn(file2.turns)) continue;
49126
+ if (!file2 || hasRunningTurn(file2.turns)) continue;
49068
49127
  const next = pickNextRunnableTurn(file2.turns);
49069
49128
  if (!next) continue;
49070
49129
  if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
49071
49130
  next.lastCliState = "failed";
49072
49131
  await writePersistedQueue(file2);
49073
- sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
49132
+ sendPromptQueueClientReport(deps.getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
49074
49133
  continue;
49075
49134
  }
49076
49135
  next.lastCliState = "running";
49077
49136
  await writePersistedQueue(file2);
49078
49137
  setRunIdQueueKey(next.turnId, queueKey);
49079
- startedThisTick.add(next.turnId);
49138
+ started.add(next.turnId);
49080
49139
  report[queueKey] = [{ turnId: next.turnId, cliState: "running" }];
49140
+ await yieldToEventLoop();
49081
49141
  }
49082
- if (Object.keys(report).length > 0) {
49083
- sendPromptQueueClientReport(getWs(), report);
49084
- }
49085
- for (const [queueKey, serverTurns] of Object.entries(raw)) {
49086
- if (!Array.isArray(serverTurns)) continue;
49087
- const file2 = await readPersistedQueue(queueKey);
49088
- if (!file2) continue;
49089
- const running = file2.turns.find((t) => t.lastCliState === "running");
49090
- if (!running || !startedThisTick.has(running.turnId)) continue;
49091
- if (getRunIdQueueKey(running.turnId) !== queueKey) continue;
49092
- dispatchLocalPrompt(running, deps);
49093
- }
49142
+ if (Object.keys(report).length) sendPromptQueueClientReport(deps.getWs(), report);
49143
+ return started;
49144
+ }
49145
+
49146
+ // src/prompt-turn-queue/runner/apply-prompt-queue-state-from-server.ts
49147
+ async function applyPromptQueueStateFromServer(msg, deps) {
49148
+ const raw = msg.queues;
49149
+ if (!raw || typeof raw !== "object") return;
49150
+ const entries = promptQueueSnapshotEntries(raw);
49151
+ await persistPromptQueueSnapshot(entries);
49152
+ await handlePromptQueueCancellations(entries, deps);
49153
+ const started = await startPromptQueueRuns(entries, deps);
49154
+ await dispatchStartedPromptQueueRuns(entries, started, deps);
49094
49155
  }
49095
49156
 
49096
49157
  // src/agents/acp/from-bridge/bridge-prompt-wiring.ts
@@ -49191,8 +49252,8 @@ async function runBridgePromptPreamble(params) {
49191
49252
  log: log2
49192
49253
  });
49193
49254
  if (s && sessionId) {
49194
- const cliGitBranch = await readGitBranch(effectiveCwd);
49195
49255
  const usesWt = sessionWorktreeManager.usesWorktreeSession(sessionId);
49256
+ const cliGitBranch = repoRoots.length > 0 ? await readGitBranch(effectiveCwd) : null;
49196
49257
  const isolatedSessionParentPath = sessionWorktreeManager.getIsolatedSessionParentPathForSession(sessionId);
49197
49258
  sendWsMessage(s, {
49198
49259
  type: "session_git_context_report",
@@ -49356,10 +49417,34 @@ var handlePromptMessage = (msg, deps) => {
49356
49417
  handleBridgePrompt(msg, deps);
49357
49418
  };
49358
49419
 
49420
+ // src/prompt-turn-queue/runner/serial-prompt-queue-work.ts
49421
+ var running = false;
49422
+ var latestWork = null;
49423
+ async function drain() {
49424
+ while (latestWork) {
49425
+ const work = latestWork;
49426
+ latestWork = null;
49427
+ await work();
49428
+ }
49429
+ }
49430
+ function enqueueLatestPromptQueueStateWork(work) {
49431
+ latestWork = work;
49432
+ if (running) return;
49433
+ running = true;
49434
+ void drain().finally(() => {
49435
+ running = false;
49436
+ if (latestWork) enqueueLatestPromptQueueStateWork(latestWork);
49437
+ });
49438
+ }
49439
+
49359
49440
  // src/routing/handlers/prompt-queue-state.ts
49360
49441
  var handlePromptQueueStateMessage = (msg, deps) => {
49361
- void applyPromptQueueStateFromServer(msg, deps).catch((err) => {
49362
- deps.log(`[Queue] applyPromptQueueStateFromServer failed: ${err instanceof Error ? err.message : String(err)}`);
49442
+ enqueueLatestPromptQueueStateWork(async () => {
49443
+ try {
49444
+ await applyPromptQueueStateFromServer(msg, deps);
49445
+ } catch (err) {
49446
+ deps.log(`[Queue] applyPromptQueueStateFromServer failed: ${err instanceof Error ? err.message : String(err)}`);
49447
+ }
49363
49448
  });
49364
49449
  };
49365
49450
 
@@ -49610,7 +49695,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
49610
49695
  };
49611
49696
 
49612
49697
  // src/routing/handlers/revert-turn-snapshot.ts
49613
- import * as fs59 from "node:fs";
49698
+ import * as fs61 from "node:fs";
49614
49699
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
49615
49700
  const id = typeof msg.id === "string" ? msg.id : "";
49616
49701
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -49623,7 +49708,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
49623
49708
  const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
49624
49709
  const file2 = snapshotFilePath(agentBase, turnId);
49625
49710
  try {
49626
- await fs59.promises.access(file2, fs59.constants.F_OK);
49711
+ await fs61.promises.access(file2, fs61.constants.F_OK);
49627
49712
  } catch {
49628
49713
  sendWsMessage(s, {
49629
49714
  type: "revert_turn_snapshot_result",
@@ -49721,8 +49806,8 @@ function isValidRemoteSkillInstallItem(item) {
49721
49806
 
49722
49807
  // src/skills/install/install-remote-skills-async.ts
49723
49808
  init_yield_to_event_loop();
49724
- import fs60 from "node:fs";
49725
- import path79 from "node:path";
49809
+ import fs62 from "node:fs";
49810
+ import path81 from "node:path";
49726
49811
 
49727
49812
  // src/skills/install/constants.ts
49728
49813
  var INSTALL_SKILLS_YIELD_EVERY = 16;
@@ -49733,12 +49818,12 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
49733
49818
  if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
49734
49819
  await yieldToEventLoop();
49735
49820
  }
49736
- const dest = path79.join(skillDir, f.path);
49737
- await fs60.promises.mkdir(path79.dirname(dest), { recursive: true });
49821
+ const dest = path81.join(skillDir, f.path);
49822
+ await fs62.promises.mkdir(path81.dirname(dest), { recursive: true });
49738
49823
  if (f.text !== void 0) {
49739
- await fs60.promises.writeFile(dest, f.text, "utf8");
49824
+ await fs62.promises.writeFile(dest, f.text, "utf8");
49740
49825
  } else if (f.base64) {
49741
- await fs60.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
49826
+ await fs62.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
49742
49827
  }
49743
49828
  }
49744
49829
  async function installRemoteSkillsAsync(cwd, targetDir, items) {
@@ -49750,7 +49835,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
49750
49835
  try {
49751
49836
  for (const item of items) {
49752
49837
  if (!isValidRemoteSkillInstallItem(item)) continue;
49753
- const skillDir = path79.join(cwd, targetDir, item.skillName);
49838
+ const skillDir = path81.join(cwd, targetDir, item.skillName);
49754
49839
  for (const f of item.files) {
49755
49840
  await writeInstallFileAsync(skillDir, f, filesWritten);
49756
49841
  }
@@ -50057,13 +50142,13 @@ function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
50057
50142
 
50058
50143
  // src/files/handle-file-browser-search.ts
50059
50144
  init_yield_to_event_loop();
50060
- import path80 from "node:path";
50145
+ import path82 from "node:path";
50061
50146
  var SEARCH_LIMIT = 100;
50062
50147
  function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
50063
50148
  void (async () => {
50064
50149
  await yieldToEventLoop();
50065
50150
  const q = typeof msg.q === "string" ? msg.q : "";
50066
- const sessionParentPath = path80.resolve(
50151
+ const sessionParentPath = path82.resolve(
50067
50152
  sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
50068
50153
  );
50069
50154
  if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
@@ -50161,7 +50246,7 @@ function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeMana
50161
50246
  }
50162
50247
 
50163
50248
  // src/git/bridge-git-context.ts
50164
- import * as path81 from "node:path";
50249
+ import * as path83 from "node:path";
50165
50250
  init_yield_to_event_loop();
50166
50251
 
50167
50252
  // src/git/branches/get-current-branch.ts
@@ -50212,12 +50297,12 @@ async function listRepoBranchRefs(repoPath) {
50212
50297
  // src/git/bridge-git-context.ts
50213
50298
  function folderNameForRelPath(relPath, bridgeRoot) {
50214
50299
  if (relPath === "." || relPath === "") {
50215
- return path81.basename(path81.resolve(bridgeRoot)) || "repo";
50300
+ return path83.basename(path83.resolve(bridgeRoot)) || "repo";
50216
50301
  }
50217
- return path81.basename(relPath) || relPath;
50302
+ return path83.basename(relPath) || relPath;
50218
50303
  }
50219
50304
  async function discoverGitReposForBridgeContext(bridgeRoot) {
50220
- const root = path81.resolve(bridgeRoot);
50305
+ const root = path83.resolve(bridgeRoot);
50221
50306
  if (await isGitRepoDirectory(root)) {
50222
50307
  const remoteUrl = await getRemoteOriginUrl(root);
50223
50308
  return [{ absolutePath: root, remoteUrl }];
@@ -50225,19 +50310,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
50225
50310
  const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
50226
50311
  const byPath = /* @__PURE__ */ new Map();
50227
50312
  for (const repo of [...deep, ...shallow]) {
50228
- byPath.set(path81.resolve(repo.absolutePath), repo);
50313
+ byPath.set(path83.resolve(repo.absolutePath), repo);
50229
50314
  }
50230
50315
  return [...byPath.values()];
50231
50316
  }
50232
50317
  async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
50233
- const bridgeResolved = path81.resolve(bridgeRoot);
50318
+ const bridgeResolved = path83.resolve(bridgeRoot);
50234
50319
  const repos = await discoverGitReposForBridgeContext(bridgeResolved);
50235
50320
  const rows = [];
50236
50321
  for (let i = 0; i < repos.length; i++) {
50237
50322
  if (i > 0) await yieldToEventLoop();
50238
50323
  const repo = repos[i];
50239
- let rel = path81.relative(bridgeResolved, repo.absolutePath);
50240
- if (rel.startsWith("..") || path81.isAbsolute(rel)) continue;
50324
+ let rel = path83.relative(bridgeResolved, repo.absolutePath);
50325
+ if (rel.startsWith("..") || path83.isAbsolute(rel)) continue;
50241
50326
  const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
50242
50327
  const currentBranch = await getCurrentBranch(repo.absolutePath);
50243
50328
  const remoteUrl = repo.remoteUrl.trim() || null;
@@ -50252,11 +50337,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
50252
50337
  return rows;
50253
50338
  }
50254
50339
  async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
50255
- const bridgeResolved = path81.resolve(bridgeRoot);
50340
+ const bridgeResolved = path83.resolve(bridgeRoot);
50256
50341
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
50257
- const repoPath = rel === "" ? bridgeResolved : path81.join(bridgeResolved, rel);
50258
- const resolved = path81.resolve(repoPath);
50259
- if (!resolved.startsWith(bridgeResolved + path81.sep) && resolved !== bridgeResolved) {
50342
+ const repoPath = rel === "" ? bridgeResolved : path83.join(bridgeResolved, rel);
50343
+ const resolved = path83.resolve(repoPath);
50344
+ if (!resolved.startsWith(bridgeResolved + path83.sep) && resolved !== bridgeResolved) {
50260
50345
  return [];
50261
50346
  }
50262
50347
  return listRepoBranchRefs(resolved);