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