@buildautomaton/cli 0.1.85 → 0.1.86

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
@@ -4089,10 +4089,10 @@ function mergeDefs(...defs) {
4089
4089
  function cloneDef(schema) {
4090
4090
  return mergeDefs(schema._zod.def);
4091
4091
  }
4092
- function getElementAtPath(obj, path86) {
4093
- if (!path86)
4092
+ function getElementAtPath(obj, path88) {
4093
+ if (!path88)
4094
4094
  return obj;
4095
- return path86.reduce((acc, key) => acc?.[key], obj);
4095
+ return path88.reduce((acc, key) => acc?.[key], obj);
4096
4096
  }
4097
4097
  function promiseAllObject(promisesObj) {
4098
4098
  const keys = Object.keys(promisesObj);
@@ -4420,11 +4420,11 @@ function explicitlyAborted(x, startIndex = 0) {
4420
4420
  }
4421
4421
  return false;
4422
4422
  }
4423
- function prefixIssues(path86, issues) {
4423
+ function prefixIssues(path88, issues) {
4424
4424
  return issues.map((iss) => {
4425
4425
  var _a4;
4426
4426
  (_a4 = iss).path ?? (_a4.path = []);
4427
- iss.path.unshift(path86);
4427
+ iss.path.unshift(path88);
4428
4428
  return iss;
4429
4429
  });
4430
4430
  }
@@ -4641,16 +4641,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
4641
4641
  }
4642
4642
  function formatError(error51, mapper = (issue2) => issue2.message) {
4643
4643
  const fieldErrors = { _errors: [] };
4644
- const processError = (error52, path86 = []) => {
4644
+ const processError = (error52, path88 = []) => {
4645
4645
  for (const issue2 of error52.issues) {
4646
4646
  if (issue2.code === "invalid_union" && issue2.errors.length) {
4647
- issue2.errors.map((issues) => processError({ issues }, [...path86, ...issue2.path]));
4647
+ issue2.errors.map((issues) => processError({ issues }, [...path88, ...issue2.path]));
4648
4648
  } else if (issue2.code === "invalid_key") {
4649
- processError({ issues: issue2.issues }, [...path86, ...issue2.path]);
4649
+ processError({ issues: issue2.issues }, [...path88, ...issue2.path]);
4650
4650
  } else if (issue2.code === "invalid_element") {
4651
- processError({ issues: issue2.issues }, [...path86, ...issue2.path]);
4651
+ processError({ issues: issue2.issues }, [...path88, ...issue2.path]);
4652
4652
  } else {
4653
- const fullpath = [...path86, ...issue2.path];
4653
+ const fullpath = [...path88, ...issue2.path];
4654
4654
  if (fullpath.length === 0) {
4655
4655
  fieldErrors._errors.push(mapper(issue2));
4656
4656
  } else {
@@ -4677,17 +4677,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
4677
4677
  }
4678
4678
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
4679
4679
  const result = { errors: [] };
4680
- const processError = (error52, path86 = []) => {
4680
+ const processError = (error52, path88 = []) => {
4681
4681
  var _a4, _b;
4682
4682
  for (const issue2 of error52.issues) {
4683
4683
  if (issue2.code === "invalid_union" && issue2.errors.length) {
4684
- issue2.errors.map((issues) => processError({ issues }, [...path86, ...issue2.path]));
4684
+ issue2.errors.map((issues) => processError({ issues }, [...path88, ...issue2.path]));
4685
4685
  } else if (issue2.code === "invalid_key") {
4686
- processError({ issues: issue2.issues }, [...path86, ...issue2.path]);
4686
+ processError({ issues: issue2.issues }, [...path88, ...issue2.path]);
4687
4687
  } else if (issue2.code === "invalid_element") {
4688
- processError({ issues: issue2.issues }, [...path86, ...issue2.path]);
4688
+ processError({ issues: issue2.issues }, [...path88, ...issue2.path]);
4689
4689
  } else {
4690
- const fullpath = [...path86, ...issue2.path];
4690
+ const fullpath = [...path88, ...issue2.path];
4691
4691
  if (fullpath.length === 0) {
4692
4692
  result.errors.push(mapper(issue2));
4693
4693
  continue;
@@ -4719,8 +4719,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
4719
4719
  }
4720
4720
  function toDotPath(_path) {
4721
4721
  const segs = [];
4722
- const path86 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
4723
- for (const seg of path86) {
4722
+ const path88 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
4723
+ for (const seg of path88) {
4724
4724
  if (typeof seg === "number")
4725
4725
  segs.push(`[${seg}]`);
4726
4726
  else if (typeof seg === "symbol")
@@ -18150,13 +18150,13 @@ function resolveRef(ref, ctx) {
18150
18150
  if (!ref.startsWith("#")) {
18151
18151
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
18152
18152
  }
18153
- const path86 = ref.slice(1).split("/").filter(Boolean);
18154
- if (path86.length === 0) {
18153
+ const path88 = ref.slice(1).split("/").filter(Boolean);
18154
+ if (path88.length === 0) {
18155
18155
  return ctx.rootSchema;
18156
18156
  }
18157
18157
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
18158
- if (path86[0] === defsKey) {
18159
- const key = path86[1];
18158
+ if (path88[0] === defsKey) {
18159
+ const key = path88[1];
18160
18160
  if (!key || !ctx.defs[key]) {
18161
18161
  throw new Error(`Reference not found: ${ref}`);
18162
18162
  }
@@ -21757,7 +21757,7 @@ function readMigrationSql(filename, ...searchSubdirs) {
21757
21757
  join2(moduleDir, "..", sub, filename),
21758
21758
  join2(moduleDir, "..", "..", "dist", sub, filename)
21759
21759
  ]);
21760
- const resolved = candidates.find((path86) => existsSync(path86));
21760
+ const resolved = candidates.find((path88) => existsSync(path88));
21761
21761
  if (!resolved) {
21762
21762
  throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
21763
21763
  }
@@ -22835,7 +22835,7 @@ var require_ignore = __commonJS({
22835
22835
  // path matching.
22836
22836
  // - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
22837
22837
  // @returns {TestResult} true if a file is ignored
22838
- test(path86, checkUnignored, mode) {
22838
+ test(path88, checkUnignored, mode) {
22839
22839
  let ignored = false;
22840
22840
  let unignored = false;
22841
22841
  let matchedRule;
@@ -22844,7 +22844,7 @@ var require_ignore = __commonJS({
22844
22844
  if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
22845
22845
  return;
22846
22846
  }
22847
- const matched = rule[mode].test(path86);
22847
+ const matched = rule[mode].test(path88);
22848
22848
  if (!matched) {
22849
22849
  return;
22850
22850
  }
@@ -22865,17 +22865,17 @@ var require_ignore = __commonJS({
22865
22865
  var throwError = (message, Ctor) => {
22866
22866
  throw new Ctor(message);
22867
22867
  };
22868
- var checkPath = (path86, originalPath, doThrow) => {
22869
- if (!isString(path86)) {
22868
+ var checkPath = (path88, originalPath, doThrow) => {
22869
+ if (!isString(path88)) {
22870
22870
  return doThrow(
22871
22871
  `path must be a string, but got \`${originalPath}\``,
22872
22872
  TypeError
22873
22873
  );
22874
22874
  }
22875
- if (!path86) {
22875
+ if (!path88) {
22876
22876
  return doThrow(`path must not be empty`, TypeError);
22877
22877
  }
22878
- if (checkPath.isNotRelative(path86)) {
22878
+ if (checkPath.isNotRelative(path88)) {
22879
22879
  const r = "`path.relative()`d";
22880
22880
  return doThrow(
22881
22881
  `path should be a ${r} string, but got "${originalPath}"`,
@@ -22884,7 +22884,7 @@ var require_ignore = __commonJS({
22884
22884
  }
22885
22885
  return true;
22886
22886
  };
22887
- var isNotRelative = (path86) => REGEX_TEST_INVALID_PATH.test(path86);
22887
+ var isNotRelative = (path88) => REGEX_TEST_INVALID_PATH.test(path88);
22888
22888
  checkPath.isNotRelative = isNotRelative;
22889
22889
  checkPath.convert = (p) => p;
22890
22890
  var Ignore = class {
@@ -22914,19 +22914,19 @@ var require_ignore = __commonJS({
22914
22914
  }
22915
22915
  // @returns {TestResult}
22916
22916
  _test(originalPath, cache2, checkUnignored, slices) {
22917
- const path86 = originalPath && checkPath.convert(originalPath);
22917
+ const path88 = originalPath && checkPath.convert(originalPath);
22918
22918
  checkPath(
22919
- path86,
22919
+ path88,
22920
22920
  originalPath,
22921
22921
  this._strictPathCheck ? throwError : RETURN_FALSE
22922
22922
  );
22923
- return this._t(path86, cache2, checkUnignored, slices);
22923
+ return this._t(path88, cache2, checkUnignored, slices);
22924
22924
  }
22925
- checkIgnore(path86) {
22926
- if (!REGEX_TEST_TRAILING_SLASH.test(path86)) {
22927
- return this.test(path86);
22925
+ checkIgnore(path88) {
22926
+ if (!REGEX_TEST_TRAILING_SLASH.test(path88)) {
22927
+ return this.test(path88);
22928
22928
  }
22929
- const slices = path86.split(SLASH).filter(Boolean);
22929
+ const slices = path88.split(SLASH).filter(Boolean);
22930
22930
  slices.pop();
22931
22931
  if (slices.length) {
22932
22932
  const parent = this._t(
@@ -22939,18 +22939,18 @@ var require_ignore = __commonJS({
22939
22939
  return parent;
22940
22940
  }
22941
22941
  }
22942
- return this._rules.test(path86, false, MODE_CHECK_IGNORE);
22942
+ return this._rules.test(path88, false, MODE_CHECK_IGNORE);
22943
22943
  }
22944
- _t(path86, cache2, checkUnignored, slices) {
22945
- if (path86 in cache2) {
22946
- return cache2[path86];
22944
+ _t(path88, cache2, checkUnignored, slices) {
22945
+ if (path88 in cache2) {
22946
+ return cache2[path88];
22947
22947
  }
22948
22948
  if (!slices) {
22949
- slices = path86.split(SLASH).filter(Boolean);
22949
+ slices = path88.split(SLASH).filter(Boolean);
22950
22950
  }
22951
22951
  slices.pop();
22952
22952
  if (!slices.length) {
22953
- return cache2[path86] = this._rules.test(path86, checkUnignored, MODE_IGNORE);
22953
+ return cache2[path88] = this._rules.test(path88, checkUnignored, MODE_IGNORE);
22954
22954
  }
22955
22955
  const parent = this._t(
22956
22956
  slices.join(SLASH) + SLASH,
@@ -22958,29 +22958,29 @@ var require_ignore = __commonJS({
22958
22958
  checkUnignored,
22959
22959
  slices
22960
22960
  );
22961
- return cache2[path86] = parent.ignored ? parent : this._rules.test(path86, checkUnignored, MODE_IGNORE);
22961
+ return cache2[path88] = parent.ignored ? parent : this._rules.test(path88, checkUnignored, MODE_IGNORE);
22962
22962
  }
22963
- ignores(path86) {
22964
- return this._test(path86, this._ignoreCache, false).ignored;
22963
+ ignores(path88) {
22964
+ return this._test(path88, this._ignoreCache, false).ignored;
22965
22965
  }
22966
22966
  createFilter() {
22967
- return (path86) => !this.ignores(path86);
22967
+ return (path88) => !this.ignores(path88);
22968
22968
  }
22969
22969
  filter(paths) {
22970
22970
  return makeArray(paths).filter(this.createFilter());
22971
22971
  }
22972
22972
  // @returns {TestResult}
22973
- test(path86) {
22974
- return this._test(path86, this._testCache, true);
22973
+ test(path88) {
22974
+ return this._test(path88, this._testCache, true);
22975
22975
  }
22976
22976
  };
22977
22977
  var factory = (options) => new Ignore(options);
22978
- var isPathValid = (path86) => checkPath(path86 && checkPath.convert(path86), path86, RETURN_FALSE);
22978
+ var isPathValid = (path88) => checkPath(path88 && checkPath.convert(path88), path88, RETURN_FALSE);
22979
22979
  var setupWindows = () => {
22980
22980
  const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
22981
22981
  checkPath.convert = makePosix;
22982
22982
  const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
22983
- checkPath.isNotRelative = (path86) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path86) || isNotRelative(path86);
22983
+ checkPath.isNotRelative = (path88) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path88) || isNotRelative(path88);
22984
22984
  };
22985
22985
  if (
22986
22986
  // Detect `process` so that it can run in browsers.
@@ -27064,7 +27064,7 @@ var require_has_flag = __commonJS({
27064
27064
  var require_supports_color = __commonJS({
27065
27065
  "../../node_modules/.pnpm/supports-color@7.2.0/node_modules/supports-color/index.js"(exports, module) {
27066
27066
  "use strict";
27067
- var os10 = __require("os");
27067
+ var os11 = __require("os");
27068
27068
  var tty = __require("tty");
27069
27069
  var hasFlag = require_has_flag();
27070
27070
  var { env } = process;
@@ -27112,7 +27112,7 @@ var require_supports_color = __commonJS({
27112
27112
  return min;
27113
27113
  }
27114
27114
  if (process.platform === "win32") {
27115
- const osRelease = os10.release().split(".");
27115
+ const osRelease = os11.release().split(".");
27116
27116
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
27117
27117
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
27118
27118
  }
@@ -27358,10 +27358,10 @@ var require_src2 = __commonJS({
27358
27358
  var fs_1 = __require("fs");
27359
27359
  var debug_1 = __importDefault(require_src());
27360
27360
  var log2 = debug_1.default("@kwsites/file-exists");
27361
- function check2(path86, isFile, isDirectory) {
27362
- log2(`checking %s`, path86);
27361
+ function check2(path88, isFile, isDirectory) {
27362
+ log2(`checking %s`, path88);
27363
27363
  try {
27364
- const stat2 = fs_1.statSync(path86);
27364
+ const stat2 = fs_1.statSync(path88);
27365
27365
  if (stat2.isFile() && isFile) {
27366
27366
  log2(`[OK] path represents a file`);
27367
27367
  return true;
@@ -27381,8 +27381,8 @@ var require_src2 = __commonJS({
27381
27381
  throw e;
27382
27382
  }
27383
27383
  }
27384
- function exists2(path86, type = exports.READABLE) {
27385
- return check2(path86, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
27384
+ function exists2(path88, type = exports.READABLE) {
27385
+ return check2(path88, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
27386
27386
  }
27387
27387
  exports.exists = exists2;
27388
27388
  exports.FILE = 1;
@@ -28423,8 +28423,8 @@ function getErrorMap() {
28423
28423
 
28424
28424
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
28425
28425
  var makeIssue = (params) => {
28426
- const { data, path: path86, errorMaps, issueData } = params;
28427
- const fullPath = [...path86, ...issueData.path || []];
28426
+ const { data, path: path88, errorMaps, issueData } = params;
28427
+ const fullPath = [...path88, ...issueData.path || []];
28428
28428
  const fullIssue = {
28429
28429
  ...issueData,
28430
28430
  path: fullPath
@@ -28540,11 +28540,11 @@ var errorUtil;
28540
28540
 
28541
28541
  // ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js
28542
28542
  var ParseInputLazyPath = class {
28543
- constructor(parent, value, path86, key) {
28543
+ constructor(parent, value, path88, key) {
28544
28544
  this._cachedPath = [];
28545
28545
  this.parent = parent;
28546
28546
  this.data = value;
28547
- this._path = path86;
28547
+ this._path = path88;
28548
28548
  this._key = key;
28549
28549
  }
28550
28550
  get path() {
@@ -33880,8 +33880,8 @@ function randomSecret() {
33880
33880
  }
33881
33881
  return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
33882
33882
  }
33883
- async function requestPreviewApi(port, secret, method, path86, body) {
33884
- const url2 = `http://127.0.0.1:${port}${path86}`;
33883
+ async function requestPreviewApi(port, secret, method, path88, body) {
33884
+ const url2 = `http://127.0.0.1:${port}${path88}`;
33885
33885
  const headers = {
33886
33886
  [PREVIEW_SECRET_HEADER]: secret,
33887
33887
  "Content-Type": "application/json"
@@ -33893,7 +33893,7 @@ async function requestPreviewApi(port, secret, method, path86, body) {
33893
33893
  });
33894
33894
  const data = await res.json().catch(() => ({}));
33895
33895
  if (!res.ok) {
33896
- throw new Error(data?.error ?? `Preview API ${method} ${path86}: ${res.status}`);
33896
+ throw new Error(data?.error ?? `Preview API ${method} ${path88}: ${res.status}`);
33897
33897
  }
33898
33898
  return data;
33899
33899
  }
@@ -35195,7 +35195,7 @@ function createPendingAuthOnMessage(params) {
35195
35195
  }
35196
35196
 
35197
35197
  // src/cli-version.ts
35198
- var CLI_VERSION = "0.1.85".length > 0 ? "0.1.85" : "0.0.0-dev";
35198
+ var CLI_VERSION = "0.1.86".length > 0 ? "0.1.86" : "0.0.0-dev";
35199
35199
 
35200
35200
  // src/auth/pending/pending-auth-on-open.ts
35201
35201
  function createPendingAuthOnOpen(params) {
@@ -36566,8 +36566,8 @@ async function cancelRun(ctx, runId) {
36566
36566
  }
36567
36567
 
36568
36568
  // src/agents/acp/ensure-acp-client.ts
36569
- import * as fs23 from "node:fs";
36570
- import * as path29 from "node:path";
36569
+ import * as fs24 from "node:fs";
36570
+ import * as path31 from "node:path";
36571
36571
 
36572
36572
  // src/paths/session-layout-paths.ts
36573
36573
  import * as path26 from "node:path";
@@ -36757,6 +36757,7 @@ init_log();
36757
36757
  function createCursorAcpSessionContext(options) {
36758
36758
  const suppressLoadReplayRef = { value: false };
36759
36759
  return {
36760
+ cloudSessionId: options.cloudSessionId,
36760
36761
  cwd: options.cwd,
36761
36762
  onFileChange: options.onFileChange,
36762
36763
  mcpServers: options.mcpServers ?? [],
@@ -36849,6 +36850,41 @@ function createCursorAcpHandle(options) {
36849
36850
  // src/agents/acp/clients/cursor/cursor-acp-init.ts
36850
36851
  import * as readline from "node:readline";
36851
36852
 
36853
+ // src/agents/acp/clients/cursor/cursor-incoming-cursor-create-plan.ts
36854
+ function buildCursorCreatePlanToolCallUpdate(requestId, params) {
36855
+ const toolCallId = params.toolCallId ?? params.tool_call_id;
36856
+ if (typeof toolCallId !== "string" || !toolCallId.trim()) return null;
36857
+ const name = typeof params.name === "string" ? params.name.trim() : "";
36858
+ const overview = typeof params.overview === "string" ? params.overview : void 0;
36859
+ const plan = typeof params.plan === "string" ? params.plan : "";
36860
+ const todos = Array.isArray(params.todos) ? params.todos : void 0;
36861
+ const phases = Array.isArray(params.phases) ? params.phases : void 0;
36862
+ const isProject = typeof params.isProject === "boolean" ? params.isProject : void 0;
36863
+ return {
36864
+ sessionUpdate: "tool_call",
36865
+ toolCallId,
36866
+ title: name || "Plan",
36867
+ status: "pending",
36868
+ cursorPlan: {
36869
+ requestId,
36870
+ ...name ? { name } : {},
36871
+ ...overview != null ? { overview } : {},
36872
+ plan,
36873
+ ...todos != null ? { todos } : {},
36874
+ ...phases != null ? { phases } : {},
36875
+ ...isProject != null ? { isProject } : {}
36876
+ }
36877
+ };
36878
+ }
36879
+ function queueCursorCreatePlanRequest(method, id, msg, deps) {
36880
+ const params = msg.params ?? {};
36881
+ const requestId = String(id);
36882
+ deps.pendingRequests.set(id, { method, params });
36883
+ const update = buildCursorCreatePlanToolCallUpdate(requestId, params);
36884
+ if (update) deps.onSessionUpdate?.(update);
36885
+ deps.onRequest?.({ requestId, method, params });
36886
+ }
36887
+
36852
36888
  // src/agents/acp/clients/cursor/cursor-incoming-cursor-task.ts
36853
36889
  function buildCursorTaskToolCallUpdate(params) {
36854
36890
  const toolCallId = params.toolCallId ?? params.tool_call_id;
@@ -36881,9 +36917,13 @@ function handleCursorIncomingCursorTask(id, msg, deps) {
36881
36917
  }
36882
36918
 
36883
36919
  // src/agents/acp/clients/cursor/cursor-incoming-cursor-methods.ts
36884
- var CURSOR_BRIDGE_METHODS = /* @__PURE__ */ new Set(["cursor/create_plan", "cursor/ask_question"]);
36920
+ var CURSOR_BRIDGE_METHODS = /* @__PURE__ */ new Set(["cursor/ask_question"]);
36885
36921
  var CURSOR_NOOP_METHODS = /* @__PURE__ */ new Set(["cursor/update_todos", "cursor/generate_image"]);
36886
36922
  function handleCursorIncomingCursorMethods(method, id, msg, deps) {
36923
+ if (method === "cursor/create_plan") {
36924
+ queueCursorCreatePlanRequest(method, id, msg, deps);
36925
+ return true;
36926
+ }
36887
36927
  if (CURSOR_BRIDGE_METHODS.has(method)) {
36888
36928
  const params = msg.params ?? {};
36889
36929
  deps.pendingRequests.set(id, { method, params });
@@ -36997,10 +37037,71 @@ function handleCursorIncomingPermissionRequest(id, method, msg, deps) {
36997
37037
  return true;
36998
37038
  }
36999
37039
 
37040
+ // src/agents/acp/clients/cursor/write-create-plan-file.ts
37041
+ import * as fs23 from "node:fs";
37042
+ import * as path28 from "node:path";
37043
+ import { pathToFileURL as pathToFileURL2 } from "node:url";
37044
+
37045
+ // src/paths/session-plans-paths.ts
37046
+ import * as os8 from "node:os";
37047
+ import * as path27 from "node:path";
37048
+ function getSessionPlansRootDir() {
37049
+ return path27.join(os8.homedir(), ".buildautomaton", "plans");
37050
+ }
37051
+ function sanitizeSessionPlansKey(sessionId) {
37052
+ const t = sessionId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 220);
37053
+ return t || "session";
37054
+ }
37055
+ function getSessionPlansDir(sessionId) {
37056
+ return path27.join(getSessionPlansRootDir(), sanitizeSessionPlansKey(sessionId));
37057
+ }
37058
+
37059
+ // src/agents/acp/clients/cursor/write-create-plan-file.ts
37060
+ function sanitizePlanFileBase(toolCallId) {
37061
+ const t = toolCallId.replace(/[^a-zA-Z0-9_-]+/g, "_").slice(0, 120);
37062
+ return t || "plan";
37063
+ }
37064
+ function writeCreatePlanFile(params) {
37065
+ const dir = getSessionPlansDir(params.cloudSessionId);
37066
+ fs23.mkdirSync(dir, { recursive: true });
37067
+ const filePath = path28.join(dir, `${sanitizePlanFileBase(params.toolCallId)}.md`);
37068
+ fs23.writeFileSync(filePath, params.planMarkdown, "utf8");
37069
+ return pathToFileURL2(filePath).href;
37070
+ }
37071
+
37072
+ // src/agents/acp/clients/cursor/enrich-create-plan-rpc-result.ts
37073
+ function asRecord2(v) {
37074
+ return v != null && typeof v === "object" && !Array.isArray(v) ? v : null;
37075
+ }
37076
+ function enrichCreatePlanRpcResult(result, pendingParams, cloudSessionId) {
37077
+ const root = asRecord2(result);
37078
+ const outcome = asRecord2(root?.outcome);
37079
+ if (!outcome) return result;
37080
+ const kind = typeof outcome.outcome === "string" ? outcome.outcome : "";
37081
+ if (kind !== "accepted") {
37082
+ const { plan: _drop, ...rest } = outcome;
37083
+ return { ...root, outcome: rest };
37084
+ }
37085
+ const planMarkdown = typeof outcome.plan === "string" ? outcome.plan : "";
37086
+ const toolCallIdRaw = pendingParams.toolCallId ?? pendingParams.tool_call_id;
37087
+ const toolCallId = typeof toolCallIdRaw === "string" ? toolCallIdRaw.trim() : "";
37088
+ const sessionId = cloudSessionId?.trim() ?? "";
37089
+ if (planMarkdown && toolCallId && sessionId) {
37090
+ const planUri = writeCreatePlanFile({ cloudSessionId: sessionId, toolCallId, planMarkdown });
37091
+ return { outcome: { outcome: "accepted", planUri } };
37092
+ }
37093
+ return { outcome: { outcome: "accepted" } };
37094
+ }
37095
+
37000
37096
  // src/agents/acp/clients/cursor/cursor-incoming-resolve-request.ts
37001
- function resolveCursorIncomingRequest(pendingRequests2, respond, requestId, result) {
37097
+ function resolveCursorIncomingRequest(pendingRequests2, respond, requestId, result, cloudSessionId) {
37002
37098
  const pending2 = pendingRequests2.get(requestId);
37003
- const payload = pending2?.method === "session/request_permission" ? enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params) : result;
37099
+ let payload = result;
37100
+ if (pending2?.method === "session/request_permission") {
37101
+ payload = enrichAcpPermissionRpcResultFromRequestParams(result, pending2.params);
37102
+ } else if (pending2?.method === "cursor/create_plan") {
37103
+ payload = enrichCreatePlanRpcResult(result, pending2.params, cloudSessionId ?? void 0);
37104
+ }
37004
37105
  respond(requestId, payload);
37005
37106
  pendingRequests2.delete(requestId);
37006
37107
  }
@@ -37061,7 +37162,13 @@ function createCursorAcpIncomingLineHandler(deps) {
37061
37162
  pendingRequests: deps.pendingRequests
37062
37163
  };
37063
37164
  return {
37064
- resolveRequest: (requestId, result) => resolveCursorIncomingRequest(deps.pendingRequests, deps.respond, requestId, result),
37165
+ resolveRequest: (requestId, result) => resolveCursorIncomingRequest(
37166
+ deps.pendingRequests,
37167
+ deps.respond,
37168
+ requestId,
37169
+ result,
37170
+ deps.sessionCtx.cloudSessionId
37171
+ ),
37065
37172
  handleLine(line) {
37066
37173
  const msg = safeJsonParse(line);
37067
37174
  if (!msg) return;
@@ -37264,6 +37371,7 @@ async function createCursorAcpClient(options) {
37264
37371
  const skipBrowserAuthenticate = cursorAgentUsesApiKeyAuth(spawnEnv);
37265
37372
  const sessionCtx = createCursorAcpSessionContext({
37266
37373
  cwd,
37374
+ cloudSessionId: options.cloudSessionId,
37267
37375
  mcpServers: options.mcpServers,
37268
37376
  persistedAcpSessionId,
37269
37377
  backendAgentType,
@@ -37413,18 +37521,18 @@ import { existsSync as existsSync4, statSync } from "node:fs";
37413
37521
 
37414
37522
  // src/git/get-git-repo-root-sync.ts
37415
37523
  import { execFileSync as execFileSync3 } from "node:child_process";
37416
- import * as path27 from "node:path";
37524
+ import * as path29 from "node:path";
37417
37525
  var GIT_LOOKUP_TIMEOUT_MS = 2e3;
37418
37526
  function getGitRepoRootSync(startDir) {
37419
37527
  try {
37420
37528
  const out = execFileSync3("git", ["rev-parse", "--show-toplevel"], {
37421
- cwd: path27.resolve(startDir),
37529
+ cwd: path29.resolve(startDir),
37422
37530
  encoding: "utf8",
37423
37531
  stdio: ["ignore", "pipe", "ignore"],
37424
37532
  maxBuffer: 1024 * 1024,
37425
37533
  timeout: GIT_LOOKUP_TIMEOUT_MS
37426
37534
  }).trim();
37427
- return out ? path27.resolve(out) : null;
37535
+ return out ? path29.resolve(out) : null;
37428
37536
  } catch {
37429
37537
  return null;
37430
37538
  }
@@ -37433,26 +37541,26 @@ function getGitRepoRootSync(startDir) {
37433
37541
  // src/agents/acp/workspace-files.ts
37434
37542
  import { execFileSync as execFileSync4 } from "node:child_process";
37435
37543
  import { readFileSync as readFileSync4 } from "node:fs";
37436
- import * as path28 from "node:path";
37544
+ import * as path30 from "node:path";
37437
37545
  var GIT_FILE_READ_TIMEOUT_MS = 2e3;
37438
37546
  function resolveWorkspaceFilePath(sessionParentPath, rawPath) {
37439
37547
  const trimmed2 = rawPath.trim();
37440
37548
  if (!trimmed2) return null;
37441
- const normalizedSessionParent = path28.resolve(sessionParentPath);
37549
+ const normalizedSessionParent = path30.resolve(sessionParentPath);
37442
37550
  let resolvedPath = resolveSafePathUnderCwd(sessionParentPath, trimmed2);
37443
37551
  if (!resolvedPath) {
37444
- const candidate = path28.isAbsolute(trimmed2) ? path28.normalize(trimmed2) : path28.normalize(path28.resolve(normalizedSessionParent, trimmed2));
37552
+ const candidate = path30.isAbsolute(trimmed2) ? path30.normalize(trimmed2) : path30.normalize(path30.resolve(normalizedSessionParent, trimmed2));
37445
37553
  const gitRoot2 = getGitRepoRootSync(sessionParentPath);
37446
37554
  if (!gitRoot2) return null;
37447
- const rel = path28.relative(gitRoot2, candidate);
37448
- if (rel.startsWith("..") || path28.isAbsolute(rel)) return null;
37555
+ const rel = path30.relative(gitRoot2, candidate);
37556
+ if (rel.startsWith("..") || path30.isAbsolute(rel)) return null;
37449
37557
  resolvedPath = candidate;
37450
37558
  }
37451
37559
  const gitRoot = getGitRepoRootSync(sessionParentPath);
37452
37560
  if (gitRoot) {
37453
- const relFromRoot = path28.relative(gitRoot, resolvedPath);
37454
- if (!relFromRoot.startsWith("..") && !path28.isAbsolute(relFromRoot)) {
37455
- return { resolvedPath, display: relFromRoot.split(path28.sep).join("/") };
37561
+ const relFromRoot = path30.relative(gitRoot, resolvedPath);
37562
+ if (!relFromRoot.startsWith("..") && !path30.isAbsolute(relFromRoot)) {
37563
+ return { resolvedPath, display: relFromRoot.split(path30.sep).join("/") };
37456
37564
  }
37457
37565
  }
37458
37566
  return { resolvedPath, display: toDisplayPathRelativeToCwd(sessionParentPath, resolvedPath) };
@@ -37461,9 +37569,9 @@ function readUtf8WorkspaceFile(sessionParentPath, displayPath) {
37461
37569
  if (!displayPath || displayPath.includes("..")) return "";
37462
37570
  const gitRoot = getGitRepoRootSync(sessionParentPath);
37463
37571
  if (gitRoot) {
37464
- const resolvedPath2 = path28.resolve(gitRoot, displayPath);
37465
- const rel = path28.relative(gitRoot, resolvedPath2);
37466
- if (!rel.startsWith("..") && !path28.isAbsolute(rel)) {
37572
+ const resolvedPath2 = path30.resolve(gitRoot, displayPath);
37573
+ const rel = path30.relative(gitRoot, resolvedPath2);
37574
+ if (!rel.startsWith("..") && !path30.isAbsolute(rel)) {
37467
37575
  try {
37468
37576
  return readFileSync4(resolvedPath2, "utf8");
37469
37577
  } catch {
@@ -37482,9 +37590,9 @@ function tryWorkspaceDisplayToPath(sessionParentPath, displayPath) {
37482
37590
  if (!displayPath || displayPath.includes("..")) return null;
37483
37591
  const gitRoot = getGitRepoRootSync(sessionParentPath);
37484
37592
  if (gitRoot) {
37485
- const resolvedPath = path28.resolve(gitRoot, displayPath);
37486
- const rel = path28.relative(gitRoot, resolvedPath);
37487
- if (!rel.startsWith("..") && !path28.isAbsolute(rel)) return resolvedPath;
37593
+ const resolvedPath = path30.resolve(gitRoot, displayPath);
37594
+ const rel = path30.relative(gitRoot, resolvedPath);
37595
+ if (!rel.startsWith("..") && !path30.isAbsolute(rel)) return resolvedPath;
37488
37596
  }
37489
37597
  return resolveSafePathUnderCwd(sessionParentPath, displayPath);
37490
37598
  }
@@ -38371,11 +38479,11 @@ init_cli_process_interrupt();
38371
38479
  var BRIDGE_MCP_SERVER_NAME2 = "buildautomaton-bridge";
38372
38480
 
38373
38481
  // src/mcp/resolve-bridge-mcp-server-path.ts
38374
- import { dirname as dirname7, join as join7 } from "node:path";
38482
+ import { dirname as dirname7, join as join9 } from "node:path";
38375
38483
  import { fileURLToPath as fileURLToPath7 } from "node:url";
38376
38484
  function resolveBridgeMcpServerScriptPath() {
38377
38485
  const cliDir = dirname7(fileURLToPath7(import.meta.url));
38378
- return join7(cliDir, "bridge-mcp-server.js");
38486
+ return join9(cliDir, "bridge-mcp-server.js");
38379
38487
  }
38380
38488
 
38381
38489
  // src/mcp/build-acp-mcp-servers.ts
@@ -38434,7 +38542,7 @@ async function ensureAcpClient(options) {
38434
38542
  if (state.acpStartPromise && !state.acpHandle) {
38435
38543
  await state.acpStartPromise;
38436
38544
  }
38437
- if (state.acpHandle && state.lastAcpCwd != null && path29.resolve(state.lastAcpCwd) !== path29.resolve(targetSessionParentPath)) {
38545
+ if (state.acpHandle && state.lastAcpCwd != null && path31.resolve(state.lastAcpCwd) !== path31.resolve(targetSessionParentPath)) {
38438
38546
  try {
38439
38547
  state.acpHandle.disconnect();
38440
38548
  } catch {
@@ -38466,7 +38574,7 @@ async function ensureAcpClient(options) {
38466
38574
  if (!state.acpStartPromise) {
38467
38575
  let statOk = false;
38468
38576
  try {
38469
- const st = await fs23.promises.stat(targetSessionParentPath);
38577
+ const st = await fs24.promises.stat(targetSessionParentPath);
38470
38578
  statOk = st.isDirectory();
38471
38579
  if (!statOk) {
38472
38580
  state.lastAcpStartError = `Agent cwd is not a directory: ${targetSessionParentPath}`;
@@ -38545,6 +38653,7 @@ async function ensureAcpClient(options) {
38545
38653
  },
38546
38654
  ...hooks,
38547
38655
  cwd: targetSessionParentPath,
38656
+ cloudSessionId: cloudSessionId ?? null,
38548
38657
  mcpServers
38549
38658
  }).then(async (h) => {
38550
38659
  if (spawnEpoch !== state.clientEpoch || isCliImmediateShutdownRequested()) {
@@ -38764,8 +38873,8 @@ async function execGitFile(args, options) {
38764
38873
  }
38765
38874
 
38766
38875
  // src/git/changes/parse/normalize-git-diff-path.ts
38767
- function normalizeGitDiffPath(path86) {
38768
- return path86.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
38876
+ function normalizeGitDiffPath(path88) {
38877
+ return path88.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
38769
38878
  }
38770
38879
 
38771
38880
  // src/git/changes/parse/parse-name-status-entries.ts
@@ -38804,7 +38913,7 @@ function parseNameStatusLines(lines) {
38804
38913
  }
38805
38914
 
38806
38915
  // src/git/snapshot/diff/messages.ts
38807
- import * as path30 from "node:path";
38916
+ import * as path32 from "node:path";
38808
38917
 
38809
38918
  // src/git/snapshot/diff/files.ts
38810
38919
  import { readFile, stat } from "node:fs/promises";
@@ -38835,7 +38944,7 @@ async function buildTrackedChangeMessage(options) {
38835
38944
  const diffArgs = entry.change === "moved" && oldRel ? ["diff", "--no-color", "-M", baselineRev, "--", oldRel, rel] : ["diff", "--no-color", "-M", baselineRev, "--", rel];
38836
38945
  const { stdout: patchContent } = await execGitFile(diffArgs, { cwd: repoPath });
38837
38946
  if (!patchContent.trim()) return null;
38838
- const workspaceFilePath = path30.join(repoPath, rel);
38947
+ const workspaceFilePath = path32.join(repoPath, rel);
38839
38948
  const newText = entry.change === "removed" ? "" : await readWorkspaceFileAsUtf8(workspaceFilePath);
38840
38949
  const oldText = entry.change === "added" ? "" : await readGitBlobAsUtf8(repoPath, baselineRev, oldRel ?? rel);
38841
38950
  return {
@@ -38867,9 +38976,9 @@ function buildUntrackedChangeMessage(options) {
38867
38976
  }
38868
38977
 
38869
38978
  // src/git/snapshot/diff/paths.ts
38870
- import * as path31 from "node:path";
38979
+ import * as path33 from "node:path";
38871
38980
  function repoDisplayPath(repoPath, multiRepo) {
38872
- const slug = path31.basename(repoPath).replace(/[^\w.-]+/g, "_") || "repo";
38981
+ const slug = path33.basename(repoPath).replace(/[^\w.-]+/g, "_") || "repo";
38873
38982
  return (rel) => multiRepo ? `${slug}/${rel}` : rel;
38874
38983
  }
38875
38984
  function safeRelPath(rel) {
@@ -38881,12 +38990,12 @@ function newUntrackedPaths(raw, baselineUntracked, seen) {
38881
38990
  }
38882
38991
 
38883
38992
  // src/git/snapshot/diff/move-pairs.ts
38884
- import * as path32 from "node:path";
38993
+ import * as path34 from "node:path";
38885
38994
  async function readUntrackedTexts(repoPath, untracked) {
38886
38995
  const out = /* @__PURE__ */ new Map();
38887
38996
  await forEachWithGitYield(untracked, async (rel) => {
38888
38997
  if (!safeRelPath(rel)) return;
38889
- const newText = await readWorkspaceFileAsUtf8(path32.join(repoPath, rel));
38998
+ const newText = await readWorkspaceFileAsUtf8(path34.join(repoPath, rel));
38890
38999
  if (newText !== void 0) out.set(rel, newText);
38891
39000
  });
38892
39001
  return out;
@@ -39003,12 +39112,12 @@ async function collectRepoTurnChanges(options) {
39003
39112
  import { readFile as readFile2 } from "node:fs/promises";
39004
39113
 
39005
39114
  // src/git/snapshot/types.ts
39006
- import * as path33 from "node:path";
39115
+ import * as path35 from "node:path";
39007
39116
  function snapshotsDirForCwd(agentCwd) {
39008
- return path33.join(agentCwd, ".buildautomaton", "snapshots");
39117
+ return path35.join(agentCwd, ".buildautomaton", "snapshots");
39009
39118
  }
39010
39119
  function snapshotFilePath(agentCwd, runId) {
39011
- return path33.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
39120
+ return path35.join(snapshotsDirForCwd(agentCwd), `${runId}.json`);
39012
39121
  }
39013
39122
 
39014
39123
  // src/git/snapshot/diff/load-pre-turn-snapshot.ts
@@ -39076,6 +39185,18 @@ function reportPostTurnEnrichment(options) {
39076
39185
  });
39077
39186
  }
39078
39187
 
39188
+ // src/agents/acp/clients/cursor/cleanup-session-plans.ts
39189
+ import * as fs25 from "node:fs";
39190
+ function cleanupSessionPlans(sessionId) {
39191
+ const id = typeof sessionId === "string" ? sessionId.trim() : "";
39192
+ if (!id) return;
39193
+ const dir = getSessionPlansDir(id);
39194
+ try {
39195
+ fs25.rmSync(dir, { recursive: true, force: true });
39196
+ } catch {
39197
+ }
39198
+ }
39199
+
39079
39200
  // src/agents/acp/prompts/finalize-and-send-prompt-result.ts
39080
39201
  async function finalizeAndSendPromptResult(params) {
39081
39202
  const {
@@ -39093,6 +39214,7 @@ async function finalizeAndSendPromptResult(params) {
39093
39214
  sendSessionUpdate,
39094
39215
  log: log2
39095
39216
  } = params;
39217
+ cleanupSessionPlans(sessionId);
39096
39218
  const planningTodosSubmit = isPlanningSession ? await maybeSubmitPlanningTodosAfterAgentSuccess({
39097
39219
  sessionId,
39098
39220
  runId,
@@ -40387,7 +40509,7 @@ async function createBridgeAccessState(options = {}) {
40387
40509
  }
40388
40510
 
40389
40511
  // src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
40390
- import * as path35 from "node:path";
40512
+ import * as path37 from "node:path";
40391
40513
 
40392
40514
  // src/agents/detect-local-agent-types.ts
40393
40515
  init_yield_to_event_loop();
@@ -40492,7 +40614,7 @@ function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
40492
40614
  init_cli_database();
40493
40615
 
40494
40616
  // src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
40495
- import * as path34 from "node:path";
40617
+ import * as path36 from "node:path";
40496
40618
  init_cli_database();
40497
40619
  init_cli_process_interrupt();
40498
40620
  async function probeOneAgentTypeForCapabilities(params) {
@@ -40532,7 +40654,7 @@ async function probeOneAgentTypeForCapabilities(params) {
40532
40654
  if (!canContinue()) return false;
40533
40655
  handle = await resolved.createClient({
40534
40656
  command: resolved.command,
40535
- cwd: path34.resolve(cwd),
40657
+ cwd: path36.resolve(cwd),
40536
40658
  backendAgentType: agentType,
40537
40659
  sessionMode: "agent",
40538
40660
  persistedAcpSessionId: null,
@@ -40625,7 +40747,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
40625
40747
  const { workspaceId, log: log2, getWs } = params;
40626
40748
  const isCurrent = beginAgentCapabilityWarmupRun();
40627
40749
  if (!isCurrent()) return;
40628
- const cwd = path35.resolve(getBridgeRoot());
40750
+ const cwd = path37.resolve(getBridgeRoot());
40629
40751
  async function sendBatchFromCache() {
40630
40752
  if (!isCurrent()) return;
40631
40753
  const socket = getWs();
@@ -40752,7 +40874,7 @@ async function createBridgeAccessAndAcp(options) {
40752
40874
  }
40753
40875
 
40754
40876
  // src/connection/create-bridge-preview-stack.ts
40755
- import * as path38 from "node:path";
40877
+ import * as path40 from "node:path";
40756
40878
 
40757
40879
  // src/preview-environments/manager/firehose-messages.ts
40758
40880
  function buildFirehoseSnapshotMessage(params) {
@@ -41070,7 +41192,7 @@ function attachChildErrorHandler(d) {
41070
41192
  }
41071
41193
 
41072
41194
  // src/preview-environments/process/wire/handle-exit.ts
41073
- import fs24 from "node:fs";
41195
+ import fs26 from "node:fs";
41074
41196
  function logStopLine(d, code, signal) {
41075
41197
  const { title } = d;
41076
41198
  if (signal) {
@@ -41109,7 +41231,7 @@ function attachChildExitHandler(d) {
41109
41231
  const cleanupDir = d.mergedCleanupDir;
41110
41232
  const mergedPath = d.mergedLogPath;
41111
41233
  if (mergedPath && !stale) {
41112
- fs24.readFile(mergedPath, (err, buf) => {
41234
+ fs26.readFile(mergedPath, (err, buf) => {
41113
41235
  if (!err && buf.length > d.mergedReadPos.value) {
41114
41236
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
41115
41237
  if (chunk.length > 0) {
@@ -41155,7 +41277,7 @@ function wireChildOutputPipes(d) {
41155
41277
  }
41156
41278
 
41157
41279
  // src/preview-environments/process/wire/poll-merged-log.ts
41158
- import fs25 from "node:fs";
41280
+ import fs27 from "node:fs";
41159
41281
  function startMergedLogPoll(d) {
41160
41282
  if (!d.mergedLogPath || !d.mergedCleanupDir) return;
41161
41283
  const { environmentId } = d;
@@ -41165,7 +41287,7 @@ function startMergedLogPoll(d) {
41165
41287
  d.setPollInterval(void 0);
41166
41288
  return;
41167
41289
  }
41168
- fs25.readFile(d.mergedLogPath, (err, buf) => {
41290
+ fs27.readFile(d.mergedLogPath, (err, buf) => {
41169
41291
  if (err || (d.getSpawnGeneration() ?? 0) !== d.scheduledGen) return;
41170
41292
  if (buf.length <= d.mergedReadPos.value) return;
41171
41293
  const chunk = Buffer.from(buf.subarray(d.mergedReadPos.value));
@@ -41380,7 +41502,7 @@ function previewEnvironmentSpawnOptions(lifecycle = DEFAULT_PREVIEW_ENVIRONMENT_
41380
41502
  }
41381
41503
 
41382
41504
  // src/preview-environments/manager/shell-spawn/utils.ts
41383
- import fs26 from "node:fs";
41505
+ import fs28 from "node:fs";
41384
41506
  function mergePreviewEnvironmentSpawnOptions(opts, lifecycle = DEFAULT_PREVIEW_ENVIRONMENT_PROCESS_LIFECYCLE) {
41385
41507
  return { ...opts, ...previewEnvironmentSpawnOptions(lifecycle) };
41386
41508
  }
@@ -41389,7 +41511,7 @@ function isSpawnEbadf(e) {
41389
41511
  }
41390
41512
  function rmDirQuiet(dir) {
41391
41513
  try {
41392
- fs26.rmSync(dir, { recursive: true, force: true });
41514
+ fs28.rmSync(dir, { recursive: true, force: true });
41393
41515
  } catch {
41394
41516
  }
41395
41517
  }
@@ -41397,7 +41519,7 @@ var cachedDevNullReadFd;
41397
41519
  function devNullReadFd() {
41398
41520
  if (cachedDevNullReadFd === void 0) {
41399
41521
  const devPath = process.platform === "win32" ? "nul" : "/dev/null";
41400
- cachedDevNullReadFd = fs26.openSync(devPath, "r");
41522
+ cachedDevNullReadFd = fs28.openSync(devPath, "r");
41401
41523
  }
41402
41524
  return cachedDevNullReadFd;
41403
41525
  }
@@ -41477,15 +41599,15 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal, lifecycle)
41477
41599
 
41478
41600
  // src/preview-environments/manager/shell-spawn/try-spawn-merged-log-file.ts
41479
41601
  import { spawn as spawn7 } from "node:child_process";
41480
- import fs27 from "node:fs";
41602
+ import fs29 from "node:fs";
41481
41603
  import { tmpdir } from "node:os";
41482
- import path36 from "node:path";
41604
+ import path38 from "node:path";
41483
41605
  function trySpawnMergedLogFile(command, env, cwd, signal, lifecycle) {
41484
- const tmpRoot = fs27.mkdtempSync(path36.join(tmpdir(), "ba-devsrv-log-"));
41485
- const logPath = path36.join(tmpRoot, "combined.log");
41606
+ const tmpRoot = fs29.mkdtempSync(path38.join(tmpdir(), "ba-devsrv-log-"));
41607
+ const logPath = path38.join(tmpRoot, "combined.log");
41486
41608
  let logFd;
41487
41609
  try {
41488
- logFd = fs27.openSync(logPath, "a");
41610
+ logFd = fs29.openSync(logPath, "a");
41489
41611
  } catch {
41490
41612
  rmDirQuiet(tmpRoot);
41491
41613
  return null;
@@ -41509,7 +41631,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal, lifecycle) {
41509
41631
  mergePreviewEnvironmentSpawnOptions({ env, cwd, stdio, ...signal ? { signal } : {} }, lifecycle)
41510
41632
  );
41511
41633
  }
41512
- fs27.closeSync(logFd);
41634
+ fs29.closeSync(logFd);
41513
41635
  return {
41514
41636
  proc,
41515
41637
  pipedStdoutStderr: true,
@@ -41518,7 +41640,7 @@ function trySpawnMergedLogFile(command, env, cwd, signal, lifecycle) {
41518
41640
  };
41519
41641
  } catch (e) {
41520
41642
  try {
41521
- fs27.closeSync(logFd);
41643
+ fs29.closeSync(logFd);
41522
41644
  } catch {
41523
41645
  }
41524
41646
  rmDirQuiet(tmpRoot);
@@ -41529,22 +41651,22 @@ function trySpawnMergedLogFile(command, env, cwd, signal, lifecycle) {
41529
41651
 
41530
41652
  // src/preview-environments/manager/shell-spawn/try-spawn-shell-script-log-redirect.ts
41531
41653
  import { spawn as spawn8 } from "node:child_process";
41532
- import fs28 from "node:fs";
41654
+ import fs30 from "node:fs";
41533
41655
  import { tmpdir as tmpdir2 } from "node:os";
41534
- import path37 from "node:path";
41656
+ import path39 from "node:path";
41535
41657
  function shSingleQuote(s) {
41536
41658
  return `'${s.replace(/'/g, `'\\''`)}'`;
41537
41659
  }
41538
41660
  function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal, lifecycle) {
41539
- const tmpRoot = fs28.mkdtempSync(path37.join(tmpdir2(), "ba-devsrv-sh-"));
41540
- const logPath = path37.join(tmpRoot, "combined.log");
41541
- const innerPath = path37.join(tmpRoot, "_cmd.sh");
41542
- const runnerPath = path37.join(tmpRoot, "_run.sh");
41661
+ const tmpRoot = fs30.mkdtempSync(path39.join(tmpdir2(), "ba-devsrv-sh-"));
41662
+ const logPath = path39.join(tmpRoot, "combined.log");
41663
+ const innerPath = path39.join(tmpRoot, "_cmd.sh");
41664
+ const runnerPath = path39.join(tmpRoot, "_run.sh");
41543
41665
  try {
41544
- fs28.writeFileSync(innerPath, `#!/bin/sh
41666
+ fs30.writeFileSync(innerPath, `#!/bin/sh
41545
41667
  ${command}
41546
41668
  `);
41547
- fs28.writeFileSync(
41669
+ fs30.writeFileSync(
41548
41670
  runnerPath,
41549
41671
  `#!/bin/sh
41550
41672
  cd ${shSingleQuote(cwd)}
@@ -41572,13 +41694,13 @@ cd ${shSingleQuote(cwd)}
41572
41694
  }
41573
41695
  }
41574
41696
  function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal, lifecycle) {
41575
- const tmpRoot = fs28.mkdtempSync(path37.join(tmpdir2(), "ba-devsrv-sh-"));
41576
- const logPath = path37.join(tmpRoot, "combined.log");
41577
- const runnerPath = path37.join(tmpRoot, "_run.bat");
41697
+ const tmpRoot = fs30.mkdtempSync(path39.join(tmpdir2(), "ba-devsrv-sh-"));
41698
+ const logPath = path39.join(tmpRoot, "combined.log");
41699
+ const runnerPath = path39.join(tmpRoot, "_run.bat");
41578
41700
  const q = (p) => `"${p.replace(/"/g, '""')}"`;
41579
41701
  const com = process.env.ComSpec || "cmd.exe";
41580
41702
  try {
41581
- fs28.writeFileSync(
41703
+ fs30.writeFileSync(
41582
41704
  runnerPath,
41583
41705
  `@ECHO OFF\r
41584
41706
  CD /D ${q(cwd)}\r
@@ -41896,8 +42018,8 @@ function createBridgePreviewStack(options) {
41896
42018
  scheduleInitialIndexBuilds(getBridgeRoot());
41897
42019
  };
41898
42020
  const identifyReportedPaths = {
41899
- bridgeRootPath: path38.resolve(getBridgeRoot()),
41900
- worktreesRootPath: path38.resolve(options.worktreesRootPath),
42021
+ bridgeRootPath: path40.resolve(getBridgeRoot()),
42022
+ worktreesRootPath: path40.resolve(options.worktreesRootPath),
41901
42023
  localShortcutPort: 0,
41902
42024
  localShortcutToken: ""
41903
42025
  };
@@ -42624,17 +42746,17 @@ async function yieldSkillDiscoveryWork(entryCount) {
42624
42746
  }
42625
42747
 
42626
42748
  // src/skills/discovery/discover-local-skills.ts
42627
- import fs29 from "node:fs";
42628
- import path39 from "node:path";
42749
+ import fs31 from "node:fs";
42750
+ import path41 from "node:path";
42629
42751
  function collectSkillFromDir(rel, base, name, seenKeys, out) {
42630
- const dir = path39.join(base, name);
42752
+ const dir = path41.join(base, name);
42631
42753
  try {
42632
- if (!fs29.statSync(dir).isDirectory()) return;
42754
+ if (!fs31.statSync(dir).isDirectory()) return;
42633
42755
  } catch {
42634
42756
  return;
42635
42757
  }
42636
- const skillMd = path39.join(dir, "SKILL.md");
42637
- if (!fs29.existsSync(skillMd)) return;
42758
+ const skillMd = path41.join(dir, "SKILL.md");
42759
+ if (!fs31.existsSync(skillMd)) return;
42638
42760
  const key = `${rel}/${name}`;
42639
42761
  if (seenKeys.has(key)) return;
42640
42762
  seenKeys.add(key);
@@ -42646,11 +42768,11 @@ async function discoverLocalSkillsAsync(cwd) {
42646
42768
  let work = 0;
42647
42769
  for (const rel of SKILL_DISCOVERY_ROOTS) {
42648
42770
  await yieldSkillDiscoveryWork(++work);
42649
- const base = path39.join(cwd, rel);
42650
- if (!fs29.existsSync(base) || !fs29.statSync(base).isDirectory()) continue;
42771
+ const base = path41.join(cwd, rel);
42772
+ if (!fs31.existsSync(base) || !fs31.statSync(base).isDirectory()) continue;
42651
42773
  let entries = [];
42652
42774
  try {
42653
- entries = fs29.readdirSync(base);
42775
+ entries = fs31.readdirSync(base);
42654
42776
  } catch {
42655
42777
  continue;
42656
42778
  }
@@ -42663,16 +42785,16 @@ async function discoverLocalSkillsAsync(cwd) {
42663
42785
  }
42664
42786
 
42665
42787
  // src/skills/discovery/discover-skill-layout-roots.ts
42666
- import fs30 from "node:fs";
42667
- import path40 from "node:path";
42788
+ import fs32 from "node:fs";
42789
+ import path42 from "node:path";
42668
42790
  function collectLayoutSkill(rel, base, name, skills2) {
42669
- const dir = path40.join(base, name);
42791
+ const dir = path42.join(base, name);
42670
42792
  try {
42671
- if (!fs30.statSync(dir).isDirectory()) return;
42793
+ if (!fs32.statSync(dir).isDirectory()) return;
42672
42794
  } catch {
42673
42795
  return;
42674
42796
  }
42675
- if (!fs30.existsSync(path40.join(dir, "SKILL.md"))) return;
42797
+ if (!fs32.existsSync(path42.join(dir, "SKILL.md"))) return;
42676
42798
  const relPath = `${rel}/${name}`.replace(/\\/g, "/");
42677
42799
  skills2.push({ name, relPath });
42678
42800
  }
@@ -42681,11 +42803,11 @@ async function discoverSkillLayoutRootsAsync(cwd) {
42681
42803
  let work = 0;
42682
42804
  for (const rel of SKILL_DISCOVERY_ROOTS) {
42683
42805
  await yieldSkillDiscoveryWork(++work);
42684
- const base = path40.join(cwd, rel);
42685
- if (!fs30.existsSync(base) || !fs30.statSync(base).isDirectory()) continue;
42806
+ const base = path42.join(cwd, rel);
42807
+ if (!fs32.existsSync(base) || !fs32.statSync(base).isDirectory()) continue;
42686
42808
  let entries = [];
42687
42809
  try {
42688
- entries = fs30.readdirSync(base);
42810
+ entries = fs32.readdirSync(base);
42689
42811
  } catch {
42690
42812
  continue;
42691
42813
  }
@@ -42832,12 +42954,12 @@ function createBridgeRuntimeMessageSetup(options) {
42832
42954
  }
42833
42955
 
42834
42956
  // src/worktrees/worktree-layout-file.ts
42835
- import * as fs31 from "node:fs";
42836
- import * as path41 from "node:path";
42837
- import os8 from "node:os";
42957
+ import * as fs33 from "node:fs";
42958
+ import * as path43 from "node:path";
42959
+ import os9 from "node:os";
42838
42960
  var LAYOUT_FILENAME = "worktree-launcher-layout.json";
42839
42961
  function defaultWorktreeLayoutPath() {
42840
- return path41.join(os8.homedir(), ".buildautomaton", LAYOUT_FILENAME);
42962
+ return path43.join(os9.homedir(), ".buildautomaton", LAYOUT_FILENAME);
42841
42963
  }
42842
42964
  function normalizeLoadedLayout(raw) {
42843
42965
  if (raw && typeof raw === "object" && "launcherCwds" in raw) {
@@ -42849,8 +42971,8 @@ function normalizeLoadedLayout(raw) {
42849
42971
  function loadWorktreeLayout() {
42850
42972
  try {
42851
42973
  const p = defaultWorktreeLayoutPath();
42852
- if (!fs31.existsSync(p)) return { launcherCwds: [] };
42853
- const raw = JSON.parse(fs31.readFileSync(p, "utf8"));
42974
+ if (!fs33.existsSync(p)) return { launcherCwds: [] };
42975
+ const raw = JSON.parse(fs33.readFileSync(p, "utf8"));
42854
42976
  return normalizeLoadedLayout(raw);
42855
42977
  } catch {
42856
42978
  return { launcherCwds: [] };
@@ -42858,24 +42980,24 @@ function loadWorktreeLayout() {
42858
42980
  }
42859
42981
  function saveWorktreeLayout(layout) {
42860
42982
  try {
42861
- const dir = path41.dirname(defaultWorktreeLayoutPath());
42862
- fs31.mkdirSync(dir, { recursive: true });
42863
- fs31.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
42983
+ const dir = path43.dirname(defaultWorktreeLayoutPath());
42984
+ fs33.mkdirSync(dir, { recursive: true });
42985
+ fs33.writeFileSync(defaultWorktreeLayoutPath(), JSON.stringify(layout, null, 2), "utf8");
42864
42986
  } catch {
42865
42987
  }
42866
42988
  }
42867
42989
  function baseNameSafe(pathString) {
42868
- return path41.basename(pathString).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
42990
+ return path43.basename(pathString).replace(/[^a-zA-Z0-9._-]+/g, "-") || "cwd";
42869
42991
  }
42870
42992
  function getLauncherDirNameIfPresent(layout, bridgeRootPath2) {
42871
- const norm = path41.resolve(bridgeRootPath2);
42872
- const existing = layout.launcherCwds.find((e) => path41.resolve(e.absolutePath) === norm);
42993
+ const norm = path43.resolve(bridgeRootPath2);
42994
+ const existing = layout.launcherCwds.find((e) => path43.resolve(e.absolutePath) === norm);
42873
42995
  return existing?.dirName;
42874
42996
  }
42875
42997
  function allocateDirNameForLauncherCwd(layout, bridgeRootPath2) {
42876
42998
  const existing = getLauncherDirNameIfPresent(layout, bridgeRootPath2);
42877
42999
  if (existing) return existing;
42878
- const norm = path41.resolve(bridgeRootPath2);
43000
+ const norm = path43.resolve(bridgeRootPath2);
42879
43001
  const base = baseNameSafe(norm);
42880
43002
  const used = new Set(layout.launcherCwds.map((e) => e.dirName));
42881
43003
  let name = base;
@@ -42968,8 +43090,8 @@ function pathspec(...paths) {
42968
43090
  cache.set(key, paths);
42969
43091
  return key;
42970
43092
  }
42971
- function isPathSpec(path86) {
42972
- return path86 instanceof String && cache.has(path86);
43093
+ function isPathSpec(path88) {
43094
+ return path88 instanceof String && cache.has(path88);
42973
43095
  }
42974
43096
  function toPaths(pathSpec) {
42975
43097
  return cache.get(pathSpec) || [];
@@ -43058,8 +43180,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
43058
43180
  function forEachLineWithContent(input, callback) {
43059
43181
  return toLinesWithContent(input, true).map((line) => callback(line));
43060
43182
  }
43061
- function folderExists(path86) {
43062
- return (0, import_file_exists.exists)(path86, import_file_exists.FOLDER);
43183
+ function folderExists(path88) {
43184
+ return (0, import_file_exists.exists)(path88, import_file_exists.FOLDER);
43063
43185
  }
43064
43186
  function append(target, item) {
43065
43187
  if (Array.isArray(target)) {
@@ -43463,8 +43585,8 @@ function checkIsRepoRootTask() {
43463
43585
  commands,
43464
43586
  format: "utf-8",
43465
43587
  onError,
43466
- parser(path86) {
43467
- return /^\.(git)?$/.test(path86.trim());
43588
+ parser(path88) {
43589
+ return /^\.(git)?$/.test(path88.trim());
43468
43590
  }
43469
43591
  };
43470
43592
  }
@@ -43898,11 +44020,11 @@ function parseGrep(grep) {
43898
44020
  const paths = /* @__PURE__ */ new Set();
43899
44021
  const results = {};
43900
44022
  forEachLineWithContent(grep, (input) => {
43901
- const [path86, line, preview] = input.split(NULL);
43902
- paths.add(path86);
43903
- (results[path86] = results[path86] || []).push({
44023
+ const [path88, line, preview] = input.split(NULL);
44024
+ paths.add(path88);
44025
+ (results[path88] = results[path88] || []).push({
43904
44026
  line: asNumber(line),
43905
- path: path86,
44027
+ path: path88,
43906
44028
  preview
43907
44029
  });
43908
44030
  });
@@ -44667,14 +44789,14 @@ var init_hash_object = __esm2({
44667
44789
  init_task();
44668
44790
  }
44669
44791
  });
44670
- function parseInit(bare, path86, text) {
44792
+ function parseInit(bare, path88, text) {
44671
44793
  const response = String(text).trim();
44672
44794
  let result;
44673
44795
  if (result = initResponseRegex.exec(response)) {
44674
- return new InitSummary(bare, path86, false, result[1]);
44796
+ return new InitSummary(bare, path88, false, result[1]);
44675
44797
  }
44676
44798
  if (result = reInitResponseRegex.exec(response)) {
44677
- return new InitSummary(bare, path86, true, result[1]);
44799
+ return new InitSummary(bare, path88, true, result[1]);
44678
44800
  }
44679
44801
  let gitDir = "";
44680
44802
  const tokens = response.split(" ");
@@ -44685,7 +44807,7 @@ function parseInit(bare, path86, text) {
44685
44807
  break;
44686
44808
  }
44687
44809
  }
44688
- return new InitSummary(bare, path86, /^re/i.test(response), gitDir);
44810
+ return new InitSummary(bare, path88, /^re/i.test(response), gitDir);
44689
44811
  }
44690
44812
  var InitSummary;
44691
44813
  var initResponseRegex;
@@ -44694,9 +44816,9 @@ var init_InitSummary = __esm2({
44694
44816
  "src/lib/responses/InitSummary.ts"() {
44695
44817
  "use strict";
44696
44818
  InitSummary = class {
44697
- constructor(bare, path86, existing, gitDir) {
44819
+ constructor(bare, path88, existing, gitDir) {
44698
44820
  this.bare = bare;
44699
- this.path = path86;
44821
+ this.path = path88;
44700
44822
  this.existing = existing;
44701
44823
  this.gitDir = gitDir;
44702
44824
  }
@@ -44708,7 +44830,7 @@ var init_InitSummary = __esm2({
44708
44830
  function hasBareCommand(command) {
44709
44831
  return command.includes(bareCommand);
44710
44832
  }
44711
- function initTask(bare = false, path86, customArgs) {
44833
+ function initTask(bare = false, path88, customArgs) {
44712
44834
  const commands = ["init", ...customArgs];
44713
44835
  if (bare && !hasBareCommand(commands)) {
44714
44836
  commands.splice(1, 0, bareCommand);
@@ -44717,7 +44839,7 @@ function initTask(bare = false, path86, customArgs) {
44717
44839
  commands,
44718
44840
  format: "utf-8",
44719
44841
  parser(text) {
44720
- return parseInit(commands.includes("--bare"), path86, text);
44842
+ return parseInit(commands.includes("--bare"), path88, text);
44721
44843
  }
44722
44844
  };
44723
44845
  }
@@ -45533,12 +45655,12 @@ var init_FileStatusSummary = __esm2({
45533
45655
  "use strict";
45534
45656
  fromPathRegex = /^(.+)\0(.+)$/;
45535
45657
  FileStatusSummary = class {
45536
- constructor(path86, index, working_dir) {
45537
- this.path = path86;
45658
+ constructor(path88, index, working_dir) {
45659
+ this.path = path88;
45538
45660
  this.index = index;
45539
45661
  this.working_dir = working_dir;
45540
45662
  if (index === "R" || working_dir === "R") {
45541
- const detail = fromPathRegex.exec(path86) || [null, path86, path86];
45663
+ const detail = fromPathRegex.exec(path88) || [null, path88, path88];
45542
45664
  this.from = detail[2] || "";
45543
45665
  this.path = detail[1] || "";
45544
45666
  }
@@ -45569,14 +45691,14 @@ function splitLine(result, lineStr) {
45569
45691
  default:
45570
45692
  return;
45571
45693
  }
45572
- function data(index, workingDir, path86) {
45694
+ function data(index, workingDir, path88) {
45573
45695
  const raw = `${index}${workingDir}`;
45574
45696
  const handler = parsers6.get(raw);
45575
45697
  if (handler) {
45576
- handler(result, path86);
45698
+ handler(result, path88);
45577
45699
  }
45578
45700
  if (raw !== "##" && raw !== "!!") {
45579
- result.files.push(new FileStatusSummary(path86, index, workingDir));
45701
+ result.files.push(new FileStatusSummary(path88, index, workingDir));
45580
45702
  }
45581
45703
  }
45582
45704
  }
@@ -45885,9 +46007,9 @@ var init_simple_git_api = __esm2({
45885
46007
  next
45886
46008
  );
45887
46009
  }
45888
- hashObject(path86, write) {
46010
+ hashObject(path88, write) {
45889
46011
  return this._runTask(
45890
- hashObjectTask(path86, write === true),
46012
+ hashObjectTask(path88, write === true),
45891
46013
  trailingFunctionArgument(arguments)
45892
46014
  );
45893
46015
  }
@@ -46240,8 +46362,8 @@ var init_branch = __esm2({
46240
46362
  }
46241
46363
  });
46242
46364
  function toPath(input) {
46243
- const path86 = input.trim().replace(/^["']|["']$/g, "");
46244
- return path86 && normalize3(path86);
46365
+ const path88 = input.trim().replace(/^["']|["']$/g, "");
46366
+ return path88 && normalize3(path88);
46245
46367
  }
46246
46368
  var parseCheckIgnore;
46247
46369
  var init_CheckIgnore = __esm2({
@@ -46555,8 +46677,8 @@ __export2(sub_module_exports, {
46555
46677
  subModuleTask: () => subModuleTask,
46556
46678
  updateSubModuleTask: () => updateSubModuleTask
46557
46679
  });
46558
- function addSubModuleTask(repo, path86) {
46559
- return subModuleTask(["add", repo, path86]);
46680
+ function addSubModuleTask(repo, path88) {
46681
+ return subModuleTask(["add", repo, path88]);
46560
46682
  }
46561
46683
  function initSubModuleTask(customArgs) {
46562
46684
  return subModuleTask(["init", ...customArgs]);
@@ -46889,8 +47011,8 @@ var require_git = __commonJS2({
46889
47011
  }
46890
47012
  return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
46891
47013
  };
46892
- Git2.prototype.submoduleAdd = function(repo, path86, then) {
46893
- return this._runTask(addSubModuleTask2(repo, path86), trailingFunctionArgument2(arguments));
47014
+ Git2.prototype.submoduleAdd = function(repo, path88, then) {
47015
+ return this._runTask(addSubModuleTask2(repo, path88), trailingFunctionArgument2(arguments));
46894
47016
  };
46895
47017
  Git2.prototype.submoduleUpdate = function(args, then) {
46896
47018
  return this._runTask(
@@ -47629,8 +47751,8 @@ function parseNumstatEntries(lines) {
47629
47751
  }
47630
47752
  function parseNumstat(lines) {
47631
47753
  const m = /* @__PURE__ */ new Map();
47632
- for (const [path86, entry] of parseNumstatEntries(lines)) {
47633
- m.set(path86, { additions: entry.additions, deletions: entry.deletions });
47754
+ for (const [path88, entry] of parseNumstatEntries(lines)) {
47755
+ m.set(path88, { additions: entry.additions, deletions: entry.deletions });
47634
47756
  }
47635
47757
  return m;
47636
47758
  }
@@ -47759,7 +47881,7 @@ async function resolveDefaultRemoteBranchSha(g, remote) {
47759
47881
  }
47760
47882
 
47761
47883
  // src/git/commits/remote-tracking/resolve-base-sha-for-unpushed-commits.ts
47762
- import * as path42 from "node:path";
47884
+ import * as path44 from "node:path";
47763
47885
  var BASE_SHA_CACHE_TTL_MS = 3e4;
47764
47886
  var baseShaCache = /* @__PURE__ */ new Map();
47765
47887
  async function resolveBaseShaForUnpushedCommitsUncached(g) {
@@ -47770,7 +47892,7 @@ async function resolveBaseShaForUnpushedCommitsUncached(g) {
47770
47892
  }
47771
47893
  async function resolveBaseShaForUnpushedCommits(g, repoDir) {
47772
47894
  if (repoDir) {
47773
- const key = path42.resolve(repoDir);
47895
+ const key = path44.resolve(repoDir);
47774
47896
  const now = Date.now();
47775
47897
  const cached2 = baseShaCache.get(key);
47776
47898
  if (cached2 && cached2.expiresAt > now) return cached2.baseSha;
@@ -47905,17 +48027,17 @@ function formatRemoteDisplayLabel(remoteUrl) {
47905
48027
  }
47906
48028
 
47907
48029
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
47908
- import * as path52 from "node:path";
48030
+ import * as path54 from "node:path";
47909
48031
 
47910
48032
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
47911
- import * as path51 from "node:path";
48033
+ import * as path53 from "node:path";
47912
48034
 
47913
48035
  // src/git/is-git-repo.ts
47914
- import * as fs32 from "node:fs";
47915
- import * as path43 from "node:path";
48036
+ import * as fs34 from "node:fs";
48037
+ import * as path45 from "node:path";
47916
48038
  async function isGitRepoDirectory(dirPath) {
47917
48039
  try {
47918
- await fs32.promises.access(path43.join(dirPath, ".git"));
48040
+ await fs34.promises.access(path45.join(dirPath, ".git"));
47919
48041
  return true;
47920
48042
  } catch {
47921
48043
  return false;
@@ -47923,8 +48045,8 @@ async function isGitRepoDirectory(dirPath) {
47923
48045
  }
47924
48046
 
47925
48047
  // src/git/changes/listing/apply-untracked-file-stats.ts
47926
- import * as fs33 from "node:fs";
47927
- import * as path44 from "node:path";
48048
+ import * as fs35 from "node:fs";
48049
+ import * as path46 from "node:path";
47928
48050
 
47929
48051
  // src/git/changes/lines/count-lines.ts
47930
48052
  import { createReadStream } from "node:fs";
@@ -47956,7 +48078,7 @@ function createUntrackedStatsApplier(options) {
47956
48078
  if (!options.untrackedSet.has(pathInRepo)) return;
47957
48079
  if (options.nameByPath.has(pathInRepo)) return;
47958
48080
  if (row.change === "moved") return;
47959
- const repoFilePath = path44.join(options.repoGitCwd, pathInRepo);
48081
+ const repoFilePath = path46.join(options.repoGitCwd, pathInRepo);
47960
48082
  const fromGit = await numstatFromGitNoIndex(options.g, pathInRepo);
47961
48083
  if (fromGit) {
47962
48084
  row.additions = fromGit.additions;
@@ -47964,7 +48086,7 @@ function createUntrackedStatsApplier(options) {
47964
48086
  return;
47965
48087
  }
47966
48088
  try {
47967
- const st = await fs33.promises.stat(repoFilePath);
48089
+ const st = await fs35.promises.stat(repoFilePath);
47968
48090
  row.additions = st.isFile() ? await countTextFileLines(repoFilePath) : 0;
47969
48091
  } catch {
47970
48092
  row.additions = 0;
@@ -48041,7 +48163,7 @@ async function buildChangedFileRowsFromPaths(options) {
48041
48163
  }
48042
48164
 
48043
48165
  // src/git/changes/listing/enrich-working-tree-file-rows.ts
48044
- import * as path46 from "node:path";
48166
+ import * as path48 from "node:path";
48045
48167
 
48046
48168
  // src/git/changes/patch/patch-truncate.ts
48047
48169
  function truncatePatch(s) {
@@ -48129,10 +48251,10 @@ async function readGitBlobLines(repoCwd, pathInRepo) {
48129
48251
  }
48130
48252
 
48131
48253
  // src/git/changes/patch/hydrate/read-worktree-file-lines.ts
48132
- import * as fs34 from "node:fs";
48254
+ import * as fs36 from "node:fs";
48133
48255
  async function readWorktreeFileLines(filePath) {
48134
48256
  try {
48135
- const raw = await fs34.promises.readFile(filePath, "utf8");
48257
+ const raw = await fs36.promises.readFile(filePath, "utf8");
48136
48258
  return raw.split(/\r?\n/);
48137
48259
  } catch {
48138
48260
  return null;
@@ -48270,8 +48392,8 @@ async function unifiedDiffForFileInRange(repoCwd, range, pathInRepo, change, mov
48270
48392
  }
48271
48393
 
48272
48394
  // src/git/changes/total-lines/resolve-changed-file-total-lines.ts
48273
- import * as fs35 from "node:fs";
48274
- import * as path45 from "node:path";
48395
+ import * as fs37 from "node:fs";
48396
+ import * as path47 from "node:path";
48275
48397
  var MAX_BYTES = 512e3;
48276
48398
  async function countLinesInGitRef(repoGitCwd, ref, pathInRepo) {
48277
48399
  const spec = `${ref}:${pathInRepo}`;
@@ -48291,13 +48413,13 @@ async function countLinesInGitRef(repoGitCwd, ref, pathInRepo) {
48291
48413
  }
48292
48414
  async function resolveWorkingTreeFileTotalLines(options) {
48293
48415
  if (options.isBinary) return null;
48294
- const filePath = path45.join(options.repoGitCwd, options.pathInRepo);
48416
+ const filePath = path47.join(options.repoGitCwd, options.pathInRepo);
48295
48417
  if (options.change === "removed") {
48296
48418
  return countLinesInGitRef(options.repoGitCwd, "HEAD", options.pathInRepo);
48297
48419
  }
48298
48420
  if (options.change === "moved" || options.change === "modified") {
48299
48421
  try {
48300
- const st = await fs35.promises.stat(filePath);
48422
+ const st = await fs37.promises.stat(filePath);
48301
48423
  if (!st.isFile()) return null;
48302
48424
  return await countTextFileLines(filePath);
48303
48425
  } catch {
@@ -48340,7 +48462,7 @@ async function enrichWorkingTreeFileRows(options) {
48340
48462
  row.workspaceRelPath,
48341
48463
  options.repoPathRelativeToWorkspaceRoot
48342
48464
  );
48343
- const filePath = path46.join(options.repoGitCwd, filePathRelativeToRepoRoot);
48465
+ const filePath = path48.join(options.repoGitCwd, filePathRelativeToRepoRoot);
48344
48466
  const hydrateKind = row.change === "moved" ? "modified" : row.change;
48345
48467
  let patch = await unifiedDiffForFile(
48346
48468
  options.repoGitCwd,
@@ -48498,7 +48620,7 @@ async function listChangedFilesForRepo(repoGitCwd, repoPathRelativeToWorkspaceRo
48498
48620
  }
48499
48621
 
48500
48622
  // src/git/changes/listing/list-changed-files-for-commit.ts
48501
- import * as path47 from "node:path";
48623
+ import * as path49 from "node:path";
48502
48624
 
48503
48625
  // src/git/changes/listing/enrich-commit-file-rows.ts
48504
48626
  async function enrichCommitFileRows(options) {
@@ -48543,7 +48665,7 @@ async function parentForCommitDiff(g, sha) {
48543
48665
  var COMMIT_FILES_CACHE_TTL_MS = 5 * 6e4;
48544
48666
  var commitFilesCache = /* @__PURE__ */ new Map();
48545
48667
  function commitFilesCacheKey(repoGitCwd, commitSha) {
48546
- return `${path47.resolve(repoGitCwd)}:${commitSha}`;
48668
+ return `${path49.resolve(repoGitCwd)}:${commitSha}`;
48547
48669
  }
48548
48670
  async function listChangedFilesForCommit(repoGitCwd, repoPathRelativeToWorkspaceRoot, commitSha, options = {}) {
48549
48671
  const cacheKey = commitFilesCacheKey(repoGitCwd, commitSha);
@@ -48598,7 +48720,7 @@ async function listChangedFilesForCommit(repoGitCwd, repoPathRelativeToWorkspace
48598
48720
  }
48599
48721
 
48600
48722
  // src/git/commits/list-unpushed-commits.ts
48601
- import * as path48 from "node:path";
48723
+ import * as path50 from "node:path";
48602
48724
 
48603
48725
  // src/git/commits/lib/parse-log-lines.ts
48604
48726
  function parseLogShaDateSubjectLines(raw) {
@@ -48633,7 +48755,7 @@ async function gitLogNotReachableFromBase(g, baseSha, headSha) {
48633
48755
  }
48634
48756
  }
48635
48757
  async function listUnpushedCommits(repoDir) {
48636
- const key = path48.resolve(repoDir);
48758
+ const key = path50.resolve(repoDir);
48637
48759
  const now = Date.now();
48638
48760
  const cached2 = unpushedCache.get(key);
48639
48761
  if (cached2 && cached2.expiresAt > now) return cached2.commits;
@@ -48694,7 +48816,7 @@ async function loadRecentAndUnpushedCommitsForRepoDetail(repoDir, recentCommitsL
48694
48816
  }
48695
48817
 
48696
48818
  // src/git/changes/repo/load-working-tree-change-repo-git-info.ts
48697
- import * as path49 from "node:path";
48819
+ import * as path51 from "node:path";
48698
48820
 
48699
48821
  // src/git/remote-origin-url.ts
48700
48822
  async function getRemoteOriginUrl(gitDir) {
@@ -48709,7 +48831,7 @@ async function getRemoteOriginUrl(gitDir) {
48709
48831
 
48710
48832
  // src/git/changes/repo/load-working-tree-change-repo-git-info.ts
48711
48833
  async function loadWorkingTreeChangeRepoGitInfo(checkoutPath) {
48712
- const resolvedCheckoutPath = path49.resolve(checkoutPath);
48834
+ const resolvedCheckoutPath = path51.resolve(checkoutPath);
48713
48835
  const git = cliSimpleGit(resolvedCheckoutPath);
48714
48836
  await yieldToEventLoop2();
48715
48837
  const [branch, remoteUrl] = await Promise.all([
@@ -48724,14 +48846,14 @@ async function loadWorkingTreeChangeRepoGitInfo(checkoutPath) {
48724
48846
  }
48725
48847
 
48726
48848
  // src/git/changes/repo/resolve-repo-path-relative-to-workspace-root.ts
48727
- import * as path50 from "node:path";
48849
+ import * as path52 from "node:path";
48728
48850
  async function resolveRepoPathRelativeToWorkspaceRoot(options) {
48729
- const checkoutPath = path50.resolve(options.checkoutPath);
48851
+ const checkoutPath = path52.resolve(options.checkoutPath);
48730
48852
  const git = cliSimpleGit(checkoutPath);
48731
- const sessionParentPath = options.sessionParentPath ? path50.resolve(options.sessionParentPath) : null;
48853
+ const sessionParentPath = options.sessionParentPath ? path52.resolve(options.sessionParentPath) : null;
48732
48854
  let repoPathRelativeToWorkspaceRoot;
48733
48855
  if (sessionParentPath) {
48734
- const checkoutPathRelativeToSessionParent = path50.relative(sessionParentPath, checkoutPath);
48856
+ const checkoutPathRelativeToSessionParent = path52.relative(sessionParentPath, checkoutPath);
48735
48857
  repoPathRelativeToWorkspaceRoot = checkoutPathRelativeToSessionParent === "" ? "." : checkoutPathRelativeToSessionParent.replace(/\\/g, "/");
48736
48858
  } else {
48737
48859
  let gitTopLevel = checkoutPath;
@@ -48741,8 +48863,8 @@ async function resolveRepoPathRelativeToWorkspaceRoot(options) {
48741
48863
  } catch {
48742
48864
  gitTopLevel = checkoutPath;
48743
48865
  }
48744
- const gitTopLevelRelativeToBridgeRoot = path50.relative(options.bridgeRoot, path50.resolve(gitTopLevel)).replace(/\\/g, "/") || ".";
48745
- repoPathRelativeToWorkspaceRoot = gitTopLevelRelativeToBridgeRoot.startsWith("..") ? path50.basename(path50.resolve(gitTopLevel)) : gitTopLevelRelativeToBridgeRoot;
48866
+ const gitTopLevelRelativeToBridgeRoot = path52.relative(options.bridgeRoot, path52.resolve(gitTopLevel)).replace(/\\/g, "/") || ".";
48867
+ repoPathRelativeToWorkspaceRoot = gitTopLevelRelativeToBridgeRoot.startsWith("..") ? path52.basename(path52.resolve(gitTopLevel)) : gitTopLevelRelativeToBridgeRoot;
48746
48868
  }
48747
48869
  return normalizeRepoPathRelativeToWorkspaceRoot(
48748
48870
  repoPathRelativeToWorkspaceRoot === "" ? "." : repoPathRelativeToWorkspaceRoot
@@ -48751,10 +48873,10 @@ async function resolveRepoPathRelativeToWorkspaceRoot(options) {
48751
48873
 
48752
48874
  // src/git/changes/repo/build-working-tree-change-repo-detail.ts
48753
48875
  async function buildWorkingTreeChangeRepoDetail(options) {
48754
- const checkoutPath = path51.resolve(options.targetPath);
48876
+ const checkoutPath = path53.resolve(options.targetPath);
48755
48877
  if (!await isGitRepoDirectory(checkoutPath)) return null;
48756
48878
  const isCommitView = options.basis.kind === "commit";
48757
- const sessionParentPath = options.sessionParentPath ? path51.resolve(options.sessionParentPath) : null;
48879
+ const sessionParentPath = options.sessionParentPath ? path53.resolve(options.sessionParentPath) : null;
48758
48880
  const git = cliSimpleGit(checkoutPath);
48759
48881
  const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
48760
48882
  checkoutPath,
@@ -48802,8 +48924,8 @@ async function buildWorkingTreeChangeRepoDetail(options) {
48802
48924
 
48803
48925
  // src/git/changes/repo/get-working-tree-change-repo-details.ts
48804
48926
  async function getWorkingTreeChangeRepoDetails(options) {
48805
- const bridgeRoot = path52.resolve(getBridgeRoot());
48806
- const sessionParentPath = options.sessionParentPath ? path52.resolve(options.sessionParentPath) : null;
48927
+ const bridgeRoot = path54.resolve(getBridgeRoot());
48928
+ const sessionParentPath = options.sessionParentPath ? path54.resolve(options.sessionParentPath) : null;
48807
48929
  const out = [];
48808
48930
  const filter = options.repoFilterRelPath != null ? normalizeRepoPathRelativeToWorkspaceRoot(options.repoFilterRelPath) : null;
48809
48931
  const basisInput = options.basis ?? { kind: "working" };
@@ -48834,9 +48956,9 @@ async function getWorkingTreeChangeRepoDetails(options) {
48834
48956
  }
48835
48957
 
48836
48958
  // src/git/changes/repo/get-working-tree-change-file-patch.ts
48837
- import * as path53 from "node:path";
48959
+ import * as path55 from "node:path";
48838
48960
  async function getWorkingTreeChangeFilePatch(options) {
48839
- const repoGitCwd = path53.resolve(options.repoGitCwd);
48961
+ const repoGitCwd = path55.resolve(options.repoGitCwd);
48840
48962
  if (!await isGitRepoDirectory(repoGitCwd)) {
48841
48963
  throw new Error("Not a git repository");
48842
48964
  }
@@ -48875,7 +48997,7 @@ async function getWorkingTreeChangeFilePatch(options) {
48875
48997
  });
48876
48998
  return { patchContent: patchContent2, totalLines: totalLines2 };
48877
48999
  }
48878
- const filePath = path53.join(repoGitCwd, filePathRelativeToRepoRoot);
49000
+ const filePath = path55.join(repoGitCwd, filePathRelativeToRepoRoot);
48879
49001
  const hydrateKind = options.change === "moved" ? "modified" : options.change;
48880
49002
  let patchContent = await unifiedDiffForFile(
48881
49003
  repoGitCwd,
@@ -48921,18 +49043,18 @@ function parseWorkingTreeChangeKind(value) {
48921
49043
  }
48922
49044
 
48923
49045
  // src/worktrees/manager/git/get-session-working-tree-change-file-patch.ts
48924
- import * as path54 from "node:path";
49046
+ import * as path56 from "node:path";
48925
49047
  async function getSessionWorkingTreeChangeFilePatch(cache2, sessionId, discover, opts) {
48926
49048
  const targets = await resolveCommitTargetsAsync(sessionId, cache2, discover);
48927
- const bridgeRoot = path54.resolve(getBridgeRoot());
48928
- const sessionParentPath = cache2.getSessionParentPath(sessionId) ? path54.resolve(cache2.getSessionParentPath(sessionId)) : null;
49049
+ const bridgeRoot = path56.resolve(getBridgeRoot());
49050
+ const sessionParentPath = cache2.getSessionParentPath(sessionId) ? path56.resolve(cache2.getSessionParentPath(sessionId)) : null;
48929
49051
  const repoPathRelativeToWorkspaceRootFilter = normalizeRepoPathRelativeToWorkspaceRoot(
48930
49052
  opts.repoRelPath.trim()
48931
49053
  );
48932
49054
  let result = null;
48933
49055
  await forEachWithGitYield(targets, async (targetPath) => {
48934
49056
  if (result) return;
48935
- const checkoutPath = path54.resolve(targetPath);
49057
+ const checkoutPath = path56.resolve(targetPath);
48936
49058
  if (!await isGitRepoDirectory(checkoutPath)) return;
48937
49059
  const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
48938
49060
  checkoutPath,
@@ -48965,13 +49087,13 @@ async function pushSessionUpstream(cache2, sessionId, discover) {
48965
49087
  }
48966
49088
 
48967
49089
  // src/worktrees/remove-session-worktrees.ts
48968
- import * as fs38 from "node:fs";
49090
+ import * as fs40 from "node:fs";
48969
49091
 
48970
49092
  // src/git/worktrees/worktree-remove.ts
48971
- import * as fs37 from "node:fs";
49093
+ import * as fs39 from "node:fs";
48972
49094
 
48973
49095
  // src/worktrees/is-removable-session-worktree-checkout-path.ts
48974
- import path55 from "node:path";
49096
+ import path57 from "node:path";
48975
49097
  init_normalize_resolved_path();
48976
49098
  function isBridgeRootCheckoutPath(checkoutPath) {
48977
49099
  return normalizeResolvedPath(checkoutPath) === normalizeResolvedPath(getBridgeRoot());
@@ -48980,23 +49102,23 @@ function isRemovableSessionWorktreeCheckoutPath(checkoutPath, worktreesRootPath)
48980
49102
  if (isBridgeRootCheckoutPath(checkoutPath)) return false;
48981
49103
  const normalized = normalizeResolvedPath(checkoutPath);
48982
49104
  const worktreesRoot = normalizeResolvedPath(worktreesRootPath);
48983
- const rel = path55.relative(worktreesRoot, normalized);
48984
- if (rel === "" || rel.startsWith("..") || path55.isAbsolute(rel)) return false;
49105
+ const rel = path57.relative(worktreesRoot, normalized);
49106
+ if (rel === "" || rel.startsWith("..") || path57.isAbsolute(rel)) return false;
48985
49107
  return true;
48986
49108
  }
48987
49109
 
48988
49110
  // src/git/worktrees/resolve-main-repo-from-git-file.ts
48989
- import * as fs36 from "node:fs";
48990
- import * as path56 from "node:path";
49111
+ import * as fs38 from "node:fs";
49112
+ import * as path58 from "node:path";
48991
49113
  function resolveMainRepoFromWorktreeGitFile(wt) {
48992
- const gitDirFile = path56.join(wt, ".git");
48993
- if (!fs36.existsSync(gitDirFile) || !fs36.statSync(gitDirFile).isFile()) return "";
48994
- const first2 = fs36.readFileSync(gitDirFile, "utf8").trim();
49114
+ const gitDirFile = path58.join(wt, ".git");
49115
+ if (!fs38.existsSync(gitDirFile) || !fs38.statSync(gitDirFile).isFile()) return "";
49116
+ const first2 = fs38.readFileSync(gitDirFile, "utf8").trim();
48995
49117
  const m = first2.match(/^gitdir:\s*(.+)$/im);
48996
49118
  if (!m) return "";
48997
- const gitWorktreePath = path56.resolve(wt, m[1].trim());
48998
- const gitDir = path56.dirname(path56.dirname(gitWorktreePath));
48999
- return path56.dirname(gitDir);
49119
+ const gitWorktreePath = path58.resolve(wt, m[1].trim());
49120
+ const gitDir = path58.dirname(path58.dirname(gitWorktreePath));
49121
+ return path58.dirname(gitDir);
49000
49122
  }
49001
49123
 
49002
49124
  // src/git/worktrees/worktree-remove.ts
@@ -49007,7 +49129,7 @@ async function gitWorktreeRemoveForce(worktreePath) {
49007
49129
  return true;
49008
49130
  }
49009
49131
  if (isBridgeRootCheckoutPath(worktreePath)) return false;
49010
- fs37.rmSync(worktreePath, { recursive: true, force: true });
49132
+ fs39.rmSync(worktreePath, { recursive: true, force: true });
49011
49133
  return true;
49012
49134
  }
49013
49135
 
@@ -49029,7 +49151,7 @@ async function removeSessionWorktrees(paths, worktreesRootPath, log2) {
49029
49151
  log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
49030
49152
  if (isRemovableSessionWorktreeCheckoutPath(wt, worktreesRootPath)) {
49031
49153
  try {
49032
- fs38.rmSync(wt, { recursive: true, force: true });
49154
+ fs40.rmSync(wt, { recursive: true, force: true });
49033
49155
  } catch {
49034
49156
  }
49035
49157
  }
@@ -49085,12 +49207,12 @@ async function renameSessionWorktreeBranch(cache2, sessionId, newBranch, log2) {
49085
49207
  // src/worktrees/discovery/discover-session-worktree-on-disk.ts
49086
49208
  init_cli_process_interrupt();
49087
49209
  init_yield_to_event_loop();
49088
- import * as fs42 from "node:fs";
49089
- import * as path61 from "node:path";
49210
+ import * as fs44 from "node:fs";
49211
+ import * as path63 from "node:path";
49090
49212
 
49091
49213
  // src/worktrees/discovery/collect-worktree-paths.ts
49092
- import * as fs40 from "node:fs";
49093
- import * as path58 from "node:path";
49214
+ import * as fs42 from "node:fs";
49215
+ import * as path60 from "node:path";
49094
49216
 
49095
49217
  // src/worktrees/discovery/disk-walk-constants.ts
49096
49218
  var DISK_WALK_YIELD_EVERY = 64;
@@ -49120,8 +49242,8 @@ function shouldSkipDiskWalkEntry(name) {
49120
49242
  // src/worktrees/discovery/disk-walk-utils.ts
49121
49243
  init_cli_process_interrupt();
49122
49244
  init_yield_to_event_loop();
49123
- import * as fs39 from "node:fs";
49124
- import * as path57 from "node:path";
49245
+ import * as fs41 from "node:fs";
49246
+ import * as path59 from "node:path";
49125
49247
  async function yieldDuringDiskWalk(state) {
49126
49248
  state.entries++;
49127
49249
  if (state.entries % DISK_WALK_YIELD_EVERY !== 0) return true;
@@ -49131,7 +49253,7 @@ async function yieldDuringDiskWalk(state) {
49131
49253
  }
49132
49254
  async function isGitDir(dirPath) {
49133
49255
  try {
49134
- await fs39.promises.access(path57.join(dirPath, ".git"));
49256
+ await fs41.promises.access(path59.join(dirPath, ".git"));
49135
49257
  return true;
49136
49258
  } catch {
49137
49259
  return false;
@@ -49145,23 +49267,23 @@ async function collectGitRepoRootsUnderDirectory(rootPath) {
49145
49267
  const walk = async (dir) => {
49146
49268
  if (!await yieldDuringDiskWalk(state)) return;
49147
49269
  if (await isGitDir(dir)) {
49148
- out.push(path58.resolve(dir));
49270
+ out.push(path60.resolve(dir));
49149
49271
  return;
49150
49272
  }
49151
49273
  let entries;
49152
49274
  try {
49153
- entries = await fs40.promises.readdir(dir, { withFileTypes: true });
49275
+ entries = await fs42.promises.readdir(dir, { withFileTypes: true });
49154
49276
  } catch {
49155
49277
  return;
49156
49278
  }
49157
49279
  for (const e of entries) {
49158
49280
  if (shouldSkipDiskWalkEntry(e.name)) continue;
49159
- const full = path58.join(dir, e.name);
49281
+ const full = path60.join(dir, e.name);
49160
49282
  if (!e.isDirectory()) continue;
49161
49283
  await walk(full);
49162
49284
  }
49163
49285
  };
49164
- await walk(path58.resolve(rootPath));
49286
+ await walk(path60.resolve(rootPath));
49165
49287
  return { paths: [...new Set(out)], entriesVisited: state.entries };
49166
49288
  }
49167
49289
  async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK_MAX_DEPTH) {
@@ -49172,16 +49294,16 @@ async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK
49172
49294
  if (!await yieldDuringDiskWalk(state)) return;
49173
49295
  let entries;
49174
49296
  try {
49175
- entries = await fs40.promises.readdir(dir, { withFileTypes: true });
49297
+ entries = await fs42.promises.readdir(dir, { withFileTypes: true });
49176
49298
  } catch {
49177
49299
  return;
49178
49300
  }
49179
49301
  for (const e of entries) {
49180
49302
  if (shouldSkipDiskWalkEntry(e.name)) continue;
49181
- const full = path58.join(dir, e.name);
49303
+ const full = path60.join(dir, e.name);
49182
49304
  if (!e.isDirectory()) continue;
49183
49305
  if (e.name === sessionId) {
49184
- if (await isGitDir(full)) out.push(path58.resolve(full));
49306
+ if (await isGitDir(full)) out.push(path60.resolve(full));
49185
49307
  continue;
49186
49308
  }
49187
49309
  if (await isGitDir(full)) continue;
@@ -49193,14 +49315,14 @@ async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK
49193
49315
  }
49194
49316
 
49195
49317
  // src/worktrees/discovery/layout-keys-for-bridge-root.ts
49196
- import * as path59 from "node:path";
49318
+ import * as path61 from "node:path";
49197
49319
  function layoutKeysForBridgeRoot(layout, bridgeRoot, keysOnDisk) {
49198
- const bridge = path59.resolve(bridgeRoot);
49320
+ const bridge = path61.resolve(bridgeRoot);
49199
49321
  const preferred = getLauncherDirNameIfPresent(layout, bridgeRoot);
49200
49322
  const relevant = layout.launcherCwds.filter((e) => {
49201
- const entry = path59.resolve(e.absolutePath);
49202
- return bridge === entry || bridge.startsWith(entry + path59.sep) || entry.startsWith(bridge + path59.sep);
49203
- }).sort((a, b) => path59.resolve(b.absolutePath).length - path59.resolve(a.absolutePath).length).map((e) => e.dirName).filter((name) => keysOnDisk.includes(name));
49323
+ const entry = path61.resolve(e.absolutePath);
49324
+ return bridge === entry || bridge.startsWith(entry + path61.sep) || entry.startsWith(bridge + path61.sep);
49325
+ }).sort((a, b) => path61.resolve(b.absolutePath).length - path61.resolve(a.absolutePath).length).map((e) => e.dirName).filter((name) => keysOnDisk.includes(name));
49204
49326
  const ordered = [];
49205
49327
  const seen = /* @__PURE__ */ new Set();
49206
49328
  const add = (k) => {
@@ -49218,19 +49340,19 @@ function layoutKeysForBridgeRoot(layout, bridgeRoot, keysOnDisk) {
49218
49340
  }
49219
49341
 
49220
49342
  // src/worktrees/discovery/try-binding-from-isolated-directory.ts
49221
- import * as fs41 from "node:fs";
49222
- import * as path60 from "node:path";
49343
+ import * as fs43 from "node:fs";
49344
+ import * as path62 from "node:path";
49223
49345
  async function tryBindingFromIsolatedDirectory(scopeDir) {
49224
49346
  let st;
49225
49347
  try {
49226
- st = await fs41.promises.stat(scopeDir);
49348
+ st = await fs43.promises.stat(scopeDir);
49227
49349
  } catch {
49228
49350
  return null;
49229
49351
  }
49230
49352
  if (!st.isDirectory()) return null;
49231
49353
  const { paths: worktreePaths } = await collectGitRepoRootsUnderDirectory(scopeDir);
49232
49354
  if (worktreePaths.length === 0) return null;
49233
- const abs = path60.resolve(scopeDir);
49355
+ const abs = path62.resolve(scopeDir);
49234
49356
  return {
49235
49357
  parentPath: abs,
49236
49358
  repoCheckoutPaths: worktreePaths
@@ -49253,7 +49375,7 @@ async function discoverSessionWorktreeOnDisk(options) {
49253
49375
  const sid = sessionId.trim();
49254
49376
  if (!sid) return null;
49255
49377
  try {
49256
- await fs42.promises.access(worktreesRootPath);
49378
+ await fs44.promises.access(worktreesRootPath);
49257
49379
  } catch {
49258
49380
  return null;
49259
49381
  }
@@ -49262,13 +49384,13 @@ async function discoverSessionWorktreeOnDisk(options) {
49262
49384
  if (preferredKey) keysOnDisk.push(preferredKey);
49263
49385
  const scanState = { entries: 0 };
49264
49386
  try {
49265
- for (const name of await fs42.promises.readdir(worktreesRootPath)) {
49387
+ for (const name of await fs44.promises.readdir(worktreesRootPath)) {
49266
49388
  if (!await yieldDuringDiskWalk(scanState)) break;
49267
49389
  if (name.startsWith(".")) continue;
49268
- const p = path61.join(worktreesRootPath, name);
49390
+ const p = path63.join(worktreesRootPath, name);
49269
49391
  let st;
49270
49392
  try {
49271
- st = await fs42.promises.stat(p);
49393
+ st = await fs44.promises.stat(p);
49272
49394
  } catch {
49273
49395
  continue;
49274
49396
  }
@@ -49282,23 +49404,23 @@ async function discoverSessionWorktreeOnDisk(options) {
49282
49404
  for (const key of keys) {
49283
49405
  if (isCliImmediateShutdownRequested()) return null;
49284
49406
  await yieldToEventLoop();
49285
- const layoutRoot = path61.join(worktreesRootPath, key);
49407
+ const layoutRoot = path63.join(worktreesRootPath, key);
49286
49408
  let layoutSt;
49287
49409
  try {
49288
- layoutSt = await fs42.promises.stat(layoutRoot);
49410
+ layoutSt = await fs44.promises.stat(layoutRoot);
49289
49411
  } catch {
49290
49412
  continue;
49291
49413
  }
49292
49414
  if (!layoutSt.isDirectory()) continue;
49293
- const sessionDir = path61.join(layoutRoot, sid);
49415
+ const sessionDir = path63.join(layoutRoot, sid);
49294
49416
  const nested = await tryBindingFromSessionDirectory(sessionDir);
49295
49417
  if (nested) return nested;
49296
49418
  const legacy = await collectWorktreeRootsNamed(layoutRoot, sid);
49297
49419
  if (legacy.paths.length > 0) {
49298
- const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacy.paths) ?? path61.resolve(legacy.paths[0]);
49420
+ const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacy.paths) ?? path63.resolve(legacy.paths[0]);
49299
49421
  return {
49300
- sessionParentPath: path61.resolve(isolated),
49301
- repoCheckoutPaths: legacy.paths.map((p) => path61.resolve(p))
49422
+ sessionParentPath: path63.resolve(isolated),
49423
+ repoCheckoutPaths: legacy.paths.map((p) => path63.resolve(p))
49302
49424
  };
49303
49425
  }
49304
49426
  }
@@ -49306,31 +49428,31 @@ async function discoverSessionWorktreeOnDisk(options) {
49306
49428
  }
49307
49429
 
49308
49430
  // src/worktrees/discovery/discover-session-worktrees-under-session-worktree-root.ts
49309
- import * as fs43 from "node:fs";
49310
- import * as path63 from "node:path";
49431
+ import * as fs45 from "node:fs";
49432
+ import * as path65 from "node:path";
49311
49433
 
49312
49434
  // src/worktrees/discovery/discover-legacy-binding-ascending-from-checkout.ts
49313
49435
  init_cli_process_interrupt();
49314
49436
  init_yield_to_event_loop();
49315
- import * as path62 from "node:path";
49437
+ import * as path64 from "node:path";
49316
49438
  async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
49317
49439
  const sid = sessionId.trim();
49318
49440
  if (!sid) return null;
49319
- const hintR = path62.resolve(checkoutPath);
49441
+ const hintR = path64.resolve(checkoutPath);
49320
49442
  let best = null;
49321
- let cur = path62.dirname(hintR);
49443
+ let cur = path64.dirname(hintR);
49322
49444
  for (let i = 0; i < 40; i++) {
49323
49445
  if (isCliImmediateShutdownRequested()) return best;
49324
49446
  await yieldToEventLoop();
49325
49447
  const paths = await collectWorktreeRootsNamed(cur, sid);
49326
- if (paths.paths.some((p) => path62.resolve(p) === hintR)) {
49327
- const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths.paths) ?? path62.resolve(paths.paths[0]);
49448
+ if (paths.paths.some((p) => path64.resolve(p) === hintR)) {
49449
+ const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths.paths) ?? path64.resolve(paths.paths[0]);
49328
49450
  best = {
49329
- sessionParentPath: path62.resolve(isolated),
49330
- repoCheckoutPaths: paths.paths.map((p) => path62.resolve(p))
49451
+ sessionParentPath: path64.resolve(isolated),
49452
+ repoCheckoutPaths: paths.paths.map((p) => path64.resolve(p))
49331
49453
  };
49332
49454
  }
49333
- const next = path62.dirname(cur);
49455
+ const next = path64.dirname(cur);
49334
49456
  if (next === cur) break;
49335
49457
  cur = next;
49336
49458
  }
@@ -49341,12 +49463,12 @@ async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPat
49341
49463
  async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionParentPathOrHint, sessionId) {
49342
49464
  const sid = sessionId.trim();
49343
49465
  if (!sid) return null;
49344
- const hint = path63.resolve(sessionParentPathOrHint);
49345
- const underHint = await tryBindingFromSessionDirectory(path63.join(hint, sid));
49466
+ const hint = path65.resolve(sessionParentPathOrHint);
49467
+ const underHint = await tryBindingFromSessionDirectory(path65.join(hint, sid));
49346
49468
  if (underHint) return underHint;
49347
49469
  const direct = await tryBindingFromSessionDirectory(hint);
49348
49470
  if (direct) {
49349
- if (path63.basename(hint) === sid && await isGitDir(hint)) {
49471
+ if (path65.basename(hint) === sid && await isGitDir(hint)) {
49350
49472
  const legacyFromCheckout = await discoverLegacyBindingAscendingFromCheckout(sid, hint);
49351
49473
  if (legacyFromCheckout && legacyFromCheckout.repoCheckoutPaths.length > direct.repoCheckoutPaths.length) {
49352
49474
  return legacyFromCheckout;
@@ -49354,23 +49476,23 @@ async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionParentPat
49354
49476
  }
49355
49477
  return direct;
49356
49478
  }
49357
- if (path63.basename(hint) === sid && await isGitDir(hint)) {
49479
+ if (path65.basename(hint) === sid && await isGitDir(hint)) {
49358
49480
  const legacyFromCheckout = await discoverLegacyBindingAscendingFromCheckout(sid, hint);
49359
49481
  if (legacyFromCheckout) return legacyFromCheckout;
49360
49482
  }
49361
49483
  let st;
49362
49484
  try {
49363
- st = await fs43.promises.stat(hint);
49485
+ st = await fs45.promises.stat(hint);
49364
49486
  } catch {
49365
49487
  return null;
49366
49488
  }
49367
49489
  if (!st.isDirectory()) return null;
49368
49490
  const legacyPaths = await collectWorktreeRootsNamed(hint, sid);
49369
49491
  if (legacyPaths.paths.length === 0) return null;
49370
- const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths.paths) ?? path63.resolve(legacyPaths.paths[0]);
49492
+ const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths.paths) ?? path65.resolve(legacyPaths.paths[0]);
49371
49493
  return {
49372
- sessionParentPath: path63.resolve(isolated),
49373
- repoCheckoutPaths: legacyPaths.paths.map((p) => path63.resolve(p))
49494
+ sessionParentPath: path65.resolve(isolated),
49495
+ repoCheckoutPaths: legacyPaths.paths.map((p) => path65.resolve(p))
49374
49496
  };
49375
49497
  }
49376
49498
 
@@ -49431,11 +49553,11 @@ function parseSessionParent(v) {
49431
49553
  }
49432
49554
 
49433
49555
  // src/worktrees/prepare/prepare-new-isolated-worktrees.ts
49434
- import * as fs47 from "node:fs";
49556
+ import * as fs49 from "node:fs";
49435
49557
 
49436
49558
  // src/git/discover-repos.ts
49437
- import * as fs44 from "node:fs";
49438
- import * as path64 from "node:path";
49559
+ import * as fs46 from "node:fs";
49560
+ import * as path66 from "node:path";
49439
49561
  init_yield_to_event_loop();
49440
49562
  var GIT_DISCOVER_YIELD_EVERY = 32;
49441
49563
  async function yieldGitDiscoverWork(entryCount) {
@@ -49445,14 +49567,14 @@ async function yieldGitDiscoverWork(entryCount) {
49445
49567
  }
49446
49568
  async function discoverGitRepos(cwd = getBridgeRoot()) {
49447
49569
  const result = [];
49448
- const cwdResolved = path64.resolve(cwd);
49570
+ const cwdResolved = path66.resolve(cwd);
49449
49571
  if (await isGitRepoDirectory(cwdResolved)) {
49450
49572
  const remoteUrl = await getRemoteOriginUrl(cwdResolved);
49451
49573
  result.push({ absolutePath: cwdResolved, remoteUrl });
49452
49574
  }
49453
49575
  let entries;
49454
49576
  try {
49455
- entries = fs44.readdirSync(cwdResolved, { withFileTypes: true });
49577
+ entries = fs46.readdirSync(cwdResolved, { withFileTypes: true });
49456
49578
  } catch {
49457
49579
  return result;
49458
49580
  }
@@ -49460,7 +49582,7 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
49460
49582
  await yieldGitDiscoverWork(i + 1);
49461
49583
  const ent = entries[i];
49462
49584
  if (!ent.isDirectory()) continue;
49463
- const childPath2 = path64.join(cwdResolved, ent.name);
49585
+ const childPath2 = path66.join(cwdResolved, ent.name);
49464
49586
  if (await isGitRepoDirectory(childPath2)) {
49465
49587
  const remoteUrl = await getRemoteOriginUrl(childPath2);
49466
49588
  result.push({ absolutePath: childPath2, remoteUrl });
@@ -49469,17 +49591,17 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
49469
49591
  return result;
49470
49592
  }
49471
49593
  async function discoverGitReposUnderRoot(rootPath) {
49472
- const root = path64.resolve(rootPath);
49594
+ const root = path66.resolve(rootPath);
49473
49595
  const roots = [];
49474
49596
  let walkEntries = 0;
49475
49597
  async function walk(dir) {
49476
49598
  if (await isGitRepoDirectory(dir)) {
49477
- roots.push(path64.resolve(dir));
49599
+ roots.push(path66.resolve(dir));
49478
49600
  return;
49479
49601
  }
49480
49602
  let entries;
49481
49603
  try {
49482
- entries = fs44.readdirSync(dir, { withFileTypes: true });
49604
+ entries = fs46.readdirSync(dir, { withFileTypes: true });
49483
49605
  } catch {
49484
49606
  return;
49485
49607
  }
@@ -49487,7 +49609,7 @@ async function discoverGitReposUnderRoot(rootPath) {
49487
49609
  await yieldGitDiscoverWork(++walkEntries);
49488
49610
  const ent = entries[i];
49489
49611
  if (!ent.isDirectory() || ent.name === ".git") continue;
49490
- await walk(path64.join(dir, ent.name));
49612
+ await walk(path66.join(dir, ent.name));
49491
49613
  }
49492
49614
  }
49493
49615
  await walk(root);
@@ -49503,8 +49625,8 @@ async function discoverGitReposUnderRoot(rootPath) {
49503
49625
  }
49504
49626
 
49505
49627
  // src/worktrees/prepare/add-isolated-repo-worktree.ts
49506
- import * as fs46 from "node:fs";
49507
- import * as path66 from "node:path";
49628
+ import * as fs48 from "node:fs";
49629
+ import * as path68 from "node:path";
49508
49630
 
49509
49631
  // src/git/worktrees/worktree-add.ts
49510
49632
  async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch, baseRef = "HEAD") {
@@ -49520,8 +49642,8 @@ async function gitWorktreeAddExistingBranch(mainRepoPath, worktreePath, branch)
49520
49642
  }
49521
49643
 
49522
49644
  // src/worktrees/prepare/copy-bridge-files-along-worktree-path.ts
49523
- import * as fs45 from "node:fs";
49524
- import * as path65 from "node:path";
49645
+ import * as fs47 from "node:fs";
49646
+ import * as path67 from "node:path";
49525
49647
  var BRIDGE_FILES_ALONG_WORKTREE_PATH = ["AGENTS.md"];
49526
49648
  function copyBridgeFilesAlongWorktreePath(options) {
49527
49649
  const { bridgeRoot, scopeDir, repoPathRelativeToBridgeRoot, log: log2 } = options;
@@ -49530,19 +49652,19 @@ function copyBridgeFilesAlongWorktreePath(options) {
49530
49652
  const segments = repoPathRelativeToBridgeRoot.split("/").filter(Boolean);
49531
49653
  for (let i = 0; i < segments.length; i++) {
49532
49654
  const prefix = segments.slice(0, i).join("/");
49533
- const bridgeDir = prefix ? path65.join(bridgeRoot, prefix) : bridgeRoot;
49534
- const destDir = prefix ? path65.join(scopeDir, prefix) : scopeDir;
49655
+ const bridgeDir = prefix ? path67.join(bridgeRoot, prefix) : bridgeRoot;
49656
+ const destDir = prefix ? path67.join(scopeDir, prefix) : scopeDir;
49535
49657
  for (const fileName of fileNames) {
49536
49658
  copyFileIfPresent(bridgeDir, destDir, fileName, log2);
49537
49659
  }
49538
49660
  }
49539
49661
  }
49540
49662
  function copyFileIfPresent(srcDir, destDir, fileName, log2) {
49541
- const src = path65.join(srcDir, fileName);
49542
- if (!fs45.existsSync(src)) return;
49543
- const dest = path65.join(destDir, fileName);
49663
+ const src = path67.join(srcDir, fileName);
49664
+ if (!fs47.existsSync(src)) return;
49665
+ const dest = path67.join(destDir, fileName);
49544
49666
  try {
49545
- fs45.copyFileSync(src, dest);
49667
+ fs47.copyFileSync(src, dest);
49546
49668
  log2?.(`[worktrees] Copied ${fileName} to ${dest}`);
49547
49669
  } catch (e) {
49548
49670
  log2?.(
@@ -49574,16 +49696,16 @@ async function addIsolatedRepoWorktree(options) {
49574
49696
  worktreeBaseBranches,
49575
49697
  log: log2
49576
49698
  } = options;
49577
- const repoPathRelativeToBridgeRootRaw = path66.relative(bridgeResolved, repoAbsolutePath);
49578
- if (repoPathRelativeToBridgeRootRaw.startsWith("..") || path66.isAbsolute(repoPathRelativeToBridgeRootRaw)) {
49699
+ const repoPathRelativeToBridgeRootRaw = path68.relative(bridgeResolved, repoAbsolutePath);
49700
+ if (repoPathRelativeToBridgeRootRaw.startsWith("..") || path68.isAbsolute(repoPathRelativeToBridgeRootRaw)) {
49579
49701
  return null;
49580
49702
  }
49581
49703
  const repoPathRelativeToBridgeRoot = normalizeRepoPathRelativeToWorkspaceRoot(
49582
49704
  repoPathRelativeToBridgeRootRaw === "" ? "." : repoPathRelativeToBridgeRootRaw
49583
49705
  );
49584
- const worktreePath = repoPathRelativeToBridgeRoot === "." ? scopeDir : path66.join(scopeDir, repoPathRelativeToBridgeRoot);
49706
+ const worktreePath = repoPathRelativeToBridgeRoot === "." ? scopeDir : path68.join(scopeDir, repoPathRelativeToBridgeRoot);
49585
49707
  if (repoPathRelativeToBridgeRoot !== ".") {
49586
- fs46.mkdirSync(path66.dirname(worktreePath), { recursive: true });
49708
+ fs48.mkdirSync(path68.dirname(worktreePath), { recursive: true });
49587
49709
  copyBridgeFilesAlongWorktreePath({
49588
49710
  bridgeRoot: bridgeResolved,
49589
49711
  scopeDir,
@@ -49611,7 +49733,7 @@ async function addIsolatedRepoWorktree(options) {
49611
49733
  }
49612
49734
 
49613
49735
  // src/worktrees/prepare/resolve-isolated-scope-dir.ts
49614
- import * as path67 from "node:path";
49736
+ import * as path69 from "node:path";
49615
49737
 
49616
49738
  // src/worktrees/worktree-layout-kind.ts
49617
49739
  function sanitizeWorktreeBranchSegment(value) {
@@ -49641,10 +49763,10 @@ function previewDeployBranchName(environmentId) {
49641
49763
 
49642
49764
  // src/worktrees/prepare/resolve-isolated-scope-dir.ts
49643
49765
  function resolveIsolatedScopeDir(options) {
49644
- const bridgeResolved = path67.resolve(options.bridgeRoot);
49766
+ const bridgeResolved = path69.resolve(options.bridgeRoot);
49645
49767
  const cwdKey = allocateDirNameForLauncherCwd(options.layout, bridgeResolved);
49646
- const bridgeKeyDir = path67.join(options.worktreesRootPath, cwdKey);
49647
- const scopeDir = path67.join(bridgeKeyDir, ...layoutDirSegments(options.kind, options.scopeId));
49768
+ const bridgeKeyDir = path69.join(options.worktreesRootPath, cwdKey);
49769
+ const scopeDir = path69.join(bridgeKeyDir, ...layoutDirSegments(options.kind, options.scopeId));
49648
49770
  return { bridgeResolved, scopeDir };
49649
49771
  }
49650
49772
 
@@ -49674,7 +49796,7 @@ async function prepareNewIsolatedWorktrees(options) {
49674
49796
  return null;
49675
49797
  }
49676
49798
  const worktreePaths = [];
49677
- fs47.mkdirSync(scopeDir, { recursive: true });
49799
+ fs49.mkdirSync(scopeDir, { recursive: true });
49678
49800
  await forEachWithGitYield(repos, async (repo) => {
49679
49801
  const worktreePath = await addIsolatedRepoWorktree({
49680
49802
  kind,
@@ -49746,10 +49868,10 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
49746
49868
  }
49747
49869
 
49748
49870
  // src/worktrees/manager/resolve-explicit-session-parent-path.ts
49749
- import * as path68 from "node:path";
49871
+ import * as path70 from "node:path";
49750
49872
  init_yield_to_event_loop();
49751
49873
  async function resolveExplicitSessionParentPath(params) {
49752
- const resolved = path68.resolve(params.parentPathRaw);
49874
+ const resolved = path70.resolve(params.parentPathRaw);
49753
49875
  if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
49754
49876
  return resolved;
49755
49877
  }
@@ -49766,7 +49888,7 @@ async function resolveExplicitSessionParentPath(params) {
49766
49888
  await yieldToEventLoop();
49767
49889
  const tryRoot = await discoverSessionWorktreesUnderSessionWorktreeRoot(cur, params.sessionId);
49768
49890
  if (tryRoot) return rememberAndReturn(tryRoot);
49769
- const next = path68.dirname(cur);
49891
+ const next = path70.dirname(cur);
49770
49892
  if (next === cur) break;
49771
49893
  cur = next;
49772
49894
  }
@@ -49927,15 +50049,15 @@ var SessionWorktreeManager = class {
49927
50049
  };
49928
50050
 
49929
50051
  // src/worktrees/discovery/discover-preview-worktree-on-disk.ts
49930
- import * as fs48 from "node:fs";
49931
- import * as path69 from "node:path";
50052
+ import * as fs50 from "node:fs";
50053
+ import * as path71 from "node:path";
49932
50054
  init_yield_to_event_loop();
49933
50055
  async function discoverPreviewWorktreeOnDisk(options) {
49934
50056
  const { environmentId, worktreesRootPath, layout, bridgeRoot } = options;
49935
50057
  const eid = environmentId.trim();
49936
50058
  if (!eid) return null;
49937
50059
  try {
49938
- await fs48.promises.access(worktreesRootPath);
50060
+ await fs50.promises.access(worktreesRootPath);
49939
50061
  } catch {
49940
50062
  return null;
49941
50063
  }
@@ -49944,13 +50066,13 @@ async function discoverPreviewWorktreeOnDisk(options) {
49944
50066
  if (preferredKey) keysOnDisk.push(preferredKey);
49945
50067
  const scanState = { entries: 0 };
49946
50068
  try {
49947
- for (const name of await fs48.promises.readdir(worktreesRootPath)) {
50069
+ for (const name of await fs50.promises.readdir(worktreesRootPath)) {
49948
50070
  if (!await yieldDuringDiskWalk(scanState)) break;
49949
50071
  if (name.startsWith(".")) continue;
49950
- const p = path69.join(worktreesRootPath, name);
50072
+ const p = path71.join(worktreesRootPath, name);
49951
50073
  let st;
49952
50074
  try {
49953
- st = await fs48.promises.stat(p);
50075
+ st = await fs50.promises.stat(p);
49954
50076
  } catch {
49955
50077
  continue;
49956
50078
  }
@@ -49964,7 +50086,7 @@ async function discoverPreviewWorktreeOnDisk(options) {
49964
50086
  const previewDirRel = layoutDirSegments("preview_environment", eid);
49965
50087
  for (const key of keys) {
49966
50088
  await yieldToEventLoop();
49967
- const previewDir = path69.join(worktreesRootPath, key, ...previewDirRel);
50089
+ const previewDir = path71.join(worktreesRootPath, key, ...previewDirRel);
49968
50090
  const binding = await tryBindingFromIsolatedDirectory(previewDir);
49969
50091
  if (binding) return binding;
49970
50092
  }
@@ -50091,7 +50213,7 @@ var PreviewWorktreeManager = class {
50091
50213
  };
50092
50214
 
50093
50215
  // src/worktrees/deploy/deploy-session-to-preview-environment.ts
50094
- import * as path73 from "node:path";
50216
+ import * as path75 from "node:path";
50095
50217
 
50096
50218
  // src/git/worktrees/reset-worktree-to-branch.ts
50097
50219
  async function gitResetWorktreeToBranch(worktreePath, branch) {
@@ -50102,8 +50224,8 @@ async function gitResetWorktreeToBranch(worktreePath, branch) {
50102
50224
  }
50103
50225
 
50104
50226
  // src/worktrees/deploy/capture-and-apply-wip.ts
50105
- import * as fs49 from "node:fs";
50106
- import * as path70 from "node:path";
50227
+ import * as fs51 from "node:fs";
50228
+ import * as path72 from "node:path";
50107
50229
 
50108
50230
  // src/git/snapshot/git.ts
50109
50231
  var SNAPSHOT_GIT_TIMEOUT_MS = 5e3;
@@ -50158,12 +50280,12 @@ async function applyWorkingTreeWip(targetRepoPath, sourceRepoPath, wip, log2) {
50158
50280
  if (!ap.ok) return ap;
50159
50281
  }
50160
50282
  await forEachWithGitYield(wip.untrackedPaths, async (rel) => {
50161
- const src = path70.join(sourceRepoPath, rel);
50162
- const dst = path70.join(targetRepoPath, rel);
50283
+ const src = path72.join(sourceRepoPath, rel);
50284
+ const dst = path72.join(targetRepoPath, rel);
50163
50285
  try {
50164
- if (!fs49.existsSync(src)) return;
50165
- fs49.mkdirSync(path70.dirname(dst), { recursive: true });
50166
- fs49.copyFileSync(src, dst);
50286
+ if (!fs51.existsSync(src)) return;
50287
+ fs51.mkdirSync(path72.dirname(dst), { recursive: true });
50288
+ fs51.copyFileSync(src, dst);
50167
50289
  } catch (e) {
50168
50290
  log2(
50169
50291
  `[worktrees] Failed to copy untracked ${rel}: ${e instanceof Error ? e.message : String(e)}`
@@ -50174,14 +50296,14 @@ async function applyWorkingTreeWip(targetRepoPath, sourceRepoPath, wip, log2) {
50174
50296
  }
50175
50297
 
50176
50298
  // src/worktrees/deploy/resolve-isolated-checkout-for-repo-path-relative-to-workspace-root.ts
50177
- import * as path71 from "node:path";
50299
+ import * as path73 from "node:path";
50178
50300
  async function resolveIsolatedCheckoutForRepoPathRelativeToWorkspaceRoot(options) {
50179
50301
  const { checkoutPaths, sessionParentPath, bridgeRoot, repoPathRelativeToWorkspaceRoot } = options;
50180
- const resolvedSessionParentPath = sessionParentPath ? path71.resolve(sessionParentPath) : null;
50302
+ const resolvedSessionParentPath = sessionParentPath ? path73.resolve(sessionParentPath) : null;
50181
50303
  let match = null;
50182
50304
  await forEachWithGitYield(checkoutPaths, async (checkoutPath) => {
50183
50305
  if (match) return;
50184
- const resolvedCheckoutPath = path71.resolve(checkoutPath);
50306
+ const resolvedCheckoutPath = path73.resolve(checkoutPath);
50185
50307
  if (!await isGitRepoDirectory(resolvedCheckoutPath)) return;
50186
50308
  const resolvedRepoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
50187
50309
  checkoutPath: resolvedCheckoutPath,
@@ -50235,7 +50357,7 @@ async function applySessionWipToPreviewCheckouts(options) {
50235
50357
  }
50236
50358
 
50237
50359
  // src/worktrees/deploy/collect-session-repo-deploy-states.ts
50238
- import * as path72 from "node:path";
50360
+ import * as path74 from "node:path";
50239
50361
 
50240
50362
  // src/git/branches/create-or-update-branch.ts
50241
50363
  async function gitCreateOrUpdateBranch(repoPath, branch, startRef, options) {
@@ -50272,19 +50394,19 @@ async function collectSessionRepoDeployStates(options) {
50272
50394
  const sessionParentPath = sessionWorktreeManager.getSessionParentPath(sid);
50273
50395
  const states = [];
50274
50396
  await forEachWithGitYield(sessionTargets, async (sessionCheckout) => {
50275
- const checkoutPath = path72.resolve(sessionCheckout);
50397
+ const checkoutPath = path74.resolve(sessionCheckout);
50276
50398
  if (!await isGitRepoDirectory(checkoutPath)) return;
50277
50399
  const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
50278
50400
  checkoutPath,
50279
50401
  bridgeRoot,
50280
- sessionParentPath: sessionParentPath ? path72.resolve(sessionParentPath) : null
50402
+ sessionParentPath: sessionParentPath ? path74.resolve(sessionParentPath) : null
50281
50403
  });
50282
50404
  if (!repoPathRelativeToWorkspaceRoot) return;
50283
50405
  const mainRepoPath = resolveMainRepoPath(checkoutPath);
50284
50406
  const headSha = (await cliSimpleGit(checkoutPath).revparse(["HEAD"])).trim();
50285
50407
  const previewCheckout = previewCheckoutPaths.length > 0 ? await resolveIsolatedCheckoutForRepoPathRelativeToWorkspaceRoot({
50286
50408
  checkoutPaths: previewCheckoutPaths,
50287
- sessionParentPath: previewParentPath ? path72.resolve(previewParentPath) : null,
50409
+ sessionParentPath: previewParentPath ? path74.resolve(previewParentPath) : null,
50288
50410
  bridgeRoot,
50289
50411
  repoPathRelativeToWorkspaceRoot
50290
50412
  }) : null;
@@ -50304,7 +50426,7 @@ async function deploySessionToPreviewEnvironment(options) {
50304
50426
  const eid = options.environmentId.trim();
50305
50427
  if (!sid || !eid) return { ok: false, error: "sessionId and environmentId are required" };
50306
50428
  const deployBranch = previewDeployBranchName(eid);
50307
- const bridgeRoot = path73.resolve(getBridgeRoot());
50429
+ const bridgeRoot = path75.resolve(getBridgeRoot());
50308
50430
  await previewWorktreeManager.ensureCached(eid);
50309
50431
  const existingPreviewParentPath = previewWorktreeManager.getPreviewParentPath(eid) ?? null;
50310
50432
  const existingPreviewCheckoutPaths = previewWorktreeManager.getRepoCheckoutPaths(eid) ?? [];
@@ -50344,10 +50466,10 @@ async function deploySessionToPreviewEnvironment(options) {
50344
50466
  }
50345
50467
 
50346
50468
  // src/worktrees/manager/default-worktrees-root-path.ts
50347
- import * as path74 from "node:path";
50348
- import os9 from "node:os";
50469
+ import * as path76 from "node:path";
50470
+ import os10 from "node:os";
50349
50471
  function defaultWorktreesRootPath() {
50350
- return path74.join(os9.homedir(), ".buildautomaton", "worktrees");
50472
+ return path76.join(os10.homedir(), ".buildautomaton", "worktrees");
50351
50473
  }
50352
50474
 
50353
50475
  // src/connection/create-bridge-worktree-managers.ts
@@ -50477,14 +50599,14 @@ function assertBridgeWorkspace(ctx) {
50477
50599
  }
50478
50600
 
50479
50601
  // src/files/list-dir/index.ts
50480
- import fs51 from "node:fs";
50602
+ import fs53 from "node:fs";
50481
50603
 
50482
50604
  // src/files/ensure-under-cwd.ts
50483
- import path75 from "node:path";
50605
+ import path77 from "node:path";
50484
50606
  function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
50485
- const normalized = path75.normalize(relativePath).replace(/^(\.\/)+/, "");
50486
- const resolved = path75.resolve(cwd, normalized);
50487
- if (!resolved.startsWith(cwd + path75.sep) && resolved !== cwd) {
50607
+ const normalized = path77.normalize(relativePath).replace(/^(\.\/)+/, "");
50608
+ const resolved = path77.resolve(cwd, normalized);
50609
+ if (!resolved.startsWith(cwd + path77.sep) && resolved !== cwd) {
50488
50610
  return null;
50489
50611
  }
50490
50612
  return resolved;
@@ -50497,15 +50619,15 @@ init_yield_to_event_loop();
50497
50619
  var LIST_DIR_YIELD_EVERY = 256;
50498
50620
 
50499
50621
  // src/files/list-dir/map-dir-entry.ts
50500
- import path76 from "node:path";
50501
- import fs50 from "node:fs";
50622
+ import path78 from "node:path";
50623
+ import fs52 from "node:fs";
50502
50624
  async function mapDirEntry(d, relativePath, resolved) {
50503
- const entryPath = path76.join(relativePath || ".", d.name).replace(/\\/g, "/");
50504
- const fullPath = path76.join(resolved, d.name);
50625
+ const entryPath = path78.join(relativePath || ".", d.name).replace(/\\/g, "/");
50626
+ const fullPath = path78.join(resolved, d.name);
50505
50627
  let isDir = d.isDirectory();
50506
50628
  if (d.isSymbolicLink()) {
50507
50629
  try {
50508
- const targetStat = await fs50.promises.stat(fullPath);
50630
+ const targetStat = await fs52.promises.stat(fullPath);
50509
50631
  isDir = targetStat.isDirectory();
50510
50632
  } catch {
50511
50633
  isDir = false;
@@ -50535,7 +50657,7 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
50535
50657
  return { error: "Path is outside working directory" };
50536
50658
  }
50537
50659
  try {
50538
- const names = await fs51.promises.readdir(resolved, { withFileTypes: true });
50660
+ const names = await fs53.promises.readdir(resolved, { withFileTypes: true });
50539
50661
  const entries = [];
50540
50662
  for (let i = 0; i < names.length; i++) {
50541
50663
  if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
@@ -50551,13 +50673,13 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
50551
50673
  }
50552
50674
 
50553
50675
  // src/git/tree/resolve-repo-abs-path.ts
50554
- import * as path77 from "node:path";
50676
+ import * as path79 from "node:path";
50555
50677
  function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
50556
- const bridgeResolved = path77.resolve(bridgeRoot);
50678
+ const bridgeResolved = path79.resolve(bridgeRoot);
50557
50679
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
50558
- const repoPath = rel === "" ? bridgeResolved : path77.join(bridgeResolved, rel);
50559
- const resolved = path77.resolve(repoPath);
50560
- if (!resolved.startsWith(bridgeResolved + path77.sep) && resolved !== bridgeResolved) {
50680
+ const repoPath = rel === "" ? bridgeResolved : path79.join(bridgeResolved, rel);
50681
+ const resolved = path79.resolve(repoPath);
50682
+ if (!resolved.startsWith(bridgeResolved + path79.sep) && resolved !== bridgeResolved) {
50561
50683
  return null;
50562
50684
  }
50563
50685
  return resolved;
@@ -51038,25 +51160,25 @@ async function GET2(ctx) {
51038
51160
  init_in_flight();
51039
51161
 
51040
51162
  // src/files/read/read-file-async.ts
51041
- import fs57 from "node:fs";
51163
+ import fs59 from "node:fs";
51042
51164
  init_yield_to_event_loop();
51043
51165
 
51044
51166
  // src/files/read/resolve-file-cache.ts
51045
- import fs52 from "node:fs";
51046
- import path78 from "node:path";
51167
+ import fs54 from "node:fs";
51168
+ import path80 from "node:path";
51047
51169
  var RESOLVE_CACHE_MAX = 4096;
51048
51170
  var resolveCache = /* @__PURE__ */ new Map();
51049
51171
  function resolveCacheKey(sessionParentPath, relativePath) {
51050
51172
  return `${sessionParentPath}\0${relativePath}`;
51051
51173
  }
51052
51174
  function pathStaysUnderParent(filePath, sessionParentPath) {
51053
- const parent = path78.resolve(sessionParentPath);
51054
- const resolved = path78.resolve(filePath);
51055
- return resolved === parent || resolved.startsWith(`${parent}${path78.sep}`);
51175
+ const parent = path80.resolve(sessionParentPath);
51176
+ const resolved = path80.resolve(filePath);
51177
+ return resolved === parent || resolved.startsWith(`${parent}${path80.sep}`);
51056
51178
  }
51057
51179
  function statMatchesCacheSync(entry) {
51058
51180
  try {
51059
- const stat2 = fs52.statSync(entry.path);
51181
+ const stat2 = fs54.statSync(entry.path);
51060
51182
  return stat2.isFile() && stat2.mtimeMs === entry.mtimeMs && stat2.size === entry.size;
51061
51183
  } catch {
51062
51184
  return false;
@@ -51089,7 +51211,7 @@ function joinInflightResolve(cacheKey, factory) {
51089
51211
  }
51090
51212
 
51091
51213
  // src/files/read/resolve-file-for-read-core.ts
51092
- import fs53 from "node:fs";
51214
+ import fs55 from "node:fs";
51093
51215
  import { isMainThread as isMainThread4 } from "node:worker_threads";
51094
51216
  function resolveFileForReadImplSync(relativePath, sessionParentPath) {
51095
51217
  const cacheKey = resolveCacheKey(sessionParentPath, relativePath);
@@ -51099,13 +51221,13 @@ function resolveFileForReadImplSync(relativePath, sessionParentPath) {
51099
51221
  let size;
51100
51222
  let mtimeMs;
51101
51223
  try {
51102
- const lstat = fs53.lstatSync(resolved);
51224
+ const lstat = fs55.lstatSync(resolved);
51103
51225
  if (lstat.isSymbolicLink()) {
51104
- real = fs53.realpathSync(resolved);
51226
+ real = fs55.realpathSync(resolved);
51105
51227
  if (!pathStaysUnderParent(real, sessionParentPath)) {
51106
51228
  return { error: "Path is outside working directory" };
51107
51229
  }
51108
- const stat2 = fs53.statSync(real);
51230
+ const stat2 = fs55.statSync(real);
51109
51231
  if (!stat2.isFile()) return { error: "Not a file" };
51110
51232
  size = stat2.size;
51111
51233
  mtimeMs = stat2.mtimeMs;
@@ -51133,13 +51255,13 @@ async function resolveFileForReadImpl(relativePath, sessionParentPath) {
51133
51255
  let size;
51134
51256
  let mtimeMs;
51135
51257
  try {
51136
- const lstat = await fs53.promises.lstat(resolved);
51258
+ const lstat = await fs55.promises.lstat(resolved);
51137
51259
  if (lstat.isSymbolicLink()) {
51138
- real = await fs53.promises.realpath(resolved);
51260
+ real = await fs55.promises.realpath(resolved);
51139
51261
  if (!pathStaysUnderParent(real, sessionParentPath)) {
51140
51262
  return { error: "Path is outside working directory" };
51141
51263
  }
51142
- const stat2 = await fs53.promises.stat(real);
51264
+ const stat2 = await fs55.promises.stat(real);
51143
51265
  if (!stat2.isFile()) return { error: "Not a file" };
51144
51266
  size = stat2.size;
51145
51267
  mtimeMs = stat2.mtimeMs;
@@ -51188,7 +51310,7 @@ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeR
51188
51310
 
51189
51311
  // src/files/read/read-file-range-async.ts
51190
51312
  init_yield_to_event_loop();
51191
- import fs54 from "node:fs";
51313
+ import fs56 from "node:fs";
51192
51314
  import { StringDecoder as StringDecoder2 } from "node:string_decoder";
51193
51315
 
51194
51316
  // src/files/read/read-file-range-line-zero.ts
@@ -51302,8 +51424,8 @@ function finishLineZeroTail(state, tail, resultLines, fileSize, lineChunkSize, l
51302
51424
 
51303
51425
  // src/files/read/read-file-range-async.ts
51304
51426
  async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE, fileSizeIn) {
51305
- const fileSize = fileSizeIn ?? (await fs54.promises.stat(filePath)).size;
51306
- const fd = await fs54.promises.open(filePath, "r");
51427
+ const fileSize = fileSizeIn ?? (await fs56.promises.stat(filePath)).size;
51428
+ const fd = await fs56.promises.open(filePath, "r");
51307
51429
  const bufSize = 64 * 1024;
51308
51430
  const buf = Buffer.alloc(bufSize);
51309
51431
  const decoder = new StringDecoder2("utf8");
@@ -51404,7 +51526,7 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
51404
51526
  }
51405
51527
 
51406
51528
  // src/files/read/read-small-file-range-async.ts
51407
- import fs55 from "node:fs";
51529
+ import fs57 from "node:fs";
51408
51530
  import { isMainThread as isMainThread5 } from "node:worker_threads";
51409
51531
  var SMALL_FILE_RANGE_MAX_BYTES = 512 * 1024;
51410
51532
  function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize) {
@@ -51434,7 +51556,7 @@ function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize,
51434
51556
  };
51435
51557
  }
51436
51558
  function readSmallFileRangeSync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
51437
- const raw = fs55.readFileSync(filePath, "utf8");
51559
+ const raw = fs57.readFileSync(filePath, "utf8");
51438
51560
  const lines = raw.split(/\r?\n/);
51439
51561
  return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
51440
51562
  }
@@ -51442,28 +51564,28 @@ async function readSmallFileRangeAsync(filePath, fileSize, startLine, endLine, l
51442
51564
  if (isMainThread5) {
51443
51565
  return readSmallFileRangeSync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize);
51444
51566
  }
51445
- const raw = await fs55.promises.readFile(filePath, "utf8");
51567
+ const raw = await fs57.promises.readFile(filePath, "utf8");
51446
51568
  const lines = raw.split(/\r?\n/);
51447
51569
  return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
51448
51570
  }
51449
51571
 
51450
51572
  // src/files/read/read-file-buffer-full-async.ts
51451
51573
  init_yield_to_event_loop();
51452
- import fs56 from "node:fs";
51574
+ import fs58 from "node:fs";
51453
51575
  import { isMainThread as isMainThread6 } from "node:worker_threads";
51454
51576
  var READ_CHUNK_BYTES = 256 * 1024;
51455
51577
  var MAIN_THREAD_SYNC_READ_MAX_BYTES = 512 * 1024;
51456
51578
  async function readFileBufferFullAsync(filePath, knownSize) {
51457
51579
  if (isMainThread6) {
51458
- const size2 = knownSize ?? fs56.statSync(filePath).size;
51580
+ const size2 = knownSize ?? fs58.statSync(filePath).size;
51459
51581
  if (size2 <= MAIN_THREAD_SYNC_READ_MAX_BYTES) {
51460
51582
  await yieldToEventLoop();
51461
- const buffer = fs56.readFileSync(filePath);
51583
+ const buffer = fs58.readFileSync(filePath);
51462
51584
  return { buffer, size: buffer.length };
51463
51585
  }
51464
51586
  }
51465
- const size = knownSize ?? (await fs56.promises.stat(filePath)).size;
51466
- const fd = await fs56.promises.open(filePath, "r");
51587
+ const size = knownSize ?? (await fs58.promises.stat(filePath)).size;
51588
+ const fd = await fs58.promises.open(filePath, "r");
51467
51589
  const chunks = [];
51468
51590
  let position = 0;
51469
51591
  let bytesSinceYield = 0;
@@ -51566,7 +51688,7 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
51566
51688
  }
51567
51689
  if (hasRange) {
51568
51690
  if (fileSize == null) {
51569
- const stat2 = await fs57.promises.stat(resolvedPath);
51691
+ const stat2 = await fs59.promises.stat(resolvedPath);
51570
51692
  fileSize = stat2.size;
51571
51693
  }
51572
51694
  const read2 = fileSize <= SMALL_FILE_RANGE_MAX_BYTES ? await readSmallFileRangeAsync(
@@ -51864,12 +51986,12 @@ function parseOptionalInt2(raw) {
51864
51986
  return Number.isInteger(parsed) ? parsed : void 0;
51865
51987
  }
51866
51988
  function parseCodeNavParams(url2) {
51867
- const path86 = url2.searchParams.get("path") ?? "";
51989
+ const path88 = url2.searchParams.get("path") ?? "";
51868
51990
  const opRaw = url2.searchParams.get("op")?.trim();
51869
51991
  const op = opRaw === "references" ? "references" : opRaw === "symbols" ? "symbols" : opRaw === "definitions" ? "definitions" : "definition";
51870
51992
  const line = parseOptionalInt2(url2.searchParams.get("line")) ?? 1;
51871
51993
  const column = parseOptionalInt2(url2.searchParams.get("column")) ?? 0;
51872
- return { path: path86, op, line, column };
51994
+ return { path: path88, op, line, column };
51873
51995
  }
51874
51996
  function parseCodeNavPath(url2) {
51875
51997
  const raw = url2.searchParams.get("path")?.trim();
@@ -52667,18 +52789,18 @@ function hasRunningTurn(turns) {
52667
52789
  }
52668
52790
 
52669
52791
  // src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
52670
- import fs60 from "node:fs";
52792
+ import fs62 from "node:fs";
52671
52793
 
52672
52794
  // src/git/snapshot/capture.ts
52673
- import * as fs59 from "node:fs";
52674
- import * as path80 from "node:path";
52795
+ import * as fs61 from "node:fs";
52796
+ import * as path82 from "node:path";
52675
52797
 
52676
52798
  // src/git/snapshot/apply-pre-turn-snapshot.ts
52677
- import * as fs58 from "node:fs";
52799
+ import * as fs60 from "node:fs";
52678
52800
  async function applyPreTurnSnapshot(filePath, log2) {
52679
52801
  let data;
52680
52802
  try {
52681
- data = JSON.parse(fs58.readFileSync(filePath, "utf8"));
52803
+ data = JSON.parse(fs60.readFileSync(filePath, "utf8"));
52682
52804
  } catch (error51) {
52683
52805
  return { ok: false, error: error51 instanceof Error ? error51.message : String(error51) };
52684
52806
  }
@@ -52707,18 +52829,18 @@ async function applyPreTurnSnapshot(filePath, log2) {
52707
52829
  }
52708
52830
 
52709
52831
  // src/git/snapshot/resolve-repo-roots.ts
52710
- import * as path79 from "node:path";
52832
+ import * as path81 from "node:path";
52711
52833
  async function resolveSnapshotRepoRoots(options) {
52712
52834
  const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
52713
52835
  if (worktreePaths?.length) {
52714
- const paths = [...new Set(worktreePaths.map((p) => path79.resolve(p)))];
52836
+ const paths = [...new Set(worktreePaths.map((p) => path81.resolve(p)))];
52715
52837
  return (await Promise.all(paths.map(async (p) => await isGitRepoDirectory(p) ? p : null))).filter((p) => p != null);
52716
52838
  }
52717
52839
  try {
52718
52840
  const roots = (await discoverGitReposUnderRoot(fallbackCwd)).map((repo) => repo.absolutePath);
52719
52841
  const sid = sessionId?.trim();
52720
52842
  if (!sid) return roots;
52721
- const sessionRoots = roots.filter((root) => path79.basename(root) === sid);
52843
+ const sessionRoots = roots.filter((root) => path81.basename(root) === sid);
52722
52844
  return sessionRoots.length > 0 ? sessionRoots : roots;
52723
52845
  } catch (error51) {
52724
52846
  log2(`[snapshot] Discover repositories failed: ${error51 instanceof Error ? error51.message : String(error51)}`);
@@ -52740,7 +52862,7 @@ async function capturePreTurnSnapshot(options) {
52740
52862
  });
52741
52863
  const dir = snapshotsDirForCwd(agentCwd);
52742
52864
  try {
52743
- fs59.mkdirSync(dir, { recursive: true });
52865
+ fs61.mkdirSync(dir, { recursive: true });
52744
52866
  } catch (e) {
52745
52867
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
52746
52868
  }
@@ -52749,9 +52871,9 @@ async function capturePreTurnSnapshot(options) {
52749
52871
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
52750
52872
  repos
52751
52873
  };
52752
- const filePath = path80.join(dir, `${runId}.json`);
52874
+ const filePath = path82.join(dir, `${runId}.json`);
52753
52875
  try {
52754
- fs59.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
52876
+ fs61.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
52755
52877
  } catch (e) {
52756
52878
  return { ok: false, error: e instanceof Error ? e.message : String(e) };
52757
52879
  }
@@ -52771,7 +52893,7 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
52771
52893
  const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
52772
52894
  const file2 = snapshotFilePath(agentBase, tid);
52773
52895
  try {
52774
- await fs60.promises.access(file2, fs60.constants.F_OK);
52896
+ await fs62.promises.access(file2, fs62.constants.F_OK);
52775
52897
  } catch {
52776
52898
  deps.log(
52777
52899
  `[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
@@ -53422,6 +53544,7 @@ var handleRenameSessionBranchMessage = (msg, deps) => {
53422
53544
  var handleSessionArchivedMessage = (msg, deps) => {
53423
53545
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
53424
53546
  if (!sessionId) return;
53547
+ cleanupSessionPlans(sessionId);
53425
53548
  void deps.sessionWorktreeManager.removeSessionWorktrees(sessionId);
53426
53549
  };
53427
53550
 
@@ -53429,11 +53552,12 @@ var handleSessionArchivedMessage = (msg, deps) => {
53429
53552
  var handleSessionDiscardedMessage = (msg, deps) => {
53430
53553
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
53431
53554
  if (!sessionId) return;
53555
+ cleanupSessionPlans(sessionId);
53432
53556
  void deps.sessionWorktreeManager.removeSessionWorktrees(sessionId);
53433
53557
  };
53434
53558
 
53435
53559
  // src/routing/handlers/revert-turn-snapshot.ts
53436
- import * as fs61 from "node:fs";
53560
+ import * as fs63 from "node:fs";
53437
53561
  var handleRevertTurnSnapshotMessage = (msg, deps) => {
53438
53562
  const id = typeof msg.id === "string" ? msg.id : "";
53439
53563
  const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
@@ -53446,7 +53570,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
53446
53570
  const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
53447
53571
  const file2 = snapshotFilePath(agentBase, turnId);
53448
53572
  try {
53449
- await fs61.promises.access(file2, fs61.constants.F_OK);
53573
+ await fs63.promises.access(file2, fs63.constants.F_OK);
53450
53574
  } catch {
53451
53575
  sendWsMessage(s, {
53452
53576
  type: "revert_turn_snapshot_result",
@@ -53544,8 +53668,8 @@ function isValidRemoteSkillInstallItem(item) {
53544
53668
 
53545
53669
  // src/skills/install/install-remote-skills-async.ts
53546
53670
  init_yield_to_event_loop();
53547
- import fs62 from "node:fs";
53548
- import path81 from "node:path";
53671
+ import fs64 from "node:fs";
53672
+ import path83 from "node:path";
53549
53673
 
53550
53674
  // src/skills/install/constants.ts
53551
53675
  var INSTALL_SKILLS_YIELD_EVERY = 16;
@@ -53556,12 +53680,12 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
53556
53680
  if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
53557
53681
  await yieldToEventLoop();
53558
53682
  }
53559
- const dest = path81.join(skillDir, f.path);
53560
- await fs62.promises.mkdir(path81.dirname(dest), { recursive: true });
53683
+ const dest = path83.join(skillDir, f.path);
53684
+ await fs64.promises.mkdir(path83.dirname(dest), { recursive: true });
53561
53685
  if (f.text !== void 0) {
53562
- await fs62.promises.writeFile(dest, f.text, "utf8");
53686
+ await fs64.promises.writeFile(dest, f.text, "utf8");
53563
53687
  } else if (f.base64) {
53564
- await fs62.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
53688
+ await fs64.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
53565
53689
  }
53566
53690
  }
53567
53691
  async function installRemoteSkillsAsync(cwd, targetDir, items) {
@@ -53573,7 +53697,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
53573
53697
  try {
53574
53698
  for (const item of items) {
53575
53699
  if (!isValidRemoteSkillInstallItem(item)) continue;
53576
- const skillDir = path81.join(cwd, targetDir, item.skillName);
53700
+ const skillDir = path83.join(cwd, targetDir, item.skillName);
53577
53701
  for (const f of item.files) {
53578
53702
  await writeInstallFileAsync(skillDir, f, filesWritten);
53579
53703
  }
@@ -53936,13 +54060,13 @@ function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
53936
54060
 
53937
54061
  // src/files/handle-file-browser-search.ts
53938
54062
  init_yield_to_event_loop();
53939
- import path82 from "node:path";
54063
+ import path84 from "node:path";
53940
54064
  var SEARCH_LIMIT = 100;
53941
54065
  function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
53942
54066
  void (async () => {
53943
54067
  await yieldToEventLoop();
53944
54068
  const q = typeof msg.q === "string" ? msg.q : "";
53945
- const sessionParentPath = path82.resolve(
54069
+ const sessionParentPath = path84.resolve(
53946
54070
  sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
53947
54071
  );
53948
54072
  if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
@@ -54040,7 +54164,7 @@ function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeMana
54040
54164
  }
54041
54165
 
54042
54166
  // src/git/bridge-git-context.ts
54043
- import * as path83 from "node:path";
54167
+ import * as path85 from "node:path";
54044
54168
  init_yield_to_event_loop();
54045
54169
 
54046
54170
  // src/git/branches/get-current-branch.ts
@@ -54108,12 +54232,12 @@ function listPendingCheckouts() {
54108
54232
  // src/git/bridge-git-context.ts
54109
54233
  function folderNameForRelPath(relPath, bridgeRoot) {
54110
54234
  if (relPath === "." || relPath === "") {
54111
- return path83.basename(path83.resolve(bridgeRoot)) || "repo";
54235
+ return path85.basename(path85.resolve(bridgeRoot)) || "repo";
54112
54236
  }
54113
- return path83.basename(relPath) || relPath;
54237
+ return path85.basename(relPath) || relPath;
54114
54238
  }
54115
54239
  async function discoverGitReposForBridgeContext(bridgeRoot) {
54116
- const root = path83.resolve(bridgeRoot);
54240
+ const root = path85.resolve(bridgeRoot);
54117
54241
  if (await isGitRepoDirectory(root)) {
54118
54242
  const remoteUrl = await getRemoteOriginUrl(root);
54119
54243
  return [{ absolutePath: root, remoteUrl }];
@@ -54121,19 +54245,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
54121
54245
  const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
54122
54246
  const byPath = /* @__PURE__ */ new Map();
54123
54247
  for (const repo of [...deep, ...shallow]) {
54124
- byPath.set(path83.resolve(repo.absolutePath), repo);
54248
+ byPath.set(path85.resolve(repo.absolutePath), repo);
54125
54249
  }
54126
54250
  return [...byPath.values()];
54127
54251
  }
54128
54252
  async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
54129
- const bridgeResolved = path83.resolve(bridgeRoot);
54253
+ const bridgeResolved = path85.resolve(bridgeRoot);
54130
54254
  const repos = await discoverGitReposForBridgeContext(bridgeResolved);
54131
54255
  const rows = [];
54132
54256
  for (let i = 0; i < repos.length; i++) {
54133
54257
  if (i > 0) await yieldToEventLoop();
54134
54258
  const repo = repos[i];
54135
- let rel = path83.relative(bridgeResolved, repo.absolutePath);
54136
- if (rel.startsWith("..") || path83.isAbsolute(rel)) continue;
54259
+ let rel = path85.relative(bridgeResolved, repo.absolutePath);
54260
+ if (rel.startsWith("..") || path85.isAbsolute(rel)) continue;
54137
54261
  const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
54138
54262
  const currentBranch = await getCurrentBranch(repo.absolutePath);
54139
54263
  const remoteUrl = repo.remoteUrl.trim() || null;
@@ -54164,11 +54288,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
54164
54288
  return rows;
54165
54289
  }
54166
54290
  async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
54167
- const bridgeResolved = path83.resolve(bridgeRoot);
54291
+ const bridgeResolved = path85.resolve(bridgeRoot);
54168
54292
  const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
54169
- const repoPath = rel === "" ? bridgeResolved : path83.join(bridgeResolved, rel);
54170
- const resolved = path83.resolve(repoPath);
54171
- if (!resolved.startsWith(bridgeResolved + path83.sep) && resolved !== bridgeResolved) {
54293
+ const repoPath = rel === "" ? bridgeResolved : path85.join(bridgeResolved, rel);
54294
+ const resolved = path85.resolve(repoPath);
54295
+ if (!resolved.startsWith(bridgeResolved + path85.sep) && resolved !== bridgeResolved) {
54172
54296
  return [];
54173
54297
  }
54174
54298
  return listRepoBranchRefs(resolved);
@@ -54218,8 +54342,8 @@ function handleListRepoBranchesRequestMessage(msg, getWs) {
54218
54342
  }
54219
54343
 
54220
54344
  // src/git/checkout/bridge-git-checkout.ts
54221
- import * as fs64 from "node:fs/promises";
54222
- import * as path85 from "node:path";
54345
+ import * as fs66 from "node:fs/promises";
54346
+ import * as path87 from "node:path";
54223
54347
 
54224
54348
  // src/git/checkout/normalize-clone-url.ts
54225
54349
  function normalizeCloneUrl(url2) {
@@ -54239,12 +54363,12 @@ function cloneUrlWithHttpsAuth(url2, auth) {
54239
54363
  }
54240
54364
 
54241
54365
  // src/git/checkout/resolve-checkout-target.ts
54242
- import * as fs63 from "node:fs/promises";
54243
- import * as path84 from "node:path";
54366
+ import * as fs65 from "node:fs/promises";
54367
+ import * as path86 from "node:path";
54244
54368
  var FOLDER_NAME_RE = /^[A-Za-z0-9._-]+$/;
54245
54369
  async function pathExists(p) {
54246
54370
  try {
54247
- await fs63.access(p);
54371
+ await fs65.access(p);
54248
54372
  return true;
54249
54373
  } catch {
54250
54374
  return false;
@@ -54256,7 +54380,7 @@ async function resolveCheckoutTarget(opts) {
54256
54380
  if (await isGitRepoDirectory(bridgeRoot)) {
54257
54381
  throw new Error("Bridge root is already a git repository");
54258
54382
  }
54259
- const entries = await fs63.readdir(bridgeRoot).catch(() => []);
54383
+ const entries = await fs65.readdir(bridgeRoot).catch(() => []);
54260
54384
  if (entries.length > 0) {
54261
54385
  throw new Error("Bridge root must be empty to initialize a monorepo checkout");
54262
54386
  }
@@ -54269,8 +54393,8 @@ async function resolveCheckoutTarget(opts) {
54269
54393
  if (await isGitRepoDirectory(bridgeRoot)) {
54270
54394
  throw new Error("Cannot add a nested repo while the bridge root is itself a git repository");
54271
54395
  }
54272
- const targetDir = path84.resolve(bridgeRoot, folder);
54273
- if (!targetDir.startsWith(bridgeRoot + path84.sep)) {
54396
+ const targetDir = path86.resolve(bridgeRoot, folder);
54397
+ if (!targetDir.startsWith(bridgeRoot + path86.sep)) {
54274
54398
  throw new Error("Invalid folderName");
54275
54399
  }
54276
54400
  if (await pathExists(targetDir)) {
@@ -54289,10 +54413,10 @@ async function bridgeGitCheckout(params) {
54289
54413
  });
54290
54414
  const folderName = relPath === "." ? "repo" : relPath;
54291
54415
  beginPendingCheckout({ relPath, folderName, remoteUrl: cloneUrl });
54292
- const parent = path85.dirname(targetDir);
54293
- await fs64.mkdir(parent, { recursive: true });
54416
+ const parent = path87.dirname(targetDir);
54417
+ await fs66.mkdir(parent, { recursive: true });
54294
54418
  if (relPath !== ".") {
54295
- await fs64.mkdir(targetDir, { recursive: true });
54419
+ await fs66.mkdir(targetDir, { recursive: true });
54296
54420
  }
54297
54421
  const url2 = cloneUrlWithHttpsAuth(cloneUrl, params.auth ?? null);
54298
54422
  try {
@@ -54303,7 +54427,7 @@ async function bridgeGitCheckout(params) {
54303
54427
  return { relPath, folderName };
54304
54428
  } catch (e) {
54305
54429
  if (relPath !== ".") {
54306
- await fs64.rm(targetDir, { recursive: true, force: true }).catch(() => void 0);
54430
+ await fs66.rm(targetDir, { recursive: true, force: true }).catch(() => void 0);
54307
54431
  }
54308
54432
  const msg = e instanceof Error ? e.message : String(e);
54309
54433
  throw new Error(