@buildautomaton/cli 0.1.68 → 0.1.70
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 +1201 -883
- package/dist/cli.js.map +4 -4
- package/dist/index.js +935 -617
- 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: path82, errorMaps, issueData } = params;
|
|
4212
|
+
const fullPath = [...path82, ...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, path82, key) {
|
|
4521
4521
|
this._cachedPath = [];
|
|
4522
4522
|
this.parent = parent;
|
|
4523
4523
|
this.data = value;
|
|
4524
|
-
this._path =
|
|
4524
|
+
this._path = path82;
|
|
4525
4525
|
this._key = key;
|
|
4526
4526
|
}
|
|
4527
4527
|
get path() {
|
|
@@ -8182,10 +8182,10 @@ function assignProp(target, prop, value) {
|
|
|
8182
8182
|
configurable: true
|
|
8183
8183
|
});
|
|
8184
8184
|
}
|
|
8185
|
-
function getElementAtPath(obj,
|
|
8186
|
-
if (!
|
|
8185
|
+
function getElementAtPath(obj, path82) {
|
|
8186
|
+
if (!path82)
|
|
8187
8187
|
return obj;
|
|
8188
|
-
return
|
|
8188
|
+
return path82.reduce((acc, key) => acc?.[key], obj);
|
|
8189
8189
|
}
|
|
8190
8190
|
function promiseAllObject(promisesObj) {
|
|
8191
8191
|
const keys = Object.keys(promisesObj);
|
|
@@ -8434,11 +8434,11 @@ function aborted(x, startIndex = 0) {
|
|
|
8434
8434
|
}
|
|
8435
8435
|
return false;
|
|
8436
8436
|
}
|
|
8437
|
-
function prefixIssues(
|
|
8437
|
+
function prefixIssues(path82, 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(path82);
|
|
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, path82 = []) => {
|
|
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 = [...path82, ...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(path82) {
|
|
8671
8671
|
const segs = [];
|
|
8672
|
-
for (const seg of
|
|
8672
|
+
for (const seg of path82) {
|
|
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
|
join(moduleDir, "..", sub, filename),
|
|
22377
22377
|
join(moduleDir, "..", "..", "dist", sub, filename)
|
|
22378
22378
|
]);
|
|
22379
|
-
const resolved = candidates.find((
|
|
22379
|
+
const resolved = candidates.find((path82) => existsSync(path82));
|
|
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(path82, 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(path82);
|
|
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 = (path82, originalPath, doThrow) => {
|
|
23481
|
+
if (!isString(path82)) {
|
|
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 (!path82) {
|
|
23488
23488
|
return doThrow(`path must not be empty`, TypeError);
|
|
23489
23489
|
}
|
|
23490
|
-
if (checkPath.isNotRelative(
|
|
23490
|
+
if (checkPath.isNotRelative(path82)) {
|
|
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 = (path82) => REGEX_TEST_INVALID_PATH.test(path82);
|
|
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 path82 = originalPath && checkPath.convert(originalPath);
|
|
23530
23530
|
checkPath(
|
|
23531
|
-
|
|
23531
|
+
path82,
|
|
23532
23532
|
originalPath,
|
|
23533
23533
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
23534
23534
|
);
|
|
23535
|
-
return this._t(
|
|
23535
|
+
return this._t(path82, cache2, checkUnignored, slices);
|
|
23536
23536
|
}
|
|
23537
|
-
checkIgnore(
|
|
23538
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
23539
|
-
return this.test(
|
|
23537
|
+
checkIgnore(path82) {
|
|
23538
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path82)) {
|
|
23539
|
+
return this.test(path82);
|
|
23540
23540
|
}
|
|
23541
|
-
const slices =
|
|
23541
|
+
const slices = path82.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(path82, false, MODE_CHECK_IGNORE);
|
|
23555
23555
|
}
|
|
23556
|
-
_t(
|
|
23557
|
-
if (
|
|
23558
|
-
return cache2[
|
|
23556
|
+
_t(path82, cache2, checkUnignored, slices) {
|
|
23557
|
+
if (path82 in cache2) {
|
|
23558
|
+
return cache2[path82];
|
|
23559
23559
|
}
|
|
23560
23560
|
if (!slices) {
|
|
23561
|
-
slices =
|
|
23561
|
+
slices = path82.split(SLASH).filter(Boolean);
|
|
23562
23562
|
}
|
|
23563
23563
|
slices.pop();
|
|
23564
23564
|
if (!slices.length) {
|
|
23565
|
-
return cache2[
|
|
23565
|
+
return cache2[path82] = this._rules.test(path82, 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[path82] = parent.ignored ? parent : this._rules.test(path82, checkUnignored, MODE_IGNORE);
|
|
23574
23574
|
}
|
|
23575
|
-
ignores(
|
|
23576
|
-
return this._test(
|
|
23575
|
+
ignores(path82) {
|
|
23576
|
+
return this._test(path82, this._ignoreCache, false).ignored;
|
|
23577
23577
|
}
|
|
23578
23578
|
createFilter() {
|
|
23579
|
-
return (
|
|
23579
|
+
return (path82) => !this.ignores(path82);
|
|
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(path82) {
|
|
23586
|
+
return this._test(path82, this._testCache, true);
|
|
23587
23587
|
}
|
|
23588
23588
|
};
|
|
23589
23589
|
var factory = (options) => new Ignore(options);
|
|
23590
|
-
var isPathValid = (
|
|
23590
|
+
var isPathValid = (path82) => checkPath(path82 && checkPath.convert(path82), path82, 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 = (path82) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path82) || isNotRelative(path82);
|
|
23596
23596
|
};
|
|
23597
23597
|
if (
|
|
23598
23598
|
// Detect `process` so that it can run in browsers.
|
|
@@ -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(path82, isFile, isDirectory) {
|
|
27964
|
+
log2(`checking %s`, path82);
|
|
27965
27965
|
try {
|
|
27966
|
-
const stat2 = fs_1.statSync(
|
|
27966
|
+
const stat2 = fs_1.statSync(path82);
|
|
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(path82, type = exports.READABLE) {
|
|
27987
|
+
return check2(path82, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
27988
27988
|
}
|
|
27989
27989
|
exports.exists = exists2;
|
|
27990
27990
|
exports.FILE = 1;
|
|
@@ -29341,6 +29341,18 @@ function getAgentModelFromAgentConfig(config2) {
|
|
|
29341
29341
|
return t !== "" ? t : null;
|
|
29342
29342
|
}
|
|
29343
29343
|
|
|
29344
|
+
// ../types/src/overview/heatmap/constants.ts
|
|
29345
|
+
var HOUR_MS = 36e5;
|
|
29346
|
+
var DAY_MS = 24 * HOUR_MS;
|
|
29347
|
+
|
|
29348
|
+
// ../types/src/bridges/agents/types.ts
|
|
29349
|
+
var INSTALLABLE_BRIDGE_AGENTS = [
|
|
29350
|
+
{ value: "claude-code", label: "Anthropic Claude Code", tokenLabel: "Anthropic API key", tokenEnvVar: "ANTHROPIC_API_KEY" },
|
|
29351
|
+
{ value: "codex-acp", label: "Codex", tokenLabel: "OpenAI API key", tokenEnvVar: "OPENAI_API_KEY" },
|
|
29352
|
+
{ value: "cursor-cli", label: "Cursor CLI agent", tokenLabel: "Cursor API key", tokenEnvVar: "CURSOR_API_KEY" },
|
|
29353
|
+
{ value: "opencode", label: "OpenCode agent", tokenLabel: "Provider API key", tokenEnvVar: "OPENCODE_API_KEY" }
|
|
29354
|
+
];
|
|
29355
|
+
|
|
29344
29356
|
// src/agents/acp/safe-fs-path.ts
|
|
29345
29357
|
import * as path2 from "node:path";
|
|
29346
29358
|
function resolveSafePathUnderCwd(cwd, filePath) {
|
|
@@ -30338,8 +30350,8 @@ function randomSecret() {
|
|
|
30338
30350
|
}
|
|
30339
30351
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
30340
30352
|
}
|
|
30341
|
-
async function requestPreviewApi(port, secret, method,
|
|
30342
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
30353
|
+
async function requestPreviewApi(port, secret, method, path82, body) {
|
|
30354
|
+
const url2 = `http://127.0.0.1:${port}${path82}`;
|
|
30343
30355
|
const headers = {
|
|
30344
30356
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
30345
30357
|
"Content-Type": "application/json"
|
|
@@ -30351,7 +30363,7 @@ async function requestPreviewApi(port, secret, method, path80, body) {
|
|
|
30351
30363
|
});
|
|
30352
30364
|
const data = await res.json().catch(() => ({}));
|
|
30353
30365
|
if (!res.ok) {
|
|
30354
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
30366
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path82}: ${res.status}`);
|
|
30355
30367
|
}
|
|
30356
30368
|
return data;
|
|
30357
30369
|
}
|
|
@@ -30574,7 +30586,7 @@ function installBridgeProcessResilience() {
|
|
|
30574
30586
|
}
|
|
30575
30587
|
|
|
30576
30588
|
// src/cli-version.ts
|
|
30577
|
-
var CLI_VERSION = "0.1.
|
|
30589
|
+
var CLI_VERSION = "0.1.70".length > 0 ? "0.1.70" : "0.0.0-dev";
|
|
30578
30590
|
|
|
30579
30591
|
// src/connection/heartbeat/constants.ts
|
|
30580
30592
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -34971,8 +34983,8 @@ async function execGitFile(args, options) {
|
|
|
34971
34983
|
}
|
|
34972
34984
|
|
|
34973
34985
|
// src/git/changes/parse/normalize-git-diff-path.ts
|
|
34974
|
-
function normalizeGitDiffPath(
|
|
34975
|
-
return
|
|
34986
|
+
function normalizeGitDiffPath(path82) {
|
|
34987
|
+
return path82.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
|
|
34976
34988
|
}
|
|
34977
34989
|
|
|
34978
34990
|
// src/git/changes/parse/parse-name-status-entries.ts
|
|
@@ -36481,6 +36493,21 @@ function createBridgeMcpToolRegistry(shared) {
|
|
|
36481
36493
|
// src/mcp/bridge-access/start-server.ts
|
|
36482
36494
|
import * as http from "node:http";
|
|
36483
36495
|
|
|
36496
|
+
// src/http/close-http-server.ts
|
|
36497
|
+
function isServerNotRunningError(err) {
|
|
36498
|
+
return err.code === "ERR_SERVER_NOT_RUNNING";
|
|
36499
|
+
}
|
|
36500
|
+
function closeHttpServer(server) {
|
|
36501
|
+
if (!server) return Promise.resolve();
|
|
36502
|
+
return new Promise((resolve35) => {
|
|
36503
|
+
server.close((err) => {
|
|
36504
|
+
if (err && !isServerNotRunningError(err)) {
|
|
36505
|
+
}
|
|
36506
|
+
resolve35();
|
|
36507
|
+
});
|
|
36508
|
+
});
|
|
36509
|
+
}
|
|
36510
|
+
|
|
36484
36511
|
// src/mcp/bridge-access/read-json-body.ts
|
|
36485
36512
|
function readJsonBody(req) {
|
|
36486
36513
|
return new Promise((resolve35, reject) => {
|
|
@@ -36562,9 +36589,7 @@ function startBridgeAccessServer(registry2) {
|
|
|
36562
36589
|
}
|
|
36563
36590
|
resolve35({
|
|
36564
36591
|
port: addr.port,
|
|
36565
|
-
close: () =>
|
|
36566
|
-
server.close((err) => err ? closeReject(err) : closeResolve());
|
|
36567
|
-
})
|
|
36592
|
+
close: () => closeHttpServer(server)
|
|
36568
36593
|
});
|
|
36569
36594
|
});
|
|
36570
36595
|
});
|
|
@@ -39169,8 +39194,8 @@ function pathspec(...paths) {
|
|
|
39169
39194
|
cache.set(key, paths);
|
|
39170
39195
|
return key;
|
|
39171
39196
|
}
|
|
39172
|
-
function isPathSpec(
|
|
39173
|
-
return
|
|
39197
|
+
function isPathSpec(path82) {
|
|
39198
|
+
return path82 instanceof String && cache.has(path82);
|
|
39174
39199
|
}
|
|
39175
39200
|
function toPaths(pathSpec) {
|
|
39176
39201
|
return cache.get(pathSpec) || [];
|
|
@@ -39259,8 +39284,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
39259
39284
|
function forEachLineWithContent(input, callback) {
|
|
39260
39285
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
39261
39286
|
}
|
|
39262
|
-
function folderExists(
|
|
39263
|
-
return (0, import_file_exists.exists)(
|
|
39287
|
+
function folderExists(path82) {
|
|
39288
|
+
return (0, import_file_exists.exists)(path82, import_file_exists.FOLDER);
|
|
39264
39289
|
}
|
|
39265
39290
|
function append(target, item) {
|
|
39266
39291
|
if (Array.isArray(target)) {
|
|
@@ -39664,8 +39689,8 @@ function checkIsRepoRootTask() {
|
|
|
39664
39689
|
commands,
|
|
39665
39690
|
format: "utf-8",
|
|
39666
39691
|
onError,
|
|
39667
|
-
parser(
|
|
39668
|
-
return /^\.(git)?$/.test(
|
|
39692
|
+
parser(path82) {
|
|
39693
|
+
return /^\.(git)?$/.test(path82.trim());
|
|
39669
39694
|
}
|
|
39670
39695
|
};
|
|
39671
39696
|
}
|
|
@@ -40099,11 +40124,11 @@ function parseGrep(grep) {
|
|
|
40099
40124
|
const paths = /* @__PURE__ */ new Set();
|
|
40100
40125
|
const results = {};
|
|
40101
40126
|
forEachLineWithContent(grep, (input) => {
|
|
40102
|
-
const [
|
|
40103
|
-
paths.add(
|
|
40104
|
-
(results[
|
|
40127
|
+
const [path82, line, preview] = input.split(NULL);
|
|
40128
|
+
paths.add(path82);
|
|
40129
|
+
(results[path82] = results[path82] || []).push({
|
|
40105
40130
|
line: asNumber(line),
|
|
40106
|
-
path:
|
|
40131
|
+
path: path82,
|
|
40107
40132
|
preview
|
|
40108
40133
|
});
|
|
40109
40134
|
});
|
|
@@ -40868,14 +40893,14 @@ var init_hash_object = __esm2({
|
|
|
40868
40893
|
init_task();
|
|
40869
40894
|
}
|
|
40870
40895
|
});
|
|
40871
|
-
function parseInit(bare,
|
|
40896
|
+
function parseInit(bare, path82, text) {
|
|
40872
40897
|
const response = String(text).trim();
|
|
40873
40898
|
let result;
|
|
40874
40899
|
if (result = initResponseRegex.exec(response)) {
|
|
40875
|
-
return new InitSummary(bare,
|
|
40900
|
+
return new InitSummary(bare, path82, false, result[1]);
|
|
40876
40901
|
}
|
|
40877
40902
|
if (result = reInitResponseRegex.exec(response)) {
|
|
40878
|
-
return new InitSummary(bare,
|
|
40903
|
+
return new InitSummary(bare, path82, true, result[1]);
|
|
40879
40904
|
}
|
|
40880
40905
|
let gitDir = "";
|
|
40881
40906
|
const tokens = response.split(" ");
|
|
@@ -40886,7 +40911,7 @@ function parseInit(bare, path80, text) {
|
|
|
40886
40911
|
break;
|
|
40887
40912
|
}
|
|
40888
40913
|
}
|
|
40889
|
-
return new InitSummary(bare,
|
|
40914
|
+
return new InitSummary(bare, path82, /^re/i.test(response), gitDir);
|
|
40890
40915
|
}
|
|
40891
40916
|
var InitSummary;
|
|
40892
40917
|
var initResponseRegex;
|
|
@@ -40895,9 +40920,9 @@ var init_InitSummary = __esm2({
|
|
|
40895
40920
|
"src/lib/responses/InitSummary.ts"() {
|
|
40896
40921
|
"use strict";
|
|
40897
40922
|
InitSummary = class {
|
|
40898
|
-
constructor(bare,
|
|
40923
|
+
constructor(bare, path82, existing, gitDir) {
|
|
40899
40924
|
this.bare = bare;
|
|
40900
|
-
this.path =
|
|
40925
|
+
this.path = path82;
|
|
40901
40926
|
this.existing = existing;
|
|
40902
40927
|
this.gitDir = gitDir;
|
|
40903
40928
|
}
|
|
@@ -40909,7 +40934,7 @@ var init_InitSummary = __esm2({
|
|
|
40909
40934
|
function hasBareCommand(command) {
|
|
40910
40935
|
return command.includes(bareCommand);
|
|
40911
40936
|
}
|
|
40912
|
-
function initTask(bare = false,
|
|
40937
|
+
function initTask(bare = false, path82, customArgs) {
|
|
40913
40938
|
const commands = ["init", ...customArgs];
|
|
40914
40939
|
if (bare && !hasBareCommand(commands)) {
|
|
40915
40940
|
commands.splice(1, 0, bareCommand);
|
|
@@ -40918,7 +40943,7 @@ function initTask(bare = false, path80, customArgs) {
|
|
|
40918
40943
|
commands,
|
|
40919
40944
|
format: "utf-8",
|
|
40920
40945
|
parser(text) {
|
|
40921
|
-
return parseInit(commands.includes("--bare"),
|
|
40946
|
+
return parseInit(commands.includes("--bare"), path82, text);
|
|
40922
40947
|
}
|
|
40923
40948
|
};
|
|
40924
40949
|
}
|
|
@@ -41734,12 +41759,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
41734
41759
|
"use strict";
|
|
41735
41760
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
41736
41761
|
FileStatusSummary = class {
|
|
41737
|
-
constructor(
|
|
41738
|
-
this.path =
|
|
41762
|
+
constructor(path82, index, working_dir) {
|
|
41763
|
+
this.path = path82;
|
|
41739
41764
|
this.index = index;
|
|
41740
41765
|
this.working_dir = working_dir;
|
|
41741
41766
|
if (index === "R" || working_dir === "R") {
|
|
41742
|
-
const detail = fromPathRegex.exec(
|
|
41767
|
+
const detail = fromPathRegex.exec(path82) || [null, path82, path82];
|
|
41743
41768
|
this.from = detail[2] || "";
|
|
41744
41769
|
this.path = detail[1] || "";
|
|
41745
41770
|
}
|
|
@@ -41770,14 +41795,14 @@ function splitLine(result, lineStr) {
|
|
|
41770
41795
|
default:
|
|
41771
41796
|
return;
|
|
41772
41797
|
}
|
|
41773
|
-
function data(index, workingDir,
|
|
41798
|
+
function data(index, workingDir, path82) {
|
|
41774
41799
|
const raw = `${index}${workingDir}`;
|
|
41775
41800
|
const handler = parsers6.get(raw);
|
|
41776
41801
|
if (handler) {
|
|
41777
|
-
handler(result,
|
|
41802
|
+
handler(result, path82);
|
|
41778
41803
|
}
|
|
41779
41804
|
if (raw !== "##" && raw !== "!!") {
|
|
41780
|
-
result.files.push(new FileStatusSummary(
|
|
41805
|
+
result.files.push(new FileStatusSummary(path82, index, workingDir));
|
|
41781
41806
|
}
|
|
41782
41807
|
}
|
|
41783
41808
|
}
|
|
@@ -42086,9 +42111,9 @@ var init_simple_git_api = __esm2({
|
|
|
42086
42111
|
next
|
|
42087
42112
|
);
|
|
42088
42113
|
}
|
|
42089
|
-
hashObject(
|
|
42114
|
+
hashObject(path82, write) {
|
|
42090
42115
|
return this._runTask(
|
|
42091
|
-
hashObjectTask(
|
|
42116
|
+
hashObjectTask(path82, write === true),
|
|
42092
42117
|
trailingFunctionArgument(arguments)
|
|
42093
42118
|
);
|
|
42094
42119
|
}
|
|
@@ -42441,8 +42466,8 @@ var init_branch = __esm2({
|
|
|
42441
42466
|
}
|
|
42442
42467
|
});
|
|
42443
42468
|
function toPath(input) {
|
|
42444
|
-
const
|
|
42445
|
-
return
|
|
42469
|
+
const path82 = input.trim().replace(/^["']|["']$/g, "");
|
|
42470
|
+
return path82 && normalize3(path82);
|
|
42446
42471
|
}
|
|
42447
42472
|
var parseCheckIgnore;
|
|
42448
42473
|
var init_CheckIgnore = __esm2({
|
|
@@ -42756,8 +42781,8 @@ __export2(sub_module_exports, {
|
|
|
42756
42781
|
subModuleTask: () => subModuleTask,
|
|
42757
42782
|
updateSubModuleTask: () => updateSubModuleTask
|
|
42758
42783
|
});
|
|
42759
|
-
function addSubModuleTask(repo,
|
|
42760
|
-
return subModuleTask(["add", repo,
|
|
42784
|
+
function addSubModuleTask(repo, path82) {
|
|
42785
|
+
return subModuleTask(["add", repo, path82]);
|
|
42761
42786
|
}
|
|
42762
42787
|
function initSubModuleTask(customArgs) {
|
|
42763
42788
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -43090,8 +43115,8 @@ var require_git = __commonJS2({
|
|
|
43090
43115
|
}
|
|
43091
43116
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
43092
43117
|
};
|
|
43093
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
43094
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
43118
|
+
Git2.prototype.submoduleAdd = function(repo, path82, then) {
|
|
43119
|
+
return this._runTask(addSubModuleTask2(repo, path82), trailingFunctionArgument2(arguments));
|
|
43095
43120
|
};
|
|
43096
43121
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
43097
43122
|
return this._runTask(
|
|
@@ -43830,8 +43855,8 @@ function parseNumstatEntries(lines) {
|
|
|
43830
43855
|
}
|
|
43831
43856
|
function parseNumstat(lines) {
|
|
43832
43857
|
const m = /* @__PURE__ */ new Map();
|
|
43833
|
-
for (const [
|
|
43834
|
-
m.set(
|
|
43858
|
+
for (const [path82, entry] of parseNumstatEntries(lines)) {
|
|
43859
|
+
m.set(path82, { additions: entry.additions, deletions: entry.deletions });
|
|
43835
43860
|
}
|
|
43836
43861
|
return m;
|
|
43837
43862
|
}
|
|
@@ -45626,9 +45651,8 @@ function parseSessionParent(v) {
|
|
|
45626
45651
|
return null;
|
|
45627
45652
|
}
|
|
45628
45653
|
|
|
45629
|
-
// src/worktrees/prepare-new-isolated-worktrees.ts
|
|
45630
|
-
import * as
|
|
45631
|
-
import * as path64 from "node:path";
|
|
45654
|
+
// src/worktrees/prepare/prepare-new-isolated-worktrees.ts
|
|
45655
|
+
import * as fs46 from "node:fs";
|
|
45632
45656
|
|
|
45633
45657
|
// src/git/discover-repos.ts
|
|
45634
45658
|
import * as fs43 from "node:fs";
|
|
@@ -45699,6 +45723,10 @@ async function discoverGitReposUnderRoot(rootPath) {
|
|
|
45699
45723
|
return out;
|
|
45700
45724
|
}
|
|
45701
45725
|
|
|
45726
|
+
// src/worktrees/prepare/add-isolated-repo-worktree.ts
|
|
45727
|
+
import * as fs45 from "node:fs";
|
|
45728
|
+
import * as path65 from "node:path";
|
|
45729
|
+
|
|
45702
45730
|
// src/git/worktrees/worktree-add.ts
|
|
45703
45731
|
async function gitWorktreeAddBranch(mainRepoPath, worktreePath, branch, baseRef = "HEAD") {
|
|
45704
45732
|
const mainGit = cliSimpleGit(mainRepoPath);
|
|
@@ -45712,6 +45740,100 @@ async function gitWorktreeAddExistingBranch(mainRepoPath, worktreePath, branch)
|
|
|
45712
45740
|
await mainGit.raw(["worktree", "add", worktreePath, branch]);
|
|
45713
45741
|
}
|
|
45714
45742
|
|
|
45743
|
+
// src/worktrees/prepare/copy-bridge-files-along-worktree-path.ts
|
|
45744
|
+
import * as fs44 from "node:fs";
|
|
45745
|
+
import * as path64 from "node:path";
|
|
45746
|
+
var BRIDGE_FILES_ALONG_WORKTREE_PATH = ["AGENTS.md"];
|
|
45747
|
+
function copyBridgeFilesAlongWorktreePath(options) {
|
|
45748
|
+
const { bridgeRoot, scopeDir, repoPathRelativeToBridgeRoot, log: log2 } = options;
|
|
45749
|
+
const fileNames = options.fileNames ?? BRIDGE_FILES_ALONG_WORKTREE_PATH;
|
|
45750
|
+
if (repoPathRelativeToBridgeRoot === ".") return;
|
|
45751
|
+
const segments = repoPathRelativeToBridgeRoot.split("/").filter(Boolean);
|
|
45752
|
+
for (let i = 0; i < segments.length; i++) {
|
|
45753
|
+
const prefix = segments.slice(0, i).join("/");
|
|
45754
|
+
const bridgeDir = prefix ? path64.join(bridgeRoot, prefix) : bridgeRoot;
|
|
45755
|
+
const destDir = prefix ? path64.join(scopeDir, prefix) : scopeDir;
|
|
45756
|
+
for (const fileName of fileNames) {
|
|
45757
|
+
copyFileIfPresent(bridgeDir, destDir, fileName, log2);
|
|
45758
|
+
}
|
|
45759
|
+
}
|
|
45760
|
+
}
|
|
45761
|
+
function copyFileIfPresent(srcDir, destDir, fileName, log2) {
|
|
45762
|
+
const src = path64.join(srcDir, fileName);
|
|
45763
|
+
if (!fs44.existsSync(src)) return;
|
|
45764
|
+
const dest = path64.join(destDir, fileName);
|
|
45765
|
+
try {
|
|
45766
|
+
fs44.copyFileSync(src, dest);
|
|
45767
|
+
log2?.(`[worktrees] Copied ${fileName} to ${dest}`);
|
|
45768
|
+
} catch (e) {
|
|
45769
|
+
log2?.(
|
|
45770
|
+
`[worktrees] Failed to copy ${fileName} to ${dest}: ${e instanceof Error ? e.message : String(e)}`
|
|
45771
|
+
);
|
|
45772
|
+
}
|
|
45773
|
+
}
|
|
45774
|
+
|
|
45775
|
+
// src/worktrees/prepare/resolve-base-ref-for-repo.ts
|
|
45776
|
+
function resolveBaseRefForRepo(repoPathRelativeToBridgeRoot, baseBranches) {
|
|
45777
|
+
if (!baseBranches) return "HEAD";
|
|
45778
|
+
const direct = baseBranches[repoPathRelativeToBridgeRoot]?.trim();
|
|
45779
|
+
if (direct) return direct;
|
|
45780
|
+
if (repoPathRelativeToBridgeRoot !== "." && baseBranches["."]?.trim()) {
|
|
45781
|
+
return baseBranches["."].trim();
|
|
45782
|
+
}
|
|
45783
|
+
return "HEAD";
|
|
45784
|
+
}
|
|
45785
|
+
|
|
45786
|
+
// src/worktrees/prepare/add-isolated-repo-worktree.ts
|
|
45787
|
+
async function addIsolatedRepoWorktree(options) {
|
|
45788
|
+
const {
|
|
45789
|
+
kind,
|
|
45790
|
+
bridgeResolved,
|
|
45791
|
+
scopeDir,
|
|
45792
|
+
repoAbsolutePath,
|
|
45793
|
+
branch,
|
|
45794
|
+
existingBranch,
|
|
45795
|
+
worktreeBaseBranches,
|
|
45796
|
+
log: log2
|
|
45797
|
+
} = options;
|
|
45798
|
+
const repoPathRelativeToBridgeRootRaw = path65.relative(bridgeResolved, repoAbsolutePath);
|
|
45799
|
+
if (repoPathRelativeToBridgeRootRaw.startsWith("..") || path65.isAbsolute(repoPathRelativeToBridgeRootRaw)) {
|
|
45800
|
+
return null;
|
|
45801
|
+
}
|
|
45802
|
+
const repoPathRelativeToBridgeRoot = normalizeRepoPathRelativeToWorkspaceRoot(
|
|
45803
|
+
repoPathRelativeToBridgeRootRaw === "" ? "." : repoPathRelativeToBridgeRootRaw
|
|
45804
|
+
);
|
|
45805
|
+
const worktreePath = repoPathRelativeToBridgeRoot === "." ? scopeDir : path65.join(scopeDir, repoPathRelativeToBridgeRoot);
|
|
45806
|
+
if (repoPathRelativeToBridgeRoot !== ".") {
|
|
45807
|
+
fs45.mkdirSync(path65.dirname(worktreePath), { recursive: true });
|
|
45808
|
+
copyBridgeFilesAlongWorktreePath({
|
|
45809
|
+
bridgeRoot: bridgeResolved,
|
|
45810
|
+
scopeDir,
|
|
45811
|
+
repoPathRelativeToBridgeRoot,
|
|
45812
|
+
log: log2
|
|
45813
|
+
});
|
|
45814
|
+
}
|
|
45815
|
+
const checkoutBranch = existingBranch?.trim() || branch;
|
|
45816
|
+
try {
|
|
45817
|
+
if (existingBranch?.trim()) {
|
|
45818
|
+
await gitWorktreeAddExistingBranch(repoAbsolutePath, worktreePath, checkoutBranch);
|
|
45819
|
+
log2(`[worktrees] Added ${kind} worktree ${worktreePath} (existing branch ${checkoutBranch}).`);
|
|
45820
|
+
} else {
|
|
45821
|
+
const baseRef = resolveBaseRefForRepo(repoPathRelativeToBridgeRoot, worktreeBaseBranches);
|
|
45822
|
+
await gitWorktreeAddBranch(repoAbsolutePath, worktreePath, branch, baseRef);
|
|
45823
|
+
log2(`[worktrees] Added ${kind} worktree ${worktreePath} (branch ${branch}, base ${baseRef}).`);
|
|
45824
|
+
}
|
|
45825
|
+
return worktreePath;
|
|
45826
|
+
} catch (e) {
|
|
45827
|
+
log2(
|
|
45828
|
+
`[worktrees] Worktree add failed for ${repoAbsolutePath}: ${e instanceof Error ? e.message : String(e)}`
|
|
45829
|
+
);
|
|
45830
|
+
return null;
|
|
45831
|
+
}
|
|
45832
|
+
}
|
|
45833
|
+
|
|
45834
|
+
// src/worktrees/prepare/resolve-isolated-scope-dir.ts
|
|
45835
|
+
import * as path66 from "node:path";
|
|
45836
|
+
|
|
45715
45837
|
// src/worktrees/worktree-layout-kind.ts
|
|
45716
45838
|
function sanitizeWorktreeBranchSegment(value) {
|
|
45717
45839
|
return value.replace(/[^a-zA-Z0-9/_-]+/g, "-").slice(0, 80) || "worktree";
|
|
@@ -45738,16 +45860,16 @@ function previewDeployBranchName(environmentId) {
|
|
|
45738
45860
|
return `preview-deploy-${sanitizeWorktreeBranchSegment(environmentId.trim())}`;
|
|
45739
45861
|
}
|
|
45740
45862
|
|
|
45741
|
-
// src/worktrees/prepare-
|
|
45742
|
-
function
|
|
45743
|
-
|
|
45744
|
-
const
|
|
45745
|
-
|
|
45746
|
-
|
|
45747
|
-
|
|
45748
|
-
}
|
|
45749
|
-
return "HEAD";
|
|
45863
|
+
// src/worktrees/prepare/resolve-isolated-scope-dir.ts
|
|
45864
|
+
function resolveIsolatedScopeDir(options) {
|
|
45865
|
+
const bridgeResolved = path66.resolve(options.bridgeRoot);
|
|
45866
|
+
const cwdKey = allocateDirNameForLauncherCwd(options.layout, bridgeResolved);
|
|
45867
|
+
const bridgeKeyDir = path66.join(options.worktreesRootPath, cwdKey);
|
|
45868
|
+
const scopeDir = path66.join(bridgeKeyDir, ...layoutDirSegments(options.kind, options.scopeId));
|
|
45869
|
+
return { bridgeResolved, scopeDir };
|
|
45750
45870
|
}
|
|
45871
|
+
|
|
45872
|
+
// src/worktrees/prepare/prepare-new-isolated-worktrees.ts
|
|
45751
45873
|
async function prepareNewIsolatedWorktrees(options) {
|
|
45752
45874
|
const {
|
|
45753
45875
|
kind,
|
|
@@ -45760,45 +45882,32 @@ async function prepareNewIsolatedWorktrees(options) {
|
|
|
45760
45882
|
worktreeBaseBranches,
|
|
45761
45883
|
existingBranch
|
|
45762
45884
|
} = options;
|
|
45763
|
-
const bridgeResolved =
|
|
45764
|
-
|
|
45765
|
-
|
|
45766
|
-
|
|
45885
|
+
const { bridgeResolved, scopeDir } = resolveIsolatedScopeDir({
|
|
45886
|
+
worktreesRootPath,
|
|
45887
|
+
bridgeRoot,
|
|
45888
|
+
kind,
|
|
45889
|
+
scopeId,
|
|
45890
|
+
layout
|
|
45891
|
+
});
|
|
45767
45892
|
const repos = await discoverGitReposUnderRoot(bridgeResolved);
|
|
45768
45893
|
if (repos.length === 0) {
|
|
45769
45894
|
log2(`[worktrees] No Git repositories under bridge root; skipping ${kind} worktree creation.`);
|
|
45770
45895
|
return null;
|
|
45771
45896
|
}
|
|
45772
45897
|
const worktreePaths = [];
|
|
45773
|
-
|
|
45898
|
+
fs46.mkdirSync(scopeDir, { recursive: true });
|
|
45774
45899
|
await forEachWithGitYield(repos, async (repo) => {
|
|
45775
|
-
const
|
|
45776
|
-
|
|
45777
|
-
|
|
45778
|
-
|
|
45779
|
-
|
|
45780
|
-
|
|
45781
|
-
|
|
45782
|
-
|
|
45783
|
-
|
|
45784
|
-
|
|
45785
|
-
|
|
45786
|
-
const checkoutBranch = existingBranch?.trim() || branch;
|
|
45787
|
-
try {
|
|
45788
|
-
if (existingBranch?.trim()) {
|
|
45789
|
-
await gitWorktreeAddExistingBranch(repo.absolutePath, worktreePath, checkoutBranch);
|
|
45790
|
-
log2(`[worktrees] Added ${kind} worktree ${worktreePath} (existing branch ${checkoutBranch}).`);
|
|
45791
|
-
} else {
|
|
45792
|
-
const baseRef = resolveBaseRefForRepo(repoPathRelativeToBridgeRoot, worktreeBaseBranches);
|
|
45793
|
-
await gitWorktreeAddBranch(repo.absolutePath, worktreePath, branch, baseRef);
|
|
45794
|
-
log2(`[worktrees] Added ${kind} worktree ${worktreePath} (branch ${branch}, base ${baseRef}).`);
|
|
45795
|
-
}
|
|
45796
|
-
worktreePaths.push(worktreePath);
|
|
45797
|
-
} catch (e) {
|
|
45798
|
-
log2(
|
|
45799
|
-
`[worktrees] Worktree add failed for ${repo.absolutePath}: ${e instanceof Error ? e.message : String(e)}`
|
|
45800
|
-
);
|
|
45801
|
-
}
|
|
45900
|
+
const worktreePath = await addIsolatedRepoWorktree({
|
|
45901
|
+
kind,
|
|
45902
|
+
bridgeResolved,
|
|
45903
|
+
scopeDir,
|
|
45904
|
+
repoAbsolutePath: repo.absolutePath,
|
|
45905
|
+
branch,
|
|
45906
|
+
existingBranch,
|
|
45907
|
+
worktreeBaseBranches,
|
|
45908
|
+
log: log2
|
|
45909
|
+
});
|
|
45910
|
+
if (worktreePath) worktreePaths.push(worktreePath);
|
|
45802
45911
|
});
|
|
45803
45912
|
if (worktreePaths.length === 0) return null;
|
|
45804
45913
|
return {
|
|
@@ -45858,10 +45967,10 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
|
|
|
45858
45967
|
}
|
|
45859
45968
|
|
|
45860
45969
|
// src/worktrees/manager/resolve-explicit-session-parent-path.ts
|
|
45861
|
-
import * as
|
|
45970
|
+
import * as path67 from "node:path";
|
|
45862
45971
|
init_yield_to_event_loop();
|
|
45863
45972
|
async function resolveExplicitSessionParentPath(params) {
|
|
45864
|
-
const resolved =
|
|
45973
|
+
const resolved = path67.resolve(params.parentPathRaw);
|
|
45865
45974
|
if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
|
|
45866
45975
|
return resolved;
|
|
45867
45976
|
}
|
|
@@ -45878,7 +45987,7 @@ async function resolveExplicitSessionParentPath(params) {
|
|
|
45878
45987
|
await yieldToEventLoop();
|
|
45879
45988
|
const tryRoot = await discoverSessionWorktreesUnderSessionWorktreeRoot(cur, params.sessionId);
|
|
45880
45989
|
if (tryRoot) return rememberAndReturn(tryRoot);
|
|
45881
|
-
const next =
|
|
45990
|
+
const next = path67.dirname(cur);
|
|
45882
45991
|
if (next === cur) break;
|
|
45883
45992
|
cur = next;
|
|
45884
45993
|
}
|
|
@@ -46026,15 +46135,15 @@ var SessionWorktreeManager = class {
|
|
|
46026
46135
|
};
|
|
46027
46136
|
|
|
46028
46137
|
// src/worktrees/discovery/discover-preview-worktree-on-disk.ts
|
|
46029
|
-
import * as
|
|
46030
|
-
import * as
|
|
46138
|
+
import * as fs47 from "node:fs";
|
|
46139
|
+
import * as path68 from "node:path";
|
|
46031
46140
|
init_yield_to_event_loop();
|
|
46032
46141
|
async function discoverPreviewWorktreeOnDisk(options) {
|
|
46033
46142
|
const { environmentId, worktreesRootPath, layout, bridgeRoot } = options;
|
|
46034
46143
|
const eid = environmentId.trim();
|
|
46035
46144
|
if (!eid) return null;
|
|
46036
46145
|
try {
|
|
46037
|
-
await
|
|
46146
|
+
await fs47.promises.access(worktreesRootPath);
|
|
46038
46147
|
} catch {
|
|
46039
46148
|
return null;
|
|
46040
46149
|
}
|
|
@@ -46043,13 +46152,13 @@ async function discoverPreviewWorktreeOnDisk(options) {
|
|
|
46043
46152
|
if (preferredKey) keysOnDisk.push(preferredKey);
|
|
46044
46153
|
const scanState = { entries: 0 };
|
|
46045
46154
|
try {
|
|
46046
|
-
for (const name of await
|
|
46155
|
+
for (const name of await fs47.promises.readdir(worktreesRootPath)) {
|
|
46047
46156
|
if (!await yieldDuringDiskWalk(scanState)) break;
|
|
46048
46157
|
if (name.startsWith(".")) continue;
|
|
46049
|
-
const p =
|
|
46158
|
+
const p = path68.join(worktreesRootPath, name);
|
|
46050
46159
|
let st;
|
|
46051
46160
|
try {
|
|
46052
|
-
st = await
|
|
46161
|
+
st = await fs47.promises.stat(p);
|
|
46053
46162
|
} catch {
|
|
46054
46163
|
continue;
|
|
46055
46164
|
}
|
|
@@ -46063,7 +46172,7 @@ async function discoverPreviewWorktreeOnDisk(options) {
|
|
|
46063
46172
|
const previewDirRel = layoutDirSegments("preview_environment", eid);
|
|
46064
46173
|
for (const key of keys) {
|
|
46065
46174
|
await yieldToEventLoop();
|
|
46066
|
-
const previewDir =
|
|
46175
|
+
const previewDir = path68.join(worktreesRootPath, key, ...previewDirRel);
|
|
46067
46176
|
const binding = await tryBindingFromIsolatedDirectory(previewDir);
|
|
46068
46177
|
if (binding) return binding;
|
|
46069
46178
|
}
|
|
@@ -46190,7 +46299,7 @@ var PreviewWorktreeManager = class {
|
|
|
46190
46299
|
};
|
|
46191
46300
|
|
|
46192
46301
|
// src/worktrees/deploy/deploy-session-to-preview-environment.ts
|
|
46193
|
-
import * as
|
|
46302
|
+
import * as path72 from "node:path";
|
|
46194
46303
|
|
|
46195
46304
|
// src/git/worktrees/reset-worktree-to-branch.ts
|
|
46196
46305
|
async function gitResetWorktreeToBranch(worktreePath, branch) {
|
|
@@ -46201,8 +46310,8 @@ async function gitResetWorktreeToBranch(worktreePath, branch) {
|
|
|
46201
46310
|
}
|
|
46202
46311
|
|
|
46203
46312
|
// src/worktrees/deploy/capture-and-apply-wip.ts
|
|
46204
|
-
import * as
|
|
46205
|
-
import * as
|
|
46313
|
+
import * as fs48 from "node:fs";
|
|
46314
|
+
import * as path69 from "node:path";
|
|
46206
46315
|
|
|
46207
46316
|
// src/git/snapshot/git.ts
|
|
46208
46317
|
async function gitStashCreate(repoRoot, log2) {
|
|
@@ -46250,12 +46359,12 @@ async function applyWorkingTreeWip(targetRepoPath, sourceRepoPath, wip, log2) {
|
|
|
46250
46359
|
if (!ap.ok) return ap;
|
|
46251
46360
|
}
|
|
46252
46361
|
await forEachWithGitYield(wip.untrackedPaths, async (rel) => {
|
|
46253
|
-
const src =
|
|
46254
|
-
const dst =
|
|
46362
|
+
const src = path69.join(sourceRepoPath, rel);
|
|
46363
|
+
const dst = path69.join(targetRepoPath, rel);
|
|
46255
46364
|
try {
|
|
46256
|
-
if (!
|
|
46257
|
-
|
|
46258
|
-
|
|
46365
|
+
if (!fs48.existsSync(src)) return;
|
|
46366
|
+
fs48.mkdirSync(path69.dirname(dst), { recursive: true });
|
|
46367
|
+
fs48.copyFileSync(src, dst);
|
|
46259
46368
|
} catch (e) {
|
|
46260
46369
|
log2(
|
|
46261
46370
|
`[worktrees] Failed to copy untracked ${rel}: ${e instanceof Error ? e.message : String(e)}`
|
|
@@ -46266,14 +46375,14 @@ async function applyWorkingTreeWip(targetRepoPath, sourceRepoPath, wip, log2) {
|
|
|
46266
46375
|
}
|
|
46267
46376
|
|
|
46268
46377
|
// src/worktrees/deploy/resolve-isolated-checkout-for-repo-path-relative-to-workspace-root.ts
|
|
46269
|
-
import * as
|
|
46378
|
+
import * as path70 from "node:path";
|
|
46270
46379
|
async function resolveIsolatedCheckoutForRepoPathRelativeToWorkspaceRoot(options) {
|
|
46271
46380
|
const { checkoutPaths, sessionParentPath, bridgeRoot, repoPathRelativeToWorkspaceRoot } = options;
|
|
46272
|
-
const resolvedSessionParentPath = sessionParentPath ?
|
|
46381
|
+
const resolvedSessionParentPath = sessionParentPath ? path70.resolve(sessionParentPath) : null;
|
|
46273
46382
|
let match = null;
|
|
46274
46383
|
await forEachWithGitYield(checkoutPaths, async (checkoutPath) => {
|
|
46275
46384
|
if (match) return;
|
|
46276
|
-
const resolvedCheckoutPath =
|
|
46385
|
+
const resolvedCheckoutPath = path70.resolve(checkoutPath);
|
|
46277
46386
|
if (!await isGitRepoDirectory(resolvedCheckoutPath)) return;
|
|
46278
46387
|
const resolvedRepoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
|
|
46279
46388
|
checkoutPath: resolvedCheckoutPath,
|
|
@@ -46327,7 +46436,7 @@ async function applySessionWipToPreviewCheckouts(options) {
|
|
|
46327
46436
|
}
|
|
46328
46437
|
|
|
46329
46438
|
// src/worktrees/deploy/collect-session-repo-deploy-states.ts
|
|
46330
|
-
import * as
|
|
46439
|
+
import * as path71 from "node:path";
|
|
46331
46440
|
|
|
46332
46441
|
// src/git/branches/create-or-update-branch.ts
|
|
46333
46442
|
async function gitCreateOrUpdateBranch(repoPath, branch, startRef, options) {
|
|
@@ -46364,19 +46473,19 @@ async function collectSessionRepoDeployStates(options) {
|
|
|
46364
46473
|
const sessionParentPath = sessionWorktreeManager.getSessionParentPath(sid);
|
|
46365
46474
|
const states = [];
|
|
46366
46475
|
await forEachWithGitYield(sessionTargets, async (sessionCheckout) => {
|
|
46367
|
-
const checkoutPath =
|
|
46476
|
+
const checkoutPath = path71.resolve(sessionCheckout);
|
|
46368
46477
|
if (!await isGitRepoDirectory(checkoutPath)) return;
|
|
46369
46478
|
const repoPathRelativeToWorkspaceRoot = await resolveRepoPathRelativeToWorkspaceRoot({
|
|
46370
46479
|
checkoutPath,
|
|
46371
46480
|
bridgeRoot,
|
|
46372
|
-
sessionParentPath: sessionParentPath ?
|
|
46481
|
+
sessionParentPath: sessionParentPath ? path71.resolve(sessionParentPath) : null
|
|
46373
46482
|
});
|
|
46374
46483
|
if (!repoPathRelativeToWorkspaceRoot) return;
|
|
46375
46484
|
const mainRepoPath = resolveMainRepoPath(checkoutPath);
|
|
46376
46485
|
const headSha = (await cliSimpleGit(checkoutPath).revparse(["HEAD"])).trim();
|
|
46377
46486
|
const previewCheckout = previewCheckoutPaths.length > 0 ? await resolveIsolatedCheckoutForRepoPathRelativeToWorkspaceRoot({
|
|
46378
46487
|
checkoutPaths: previewCheckoutPaths,
|
|
46379
|
-
sessionParentPath: previewParentPath ?
|
|
46488
|
+
sessionParentPath: previewParentPath ? path71.resolve(previewParentPath) : null,
|
|
46380
46489
|
bridgeRoot,
|
|
46381
46490
|
repoPathRelativeToWorkspaceRoot
|
|
46382
46491
|
}) : null;
|
|
@@ -46396,7 +46505,7 @@ async function deploySessionToPreviewEnvironment(options) {
|
|
|
46396
46505
|
const eid = options.environmentId.trim();
|
|
46397
46506
|
if (!sid || !eid) return { ok: false, error: "sessionId and environmentId are required" };
|
|
46398
46507
|
const deployBranch = previewDeployBranchName(eid);
|
|
46399
|
-
const bridgeRoot =
|
|
46508
|
+
const bridgeRoot = path72.resolve(getBridgeRoot());
|
|
46400
46509
|
await previewWorktreeManager.ensureCached(eid);
|
|
46401
46510
|
const existingPreviewParentPath = previewWorktreeManager.getPreviewParentPath(eid) ?? null;
|
|
46402
46511
|
const existingPreviewCheckoutPaths = previewWorktreeManager.getRepoCheckoutPaths(eid) ?? [];
|
|
@@ -46436,10 +46545,10 @@ async function deploySessionToPreviewEnvironment(options) {
|
|
|
46436
46545
|
}
|
|
46437
46546
|
|
|
46438
46547
|
// src/worktrees/manager/default-worktrees-root-path.ts
|
|
46439
|
-
import * as
|
|
46548
|
+
import * as path73 from "node:path";
|
|
46440
46549
|
import os9 from "node:os";
|
|
46441
46550
|
function defaultWorktreesRootPath() {
|
|
46442
|
-
return
|
|
46551
|
+
return path73.join(os9.homedir(), ".buildautomaton", "worktrees");
|
|
46443
46552
|
}
|
|
46444
46553
|
|
|
46445
46554
|
// src/connection/create-bridge-worktree-managers.ts
|
|
@@ -46569,14 +46678,14 @@ function assertBridgeWorkspace(ctx) {
|
|
|
46569
46678
|
}
|
|
46570
46679
|
|
|
46571
46680
|
// src/files/list-dir/index.ts
|
|
46572
|
-
import
|
|
46681
|
+
import fs50 from "node:fs";
|
|
46573
46682
|
|
|
46574
46683
|
// src/files/ensure-under-cwd.ts
|
|
46575
|
-
import
|
|
46684
|
+
import path74 from "node:path";
|
|
46576
46685
|
function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
46577
|
-
const normalized =
|
|
46578
|
-
const resolved =
|
|
46579
|
-
if (!resolved.startsWith(cwd +
|
|
46686
|
+
const normalized = path74.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
46687
|
+
const resolved = path74.resolve(cwd, normalized);
|
|
46688
|
+
if (!resolved.startsWith(cwd + path74.sep) && resolved !== cwd) {
|
|
46580
46689
|
return null;
|
|
46581
46690
|
}
|
|
46582
46691
|
return resolved;
|
|
@@ -46589,15 +46698,15 @@ init_yield_to_event_loop();
|
|
|
46589
46698
|
var LIST_DIR_YIELD_EVERY = 256;
|
|
46590
46699
|
|
|
46591
46700
|
// src/files/list-dir/map-dir-entry.ts
|
|
46592
|
-
import
|
|
46593
|
-
import
|
|
46701
|
+
import path75 from "node:path";
|
|
46702
|
+
import fs49 from "node:fs";
|
|
46594
46703
|
async function mapDirEntry(d, relativePath, resolved) {
|
|
46595
|
-
const entryPath =
|
|
46596
|
-
const fullPath =
|
|
46704
|
+
const entryPath = path75.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
46705
|
+
const fullPath = path75.join(resolved, d.name);
|
|
46597
46706
|
let isDir = d.isDirectory();
|
|
46598
46707
|
if (d.isSymbolicLink()) {
|
|
46599
46708
|
try {
|
|
46600
|
-
const targetStat = await
|
|
46709
|
+
const targetStat = await fs49.promises.stat(fullPath);
|
|
46601
46710
|
isDir = targetStat.isDirectory();
|
|
46602
46711
|
} catch {
|
|
46603
46712
|
isDir = false;
|
|
@@ -46627,7 +46736,7 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
|
46627
46736
|
return { error: "Path is outside working directory" };
|
|
46628
46737
|
}
|
|
46629
46738
|
try {
|
|
46630
|
-
const names = await
|
|
46739
|
+
const names = await fs50.promises.readdir(resolved, { withFileTypes: true });
|
|
46631
46740
|
const entries = [];
|
|
46632
46741
|
for (let i = 0; i < names.length; i++) {
|
|
46633
46742
|
if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
|
|
@@ -46643,13 +46752,13 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
|
46643
46752
|
}
|
|
46644
46753
|
|
|
46645
46754
|
// src/git/tree/resolve-repo-abs-path.ts
|
|
46646
|
-
import * as
|
|
46755
|
+
import * as path76 from "node:path";
|
|
46647
46756
|
function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
46648
|
-
const bridgeResolved =
|
|
46757
|
+
const bridgeResolved = path76.resolve(bridgeRoot);
|
|
46649
46758
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
46650
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
46651
|
-
const resolved =
|
|
46652
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
46759
|
+
const repoPath = rel === "" ? bridgeResolved : path76.join(bridgeResolved, rel);
|
|
46760
|
+
const resolved = path76.resolve(repoPath);
|
|
46761
|
+
if (!resolved.startsWith(bridgeResolved + path76.sep) && resolved !== bridgeResolved) {
|
|
46653
46762
|
return null;
|
|
46654
46763
|
}
|
|
46655
46764
|
return resolved;
|
|
@@ -47130,25 +47239,25 @@ async function GET2(ctx) {
|
|
|
47130
47239
|
init_in_flight();
|
|
47131
47240
|
|
|
47132
47241
|
// src/files/read/read-file-async.ts
|
|
47133
|
-
import
|
|
47242
|
+
import fs56 from "node:fs";
|
|
47134
47243
|
init_yield_to_event_loop();
|
|
47135
47244
|
|
|
47136
47245
|
// src/files/read/resolve-file-cache.ts
|
|
47137
|
-
import
|
|
47138
|
-
import
|
|
47246
|
+
import fs51 from "node:fs";
|
|
47247
|
+
import path77 from "node:path";
|
|
47139
47248
|
var RESOLVE_CACHE_MAX = 4096;
|
|
47140
47249
|
var resolveCache = /* @__PURE__ */ new Map();
|
|
47141
47250
|
function resolveCacheKey(sessionParentPath, relativePath) {
|
|
47142
47251
|
return `${sessionParentPath}\0${relativePath}`;
|
|
47143
47252
|
}
|
|
47144
47253
|
function pathStaysUnderParent(filePath, sessionParentPath) {
|
|
47145
|
-
const parent =
|
|
47146
|
-
const resolved =
|
|
47147
|
-
return resolved === parent || resolved.startsWith(`${parent}${
|
|
47254
|
+
const parent = path77.resolve(sessionParentPath);
|
|
47255
|
+
const resolved = path77.resolve(filePath);
|
|
47256
|
+
return resolved === parent || resolved.startsWith(`${parent}${path77.sep}`);
|
|
47148
47257
|
}
|
|
47149
47258
|
function statMatchesCacheSync(entry) {
|
|
47150
47259
|
try {
|
|
47151
|
-
const stat2 =
|
|
47260
|
+
const stat2 = fs51.statSync(entry.path);
|
|
47152
47261
|
return stat2.isFile() && stat2.mtimeMs === entry.mtimeMs && stat2.size === entry.size;
|
|
47153
47262
|
} catch {
|
|
47154
47263
|
return false;
|
|
@@ -47181,7 +47290,7 @@ function joinInflightResolve(cacheKey, factory) {
|
|
|
47181
47290
|
}
|
|
47182
47291
|
|
|
47183
47292
|
// src/files/read/resolve-file-for-read-core.ts
|
|
47184
|
-
import
|
|
47293
|
+
import fs52 from "node:fs";
|
|
47185
47294
|
import { isMainThread as isMainThread4 } from "node:worker_threads";
|
|
47186
47295
|
function resolveFileForReadImplSync(relativePath, sessionParentPath) {
|
|
47187
47296
|
const cacheKey = resolveCacheKey(sessionParentPath, relativePath);
|
|
@@ -47191,13 +47300,13 @@ function resolveFileForReadImplSync(relativePath, sessionParentPath) {
|
|
|
47191
47300
|
let size;
|
|
47192
47301
|
let mtimeMs;
|
|
47193
47302
|
try {
|
|
47194
|
-
const lstat =
|
|
47303
|
+
const lstat = fs52.lstatSync(resolved);
|
|
47195
47304
|
if (lstat.isSymbolicLink()) {
|
|
47196
|
-
real =
|
|
47305
|
+
real = fs52.realpathSync(resolved);
|
|
47197
47306
|
if (!pathStaysUnderParent(real, sessionParentPath)) {
|
|
47198
47307
|
return { error: "Path is outside working directory" };
|
|
47199
47308
|
}
|
|
47200
|
-
const stat2 =
|
|
47309
|
+
const stat2 = fs52.statSync(real);
|
|
47201
47310
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
47202
47311
|
size = stat2.size;
|
|
47203
47312
|
mtimeMs = stat2.mtimeMs;
|
|
@@ -47225,13 +47334,13 @@ async function resolveFileForReadImpl(relativePath, sessionParentPath) {
|
|
|
47225
47334
|
let size;
|
|
47226
47335
|
let mtimeMs;
|
|
47227
47336
|
try {
|
|
47228
|
-
const lstat = await
|
|
47337
|
+
const lstat = await fs52.promises.lstat(resolved);
|
|
47229
47338
|
if (lstat.isSymbolicLink()) {
|
|
47230
|
-
real = await
|
|
47339
|
+
real = await fs52.promises.realpath(resolved);
|
|
47231
47340
|
if (!pathStaysUnderParent(real, sessionParentPath)) {
|
|
47232
47341
|
return { error: "Path is outside working directory" };
|
|
47233
47342
|
}
|
|
47234
|
-
const stat2 = await
|
|
47343
|
+
const stat2 = await fs52.promises.stat(real);
|
|
47235
47344
|
if (!stat2.isFile()) return { error: "Not a file" };
|
|
47236
47345
|
size = stat2.size;
|
|
47237
47346
|
mtimeMs = stat2.mtimeMs;
|
|
@@ -47280,7 +47389,7 @@ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeR
|
|
|
47280
47389
|
|
|
47281
47390
|
// src/files/read/read-file-range-async.ts
|
|
47282
47391
|
init_yield_to_event_loop();
|
|
47283
|
-
import
|
|
47392
|
+
import fs53 from "node:fs";
|
|
47284
47393
|
import { StringDecoder as StringDecoder2 } from "node:string_decoder";
|
|
47285
47394
|
|
|
47286
47395
|
// src/files/read/read-file-range-line-zero.ts
|
|
@@ -47394,8 +47503,8 @@ function finishLineZeroTail(state, tail, resultLines, fileSize, lineChunkSize, l
|
|
|
47394
47503
|
|
|
47395
47504
|
// src/files/read/read-file-range-async.ts
|
|
47396
47505
|
async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE, fileSizeIn) {
|
|
47397
|
-
const fileSize = fileSizeIn ?? (await
|
|
47398
|
-
const fd = await
|
|
47506
|
+
const fileSize = fileSizeIn ?? (await fs53.promises.stat(filePath)).size;
|
|
47507
|
+
const fd = await fs53.promises.open(filePath, "r");
|
|
47399
47508
|
const bufSize = 64 * 1024;
|
|
47400
47509
|
const buf = Buffer.alloc(bufSize);
|
|
47401
47510
|
const decoder = new StringDecoder2("utf8");
|
|
@@ -47496,7 +47605,7 @@ async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, li
|
|
|
47496
47605
|
}
|
|
47497
47606
|
|
|
47498
47607
|
// src/files/read/read-small-file-range-async.ts
|
|
47499
|
-
import
|
|
47608
|
+
import fs54 from "node:fs";
|
|
47500
47609
|
import { isMainThread as isMainThread5 } from "node:worker_threads";
|
|
47501
47610
|
var SMALL_FILE_RANGE_MAX_BYTES = 512 * 1024;
|
|
47502
47611
|
function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize) {
|
|
@@ -47526,7 +47635,7 @@ function sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize,
|
|
|
47526
47635
|
};
|
|
47527
47636
|
}
|
|
47528
47637
|
function readSmallFileRangeSync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
47529
|
-
const raw =
|
|
47638
|
+
const raw = fs54.readFileSync(filePath, "utf8");
|
|
47530
47639
|
const lines = raw.split(/\r?\n/);
|
|
47531
47640
|
return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
|
|
47532
47641
|
}
|
|
@@ -47534,28 +47643,28 @@ async function readSmallFileRangeAsync(filePath, fileSize, startLine, endLine, l
|
|
|
47534
47643
|
if (isMainThread5) {
|
|
47535
47644
|
return readSmallFileRangeSync(filePath, fileSize, startLine, endLine, lineOffsetIn, lineChunkSize);
|
|
47536
47645
|
}
|
|
47537
|
-
const raw = await
|
|
47646
|
+
const raw = await fs54.promises.readFile(filePath, "utf8");
|
|
47538
47647
|
const lines = raw.split(/\r?\n/);
|
|
47539
47648
|
return sliceLineRange(lines, startLine, endLine, lineOffsetIn, lineChunkSize, fileSize);
|
|
47540
47649
|
}
|
|
47541
47650
|
|
|
47542
47651
|
// src/files/read/read-file-buffer-full-async.ts
|
|
47543
47652
|
init_yield_to_event_loop();
|
|
47544
|
-
import
|
|
47653
|
+
import fs55 from "node:fs";
|
|
47545
47654
|
import { isMainThread as isMainThread6 } from "node:worker_threads";
|
|
47546
47655
|
var READ_CHUNK_BYTES = 256 * 1024;
|
|
47547
47656
|
var MAIN_THREAD_SYNC_READ_MAX_BYTES = 512 * 1024;
|
|
47548
47657
|
async function readFileBufferFullAsync(filePath, knownSize) {
|
|
47549
47658
|
if (isMainThread6) {
|
|
47550
|
-
const size2 = knownSize ??
|
|
47659
|
+
const size2 = knownSize ?? fs55.statSync(filePath).size;
|
|
47551
47660
|
if (size2 <= MAIN_THREAD_SYNC_READ_MAX_BYTES) {
|
|
47552
47661
|
await yieldToEventLoop();
|
|
47553
|
-
const buffer =
|
|
47662
|
+
const buffer = fs55.readFileSync(filePath);
|
|
47554
47663
|
return { buffer, size: buffer.length };
|
|
47555
47664
|
}
|
|
47556
47665
|
}
|
|
47557
|
-
const size = knownSize ?? (await
|
|
47558
|
-
const fd = await
|
|
47666
|
+
const size = knownSize ?? (await fs55.promises.stat(filePath)).size;
|
|
47667
|
+
const fd = await fs55.promises.open(filePath, "r");
|
|
47559
47668
|
const chunks = [];
|
|
47560
47669
|
let position = 0;
|
|
47561
47670
|
let bytesSinceYield = 0;
|
|
@@ -47658,7 +47767,7 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
|
|
|
47658
47767
|
}
|
|
47659
47768
|
if (hasRange) {
|
|
47660
47769
|
if (fileSize == null) {
|
|
47661
|
-
const stat2 = await
|
|
47770
|
+
const stat2 = await fs56.promises.stat(resolvedPath);
|
|
47662
47771
|
fileSize = stat2.size;
|
|
47663
47772
|
}
|
|
47664
47773
|
const read2 = fileSize <= SMALL_FILE_RANGE_MAX_BYTES ? await readSmallFileRangeAsync(
|
|
@@ -47956,12 +48065,12 @@ function parseOptionalInt2(raw) {
|
|
|
47956
48065
|
return Number.isInteger(parsed) ? parsed : void 0;
|
|
47957
48066
|
}
|
|
47958
48067
|
function parseCodeNavParams(url2) {
|
|
47959
|
-
const
|
|
48068
|
+
const path82 = url2.searchParams.get("path") ?? "";
|
|
47960
48069
|
const opRaw = url2.searchParams.get("op")?.trim();
|
|
47961
48070
|
const op = opRaw === "references" ? "references" : opRaw === "symbols" ? "symbols" : opRaw === "definitions" ? "definitions" : "definition";
|
|
47962
48071
|
const line = parseOptionalInt2(url2.searchParams.get("line")) ?? 1;
|
|
47963
48072
|
const column = parseOptionalInt2(url2.searchParams.get("column")) ?? 0;
|
|
47964
|
-
return { path:
|
|
48073
|
+
return { path: path82, op, line, column };
|
|
47965
48074
|
}
|
|
47966
48075
|
function parseCodeNavPath(url2) {
|
|
47967
48076
|
const raw = url2.searchParams.get("path")?.trim();
|
|
@@ -48149,12 +48258,6 @@ function listenOnPort(server, port) {
|
|
|
48149
48258
|
});
|
|
48150
48259
|
});
|
|
48151
48260
|
}
|
|
48152
|
-
function closeServer(server) {
|
|
48153
|
-
if (!server) return Promise.resolve();
|
|
48154
|
-
return new Promise((resolve35, reject) => {
|
|
48155
|
-
server.close((err) => err ? reject(err) : resolve35());
|
|
48156
|
-
});
|
|
48157
|
-
}
|
|
48158
48261
|
function delay3(ms) {
|
|
48159
48262
|
return new Promise((resolve35) => setTimeout(resolve35, ms));
|
|
48160
48263
|
}
|
|
@@ -48179,8 +48282,7 @@ function startLocalShortcutServer(ctx) {
|
|
|
48179
48282
|
if (restartAttempts >= MAX_RESTART_ATTEMPTS) return;
|
|
48180
48283
|
restartAttempts += 1;
|
|
48181
48284
|
restarting = (async () => {
|
|
48182
|
-
await
|
|
48183
|
-
});
|
|
48285
|
+
await closeHttpServer(currentServer);
|
|
48184
48286
|
currentServer = null;
|
|
48185
48287
|
if (closed) return;
|
|
48186
48288
|
await delay3(RESTART_DELAY_MS);
|
|
@@ -48200,7 +48302,7 @@ function startLocalShortcutServer(ctx) {
|
|
|
48200
48302
|
token: ctx.token,
|
|
48201
48303
|
close: async () => {
|
|
48202
48304
|
closed = true;
|
|
48203
|
-
await
|
|
48305
|
+
await closeHttpServer(currentServer);
|
|
48204
48306
|
currentServer = null;
|
|
48205
48307
|
}
|
|
48206
48308
|
}));
|
|
@@ -48353,6 +48455,7 @@ var API_TO_BRIDGE_MESSAGE_TYPES = [
|
|
|
48353
48455
|
"code_nav",
|
|
48354
48456
|
"skill_layout_request",
|
|
48355
48457
|
"install_skills",
|
|
48458
|
+
"install_agent",
|
|
48356
48459
|
"refresh_local_skills",
|
|
48357
48460
|
"bridge_git_context_request",
|
|
48358
48461
|
"list_repo_branches_request"
|
|
@@ -48428,6 +48531,100 @@ var handleBridgeHeartbeatAck = (msg, deps) => {
|
|
|
48428
48531
|
deps.onBridgeHeartbeatAck?.(Math.trunc(raw));
|
|
48429
48532
|
};
|
|
48430
48533
|
|
|
48534
|
+
// src/routing/dispatch/connection.ts
|
|
48535
|
+
function dispatchBridgeConnectionMessage(msg, deps) {
|
|
48536
|
+
switch (msg.type) {
|
|
48537
|
+
case "auth_token":
|
|
48538
|
+
handleAuthToken(msg, deps);
|
|
48539
|
+
break;
|
|
48540
|
+
case "bridge_identified":
|
|
48541
|
+
handleBridgeIdentified(msg, deps);
|
|
48542
|
+
break;
|
|
48543
|
+
case "ha":
|
|
48544
|
+
handleBridgeHeartbeatAck(msg, deps);
|
|
48545
|
+
break;
|
|
48546
|
+
}
|
|
48547
|
+
}
|
|
48548
|
+
|
|
48549
|
+
// src/routing/handlers/preview-environment-control.ts
|
|
48550
|
+
var handlePreviewEnvironmentControl = (msg, deps) => {
|
|
48551
|
+
let wire;
|
|
48552
|
+
try {
|
|
48553
|
+
wire = deps.e2ee ? deps.e2ee.decryptMessage(msg) : msg;
|
|
48554
|
+
} catch (e) {
|
|
48555
|
+
deps.log(`[E2EE] Could not decrypt preview environment command: ${e instanceof Error ? e.message : String(e)}`);
|
|
48556
|
+
return;
|
|
48557
|
+
}
|
|
48558
|
+
const environmentId = typeof wire.environmentId === "string" ? wire.environmentId : "";
|
|
48559
|
+
const action = wire.action === "start" || wire.action === "stop" ? wire.action : null;
|
|
48560
|
+
if (!environmentId || !action) return;
|
|
48561
|
+
deps.previewEnvironmentManager?.handleControl(environmentId, action);
|
|
48562
|
+
};
|
|
48563
|
+
|
|
48564
|
+
// src/routing/handlers/preview-environments-config.ts
|
|
48565
|
+
var VALID_PORT = (p) => typeof p === "number" && Number.isInteger(p) && p > 0 && p < 65536;
|
|
48566
|
+
var handlePreviewEnvironmentsConfig = (msg, deps) => {
|
|
48567
|
+
const previewEnvironments = msg.previewEnvironments;
|
|
48568
|
+
const proxyPorts = Array.isArray(msg.proxyPorts) ? msg.proxyPorts.filter(VALID_PORT) : void 0;
|
|
48569
|
+
setImmediate(() => {
|
|
48570
|
+
deps.previewEnvironmentManager?.applyConfig(previewEnvironments ?? []);
|
|
48571
|
+
const environmentIds = parsePreviewEnvironmentDefs(previewEnvironments ?? []).map((d) => d.environmentId);
|
|
48572
|
+
void deps.previewWorktreeManager?.syncConfiguredEnvironments(environmentIds);
|
|
48573
|
+
if (proxyPorts !== void 0) {
|
|
48574
|
+
deps.updateFirehoseProxyPorts?.(proxyPorts);
|
|
48575
|
+
}
|
|
48576
|
+
});
|
|
48577
|
+
};
|
|
48578
|
+
|
|
48579
|
+
// src/routing/handlers/send-deploy-session-to-preview-result.ts
|
|
48580
|
+
function sendDeploySessionToPreviewResult(ws, id, payload) {
|
|
48581
|
+
if (!ws) return;
|
|
48582
|
+
sendWsMessage(ws, { type: "deploy_session_to_preview_result", id, ...payload });
|
|
48583
|
+
}
|
|
48584
|
+
|
|
48585
|
+
// src/routing/handlers/deploy-session-to-preview.ts
|
|
48586
|
+
var handleDeploySessionToPreviewMessage = (msg, deps) => {
|
|
48587
|
+
if (typeof msg.id !== "string") return;
|
|
48588
|
+
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
48589
|
+
const environmentId = typeof msg.environmentId === "string" ? msg.environmentId : "";
|
|
48590
|
+
if (!sessionId || !environmentId) return;
|
|
48591
|
+
void (async () => {
|
|
48592
|
+
const ws = deps.getWs();
|
|
48593
|
+
const reply = (payload) => sendDeploySessionToPreviewResult(ws, msg.id, payload);
|
|
48594
|
+
try {
|
|
48595
|
+
if (!deps.previewWorktreeManager) {
|
|
48596
|
+
reply({ ok: false, error: "Preview worktree manager unavailable" });
|
|
48597
|
+
return;
|
|
48598
|
+
}
|
|
48599
|
+
const result = await deploySessionToPreviewEnvironment({
|
|
48600
|
+
sessionWorktreeManager: deps.sessionWorktreeManager,
|
|
48601
|
+
previewWorktreeManager: deps.previewWorktreeManager,
|
|
48602
|
+
sessionId,
|
|
48603
|
+
environmentId,
|
|
48604
|
+
log: deps.log
|
|
48605
|
+
});
|
|
48606
|
+
reply(result);
|
|
48607
|
+
} catch (e) {
|
|
48608
|
+
reply({ ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
48609
|
+
}
|
|
48610
|
+
})();
|
|
48611
|
+
};
|
|
48612
|
+
|
|
48613
|
+
// src/routing/dispatch/preview.ts
|
|
48614
|
+
function dispatchBridgePreviewMessage(msg, deps) {
|
|
48615
|
+
switch (msg.type) {
|
|
48616
|
+
case "preview_environments_config":
|
|
48617
|
+
handlePreviewEnvironmentsConfig(msg, deps);
|
|
48618
|
+
break;
|
|
48619
|
+
case "preview_environment_control":
|
|
48620
|
+
handlePreviewEnvironmentControl(msg, deps);
|
|
48621
|
+
break;
|
|
48622
|
+
case "deploy_session_to_preview":
|
|
48623
|
+
handleDeploySessionToPreviewMessage(msg, deps);
|
|
48624
|
+
break;
|
|
48625
|
+
}
|
|
48626
|
+
}
|
|
48627
|
+
|
|
48431
48628
|
// src/agents/acp/from-bridge/handle-bridge-agent-config.ts
|
|
48432
48629
|
function handleBridgeAgentConfig(msg, { acpManager }) {
|
|
48433
48630
|
if (!Array.isArray(msg.agents) || msg.agents.length === 0) return;
|
|
@@ -48577,15 +48774,15 @@ function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
|
48577
48774
|
}
|
|
48578
48775
|
|
|
48579
48776
|
// src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
|
|
48580
|
-
import
|
|
48777
|
+
import fs58 from "node:fs";
|
|
48581
48778
|
|
|
48582
48779
|
// src/git/snapshot/capture.ts
|
|
48583
|
-
import * as
|
|
48584
|
-
import * as
|
|
48780
|
+
import * as fs57 from "node:fs";
|
|
48781
|
+
import * as path78 from "node:path";
|
|
48585
48782
|
async function resolveSnapshotRepoRoots(options) {
|
|
48586
48783
|
const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
|
|
48587
48784
|
if (worktreePaths?.length) {
|
|
48588
|
-
const uniq = [...new Set(worktreePaths.map((p) =>
|
|
48785
|
+
const uniq = [...new Set(worktreePaths.map((p) => path78.resolve(p)))];
|
|
48589
48786
|
return uniq;
|
|
48590
48787
|
}
|
|
48591
48788
|
try {
|
|
@@ -48593,7 +48790,7 @@ async function resolveSnapshotRepoRoots(options) {
|
|
|
48593
48790
|
const mapped = repos.map((r) => r.absolutePath);
|
|
48594
48791
|
const sid = sessionId?.trim();
|
|
48595
48792
|
if (sid) {
|
|
48596
|
-
const filtered = mapped.filter((root) =>
|
|
48793
|
+
const filtered = mapped.filter((root) => path78.basename(root) === sid);
|
|
48597
48794
|
if (filtered.length > 0) return filtered;
|
|
48598
48795
|
}
|
|
48599
48796
|
return mapped;
|
|
@@ -48615,7 +48812,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
48615
48812
|
});
|
|
48616
48813
|
const dir = snapshotsDirForCwd(agentCwd);
|
|
48617
48814
|
try {
|
|
48618
|
-
|
|
48815
|
+
fs57.mkdirSync(dir, { recursive: true });
|
|
48619
48816
|
} catch (e) {
|
|
48620
48817
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
48621
48818
|
}
|
|
@@ -48624,9 +48821,9 @@ async function capturePreTurnSnapshot(options) {
|
|
|
48624
48821
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
48625
48822
|
repos
|
|
48626
48823
|
};
|
|
48627
|
-
const filePath =
|
|
48824
|
+
const filePath = path78.join(dir, `${runId}.json`);
|
|
48628
48825
|
try {
|
|
48629
|
-
|
|
48826
|
+
fs57.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
48630
48827
|
} catch (e) {
|
|
48631
48828
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
48632
48829
|
}
|
|
@@ -48639,7 +48836,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
48639
48836
|
async function applyPreTurnSnapshot(filePath, log2) {
|
|
48640
48837
|
let data;
|
|
48641
48838
|
try {
|
|
48642
|
-
const raw =
|
|
48839
|
+
const raw = fs57.readFileSync(filePath, "utf8");
|
|
48643
48840
|
data = JSON.parse(raw);
|
|
48644
48841
|
} catch (e) {
|
|
48645
48842
|
return { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
@@ -48679,7 +48876,7 @@ async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
|
48679
48876
|
const agentBase = deps.sessionWorktreeManager.getSessionWorktreeRootForSession(sid) ?? getBridgeRoot();
|
|
48680
48877
|
const file2 = snapshotFilePath(agentBase, tid);
|
|
48681
48878
|
try {
|
|
48682
|
-
await
|
|
48879
|
+
await fs58.promises.access(file2, fs58.constants.F_OK);
|
|
48683
48880
|
} catch {
|
|
48684
48881
|
deps.log(
|
|
48685
48882
|
`[Queue] requeued_with_revert: no pre-turn snapshot for ${tid.slice(0, 8)}\u2026; continuing without revert.`
|
|
@@ -49066,290 +49263,6 @@ var handleSessionRequestResponseMessage = (msg, deps) => {
|
|
|
49066
49263
|
handleBridgeSessionRequestResponse(msg, deps);
|
|
49067
49264
|
};
|
|
49068
49265
|
|
|
49069
|
-
// src/skills/handle-skill-call.ts
|
|
49070
|
-
function handleSkillCall(msg, socket, log2) {
|
|
49071
|
-
callSkill(msg.skillId, msg.operationId, msg.params ?? {}).then((result) => {
|
|
49072
|
-
sendWsMessage(socket, { type: "skill_result", id: msg.id, result });
|
|
49073
|
-
}).catch((err) => {
|
|
49074
|
-
sendWsMessage(socket, { type: "skill_result", id: msg.id, error: String(err) });
|
|
49075
|
-
log2(`[Bridge service] Skill invocation failed (${msg.skillId}/${msg.operationId}): ${err}`);
|
|
49076
|
-
});
|
|
49077
|
-
}
|
|
49078
|
-
|
|
49079
|
-
// src/routing/handlers/skill-call.ts
|
|
49080
|
-
var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
49081
|
-
const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
|
|
49082
|
-
const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
|
|
49083
|
-
if (!skillId || !operationId) return;
|
|
49084
|
-
const socket = getWs();
|
|
49085
|
-
if (!socket) return;
|
|
49086
|
-
handleSkillCall(
|
|
49087
|
-
{ id: msg.id, skillId, operationId, params: msg.params },
|
|
49088
|
-
socket,
|
|
49089
|
-
log2
|
|
49090
|
-
);
|
|
49091
|
-
};
|
|
49092
|
-
|
|
49093
|
-
// src/files/browser/send-file-browser-message.ts
|
|
49094
|
-
function sendFileBrowserMessage(socket, e2ee, payload) {
|
|
49095
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
|
|
49096
|
-
}
|
|
49097
|
-
|
|
49098
|
-
// src/files/browser/handle-file-browser-list.ts
|
|
49099
|
-
async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
|
|
49100
|
-
const result = await executeFileBrowserList({ reqPath, sessionParentPath, gitScope });
|
|
49101
|
-
if ("error" in result) {
|
|
49102
|
-
sendWsMessage(socket, { type: "file_browser_response", id, error: result.error });
|
|
49103
|
-
return;
|
|
49104
|
-
}
|
|
49105
|
-
sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
|
|
49106
|
-
}
|
|
49107
|
-
|
|
49108
|
-
// src/files/browser/handle-file-browser-read.ts
|
|
49109
|
-
async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
|
|
49110
|
-
const result = await executeFileBrowserRead({ msg, reqPath, sessionParentPath, gitScope });
|
|
49111
|
-
if ("error" in result) {
|
|
49112
|
-
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
49113
|
-
return;
|
|
49114
|
-
}
|
|
49115
|
-
const payload = {
|
|
49116
|
-
type: "file_browser_response",
|
|
49117
|
-
id: msg.id,
|
|
49118
|
-
content: result.content,
|
|
49119
|
-
totalLines: result.totalLines,
|
|
49120
|
-
size: result.size
|
|
49121
|
-
};
|
|
49122
|
-
if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
|
|
49123
|
-
if (result.mimeType != null) payload.mimeType = result.mimeType;
|
|
49124
|
-
if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
|
|
49125
|
-
sendFileBrowserMessage(socket, e2ee, payload);
|
|
49126
|
-
}
|
|
49127
|
-
|
|
49128
|
-
// src/files/browser/index.ts
|
|
49129
|
-
init_in_flight();
|
|
49130
|
-
function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49131
|
-
beginFileBrowserRequest();
|
|
49132
|
-
void (async () => {
|
|
49133
|
-
try {
|
|
49134
|
-
const reqPath = msg.path.replace(/^\/+/, "") || ".";
|
|
49135
|
-
const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
|
|
49136
|
-
const gitScope = resolveGitBranchScope(msg);
|
|
49137
|
-
if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
|
|
49138
|
-
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
|
|
49139
|
-
return;
|
|
49140
|
-
}
|
|
49141
|
-
if (msg.op === "read") {
|
|
49142
|
-
await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
|
|
49143
|
-
} else {
|
|
49144
|
-
await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
|
|
49145
|
-
}
|
|
49146
|
-
} finally {
|
|
49147
|
-
endFileBrowserRequest();
|
|
49148
|
-
}
|
|
49149
|
-
})();
|
|
49150
|
-
}
|
|
49151
|
-
|
|
49152
|
-
// src/files/handle-file-browser-search.ts
|
|
49153
|
-
init_yield_to_event_loop();
|
|
49154
|
-
import path77 from "node:path";
|
|
49155
|
-
var SEARCH_LIMIT = 100;
|
|
49156
|
-
function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49157
|
-
void (async () => {
|
|
49158
|
-
await yieldToEventLoop();
|
|
49159
|
-
const q = typeof msg.q === "string" ? msg.q : "";
|
|
49160
|
-
const sessionParentPath = path77.resolve(
|
|
49161
|
-
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
49162
|
-
);
|
|
49163
|
-
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
49164
|
-
triggerFileIndexBuild(sessionParentPath);
|
|
49165
|
-
const payload2 = {
|
|
49166
|
-
type: "file_browser_search_response",
|
|
49167
|
-
id: msg.id,
|
|
49168
|
-
paths: [],
|
|
49169
|
-
indexReady: false
|
|
49170
|
-
};
|
|
49171
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
49172
|
-
return;
|
|
49173
|
-
}
|
|
49174
|
-
const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
|
|
49175
|
-
const payload = {
|
|
49176
|
-
type: "file_browser_search_response",
|
|
49177
|
-
id: msg.id,
|
|
49178
|
-
paths: results,
|
|
49179
|
-
indexReady: true
|
|
49180
|
-
};
|
|
49181
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
|
|
49182
|
-
})();
|
|
49183
|
-
}
|
|
49184
|
-
function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
|
|
49185
|
-
setImmediate(() => {
|
|
49186
|
-
void ensureFileIndexAsync(sessionParentPath).catch((e) => {
|
|
49187
|
-
console.error("[file-index] Background build failed:", e);
|
|
49188
|
-
});
|
|
49189
|
-
});
|
|
49190
|
-
}
|
|
49191
|
-
|
|
49192
|
-
// src/routing/handlers/file-browser-messages.ts
|
|
49193
|
-
function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49194
|
-
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
49195
|
-
const socket = getWs();
|
|
49196
|
-
if (!socket) return;
|
|
49197
|
-
handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager);
|
|
49198
|
-
}
|
|
49199
|
-
function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49200
|
-
if (typeof msg.id !== "string") return;
|
|
49201
|
-
const socket = getWs();
|
|
49202
|
-
if (!socket) return;
|
|
49203
|
-
handleFileBrowserSearch(
|
|
49204
|
-
msg,
|
|
49205
|
-
socket,
|
|
49206
|
-
e2ee,
|
|
49207
|
-
sessionWorktreeManager
|
|
49208
|
-
);
|
|
49209
|
-
}
|
|
49210
|
-
|
|
49211
|
-
// src/code-nav/handlers/send-code-nav-response.ts
|
|
49212
|
-
var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
|
|
49213
|
-
function sendCodeNavResponse(socket, e2ee, payload) {
|
|
49214
|
-
const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
|
|
49215
|
-
sendWsMessage(
|
|
49216
|
-
socket,
|
|
49217
|
-
e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
|
|
49218
|
-
);
|
|
49219
|
-
}
|
|
49220
|
-
|
|
49221
|
-
// src/code-nav/handlers/handle-code-nav-request.ts
|
|
49222
|
-
function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49223
|
-
void (async () => {
|
|
49224
|
-
const body = await executeCodeNavRequest(msg, sessionWorktreeManager);
|
|
49225
|
-
sendCodeNavResponse(socket, e2ee, {
|
|
49226
|
-
type: "code_nav_response",
|
|
49227
|
-
id: msg.id,
|
|
49228
|
-
...body
|
|
49229
|
-
});
|
|
49230
|
-
})();
|
|
49231
|
-
}
|
|
49232
|
-
|
|
49233
|
-
// src/code-nav/handlers/trigger-symbol-index-build.ts
|
|
49234
|
-
init_normalize_resolved_path();
|
|
49235
|
-
|
|
49236
|
-
// src/routing/handlers/code-nav-messages.ts
|
|
49237
|
-
function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49238
|
-
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
49239
|
-
const socket = getWs();
|
|
49240
|
-
if (!socket) return;
|
|
49241
|
-
handleCodeNavRequest(
|
|
49242
|
-
{
|
|
49243
|
-
id: msg.id,
|
|
49244
|
-
type: "code_nav",
|
|
49245
|
-
op: msg.op === "references" ? "references" : msg.op === "symbols" ? "symbols" : msg.op === "definitions" ? "definitions" : "definition",
|
|
49246
|
-
path: msg.path,
|
|
49247
|
-
line: typeof msg.line === "number" ? msg.line : 1,
|
|
49248
|
-
column: typeof msg.column === "number" ? msg.column : 0,
|
|
49249
|
-
sessionId: msg.sessionId
|
|
49250
|
-
},
|
|
49251
|
-
socket,
|
|
49252
|
-
e2ee,
|
|
49253
|
-
sessionWorktreeManager
|
|
49254
|
-
);
|
|
49255
|
-
}
|
|
49256
|
-
|
|
49257
|
-
// src/routing/handlers/skill-layout-request.ts
|
|
49258
|
-
function handleSkillLayoutRequest(msg, deps) {
|
|
49259
|
-
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49260
|
-
void (async () => {
|
|
49261
|
-
const socket = deps.getWs();
|
|
49262
|
-
const roots = await discoverSkillLayoutRootsAsync(getBridgeRoot());
|
|
49263
|
-
if (socket) {
|
|
49264
|
-
sendWsMessage(socket, { type: "skill_layout_response", id, roots });
|
|
49265
|
-
}
|
|
49266
|
-
})();
|
|
49267
|
-
}
|
|
49268
|
-
|
|
49269
|
-
// src/skills/install/is-valid-install-item.ts
|
|
49270
|
-
function isValidRemoteSkillInstallItem(item) {
|
|
49271
|
-
if (item === null || typeof item !== "object") return false;
|
|
49272
|
-
const o = item;
|
|
49273
|
-
return typeof o.sourceId === "string" && typeof o.skillName === "string" && typeof o.versionHash === "string" && Array.isArray(o.files);
|
|
49274
|
-
}
|
|
49275
|
-
|
|
49276
|
-
// src/skills/install/install-remote-skills-async.ts
|
|
49277
|
-
init_yield_to_event_loop();
|
|
49278
|
-
import fs57 from "node:fs";
|
|
49279
|
-
import path78 from "node:path";
|
|
49280
|
-
|
|
49281
|
-
// src/skills/install/constants.ts
|
|
49282
|
-
var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
49283
|
-
|
|
49284
|
-
// src/skills/install/install-remote-skills-async.ts
|
|
49285
|
-
async function writeInstallFileAsync(skillDir, f, filesWritten) {
|
|
49286
|
-
if (typeof f.path !== "string" || !f.text && !f.base64) return;
|
|
49287
|
-
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
49288
|
-
await yieldToEventLoop();
|
|
49289
|
-
}
|
|
49290
|
-
const dest = path78.join(skillDir, f.path);
|
|
49291
|
-
await fs57.promises.mkdir(path78.dirname(dest), { recursive: true });
|
|
49292
|
-
if (f.text !== void 0) {
|
|
49293
|
-
await fs57.promises.writeFile(dest, f.text, "utf8");
|
|
49294
|
-
} else if (f.base64) {
|
|
49295
|
-
await fs57.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
|
|
49296
|
-
}
|
|
49297
|
-
}
|
|
49298
|
-
async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
49299
|
-
const installed2 = [];
|
|
49300
|
-
if (!Array.isArray(items)) {
|
|
49301
|
-
return { success: false, error: "Invalid items" };
|
|
49302
|
-
}
|
|
49303
|
-
const filesWritten = { count: 0 };
|
|
49304
|
-
try {
|
|
49305
|
-
for (const item of items) {
|
|
49306
|
-
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
49307
|
-
const skillDir = path78.join(cwd, targetDir, item.skillName);
|
|
49308
|
-
for (const f of item.files) {
|
|
49309
|
-
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
49310
|
-
}
|
|
49311
|
-
installed2.push({
|
|
49312
|
-
sourceId: item.sourceId,
|
|
49313
|
-
skillName: item.skillName,
|
|
49314
|
-
versionHash: item.versionHash
|
|
49315
|
-
});
|
|
49316
|
-
}
|
|
49317
|
-
return { success: true, installed: installed2 };
|
|
49318
|
-
} catch (e) {
|
|
49319
|
-
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
49320
|
-
}
|
|
49321
|
-
}
|
|
49322
|
-
|
|
49323
|
-
// src/routing/handlers/install-skills.ts
|
|
49324
|
-
var handleInstallSkillsMessage = (msg, deps) => {
|
|
49325
|
-
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49326
|
-
const targetDir = typeof msg.targetDir === "string" && msg.targetDir.trim() ? msg.targetDir.trim() : ".agents/skills";
|
|
49327
|
-
const rawItems = msg.items;
|
|
49328
|
-
const cwd = getBridgeRoot();
|
|
49329
|
-
void (async () => {
|
|
49330
|
-
const socket = deps.getWs();
|
|
49331
|
-
const result = await installRemoteSkillsAsync(cwd, targetDir, rawItems);
|
|
49332
|
-
if (!result.success) {
|
|
49333
|
-
const err = result.error ?? "Invalid items";
|
|
49334
|
-
deps.log(`[Bridge service] Install skills failed: ${err}`);
|
|
49335
|
-
if (socket) {
|
|
49336
|
-
sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
|
|
49337
|
-
}
|
|
49338
|
-
return;
|
|
49339
|
-
}
|
|
49340
|
-
if (socket) {
|
|
49341
|
-
sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
|
|
49342
|
-
}
|
|
49343
|
-
})();
|
|
49344
|
-
};
|
|
49345
|
-
|
|
49346
|
-
// src/routing/handlers/refresh-local-skills.ts
|
|
49347
|
-
var handleRefreshLocalSkills = (_msg, deps) => {
|
|
49348
|
-
setImmediate(() => {
|
|
49349
|
-
deps.sendLocalSkillsReport?.();
|
|
49350
|
-
});
|
|
49351
|
-
};
|
|
49352
|
-
|
|
49353
49266
|
// src/routing/handlers/git/handle-session-git-commit.ts
|
|
49354
49267
|
async function handleSessionGitCommitAction(deps, sessionId, msg, reply) {
|
|
49355
49268
|
const branch = typeof msg.branch === "string" ? msg.branch : "";
|
|
@@ -49586,7 +49499,7 @@ var handleSessionDiscardedMessage = (msg, deps) => {
|
|
|
49586
49499
|
};
|
|
49587
49500
|
|
|
49588
49501
|
// src/routing/handlers/revert-turn-snapshot.ts
|
|
49589
|
-
import * as
|
|
49502
|
+
import * as fs59 from "node:fs";
|
|
49590
49503
|
var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
49591
49504
|
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49592
49505
|
const sessionId = typeof msg.sessionId === "string" ? msg.sessionId : "";
|
|
@@ -49599,7 +49512,7 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
49599
49512
|
const agentBase = sessionWorktreeManager.getSessionWorktreeRootForSession(sessionId) ?? getBridgeRoot();
|
|
49600
49513
|
const file2 = snapshotFilePath(agentBase, turnId);
|
|
49601
49514
|
try {
|
|
49602
|
-
await
|
|
49515
|
+
await fs59.promises.access(file2, fs59.constants.F_OK);
|
|
49603
49516
|
} catch {
|
|
49604
49517
|
sendWsMessage(s, {
|
|
49605
49518
|
type: "revert_turn_snapshot_result",
|
|
@@ -49619,72 +49532,490 @@ var handleRevertTurnSnapshotMessage = (msg, deps) => {
|
|
|
49619
49532
|
})();
|
|
49620
49533
|
};
|
|
49621
49534
|
|
|
49622
|
-
// src/routing/
|
|
49623
|
-
|
|
49624
|
-
|
|
49535
|
+
// src/routing/dispatch/session.ts
|
|
49536
|
+
function dispatchBridgeSessionMessage(msg, deps) {
|
|
49537
|
+
switch (msg.type) {
|
|
49538
|
+
case "agent_config":
|
|
49539
|
+
handleAgentConfigMessage(msg, deps);
|
|
49540
|
+
break;
|
|
49541
|
+
case "prompt_queue_state":
|
|
49542
|
+
handlePromptQueueStateMessage(msg, deps);
|
|
49543
|
+
break;
|
|
49544
|
+
case "prompt":
|
|
49545
|
+
handlePromptMessage(msg, deps);
|
|
49546
|
+
break;
|
|
49547
|
+
case "session_git_request":
|
|
49548
|
+
handleSessionGitRequestMessage(msg, deps);
|
|
49549
|
+
break;
|
|
49550
|
+
case "rename_session_branch":
|
|
49551
|
+
handleRenameSessionBranchMessage(msg, deps);
|
|
49552
|
+
break;
|
|
49553
|
+
case "session_archived":
|
|
49554
|
+
handleSessionArchivedMessage(msg, deps);
|
|
49555
|
+
break;
|
|
49556
|
+
case "session_discarded":
|
|
49557
|
+
handleSessionDiscardedMessage(msg, deps);
|
|
49558
|
+
break;
|
|
49559
|
+
case "revert_turn_snapshot":
|
|
49560
|
+
handleRevertTurnSnapshotMessage(msg, deps);
|
|
49561
|
+
break;
|
|
49562
|
+
case "cursor_request_response":
|
|
49563
|
+
handleSessionRequestResponseMessage(msg, deps);
|
|
49564
|
+
break;
|
|
49565
|
+
}
|
|
49566
|
+
}
|
|
49567
|
+
|
|
49568
|
+
// src/skills/handle-skill-call.ts
|
|
49569
|
+
function handleSkillCall(msg, socket, log2) {
|
|
49570
|
+
callSkill(msg.skillId, msg.operationId, msg.params ?? {}).then((result) => {
|
|
49571
|
+
sendWsMessage(socket, { type: "skill_result", id: msg.id, result });
|
|
49572
|
+
}).catch((err) => {
|
|
49573
|
+
sendWsMessage(socket, { type: "skill_result", id: msg.id, error: String(err) });
|
|
49574
|
+
log2(`[Bridge service] Skill invocation failed (${msg.skillId}/${msg.operationId}): ${err}`);
|
|
49575
|
+
});
|
|
49576
|
+
}
|
|
49577
|
+
|
|
49578
|
+
// src/routing/handlers/skill-call.ts
|
|
49579
|
+
var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
49580
|
+
const skillId = typeof msg.skillId === "string" ? msg.skillId : "";
|
|
49581
|
+
const operationId = typeof msg.operationId === "string" ? msg.operationId : "";
|
|
49582
|
+
if (!skillId || !operationId) return;
|
|
49583
|
+
const socket = getWs();
|
|
49584
|
+
if (!socket) return;
|
|
49585
|
+
handleSkillCall(
|
|
49586
|
+
{ id: msg.id, skillId, operationId, params: msg.params },
|
|
49587
|
+
socket,
|
|
49588
|
+
log2
|
|
49589
|
+
);
|
|
49590
|
+
};
|
|
49591
|
+
|
|
49592
|
+
// src/routing/handlers/skill-layout-request.ts
|
|
49593
|
+
function handleSkillLayoutRequest(msg, deps) {
|
|
49594
|
+
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49595
|
+
void (async () => {
|
|
49596
|
+
const socket = deps.getWs();
|
|
49597
|
+
const roots = await discoverSkillLayoutRootsAsync(getBridgeRoot());
|
|
49598
|
+
if (socket) {
|
|
49599
|
+
sendWsMessage(socket, { type: "skill_layout_response", id, roots });
|
|
49600
|
+
}
|
|
49601
|
+
})();
|
|
49602
|
+
}
|
|
49603
|
+
|
|
49604
|
+
// src/skills/install/is-valid-install-item.ts
|
|
49605
|
+
function isValidRemoteSkillInstallItem(item) {
|
|
49606
|
+
if (item === null || typeof item !== "object") return false;
|
|
49607
|
+
const o = item;
|
|
49608
|
+
return typeof o.sourceId === "string" && typeof o.skillName === "string" && typeof o.versionHash === "string" && Array.isArray(o.files);
|
|
49609
|
+
}
|
|
49610
|
+
|
|
49611
|
+
// src/skills/install/install-remote-skills-async.ts
|
|
49612
|
+
init_yield_to_event_loop();
|
|
49613
|
+
import fs60 from "node:fs";
|
|
49614
|
+
import path79 from "node:path";
|
|
49615
|
+
|
|
49616
|
+
// src/skills/install/constants.ts
|
|
49617
|
+
var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
49618
|
+
|
|
49619
|
+
// src/skills/install/install-remote-skills-async.ts
|
|
49620
|
+
async function writeInstallFileAsync(skillDir, f, filesWritten) {
|
|
49621
|
+
if (typeof f.path !== "string" || !f.text && !f.base64) return;
|
|
49622
|
+
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
49623
|
+
await yieldToEventLoop();
|
|
49624
|
+
}
|
|
49625
|
+
const dest = path79.join(skillDir, f.path);
|
|
49626
|
+
await fs60.promises.mkdir(path79.dirname(dest), { recursive: true });
|
|
49627
|
+
if (f.text !== void 0) {
|
|
49628
|
+
await fs60.promises.writeFile(dest, f.text, "utf8");
|
|
49629
|
+
} else if (f.base64) {
|
|
49630
|
+
await fs60.promises.writeFile(dest, Buffer.from(f.base64, "base64"));
|
|
49631
|
+
}
|
|
49632
|
+
}
|
|
49633
|
+
async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
49634
|
+
const installed2 = [];
|
|
49635
|
+
if (!Array.isArray(items)) {
|
|
49636
|
+
return { success: false, error: "Invalid items" };
|
|
49637
|
+
}
|
|
49638
|
+
const filesWritten = { count: 0 };
|
|
49625
49639
|
try {
|
|
49626
|
-
|
|
49640
|
+
for (const item of items) {
|
|
49641
|
+
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
49642
|
+
const skillDir = path79.join(cwd, targetDir, item.skillName);
|
|
49643
|
+
for (const f of item.files) {
|
|
49644
|
+
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
49645
|
+
}
|
|
49646
|
+
installed2.push({
|
|
49647
|
+
sourceId: item.sourceId,
|
|
49648
|
+
skillName: item.skillName,
|
|
49649
|
+
versionHash: item.versionHash
|
|
49650
|
+
});
|
|
49651
|
+
}
|
|
49652
|
+
return { success: true, installed: installed2 };
|
|
49627
49653
|
} catch (e) {
|
|
49628
|
-
|
|
49629
|
-
return;
|
|
49654
|
+
return { success: false, error: e instanceof Error ? e.message : String(e) };
|
|
49630
49655
|
}
|
|
49631
|
-
|
|
49632
|
-
|
|
49633
|
-
|
|
49634
|
-
|
|
49656
|
+
}
|
|
49657
|
+
|
|
49658
|
+
// src/routing/handlers/install-skills.ts
|
|
49659
|
+
var handleInstallSkillsMessage = (msg, deps) => {
|
|
49660
|
+
const id = typeof msg.id === "string" ? msg.id : "";
|
|
49661
|
+
const targetDir = typeof msg.targetDir === "string" && msg.targetDir.trim() ? msg.targetDir.trim() : ".agents/skills";
|
|
49662
|
+
const rawItems = msg.items;
|
|
49663
|
+
const cwd = getBridgeRoot();
|
|
49664
|
+
void (async () => {
|
|
49665
|
+
const socket = deps.getWs();
|
|
49666
|
+
const result = await installRemoteSkillsAsync(cwd, targetDir, rawItems);
|
|
49667
|
+
if (!result.success) {
|
|
49668
|
+
const err = result.error ?? "Invalid items";
|
|
49669
|
+
deps.log(`[Bridge service] Install skills failed: ${err}`);
|
|
49670
|
+
if (socket) {
|
|
49671
|
+
sendWsMessage(socket, { type: "install_skills_result", id, success: false, error: err });
|
|
49672
|
+
}
|
|
49673
|
+
return;
|
|
49674
|
+
}
|
|
49675
|
+
if (socket) {
|
|
49676
|
+
sendWsMessage(socket, { type: "install_skills_result", id, success: true, installed: result.installed });
|
|
49677
|
+
}
|
|
49678
|
+
})();
|
|
49635
49679
|
};
|
|
49636
49680
|
|
|
49637
|
-
// src/
|
|
49638
|
-
|
|
49639
|
-
|
|
49640
|
-
|
|
49641
|
-
|
|
49642
|
-
|
|
49643
|
-
|
|
49644
|
-
|
|
49645
|
-
|
|
49646
|
-
|
|
49647
|
-
|
|
49681
|
+
// src/agents/install/commands/run-npm-global-install.ts
|
|
49682
|
+
import { execFile as execFile9 } from "node:child_process";
|
|
49683
|
+
import { promisify as promisify10 } from "node:util";
|
|
49684
|
+
var execFileAsync8 = promisify10(execFile9);
|
|
49685
|
+
async function runNpmGlobalInstall(packageName, env, timeoutMs = 3e5) {
|
|
49686
|
+
await execFileAsync8("npm", ["install", "-g", packageName], { timeout: timeoutMs, env });
|
|
49687
|
+
}
|
|
49688
|
+
|
|
49689
|
+
// src/agents/install/commands/claude-code.ts
|
|
49690
|
+
var claudeCodeInstallCommand = {
|
|
49691
|
+
agentType: "claude-code",
|
|
49692
|
+
detectCommand: "claude",
|
|
49693
|
+
async install(ctx) {
|
|
49694
|
+
ctx.onProgress?.("Installing Anthropic Claude Code");
|
|
49695
|
+
await runNpmGlobalInstall("@anthropic-ai/claude-code", {
|
|
49696
|
+
...ctx.env,
|
|
49697
|
+
ANTHROPIC_API_KEY: ctx.authToken
|
|
49698
|
+
});
|
|
49699
|
+
}
|
|
49700
|
+
};
|
|
49701
|
+
|
|
49702
|
+
// src/agents/install/commands/codex-acp.ts
|
|
49703
|
+
var codexAcpInstallCommand = {
|
|
49704
|
+
agentType: "codex-acp",
|
|
49705
|
+
detectCommand: "codex",
|
|
49706
|
+
async install(ctx) {
|
|
49707
|
+
ctx.onProgress?.("Installing Codex");
|
|
49708
|
+
await runNpmGlobalInstall("@openai/codex", {
|
|
49709
|
+
...ctx.env,
|
|
49710
|
+
OPENAI_API_KEY: ctx.authToken
|
|
49711
|
+
});
|
|
49712
|
+
}
|
|
49713
|
+
};
|
|
49714
|
+
|
|
49715
|
+
// src/agents/install/commands/cursor-cli.ts
|
|
49716
|
+
import { execFile as execFile10 } from "node:child_process";
|
|
49717
|
+
import { promisify as promisify11 } from "node:util";
|
|
49718
|
+
var execFileAsync9 = promisify11(execFile10);
|
|
49719
|
+
var cursorCliInstallCommand = {
|
|
49720
|
+
agentType: "cursor-cli",
|
|
49721
|
+
detectCommand: "agent",
|
|
49722
|
+
async install(ctx) {
|
|
49723
|
+
ctx.onProgress?.("Installing Cursor CLI");
|
|
49724
|
+
await execFileAsync9("bash", ["-lc", "curl -fsSL https://cursor.com/install | bash"], {
|
|
49725
|
+
timeout: 3e5,
|
|
49726
|
+
env: { ...ctx.env, CURSOR_API_KEY: ctx.authToken }
|
|
49727
|
+
});
|
|
49728
|
+
}
|
|
49729
|
+
};
|
|
49730
|
+
|
|
49731
|
+
// src/agents/install/commands/opencode.ts
|
|
49732
|
+
var opencodeInstallCommand = {
|
|
49733
|
+
agentType: "opencode",
|
|
49734
|
+
detectCommand: "opencode",
|
|
49735
|
+
async install(ctx) {
|
|
49736
|
+
ctx.onProgress?.("Installing OpenCode");
|
|
49737
|
+
await runNpmGlobalInstall("opencode-ai", {
|
|
49738
|
+
...ctx.env,
|
|
49739
|
+
OPENCODE_API_KEY: ctx.authToken
|
|
49740
|
+
});
|
|
49741
|
+
}
|
|
49742
|
+
};
|
|
49743
|
+
|
|
49744
|
+
// src/agents/install/commands/index.ts
|
|
49745
|
+
var COMMANDS = [
|
|
49746
|
+
claudeCodeInstallCommand,
|
|
49747
|
+
codexAcpInstallCommand,
|
|
49748
|
+
cursorCliInstallCommand,
|
|
49749
|
+
opencodeInstallCommand
|
|
49750
|
+
];
|
|
49751
|
+
var byType = new Map(COMMANDS.map((c) => [c.agentType, c]));
|
|
49752
|
+
function getAgentInstallCommand(agentType) {
|
|
49753
|
+
return byType.get(agentType);
|
|
49754
|
+
}
|
|
49755
|
+
|
|
49756
|
+
// src/agents/install/install-local-agent.ts
|
|
49757
|
+
async function installLocalAgentOnBridge(params) {
|
|
49758
|
+
const spec = INSTALLABLE_BRIDGE_AGENTS.find((a) => a.value === params.agentType);
|
|
49759
|
+
if (!spec) return { success: false, error: `Unsupported agent type: ${params.agentType}` };
|
|
49760
|
+
const command = getAgentInstallCommand(params.agentType);
|
|
49761
|
+
if (!command) return { success: false, error: `No install command for ${params.agentType}` };
|
|
49762
|
+
params.onProgress?.(`Configuring ${spec.label} credentials`);
|
|
49763
|
+
try {
|
|
49764
|
+
await command.install({
|
|
49765
|
+
authToken: params.authToken,
|
|
49766
|
+
onProgress: params.onProgress,
|
|
49767
|
+
env: { ...process.env, [spec.tokenEnvVar]: params.authToken }
|
|
49768
|
+
});
|
|
49769
|
+
} catch (e) {
|
|
49770
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
49771
|
+
return { success: false, error: msg };
|
|
49772
|
+
}
|
|
49773
|
+
const found = await isCommandOnPath(command.detectCommand);
|
|
49774
|
+
if (!found) {
|
|
49775
|
+
return { success: false, error: `${command.detectCommand} not found on PATH after install` };
|
|
49776
|
+
}
|
|
49777
|
+
return { success: true };
|
|
49778
|
+
}
|
|
49779
|
+
|
|
49780
|
+
// src/routing/handlers/install-agent.ts
|
|
49781
|
+
var handleInstallAgentMessage = (msg, deps) => {
|
|
49782
|
+
const processId = typeof msg.processId === "string" ? msg.processId : "";
|
|
49783
|
+
const agentId = typeof msg.agentId === "string" ? msg.agentId : "";
|
|
49784
|
+
const tokenId = typeof msg.tokenId === "string" ? msg.tokenId : "";
|
|
49785
|
+
const agentType = typeof msg.agentType === "string" ? msg.agentType : "";
|
|
49786
|
+
const authToken = typeof msg.authToken === "string" ? msg.authToken : "";
|
|
49787
|
+
if (!processId || !agentId || !tokenId || !agentType || !authToken) return;
|
|
49788
|
+
void (async () => {
|
|
49789
|
+
const socket = deps.getWs();
|
|
49790
|
+
const report = (step, message) => {
|
|
49791
|
+
if (socket) {
|
|
49792
|
+
sendWsMessage(socket, {
|
|
49793
|
+
type: "install_agent_progress",
|
|
49794
|
+
processId,
|
|
49795
|
+
agentId,
|
|
49796
|
+
tokenId,
|
|
49797
|
+
agentType,
|
|
49798
|
+
step,
|
|
49799
|
+
message
|
|
49800
|
+
});
|
|
49801
|
+
}
|
|
49802
|
+
};
|
|
49803
|
+
const result = await installLocalAgentOnBridge({
|
|
49804
|
+
agentType,
|
|
49805
|
+
authToken,
|
|
49806
|
+
onProgress: (message) => report("agent_install_package", message)
|
|
49807
|
+
});
|
|
49808
|
+
if (socket) {
|
|
49809
|
+
sendWsMessage(socket, {
|
|
49810
|
+
type: "install_agent_result",
|
|
49811
|
+
processId,
|
|
49812
|
+
agentId,
|
|
49813
|
+
tokenId,
|
|
49814
|
+
agentType,
|
|
49815
|
+
success: result.success,
|
|
49816
|
+
error: result.error
|
|
49817
|
+
});
|
|
49818
|
+
}
|
|
49819
|
+
if (!result.success) {
|
|
49820
|
+
deps.log(`[Bridge service] Install agent failed: ${result.error ?? "unknown"}`);
|
|
49648
49821
|
}
|
|
49822
|
+
})();
|
|
49823
|
+
};
|
|
49824
|
+
|
|
49825
|
+
// src/routing/handlers/refresh-local-skills.ts
|
|
49826
|
+
var handleRefreshLocalSkills = (_msg, deps) => {
|
|
49827
|
+
setImmediate(() => {
|
|
49828
|
+
deps.sendLocalSkillsReport?.();
|
|
49649
49829
|
});
|
|
49650
49830
|
};
|
|
49651
49831
|
|
|
49652
|
-
// src/routing/
|
|
49653
|
-
function
|
|
49654
|
-
|
|
49655
|
-
|
|
49832
|
+
// src/routing/dispatch/skills.ts
|
|
49833
|
+
function dispatchBridgeSkillsMessage(msg, deps) {
|
|
49834
|
+
switch (msg.type) {
|
|
49835
|
+
case "skill_call":
|
|
49836
|
+
handleSkillCallMessage(msg, deps);
|
|
49837
|
+
break;
|
|
49838
|
+
case "skill_layout_request":
|
|
49839
|
+
handleSkillLayoutRequest(msg, deps);
|
|
49840
|
+
break;
|
|
49841
|
+
case "install_skills":
|
|
49842
|
+
handleInstallSkillsMessage(msg, deps);
|
|
49843
|
+
break;
|
|
49844
|
+
case "install_agent":
|
|
49845
|
+
handleInstallAgentMessage(msg, deps);
|
|
49846
|
+
break;
|
|
49847
|
+
case "refresh_local_skills":
|
|
49848
|
+
handleRefreshLocalSkills(msg, deps);
|
|
49849
|
+
break;
|
|
49850
|
+
}
|
|
49656
49851
|
}
|
|
49657
49852
|
|
|
49658
|
-
// src/
|
|
49659
|
-
|
|
49660
|
-
|
|
49661
|
-
|
|
49662
|
-
|
|
49663
|
-
|
|
49853
|
+
// src/files/browser/send-file-browser-message.ts
|
|
49854
|
+
function sendFileBrowserMessage(socket, e2ee, payload) {
|
|
49855
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
|
|
49856
|
+
}
|
|
49857
|
+
|
|
49858
|
+
// src/files/browser/handle-file-browser-list.ts
|
|
49859
|
+
async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
|
|
49860
|
+
const result = await executeFileBrowserList({ reqPath, sessionParentPath, gitScope });
|
|
49861
|
+
if ("error" in result) {
|
|
49862
|
+
sendWsMessage(socket, { type: "file_browser_response", id, error: result.error });
|
|
49863
|
+
return;
|
|
49864
|
+
}
|
|
49865
|
+
sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
|
|
49866
|
+
}
|
|
49867
|
+
|
|
49868
|
+
// src/files/browser/handle-file-browser-read.ts
|
|
49869
|
+
async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
|
|
49870
|
+
const result = await executeFileBrowserRead({ msg, reqPath, sessionParentPath, gitScope });
|
|
49871
|
+
if ("error" in result) {
|
|
49872
|
+
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
49873
|
+
return;
|
|
49874
|
+
}
|
|
49875
|
+
const payload = {
|
|
49876
|
+
type: "file_browser_response",
|
|
49877
|
+
id: msg.id,
|
|
49878
|
+
content: result.content,
|
|
49879
|
+
totalLines: result.totalLines,
|
|
49880
|
+
size: result.size
|
|
49881
|
+
};
|
|
49882
|
+
if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
|
|
49883
|
+
if (result.mimeType != null) payload.mimeType = result.mimeType;
|
|
49884
|
+
if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
|
|
49885
|
+
sendFileBrowserMessage(socket, e2ee, payload);
|
|
49886
|
+
}
|
|
49887
|
+
|
|
49888
|
+
// src/files/browser/index.ts
|
|
49889
|
+
init_in_flight();
|
|
49890
|
+
function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49891
|
+
beginFileBrowserRequest();
|
|
49664
49892
|
void (async () => {
|
|
49665
|
-
const ws = deps.getWs();
|
|
49666
|
-
const reply = (payload) => sendDeploySessionToPreviewResult(ws, msg.id, payload);
|
|
49667
49893
|
try {
|
|
49668
|
-
|
|
49669
|
-
|
|
49894
|
+
const reqPath = msg.path.replace(/^\/+/, "") || ".";
|
|
49895
|
+
const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
|
|
49896
|
+
const gitScope = resolveGitBranchScope(msg);
|
|
49897
|
+
if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
|
|
49898
|
+
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
|
|
49670
49899
|
return;
|
|
49671
49900
|
}
|
|
49672
|
-
|
|
49673
|
-
|
|
49674
|
-
|
|
49675
|
-
|
|
49676
|
-
|
|
49677
|
-
|
|
49678
|
-
|
|
49679
|
-
reply(result);
|
|
49680
|
-
} catch (e) {
|
|
49681
|
-
reply({ ok: false, error: e instanceof Error ? e.message : String(e) });
|
|
49901
|
+
if (msg.op === "read") {
|
|
49902
|
+
await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
|
|
49903
|
+
} else {
|
|
49904
|
+
await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
|
|
49905
|
+
}
|
|
49906
|
+
} finally {
|
|
49907
|
+
endFileBrowserRequest();
|
|
49682
49908
|
}
|
|
49683
49909
|
})();
|
|
49684
|
-
}
|
|
49910
|
+
}
|
|
49911
|
+
|
|
49912
|
+
// src/files/handle-file-browser-search.ts
|
|
49913
|
+
init_yield_to_event_loop();
|
|
49914
|
+
import path80 from "node:path";
|
|
49915
|
+
var SEARCH_LIMIT = 100;
|
|
49916
|
+
function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49917
|
+
void (async () => {
|
|
49918
|
+
await yieldToEventLoop();
|
|
49919
|
+
const q = typeof msg.q === "string" ? msg.q : "";
|
|
49920
|
+
const sessionParentPath = path80.resolve(
|
|
49921
|
+
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
49922
|
+
);
|
|
49923
|
+
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
49924
|
+
triggerFileIndexBuild(sessionParentPath);
|
|
49925
|
+
const payload2 = {
|
|
49926
|
+
type: "file_browser_search_response",
|
|
49927
|
+
id: msg.id,
|
|
49928
|
+
paths: [],
|
|
49929
|
+
indexReady: false
|
|
49930
|
+
};
|
|
49931
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
49932
|
+
return;
|
|
49933
|
+
}
|
|
49934
|
+
const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
|
|
49935
|
+
const payload = {
|
|
49936
|
+
type: "file_browser_search_response",
|
|
49937
|
+
id: msg.id,
|
|
49938
|
+
paths: results,
|
|
49939
|
+
indexReady: true
|
|
49940
|
+
};
|
|
49941
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
|
|
49942
|
+
})();
|
|
49943
|
+
}
|
|
49944
|
+
function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
|
|
49945
|
+
setImmediate(() => {
|
|
49946
|
+
void ensureFileIndexAsync(sessionParentPath).catch((e) => {
|
|
49947
|
+
console.error("[file-index] Background build failed:", e);
|
|
49948
|
+
});
|
|
49949
|
+
});
|
|
49950
|
+
}
|
|
49951
|
+
|
|
49952
|
+
// src/routing/handlers/file-browser-messages.ts
|
|
49953
|
+
function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49954
|
+
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
49955
|
+
const socket = getWs();
|
|
49956
|
+
if (!socket) return;
|
|
49957
|
+
handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager);
|
|
49958
|
+
}
|
|
49959
|
+
function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49960
|
+
if (typeof msg.id !== "string") return;
|
|
49961
|
+
const socket = getWs();
|
|
49962
|
+
if (!socket) return;
|
|
49963
|
+
handleFileBrowserSearch(
|
|
49964
|
+
msg,
|
|
49965
|
+
socket,
|
|
49966
|
+
e2ee,
|
|
49967
|
+
sessionWorktreeManager
|
|
49968
|
+
);
|
|
49969
|
+
}
|
|
49970
|
+
|
|
49971
|
+
// src/code-nav/handlers/send-code-nav-response.ts
|
|
49972
|
+
var ENCRYPTED_FIELDS = ["definition", "definitions", "references", "symbols", "confidentTarget"];
|
|
49973
|
+
function sendCodeNavResponse(socket, e2ee, payload) {
|
|
49974
|
+
const fieldsToEncrypt = ENCRYPTED_FIELDS.filter((field) => field in payload && payload[field] !== void 0);
|
|
49975
|
+
sendWsMessage(
|
|
49976
|
+
socket,
|
|
49977
|
+
e2ee && fieldsToEncrypt.length > 0 ? e2ee.encryptFields(payload, [...fieldsToEncrypt]) : payload
|
|
49978
|
+
);
|
|
49979
|
+
}
|
|
49980
|
+
|
|
49981
|
+
// src/code-nav/handlers/handle-code-nav-request.ts
|
|
49982
|
+
function handleCodeNavRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
49983
|
+
void (async () => {
|
|
49984
|
+
const body = await executeCodeNavRequest(msg, sessionWorktreeManager);
|
|
49985
|
+
sendCodeNavResponse(socket, e2ee, {
|
|
49986
|
+
type: "code_nav_response",
|
|
49987
|
+
id: msg.id,
|
|
49988
|
+
...body
|
|
49989
|
+
});
|
|
49990
|
+
})();
|
|
49991
|
+
}
|
|
49992
|
+
|
|
49993
|
+
// src/code-nav/handlers/trigger-symbol-index-build.ts
|
|
49994
|
+
init_normalize_resolved_path();
|
|
49995
|
+
|
|
49996
|
+
// src/routing/handlers/code-nav-messages.ts
|
|
49997
|
+
function handleFileBrowserCodeNavMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
49998
|
+
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
49999
|
+
const socket = getWs();
|
|
50000
|
+
if (!socket) return;
|
|
50001
|
+
handleCodeNavRequest(
|
|
50002
|
+
{
|
|
50003
|
+
id: msg.id,
|
|
50004
|
+
type: "code_nav",
|
|
50005
|
+
op: msg.op === "references" ? "references" : msg.op === "symbols" ? "symbols" : msg.op === "definitions" ? "definitions" : "definition",
|
|
50006
|
+
path: msg.path,
|
|
50007
|
+
line: typeof msg.line === "number" ? msg.line : 1,
|
|
50008
|
+
column: typeof msg.column === "number" ? msg.column : 0,
|
|
50009
|
+
sessionId: msg.sessionId
|
|
50010
|
+
},
|
|
50011
|
+
socket,
|
|
50012
|
+
e2ee,
|
|
50013
|
+
sessionWorktreeManager
|
|
50014
|
+
);
|
|
50015
|
+
}
|
|
49685
50016
|
|
|
49686
50017
|
// src/git/bridge-git-context.ts
|
|
49687
|
-
import * as
|
|
50018
|
+
import * as path81 from "node:path";
|
|
49688
50019
|
init_yield_to_event_loop();
|
|
49689
50020
|
|
|
49690
50021
|
// src/git/branches/get-current-branch.ts
|
|
@@ -49735,12 +50066,12 @@ async function listRepoBranchRefs(repoPath) {
|
|
|
49735
50066
|
// src/git/bridge-git-context.ts
|
|
49736
50067
|
function folderNameForRelPath(relPath, bridgeRoot) {
|
|
49737
50068
|
if (relPath === "." || relPath === "") {
|
|
49738
|
-
return
|
|
50069
|
+
return path81.basename(path81.resolve(bridgeRoot)) || "repo";
|
|
49739
50070
|
}
|
|
49740
|
-
return
|
|
50071
|
+
return path81.basename(relPath) || relPath;
|
|
49741
50072
|
}
|
|
49742
50073
|
async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
49743
|
-
const root =
|
|
50074
|
+
const root = path81.resolve(bridgeRoot);
|
|
49744
50075
|
if (await isGitRepoDirectory(root)) {
|
|
49745
50076
|
const remoteUrl = await getRemoteOriginUrl(root);
|
|
49746
50077
|
return [{ absolutePath: root, remoteUrl }];
|
|
@@ -49748,19 +50079,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
|
49748
50079
|
const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
|
|
49749
50080
|
const byPath = /* @__PURE__ */ new Map();
|
|
49750
50081
|
for (const repo of [...deep, ...shallow]) {
|
|
49751
|
-
byPath.set(
|
|
50082
|
+
byPath.set(path81.resolve(repo.absolutePath), repo);
|
|
49752
50083
|
}
|
|
49753
50084
|
return [...byPath.values()];
|
|
49754
50085
|
}
|
|
49755
50086
|
async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
49756
|
-
const bridgeResolved =
|
|
50087
|
+
const bridgeResolved = path81.resolve(bridgeRoot);
|
|
49757
50088
|
const repos = await discoverGitReposForBridgeContext(bridgeResolved);
|
|
49758
50089
|
const rows = [];
|
|
49759
50090
|
for (let i = 0; i < repos.length; i++) {
|
|
49760
50091
|
if (i > 0) await yieldToEventLoop();
|
|
49761
50092
|
const repo = repos[i];
|
|
49762
|
-
let rel =
|
|
49763
|
-
if (rel.startsWith("..") ||
|
|
50093
|
+
let rel = path81.relative(bridgeResolved, repo.absolutePath);
|
|
50094
|
+
if (rel.startsWith("..") || path81.isAbsolute(rel)) continue;
|
|
49764
50095
|
const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
|
|
49765
50096
|
const currentBranch = await getCurrentBranch(repo.absolutePath);
|
|
49766
50097
|
const remoteUrl = repo.remoteUrl.trim() || null;
|
|
@@ -49775,11 +50106,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
|
49775
50106
|
return rows;
|
|
49776
50107
|
}
|
|
49777
50108
|
async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
49778
|
-
const bridgeResolved =
|
|
50109
|
+
const bridgeResolved = path81.resolve(bridgeRoot);
|
|
49779
50110
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
49780
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
49781
|
-
const resolved =
|
|
49782
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
50111
|
+
const repoPath = rel === "" ? bridgeResolved : path81.join(bridgeResolved, rel);
|
|
50112
|
+
const resolved = path81.resolve(repoPath);
|
|
50113
|
+
if (!resolved.startsWith(bridgeResolved + path81.sep) && resolved !== bridgeResolved) {
|
|
49783
50114
|
return [];
|
|
49784
50115
|
}
|
|
49785
50116
|
return listRepoBranchRefs(resolved);
|
|
@@ -49828,80 +50159,64 @@ function handleListRepoBranchesRequestMessage(msg, getWs) {
|
|
|
49828
50159
|
})();
|
|
49829
50160
|
}
|
|
49830
50161
|
|
|
49831
|
-
// src/routing/dispatch-
|
|
50162
|
+
// src/routing/dispatch/file-browser.ts
|
|
50163
|
+
function dispatchBridgeFileBrowserMessage(msg, deps) {
|
|
50164
|
+
switch (msg.type) {
|
|
50165
|
+
case "file_browser_request":
|
|
50166
|
+
handleFileBrowserRequestMessage(msg, deps);
|
|
50167
|
+
break;
|
|
50168
|
+
case "file_browser_search":
|
|
50169
|
+
handleFileBrowserSearchMessage(msg, deps);
|
|
50170
|
+
break;
|
|
50171
|
+
case "code_nav":
|
|
50172
|
+
handleFileBrowserCodeNavMessage(msg, deps);
|
|
50173
|
+
break;
|
|
50174
|
+
case "bridge_git_context_request":
|
|
50175
|
+
handleBridgeGitContextRequestMessage(msg, deps.getWs);
|
|
50176
|
+
break;
|
|
50177
|
+
case "list_repo_branches_request":
|
|
50178
|
+
handleListRepoBranchesRequestMessage(msg, deps.getWs);
|
|
50179
|
+
break;
|
|
50180
|
+
}
|
|
50181
|
+
}
|
|
50182
|
+
|
|
50183
|
+
// src/routing/dispatch/index.ts
|
|
49832
50184
|
function dispatchBridgeMessage(msg, deps) {
|
|
49833
50185
|
switch (msg.type) {
|
|
49834
50186
|
case "auth_token":
|
|
49835
|
-
handleAuthToken(msg, deps);
|
|
49836
|
-
break;
|
|
49837
50187
|
case "bridge_identified":
|
|
49838
|
-
handleBridgeIdentified(msg, deps);
|
|
49839
|
-
break;
|
|
49840
50188
|
case "ha":
|
|
49841
|
-
|
|
50189
|
+
dispatchBridgeConnectionMessage(msg, deps);
|
|
49842
50190
|
break;
|
|
49843
50191
|
case "preview_environments_config":
|
|
49844
|
-
handlePreviewEnvironmentsConfig(msg, deps);
|
|
49845
|
-
break;
|
|
49846
50192
|
case "preview_environment_control":
|
|
49847
|
-
handlePreviewEnvironmentControl(msg, deps);
|
|
49848
|
-
break;
|
|
49849
50193
|
case "deploy_session_to_preview":
|
|
49850
|
-
|
|
50194
|
+
dispatchBridgePreviewMessage(msg, deps);
|
|
49851
50195
|
break;
|
|
49852
50196
|
case "agent_config":
|
|
49853
|
-
handleAgentConfigMessage(msg, deps);
|
|
49854
|
-
break;
|
|
49855
50197
|
case "prompt_queue_state":
|
|
49856
|
-
handlePromptQueueStateMessage(msg, deps);
|
|
49857
|
-
break;
|
|
49858
50198
|
case "prompt":
|
|
49859
|
-
handlePromptMessage(msg, deps);
|
|
49860
|
-
break;
|
|
49861
50199
|
case "session_git_request":
|
|
49862
|
-
handleSessionGitRequestMessage(msg, deps);
|
|
49863
|
-
break;
|
|
49864
50200
|
case "rename_session_branch":
|
|
49865
|
-
handleRenameSessionBranchMessage(msg, deps);
|
|
49866
|
-
break;
|
|
49867
50201
|
case "session_archived":
|
|
49868
|
-
handleSessionArchivedMessage(msg, deps);
|
|
49869
|
-
break;
|
|
49870
50202
|
case "session_discarded":
|
|
49871
|
-
handleSessionDiscardedMessage(msg, deps);
|
|
49872
|
-
break;
|
|
49873
50203
|
case "revert_turn_snapshot":
|
|
49874
|
-
handleRevertTurnSnapshotMessage(msg, deps);
|
|
49875
|
-
break;
|
|
49876
50204
|
case "cursor_request_response":
|
|
49877
|
-
|
|
50205
|
+
dispatchBridgeSessionMessage(msg, deps);
|
|
49878
50206
|
break;
|
|
49879
50207
|
case "skill_call":
|
|
49880
|
-
handleSkillCallMessage(msg, deps);
|
|
49881
|
-
break;
|
|
49882
|
-
case "file_browser_request":
|
|
49883
|
-
handleFileBrowserRequestMessage(msg, deps);
|
|
49884
|
-
break;
|
|
49885
|
-
case "file_browser_search":
|
|
49886
|
-
handleFileBrowserSearchMessage(msg, deps);
|
|
49887
|
-
break;
|
|
49888
|
-
case "code_nav":
|
|
49889
|
-
handleFileBrowserCodeNavMessage(msg, deps);
|
|
49890
|
-
break;
|
|
49891
50208
|
case "skill_layout_request":
|
|
49892
|
-
handleSkillLayoutRequest(msg, deps);
|
|
49893
|
-
break;
|
|
49894
50209
|
case "install_skills":
|
|
49895
|
-
|
|
49896
|
-
break;
|
|
50210
|
+
case "install_agent":
|
|
49897
50211
|
case "refresh_local_skills":
|
|
49898
|
-
|
|
50212
|
+
dispatchBridgeSkillsMessage(msg, deps);
|
|
49899
50213
|
break;
|
|
50214
|
+
case "file_browser_request":
|
|
50215
|
+
case "file_browser_search":
|
|
50216
|
+
case "code_nav":
|
|
49900
50217
|
case "bridge_git_context_request":
|
|
49901
|
-
handleBridgeGitContextRequestMessage(msg, deps.getWs);
|
|
49902
|
-
break;
|
|
49903
50218
|
case "list_repo_branches_request":
|
|
49904
|
-
|
|
50219
|
+
dispatchBridgeFileBrowserMessage(msg, deps);
|
|
49905
50220
|
break;
|
|
49906
50221
|
}
|
|
49907
50222
|
}
|
|
@@ -50295,15 +50610,18 @@ async function runConnectedBridge(options, restartWithoutAuth) {
|
|
|
50295
50610
|
const firehoseServerUrl = options.firehoseServerUrl ?? options.proxyServerUrl;
|
|
50296
50611
|
let cleanupKeyCommand;
|
|
50297
50612
|
let bridgeClose = null;
|
|
50613
|
+
let shutdownStarted = false;
|
|
50298
50614
|
const onSignal = (kind) => {
|
|
50299
50615
|
requestCliImmediateShutdown();
|
|
50300
50616
|
abortActiveGitChildProcesses();
|
|
50301
50617
|
cleanupKeyCommand?.();
|
|
50618
|
+
if (shutdownStarted) return;
|
|
50619
|
+
shutdownStarted = true;
|
|
50302
50620
|
logImmediate(
|
|
50303
50621
|
kind === "interrupt" ? "Keyboard interrupt (Ctrl+C) \u2014 stopping\u2026" : "Stop requested \u2014 shutting down\u2026"
|
|
50304
50622
|
);
|
|
50305
50623
|
if (bridgeClose) {
|
|
50306
|
-
void bridgeClose().
|
|
50624
|
+
void bridgeClose().finally(() => process.exit(0));
|
|
50307
50625
|
return;
|
|
50308
50626
|
}
|
|
50309
50627
|
process.exit(0);
|