@buildautomaton/cli 0.1.51 → 0.1.53
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 +719 -312
- package/dist/cli.js.map +4 -4
- package/dist/index.js +704 -297
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4175,8 +4175,8 @@ var init_parseUtil = __esm({
|
|
|
4175
4175
|
init_errors();
|
|
4176
4176
|
init_en();
|
|
4177
4177
|
makeIssue = (params) => {
|
|
4178
|
-
const { data, path:
|
|
4179
|
-
const fullPath = [...
|
|
4178
|
+
const { data, path: path61, errorMaps, issueData } = params;
|
|
4179
|
+
const fullPath = [...path61, ...issueData.path || []];
|
|
4180
4180
|
const fullIssue = {
|
|
4181
4181
|
...issueData,
|
|
4182
4182
|
path: fullPath
|
|
@@ -4484,11 +4484,11 @@ var init_types = __esm({
|
|
|
4484
4484
|
init_parseUtil();
|
|
4485
4485
|
init_util();
|
|
4486
4486
|
ParseInputLazyPath = class {
|
|
4487
|
-
constructor(parent, value,
|
|
4487
|
+
constructor(parent, value, path61, key) {
|
|
4488
4488
|
this._cachedPath = [];
|
|
4489
4489
|
this.parent = parent;
|
|
4490
4490
|
this.data = value;
|
|
4491
|
-
this._path =
|
|
4491
|
+
this._path = path61;
|
|
4492
4492
|
this._key = key;
|
|
4493
4493
|
}
|
|
4494
4494
|
get path() {
|
|
@@ -8103,10 +8103,10 @@ function assignProp(target, prop, value) {
|
|
|
8103
8103
|
configurable: true
|
|
8104
8104
|
});
|
|
8105
8105
|
}
|
|
8106
|
-
function getElementAtPath(obj,
|
|
8107
|
-
if (!
|
|
8106
|
+
function getElementAtPath(obj, path61) {
|
|
8107
|
+
if (!path61)
|
|
8108
8108
|
return obj;
|
|
8109
|
-
return
|
|
8109
|
+
return path61.reduce((acc, key) => acc?.[key], obj);
|
|
8110
8110
|
}
|
|
8111
8111
|
function promiseAllObject(promisesObj) {
|
|
8112
8112
|
const keys = Object.keys(promisesObj);
|
|
@@ -8355,11 +8355,11 @@ function aborted(x, startIndex = 0) {
|
|
|
8355
8355
|
}
|
|
8356
8356
|
return false;
|
|
8357
8357
|
}
|
|
8358
|
-
function prefixIssues(
|
|
8358
|
+
function prefixIssues(path61, issues) {
|
|
8359
8359
|
return issues.map((iss) => {
|
|
8360
8360
|
var _a2;
|
|
8361
8361
|
(_a2 = iss).path ?? (_a2.path = []);
|
|
8362
|
-
iss.path.unshift(
|
|
8362
|
+
iss.path.unshift(path61);
|
|
8363
8363
|
return iss;
|
|
8364
8364
|
});
|
|
8365
8365
|
}
|
|
@@ -8548,7 +8548,7 @@ function treeifyError(error40, _mapper) {
|
|
|
8548
8548
|
return issue2.message;
|
|
8549
8549
|
};
|
|
8550
8550
|
const result = { errors: [] };
|
|
8551
|
-
const processError = (error41,
|
|
8551
|
+
const processError = (error41, path61 = []) => {
|
|
8552
8552
|
var _a2, _b;
|
|
8553
8553
|
for (const issue2 of error41.issues) {
|
|
8554
8554
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -8558,7 +8558,7 @@ function treeifyError(error40, _mapper) {
|
|
|
8558
8558
|
} else if (issue2.code === "invalid_element") {
|
|
8559
8559
|
processError({ issues: issue2.issues }, issue2.path);
|
|
8560
8560
|
} else {
|
|
8561
|
-
const fullpath = [...
|
|
8561
|
+
const fullpath = [...path61, ...issue2.path];
|
|
8562
8562
|
if (fullpath.length === 0) {
|
|
8563
8563
|
result.errors.push(mapper(issue2));
|
|
8564
8564
|
continue;
|
|
@@ -8588,9 +8588,9 @@ function treeifyError(error40, _mapper) {
|
|
|
8588
8588
|
processError(error40);
|
|
8589
8589
|
return result;
|
|
8590
8590
|
}
|
|
8591
|
-
function toDotPath(
|
|
8591
|
+
function toDotPath(path61) {
|
|
8592
8592
|
const segs = [];
|
|
8593
|
-
for (const seg of
|
|
8593
|
+
for (const seg of path61) {
|
|
8594
8594
|
if (typeof seg === "number")
|
|
8595
8595
|
segs.push(`[${seg}]`);
|
|
8596
8596
|
else if (typeof seg === "symbol")
|
|
@@ -21053,8 +21053,8 @@ var init_acp = __esm({
|
|
|
21053
21053
|
this.#requestHandler = requestHandler;
|
|
21054
21054
|
this.#notificationHandler = notificationHandler;
|
|
21055
21055
|
this.#stream = stream;
|
|
21056
|
-
this.#closedPromise = new Promise((
|
|
21057
|
-
this.#abortController.signal.addEventListener("abort", () =>
|
|
21056
|
+
this.#closedPromise = new Promise((resolve33) => {
|
|
21057
|
+
this.#abortController.signal.addEventListener("abort", () => resolve33());
|
|
21058
21058
|
});
|
|
21059
21059
|
this.#receive();
|
|
21060
21060
|
}
|
|
@@ -21203,8 +21203,8 @@ var init_acp = __esm({
|
|
|
21203
21203
|
}
|
|
21204
21204
|
async sendRequest(method, params) {
|
|
21205
21205
|
const id = this.#nextRequestId++;
|
|
21206
|
-
const responsePromise = new Promise((
|
|
21207
|
-
this.#pendingResponses.set(id, { resolve:
|
|
21206
|
+
const responsePromise = new Promise((resolve33, reject) => {
|
|
21207
|
+
this.#pendingResponses.set(id, { resolve: resolve33, reject });
|
|
21208
21208
|
});
|
|
21209
21209
|
await this.#sendMessage({ jsonrpc: "2.0", id, method, params });
|
|
21210
21210
|
return responsePromise;
|
|
@@ -22073,10 +22073,10 @@ var require_src2 = __commonJS({
|
|
|
22073
22073
|
var fs_1 = __require("fs");
|
|
22074
22074
|
var debug_1 = __importDefault(require_src());
|
|
22075
22075
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
22076
|
-
function check2(
|
|
22077
|
-
log2(`checking %s`,
|
|
22076
|
+
function check2(path61, isFile, isDirectory) {
|
|
22077
|
+
log2(`checking %s`, path61);
|
|
22078
22078
|
try {
|
|
22079
|
-
const stat2 = fs_1.statSync(
|
|
22079
|
+
const stat2 = fs_1.statSync(path61);
|
|
22080
22080
|
if (stat2.isFile() && isFile) {
|
|
22081
22081
|
log2(`[OK] path represents a file`);
|
|
22082
22082
|
return true;
|
|
@@ -22096,8 +22096,8 @@ var require_src2 = __commonJS({
|
|
|
22096
22096
|
throw e;
|
|
22097
22097
|
}
|
|
22098
22098
|
}
|
|
22099
|
-
function exists2(
|
|
22100
|
-
return check2(
|
|
22099
|
+
function exists2(path61, type = exports.READABLE) {
|
|
22100
|
+
return check2(path61, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
22101
22101
|
}
|
|
22102
22102
|
exports.exists = exists2;
|
|
22103
22103
|
exports.FILE = 1;
|
|
@@ -22446,10 +22446,10 @@ async function killChildProcessTreeGracefully(child, graceMs = ACP_PROCESS_TREE_
|
|
|
22446
22446
|
}
|
|
22447
22447
|
await killProcessTree(pid, "SIGTERM");
|
|
22448
22448
|
if (graceMs <= 0) return;
|
|
22449
|
-
const exited = new Promise((
|
|
22450
|
-
child.once("exit", () =>
|
|
22449
|
+
const exited = new Promise((resolve33) => {
|
|
22450
|
+
child.once("exit", () => resolve33());
|
|
22451
22451
|
});
|
|
22452
|
-
await Promise.race([exited, new Promise((
|
|
22452
|
+
await Promise.race([exited, new Promise((resolve33) => setTimeout(resolve33, graceMs))]);
|
|
22453
22453
|
if (child.exitCode == null && child.signalCode == null) {
|
|
22454
22454
|
await killProcessTree(pid, "SIGKILL");
|
|
22455
22455
|
}
|
|
@@ -22466,8 +22466,8 @@ async function gracefulAcpSubprocessDisconnect(params) {
|
|
|
22466
22466
|
await transport.closeSession?.(sessionId);
|
|
22467
22467
|
} catch {
|
|
22468
22468
|
}
|
|
22469
|
-
await new Promise((
|
|
22470
|
-
const timer = setTimeout(
|
|
22469
|
+
await new Promise((resolve33) => {
|
|
22470
|
+
const timer = setTimeout(resolve33, ACP_GRACEFUL_SESSION_CLOSE_WAIT_MS);
|
|
22471
22471
|
timer.unref?.();
|
|
22472
22472
|
});
|
|
22473
22473
|
}
|
|
@@ -23172,9 +23172,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
|
23172
23172
|
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
23173
23173
|
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
23174
23174
|
if (!rawPath || !summary) continue;
|
|
23175
|
-
const
|
|
23176
|
-
if (!
|
|
23177
|
-
rows.push({ path:
|
|
23175
|
+
const path61 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
23176
|
+
if (!path61) continue;
|
|
23177
|
+
rows.push({ path: path61, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
23178
23178
|
}
|
|
23179
23179
|
return rows;
|
|
23180
23180
|
}
|
|
@@ -23402,6 +23402,11 @@ var BRIDGE_MCP_TOOL_LABELS = {
|
|
|
23402
23402
|
[GET_PARENT_SESSION_TURN_TRANSCRIPT_TOOL]: "Read parent session transcript"
|
|
23403
23403
|
};
|
|
23404
23404
|
|
|
23405
|
+
// ../types/src/prompts/server.ts
|
|
23406
|
+
function isRunnableBridgePromptTurnServerState(state) {
|
|
23407
|
+
return state === "queued" || state === "requeued" || state === "requeued_with_revert";
|
|
23408
|
+
}
|
|
23409
|
+
|
|
23405
23410
|
// ../types/src/claude-code-permission-mode.ts
|
|
23406
23411
|
var CLAUDE_CODE_PERMISSION_MODES = [
|
|
23407
23412
|
"default",
|
|
@@ -23628,11 +23633,11 @@ function createSdkStdioExtNotificationHandler(options) {
|
|
|
23628
23633
|
// src/agents/acp/clients/sdk/sdk-stdio-permission-request-handshake.ts
|
|
23629
23634
|
function awaitSdkStdioPermissionRequestHandshake(params) {
|
|
23630
23635
|
const { requestId, paramsRecord, pending, onRequest } = params;
|
|
23631
|
-
return new Promise((
|
|
23632
|
-
pending.set(requestId, { resolve:
|
|
23636
|
+
return new Promise((resolve33) => {
|
|
23637
|
+
pending.set(requestId, { resolve: resolve33, params: paramsRecord });
|
|
23633
23638
|
if (onRequest == null) {
|
|
23634
23639
|
pending.delete(requestId);
|
|
23635
|
-
|
|
23640
|
+
resolve33({ outcome: { outcome: "denied" } });
|
|
23636
23641
|
return;
|
|
23637
23642
|
}
|
|
23638
23643
|
try {
|
|
@@ -24176,10 +24181,10 @@ function createSdkStdioInitSettle(child) {
|
|
|
24176
24181
|
forceAcpSubprocessDisconnect(child);
|
|
24177
24182
|
reject(err);
|
|
24178
24183
|
},
|
|
24179
|
-
settleResolve(
|
|
24184
|
+
settleResolve(resolve33, handle) {
|
|
24180
24185
|
if (initSettled) return;
|
|
24181
24186
|
initSettled = true;
|
|
24182
|
-
|
|
24187
|
+
resolve33(handle);
|
|
24183
24188
|
}
|
|
24184
24189
|
};
|
|
24185
24190
|
}
|
|
@@ -24248,7 +24253,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
24248
24253
|
onFileChange,
|
|
24249
24254
|
stderrCapture
|
|
24250
24255
|
});
|
|
24251
|
-
return new Promise((
|
|
24256
|
+
return new Promise((resolve33, reject) => {
|
|
24252
24257
|
const init = createSdkStdioInitSettle(child);
|
|
24253
24258
|
child.on("error", (err) => {
|
|
24254
24259
|
init.settleReject(reject, new Error(formatSpawnError(err, command[0])));
|
|
@@ -24273,7 +24278,7 @@ async function createSdkStdioAcpClient(options) {
|
|
|
24273
24278
|
protocolVersion: PROTOCOL_VERSION2
|
|
24274
24279
|
});
|
|
24275
24280
|
init.settleResolve(
|
|
24276
|
-
|
|
24281
|
+
resolve33,
|
|
24277
24282
|
createSdkStdioHandle({
|
|
24278
24283
|
child,
|
|
24279
24284
|
sessionId: established.sessionId,
|
|
@@ -24381,7 +24386,7 @@ async function proxyToLocal(request) {
|
|
|
24381
24386
|
};
|
|
24382
24387
|
const maxAttempts = isIdempotentProxyMethod(request.method) ? LOCAL_PREVIEW_FETCH_RETRY_DELAYS_MS.length + 1 : 1;
|
|
24383
24388
|
for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
|
|
24384
|
-
const once = await new Promise((
|
|
24389
|
+
const once = await new Promise((resolve33) => {
|
|
24385
24390
|
const req = mod.request(opts, (res) => {
|
|
24386
24391
|
const chunks = [];
|
|
24387
24392
|
res.on("data", (c) => chunks.push(c));
|
|
@@ -24392,7 +24397,7 @@ async function proxyToLocal(request) {
|
|
|
24392
24397
|
if (typeof v === "string") headers[k] = v;
|
|
24393
24398
|
else if (Array.isArray(v) && v[0]) headers[k] = v[0];
|
|
24394
24399
|
}
|
|
24395
|
-
|
|
24400
|
+
resolve33({
|
|
24396
24401
|
id: request.id,
|
|
24397
24402
|
statusCode: res.statusCode ?? 0,
|
|
24398
24403
|
headers,
|
|
@@ -24401,7 +24406,7 @@ async function proxyToLocal(request) {
|
|
|
24401
24406
|
});
|
|
24402
24407
|
});
|
|
24403
24408
|
req.on("error", (err) => {
|
|
24404
|
-
|
|
24409
|
+
resolve33({
|
|
24405
24410
|
id: request.id,
|
|
24406
24411
|
statusCode: 0,
|
|
24407
24412
|
headers: {},
|
|
@@ -24483,8 +24488,8 @@ function randomSecret() {
|
|
|
24483
24488
|
}
|
|
24484
24489
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
24485
24490
|
}
|
|
24486
|
-
async function requestPreviewApi(port, secret, method,
|
|
24487
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
24491
|
+
async function requestPreviewApi(port, secret, method, path61, body) {
|
|
24492
|
+
const url2 = `http://127.0.0.1:${port}${path61}`;
|
|
24488
24493
|
const headers = {
|
|
24489
24494
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
24490
24495
|
"Content-Type": "application/json"
|
|
@@ -24496,7 +24501,7 @@ async function requestPreviewApi(port, secret, method, path60, body) {
|
|
|
24496
24501
|
});
|
|
24497
24502
|
const data = await res.json().catch(() => ({}));
|
|
24498
24503
|
if (!res.ok) {
|
|
24499
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
24504
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path61}: ${res.status}`);
|
|
24500
24505
|
}
|
|
24501
24506
|
return data;
|
|
24502
24507
|
}
|
|
@@ -24711,7 +24716,7 @@ function installBridgeProcessResilience() {
|
|
|
24711
24716
|
}
|
|
24712
24717
|
|
|
24713
24718
|
// src/cli-version.ts
|
|
24714
|
-
var CLI_VERSION = "0.1.
|
|
24719
|
+
var CLI_VERSION = "0.1.53".length > 0 ? "0.1.53" : "0.0.0-dev";
|
|
24715
24720
|
|
|
24716
24721
|
// src/connection/heartbeat/constants.ts
|
|
24717
24722
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -25152,14 +25157,14 @@ var baseOpen = async (options) => {
|
|
|
25152
25157
|
}
|
|
25153
25158
|
const subprocess = childProcess.spawn(command, cliArguments, childProcessOptions);
|
|
25154
25159
|
if (options.wait) {
|
|
25155
|
-
return new Promise((
|
|
25160
|
+
return new Promise((resolve33, reject) => {
|
|
25156
25161
|
subprocess.once("error", reject);
|
|
25157
25162
|
subprocess.once("close", (exitCode) => {
|
|
25158
25163
|
if (!options.allowNonzeroExitCode && exitCode > 0) {
|
|
25159
25164
|
reject(new Error(`Exited with code ${exitCode}`));
|
|
25160
25165
|
return;
|
|
25161
25166
|
}
|
|
25162
|
-
|
|
25167
|
+
resolve33(subprocess);
|
|
25163
25168
|
});
|
|
25164
25169
|
});
|
|
25165
25170
|
}
|
|
@@ -25703,8 +25708,8 @@ function runPendingAuth(options) {
|
|
|
25703
25708
|
let hasOpenedBrowser = false;
|
|
25704
25709
|
let resolved = false;
|
|
25705
25710
|
let resolveAuth;
|
|
25706
|
-
const authPromise = new Promise((
|
|
25707
|
-
resolveAuth =
|
|
25711
|
+
const authPromise = new Promise((resolve33) => {
|
|
25712
|
+
resolveAuth = resolve33;
|
|
25708
25713
|
});
|
|
25709
25714
|
let reconnectAttempt = 0;
|
|
25710
25715
|
const signInQuiet = createEmptyReconnectQuietSlot();
|
|
@@ -25855,7 +25860,7 @@ import sqliteWasm from "node-sqlite3-wasm";
|
|
|
25855
25860
|
|
|
25856
25861
|
// src/runtime/yield-to-event-loop.ts
|
|
25857
25862
|
function yieldToEventLoop() {
|
|
25858
|
-
return new Promise((
|
|
25863
|
+
return new Promise((resolve33) => setImmediate(resolve33));
|
|
25859
25864
|
}
|
|
25860
25865
|
|
|
25861
25866
|
// src/sqlite/cli-sqlite-paths.ts
|
|
@@ -27019,7 +27024,7 @@ async function createCursorAcpClient(options) {
|
|
|
27019
27024
|
onFileChange,
|
|
27020
27025
|
stderrCapture
|
|
27021
27026
|
});
|
|
27022
|
-
return new Promise((
|
|
27027
|
+
return new Promise((resolve33, reject) => {
|
|
27023
27028
|
child.on("error", (err) => {
|
|
27024
27029
|
killChildProcessTree(child, "SIGKILL");
|
|
27025
27030
|
reject(new Error(formatSpawnError(err, command[0])));
|
|
@@ -27031,7 +27036,7 @@ async function createCursorAcpClient(options) {
|
|
|
27031
27036
|
sessionCtx,
|
|
27032
27037
|
incomingDeps: { dbgFs, sessionCtx, onSessionUpdate, onRequest }
|
|
27033
27038
|
});
|
|
27034
|
-
|
|
27039
|
+
resolve33(
|
|
27035
27040
|
createCursorAcpHandle({
|
|
27036
27041
|
child,
|
|
27037
27042
|
sessionId: established.sessionId,
|
|
@@ -28237,8 +28242,8 @@ function pathspec(...paths) {
|
|
|
28237
28242
|
cache.set(key, paths);
|
|
28238
28243
|
return key;
|
|
28239
28244
|
}
|
|
28240
|
-
function isPathSpec(
|
|
28241
|
-
return
|
|
28245
|
+
function isPathSpec(path61) {
|
|
28246
|
+
return path61 instanceof String && cache.has(path61);
|
|
28242
28247
|
}
|
|
28243
28248
|
function toPaths(pathSpec) {
|
|
28244
28249
|
return cache.get(pathSpec) || [];
|
|
@@ -28327,8 +28332,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
28327
28332
|
function forEachLineWithContent(input, callback) {
|
|
28328
28333
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
28329
28334
|
}
|
|
28330
|
-
function folderExists(
|
|
28331
|
-
return (0, import_file_exists.exists)(
|
|
28335
|
+
function folderExists(path61) {
|
|
28336
|
+
return (0, import_file_exists.exists)(path61, import_file_exists.FOLDER);
|
|
28332
28337
|
}
|
|
28333
28338
|
function append(target, item) {
|
|
28334
28339
|
if (Array.isArray(target)) {
|
|
@@ -28732,8 +28737,8 @@ function checkIsRepoRootTask() {
|
|
|
28732
28737
|
commands,
|
|
28733
28738
|
format: "utf-8",
|
|
28734
28739
|
onError,
|
|
28735
|
-
parser(
|
|
28736
|
-
return /^\.(git)?$/.test(
|
|
28740
|
+
parser(path61) {
|
|
28741
|
+
return /^\.(git)?$/.test(path61.trim());
|
|
28737
28742
|
}
|
|
28738
28743
|
};
|
|
28739
28744
|
}
|
|
@@ -29167,11 +29172,11 @@ function parseGrep(grep) {
|
|
|
29167
29172
|
const paths = /* @__PURE__ */ new Set();
|
|
29168
29173
|
const results = {};
|
|
29169
29174
|
forEachLineWithContent(grep, (input) => {
|
|
29170
|
-
const [
|
|
29171
|
-
paths.add(
|
|
29172
|
-
(results[
|
|
29175
|
+
const [path61, line, preview] = input.split(NULL);
|
|
29176
|
+
paths.add(path61);
|
|
29177
|
+
(results[path61] = results[path61] || []).push({
|
|
29173
29178
|
line: asNumber(line),
|
|
29174
|
-
path:
|
|
29179
|
+
path: path61,
|
|
29175
29180
|
preview
|
|
29176
29181
|
});
|
|
29177
29182
|
});
|
|
@@ -29936,14 +29941,14 @@ var init_hash_object = __esm2({
|
|
|
29936
29941
|
init_task();
|
|
29937
29942
|
}
|
|
29938
29943
|
});
|
|
29939
|
-
function parseInit(bare,
|
|
29944
|
+
function parseInit(bare, path61, text) {
|
|
29940
29945
|
const response = String(text).trim();
|
|
29941
29946
|
let result;
|
|
29942
29947
|
if (result = initResponseRegex.exec(response)) {
|
|
29943
|
-
return new InitSummary(bare,
|
|
29948
|
+
return new InitSummary(bare, path61, false, result[1]);
|
|
29944
29949
|
}
|
|
29945
29950
|
if (result = reInitResponseRegex.exec(response)) {
|
|
29946
|
-
return new InitSummary(bare,
|
|
29951
|
+
return new InitSummary(bare, path61, true, result[1]);
|
|
29947
29952
|
}
|
|
29948
29953
|
let gitDir = "";
|
|
29949
29954
|
const tokens = response.split(" ");
|
|
@@ -29954,7 +29959,7 @@ function parseInit(bare, path60, text) {
|
|
|
29954
29959
|
break;
|
|
29955
29960
|
}
|
|
29956
29961
|
}
|
|
29957
|
-
return new InitSummary(bare,
|
|
29962
|
+
return new InitSummary(bare, path61, /^re/i.test(response), gitDir);
|
|
29958
29963
|
}
|
|
29959
29964
|
var InitSummary;
|
|
29960
29965
|
var initResponseRegex;
|
|
@@ -29963,9 +29968,9 @@ var init_InitSummary = __esm2({
|
|
|
29963
29968
|
"src/lib/responses/InitSummary.ts"() {
|
|
29964
29969
|
"use strict";
|
|
29965
29970
|
InitSummary = class {
|
|
29966
|
-
constructor(bare,
|
|
29971
|
+
constructor(bare, path61, existing, gitDir) {
|
|
29967
29972
|
this.bare = bare;
|
|
29968
|
-
this.path =
|
|
29973
|
+
this.path = path61;
|
|
29969
29974
|
this.existing = existing;
|
|
29970
29975
|
this.gitDir = gitDir;
|
|
29971
29976
|
}
|
|
@@ -29977,7 +29982,7 @@ var init_InitSummary = __esm2({
|
|
|
29977
29982
|
function hasBareCommand(command) {
|
|
29978
29983
|
return command.includes(bareCommand);
|
|
29979
29984
|
}
|
|
29980
|
-
function initTask(bare = false,
|
|
29985
|
+
function initTask(bare = false, path61, customArgs) {
|
|
29981
29986
|
const commands = ["init", ...customArgs];
|
|
29982
29987
|
if (bare && !hasBareCommand(commands)) {
|
|
29983
29988
|
commands.splice(1, 0, bareCommand);
|
|
@@ -29986,7 +29991,7 @@ function initTask(bare = false, path60, customArgs) {
|
|
|
29986
29991
|
commands,
|
|
29987
29992
|
format: "utf-8",
|
|
29988
29993
|
parser(text) {
|
|
29989
|
-
return parseInit(commands.includes("--bare"),
|
|
29994
|
+
return parseInit(commands.includes("--bare"), path61, text);
|
|
29990
29995
|
}
|
|
29991
29996
|
};
|
|
29992
29997
|
}
|
|
@@ -30802,12 +30807,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
30802
30807
|
"use strict";
|
|
30803
30808
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
30804
30809
|
FileStatusSummary = class {
|
|
30805
|
-
constructor(
|
|
30806
|
-
this.path =
|
|
30810
|
+
constructor(path61, index, working_dir) {
|
|
30811
|
+
this.path = path61;
|
|
30807
30812
|
this.index = index;
|
|
30808
30813
|
this.working_dir = working_dir;
|
|
30809
30814
|
if (index === "R" || working_dir === "R") {
|
|
30810
|
-
const detail = fromPathRegex.exec(
|
|
30815
|
+
const detail = fromPathRegex.exec(path61) || [null, path61, path61];
|
|
30811
30816
|
this.from = detail[2] || "";
|
|
30812
30817
|
this.path = detail[1] || "";
|
|
30813
30818
|
}
|
|
@@ -30838,14 +30843,14 @@ function splitLine(result, lineStr) {
|
|
|
30838
30843
|
default:
|
|
30839
30844
|
return;
|
|
30840
30845
|
}
|
|
30841
|
-
function data(index, workingDir,
|
|
30846
|
+
function data(index, workingDir, path61) {
|
|
30842
30847
|
const raw = `${index}${workingDir}`;
|
|
30843
30848
|
const handler = parsers6.get(raw);
|
|
30844
30849
|
if (handler) {
|
|
30845
|
-
handler(result,
|
|
30850
|
+
handler(result, path61);
|
|
30846
30851
|
}
|
|
30847
30852
|
if (raw !== "##" && raw !== "!!") {
|
|
30848
|
-
result.files.push(new FileStatusSummary(
|
|
30853
|
+
result.files.push(new FileStatusSummary(path61, index, workingDir));
|
|
30849
30854
|
}
|
|
30850
30855
|
}
|
|
30851
30856
|
}
|
|
@@ -31154,9 +31159,9 @@ var init_simple_git_api = __esm2({
|
|
|
31154
31159
|
next
|
|
31155
31160
|
);
|
|
31156
31161
|
}
|
|
31157
|
-
hashObject(
|
|
31162
|
+
hashObject(path61, write) {
|
|
31158
31163
|
return this._runTask(
|
|
31159
|
-
hashObjectTask(
|
|
31164
|
+
hashObjectTask(path61, write === true),
|
|
31160
31165
|
trailingFunctionArgument(arguments)
|
|
31161
31166
|
);
|
|
31162
31167
|
}
|
|
@@ -31509,8 +31514,8 @@ var init_branch = __esm2({
|
|
|
31509
31514
|
}
|
|
31510
31515
|
});
|
|
31511
31516
|
function toPath(input) {
|
|
31512
|
-
const
|
|
31513
|
-
return
|
|
31517
|
+
const path61 = input.trim().replace(/^["']|["']$/g, "");
|
|
31518
|
+
return path61 && normalize3(path61);
|
|
31514
31519
|
}
|
|
31515
31520
|
var parseCheckIgnore;
|
|
31516
31521
|
var init_CheckIgnore = __esm2({
|
|
@@ -31824,8 +31829,8 @@ __export2(sub_module_exports, {
|
|
|
31824
31829
|
subModuleTask: () => subModuleTask,
|
|
31825
31830
|
updateSubModuleTask: () => updateSubModuleTask
|
|
31826
31831
|
});
|
|
31827
|
-
function addSubModuleTask(repo,
|
|
31828
|
-
return subModuleTask(["add", repo,
|
|
31832
|
+
function addSubModuleTask(repo, path61) {
|
|
31833
|
+
return subModuleTask(["add", repo, path61]);
|
|
31829
31834
|
}
|
|
31830
31835
|
function initSubModuleTask(customArgs) {
|
|
31831
31836
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -32158,8 +32163,8 @@ var require_git = __commonJS2({
|
|
|
32158
32163
|
}
|
|
32159
32164
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
32160
32165
|
};
|
|
32161
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
32162
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
32166
|
+
Git2.prototype.submoduleAdd = function(repo, path61, then) {
|
|
32167
|
+
return this._runTask(addSubModuleTask2(repo, path61), trailingFunctionArgument2(arguments));
|
|
32163
32168
|
};
|
|
32164
32169
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
32165
32170
|
return this._runTask(
|
|
@@ -32796,8 +32801,8 @@ async function runGitTask(fn) {
|
|
|
32796
32801
|
}
|
|
32797
32802
|
async function yieldToEventLoop2() {
|
|
32798
32803
|
throwIfGitShutdownRequested();
|
|
32799
|
-
await new Promise((
|
|
32800
|
-
setImmediate(
|
|
32804
|
+
await new Promise((resolve33) => {
|
|
32805
|
+
setImmediate(resolve33);
|
|
32801
32806
|
});
|
|
32802
32807
|
throwIfGitShutdownRequested();
|
|
32803
32808
|
}
|
|
@@ -32877,10 +32882,10 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
|
32877
32882
|
await yieldGitDiscoverWork(i + 1);
|
|
32878
32883
|
const ent = entries[i];
|
|
32879
32884
|
if (!ent.isDirectory()) continue;
|
|
32880
|
-
const
|
|
32881
|
-
if (await isGitRepoDirectory(
|
|
32882
|
-
const remoteUrl = await getRemoteOriginUrl(
|
|
32883
|
-
result.push({ absolutePath:
|
|
32885
|
+
const childPath2 = path16.join(cwdResolved, ent.name);
|
|
32886
|
+
if (await isGitRepoDirectory(childPath2)) {
|
|
32887
|
+
const remoteUrl = await getRemoteOriginUrl(childPath2);
|
|
32888
|
+
result.push({ absolutePath: childPath2, remoteUrl });
|
|
32884
32889
|
}
|
|
32885
32890
|
}
|
|
32886
32891
|
return result;
|
|
@@ -33132,9 +33137,9 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
33132
33137
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
33133
33138
|
async function putEncryptedChangeSummaryRows(params) {
|
|
33134
33139
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
33135
|
-
const entries = params.rows.map(({ path:
|
|
33140
|
+
const entries = params.rows.map(({ path: path61, summary }) => {
|
|
33136
33141
|
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
33137
|
-
return { path:
|
|
33142
|
+
return { path: path61, summary: JSON.stringify(enc) };
|
|
33138
33143
|
});
|
|
33139
33144
|
const res = await fetch(
|
|
33140
33145
|
`${base}/internal/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
@@ -34074,8 +34079,8 @@ async function commitSessionWorktree(cache2, params) {
|
|
|
34074
34079
|
}
|
|
34075
34080
|
|
|
34076
34081
|
// src/git/changes/parse/normalize-git-diff-path.ts
|
|
34077
|
-
function normalizeGitDiffPath(
|
|
34078
|
-
return
|
|
34082
|
+
function normalizeGitDiffPath(path61) {
|
|
34083
|
+
return path61.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
|
|
34079
34084
|
}
|
|
34080
34085
|
|
|
34081
34086
|
// src/git/changes/parse/expand-git-rename-numstat-path.ts
|
|
@@ -34175,8 +34180,8 @@ function parseNumstatEntries(lines) {
|
|
|
34175
34180
|
}
|
|
34176
34181
|
function parseNumstat(lines) {
|
|
34177
34182
|
const m = /* @__PURE__ */ new Map();
|
|
34178
|
-
for (const [
|
|
34179
|
-
m.set(
|
|
34183
|
+
for (const [path61, entry] of parseNumstatEntries(lines)) {
|
|
34184
|
+
m.set(path61, { additions: entry.additions, deletions: entry.deletions });
|
|
34180
34185
|
}
|
|
34181
34186
|
return m;
|
|
34182
34187
|
}
|
|
@@ -34614,24 +34619,45 @@ function truncatePatch(s) {
|
|
|
34614
34619
|
}
|
|
34615
34620
|
|
|
34616
34621
|
// src/git/changes/patch/unified-diff-for-file.ts
|
|
34622
|
+
var RENAME_DIFF_ARGS = ["-M", "--find-renames"];
|
|
34623
|
+
function devNullPath() {
|
|
34624
|
+
return process.platform === "win32" ? "NUL" : "/dev/null";
|
|
34625
|
+
}
|
|
34617
34626
|
function patchTextFromGitDiffOutput(raw) {
|
|
34618
34627
|
if (raw.trim() === "") return void 0;
|
|
34619
34628
|
return normalizePatchContent(raw);
|
|
34620
34629
|
}
|
|
34630
|
+
async function rawGitDiff(g, args) {
|
|
34631
|
+
return String(await g.raw([...args]).catch(() => ""));
|
|
34632
|
+
}
|
|
34633
|
+
async function unifiedDiffAgainstHead(g, pathInRepo, change, movedFromPathInRepo) {
|
|
34634
|
+
const args = change === "moved" && movedFromPathInRepo ? ["diff", "--no-color", ...RENAME_DIFF_ARGS, "HEAD", "--", movedFromPathInRepo, pathInRepo] : change === "removed" ? ["diff", "--no-color", ...RENAME_DIFF_ARGS, "HEAD", "--", pathInRepo] : ["diff", "--no-color", ...RENAME_DIFF_ARGS, "HEAD", "--", pathInRepo];
|
|
34635
|
+
return patchTextFromGitDiffOutput(await rawGitDiff(g, args));
|
|
34636
|
+
}
|
|
34637
|
+
async function unifiedDiffForAddedUntrackedFile(g, pathInRepo) {
|
|
34638
|
+
const raw = await rawGitDiff(g, [
|
|
34639
|
+
"diff",
|
|
34640
|
+
"--no-color",
|
|
34641
|
+
...RENAME_DIFF_ARGS,
|
|
34642
|
+
"--no-index",
|
|
34643
|
+
"--",
|
|
34644
|
+
devNullPath(),
|
|
34645
|
+
pathInRepo
|
|
34646
|
+
]);
|
|
34647
|
+
return patchTextFromGitDiffOutput(raw);
|
|
34648
|
+
}
|
|
34621
34649
|
async function unifiedDiffForFile(repoCwd, pathInRepo, change, movedFromPathInRepo) {
|
|
34622
34650
|
const g = cliSimpleGit(repoCwd);
|
|
34623
|
-
|
|
34624
|
-
|
|
34625
|
-
|
|
34626
|
-
|
|
34651
|
+
let patch = await unifiedDiffAgainstHead(g, pathInRepo, change, movedFromPathInRepo);
|
|
34652
|
+
if (!patch && change === "added") {
|
|
34653
|
+
patch = await unifiedDiffForAddedUntrackedFile(g, pathInRepo);
|
|
34654
|
+
}
|
|
34627
34655
|
return patch ? truncatePatch(patch) : void 0;
|
|
34628
34656
|
}
|
|
34629
34657
|
async function unifiedDiffForFileInRange(repoCwd, range, pathInRepo, change, movedFromPathInRepo) {
|
|
34630
34658
|
const g = cliSimpleGit(repoCwd);
|
|
34631
|
-
const
|
|
34632
|
-
const
|
|
34633
|
-
const raw = await g.raw([...args]).catch(() => "");
|
|
34634
|
-
const patch = patchTextFromGitDiffOutput(String(raw));
|
|
34659
|
+
const args = change === "moved" && movedFromPathInRepo ? ["diff", "--no-color", ...RENAME_DIFF_ARGS, "-U20000", range, "--", movedFromPathInRepo, pathInRepo] : ["diff", "--no-color", ...RENAME_DIFF_ARGS, "-U20000", range, "--", pathInRepo];
|
|
34660
|
+
const patch = patchTextFromGitDiffOutput(await rawGitDiff(g, args));
|
|
34635
34661
|
return patch ? truncatePatch(patch) : void 0;
|
|
34636
34662
|
}
|
|
34637
34663
|
|
|
@@ -34809,7 +34835,7 @@ async function parentForCommitDiff(g, sha) {
|
|
|
34809
34835
|
}
|
|
34810
34836
|
|
|
34811
34837
|
// src/git/changes/listing/rename-diff-args.ts
|
|
34812
|
-
var
|
|
34838
|
+
var RENAME_DIFF_ARGS2 = ["-M", "--find-renames"];
|
|
34813
34839
|
|
|
34814
34840
|
// src/git/changes/rows/pick-preferred-changed-file-row.ts
|
|
34815
34841
|
function rowRank(row) {
|
|
@@ -34862,7 +34888,7 @@ async function listChangedFilesForCommit(repoGitCwd, repoRelPath, commitSha, opt
|
|
|
34862
34888
|
const g = cliSimpleGit(repoGitCwd);
|
|
34863
34889
|
const normRel = normalizeRepoRelPath(repoRelPath);
|
|
34864
34890
|
const [nameStatusRaw, numstatRaw] = await Promise.all([
|
|
34865
|
-
g.raw(["diff-tree", "--no-commit-id", "--name-status", "-r", ...
|
|
34891
|
+
g.raw(["diff-tree", "--no-commit-id", "--name-status", "-r", ...RENAME_DIFF_ARGS2, commitSha]).catch(() => ""),
|
|
34866
34892
|
g.raw(["show", "--numstat", "--format=format:", commitSha]).catch(() => "")
|
|
34867
34893
|
]);
|
|
34868
34894
|
const parsed = parseDiffOutput(String(nameStatusRaw), String(numstatRaw));
|
|
@@ -35134,8 +35160,8 @@ async function enrichWorkingTreeFileRows(options) {
|
|
|
35134
35160
|
async function listChangedFilesForRepo(repoGitCwd, repoRelPath, options = {}) {
|
|
35135
35161
|
const g = cliSimpleGit(repoGitCwd);
|
|
35136
35162
|
const [nameStatusRaw, numstatRaw, untrackedRaw] = await Promise.all([
|
|
35137
|
-
g.raw(["diff", ...
|
|
35138
|
-
g.raw(["diff", ...
|
|
35163
|
+
g.raw(["diff", ...RENAME_DIFF_ARGS2, "--name-status", "HEAD"]).catch(() => ""),
|
|
35164
|
+
g.raw(["diff", ...RENAME_DIFF_ARGS2, "HEAD", "--numstat"]).catch(() => ""),
|
|
35139
35165
|
g.raw(["ls-files", "--others", "--exclude-standard"]).catch(() => "")
|
|
35140
35166
|
]);
|
|
35141
35167
|
const parsed = parseDiffOutput(String(nameStatusRaw), String(numstatRaw));
|
|
@@ -36402,7 +36428,7 @@ function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
|
36402
36428
|
}
|
|
36403
36429
|
|
|
36404
36430
|
// src/connection/create-bridge-connection.ts
|
|
36405
|
-
import * as
|
|
36431
|
+
import * as path60 from "node:path";
|
|
36406
36432
|
|
|
36407
36433
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
36408
36434
|
import { rm as rm2 } from "node:fs/promises";
|
|
@@ -36424,15 +36450,15 @@ function sendDevServerStatus(getWs, serverId, status, options) {
|
|
|
36424
36450
|
|
|
36425
36451
|
// src/dev-servers/process/terminate-child-process.ts
|
|
36426
36452
|
async function sigtermAndWaitForExit(proc, graceMs, log2, shortId) {
|
|
36427
|
-
const exited = new Promise((
|
|
36428
|
-
proc.once("exit", () =>
|
|
36453
|
+
const exited = new Promise((resolve33) => {
|
|
36454
|
+
proc.once("exit", () => resolve33());
|
|
36429
36455
|
});
|
|
36430
36456
|
log2(`[dev-server] Sending SIGTERM to ${shortId} (pid=${proc.pid ?? "?"}).`);
|
|
36431
36457
|
try {
|
|
36432
36458
|
proc.kill("SIGTERM");
|
|
36433
36459
|
} catch {
|
|
36434
36460
|
}
|
|
36435
|
-
await Promise.race([exited, new Promise((
|
|
36461
|
+
await Promise.race([exited, new Promise((resolve33) => setTimeout(resolve33, graceMs))]);
|
|
36436
36462
|
}
|
|
36437
36463
|
function forceKillChild(proc, log2, shortId, graceMs) {
|
|
36438
36464
|
log2(
|
|
@@ -37870,12 +37896,16 @@ var handleAgentConfigMessage = (msg, deps) => {
|
|
|
37870
37896
|
// src/prompt-turn-queue/client-report.ts
|
|
37871
37897
|
function sendPromptQueueClientReport(ws, queues) {
|
|
37872
37898
|
if (!ws) return false;
|
|
37873
|
-
|
|
37899
|
+
const wireQueues = {};
|
|
37900
|
+
for (const [queueKey, rows] of Object.entries(queues)) {
|
|
37901
|
+
wireQueues[queueKey] = rows.map((r) => ({ turnId: r.turnId, clientState: r.cliState }));
|
|
37902
|
+
}
|
|
37903
|
+
sendWsMessage(ws, { type: "prompt_queue_client_report", queues: wireQueues });
|
|
37874
37904
|
return true;
|
|
37875
37905
|
}
|
|
37876
37906
|
|
|
37877
37907
|
// src/prompt-turn-queue/disk-store.ts
|
|
37878
|
-
var
|
|
37908
|
+
var MERGEABLE_BRIDGE_SERVER_STATES = /* @__PURE__ */ new Set([
|
|
37879
37909
|
"queued",
|
|
37880
37910
|
"requeued",
|
|
37881
37911
|
"requeued_with_revert",
|
|
@@ -37907,7 +37937,7 @@ async function writePersistedQueue(file2) {
|
|
|
37907
37937
|
);
|
|
37908
37938
|
});
|
|
37909
37939
|
}
|
|
37910
|
-
async function
|
|
37940
|
+
async function mergeBridgeServerQueueSnapshot(queueKey, serverTurns) {
|
|
37911
37941
|
const prev = await readPersistedQueue(queueKey);
|
|
37912
37942
|
const turns = [];
|
|
37913
37943
|
for (const raw of serverTurns) {
|
|
@@ -37916,19 +37946,19 @@ async function mergeServerQueueSnapshot(queueKey, serverTurns) {
|
|
|
37916
37946
|
const turnId = typeof o.turnId === "string" ? o.turnId : "";
|
|
37917
37947
|
const sessionId = typeof o.sessionId === "string" ? o.sessionId : "";
|
|
37918
37948
|
const turnOrd = typeof o.turnOrd === "number" ? o.turnOrd : Number(o.turnOrd) || 0;
|
|
37919
|
-
const
|
|
37920
|
-
const
|
|
37949
|
+
const bridgeServerState = o.serverState ?? o.bridgeServerState;
|
|
37950
|
+
const lastCliState = o.lastClientState ?? o.lastCliState ?? null;
|
|
37921
37951
|
const payload = o.payload && typeof o.payload === "object" ? o.payload : {};
|
|
37922
37952
|
if (!turnId || !sessionId) continue;
|
|
37923
|
-
if (!
|
|
37953
|
+
if (!MERGEABLE_BRIDGE_SERVER_STATES.has(String(bridgeServerState))) continue;
|
|
37924
37954
|
const old = prev?.turns.find((t) => t.turnId === turnId);
|
|
37925
|
-
const
|
|
37955
|
+
const mergedCli = old?.lastCliState === "running" && lastCliState == null ? "running" : lastCliState;
|
|
37926
37956
|
turns.push({
|
|
37927
37957
|
turnId,
|
|
37928
37958
|
sessionId,
|
|
37929
37959
|
turnOrd,
|
|
37930
|
-
|
|
37931
|
-
|
|
37960
|
+
bridgeServerState,
|
|
37961
|
+
lastCliState: mergedCli,
|
|
37932
37962
|
payload
|
|
37933
37963
|
});
|
|
37934
37964
|
}
|
|
@@ -37966,15 +37996,12 @@ function dispatchLocalPrompt(next, deps) {
|
|
|
37966
37996
|
}
|
|
37967
37997
|
|
|
37968
37998
|
// src/prompt-turn-queue/runner/queue-selection.ts
|
|
37969
|
-
function isRunnableServerState(s) {
|
|
37970
|
-
return s === "queued" || s === "requeued" || s === "requeued_with_revert";
|
|
37971
|
-
}
|
|
37972
37999
|
function pickNextRunnableTurn(turns) {
|
|
37973
38000
|
for (const t of turns) {
|
|
37974
|
-
if (t.
|
|
37975
|
-
if (t.
|
|
37976
|
-
if (!
|
|
37977
|
-
if (t.
|
|
38001
|
+
if (t.bridgeServerState === "discarded" || t.bridgeServerState === "stopping") continue;
|
|
38002
|
+
if (t.bridgeServerState === "cancel_requested") continue;
|
|
38003
|
+
if (!isRunnableBridgePromptTurnServerState(t.bridgeServerState)) continue;
|
|
38004
|
+
if (t.lastCliState === "running" || t.lastCliState === "stopped" || t.lastCliState === "failed" || t.lastCliState === "cancelled") {
|
|
37978
38005
|
continue;
|
|
37979
38006
|
}
|
|
37980
38007
|
return t;
|
|
@@ -37982,7 +38009,7 @@ function pickNextRunnableTurn(turns) {
|
|
|
37982
38009
|
return null;
|
|
37983
38010
|
}
|
|
37984
38011
|
function hasRunningTurn(turns) {
|
|
37985
|
-
return turns.some((t) => t.
|
|
38012
|
+
return turns.some((t) => t.lastCliState === "running");
|
|
37986
38013
|
}
|
|
37987
38014
|
|
|
37988
38015
|
// src/prompt-turn-queue/runner/run-id-queue-key-map.ts
|
|
@@ -37999,7 +38026,7 @@ function deleteRunIdQueueKey(runId) {
|
|
|
37999
38026
|
return queueKey;
|
|
38000
38027
|
}
|
|
38001
38028
|
function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
38002
|
-
for (const running of turns.filter((t) => t.
|
|
38029
|
+
for (const running of turns.filter((t) => t.lastCliState === "running")) {
|
|
38003
38030
|
runIdToQueueKey.set(running.turnId, queueKey);
|
|
38004
38031
|
}
|
|
38005
38032
|
}
|
|
@@ -38007,7 +38034,7 @@ function syncRunningTurnQueueKeys(turns, queueKey) {
|
|
|
38007
38034
|
// src/prompt-turn-queue/runner/run-local-revert-before-queued-prompt.ts
|
|
38008
38035
|
import fs37 from "node:fs";
|
|
38009
38036
|
async function runLocalRevertBeforeQueuedPrompt(next, deps) {
|
|
38010
|
-
if (next.
|
|
38037
|
+
if (next.bridgeServerState !== "requeued_with_revert") return true;
|
|
38011
38038
|
const sid = next.sessionId;
|
|
38012
38039
|
const pl = next.payload;
|
|
38013
38040
|
const tid = typeof pl.snapshotRevertTurnId === "string" && pl.snapshotRevertTurnId.trim() !== "" ? pl.snapshotRevertTurnId.trim() : next.turnId;
|
|
@@ -38037,9 +38064,9 @@ async function finalizePromptTurnOnBridge(getWs, runId, success2, opts) {
|
|
|
38037
38064
|
if (!f) return false;
|
|
38038
38065
|
const t = f.turns.find((x) => x.turnId === runId);
|
|
38039
38066
|
if (!t) return false;
|
|
38040
|
-
t.
|
|
38067
|
+
t.lastCliState = opts?.terminalCliState ?? (success2 ? "stopped" : "failed");
|
|
38041
38068
|
await writePersistedQueue(f);
|
|
38042
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId,
|
|
38069
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: runId, cliState: t.lastCliState }] });
|
|
38043
38070
|
return true;
|
|
38044
38071
|
}
|
|
38045
38072
|
|
|
@@ -38050,7 +38077,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
38050
38077
|
const getWs = deps.getWs;
|
|
38051
38078
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
38052
38079
|
if (!Array.isArray(serverTurns)) continue;
|
|
38053
|
-
const file2 = await
|
|
38080
|
+
const file2 = await mergeBridgeServerQueueSnapshot(queueKey, serverTurns);
|
|
38054
38081
|
await writePersistedQueue(file2);
|
|
38055
38082
|
}
|
|
38056
38083
|
for (const [queueKey, serverTurns] of Object.entries(raw)) {
|
|
@@ -38063,14 +38090,14 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
38063
38090
|
if (!Array.isArray(serverTurns)) continue;
|
|
38064
38091
|
const file2 = await readPersistedQueue(queueKey);
|
|
38065
38092
|
if (!file2) continue;
|
|
38066
|
-
const cancelRow = file2.turns.find((t) => t.
|
|
38093
|
+
const cancelRow = file2.turns.find((t) => t.bridgeServerState === "cancel_requested" && t.lastCliState === "running");
|
|
38067
38094
|
if (cancelRow) {
|
|
38068
38095
|
const localCancelHandled = await deps.acpManager.cancelRun(cancelRow.turnId);
|
|
38069
38096
|
if (!localCancelHandled) {
|
|
38070
38097
|
deps.log(
|
|
38071
|
-
`[Queue] server cancel_requested for ${cancelRow.turnId.slice(0, 8)}\u2026 but no local agent run is active (e.g. after CLI restart); marking cancelled and notifying bridge.`
|
|
38098
|
+
`[Queue] bridge server cancel_requested for ${cancelRow.turnId.slice(0, 8)}\u2026 but no local agent run is active (e.g. after CLI restart); marking cancelled and notifying bridge.`
|
|
38072
38099
|
);
|
|
38073
|
-
await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, {
|
|
38100
|
+
await finalizePromptTurnOnBridge(deps.getWs, cancelRow.turnId, false, { terminalCliState: "cancelled" });
|
|
38074
38101
|
const ws = deps.getWs();
|
|
38075
38102
|
if (ws && cancelRow.sessionId) {
|
|
38076
38103
|
sendWsMessage(ws, {
|
|
@@ -38095,16 +38122,16 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
38095
38122
|
const next = pickNextRunnableTurn(file2.turns);
|
|
38096
38123
|
if (!next) continue;
|
|
38097
38124
|
if (!await runLocalRevertBeforeQueuedPrompt(next, deps)) {
|
|
38098
|
-
next.
|
|
38125
|
+
next.lastCliState = "failed";
|
|
38099
38126
|
await writePersistedQueue(file2);
|
|
38100
|
-
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId,
|
|
38127
|
+
sendPromptQueueClientReport(getWs(), { [queueKey]: [{ turnId: next.turnId, cliState: "failed" }] });
|
|
38101
38128
|
continue;
|
|
38102
38129
|
}
|
|
38103
|
-
next.
|
|
38130
|
+
next.lastCliState = "running";
|
|
38104
38131
|
await writePersistedQueue(file2);
|
|
38105
38132
|
setRunIdQueueKey(next.turnId, queueKey);
|
|
38106
38133
|
startedThisTick.add(next.turnId);
|
|
38107
|
-
report[queueKey] = [{ turnId: next.turnId,
|
|
38134
|
+
report[queueKey] = [{ turnId: next.turnId, cliState: "running" }];
|
|
38108
38135
|
}
|
|
38109
38136
|
if (Object.keys(report).length > 0) {
|
|
38110
38137
|
sendPromptQueueClientReport(getWs(), report);
|
|
@@ -38113,7 +38140,7 @@ async function applyPromptQueueStateFromServer(msg, deps) {
|
|
|
38113
38140
|
if (!Array.isArray(serverTurns)) continue;
|
|
38114
38141
|
const file2 = await readPersistedQueue(queueKey);
|
|
38115
38142
|
if (!file2) continue;
|
|
38116
|
-
const running = file2.turns.find((t) => t.
|
|
38143
|
+
const running = file2.turns.find((t) => t.lastCliState === "running");
|
|
38117
38144
|
if (!running || !startedThisTick.has(running.turnId)) continue;
|
|
38118
38145
|
if (getRunIdQueueKey(running.turnId) !== queueKey) continue;
|
|
38119
38146
|
dispatchLocalPrompt(running, deps);
|
|
@@ -38140,7 +38167,7 @@ function createBridgePromptSenders(deps, getWs) {
|
|
|
38140
38167
|
getWs,
|
|
38141
38168
|
typeof pr.runId === "string" ? pr.runId : void 0,
|
|
38142
38169
|
pr.success === true,
|
|
38143
|
-
cancelled ? {
|
|
38170
|
+
cancelled ? { terminalCliState: "cancelled" } : void 0
|
|
38144
38171
|
).catch(() => {
|
|
38145
38172
|
});
|
|
38146
38173
|
}
|
|
@@ -38302,9 +38329,9 @@ function parseChangeSummarySnapshots(raw) {
|
|
|
38302
38329
|
for (const item of raw) {
|
|
38303
38330
|
if (!item || typeof item !== "object") continue;
|
|
38304
38331
|
const o = item;
|
|
38305
|
-
const
|
|
38306
|
-
if (!
|
|
38307
|
-
const row = { path:
|
|
38332
|
+
const path61 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
38333
|
+
if (!path61) continue;
|
|
38334
|
+
const row = { path: path61 };
|
|
38308
38335
|
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
38309
38336
|
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
38310
38337
|
if (typeof o.newText === "string") row.newText = o.newText;
|
|
@@ -38517,6 +38544,17 @@ var handleSkillCallMessage = (msg, { getWs, log: log2 }) => {
|
|
|
38517
38544
|
);
|
|
38518
38545
|
};
|
|
38519
38546
|
|
|
38547
|
+
// src/files/resolve-file-browser-session-parent.ts
|
|
38548
|
+
async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId) {
|
|
38549
|
+
const sid = sessionId?.trim();
|
|
38550
|
+
if (sid) {
|
|
38551
|
+
await sessionWorktreeManager.ensureRepoCheckoutPathsForSessionAsync(sid);
|
|
38552
|
+
const worktreeRoot = sessionWorktreeManager.getSessionWorktreeRootForSession(sid);
|
|
38553
|
+
if (worktreeRoot) return worktreeRoot;
|
|
38554
|
+
}
|
|
38555
|
+
return getBridgeRoot();
|
|
38556
|
+
}
|
|
38557
|
+
|
|
38520
38558
|
// src/files/list-dir/index.ts
|
|
38521
38559
|
import fs39 from "node:fs";
|
|
38522
38560
|
|
|
@@ -38588,10 +38626,447 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
|
38588
38626
|
}
|
|
38589
38627
|
}
|
|
38590
38628
|
|
|
38629
|
+
// src/files/handle-file-browser-search.ts
|
|
38630
|
+
import path54 from "node:path";
|
|
38631
|
+
var SEARCH_LIMIT = 100;
|
|
38632
|
+
function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
|
|
38633
|
+
void (async () => {
|
|
38634
|
+
await yieldToEventLoop();
|
|
38635
|
+
const q = typeof msg.q === "string" ? msg.q : "";
|
|
38636
|
+
const sessionParentPath = path54.resolve(
|
|
38637
|
+
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
38638
|
+
);
|
|
38639
|
+
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
38640
|
+
const payload2 = {
|
|
38641
|
+
type: "file_browser_search_response",
|
|
38642
|
+
id: msg.id,
|
|
38643
|
+
paths: [],
|
|
38644
|
+
indexReady: false
|
|
38645
|
+
};
|
|
38646
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
38647
|
+
return;
|
|
38648
|
+
}
|
|
38649
|
+
const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
|
|
38650
|
+
const payload = {
|
|
38651
|
+
type: "file_browser_search_response",
|
|
38652
|
+
id: msg.id,
|
|
38653
|
+
paths: results,
|
|
38654
|
+
indexReady: true
|
|
38655
|
+
};
|
|
38656
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
|
|
38657
|
+
})();
|
|
38658
|
+
}
|
|
38659
|
+
function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
|
|
38660
|
+
setImmediate(() => {
|
|
38661
|
+
void ensureFileIndexAsync(sessionParentPath).catch((e) => {
|
|
38662
|
+
console.error("[file-index] Background build failed:", e);
|
|
38663
|
+
});
|
|
38664
|
+
});
|
|
38665
|
+
}
|
|
38666
|
+
|
|
38667
|
+
// src/git/tree/resolve-repo-abs-path.ts
|
|
38668
|
+
import * as path55 from "node:path";
|
|
38669
|
+
function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
38670
|
+
const bridgeResolved = path55.resolve(bridgeRoot);
|
|
38671
|
+
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
38672
|
+
const repoPath = rel === "" ? bridgeResolved : path55.join(bridgeResolved, rel);
|
|
38673
|
+
const resolved = path55.resolve(repoPath);
|
|
38674
|
+
if (!resolved.startsWith(bridgeResolved + path55.sep) && resolved !== bridgeResolved) {
|
|
38675
|
+
return null;
|
|
38676
|
+
}
|
|
38677
|
+
return resolved;
|
|
38678
|
+
}
|
|
38679
|
+
|
|
38680
|
+
// src/git/tree/resolve-branch-commit.ts
|
|
38681
|
+
async function resolveBranchCommit(repoAbsPath, branch) {
|
|
38682
|
+
const branchRef = branch.trim();
|
|
38683
|
+
if (!branchRef) return null;
|
|
38684
|
+
try {
|
|
38685
|
+
return (await cliSimpleGit(repoAbsPath).revparse([`${branchRef}^{commit}`])).trim();
|
|
38686
|
+
} catch {
|
|
38687
|
+
return null;
|
|
38688
|
+
}
|
|
38689
|
+
}
|
|
38690
|
+
|
|
38691
|
+
// src/git/tree/list-git-tree-dir.ts
|
|
38692
|
+
function parseLsTreeLine(line) {
|
|
38693
|
+
const tab = line.indexOf(" ");
|
|
38694
|
+
if (tab < 0) return null;
|
|
38695
|
+
const meta = line.slice(0, tab).trim().split(/\s+/);
|
|
38696
|
+
if (meta.length < 3) return null;
|
|
38697
|
+
const mode = meta[0];
|
|
38698
|
+
const objectType2 = meta[1];
|
|
38699
|
+
let name = line.slice(tab + 1);
|
|
38700
|
+
if (name.startsWith('"') && name.endsWith('"')) {
|
|
38701
|
+
name = name.slice(1, -1).replace(/\\n/g, "\n").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
|
|
38702
|
+
}
|
|
38703
|
+
return { mode, objectType: objectType2, name };
|
|
38704
|
+
}
|
|
38705
|
+
function childPath(relativePath, name) {
|
|
38706
|
+
const base = relativePath.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
38707
|
+
if (!base || base === ".") return name;
|
|
38708
|
+
return `${base}/${name}`.replace(/\\/g, "/");
|
|
38709
|
+
}
|
|
38710
|
+
function lsTreeArgs(commit, relativePath) {
|
|
38711
|
+
const rel = relativePath.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
38712
|
+
if (!rel || rel === ".") return ["ls-tree", commit];
|
|
38713
|
+
return ["ls-tree", `${commit}:${rel}`];
|
|
38714
|
+
}
|
|
38715
|
+
async function listGitTreeDirAsync(repoAbsPath, branch, relativePath) {
|
|
38716
|
+
await yieldToEventLoop();
|
|
38717
|
+
const commit = await resolveBranchCommit(repoAbsPath, branch);
|
|
38718
|
+
if (!commit) return { error: "Branch not found" };
|
|
38719
|
+
try {
|
|
38720
|
+
const raw = await cliSimpleGit(repoAbsPath).raw(lsTreeArgs(commit, relativePath));
|
|
38721
|
+
await yieldToEventLoop();
|
|
38722
|
+
const lines = String(raw ?? "").split(/\r?\n/).filter((line) => line.trim().length > 0);
|
|
38723
|
+
const entries = [];
|
|
38724
|
+
for (let i = 0; i < lines.length; i++) {
|
|
38725
|
+
if (i > 0 && i % LIST_DIR_YIELD_EVERY === 0) {
|
|
38726
|
+
await yieldToEventLoop();
|
|
38727
|
+
}
|
|
38728
|
+
const parsed = parseLsTreeLine(lines[i]);
|
|
38729
|
+
if (!parsed) continue;
|
|
38730
|
+
const { mode, objectType: objectType2, name } = parsed;
|
|
38731
|
+
if (!name || name === "." || name === "..") continue;
|
|
38732
|
+
const isSymlink = mode === "120000";
|
|
38733
|
+
const isDir = objectType2 === "tree";
|
|
38734
|
+
entries.push({
|
|
38735
|
+
name,
|
|
38736
|
+
path: childPath(relativePath, name),
|
|
38737
|
+
isDir,
|
|
38738
|
+
...isSymlink ? { isSymlink: true } : {}
|
|
38739
|
+
});
|
|
38740
|
+
}
|
|
38741
|
+
if (entries.length >= LIST_DIR_YIELD_EVERY) {
|
|
38742
|
+
await yieldToEventLoop();
|
|
38743
|
+
}
|
|
38744
|
+
return { entries: sortListEntries(entries) };
|
|
38745
|
+
} catch (err) {
|
|
38746
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
38747
|
+
if (/not a tree object|does not exist|bad revision/i.test(message)) {
|
|
38748
|
+
return { error: "Path not found in branch" };
|
|
38749
|
+
}
|
|
38750
|
+
return { error: message };
|
|
38751
|
+
}
|
|
38752
|
+
}
|
|
38753
|
+
|
|
38591
38754
|
// src/files/read-file/types.ts
|
|
38592
38755
|
var LINE_CHUNK_SIZE = 64 * 1024;
|
|
38593
38756
|
var READ_RANGE_YIELD_EVERY_BYTES = 256 * 1024;
|
|
38594
38757
|
|
|
38758
|
+
// src/files/read-file/guess-mime-type.ts
|
|
38759
|
+
var MIME_BY_EXT = {
|
|
38760
|
+
png: "image/png",
|
|
38761
|
+
jpg: "image/jpeg",
|
|
38762
|
+
jpeg: "image/jpeg",
|
|
38763
|
+
gif: "image/gif",
|
|
38764
|
+
bmp: "image/bmp",
|
|
38765
|
+
ico: "image/x-icon",
|
|
38766
|
+
webp: "image/webp",
|
|
38767
|
+
avif: "image/avif",
|
|
38768
|
+
svg: "image/svg+xml",
|
|
38769
|
+
pdf: "application/pdf",
|
|
38770
|
+
json: "application/json",
|
|
38771
|
+
html: "text/html",
|
|
38772
|
+
htm: "text/html",
|
|
38773
|
+
css: "text/css",
|
|
38774
|
+
js: "text/javascript",
|
|
38775
|
+
mjs: "text/javascript",
|
|
38776
|
+
ts: "text/typescript",
|
|
38777
|
+
txt: "text/plain",
|
|
38778
|
+
md: "text/markdown",
|
|
38779
|
+
xml: "application/xml",
|
|
38780
|
+
zip: "application/zip",
|
|
38781
|
+
gz: "application/gzip",
|
|
38782
|
+
wasm: "application/wasm"
|
|
38783
|
+
};
|
|
38784
|
+
function guessMimeType(filePath) {
|
|
38785
|
+
const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
|
|
38786
|
+
return MIME_BY_EXT[ext] ?? "application/octet-stream";
|
|
38787
|
+
}
|
|
38788
|
+
|
|
38789
|
+
// src/git/tree/file/git-blob-ref.ts
|
|
38790
|
+
async function gitBlobRef(repoAbsPath, branch, relativePath) {
|
|
38791
|
+
const commit = await resolveBranchCommit(repoAbsPath, branch);
|
|
38792
|
+
await yieldToEventLoop();
|
|
38793
|
+
if (!commit) return null;
|
|
38794
|
+
const rel = relativePath.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
38795
|
+
if (!rel || rel === ".") return null;
|
|
38796
|
+
return `${commit}:${rel}`;
|
|
38797
|
+
}
|
|
38798
|
+
|
|
38799
|
+
// src/git/tree/file/is-binary-buffer.ts
|
|
38800
|
+
function isBinaryBuffer(buf) {
|
|
38801
|
+
const sample = buf.subarray(0, Math.min(buf.length, 8192));
|
|
38802
|
+
for (let i = 0; i < sample.length; i++) {
|
|
38803
|
+
if (sample[i] === 0) return true;
|
|
38804
|
+
}
|
|
38805
|
+
return false;
|
|
38806
|
+
}
|
|
38807
|
+
|
|
38808
|
+
// src/git/tree/file/read-git-blob-text-async.ts
|
|
38809
|
+
import { StringDecoder } from "node:string_decoder";
|
|
38810
|
+
async function countGitBlobLinesAsync(buf) {
|
|
38811
|
+
if (buf.length === 0) return 1;
|
|
38812
|
+
let lines = 1;
|
|
38813
|
+
let bytesSinceYield = 0;
|
|
38814
|
+
for (let i = 0; i < buf.length; i++) {
|
|
38815
|
+
const b = buf[i];
|
|
38816
|
+
if (b === 10) {
|
|
38817
|
+
lines++;
|
|
38818
|
+
} else if (b === 13) {
|
|
38819
|
+
if (i + 1 < buf.length && buf[i + 1] === 10) {
|
|
38820
|
+
lines++;
|
|
38821
|
+
i++;
|
|
38822
|
+
} else {
|
|
38823
|
+
lines++;
|
|
38824
|
+
}
|
|
38825
|
+
}
|
|
38826
|
+
bytesSinceYield++;
|
|
38827
|
+
if (bytesSinceYield >= READ_RANGE_YIELD_EVERY_BYTES) {
|
|
38828
|
+
await yieldToEventLoop();
|
|
38829
|
+
bytesSinceYield = 0;
|
|
38830
|
+
}
|
|
38831
|
+
}
|
|
38832
|
+
return lines;
|
|
38833
|
+
}
|
|
38834
|
+
async function readGitBlobLineRangeAsync(buf, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
38835
|
+
const bufSize = 64 * 1024;
|
|
38836
|
+
const decoder = new StringDecoder("utf8");
|
|
38837
|
+
let currentLine = 0;
|
|
38838
|
+
const resultLines = [];
|
|
38839
|
+
let partial2 = "";
|
|
38840
|
+
let done = false;
|
|
38841
|
+
let skipLine0Chars = typeof lineOffsetIn === "number" ? lineOffsetIn : 0;
|
|
38842
|
+
let line0CharsReturned = 0;
|
|
38843
|
+
let line0Accum = "";
|
|
38844
|
+
let bytesSinceYield = 0;
|
|
38845
|
+
let position = 0;
|
|
38846
|
+
const finish = async () => {
|
|
38847
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38848
|
+
return { content: resultLines.join("\n"), totalLines };
|
|
38849
|
+
};
|
|
38850
|
+
while (!done && position < buf.length) {
|
|
38851
|
+
const chunkEnd = Math.min(position + bufSize, buf.length);
|
|
38852
|
+
const bytesRead = chunkEnd - position;
|
|
38853
|
+
position = chunkEnd;
|
|
38854
|
+
bytesSinceYield += bytesRead;
|
|
38855
|
+
if (bytesSinceYield >= READ_RANGE_YIELD_EVERY_BYTES) {
|
|
38856
|
+
await yieldToEventLoop();
|
|
38857
|
+
bytesSinceYield = 0;
|
|
38858
|
+
}
|
|
38859
|
+
const text = partial2 + decoder.write(buf.subarray(position - bytesRead, position));
|
|
38860
|
+
partial2 = "";
|
|
38861
|
+
let lineStart = 0;
|
|
38862
|
+
for (let i = 0; i < text.length; i++) {
|
|
38863
|
+
if (text[i] === "\n") {
|
|
38864
|
+
const lineContent = (() => {
|
|
38865
|
+
let lineEnd = i;
|
|
38866
|
+
if (lineEnd > lineStart && text[lineEnd - 1] === "\r") lineEnd--;
|
|
38867
|
+
return text.slice(lineStart, lineEnd);
|
|
38868
|
+
})();
|
|
38869
|
+
if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
|
|
38870
|
+
line0Accum += lineContent;
|
|
38871
|
+
const totalLine0 = line0Accum.length;
|
|
38872
|
+
if (skipLine0Chars > 0) {
|
|
38873
|
+
if (totalLine0 <= skipLine0Chars) {
|
|
38874
|
+
skipLine0Chars -= totalLine0;
|
|
38875
|
+
line0Accum = "";
|
|
38876
|
+
currentLine++;
|
|
38877
|
+
lineStart = i + 1;
|
|
38878
|
+
if (currentLine > endLine) {
|
|
38879
|
+
done = true;
|
|
38880
|
+
break;
|
|
38881
|
+
}
|
|
38882
|
+
continue;
|
|
38883
|
+
}
|
|
38884
|
+
const from = skipLine0Chars;
|
|
38885
|
+
const take = Math.min(lineChunkSize, totalLine0 - from);
|
|
38886
|
+
resultLines.push(line0Accum.slice(from, from + take));
|
|
38887
|
+
line0CharsReturned += take;
|
|
38888
|
+
if (from + take < totalLine0) {
|
|
38889
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38890
|
+
return {
|
|
38891
|
+
content: resultLines.join("\n"),
|
|
38892
|
+
totalLines,
|
|
38893
|
+
lineOffset: lineOffsetIn + line0CharsReturned
|
|
38894
|
+
};
|
|
38895
|
+
}
|
|
38896
|
+
line0Accum = "";
|
|
38897
|
+
skipLine0Chars = 0;
|
|
38898
|
+
line0CharsReturned = 0;
|
|
38899
|
+
} else if (totalLine0 > lineChunkSize) {
|
|
38900
|
+
resultLines.push(line0Accum.slice(0, lineChunkSize));
|
|
38901
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38902
|
+
return {
|
|
38903
|
+
content: resultLines.join("\n"),
|
|
38904
|
+
totalLines,
|
|
38905
|
+
lineOffset: lineChunkSize
|
|
38906
|
+
};
|
|
38907
|
+
} else {
|
|
38908
|
+
resultLines.push(line0Accum);
|
|
38909
|
+
line0Accum = "";
|
|
38910
|
+
}
|
|
38911
|
+
} else if (currentLine >= startLine && currentLine <= endLine) {
|
|
38912
|
+
resultLines.push(lineContent);
|
|
38913
|
+
}
|
|
38914
|
+
currentLine++;
|
|
38915
|
+
lineStart = i + 1;
|
|
38916
|
+
if (currentLine > endLine) {
|
|
38917
|
+
done = true;
|
|
38918
|
+
break;
|
|
38919
|
+
}
|
|
38920
|
+
}
|
|
38921
|
+
}
|
|
38922
|
+
if (!done) {
|
|
38923
|
+
const lineContent = text.slice(lineStart);
|
|
38924
|
+
if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0)) {
|
|
38925
|
+
line0Accum += lineContent;
|
|
38926
|
+
const totalLine0 = line0Accum.length;
|
|
38927
|
+
if (skipLine0Chars > 0) {
|
|
38928
|
+
if (totalLine0 <= skipLine0Chars) {
|
|
38929
|
+
skipLine0Chars -= totalLine0;
|
|
38930
|
+
line0Accum = "";
|
|
38931
|
+
} else {
|
|
38932
|
+
const from = skipLine0Chars;
|
|
38933
|
+
const take = Math.min(lineChunkSize, totalLine0 - from);
|
|
38934
|
+
resultLines.push(line0Accum.slice(from, from + take));
|
|
38935
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38936
|
+
return {
|
|
38937
|
+
content: resultLines.join("\n"),
|
|
38938
|
+
totalLines,
|
|
38939
|
+
lineOffset: (lineOffsetIn ?? 0) + take
|
|
38940
|
+
};
|
|
38941
|
+
}
|
|
38942
|
+
} else if (totalLine0 > lineChunkSize) {
|
|
38943
|
+
resultLines.push(line0Accum.slice(0, lineChunkSize));
|
|
38944
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38945
|
+
return {
|
|
38946
|
+
content: resultLines.join("\n"),
|
|
38947
|
+
totalLines,
|
|
38948
|
+
lineOffset: lineChunkSize
|
|
38949
|
+
};
|
|
38950
|
+
}
|
|
38951
|
+
}
|
|
38952
|
+
partial2 = text.slice(lineStart);
|
|
38953
|
+
}
|
|
38954
|
+
}
|
|
38955
|
+
if (!done) {
|
|
38956
|
+
const tail = partial2 + decoder.end();
|
|
38957
|
+
if (currentLine === 0 && (startLine === 0 || lineOffsetIn !== void 0) && tail.length > 0) {
|
|
38958
|
+
line0Accum += tail.endsWith("\r") ? tail.slice(0, -1) : tail;
|
|
38959
|
+
const totalLine0 = line0Accum.length;
|
|
38960
|
+
if (skipLine0Chars > 0) {
|
|
38961
|
+
if (totalLine0 <= skipLine0Chars) {
|
|
38962
|
+
return finish();
|
|
38963
|
+
}
|
|
38964
|
+
const from = skipLine0Chars;
|
|
38965
|
+
const take = Math.min(lineChunkSize, totalLine0 - from);
|
|
38966
|
+
resultLines.push(line0Accum.slice(from, from + take));
|
|
38967
|
+
line0CharsReturned += take;
|
|
38968
|
+
if (from + take < totalLine0) {
|
|
38969
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38970
|
+
return {
|
|
38971
|
+
content: resultLines.join("\n"),
|
|
38972
|
+
totalLines,
|
|
38973
|
+
lineOffset: (lineOffsetIn ?? 0) + line0CharsReturned
|
|
38974
|
+
};
|
|
38975
|
+
}
|
|
38976
|
+
} else if (totalLine0 > lineChunkSize) {
|
|
38977
|
+
resultLines.push(line0Accum.slice(0, lineChunkSize));
|
|
38978
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
38979
|
+
return {
|
|
38980
|
+
content: resultLines.join("\n"),
|
|
38981
|
+
totalLines,
|
|
38982
|
+
lineOffset: lineChunkSize
|
|
38983
|
+
};
|
|
38984
|
+
} else {
|
|
38985
|
+
resultLines.push(line0Accum);
|
|
38986
|
+
}
|
|
38987
|
+
} else if (tail.length > 0 && currentLine >= startLine && currentLine <= endLine) {
|
|
38988
|
+
resultLines.push(tail.endsWith("\r") ? tail.slice(0, -1) : tail);
|
|
38989
|
+
}
|
|
38990
|
+
}
|
|
38991
|
+
return finish();
|
|
38992
|
+
}
|
|
38993
|
+
async function decodeGitBlobUtf8Async(buf) {
|
|
38994
|
+
await yieldToEventLoop();
|
|
38995
|
+
const text = buf.toString("utf8");
|
|
38996
|
+
await yieldToEventLoop();
|
|
38997
|
+
return text;
|
|
38998
|
+
}
|
|
38999
|
+
async function readGitBlobUtf8FullAsync(buf) {
|
|
39000
|
+
const text = await decodeGitBlobUtf8Async(buf);
|
|
39001
|
+
const totalLines = await countGitBlobLinesAsync(buf);
|
|
39002
|
+
return { content: text, totalLines };
|
|
39003
|
+
}
|
|
39004
|
+
|
|
39005
|
+
// src/git/tree/file/index.ts
|
|
39006
|
+
async function readGitTreeFileAsync(repoAbsPath, branch, relativePath, startLine, endLine, lineOffset, lineChunkSize = LINE_CHUNK_SIZE, encoding = "utf8") {
|
|
39007
|
+
await yieldToEventLoop();
|
|
39008
|
+
const branchRef = branch.trim();
|
|
39009
|
+
if (!branchRef) return { error: "branch required" };
|
|
39010
|
+
const rel = relativePath.replace(/^\/+/, "").replace(/\\/g, "/");
|
|
39011
|
+
if (!rel || rel === ".") return { error: "file path required" };
|
|
39012
|
+
const blobRef = await gitBlobRef(repoAbsPath, branchRef, rel);
|
|
39013
|
+
if (!blobRef) return { error: "Branch not found" };
|
|
39014
|
+
const hasRange = typeof startLine === "number" && typeof endLine === "number";
|
|
39015
|
+
try {
|
|
39016
|
+
if (encoding === "base64") {
|
|
39017
|
+
if (hasRange) return { error: "base64 encoding requires a full file read (no line range)" };
|
|
39018
|
+
const buf2 = await cliSimpleGit(repoAbsPath).showBuffer([blobRef]);
|
|
39019
|
+
await yieldToEventLoop();
|
|
39020
|
+
return {
|
|
39021
|
+
content: buf2.toString("base64"),
|
|
39022
|
+
size: buf2.length,
|
|
39023
|
+
mimeType: guessMimeType(rel)
|
|
39024
|
+
};
|
|
39025
|
+
}
|
|
39026
|
+
const buf = await cliSimpleGit(repoAbsPath).showBuffer([blobRef]);
|
|
39027
|
+
await yieldToEventLoop();
|
|
39028
|
+
const size = buf.length;
|
|
39029
|
+
if (isBinaryBuffer(buf)) {
|
|
39030
|
+
return { error: "Binary file cannot be displayed as text" };
|
|
39031
|
+
}
|
|
39032
|
+
if (hasRange) {
|
|
39033
|
+
const ranged = await readGitBlobLineRangeAsync(buf, startLine, endLine, lineOffset, lineChunkSize);
|
|
39034
|
+
return {
|
|
39035
|
+
content: ranged.content,
|
|
39036
|
+
totalLines: ranged.totalLines,
|
|
39037
|
+
size,
|
|
39038
|
+
...ranged.lineOffset != null ? { lineOffset: ranged.lineOffset } : {}
|
|
39039
|
+
};
|
|
39040
|
+
}
|
|
39041
|
+
const full = await readGitBlobUtf8FullAsync(buf);
|
|
39042
|
+
return { content: full.content, totalLines: full.totalLines, size, mimeType: guessMimeType(rel) };
|
|
39043
|
+
} catch (err) {
|
|
39044
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
39045
|
+
if (/does not exist|bad revision|exists on disk, but not in/i.test(message)) {
|
|
39046
|
+
return { error: "File not found in branch" };
|
|
39047
|
+
}
|
|
39048
|
+
return { error: message };
|
|
39049
|
+
}
|
|
39050
|
+
}
|
|
39051
|
+
|
|
39052
|
+
// src/files/browser/send-file-browser-message.ts
|
|
39053
|
+
function sendFileBrowserMessage(socket, e2ee, payload) {
|
|
39054
|
+
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
|
|
39055
|
+
}
|
|
39056
|
+
|
|
39057
|
+
// src/files/browser/handle-file-browser-list.ts
|
|
39058
|
+
async function handleFileBrowserList(socket, e2ee, id, reqPath, sessionParentPath, gitScope) {
|
|
39059
|
+
const result = gitScope ? await listGitTreeDirAsync(gitScope.repoAbsPath, gitScope.branch, reqPath) : await listDirAsync(reqPath, sessionParentPath);
|
|
39060
|
+
if ("error" in result) {
|
|
39061
|
+
sendWsMessage(socket, { type: "file_browser_response", id, error: result.error });
|
|
39062
|
+
return;
|
|
39063
|
+
}
|
|
39064
|
+
sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id, entries: result.entries });
|
|
39065
|
+
if (!gitScope && (reqPath === "." || reqPath === "")) {
|
|
39066
|
+
triggerFileIndexBuild(sessionParentPath);
|
|
39067
|
+
}
|
|
39068
|
+
}
|
|
39069
|
+
|
|
38595
39070
|
// src/files/read-file/resolve-file-path.ts
|
|
38596
39071
|
import fs40 from "node:fs";
|
|
38597
39072
|
async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
@@ -38614,13 +39089,13 @@ async function resolveFilePathAsync(relativePath, sessionParentPath = getBridgeR
|
|
|
38614
39089
|
|
|
38615
39090
|
// src/files/read-file/read-file-range-async.ts
|
|
38616
39091
|
import fs41 from "node:fs";
|
|
38617
|
-
import { StringDecoder } from "node:string_decoder";
|
|
39092
|
+
import { StringDecoder as StringDecoder2 } from "node:string_decoder";
|
|
38618
39093
|
async function readFileRangeAsync(filePath, startLine, endLine, lineOffsetIn, lineChunkSize = LINE_CHUNK_SIZE) {
|
|
38619
39094
|
const fileSize = (await fs41.promises.stat(filePath)).size;
|
|
38620
39095
|
const fd = await fs41.promises.open(filePath, "r");
|
|
38621
39096
|
const bufSize = 64 * 1024;
|
|
38622
39097
|
const buf = Buffer.alloc(bufSize);
|
|
38623
|
-
const decoder = new
|
|
39098
|
+
const decoder = new StringDecoder2("utf8");
|
|
38624
39099
|
let currentLine = 0;
|
|
38625
39100
|
const resultLines = [];
|
|
38626
39101
|
let partial2 = "";
|
|
@@ -38814,37 +39289,6 @@ async function readFileFullAsync(filePath) {
|
|
|
38814
39289
|
return { content: raw, totalLines: lines.length, size };
|
|
38815
39290
|
}
|
|
38816
39291
|
|
|
38817
|
-
// src/files/read-file/guess-mime-type.ts
|
|
38818
|
-
var MIME_BY_EXT = {
|
|
38819
|
-
png: "image/png",
|
|
38820
|
-
jpg: "image/jpeg",
|
|
38821
|
-
jpeg: "image/jpeg",
|
|
38822
|
-
gif: "image/gif",
|
|
38823
|
-
bmp: "image/bmp",
|
|
38824
|
-
ico: "image/x-icon",
|
|
38825
|
-
webp: "image/webp",
|
|
38826
|
-
avif: "image/avif",
|
|
38827
|
-
svg: "image/svg+xml",
|
|
38828
|
-
pdf: "application/pdf",
|
|
38829
|
-
json: "application/json",
|
|
38830
|
-
html: "text/html",
|
|
38831
|
-
htm: "text/html",
|
|
38832
|
-
css: "text/css",
|
|
38833
|
-
js: "text/javascript",
|
|
38834
|
-
mjs: "text/javascript",
|
|
38835
|
-
ts: "text/typescript",
|
|
38836
|
-
txt: "text/plain",
|
|
38837
|
-
md: "text/markdown",
|
|
38838
|
-
xml: "application/xml",
|
|
38839
|
-
zip: "application/zip",
|
|
38840
|
-
gz: "application/gzip",
|
|
38841
|
-
wasm: "application/wasm"
|
|
38842
|
-
};
|
|
38843
|
-
function guessMimeType(filePath) {
|
|
38844
|
-
const ext = filePath.split(".").pop()?.toLowerCase() ?? "";
|
|
38845
|
-
return MIME_BY_EXT[ext] ?? "application/octet-stream";
|
|
38846
|
-
}
|
|
38847
|
-
|
|
38848
39292
|
// src/files/read-file/read-file-binary-full-async.ts
|
|
38849
39293
|
async function readFileBinaryFullAsync(filePath) {
|
|
38850
39294
|
const { buffer, size } = await readFileBufferFullAsync(filePath);
|
|
@@ -38878,104 +39322,72 @@ async function readFileAsync(relativePath, startLine, endLine, lineOffset, lineC
|
|
|
38878
39322
|
}
|
|
38879
39323
|
}
|
|
38880
39324
|
|
|
38881
|
-
// src/files/
|
|
38882
|
-
async function
|
|
38883
|
-
const
|
|
38884
|
-
|
|
38885
|
-
|
|
38886
|
-
|
|
38887
|
-
|
|
39325
|
+
// src/files/browser/handle-file-browser-read.ts
|
|
39326
|
+
async function handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope) {
|
|
39327
|
+
const startLine = typeof msg.startLine === "number" ? msg.startLine : void 0;
|
|
39328
|
+
const endLine = typeof msg.endLine === "number" ? msg.endLine : void 0;
|
|
39329
|
+
const lineOffset = typeof msg.lineOffset === "number" ? msg.lineOffset : void 0;
|
|
39330
|
+
const lineChunkSize = typeof msg.lineChunkSize === "number" ? msg.lineChunkSize : void 0;
|
|
39331
|
+
const encoding = msg.encoding === "base64" ? "base64" : "utf8";
|
|
39332
|
+
const result = gitScope ? await readGitTreeFileAsync(
|
|
39333
|
+
gitScope.repoAbsPath,
|
|
39334
|
+
gitScope.branch,
|
|
39335
|
+
reqPath,
|
|
39336
|
+
startLine,
|
|
39337
|
+
endLine,
|
|
39338
|
+
lineOffset,
|
|
39339
|
+
lineChunkSize,
|
|
39340
|
+
encoding
|
|
39341
|
+
) : await readFileAsync(
|
|
39342
|
+
reqPath,
|
|
39343
|
+
startLine,
|
|
39344
|
+
endLine,
|
|
39345
|
+
lineOffset,
|
|
39346
|
+
lineChunkSize,
|
|
39347
|
+
sessionParentPath,
|
|
39348
|
+
encoding
|
|
39349
|
+
);
|
|
39350
|
+
if ("error" in result) {
|
|
39351
|
+
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
39352
|
+
return;
|
|
38888
39353
|
}
|
|
38889
|
-
|
|
39354
|
+
const payload = {
|
|
39355
|
+
type: "file_browser_response",
|
|
39356
|
+
id: msg.id,
|
|
39357
|
+
content: result.content,
|
|
39358
|
+
totalLines: result.totalLines,
|
|
39359
|
+
size: result.size
|
|
39360
|
+
};
|
|
39361
|
+
if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
|
|
39362
|
+
if (result.mimeType != null) payload.mimeType = result.mimeType;
|
|
39363
|
+
if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
|
|
39364
|
+
sendFileBrowserMessage(socket, e2ee, payload);
|
|
38890
39365
|
}
|
|
38891
39366
|
|
|
38892
|
-
// src/files/
|
|
38893
|
-
|
|
38894
|
-
|
|
38895
|
-
|
|
38896
|
-
|
|
38897
|
-
|
|
38898
|
-
|
|
38899
|
-
const sessionParentPath = path54.resolve(
|
|
38900
|
-
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
38901
|
-
);
|
|
38902
|
-
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
38903
|
-
const payload2 = {
|
|
38904
|
-
type: "file_browser_search_response",
|
|
38905
|
-
id: msg.id,
|
|
38906
|
-
paths: [],
|
|
38907
|
-
indexReady: false
|
|
38908
|
-
};
|
|
38909
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload2, ["paths"]) : payload2);
|
|
38910
|
-
return;
|
|
38911
|
-
}
|
|
38912
|
-
const results = await searchBridgeFilePathsAsync(sessionParentPath, q, SEARCH_LIMIT);
|
|
38913
|
-
const payload = {
|
|
38914
|
-
type: "file_browser_search_response",
|
|
38915
|
-
id: msg.id,
|
|
38916
|
-
paths: results,
|
|
38917
|
-
indexReady: true
|
|
38918
|
-
};
|
|
38919
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["paths"]) : payload);
|
|
38920
|
-
})();
|
|
38921
|
-
}
|
|
38922
|
-
function triggerFileIndexBuild(sessionParentPath = getBridgeRoot()) {
|
|
38923
|
-
setImmediate(() => {
|
|
38924
|
-
void ensureFileIndexAsync(sessionParentPath).catch((e) => {
|
|
38925
|
-
console.error("[file-index] Background build failed:", e);
|
|
38926
|
-
});
|
|
38927
|
-
});
|
|
39367
|
+
// src/files/browser/resolve-git-branch-scope.ts
|
|
39368
|
+
function resolveGitBranchScope(msg) {
|
|
39369
|
+
const gitBranchScope = msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0;
|
|
39370
|
+
if (!gitBranchScope) return null;
|
|
39371
|
+
const repoAbsPath = resolveRepoAbsPathFromBridge(msg.repoRelPath);
|
|
39372
|
+
if (!repoAbsPath) return null;
|
|
39373
|
+
return { repoAbsPath, branch: msg.branch.trim() };
|
|
38928
39374
|
}
|
|
38929
39375
|
|
|
38930
|
-
// src/files/
|
|
38931
|
-
function sendFileBrowserMessage(socket, e2ee, payload) {
|
|
38932
|
-
sendWsMessage(socket, e2ee ? e2ee.encryptFields(payload, ["entries", "content", "totalLines", "size", "lineOffset"]) : payload);
|
|
38933
|
-
}
|
|
39376
|
+
// src/files/browser/index.ts
|
|
38934
39377
|
function handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager) {
|
|
38935
39378
|
void (async () => {
|
|
38936
39379
|
const reqPath = msg.path.replace(/^\/+/, "") || ".";
|
|
38937
39380
|
const op = msg.op === "read" ? "read" : "list";
|
|
38938
39381
|
const sessionParentPath = sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : void 0;
|
|
39382
|
+
const gitScope = resolveGitBranchScope(msg);
|
|
39383
|
+
if (msg.source === "git_branch" && typeof msg.repoRelPath === "string" && typeof msg.branch === "string" && msg.branch.trim().length > 0 && !gitScope) {
|
|
39384
|
+
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: "Invalid repository path" });
|
|
39385
|
+
return;
|
|
39386
|
+
}
|
|
38939
39387
|
if (op === "list") {
|
|
38940
|
-
|
|
38941
|
-
if ("error" in result) {
|
|
38942
|
-
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
38943
|
-
} else {
|
|
38944
|
-
sendFileBrowserMessage(socket, e2ee, { type: "file_browser_response", id: msg.id, entries: result.entries });
|
|
38945
|
-
if (reqPath === "." || reqPath === "") {
|
|
38946
|
-
triggerFileIndexBuild(sessionParentPath);
|
|
38947
|
-
}
|
|
38948
|
-
}
|
|
39388
|
+
await handleFileBrowserList(socket, e2ee, msg.id, reqPath, sessionParentPath, gitScope);
|
|
38949
39389
|
} else {
|
|
38950
|
-
|
|
38951
|
-
const endLine = typeof msg.endLine === "number" ? msg.endLine : void 0;
|
|
38952
|
-
const lineOffset = typeof msg.lineOffset === "number" ? msg.lineOffset : void 0;
|
|
38953
|
-
const lineChunkSize = typeof msg.lineChunkSize === "number" ? msg.lineChunkSize : void 0;
|
|
38954
|
-
const encoding = msg.encoding === "base64" ? "base64" : "utf8";
|
|
38955
|
-
const result = await readFileAsync(
|
|
38956
|
-
reqPath,
|
|
38957
|
-
startLine,
|
|
38958
|
-
endLine,
|
|
38959
|
-
lineOffset,
|
|
38960
|
-
lineChunkSize,
|
|
38961
|
-
sessionParentPath,
|
|
38962
|
-
encoding
|
|
38963
|
-
);
|
|
38964
|
-
if ("error" in result) {
|
|
38965
|
-
sendWsMessage(socket, { type: "file_browser_response", id: msg.id, error: result.error });
|
|
38966
|
-
} else {
|
|
38967
|
-
const payload = {
|
|
38968
|
-
type: "file_browser_response",
|
|
38969
|
-
id: msg.id,
|
|
38970
|
-
content: result.content,
|
|
38971
|
-
totalLines: result.totalLines,
|
|
38972
|
-
size: result.size
|
|
38973
|
-
};
|
|
38974
|
-
if (result.lineOffset != null) payload.lineOffset = result.lineOffset;
|
|
38975
|
-
if (result.mimeType != null) payload.mimeType = result.mimeType;
|
|
38976
|
-
if (result.resolvedPath != null) payload.resolvedPath = result.resolvedPath;
|
|
38977
|
-
sendFileBrowserMessage(socket, e2ee, payload);
|
|
38978
|
-
}
|
|
39390
|
+
await handleFileBrowserRead(socket, e2ee, msg, reqPath, sessionParentPath, gitScope);
|
|
38979
39391
|
}
|
|
38980
39392
|
})();
|
|
38981
39393
|
}
|
|
@@ -38985,12 +39397,7 @@ function handleFileBrowserRequestMessage(msg, { getWs, e2ee, sessionWorktreeMana
|
|
|
38985
39397
|
if (typeof msg.id !== "string" || typeof msg.path !== "string") return;
|
|
38986
39398
|
const socket = getWs();
|
|
38987
39399
|
if (!socket) return;
|
|
38988
|
-
handleFileBrowserRequest(
|
|
38989
|
-
msg,
|
|
38990
|
-
socket,
|
|
38991
|
-
e2ee,
|
|
38992
|
-
sessionWorktreeManager
|
|
38993
|
-
);
|
|
39400
|
+
handleFileBrowserRequest(msg, socket, e2ee, sessionWorktreeManager);
|
|
38994
39401
|
}
|
|
38995
39402
|
function handleFileBrowserSearchMessage(msg, { getWs, e2ee, sessionWorktreeManager }) {
|
|
38996
39403
|
if (typeof msg.id !== "string") return;
|
|
@@ -39025,7 +39432,7 @@ function isValidRemoteSkillInstallItem(item) {
|
|
|
39025
39432
|
|
|
39026
39433
|
// src/skills/install/install-remote-skills-async.ts
|
|
39027
39434
|
import fs43 from "node:fs";
|
|
39028
|
-
import
|
|
39435
|
+
import path56 from "node:path";
|
|
39029
39436
|
|
|
39030
39437
|
// src/skills/install/constants.ts
|
|
39031
39438
|
var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
@@ -39036,8 +39443,8 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
|
|
|
39036
39443
|
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
39037
39444
|
await yieldToEventLoop();
|
|
39038
39445
|
}
|
|
39039
|
-
const dest =
|
|
39040
|
-
await fs43.promises.mkdir(
|
|
39446
|
+
const dest = path56.join(skillDir, f.path);
|
|
39447
|
+
await fs43.promises.mkdir(path56.dirname(dest), { recursive: true });
|
|
39041
39448
|
if (f.text !== void 0) {
|
|
39042
39449
|
await fs43.promises.writeFile(dest, f.text, "utf8");
|
|
39043
39450
|
} else if (f.base64) {
|
|
@@ -39053,7 +39460,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
|
39053
39460
|
try {
|
|
39054
39461
|
for (const item of items) {
|
|
39055
39462
|
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
39056
|
-
const skillDir =
|
|
39463
|
+
const skillDir = path56.join(cwd, targetDir, item.skillName);
|
|
39057
39464
|
for (const f of item.files) {
|
|
39058
39465
|
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
39059
39466
|
}
|
|
@@ -39392,7 +39799,7 @@ var handleDevServersConfig = (msg, deps) => {
|
|
|
39392
39799
|
};
|
|
39393
39800
|
|
|
39394
39801
|
// src/git/bridge-git-context.ts
|
|
39395
|
-
import * as
|
|
39802
|
+
import * as path57 from "node:path";
|
|
39396
39803
|
|
|
39397
39804
|
// src/git/branches/get-current-branch.ts
|
|
39398
39805
|
async function getCurrentBranch(repoPath) {
|
|
@@ -39442,12 +39849,12 @@ async function listRepoBranchRefs(repoPath) {
|
|
|
39442
39849
|
// src/git/bridge-git-context.ts
|
|
39443
39850
|
function folderNameForRelPath(relPath, bridgeRoot) {
|
|
39444
39851
|
if (relPath === "." || relPath === "") {
|
|
39445
|
-
return
|
|
39852
|
+
return path57.basename(path57.resolve(bridgeRoot)) || "repo";
|
|
39446
39853
|
}
|
|
39447
|
-
return
|
|
39854
|
+
return path57.basename(relPath) || relPath;
|
|
39448
39855
|
}
|
|
39449
39856
|
async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
39450
|
-
const root =
|
|
39857
|
+
const root = path57.resolve(bridgeRoot);
|
|
39451
39858
|
if (await isGitRepoDirectory(root)) {
|
|
39452
39859
|
const remoteUrl = await getRemoteOriginUrl(root);
|
|
39453
39860
|
return [{ absolutePath: root, remoteUrl }];
|
|
@@ -39455,19 +39862,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
|
39455
39862
|
const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
|
|
39456
39863
|
const byPath = /* @__PURE__ */ new Map();
|
|
39457
39864
|
for (const repo of [...deep, ...shallow]) {
|
|
39458
|
-
byPath.set(
|
|
39865
|
+
byPath.set(path57.resolve(repo.absolutePath), repo);
|
|
39459
39866
|
}
|
|
39460
39867
|
return [...byPath.values()];
|
|
39461
39868
|
}
|
|
39462
39869
|
async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
39463
|
-
const bridgeResolved =
|
|
39870
|
+
const bridgeResolved = path57.resolve(bridgeRoot);
|
|
39464
39871
|
const repos = await discoverGitReposForBridgeContext(bridgeResolved);
|
|
39465
39872
|
const rows = [];
|
|
39466
39873
|
for (let i = 0; i < repos.length; i++) {
|
|
39467
39874
|
if (i > 0) await yieldToEventLoop();
|
|
39468
39875
|
const repo = repos[i];
|
|
39469
|
-
let rel =
|
|
39470
|
-
if (rel.startsWith("..") ||
|
|
39876
|
+
let rel = path57.relative(bridgeResolved, repo.absolutePath);
|
|
39877
|
+
if (rel.startsWith("..") || path57.isAbsolute(rel)) continue;
|
|
39471
39878
|
const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
|
|
39472
39879
|
const currentBranch = await getCurrentBranch(repo.absolutePath);
|
|
39473
39880
|
const remoteUrl = repo.remoteUrl.trim() || null;
|
|
@@ -39482,11 +39889,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
|
39482
39889
|
return rows;
|
|
39483
39890
|
}
|
|
39484
39891
|
async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
39485
|
-
const bridgeResolved =
|
|
39892
|
+
const bridgeResolved = path57.resolve(bridgeRoot);
|
|
39486
39893
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
39487
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
39488
|
-
const resolved =
|
|
39489
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
39894
|
+
const repoPath = rel === "" ? bridgeResolved : path57.join(bridgeResolved, rel);
|
|
39895
|
+
const resolved = path57.resolve(repoPath);
|
|
39896
|
+
if (!resolved.startsWith(bridgeResolved + path57.sep) && resolved !== bridgeResolved) {
|
|
39490
39897
|
return [];
|
|
39491
39898
|
}
|
|
39492
39899
|
return listRepoBranchRefs(resolved);
|
|
@@ -40070,10 +40477,10 @@ function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
|
|
|
40070
40477
|
}
|
|
40071
40478
|
|
|
40072
40479
|
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
40073
|
-
import * as
|
|
40480
|
+
import * as path59 from "node:path";
|
|
40074
40481
|
|
|
40075
40482
|
// src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
|
|
40076
|
-
import * as
|
|
40483
|
+
import * as path58 from "node:path";
|
|
40077
40484
|
async function probeOneAgentTypeForCapabilities(params) {
|
|
40078
40485
|
const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true, shouldContinue } = params;
|
|
40079
40486
|
const canContinue = () => shouldContinue?.() !== false;
|
|
@@ -40111,7 +40518,7 @@ async function probeOneAgentTypeForCapabilities(params) {
|
|
|
40111
40518
|
if (!canContinue()) return false;
|
|
40112
40519
|
handle = await resolved.createClient({
|
|
40113
40520
|
command: resolved.command,
|
|
40114
|
-
cwd:
|
|
40521
|
+
cwd: path58.resolve(cwd),
|
|
40115
40522
|
backendAgentType: agentType,
|
|
40116
40523
|
sessionMode: "agent",
|
|
40117
40524
|
persistedAcpSessionId: null,
|
|
@@ -40189,7 +40596,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
40189
40596
|
const { workspaceId, log: log2, getWs } = params;
|
|
40190
40597
|
const isCurrent = beginAgentCapabilityWarmupRun();
|
|
40191
40598
|
if (!isCurrent()) return;
|
|
40192
|
-
const cwd =
|
|
40599
|
+
const cwd = path59.resolve(getBridgeRoot());
|
|
40193
40600
|
async function sendBatchFromCache() {
|
|
40194
40601
|
if (!isCurrent()) return;
|
|
40195
40602
|
const socket = getWs();
|
|
@@ -40535,18 +40942,18 @@ import * as http from "node:http";
|
|
|
40535
40942
|
|
|
40536
40943
|
// src/mcp/bridge-access/read-json-body.ts
|
|
40537
40944
|
function readJsonBody(req) {
|
|
40538
|
-
return new Promise((
|
|
40945
|
+
return new Promise((resolve33, reject) => {
|
|
40539
40946
|
const chunks = [];
|
|
40540
40947
|
req.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
40541
40948
|
req.on("end", () => {
|
|
40542
40949
|
try {
|
|
40543
40950
|
const raw = Buffer.concat(chunks).toString("utf8").trim();
|
|
40544
40951
|
if (!raw) {
|
|
40545
|
-
|
|
40952
|
+
resolve33({});
|
|
40546
40953
|
return;
|
|
40547
40954
|
}
|
|
40548
40955
|
const parsed = JSON.parse(raw);
|
|
40549
|
-
|
|
40956
|
+
resolve33(parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {});
|
|
40550
40957
|
} catch (e) {
|
|
40551
40958
|
reject(e);
|
|
40552
40959
|
}
|
|
@@ -40604,7 +41011,7 @@ function createBridgeAccessRequestHandler(registry2) {
|
|
|
40604
41011
|
// src/mcp/bridge-access/start-server.ts
|
|
40605
41012
|
function startBridgeAccessServer(registry2) {
|
|
40606
41013
|
const server = http.createServer(createBridgeAccessRequestHandler(registry2));
|
|
40607
|
-
return new Promise((
|
|
41014
|
+
return new Promise((resolve33, reject) => {
|
|
40608
41015
|
server.once("error", reject);
|
|
40609
41016
|
server.listen(0, "127.0.0.1", () => {
|
|
40610
41017
|
const addr = server.address();
|
|
@@ -40612,7 +41019,7 @@ function startBridgeAccessServer(registry2) {
|
|
|
40612
41019
|
reject(new Error("Bridge access server did not bind"));
|
|
40613
41020
|
return;
|
|
40614
41021
|
}
|
|
40615
|
-
|
|
41022
|
+
resolve33({
|
|
40616
41023
|
port: addr.port,
|
|
40617
41024
|
close: () => new Promise((closeResolve, closeReject) => {
|
|
40618
41025
|
server.close((err) => err ? closeReject(err) : closeResolve());
|
|
@@ -40752,8 +41159,8 @@ async function createBridgeConnection(options) {
|
|
|
40752
41159
|
getCloudAccessToken: () => tokens.accessToken
|
|
40753
41160
|
};
|
|
40754
41161
|
const identifyReportedPaths = {
|
|
40755
|
-
bridgeRootPath:
|
|
40756
|
-
worktreesRootPath:
|
|
41162
|
+
bridgeRootPath: path60.resolve(getBridgeRoot()),
|
|
41163
|
+
worktreesRootPath: path60.resolve(worktreesRootPath)
|
|
40757
41164
|
};
|
|
40758
41165
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
40759
41166
|
state,
|