@buildautomaton/cli 0.1.57 → 0.1.59
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/README.md +1 -1
- package/dist/cli.js +1283 -818
- package/dist/cli.js.map +4 -4
- package/dist/index.js +1294 -829
- package/dist/index.js.map +4 -4
- package/package.json +1 -1
- package/dist/code-nav-cache-migrations/002_code_nav_scope_chain.sql +0 -15
- package/dist/code-nav-cache-migrations/002_symbol_index_context.sql +0 -3
- package/dist/code-nav-cache-migrations/003_code_nav_query_indexes.sql +0 -5
- package/dist/code-nav-cache-migrations/003_symbol_index_parent_scope.sql +0 -2
- package/dist/code-nav-cache-migrations/004_symbol_index_import.sql +0 -19
- package/dist/code-nav-cache-migrations/005_symbol_index_member_parent_scope.sql +0 -2
- package/dist/fork-history-mcp-server.js +0 -132
- package/dist/fork-history-mcp-server.js.map +0 -7
- package/dist/migrations/002_acp_capability_cache.sql +0 -10
- package/dist/migrations/002_agent_capability_cache.sql +0 -10
- package/dist/migrations/003_file_index_parent_paths.sql +0 -17
- package/dist/migrations/004_bridge_runtime.sql +0 -14
- package/dist/migrations/004_code_nav_symbol_index.sql +0 -23
- package/dist/migrations/005_code_nav_index_version.sql +0 -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: path74, errorMaps, issueData } = params;
|
|
4179
|
+
const fullPath = [...path74, ...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, path74, key) {
|
|
4488
4488
|
this._cachedPath = [];
|
|
4489
4489
|
this.parent = parent;
|
|
4490
4490
|
this.data = value;
|
|
4491
|
-
this._path =
|
|
4491
|
+
this._path = path74;
|
|
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, path74) {
|
|
8107
|
+
if (!path74)
|
|
8108
8108
|
return obj;
|
|
8109
|
-
return
|
|
8109
|
+
return path74.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(path74, 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(path74);
|
|
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, path74 = []) => {
|
|
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 = [...path74, ...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(path74) {
|
|
8592
8592
|
const segs = [];
|
|
8593
|
-
for (const seg of
|
|
8593
|
+
for (const seg of path74) {
|
|
8594
8594
|
if (typeof seg === "number")
|
|
8595
8595
|
segs.push(`[${seg}]`);
|
|
8596
8596
|
else if (typeof seg === "symbol")
|
|
@@ -21596,7 +21596,7 @@ var require_ignore = __commonJS({
|
|
|
21596
21596
|
// path matching.
|
|
21597
21597
|
// - check `string` either `MODE_IGNORE` or `MODE_CHECK_IGNORE`
|
|
21598
21598
|
// @returns {TestResult} true if a file is ignored
|
|
21599
|
-
test(
|
|
21599
|
+
test(path74, checkUnignored, mode) {
|
|
21600
21600
|
let ignored = false;
|
|
21601
21601
|
let unignored = false;
|
|
21602
21602
|
let matchedRule;
|
|
@@ -21605,7 +21605,7 @@ var require_ignore = __commonJS({
|
|
|
21605
21605
|
if (unignored === negative && ignored !== unignored || negative && !ignored && !unignored && !checkUnignored) {
|
|
21606
21606
|
return;
|
|
21607
21607
|
}
|
|
21608
|
-
const matched = rule[mode].test(
|
|
21608
|
+
const matched = rule[mode].test(path74);
|
|
21609
21609
|
if (!matched) {
|
|
21610
21610
|
return;
|
|
21611
21611
|
}
|
|
@@ -21626,17 +21626,17 @@ var require_ignore = __commonJS({
|
|
|
21626
21626
|
var throwError = (message, Ctor) => {
|
|
21627
21627
|
throw new Ctor(message);
|
|
21628
21628
|
};
|
|
21629
|
-
var checkPath = (
|
|
21630
|
-
if (!isString(
|
|
21629
|
+
var checkPath = (path74, originalPath, doThrow) => {
|
|
21630
|
+
if (!isString(path74)) {
|
|
21631
21631
|
return doThrow(
|
|
21632
21632
|
`path must be a string, but got \`${originalPath}\``,
|
|
21633
21633
|
TypeError
|
|
21634
21634
|
);
|
|
21635
21635
|
}
|
|
21636
|
-
if (!
|
|
21636
|
+
if (!path74) {
|
|
21637
21637
|
return doThrow(`path must not be empty`, TypeError);
|
|
21638
21638
|
}
|
|
21639
|
-
if (checkPath.isNotRelative(
|
|
21639
|
+
if (checkPath.isNotRelative(path74)) {
|
|
21640
21640
|
const r = "`path.relative()`d";
|
|
21641
21641
|
return doThrow(
|
|
21642
21642
|
`path should be a ${r} string, but got "${originalPath}"`,
|
|
@@ -21645,7 +21645,7 @@ var require_ignore = __commonJS({
|
|
|
21645
21645
|
}
|
|
21646
21646
|
return true;
|
|
21647
21647
|
};
|
|
21648
|
-
var isNotRelative = (
|
|
21648
|
+
var isNotRelative = (path74) => REGEX_TEST_INVALID_PATH.test(path74);
|
|
21649
21649
|
checkPath.isNotRelative = isNotRelative;
|
|
21650
21650
|
checkPath.convert = (p) => p;
|
|
21651
21651
|
var Ignore = class {
|
|
@@ -21675,19 +21675,19 @@ var require_ignore = __commonJS({
|
|
|
21675
21675
|
}
|
|
21676
21676
|
// @returns {TestResult}
|
|
21677
21677
|
_test(originalPath, cache2, checkUnignored, slices) {
|
|
21678
|
-
const
|
|
21678
|
+
const path74 = originalPath && checkPath.convert(originalPath);
|
|
21679
21679
|
checkPath(
|
|
21680
|
-
|
|
21680
|
+
path74,
|
|
21681
21681
|
originalPath,
|
|
21682
21682
|
this._strictPathCheck ? throwError : RETURN_FALSE
|
|
21683
21683
|
);
|
|
21684
|
-
return this._t(
|
|
21684
|
+
return this._t(path74, cache2, checkUnignored, slices);
|
|
21685
21685
|
}
|
|
21686
|
-
checkIgnore(
|
|
21687
|
-
if (!REGEX_TEST_TRAILING_SLASH.test(
|
|
21688
|
-
return this.test(
|
|
21686
|
+
checkIgnore(path74) {
|
|
21687
|
+
if (!REGEX_TEST_TRAILING_SLASH.test(path74)) {
|
|
21688
|
+
return this.test(path74);
|
|
21689
21689
|
}
|
|
21690
|
-
const slices =
|
|
21690
|
+
const slices = path74.split(SLASH).filter(Boolean);
|
|
21691
21691
|
slices.pop();
|
|
21692
21692
|
if (slices.length) {
|
|
21693
21693
|
const parent = this._t(
|
|
@@ -21700,18 +21700,18 @@ var require_ignore = __commonJS({
|
|
|
21700
21700
|
return parent;
|
|
21701
21701
|
}
|
|
21702
21702
|
}
|
|
21703
|
-
return this._rules.test(
|
|
21703
|
+
return this._rules.test(path74, false, MODE_CHECK_IGNORE);
|
|
21704
21704
|
}
|
|
21705
|
-
_t(
|
|
21706
|
-
if (
|
|
21707
|
-
return cache2[
|
|
21705
|
+
_t(path74, cache2, checkUnignored, slices) {
|
|
21706
|
+
if (path74 in cache2) {
|
|
21707
|
+
return cache2[path74];
|
|
21708
21708
|
}
|
|
21709
21709
|
if (!slices) {
|
|
21710
|
-
slices =
|
|
21710
|
+
slices = path74.split(SLASH).filter(Boolean);
|
|
21711
21711
|
}
|
|
21712
21712
|
slices.pop();
|
|
21713
21713
|
if (!slices.length) {
|
|
21714
|
-
return cache2[
|
|
21714
|
+
return cache2[path74] = this._rules.test(path74, checkUnignored, MODE_IGNORE);
|
|
21715
21715
|
}
|
|
21716
21716
|
const parent = this._t(
|
|
21717
21717
|
slices.join(SLASH) + SLASH,
|
|
@@ -21719,29 +21719,29 @@ var require_ignore = __commonJS({
|
|
|
21719
21719
|
checkUnignored,
|
|
21720
21720
|
slices
|
|
21721
21721
|
);
|
|
21722
|
-
return cache2[
|
|
21722
|
+
return cache2[path74] = parent.ignored ? parent : this._rules.test(path74, checkUnignored, MODE_IGNORE);
|
|
21723
21723
|
}
|
|
21724
|
-
ignores(
|
|
21725
|
-
return this._test(
|
|
21724
|
+
ignores(path74) {
|
|
21725
|
+
return this._test(path74, this._ignoreCache, false).ignored;
|
|
21726
21726
|
}
|
|
21727
21727
|
createFilter() {
|
|
21728
|
-
return (
|
|
21728
|
+
return (path74) => !this.ignores(path74);
|
|
21729
21729
|
}
|
|
21730
21730
|
filter(paths) {
|
|
21731
21731
|
return makeArray(paths).filter(this.createFilter());
|
|
21732
21732
|
}
|
|
21733
21733
|
// @returns {TestResult}
|
|
21734
|
-
test(
|
|
21735
|
-
return this._test(
|
|
21734
|
+
test(path74) {
|
|
21735
|
+
return this._test(path74, this._testCache, true);
|
|
21736
21736
|
}
|
|
21737
21737
|
};
|
|
21738
21738
|
var factory = (options) => new Ignore(options);
|
|
21739
|
-
var isPathValid = (
|
|
21739
|
+
var isPathValid = (path74) => checkPath(path74 && checkPath.convert(path74), path74, RETURN_FALSE);
|
|
21740
21740
|
var setupWindows = () => {
|
|
21741
21741
|
const makePosix = (str) => /^\\\\\?\\/.test(str) || /["<>|\u0000-\u001F]+/u.test(str) ? str : str.replace(/\\/g, "/");
|
|
21742
21742
|
checkPath.convert = makePosix;
|
|
21743
21743
|
const REGEX_TEST_WINDOWS_PATH_ABSOLUTE = /^[a-z]:\//i;
|
|
21744
|
-
checkPath.isNotRelative = (
|
|
21744
|
+
checkPath.isNotRelative = (path74) => REGEX_TEST_WINDOWS_PATH_ABSOLUTE.test(path74) || isNotRelative(path74);
|
|
21745
21745
|
};
|
|
21746
21746
|
if (
|
|
21747
21747
|
// Detect `process` so that it can run in browsers.
|
|
@@ -22530,10 +22530,10 @@ var require_src2 = __commonJS({
|
|
|
22530
22530
|
var fs_1 = __require("fs");
|
|
22531
22531
|
var debug_1 = __importDefault(require_src());
|
|
22532
22532
|
var log2 = debug_1.default("@kwsites/file-exists");
|
|
22533
|
-
function check2(
|
|
22534
|
-
log2(`checking %s`,
|
|
22533
|
+
function check2(path74, isFile, isDirectory) {
|
|
22534
|
+
log2(`checking %s`, path74);
|
|
22535
22535
|
try {
|
|
22536
|
-
const stat2 = fs_1.statSync(
|
|
22536
|
+
const stat2 = fs_1.statSync(path74);
|
|
22537
22537
|
if (stat2.isFile() && isFile) {
|
|
22538
22538
|
log2(`[OK] path represents a file`);
|
|
22539
22539
|
return true;
|
|
@@ -22553,8 +22553,8 @@ var require_src2 = __commonJS({
|
|
|
22553
22553
|
throw e;
|
|
22554
22554
|
}
|
|
22555
22555
|
}
|
|
22556
|
-
function exists2(
|
|
22557
|
-
return check2(
|
|
22556
|
+
function exists2(path74, type = exports.READABLE) {
|
|
22557
|
+
return check2(path74, (type & exports.FILE) > 0, (type & exports.FOLDER) > 0);
|
|
22558
22558
|
}
|
|
22559
22559
|
exports.exists = exists2;
|
|
22560
22560
|
exports.FILE = 1;
|
|
@@ -23584,6 +23584,81 @@ function isUserEndedSessionTurnErrorText(errorText) {
|
|
|
23584
23584
|
// ../types/src/session-kind.ts
|
|
23585
23585
|
var SESSION_KINDS = ["regular", "planning", "planned"];
|
|
23586
23586
|
var SESSION_KIND_SET = new Set(SESSION_KINDS);
|
|
23587
|
+
function parseSessionKind(raw) {
|
|
23588
|
+
if (raw === "todo") return "planned";
|
|
23589
|
+
if (typeof raw === "string" && SESSION_KIND_SET.has(raw)) return raw;
|
|
23590
|
+
return "regular";
|
|
23591
|
+
}
|
|
23592
|
+
|
|
23593
|
+
// ../types/src/planning-todo.ts
|
|
23594
|
+
function planningTodoTitle(item) {
|
|
23595
|
+
return item.content.title;
|
|
23596
|
+
}
|
|
23597
|
+
|
|
23598
|
+
// ../types/src/parse-planning-todo-agent-json.ts
|
|
23599
|
+
function parsePlanningTodoAgentJson(raw) {
|
|
23600
|
+
if (raw == null || raw.trim() === "") return [];
|
|
23601
|
+
let text = raw.trim();
|
|
23602
|
+
const fence = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
23603
|
+
if (fence?.[1]) text = fence[1].trim();
|
|
23604
|
+
let parsed;
|
|
23605
|
+
try {
|
|
23606
|
+
parsed = JSON.parse(text);
|
|
23607
|
+
} catch {
|
|
23608
|
+
const start = text.indexOf("[");
|
|
23609
|
+
const end = text.lastIndexOf("]");
|
|
23610
|
+
if (start < 0 || end <= start) return [];
|
|
23611
|
+
try {
|
|
23612
|
+
parsed = JSON.parse(text.slice(start, end + 1));
|
|
23613
|
+
} catch {
|
|
23614
|
+
return [];
|
|
23615
|
+
}
|
|
23616
|
+
}
|
|
23617
|
+
if (!Array.isArray(parsed)) return [];
|
|
23618
|
+
const rows = [];
|
|
23619
|
+
for (const item of parsed) {
|
|
23620
|
+
if (!item || typeof item !== "object" || Array.isArray(item)) continue;
|
|
23621
|
+
const o = item;
|
|
23622
|
+
const title = typeof o.title === "string" ? o.title.trim() : "";
|
|
23623
|
+
const prompt = typeof o.prompt === "string" ? o.prompt.trim() : typeof o.promptText === "string" ? o.promptText.trim() : "";
|
|
23624
|
+
if (!title || !prompt) continue;
|
|
23625
|
+
rows.push({ title, prompt });
|
|
23626
|
+
}
|
|
23627
|
+
return rows;
|
|
23628
|
+
}
|
|
23629
|
+
|
|
23630
|
+
// ../types/src/build-planning-session-agent-prompt.ts
|
|
23631
|
+
var PLANNING_INSTRUCTIONS = [
|
|
23632
|
+
"PLANNING MODE: You must NOT make any changes to the codebase, filesystem, or environment.",
|
|
23633
|
+
"Do not run tools that modify files or execute commands that change state.",
|
|
23634
|
+
"Your only task is to analyze and produce a plan.",
|
|
23635
|
+
"",
|
|
23636
|
+
"Respond with ONLY a single JSON array \u2014 no markdown fences, no other text before or after.",
|
|
23637
|
+
"Each array element must be an object with exactly:",
|
|
23638
|
+
'- "title": a one-line summary of the task',
|
|
23639
|
+
'- "prompt": the full prompt to use when creating a new draft session from this todo',
|
|
23640
|
+
"",
|
|
23641
|
+
"Example:",
|
|
23642
|
+
'[{"title":"Add user login","prompt":"Implement a login form with email and password..."}]'
|
|
23643
|
+
].join("\n");
|
|
23644
|
+
function buildPlanningSessionAgentPrompt(userPrompt) {
|
|
23645
|
+
return [PLANNING_INSTRUCTIONS, "", "User request:", userPrompt.trim()].join("\n");
|
|
23646
|
+
}
|
|
23647
|
+
function buildPlanningSessionFollowUpAgentPrompt(userPrompt, existingTodos) {
|
|
23648
|
+
const todoLines = existingTodos.length > 0 ? existingTodos.map((t) => {
|
|
23649
|
+
const status = t.plannedSessionId ? "DONE (draft session already created)" : "OPEN";
|
|
23650
|
+
return `- [${status}] ${planningTodoTitle(t)}`;
|
|
23651
|
+
}).join("\n") : "(none yet)";
|
|
23652
|
+
return [
|
|
23653
|
+
PLANNING_INSTRUCTIONS,
|
|
23654
|
+
"",
|
|
23655
|
+
"Existing todo items from this planning session (consider these when responding; do not duplicate completed items):",
|
|
23656
|
+
todoLines,
|
|
23657
|
+
"",
|
|
23658
|
+
"User follow-up:",
|
|
23659
|
+
userPrompt.trim()
|
|
23660
|
+
].join("\n");
|
|
23661
|
+
}
|
|
23587
23662
|
|
|
23588
23663
|
// ../types/src/change-summary-path.ts
|
|
23589
23664
|
function normalizeRepoRelativePath(p) {
|
|
@@ -23640,9 +23715,9 @@ function parseChangeSummaryJson(raw, allowedPaths, options) {
|
|
|
23640
23715
|
const rawPath = typeof o.path === "string" ? o.path.trim() : "";
|
|
23641
23716
|
const summary = typeof o.summary === "string" ? o.summary.trim() : "";
|
|
23642
23717
|
if (!rawPath || !summary) continue;
|
|
23643
|
-
const
|
|
23644
|
-
if (!
|
|
23645
|
-
rows.push({ path:
|
|
23718
|
+
const path74 = skip ? normalizeRepoRelativePath(rawPath) || rawPath : resolveChangeSummaryPathAgainstAllowed(rawPath, allowedPaths);
|
|
23719
|
+
if (!path74) continue;
|
|
23720
|
+
rows.push({ path: path74, summary: clampSummaryToAtMostTwoLines(summary) });
|
|
23646
23721
|
}
|
|
23647
23722
|
return rows;
|
|
23648
23723
|
}
|
|
@@ -23967,6 +24042,19 @@ function buildCliAutoApprovedPermissionRpcResult(requestParams) {
|
|
|
23967
24042
|
};
|
|
23968
24043
|
}
|
|
23969
24044
|
|
|
24045
|
+
// ../types/src/acp-agent-text-stream-bucket.ts
|
|
24046
|
+
function resolveAgentTextStreamBucket(params) {
|
|
24047
|
+
const k = params.transcriptRowKind;
|
|
24048
|
+
const su = params.sessionUpdate;
|
|
24049
|
+
if (k === "agent_thought_chunk" || su === "agent_thought_chunk" || k === "thinking" || su === "thinking") {
|
|
24050
|
+
return "thought";
|
|
24051
|
+
}
|
|
24052
|
+
if (k === "agent_message_chunk" || su === "agent_message_chunk" || k === "update" || su === "update") {
|
|
24053
|
+
return "message";
|
|
24054
|
+
}
|
|
24055
|
+
return null;
|
|
24056
|
+
}
|
|
24057
|
+
|
|
23970
24058
|
// ../types/src/agent-config.ts
|
|
23971
24059
|
var AGENT_CONFIG_CLAUDE_PERMISSION_MODE_KEY = "claude_permission_mode";
|
|
23972
24060
|
var AGENT_CONFIG_CLI_PERMISSION_MODE_KEY = "cli_permission_mode";
|
|
@@ -24956,8 +25044,8 @@ function randomSecret() {
|
|
|
24956
25044
|
}
|
|
24957
25045
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
24958
25046
|
}
|
|
24959
|
-
async function requestPreviewApi(port, secret, method,
|
|
24960
|
-
const url2 = `http://127.0.0.1:${port}${
|
|
25047
|
+
async function requestPreviewApi(port, secret, method, path74, body) {
|
|
25048
|
+
const url2 = `http://127.0.0.1:${port}${path74}`;
|
|
24961
25049
|
const headers = {
|
|
24962
25050
|
[PREVIEW_SECRET_HEADER]: secret,
|
|
24963
25051
|
"Content-Type": "application/json"
|
|
@@ -24969,7 +25057,7 @@ async function requestPreviewApi(port, secret, method, path73, body) {
|
|
|
24969
25057
|
});
|
|
24970
25058
|
const data = await res.json().catch(() => ({}));
|
|
24971
25059
|
if (!res.ok) {
|
|
24972
|
-
throw new Error(data?.error ?? `Preview API ${method} ${
|
|
25060
|
+
throw new Error(data?.error ?? `Preview API ${method} ${path74}: ${res.status}`);
|
|
24973
25061
|
}
|
|
24974
25062
|
return data;
|
|
24975
25063
|
}
|
|
@@ -25184,7 +25272,7 @@ function installBridgeProcessResilience() {
|
|
|
25184
25272
|
}
|
|
25185
25273
|
|
|
25186
25274
|
// src/cli-version.ts
|
|
25187
|
-
var CLI_VERSION = "0.1.
|
|
25275
|
+
var CLI_VERSION = "0.1.59".length > 0 ? "0.1.59" : "0.0.0-dev";
|
|
25188
25276
|
|
|
25189
25277
|
// src/connection/heartbeat/constants.ts
|
|
25190
25278
|
var BRIDGE_APP_HEARTBEAT_INTERVAL_MS = 1e4;
|
|
@@ -26719,7 +26807,7 @@ function readMigrationSql(filename, ...searchSubdirs) {
|
|
|
26719
26807
|
join(moduleDir, "..", sub, filename),
|
|
26720
26808
|
join(moduleDir, "..", "..", "dist", sub, filename)
|
|
26721
26809
|
]);
|
|
26722
|
-
const resolved = candidates.find((
|
|
26810
|
+
const resolved = candidates.find((path74) => existsSync(path74));
|
|
26723
26811
|
if (!resolved) {
|
|
26724
26812
|
throw new Error(`Missing SQLite migration SQL: ${filename} (searched ${searchSubdirs.join(", ")})`);
|
|
26725
26813
|
}
|
|
@@ -31057,176 +31145,6 @@ function createBridgeOnRequest(opts) {
|
|
|
31057
31145
|
};
|
|
31058
31146
|
}
|
|
31059
31147
|
|
|
31060
|
-
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
|
|
31061
|
-
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
31062
|
-
function readOptionalTextField(v) {
|
|
31063
|
-
if (v === null || v === void 0) return "";
|
|
31064
|
-
if (typeof v === "string") return v;
|
|
31065
|
-
return "";
|
|
31066
|
-
}
|
|
31067
|
-
function normalizePathField(raw) {
|
|
31068
|
-
const t = raw.trim();
|
|
31069
|
-
if (t.startsWith("file://")) {
|
|
31070
|
-
try {
|
|
31071
|
-
return fileURLToPath5(t);
|
|
31072
|
-
} catch {
|
|
31073
|
-
return t;
|
|
31074
|
-
}
|
|
31075
|
-
}
|
|
31076
|
-
return t;
|
|
31077
|
-
}
|
|
31078
|
-
function extractDiffPath(o) {
|
|
31079
|
-
for (const k of ["path", "file", "filePath", "filepath", "target_path", "targetPath"]) {
|
|
31080
|
-
const v = o[k];
|
|
31081
|
-
if (typeof v === "string" && v.trim()) return normalizePathField(v);
|
|
31082
|
-
}
|
|
31083
|
-
return null;
|
|
31084
|
-
}
|
|
31085
|
-
|
|
31086
|
-
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/push-diff.ts
|
|
31087
|
-
function pushDiffIfComplete(o, sessionParentPath, out) {
|
|
31088
|
-
const t = o.type;
|
|
31089
|
-
if (typeof t !== "string" || t.toLowerCase() !== "diff") return;
|
|
31090
|
-
const rawPath = extractDiffPath(o);
|
|
31091
|
-
if (!rawPath) return;
|
|
31092
|
-
const resolved = resolveWorkspaceFilePath(sessionParentPath, rawPath);
|
|
31093
|
-
if (!resolved) return;
|
|
31094
|
-
const oldText = readOptionalTextField(o.oldText ?? o.old_text ?? o.before ?? o.oldContent);
|
|
31095
|
-
const newText = readOptionalTextField(o.newText ?? o.new_text ?? o.after ?? o.newContent);
|
|
31096
|
-
out.push({ path: resolved.display, oldText, newText });
|
|
31097
|
-
}
|
|
31098
|
-
|
|
31099
|
-
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/walk-update-for-diffs.ts
|
|
31100
|
-
var NEST_KEYS = [
|
|
31101
|
-
"content",
|
|
31102
|
-
"contents",
|
|
31103
|
-
"result",
|
|
31104
|
-
"output",
|
|
31105
|
-
"delta",
|
|
31106
|
-
"toolResult",
|
|
31107
|
-
"tool_result",
|
|
31108
|
-
"data",
|
|
31109
|
-
"arguments"
|
|
31110
|
-
];
|
|
31111
|
-
function walkValue(value, sessionParentPath, depth, out) {
|
|
31112
|
-
if (depth > 12 || value == null) return;
|
|
31113
|
-
if (Array.isArray(value)) {
|
|
31114
|
-
for (const x of value) walkValue(x, sessionParentPath, depth + 1, out);
|
|
31115
|
-
return;
|
|
31116
|
-
}
|
|
31117
|
-
if (typeof value !== "object") return;
|
|
31118
|
-
const o = value;
|
|
31119
|
-
pushDiffIfComplete(o, sessionParentPath, out);
|
|
31120
|
-
if (o.type === "content" && o.content != null && typeof o.content === "object") {
|
|
31121
|
-
walkValue(o.content, sessionParentPath, depth + 1, out);
|
|
31122
|
-
}
|
|
31123
|
-
for (const k of NEST_KEYS) {
|
|
31124
|
-
if (o.type === "content" && k === "content") continue;
|
|
31125
|
-
const v = o[k];
|
|
31126
|
-
if (v == null) continue;
|
|
31127
|
-
if (k === "arguments" && typeof v === "string") {
|
|
31128
|
-
try {
|
|
31129
|
-
walkValue(JSON.parse(v), sessionParentPath, depth + 1, out);
|
|
31130
|
-
} catch {
|
|
31131
|
-
}
|
|
31132
|
-
continue;
|
|
31133
|
-
}
|
|
31134
|
-
walkValue(v, sessionParentPath, depth + 1, out);
|
|
31135
|
-
}
|
|
31136
|
-
}
|
|
31137
|
-
|
|
31138
|
-
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/extract.ts
|
|
31139
|
-
function extractAcpFileDiffsFromUpdate(update, sessionParentPath) {
|
|
31140
|
-
if (!update || typeof update !== "object") return [];
|
|
31141
|
-
const u = update;
|
|
31142
|
-
const out = [];
|
|
31143
|
-
const content = u.content;
|
|
31144
|
-
if (Array.isArray(content)) {
|
|
31145
|
-
for (const x of content) walkValue(x, sessionParentPath, 0, out);
|
|
31146
|
-
}
|
|
31147
|
-
const byPath = /* @__PURE__ */ new Map();
|
|
31148
|
-
for (const d of out) byPath.set(d.path, d);
|
|
31149
|
-
return [...byPath.values()];
|
|
31150
|
-
}
|
|
31151
|
-
|
|
31152
|
-
// src/agents/acp/hooks/extract-tool-target-paths.ts
|
|
31153
|
-
function addPath(sessionParentPath, raw, out) {
|
|
31154
|
-
if (typeof raw !== "string") return;
|
|
31155
|
-
const trimmed2 = raw.trim();
|
|
31156
|
-
if (!trimmed2) return;
|
|
31157
|
-
const resolved = resolveWorkspaceFilePath(sessionParentPath, trimmed2);
|
|
31158
|
-
if (!resolved) return;
|
|
31159
|
-
out.add(resolved.display);
|
|
31160
|
-
}
|
|
31161
|
-
function walkLocations(sessionParentPath, loc, out) {
|
|
31162
|
-
if (!Array.isArray(loc)) return;
|
|
31163
|
-
for (const item of loc) {
|
|
31164
|
-
if (item && typeof item === "object") addPath(sessionParentPath, item.path, out);
|
|
31165
|
-
}
|
|
31166
|
-
}
|
|
31167
|
-
var PATH_KEYS = [
|
|
31168
|
-
"path",
|
|
31169
|
-
"file",
|
|
31170
|
-
"filePath",
|
|
31171
|
-
"filepath",
|
|
31172
|
-
"target_path",
|
|
31173
|
-
"targetPath",
|
|
31174
|
-
"file_path",
|
|
31175
|
-
"target_file"
|
|
31176
|
-
];
|
|
31177
|
-
function collectFromObject(sessionParentPath, obj, out, depth) {
|
|
31178
|
-
if (depth > 10) return;
|
|
31179
|
-
for (const k of PATH_KEYS) {
|
|
31180
|
-
if (k in obj) addPath(sessionParentPath, obj[k], out);
|
|
31181
|
-
}
|
|
31182
|
-
for (const v of Object.values(obj)) {
|
|
31183
|
-
if (v != null && typeof v === "object") collectUnknown(sessionParentPath, v, out, depth + 1);
|
|
31184
|
-
}
|
|
31185
|
-
}
|
|
31186
|
-
function collectUnknown(sessionParentPath, v, out, depth) {
|
|
31187
|
-
if (depth > 10 || v == null) return;
|
|
31188
|
-
if (Array.isArray(v)) {
|
|
31189
|
-
for (const x of v) collectUnknown(sessionParentPath, x, out, depth + 1);
|
|
31190
|
-
return;
|
|
31191
|
-
}
|
|
31192
|
-
if (typeof v === "object") collectFromObject(sessionParentPath, v, out, depth);
|
|
31193
|
-
}
|
|
31194
|
-
function walkContentArray(sessionParentPath, content, out) {
|
|
31195
|
-
if (!Array.isArray(content)) return;
|
|
31196
|
-
for (const item of content) {
|
|
31197
|
-
if (!item || typeof item !== "object") continue;
|
|
31198
|
-
const o = item;
|
|
31199
|
-
if (typeof o.type === "string" && o.type.toLowerCase() === "diff") {
|
|
31200
|
-
for (const k of PATH_KEYS) if (k in o) addPath(sessionParentPath, o[k], out);
|
|
31201
|
-
}
|
|
31202
|
-
if (o.type === "content" && o.content != null && typeof o.content === "object") {
|
|
31203
|
-
const inner = o.content;
|
|
31204
|
-
if (typeof inner.type === "string" && inner.type.toLowerCase() === "diff") {
|
|
31205
|
-
for (const k of PATH_KEYS) if (k in inner) addPath(sessionParentPath, inner[k], out);
|
|
31206
|
-
}
|
|
31207
|
-
}
|
|
31208
|
-
}
|
|
31209
|
-
}
|
|
31210
|
-
function extractToolTargetDisplayPaths(update, sessionParentPath) {
|
|
31211
|
-
const out = /* @__PURE__ */ new Set();
|
|
31212
|
-
if (!update || typeof update !== "object") return [];
|
|
31213
|
-
const u = update;
|
|
31214
|
-
walkLocations(sessionParentPath, u.locations, out);
|
|
31215
|
-
walkLocations(sessionParentPath, u.fileLocations, out);
|
|
31216
|
-
walkLocations(sessionParentPath, u.file_locations, out);
|
|
31217
|
-
const tc = u.toolCall ?? u.tool_call;
|
|
31218
|
-
if (tc && typeof tc.arguments === "string") {
|
|
31219
|
-
try {
|
|
31220
|
-
const parsed = JSON.parse(tc.arguments);
|
|
31221
|
-
collectUnknown(sessionParentPath, parsed, out, 0);
|
|
31222
|
-
} catch {
|
|
31223
|
-
}
|
|
31224
|
-
}
|
|
31225
|
-
walkContentArray(sessionParentPath, u.content, out);
|
|
31226
|
-
collectFromObject(sessionParentPath, u, out, 0);
|
|
31227
|
-
return [...out];
|
|
31228
|
-
}
|
|
31229
|
-
|
|
31230
31148
|
// src/agents/acp/hooks/bridge-on-session-update/constants.ts
|
|
31231
31149
|
var PATH_SNAPSHOT_DEBOUNCE_MS = 500;
|
|
31232
31150
|
|
|
@@ -31374,56 +31292,6 @@ var PathSnapshotTracker = class {
|
|
|
31374
31292
|
}
|
|
31375
31293
|
};
|
|
31376
31294
|
|
|
31377
|
-
// src/agents/acp/hooks/bridge-on-session-update/send-structured-file-changes.ts
|
|
31378
|
-
function sendExtractedDiffsAsSessionFileChanges(diffs, send, sessionParentPath, sessionId, runId, sentPaths, log2) {
|
|
31379
|
-
for (const d of diffs) {
|
|
31380
|
-
try {
|
|
31381
|
-
const patchContent = editSnippetToUnifiedDiff(d.path, d.oldText, d.newText);
|
|
31382
|
-
const dirFlags = getSessionFileChangeDirectoryFlags(sessionParentPath, d.path);
|
|
31383
|
-
send({
|
|
31384
|
-
type: "session_file_change",
|
|
31385
|
-
sessionId,
|
|
31386
|
-
runId,
|
|
31387
|
-
path: d.path,
|
|
31388
|
-
oldText: d.oldText,
|
|
31389
|
-
newText: d.newText,
|
|
31390
|
-
patchContent,
|
|
31391
|
-
isDirectory: dirFlags.isDirectory,
|
|
31392
|
-
directoryRemoved: dirFlags.directoryRemoved
|
|
31393
|
-
});
|
|
31394
|
-
sentPaths.add(d.path);
|
|
31395
|
-
} catch (err) {
|
|
31396
|
-
log2(`[Bridge service] Session file change failed for ${d.path}: ${errorMessage(err)}`);
|
|
31397
|
-
}
|
|
31398
|
-
}
|
|
31399
|
-
}
|
|
31400
|
-
function sendGitHeadVsWorkspaceForToolPaths(mergedPaths, sentPaths, send, sessionParentPath, sessionId, runId, log2) {
|
|
31401
|
-
for (const displayPath of mergedPaths) {
|
|
31402
|
-
if (sentPaths.has(displayPath)) continue;
|
|
31403
|
-
const oldText = readGitHeadBlob(sessionParentPath, displayPath);
|
|
31404
|
-
const newText = readUtf8WorkspaceFile(sessionParentPath, displayPath);
|
|
31405
|
-
if (oldText === newText) continue;
|
|
31406
|
-
try {
|
|
31407
|
-
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
31408
|
-
const dirFlags = getSessionFileChangeDirectoryFlags(sessionParentPath, displayPath);
|
|
31409
|
-
send({
|
|
31410
|
-
type: "session_file_change",
|
|
31411
|
-
sessionId,
|
|
31412
|
-
runId,
|
|
31413
|
-
path: displayPath,
|
|
31414
|
-
oldText,
|
|
31415
|
-
newText,
|
|
31416
|
-
patchContent,
|
|
31417
|
-
isDirectory: dirFlags.isDirectory,
|
|
31418
|
-
directoryRemoved: dirFlags.directoryRemoved
|
|
31419
|
-
});
|
|
31420
|
-
sentPaths.add(displayPath);
|
|
31421
|
-
} catch (err) {
|
|
31422
|
-
log2(`[Bridge service] Session file change failed for ${displayPath}: ${errorMessage(err)}`);
|
|
31423
|
-
}
|
|
31424
|
-
}
|
|
31425
|
-
}
|
|
31426
|
-
|
|
31427
31295
|
// src/agents/acp/hooks/bridge-on-session-update/send-session-info-title-update.ts
|
|
31428
31296
|
function extractSessionInfoTitle(params) {
|
|
31429
31297
|
if (!params || typeof params !== "object") return null;
|
|
@@ -31446,6 +31314,391 @@ function sendSessionInfoTitleUpdate(params) {
|
|
|
31446
31314
|
}
|
|
31447
31315
|
}
|
|
31448
31316
|
|
|
31317
|
+
// src/agents/acp/hooks/bridge-on-session-update/parse-bridge-session-update.ts
|
|
31318
|
+
function parseBridgeSessionUpdate(params) {
|
|
31319
|
+
const p = params;
|
|
31320
|
+
const updateKind = p.sessionUpdate ?? p.session_update ?? p.type ?? "update";
|
|
31321
|
+
const isCompletedToolCallUpdate = updateKind === "tool_call_update" && isCompletedToolStatus(p.status);
|
|
31322
|
+
const toolName = p.toolCall?.name ?? p.tool_call?.name ?? "";
|
|
31323
|
+
const isToolUpdate = updateKind === "tool_call" || updateKind === "tool_call_update" || typeof toolName === "string" && toolName.length > 0;
|
|
31324
|
+
return { updateKind, toolName, isToolUpdate, isCompletedToolCallUpdate };
|
|
31325
|
+
}
|
|
31326
|
+
|
|
31327
|
+
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/paths-and-text.ts
|
|
31328
|
+
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
31329
|
+
function readOptionalTextField(v) {
|
|
31330
|
+
if (v === null || v === void 0) return "";
|
|
31331
|
+
if (typeof v === "string") return v;
|
|
31332
|
+
return "";
|
|
31333
|
+
}
|
|
31334
|
+
function normalizePathField(raw) {
|
|
31335
|
+
const t = raw.trim();
|
|
31336
|
+
if (t.startsWith("file://")) {
|
|
31337
|
+
try {
|
|
31338
|
+
return fileURLToPath5(t);
|
|
31339
|
+
} catch {
|
|
31340
|
+
return t;
|
|
31341
|
+
}
|
|
31342
|
+
}
|
|
31343
|
+
return t;
|
|
31344
|
+
}
|
|
31345
|
+
function extractDiffPath(o) {
|
|
31346
|
+
for (const k of ["path", "file", "filePath", "filepath", "target_path", "targetPath"]) {
|
|
31347
|
+
const v = o[k];
|
|
31348
|
+
if (typeof v === "string" && v.trim()) return normalizePathField(v);
|
|
31349
|
+
}
|
|
31350
|
+
return null;
|
|
31351
|
+
}
|
|
31352
|
+
|
|
31353
|
+
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/push-diff.ts
|
|
31354
|
+
function pushDiffIfComplete(o, sessionParentPath, out) {
|
|
31355
|
+
const t = o.type;
|
|
31356
|
+
if (typeof t !== "string" || t.toLowerCase() !== "diff") return;
|
|
31357
|
+
const rawPath = extractDiffPath(o);
|
|
31358
|
+
if (!rawPath) return;
|
|
31359
|
+
const resolved = resolveWorkspaceFilePath(sessionParentPath, rawPath);
|
|
31360
|
+
if (!resolved) return;
|
|
31361
|
+
const oldText = readOptionalTextField(o.oldText ?? o.old_text ?? o.before ?? o.oldContent);
|
|
31362
|
+
const newText = readOptionalTextField(o.newText ?? o.new_text ?? o.after ?? o.newContent);
|
|
31363
|
+
out.push({ path: resolved.display, oldText, newText });
|
|
31364
|
+
}
|
|
31365
|
+
|
|
31366
|
+
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/walk-update-for-diffs.ts
|
|
31367
|
+
var NEST_KEYS = [
|
|
31368
|
+
"content",
|
|
31369
|
+
"contents",
|
|
31370
|
+
"result",
|
|
31371
|
+
"output",
|
|
31372
|
+
"delta",
|
|
31373
|
+
"toolResult",
|
|
31374
|
+
"tool_result",
|
|
31375
|
+
"data",
|
|
31376
|
+
"arguments"
|
|
31377
|
+
];
|
|
31378
|
+
function walkValue(value, sessionParentPath, depth, out) {
|
|
31379
|
+
if (depth > 12 || value == null) return;
|
|
31380
|
+
if (Array.isArray(value)) {
|
|
31381
|
+
for (const x of value) walkValue(x, sessionParentPath, depth + 1, out);
|
|
31382
|
+
return;
|
|
31383
|
+
}
|
|
31384
|
+
if (typeof value !== "object") return;
|
|
31385
|
+
const o = value;
|
|
31386
|
+
pushDiffIfComplete(o, sessionParentPath, out);
|
|
31387
|
+
if (o.type === "content" && o.content != null && typeof o.content === "object") {
|
|
31388
|
+
walkValue(o.content, sessionParentPath, depth + 1, out);
|
|
31389
|
+
}
|
|
31390
|
+
for (const k of NEST_KEYS) {
|
|
31391
|
+
if (o.type === "content" && k === "content") continue;
|
|
31392
|
+
const v = o[k];
|
|
31393
|
+
if (v == null) continue;
|
|
31394
|
+
if (k === "arguments" && typeof v === "string") {
|
|
31395
|
+
try {
|
|
31396
|
+
walkValue(JSON.parse(v), sessionParentPath, depth + 1, out);
|
|
31397
|
+
} catch {
|
|
31398
|
+
}
|
|
31399
|
+
continue;
|
|
31400
|
+
}
|
|
31401
|
+
walkValue(v, sessionParentPath, depth + 1, out);
|
|
31402
|
+
}
|
|
31403
|
+
}
|
|
31404
|
+
|
|
31405
|
+
// src/agents/acp/hooks/extract-acp-file-diffs-from-update/extract.ts
|
|
31406
|
+
function extractAcpFileDiffsFromUpdate(update, sessionParentPath) {
|
|
31407
|
+
if (!update || typeof update !== "object") return [];
|
|
31408
|
+
const u = update;
|
|
31409
|
+
const out = [];
|
|
31410
|
+
const content = u.content;
|
|
31411
|
+
if (Array.isArray(content)) {
|
|
31412
|
+
for (const x of content) walkValue(x, sessionParentPath, 0, out);
|
|
31413
|
+
}
|
|
31414
|
+
const byPath = /* @__PURE__ */ new Map();
|
|
31415
|
+
for (const d of out) byPath.set(d.path, d);
|
|
31416
|
+
return [...byPath.values()];
|
|
31417
|
+
}
|
|
31418
|
+
|
|
31419
|
+
// src/agents/acp/hooks/extract-tool-target-paths.ts
|
|
31420
|
+
function addPath(sessionParentPath, raw, out) {
|
|
31421
|
+
if (typeof raw !== "string") return;
|
|
31422
|
+
const trimmed2 = raw.trim();
|
|
31423
|
+
if (!trimmed2) return;
|
|
31424
|
+
const resolved = resolveWorkspaceFilePath(sessionParentPath, trimmed2);
|
|
31425
|
+
if (!resolved) return;
|
|
31426
|
+
out.add(resolved.display);
|
|
31427
|
+
}
|
|
31428
|
+
function walkLocations(sessionParentPath, loc, out) {
|
|
31429
|
+
if (!Array.isArray(loc)) return;
|
|
31430
|
+
for (const item of loc) {
|
|
31431
|
+
if (item && typeof item === "object") addPath(sessionParentPath, item.path, out);
|
|
31432
|
+
}
|
|
31433
|
+
}
|
|
31434
|
+
var PATH_KEYS = [
|
|
31435
|
+
"path",
|
|
31436
|
+
"file",
|
|
31437
|
+
"filePath",
|
|
31438
|
+
"filepath",
|
|
31439
|
+
"target_path",
|
|
31440
|
+
"targetPath",
|
|
31441
|
+
"file_path",
|
|
31442
|
+
"target_file"
|
|
31443
|
+
];
|
|
31444
|
+
function collectFromObject(sessionParentPath, obj, out, depth) {
|
|
31445
|
+
if (depth > 10) return;
|
|
31446
|
+
for (const k of PATH_KEYS) {
|
|
31447
|
+
if (k in obj) addPath(sessionParentPath, obj[k], out);
|
|
31448
|
+
}
|
|
31449
|
+
for (const v of Object.values(obj)) {
|
|
31450
|
+
if (v != null && typeof v === "object") collectUnknown(sessionParentPath, v, out, depth + 1);
|
|
31451
|
+
}
|
|
31452
|
+
}
|
|
31453
|
+
function collectUnknown(sessionParentPath, v, out, depth) {
|
|
31454
|
+
if (depth > 10 || v == null) return;
|
|
31455
|
+
if (Array.isArray(v)) {
|
|
31456
|
+
for (const x of v) collectUnknown(sessionParentPath, x, out, depth + 1);
|
|
31457
|
+
return;
|
|
31458
|
+
}
|
|
31459
|
+
if (typeof v === "object") collectFromObject(sessionParentPath, v, out, depth);
|
|
31460
|
+
}
|
|
31461
|
+
function walkContentArray(sessionParentPath, content, out) {
|
|
31462
|
+
if (!Array.isArray(content)) return;
|
|
31463
|
+
for (const item of content) {
|
|
31464
|
+
if (!item || typeof item !== "object") continue;
|
|
31465
|
+
const o = item;
|
|
31466
|
+
if (typeof o.type === "string" && o.type.toLowerCase() === "diff") {
|
|
31467
|
+
for (const k of PATH_KEYS) if (k in o) addPath(sessionParentPath, o[k], out);
|
|
31468
|
+
}
|
|
31469
|
+
if (o.type === "content" && o.content != null && typeof o.content === "object") {
|
|
31470
|
+
const inner = o.content;
|
|
31471
|
+
if (typeof inner.type === "string" && inner.type.toLowerCase() === "diff") {
|
|
31472
|
+
for (const k of PATH_KEYS) if (k in inner) addPath(sessionParentPath, inner[k], out);
|
|
31473
|
+
}
|
|
31474
|
+
}
|
|
31475
|
+
}
|
|
31476
|
+
}
|
|
31477
|
+
function extractToolTargetDisplayPaths(update, sessionParentPath) {
|
|
31478
|
+
const out = /* @__PURE__ */ new Set();
|
|
31479
|
+
if (!update || typeof update !== "object") return [];
|
|
31480
|
+
const u = update;
|
|
31481
|
+
walkLocations(sessionParentPath, u.locations, out);
|
|
31482
|
+
walkLocations(sessionParentPath, u.fileLocations, out);
|
|
31483
|
+
walkLocations(sessionParentPath, u.file_locations, out);
|
|
31484
|
+
const tc = u.toolCall ?? u.tool_call;
|
|
31485
|
+
if (tc && typeof tc.arguments === "string") {
|
|
31486
|
+
try {
|
|
31487
|
+
const parsed = JSON.parse(tc.arguments);
|
|
31488
|
+
collectUnknown(sessionParentPath, parsed, out, 0);
|
|
31489
|
+
} catch {
|
|
31490
|
+
}
|
|
31491
|
+
}
|
|
31492
|
+
walkContentArray(sessionParentPath, u.content, out);
|
|
31493
|
+
collectFromObject(sessionParentPath, u, out, 0);
|
|
31494
|
+
return [...out];
|
|
31495
|
+
}
|
|
31496
|
+
|
|
31497
|
+
// src/agents/acp/hooks/bridge-on-session-update/send-structured-file-changes.ts
|
|
31498
|
+
function sendExtractedDiffsAsSessionFileChanges(diffs, send, sessionParentPath, sessionId, runId, sentPaths, log2) {
|
|
31499
|
+
for (const d of diffs) {
|
|
31500
|
+
try {
|
|
31501
|
+
const patchContent = editSnippetToUnifiedDiff(d.path, d.oldText, d.newText);
|
|
31502
|
+
const dirFlags = getSessionFileChangeDirectoryFlags(sessionParentPath, d.path);
|
|
31503
|
+
send({
|
|
31504
|
+
type: "session_file_change",
|
|
31505
|
+
sessionId,
|
|
31506
|
+
runId,
|
|
31507
|
+
path: d.path,
|
|
31508
|
+
oldText: d.oldText,
|
|
31509
|
+
newText: d.newText,
|
|
31510
|
+
patchContent,
|
|
31511
|
+
isDirectory: dirFlags.isDirectory,
|
|
31512
|
+
directoryRemoved: dirFlags.directoryRemoved
|
|
31513
|
+
});
|
|
31514
|
+
sentPaths.add(d.path);
|
|
31515
|
+
} catch (err) {
|
|
31516
|
+
log2(`[Bridge service] Session file change failed for ${d.path}: ${errorMessage(err)}`);
|
|
31517
|
+
}
|
|
31518
|
+
}
|
|
31519
|
+
}
|
|
31520
|
+
function sendGitHeadVsWorkspaceForToolPaths(mergedPaths, sentPaths, send, sessionParentPath, sessionId, runId, log2) {
|
|
31521
|
+
for (const displayPath of mergedPaths) {
|
|
31522
|
+
if (sentPaths.has(displayPath)) continue;
|
|
31523
|
+
const oldText = readGitHeadBlob(sessionParentPath, displayPath);
|
|
31524
|
+
const newText = readUtf8WorkspaceFile(sessionParentPath, displayPath);
|
|
31525
|
+
if (oldText === newText) continue;
|
|
31526
|
+
try {
|
|
31527
|
+
const patchContent = editSnippetToUnifiedDiff(displayPath, oldText, newText);
|
|
31528
|
+
const dirFlags = getSessionFileChangeDirectoryFlags(sessionParentPath, displayPath);
|
|
31529
|
+
send({
|
|
31530
|
+
type: "session_file_change",
|
|
31531
|
+
sessionId,
|
|
31532
|
+
runId,
|
|
31533
|
+
path: displayPath,
|
|
31534
|
+
oldText,
|
|
31535
|
+
newText,
|
|
31536
|
+
patchContent,
|
|
31537
|
+
isDirectory: dirFlags.isDirectory,
|
|
31538
|
+
directoryRemoved: dirFlags.directoryRemoved
|
|
31539
|
+
});
|
|
31540
|
+
sentPaths.add(displayPath);
|
|
31541
|
+
} catch (err) {
|
|
31542
|
+
log2(`[Bridge service] Session file change failed for ${displayPath}: ${errorMessage(err)}`);
|
|
31543
|
+
}
|
|
31544
|
+
}
|
|
31545
|
+
}
|
|
31546
|
+
|
|
31547
|
+
// src/agents/acp/hooks/bridge-on-session-update/handle-bridge-tool-session-update.ts
|
|
31548
|
+
function handleBridgeToolSessionUpdate(params) {
|
|
31549
|
+
const {
|
|
31550
|
+
params: updateParams,
|
|
31551
|
+
updateKind,
|
|
31552
|
+
isToolUpdate,
|
|
31553
|
+
isCompletedToolCallUpdate,
|
|
31554
|
+
toolKey,
|
|
31555
|
+
toolPaths,
|
|
31556
|
+
status,
|
|
31557
|
+
sessionParentPath,
|
|
31558
|
+
pathTracker,
|
|
31559
|
+
sentFileChangePaths,
|
|
31560
|
+
send,
|
|
31561
|
+
runId,
|
|
31562
|
+
sessionId,
|
|
31563
|
+
log: log2
|
|
31564
|
+
} = params;
|
|
31565
|
+
if (updateKind === "tool_call") {
|
|
31566
|
+
pathTracker.resetToolSnapshots(toolKey);
|
|
31567
|
+
}
|
|
31568
|
+
if (isToolUpdate) {
|
|
31569
|
+
accumulateToolPaths(toolKey, toolPaths, pathTracker.accumulatedPathsByToolKey);
|
|
31570
|
+
}
|
|
31571
|
+
if (isToolUpdate) {
|
|
31572
|
+
const deliver = send && runId && sessionId ? (msg) => send(msg) : null;
|
|
31573
|
+
pathTracker.handleToolCallLifecycle(
|
|
31574
|
+
updateKind,
|
|
31575
|
+
toolKey,
|
|
31576
|
+
toolPaths,
|
|
31577
|
+
status,
|
|
31578
|
+
sessionParentPath,
|
|
31579
|
+
sentFileChangePaths,
|
|
31580
|
+
deliver,
|
|
31581
|
+
runId,
|
|
31582
|
+
sessionId,
|
|
31583
|
+
log2
|
|
31584
|
+
);
|
|
31585
|
+
}
|
|
31586
|
+
const diffs = extractAcpFileDiffsFromUpdate(updateParams, sessionParentPath);
|
|
31587
|
+
if (diffs.length > 0 && send && runId && sessionId) {
|
|
31588
|
+
sendExtractedDiffsAsSessionFileChanges(
|
|
31589
|
+
diffs,
|
|
31590
|
+
send,
|
|
31591
|
+
sessionParentPath,
|
|
31592
|
+
sessionId,
|
|
31593
|
+
runId,
|
|
31594
|
+
sentFileChangePaths,
|
|
31595
|
+
log2
|
|
31596
|
+
);
|
|
31597
|
+
} else if (diffs.length > 0) {
|
|
31598
|
+
log2(
|
|
31599
|
+
`[Bridge service] Agent file diff(s) not forwarded (${diffs.length}): session or run not wired to the bridge.`
|
|
31600
|
+
);
|
|
31601
|
+
}
|
|
31602
|
+
if (isCompletedToolCallUpdate && send && runId && sessionId) {
|
|
31603
|
+
const acc = pathTracker.accumulatedPathsByToolKey.get(toolKey);
|
|
31604
|
+
const merged = [.../* @__PURE__ */ new Set([...acc ? [...acc] : [], ...toolPaths])];
|
|
31605
|
+
sendGitHeadVsWorkspaceForToolPaths(
|
|
31606
|
+
merged,
|
|
31607
|
+
sentFileChangePaths,
|
|
31608
|
+
send,
|
|
31609
|
+
sessionParentPath,
|
|
31610
|
+
sessionId,
|
|
31611
|
+
runId,
|
|
31612
|
+
log2
|
|
31613
|
+
);
|
|
31614
|
+
pathTracker.accumulatedPathsByToolKey.delete(toolKey);
|
|
31615
|
+
}
|
|
31616
|
+
}
|
|
31617
|
+
function resolveBridgeToolPaths(params, isToolUpdate, sessionParentPath) {
|
|
31618
|
+
return isToolUpdate ? extractToolTargetDisplayPaths(params, sessionParentPath) : [];
|
|
31619
|
+
}
|
|
31620
|
+
|
|
31621
|
+
// src/agents/planning/extract-session-update-message-text.ts
|
|
31622
|
+
function extractSessionUpdateMessageText(params) {
|
|
31623
|
+
if (params == null || typeof params !== "object" || Array.isArray(params)) return null;
|
|
31624
|
+
const o = params;
|
|
31625
|
+
if (typeof o.text === "string" && o.text.length > 0) return o.text;
|
|
31626
|
+
const content = o.content;
|
|
31627
|
+
if (typeof content === "string" && content.length > 0) return content;
|
|
31628
|
+
if (content != null && typeof content === "object" && !Array.isArray(content)) {
|
|
31629
|
+
const c = content;
|
|
31630
|
+
if (typeof c.text === "string" && c.text.length > 0) return c.text;
|
|
31631
|
+
}
|
|
31632
|
+
const update = o.update;
|
|
31633
|
+
if (typeof update === "string" && update.length > 0) return update;
|
|
31634
|
+
if (update != null && typeof update === "object" && !Array.isArray(update)) {
|
|
31635
|
+
const u = update;
|
|
31636
|
+
const innerContent = u.content;
|
|
31637
|
+
if (typeof innerContent === "string" && innerContent.length > 0) return innerContent;
|
|
31638
|
+
if (innerContent != null && typeof innerContent === "object" && !Array.isArray(innerContent)) {
|
|
31639
|
+
const ic = innerContent;
|
|
31640
|
+
if (typeof ic.text === "string" && ic.text.length > 0) return ic.text;
|
|
31641
|
+
}
|
|
31642
|
+
}
|
|
31643
|
+
return null;
|
|
31644
|
+
}
|
|
31645
|
+
|
|
31646
|
+
// src/agents/planning/planning-session-turn-buffer.ts
|
|
31647
|
+
var buffersByRunId = /* @__PURE__ */ new Map();
|
|
31648
|
+
function registerPlanningSessionTurn(runId) {
|
|
31649
|
+
buffersByRunId.set(runId, { messageBuffer: "" });
|
|
31650
|
+
}
|
|
31651
|
+
function clearPlanningSessionTurn(runId) {
|
|
31652
|
+
buffersByRunId.delete(runId);
|
|
31653
|
+
}
|
|
31654
|
+
function capturePlanningSessionUpdate(params) {
|
|
31655
|
+
const state = buffersByRunId.get(params.runId);
|
|
31656
|
+
if (!state) return false;
|
|
31657
|
+
const sessionUpdate = params.payload != null && typeof params.payload === "object" && !Array.isArray(params.payload) ? params.payload.sessionUpdate ?? params.payload.session_update : void 0;
|
|
31658
|
+
const bucket = resolveAgentTextStreamBucket({
|
|
31659
|
+
transcriptRowKind: params.updateKind,
|
|
31660
|
+
sessionUpdate: typeof sessionUpdate === "string" ? sessionUpdate : void 0
|
|
31661
|
+
});
|
|
31662
|
+
if (bucket !== "message") return false;
|
|
31663
|
+
const text = extractSessionUpdateMessageText(params.payload);
|
|
31664
|
+
if (text) state.messageBuffer += text;
|
|
31665
|
+
return true;
|
|
31666
|
+
}
|
|
31667
|
+
function getPlanningSessionTurnOutput(runId) {
|
|
31668
|
+
return buffersByRunId.get(runId)?.messageBuffer ?? "";
|
|
31669
|
+
}
|
|
31670
|
+
function consumePlanningSessionTurnOutput(runId) {
|
|
31671
|
+
const state = buffersByRunId.get(runId);
|
|
31672
|
+
buffersByRunId.delete(runId);
|
|
31673
|
+
return state?.messageBuffer ?? "";
|
|
31674
|
+
}
|
|
31675
|
+
|
|
31676
|
+
// src/agents/acp/hooks/bridge-on-session-update/forward-bridge-session-update.ts
|
|
31677
|
+
function forwardBridgeSessionUpdate(params) {
|
|
31678
|
+
const { runId, sessionId, updateKind, payload, send, nextTranscriptStreamSeq, log: log2 } = params;
|
|
31679
|
+
if (updateKind === "permission") {
|
|
31680
|
+
return;
|
|
31681
|
+
}
|
|
31682
|
+
if (capturePlanningSessionUpdate({ runId, updateKind, payload })) {
|
|
31683
|
+
return;
|
|
31684
|
+
}
|
|
31685
|
+
try {
|
|
31686
|
+
const transcriptStreamSeq = nextTranscriptStreamSeq?.(runId);
|
|
31687
|
+
send({
|
|
31688
|
+
type: "session_update",
|
|
31689
|
+
...sessionId ? { sessionId } : {},
|
|
31690
|
+
runId,
|
|
31691
|
+
kind: updateKind,
|
|
31692
|
+
payload,
|
|
31693
|
+
...transcriptStreamSeq != null ? { transcriptStreamSeq } : {}
|
|
31694
|
+
});
|
|
31695
|
+
} catch (err) {
|
|
31696
|
+
log2(
|
|
31697
|
+
`[Bridge service] Session update send failed (${formatSessionUpdateKindForLog(updateKind)}): ${errorMessage(err)}`
|
|
31698
|
+
);
|
|
31699
|
+
}
|
|
31700
|
+
}
|
|
31701
|
+
|
|
31449
31702
|
// src/agents/acp/hooks/bridge-on-session-update/create-bridge-on-session-update.ts
|
|
31450
31703
|
function createBridgeOnSessionUpdate(opts) {
|
|
31451
31704
|
const { resolveRouting, getSendSessionUpdate, log: log2, sessionParentPath, nextTranscriptStreamSeq } = opts;
|
|
@@ -31457,8 +31710,7 @@ function createBridgeOnSessionUpdate(opts) {
|
|
|
31457
31710
|
pathTracker.onRunIdChanged(runId);
|
|
31458
31711
|
const send = getSendSessionUpdate();
|
|
31459
31712
|
const sentFileChangePaths = /* @__PURE__ */ new Set();
|
|
31460
|
-
const
|
|
31461
|
-
const updateKind = p.sessionUpdate ?? p.session_update ?? p.type ?? "update";
|
|
31713
|
+
const { updateKind, isToolUpdate, isCompletedToolCallUpdate } = parseBridgeSessionUpdate(params);
|
|
31462
31714
|
if (updateKind === "config_option_update") {
|
|
31463
31715
|
return;
|
|
31464
31716
|
}
|
|
@@ -31466,81 +31718,35 @@ function createBridgeOnSessionUpdate(opts) {
|
|
|
31466
31718
|
sendSessionInfoTitleUpdate({ payload: params, runId, sessionId, send, log: log2 });
|
|
31467
31719
|
return;
|
|
31468
31720
|
}
|
|
31469
|
-
const
|
|
31470
|
-
const toolName = p.toolCall?.name ?? p.tool_call?.name ?? "";
|
|
31471
|
-
const isToolUpdate = updateKind === "tool_call" || updateKind === "tool_call_update" || typeof toolName === "string" && toolName.length > 0;
|
|
31472
|
-
const toolPaths = isToolUpdate ? extractToolTargetDisplayPaths(params, sessionParentPath) : [];
|
|
31721
|
+
const toolPaths = resolveBridgeToolPaths(params, isToolUpdate, sessionParentPath);
|
|
31473
31722
|
const toolKey = isToolUpdate ? pathTracker.resolveToolKey(params, updateKind) : "";
|
|
31474
|
-
|
|
31475
|
-
|
|
31476
|
-
|
|
31477
|
-
|
|
31478
|
-
|
|
31479
|
-
|
|
31480
|
-
|
|
31481
|
-
|
|
31482
|
-
|
|
31483
|
-
|
|
31484
|
-
|
|
31485
|
-
|
|
31486
|
-
|
|
31487
|
-
|
|
31488
|
-
|
|
31489
|
-
|
|
31490
|
-
|
|
31491
|
-
|
|
31492
|
-
|
|
31493
|
-
);
|
|
31494
|
-
}
|
|
31495
|
-
const diffs = extractAcpFileDiffsFromUpdate(params, sessionParentPath);
|
|
31496
|
-
if (diffs.length > 0 && send && runId && sessionId) {
|
|
31497
|
-
sendExtractedDiffsAsSessionFileChanges(
|
|
31498
|
-
diffs,
|
|
31499
|
-
send,
|
|
31500
|
-
sessionParentPath,
|
|
31501
|
-
sessionId,
|
|
31723
|
+
const status = params.status;
|
|
31724
|
+
handleBridgeToolSessionUpdate({
|
|
31725
|
+
params,
|
|
31726
|
+
updateKind,
|
|
31727
|
+
isToolUpdate,
|
|
31728
|
+
isCompletedToolCallUpdate,
|
|
31729
|
+
toolKey,
|
|
31730
|
+
toolPaths,
|
|
31731
|
+
status,
|
|
31732
|
+
sessionParentPath,
|
|
31733
|
+
pathTracker,
|
|
31734
|
+
sentFileChangePaths,
|
|
31735
|
+
send,
|
|
31736
|
+
runId: runId ?? "",
|
|
31737
|
+
sessionId: sessionId ?? "",
|
|
31738
|
+
log: log2
|
|
31739
|
+
});
|
|
31740
|
+
if (runId && send) {
|
|
31741
|
+
forwardBridgeSessionUpdate({
|
|
31502
31742
|
runId,
|
|
31503
|
-
sentFileChangePaths,
|
|
31504
|
-
log2
|
|
31505
|
-
);
|
|
31506
|
-
} else if (diffs.length > 0) {
|
|
31507
|
-
log2(
|
|
31508
|
-
`[Bridge service] Agent file diff(s) not forwarded (${diffs.length}): session or run not wired to the bridge.`
|
|
31509
|
-
);
|
|
31510
|
-
}
|
|
31511
|
-
if (isCompletedToolCallUpdate && send && runId && sessionId) {
|
|
31512
|
-
const acc = pathTracker.accumulatedPathsByToolKey.get(toolKey);
|
|
31513
|
-
const merged = [.../* @__PURE__ */ new Set([...acc ? [...acc] : [], ...toolPaths])];
|
|
31514
|
-
sendGitHeadVsWorkspaceForToolPaths(
|
|
31515
|
-
merged,
|
|
31516
|
-
sentFileChangePaths,
|
|
31517
|
-
send,
|
|
31518
|
-
sessionParentPath,
|
|
31519
31743
|
sessionId,
|
|
31520
|
-
|
|
31521
|
-
|
|
31522
|
-
|
|
31523
|
-
|
|
31524
|
-
|
|
31525
|
-
|
|
31526
|
-
if (updateKind === "permission") {
|
|
31527
|
-
return;
|
|
31528
|
-
}
|
|
31529
|
-
try {
|
|
31530
|
-
const transcriptStreamSeq = nextTranscriptStreamSeq?.(runId);
|
|
31531
|
-
send({
|
|
31532
|
-
type: "session_update",
|
|
31533
|
-
...sessionId ? { sessionId } : {},
|
|
31534
|
-
runId,
|
|
31535
|
-
kind: updateKind,
|
|
31536
|
-
payload: params,
|
|
31537
|
-
...transcriptStreamSeq != null ? { transcriptStreamSeq } : {}
|
|
31538
|
-
});
|
|
31539
|
-
} catch (err) {
|
|
31540
|
-
log2(
|
|
31541
|
-
`[Bridge service] Session update send failed (${formatSessionUpdateKindForLog(updateKind)}): ${errorMessage(err)}`
|
|
31542
|
-
);
|
|
31543
|
-
}
|
|
31744
|
+
updateKind,
|
|
31745
|
+
payload: params,
|
|
31746
|
+
send,
|
|
31747
|
+
nextTranscriptStreamSeq,
|
|
31748
|
+
log: log2
|
|
31749
|
+
});
|
|
31544
31750
|
}
|
|
31545
31751
|
};
|
|
31546
31752
|
}
|
|
@@ -31880,6 +32086,40 @@ async function disconnectAll(ctx) {
|
|
|
31880
32086
|
ctx.pendingCancelRunIds.clear();
|
|
31881
32087
|
}
|
|
31882
32088
|
|
|
32089
|
+
// src/agents/acp/manager/resolve-prompt-run-context.ts
|
|
32090
|
+
function resolvePromptRunContext(ctx, opts) {
|
|
32091
|
+
const { runId, mode, agentType, agentConfig, sessionId } = opts;
|
|
32092
|
+
const preferredForPrompt = agentType ?? ctx.backendFallbackAgentType ?? null;
|
|
32093
|
+
if (!runId) {
|
|
32094
|
+
ctx.log("[Agent] Prompt ignored: missing runId (cannot route session updates).");
|
|
32095
|
+
return null;
|
|
32096
|
+
}
|
|
32097
|
+
const acpAgentKey = computeAcpAgentKey(preferredForPrompt, mode, agentConfig ?? null);
|
|
32098
|
+
if (!acpAgentKey) {
|
|
32099
|
+
return null;
|
|
32100
|
+
}
|
|
32101
|
+
const activeAcpSessionAgentKey = computeAcpSessionAgentKey(sessionId, acpAgentKey);
|
|
32102
|
+
ctx.pendingCancelRunIds.delete(runId);
|
|
32103
|
+
ctx.promptRouting.registerRun({ sessionId, runId });
|
|
32104
|
+
ctx.runDispatch.set(runId, { acpSessionAgentKey: activeAcpSessionAgentKey });
|
|
32105
|
+
return {
|
|
32106
|
+
activeRunId: runId,
|
|
32107
|
+
activeAcpAgentKey: acpAgentKey,
|
|
32108
|
+
activeAcpSessionAgentKey,
|
|
32109
|
+
preferredForPrompt
|
|
32110
|
+
};
|
|
32111
|
+
}
|
|
32112
|
+
|
|
32113
|
+
// src/agents/acp/send-prompt-result-augment.ts
|
|
32114
|
+
function augmentPromptResultAuthFields(agentType, errorText) {
|
|
32115
|
+
const err = errorText ?? "";
|
|
32116
|
+
const at = agentType ?? null;
|
|
32117
|
+
const evaluated = Boolean(at && err.trim());
|
|
32118
|
+
const suggestsAuth = evaluated && at ? localAgentErrorSuggestsAuth(at, err) : false;
|
|
32119
|
+
if (!suggestsAuth || !agentType) return {};
|
|
32120
|
+
return { agentAuthRequired: true, agentType };
|
|
32121
|
+
}
|
|
32122
|
+
|
|
31883
32123
|
// src/git/git-runtime.ts
|
|
31884
32124
|
var activeGitChildProcesses = /* @__PURE__ */ new Set();
|
|
31885
32125
|
function abortActiveGitChildProcesses() {
|
|
@@ -31954,8 +32194,8 @@ async function execGitFile(args, options) {
|
|
|
31954
32194
|
}
|
|
31955
32195
|
|
|
31956
32196
|
// src/git/changes/parse/normalize-git-diff-path.ts
|
|
31957
|
-
function normalizeGitDiffPath(
|
|
31958
|
-
return
|
|
32197
|
+
function normalizeGitDiffPath(path74) {
|
|
32198
|
+
return path74.replace(/\\/g, "/").replace(/\/ +/g, "/").trim();
|
|
31959
32199
|
}
|
|
31960
32200
|
|
|
31961
32201
|
// src/git/changes/parse/parse-name-status-entries.ts
|
|
@@ -32242,9 +32482,9 @@ async function collectTurnGitDiffFromPreTurnSnapshot(options) {
|
|
|
32242
32482
|
// src/agents/acp/put-summarize-change-summaries.ts
|
|
32243
32483
|
async function putEncryptedChangeSummaryRows(params) {
|
|
32244
32484
|
const base = params.apiBaseUrl.replace(/\/+$/, "");
|
|
32245
|
-
const entries = params.rows.map(({ path:
|
|
32485
|
+
const entries = params.rows.map(({ path: path74, summary }) => {
|
|
32246
32486
|
const enc = params.e2ee.encryptFields({ summary }, ["summary"]);
|
|
32247
|
-
return { path:
|
|
32487
|
+
return { path: path74, summary: JSON.stringify(enc) };
|
|
32248
32488
|
});
|
|
32249
32489
|
const res = await fetch(
|
|
32250
32490
|
`${base}/internal/sessions/${encodeURIComponent(params.sessionId)}/follow-ups/summarize-changes`,
|
|
@@ -32335,130 +32575,136 @@ async function maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess(params) {
|
|
|
32335
32575
|
}
|
|
32336
32576
|
}
|
|
32337
32577
|
|
|
32338
|
-
// src/agents/
|
|
32339
|
-
function
|
|
32340
|
-
const
|
|
32341
|
-
|
|
32342
|
-
const
|
|
32343
|
-
const
|
|
32344
|
-
|
|
32345
|
-
|
|
32346
|
-
|
|
32347
|
-
|
|
32348
|
-
|
|
32349
|
-
|
|
32350
|
-
|
|
32351
|
-
|
|
32352
|
-
|
|
32353
|
-
|
|
32354
|
-
|
|
32355
|
-
|
|
32356
|
-
|
|
32357
|
-
|
|
32358
|
-
|
|
32359
|
-
|
|
32360
|
-
|
|
32361
|
-
for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
|
|
32362
|
-
const b64 = btoa(binary);
|
|
32363
|
-
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
32364
|
-
}
|
|
32365
|
-
function base64UrlDecode(value) {
|
|
32366
|
-
const b64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
32367
|
-
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
32368
|
-
const binary = atob(padded);
|
|
32369
|
-
const out = new Uint8Array(binary.length);
|
|
32370
|
-
for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
|
|
32371
|
-
return out;
|
|
32578
|
+
// src/agents/planning/submit-planning-todos-for-turn.ts
|
|
32579
|
+
async function submitPlanningTodosForTurn(params) {
|
|
32580
|
+
const token = params.getCloudAccessToken();
|
|
32581
|
+
if (!token.trim()) return { ok: false, error: "Missing cloud access token" };
|
|
32582
|
+
const base = params.cloudApiBaseUrl.replace(/\/$/, "");
|
|
32583
|
+
const url2 = `${base}/internal/sessions/todos/submit`;
|
|
32584
|
+
const res = await fetch(url2, {
|
|
32585
|
+
method: "POST",
|
|
32586
|
+
headers: {
|
|
32587
|
+
Authorization: `Bearer ${token}`,
|
|
32588
|
+
"Content-Type": "application/json"
|
|
32589
|
+
},
|
|
32590
|
+
body: JSON.stringify({
|
|
32591
|
+
sessionId: params.sessionId,
|
|
32592
|
+
turnId: params.turnId,
|
|
32593
|
+
items: params.items
|
|
32594
|
+
})
|
|
32595
|
+
});
|
|
32596
|
+
if (!res.ok) {
|
|
32597
|
+
const body = await res.json().catch(() => null);
|
|
32598
|
+
return { ok: false, error: body?.error ?? `Planning todo submit failed (${res.status})` };
|
|
32599
|
+
}
|
|
32600
|
+
return { ok: true };
|
|
32372
32601
|
}
|
|
32373
32602
|
|
|
32374
|
-
// src/agents/
|
|
32375
|
-
function
|
|
32376
|
-
|
|
32377
|
-
const
|
|
32378
|
-
|
|
32379
|
-
|
|
32380
|
-
|
|
32381
|
-
|
|
32382
|
-
if (!m.startsWith("image/") || buf.length < 4) return;
|
|
32383
|
-
const b0 = buf[0];
|
|
32384
|
-
const b1 = buf[1];
|
|
32385
|
-
const b2 = buf[2];
|
|
32386
|
-
const b3 = buf[3];
|
|
32387
|
-
let looksOk = false;
|
|
32388
|
-
if (m.includes("png") && b0 === 137 && b1 === 80 && b2 === 78 && b3 === 71) looksOk = true;
|
|
32389
|
-
else if ((m.includes("jpeg") || m.includes("jpg")) && b0 === 255 && b1 === 216 && b2 === 255) looksOk = true;
|
|
32390
|
-
else if (m.includes("gif") && b0 === 71 && b1 === 73 && b2 === 70) looksOk = true;
|
|
32391
|
-
else if (m.includes("webp") && buf.length >= 12 && buf.subarray(0, 4).toString("ascii") === "RIFF" && buf.subarray(8, 12).toString("ascii") === "WEBP")
|
|
32392
|
-
looksOk = true;
|
|
32393
|
-
else if (!/(png|jpe?g|gif|webp)/i.test(m)) looksOk = true;
|
|
32394
|
-
if (!looksOk) {
|
|
32395
|
-
logDebug(
|
|
32396
|
-
`[Agent] Attachment ${idShort} (${mimeType}): decoded bytes do not match common image signatures \u2014 wrong E2EE key, corrupt blob, or metadata mismatch. First 12 bytes (hex): ${buf.subarray(0, Math.min(12, buf.length)).toString("hex")}`
|
|
32397
|
-
);
|
|
32603
|
+
// src/agents/planning/maybe-submit-planning-todos-after-agent-success.ts
|
|
32604
|
+
async function maybeSubmitPlanningTodosAfterAgentSuccess(params) {
|
|
32605
|
+
const { sessionId, runId, resultSuccess, output, cloudApiBaseUrl, getCloudAccessToken, log: log2 } = params;
|
|
32606
|
+
const buffered = runId ? getPlanningSessionTurnOutput(runId) : "";
|
|
32607
|
+
const outputFromResult = typeof output === "string" ? output : "";
|
|
32608
|
+
const outputStr = buffered.trim() !== "" ? buffered : outputFromResult;
|
|
32609
|
+
if (!sessionId || !runId || !resultSuccess || outputStr.trim() === "") {
|
|
32610
|
+
return { submitted: false, suppressOutput: false };
|
|
32398
32611
|
}
|
|
32399
|
-
|
|
32400
|
-
|
|
32401
|
-
const { attachments, sessionId, cloudApiBaseUrl, getCloudAccessToken, e2ee, log: log2 } = params;
|
|
32402
|
-
const token = getCloudAccessToken();
|
|
32403
|
-
if (!token) {
|
|
32404
|
-
return { ok: false, error: "Missing cloud access token; cannot download attachments." };
|
|
32612
|
+
if (!cloudApiBaseUrl || !getCloudAccessToken) {
|
|
32613
|
+
return { submitted: false, suppressOutput: false };
|
|
32405
32614
|
}
|
|
32406
|
-
const
|
|
32407
|
-
if (
|
|
32408
|
-
return {
|
|
32615
|
+
const items = parsePlanningTodoAgentJson(outputStr);
|
|
32616
|
+
if (items.length === 0) {
|
|
32617
|
+
return { submitted: false, suppressOutput: false };
|
|
32409
32618
|
}
|
|
32410
|
-
const
|
|
32411
|
-
|
|
32412
|
-
|
|
32413
|
-
|
|
32414
|
-
|
|
32415
|
-
|
|
32416
|
-
|
|
32417
|
-
|
|
32418
|
-
|
|
32419
|
-
|
|
32420
|
-
|
|
32421
|
-
|
|
32422
|
-
|
|
32423
|
-
|
|
32424
|
-
|
|
32425
|
-
|
|
32426
|
-
|
|
32427
|
-
|
|
32428
|
-
|
|
32429
|
-
|
|
32430
|
-
|
|
32431
|
-
|
|
32432
|
-
|
|
32433
|
-
|
|
32434
|
-
|
|
32435
|
-
|
|
32436
|
-
|
|
32437
|
-
|
|
32438
|
-
|
|
32439
|
-
|
|
32440
|
-
|
|
32441
|
-
|
|
32442
|
-
|
|
32443
|
-
|
|
32444
|
-
|
|
32619
|
+
const result = await submitPlanningTodosForTurn({
|
|
32620
|
+
sessionId,
|
|
32621
|
+
turnId: runId,
|
|
32622
|
+
items,
|
|
32623
|
+
cloudApiBaseUrl,
|
|
32624
|
+
getCloudAccessToken
|
|
32625
|
+
});
|
|
32626
|
+
if (!result.ok) {
|
|
32627
|
+
log2(`[Agent] Planning todo submit failed: ${result.error}`);
|
|
32628
|
+
return { submitted: false, suppressOutput: false };
|
|
32629
|
+
}
|
|
32630
|
+
if (runId) consumePlanningSessionTurnOutput(runId);
|
|
32631
|
+
log2(`[Agent] Planning session: stored ${items.length} todo(s) via internal API`);
|
|
32632
|
+
return { submitted: true, suppressOutput: true };
|
|
32633
|
+
}
|
|
32634
|
+
|
|
32635
|
+
// src/agents/acp/prompts/finalize-and-send-prompt-result.ts
|
|
32636
|
+
async function finalizeAndSendPromptResult(params) {
|
|
32637
|
+
const {
|
|
32638
|
+
result,
|
|
32639
|
+
sessionId,
|
|
32640
|
+
runId,
|
|
32641
|
+
promptId,
|
|
32642
|
+
agentType,
|
|
32643
|
+
agentCwd,
|
|
32644
|
+
isPlanningSession,
|
|
32645
|
+
followUpCatalogPromptId,
|
|
32646
|
+
sessionChangeSummaryFilePaths,
|
|
32647
|
+
cloudApiBaseUrl,
|
|
32648
|
+
getCloudAccessToken,
|
|
32649
|
+
e2ee,
|
|
32650
|
+
sendResult,
|
|
32651
|
+
sendSessionUpdate,
|
|
32652
|
+
log: log2
|
|
32653
|
+
} = params;
|
|
32654
|
+
if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
|
|
32655
|
+
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
32656
|
+
sessionId,
|
|
32657
|
+
runId,
|
|
32658
|
+
agentCwd,
|
|
32659
|
+
sendSessionUpdate,
|
|
32660
|
+
log: log2
|
|
32661
|
+
});
|
|
32662
|
+
}
|
|
32663
|
+
await maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess({
|
|
32664
|
+
sessionId,
|
|
32665
|
+
runId,
|
|
32666
|
+
resultSuccess: result.success === true,
|
|
32667
|
+
output: result.output,
|
|
32668
|
+
e2ee,
|
|
32669
|
+
cloudApiBaseUrl,
|
|
32670
|
+
getCloudAccessToken,
|
|
32671
|
+
followUpCatalogPromptId,
|
|
32672
|
+
sessionChangeSummaryFilePaths,
|
|
32673
|
+
log: log2
|
|
32674
|
+
});
|
|
32675
|
+
const planningTodosSubmit = await maybeSubmitPlanningTodosAfterAgentSuccess({
|
|
32676
|
+
sessionId,
|
|
32677
|
+
runId,
|
|
32678
|
+
resultSuccess: result.success === true,
|
|
32679
|
+
output: result.output,
|
|
32680
|
+
cloudApiBaseUrl,
|
|
32681
|
+
getCloudAccessToken,
|
|
32682
|
+
log: log2
|
|
32683
|
+
});
|
|
32684
|
+
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
32685
|
+
const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
|
|
32686
|
+
const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
|
|
32687
|
+
const planningFallbackOutput = !planningTodosSubmit.suppressOutput && isPlanningSession && runId ? consumePlanningSessionTurnOutput(runId) : "";
|
|
32688
|
+
sendResult({
|
|
32689
|
+
type: "prompt_result",
|
|
32690
|
+
id: promptId,
|
|
32691
|
+
...sessionId ? { sessionId } : {},
|
|
32692
|
+
...runId ? { runId } : {},
|
|
32693
|
+
...result,
|
|
32694
|
+
...planningTodosSubmit.suppressOutput ? { output: void 0 } : planningFallbackOutput.trim() !== "" ? { output: planningFallbackOutput } : {},
|
|
32695
|
+
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
32696
|
+
...augmentPromptResultAuthFields(agentType, errStr),
|
|
32697
|
+
...!result.success && cancelledByAgent ? { stopReason: "cancelled" } : {}
|
|
32698
|
+
});
|
|
32699
|
+
if (!result.success) {
|
|
32700
|
+
if (cancelledByAgent) {
|
|
32701
|
+
log2("[Agent] Run ended after stop request (stopped by user).");
|
|
32445
32702
|
} else {
|
|
32446
|
-
|
|
32703
|
+
log2(
|
|
32704
|
+
`[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
|
|
32705
|
+
);
|
|
32447
32706
|
}
|
|
32448
|
-
warnIfDecodedImageMagicUnexpected(imageBytes, mimeType, id.slice(0, 8));
|
|
32449
|
-
logDebug(
|
|
32450
|
-
`[Agent] Loaded prompt image ${id.slice(0, 8)}\u2026: ${imageBytes.length} bytes, mime=${mimeType}, ${encrypted ? "E2EE decrypted" : "plaintext from storage"}`
|
|
32451
|
-
);
|
|
32452
|
-
const dataBase64 = imageBytes.toString("base64");
|
|
32453
|
-
out.push({ mimeType, dataBase64 });
|
|
32454
|
-
}
|
|
32455
|
-
if (out.length !== wantedCount) {
|
|
32456
|
-
return {
|
|
32457
|
-
ok: false,
|
|
32458
|
-
error: `Expected ${wantedCount} image attachment(s) but only loaded ${out.length} (check attachment ids and empty rows).`
|
|
32459
|
-
};
|
|
32460
32707
|
}
|
|
32461
|
-
return { ok: true, images: out };
|
|
32462
32708
|
}
|
|
32463
32709
|
|
|
32464
32710
|
// src/agents/acp/build-forked-session-agent-prompt.ts
|
|
@@ -32518,6 +32764,32 @@ async function fetchCloudSessionMeta(params) {
|
|
|
32518
32764
|
});
|
|
32519
32765
|
}
|
|
32520
32766
|
|
|
32767
|
+
// ../e2ee/src/constants.ts
|
|
32768
|
+
var E2EE_NONCE_BYTES = 12;
|
|
32769
|
+
|
|
32770
|
+
// ../e2ee/src/types.ts
|
|
32771
|
+
function isE2eeEnvelope(value) {
|
|
32772
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return false;
|
|
32773
|
+
const o = value;
|
|
32774
|
+
return typeof o.k === "string" && typeof o.n === "string" && typeof o.c === "string";
|
|
32775
|
+
}
|
|
32776
|
+
|
|
32777
|
+
// ../e2ee/src/encoding.ts
|
|
32778
|
+
function base64UrlEncode(bytes) {
|
|
32779
|
+
let binary = "";
|
|
32780
|
+
for (let i = 0; i < bytes.length; i += 1) binary += String.fromCharCode(bytes[i]);
|
|
32781
|
+
const b64 = btoa(binary);
|
|
32782
|
+
return b64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
|
|
32783
|
+
}
|
|
32784
|
+
function base64UrlDecode(value) {
|
|
32785
|
+
const b64 = value.replace(/-/g, "+").replace(/_/g, "/");
|
|
32786
|
+
const padded = b64 + "=".repeat((4 - b64.length % 4) % 4);
|
|
32787
|
+
const binary = atob(padded);
|
|
32788
|
+
const out = new Uint8Array(binary.length);
|
|
32789
|
+
for (let i = 0; i < binary.length; i += 1) out[i] = binary.charCodeAt(i);
|
|
32790
|
+
return out;
|
|
32791
|
+
}
|
|
32792
|
+
|
|
32521
32793
|
// src/lib/e2ee/decrypt-stored-e2ee-content.ts
|
|
32522
32794
|
function parseJsonObject(raw) {
|
|
32523
32795
|
try {
|
|
@@ -32715,7 +32987,213 @@ function enrichIntegrationContentPromptForAgent(params) {
|
|
|
32715
32987
|
return injectIntegrationContentAgentPromptNote(params.agentPromptText, params.sessionId);
|
|
32716
32988
|
}
|
|
32717
32989
|
|
|
32718
|
-
// src/agents/
|
|
32990
|
+
// src/agents/planning/enrich-planning-session-prompt-for-agent.ts
|
|
32991
|
+
async function enrichPlanningSessionPromptForAgent(params) {
|
|
32992
|
+
const meta = await fetchCloudSessionMeta({
|
|
32993
|
+
sessionId: params.sessionId,
|
|
32994
|
+
cloudApiBaseUrl: params.cloudApiBaseUrl,
|
|
32995
|
+
getCloudAccessToken: params.getCloudAccessToken
|
|
32996
|
+
});
|
|
32997
|
+
if (!meta.ok) return { promptText: params.promptText, isPlanningSession: false };
|
|
32998
|
+
const sessionKind = parseSessionKind(meta.data.sessionKind);
|
|
32999
|
+
if (sessionKind !== "planning") return { promptText: params.promptText, isPlanningSession: false };
|
|
33000
|
+
const todos = Array.isArray(meta.data.planningTodos) ? meta.data.planningTodos : [];
|
|
33001
|
+
if (params.isNewSession || todos.length === 0) {
|
|
33002
|
+
return {
|
|
33003
|
+
promptText: buildPlanningSessionAgentPrompt(params.promptText),
|
|
33004
|
+
isPlanningSession: true
|
|
33005
|
+
};
|
|
33006
|
+
}
|
|
33007
|
+
return {
|
|
33008
|
+
promptText: buildPlanningSessionFollowUpAgentPrompt(params.promptText, todos),
|
|
33009
|
+
isPlanningSession: true
|
|
33010
|
+
};
|
|
33011
|
+
}
|
|
33012
|
+
|
|
33013
|
+
// src/agents/acp/prompts/prepare-agent-prompt-text.ts
|
|
33014
|
+
async function prepareAgentPromptText(params) {
|
|
33015
|
+
const { promptText, sessionId, runId, isNewSession, cloudApiBaseUrl, getCloudAccessToken } = params;
|
|
33016
|
+
let agentPromptText = promptText;
|
|
33017
|
+
let isPlanningSession = false;
|
|
33018
|
+
if (sessionId && cloudApiBaseUrl && getCloudAccessToken) {
|
|
33019
|
+
agentPromptText = await enrichForkedSessionPromptForAgent({
|
|
33020
|
+
sessionId,
|
|
33021
|
+
promptText,
|
|
33022
|
+
cloudApiBaseUrl,
|
|
33023
|
+
getCloudAccessToken
|
|
33024
|
+
});
|
|
33025
|
+
const planningEnriched = await enrichPlanningSessionPromptForAgent({
|
|
33026
|
+
sessionId,
|
|
33027
|
+
promptText: agentPromptText,
|
|
33028
|
+
isNewSession,
|
|
33029
|
+
cloudApiBaseUrl,
|
|
33030
|
+
getCloudAccessToken
|
|
33031
|
+
});
|
|
33032
|
+
agentPromptText = planningEnriched.promptText;
|
|
33033
|
+
isPlanningSession = planningEnriched.isPlanningSession;
|
|
33034
|
+
}
|
|
33035
|
+
if (isPlanningSession && runId) {
|
|
33036
|
+
registerPlanningSessionTurn(runId);
|
|
33037
|
+
}
|
|
33038
|
+
if (sessionId) {
|
|
33039
|
+
agentPromptText = enrichIntegrationContentPromptForAgent({
|
|
33040
|
+
sessionId,
|
|
33041
|
+
originalPromptText: promptText,
|
|
33042
|
+
agentPromptText
|
|
33043
|
+
});
|
|
33044
|
+
}
|
|
33045
|
+
return { agentPromptText, isPlanningSession };
|
|
33046
|
+
}
|
|
33047
|
+
|
|
33048
|
+
// src/agents/acp/fetch-session-attachments.ts
|
|
33049
|
+
function metaSaysEncrypted(meta) {
|
|
33050
|
+
if (!meta) return false;
|
|
33051
|
+
const e = meta.encrypted;
|
|
33052
|
+
return e === true || e === "true" || e === 1;
|
|
33053
|
+
}
|
|
33054
|
+
function warnIfDecodedImageMagicUnexpected(buf, mimeType, idShort) {
|
|
33055
|
+
const m = mimeType.toLowerCase();
|
|
33056
|
+
if (!m.startsWith("image/") || buf.length < 4) return;
|
|
33057
|
+
const b0 = buf[0];
|
|
33058
|
+
const b1 = buf[1];
|
|
33059
|
+
const b2 = buf[2];
|
|
33060
|
+
const b3 = buf[3];
|
|
33061
|
+
let looksOk = false;
|
|
33062
|
+
if (m.includes("png") && b0 === 137 && b1 === 80 && b2 === 78 && b3 === 71) looksOk = true;
|
|
33063
|
+
else if ((m.includes("jpeg") || m.includes("jpg")) && b0 === 255 && b1 === 216 && b2 === 255) looksOk = true;
|
|
33064
|
+
else if (m.includes("gif") && b0 === 71 && b1 === 73 && b2 === 70) looksOk = true;
|
|
33065
|
+
else if (m.includes("webp") && buf.length >= 12 && buf.subarray(0, 4).toString("ascii") === "RIFF" && buf.subarray(8, 12).toString("ascii") === "WEBP")
|
|
33066
|
+
looksOk = true;
|
|
33067
|
+
else if (!/(png|jpe?g|gif|webp)/i.test(m)) looksOk = true;
|
|
33068
|
+
if (!looksOk) {
|
|
33069
|
+
logDebug(
|
|
33070
|
+
`[Agent] Attachment ${idShort} (${mimeType}): decoded bytes do not match common image signatures \u2014 wrong E2EE key, corrupt blob, or metadata mismatch. First 12 bytes (hex): ${buf.subarray(0, Math.min(12, buf.length)).toString("hex")}`
|
|
33071
|
+
);
|
|
33072
|
+
}
|
|
33073
|
+
}
|
|
33074
|
+
async function fetchSessionAttachmentPayloadsForAgent(params) {
|
|
33075
|
+
const { attachments, sessionId, cloudApiBaseUrl, getCloudAccessToken, e2ee, log: log2 } = params;
|
|
33076
|
+
const token = getCloudAccessToken();
|
|
33077
|
+
if (!token) {
|
|
33078
|
+
return { ok: false, error: "Missing cloud access token; cannot download attachments." };
|
|
33079
|
+
}
|
|
33080
|
+
const wantedCount = attachments.filter((a) => typeof a.attachmentId === "string" && a.attachmentId.trim() !== "").length;
|
|
33081
|
+
if (wantedCount === 0) {
|
|
33082
|
+
return { ok: false, error: "No valid attachment ids in prompt." };
|
|
33083
|
+
}
|
|
33084
|
+
const base = cloudApiBaseUrl.replace(/\/+$/, "");
|
|
33085
|
+
const out = [];
|
|
33086
|
+
for (const a of attachments) {
|
|
33087
|
+
const id = typeof a.attachmentId === "string" ? a.attachmentId.trim() : "";
|
|
33088
|
+
if (!id) continue;
|
|
33089
|
+
const metaUrl = `${base}/internal/sessions/${encodeURIComponent(sessionId)}/attachments/${encodeURIComponent(id)}/meta`;
|
|
33090
|
+
const blobUrl = `${base}/internal/sessions/${encodeURIComponent(sessionId)}/attachments/${encodeURIComponent(id)}/blob`;
|
|
33091
|
+
const metaRes = await fetch(metaUrl, { headers: { Authorization: `Bearer ${token}` } });
|
|
33092
|
+
if (!metaRes.ok) {
|
|
33093
|
+
const t = await metaRes.text().catch(() => "");
|
|
33094
|
+
log2(`[Agent] Attachment meta fetch failed ${metaRes.status}: ${t.slice(0, 200)}`);
|
|
33095
|
+
return { ok: false, error: `Could not load attachment (${id.slice(0, 8)}\u2026): ${metaRes.status}` };
|
|
33096
|
+
}
|
|
33097
|
+
const meta = await metaRes.json().catch(() => null);
|
|
33098
|
+
const mimeType = typeof meta?.mimeType === "string" && meta.mimeType.trim() ? meta.mimeType.trim() : a.mimeType;
|
|
33099
|
+
const blobRes = await fetch(blobUrl, { headers: { Authorization: `Bearer ${token}` } });
|
|
33100
|
+
if (!blobRes.ok) {
|
|
33101
|
+
const t = await blobRes.text().catch(() => "");
|
|
33102
|
+
log2(`[Agent] Attachment blob fetch failed ${blobRes.status}: ${t.slice(0, 200)}`);
|
|
33103
|
+
return { ok: false, error: `Could not load attachment data (${id.slice(0, 8)}\u2026): ${blobRes.status}` };
|
|
33104
|
+
}
|
|
33105
|
+
const buf = Buffer.from(await blobRes.arrayBuffer());
|
|
33106
|
+
let imageBytes;
|
|
33107
|
+
const encrypted = metaSaysEncrypted(meta);
|
|
33108
|
+
if (encrypted) {
|
|
33109
|
+
if (!e2ee) {
|
|
33110
|
+
return { ok: false, error: "Encrypted attachments require E2EE keys on this bridge." };
|
|
33111
|
+
}
|
|
33112
|
+
const k = typeof meta?.k === "string" ? meta.k : "";
|
|
33113
|
+
const n = typeof meta?.n === "string" ? meta.n : "";
|
|
33114
|
+
if (!k || !n) {
|
|
33115
|
+
return { ok: false, error: "Invalid encrypted attachment metadata (missing key id or nonce)." };
|
|
33116
|
+
}
|
|
33117
|
+
const c = base64UrlEncode(buf);
|
|
33118
|
+
imageBytes = e2ee.decryptEnvelopeToBuffer({ k, n, c });
|
|
33119
|
+
} else {
|
|
33120
|
+
imageBytes = buf;
|
|
33121
|
+
}
|
|
33122
|
+
warnIfDecodedImageMagicUnexpected(imageBytes, mimeType, id.slice(0, 8));
|
|
33123
|
+
logDebug(
|
|
33124
|
+
`[Agent] Loaded prompt image ${id.slice(0, 8)}\u2026: ${imageBytes.length} bytes, mime=${mimeType}, ${encrypted ? "E2EE decrypted" : "plaintext from storage"}`
|
|
33125
|
+
);
|
|
33126
|
+
const dataBase64 = imageBytes.toString("base64");
|
|
33127
|
+
out.push({ mimeType, dataBase64 });
|
|
33128
|
+
}
|
|
33129
|
+
if (out.length !== wantedCount) {
|
|
33130
|
+
return {
|
|
33131
|
+
ok: false,
|
|
33132
|
+
error: `Expected ${wantedCount} image attachment(s) but only loaded ${out.length} (check attachment ids and empty rows).`
|
|
33133
|
+
};
|
|
33134
|
+
}
|
|
33135
|
+
return { ok: true, images: out };
|
|
33136
|
+
}
|
|
33137
|
+
|
|
33138
|
+
// src/agents/acp/prompts/resolve-send-prompt-images.ts
|
|
33139
|
+
async function resolveSendPromptImages(params) {
|
|
33140
|
+
const {
|
|
33141
|
+
attachments,
|
|
33142
|
+
sessionId,
|
|
33143
|
+
promptId,
|
|
33144
|
+
runId,
|
|
33145
|
+
agentType,
|
|
33146
|
+
followUpCatalogPromptId,
|
|
33147
|
+
cloudApiBaseUrl,
|
|
33148
|
+
getCloudAccessToken,
|
|
33149
|
+
e2ee,
|
|
33150
|
+
log: log2
|
|
33151
|
+
} = params;
|
|
33152
|
+
if (!attachments || attachments.length === 0) {
|
|
33153
|
+
return { ok: true, sendOpts: {} };
|
|
33154
|
+
}
|
|
33155
|
+
if (!sessionId || !cloudApiBaseUrl || !getCloudAccessToken) {
|
|
33156
|
+
return {
|
|
33157
|
+
ok: false,
|
|
33158
|
+
errorResult: {
|
|
33159
|
+
type: "prompt_result",
|
|
33160
|
+
id: promptId,
|
|
33161
|
+
...sessionId ? { sessionId } : {},
|
|
33162
|
+
...runId ? { runId } : {},
|
|
33163
|
+
success: false,
|
|
33164
|
+
error: "Prompt includes images but the bridge is not configured with a cloud API URL and token to fetch them.",
|
|
33165
|
+
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
33166
|
+
...augmentPromptResultAuthFields(agentType, "missing cloud for images download")
|
|
33167
|
+
}
|
|
33168
|
+
};
|
|
33169
|
+
}
|
|
33170
|
+
const resolved = await fetchSessionAttachmentPayloadsForAgent({
|
|
33171
|
+
attachments,
|
|
33172
|
+
sessionId,
|
|
33173
|
+
cloudApiBaseUrl,
|
|
33174
|
+
getCloudAccessToken,
|
|
33175
|
+
e2ee,
|
|
33176
|
+
log: log2
|
|
33177
|
+
});
|
|
33178
|
+
if (!resolved.ok) {
|
|
33179
|
+
return {
|
|
33180
|
+
ok: false,
|
|
33181
|
+
errorResult: {
|
|
33182
|
+
type: "prompt_result",
|
|
33183
|
+
id: promptId,
|
|
33184
|
+
...sessionId ? { sessionId } : {},
|
|
33185
|
+
...runId ? { runId } : {},
|
|
33186
|
+
success: false,
|
|
33187
|
+
error: resolved.error,
|
|
33188
|
+
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
33189
|
+
...augmentPromptResultAuthFields(agentType, resolved.error)
|
|
33190
|
+
}
|
|
33191
|
+
};
|
|
33192
|
+
}
|
|
33193
|
+
return { ok: true, sendOpts: { images: resolved.images } };
|
|
33194
|
+
}
|
|
33195
|
+
|
|
33196
|
+
// src/agents/acp/prompts/send-prompt-to-agent.ts
|
|
32719
33197
|
async function sendPromptToAgent(options) {
|
|
32720
33198
|
const {
|
|
32721
33199
|
handle,
|
|
@@ -32733,107 +33211,54 @@ async function sendPromptToAgent(options) {
|
|
|
32733
33211
|
cloudApiBaseUrl,
|
|
32734
33212
|
getCloudAccessToken,
|
|
32735
33213
|
e2ee,
|
|
32736
|
-
attachments
|
|
33214
|
+
attachments,
|
|
33215
|
+
isNewSession = false
|
|
32737
33216
|
} = options;
|
|
33217
|
+
let isPlanningSession = false;
|
|
32738
33218
|
try {
|
|
32739
|
-
|
|
32740
|
-
|
|
32741
|
-
agentPromptText = await enrichForkedSessionPromptForAgent({
|
|
32742
|
-
sessionId,
|
|
32743
|
-
promptText,
|
|
32744
|
-
cloudApiBaseUrl,
|
|
32745
|
-
getCloudAccessToken
|
|
32746
|
-
});
|
|
32747
|
-
}
|
|
32748
|
-
if (sessionId) {
|
|
32749
|
-
agentPromptText = enrichIntegrationContentPromptForAgent({
|
|
32750
|
-
sessionId,
|
|
32751
|
-
originalPromptText: promptText,
|
|
32752
|
-
agentPromptText
|
|
32753
|
-
});
|
|
32754
|
-
}
|
|
32755
|
-
let sendOpts = {};
|
|
32756
|
-
if (attachments && attachments.length > 0) {
|
|
32757
|
-
if (!sessionId || !cloudApiBaseUrl || !getCloudAccessToken) {
|
|
32758
|
-
sendResult({
|
|
32759
|
-
type: "prompt_result",
|
|
32760
|
-
id: promptId,
|
|
32761
|
-
...sessionId ? { sessionId } : {},
|
|
32762
|
-
...runId ? { runId } : {},
|
|
32763
|
-
success: false,
|
|
32764
|
-
error: "Prompt includes images but the bridge is not configured with a cloud API URL and token to fetch them.",
|
|
32765
|
-
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
32766
|
-
...augmentPromptResultAuthFields(agentType, "missing cloud for images download")
|
|
32767
|
-
});
|
|
32768
|
-
return;
|
|
32769
|
-
}
|
|
32770
|
-
const resolved = await fetchSessionAttachmentPayloadsForAgent({
|
|
32771
|
-
attachments,
|
|
32772
|
-
sessionId,
|
|
32773
|
-
cloudApiBaseUrl,
|
|
32774
|
-
getCloudAccessToken,
|
|
32775
|
-
e2ee,
|
|
32776
|
-
log: log2
|
|
32777
|
-
});
|
|
32778
|
-
if (!resolved.ok) {
|
|
32779
|
-
sendResult({
|
|
32780
|
-
type: "prompt_result",
|
|
32781
|
-
id: promptId,
|
|
32782
|
-
...sessionId ? { sessionId } : {},
|
|
32783
|
-
...runId ? { runId } : {},
|
|
32784
|
-
success: false,
|
|
32785
|
-
error: resolved.error,
|
|
32786
|
-
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
32787
|
-
...augmentPromptResultAuthFields(agentType, resolved.error)
|
|
32788
|
-
});
|
|
32789
|
-
return;
|
|
32790
|
-
}
|
|
32791
|
-
sendOpts = { images: resolved.images };
|
|
32792
|
-
}
|
|
32793
|
-
const result = await handle.sendPrompt(agentPromptText, sendOpts);
|
|
32794
|
-
if (sessionId && runId && sendSessionUpdate && agentCwd && result.success) {
|
|
32795
|
-
await collectTurnGitDiffFromPreTurnSnapshot({
|
|
32796
|
-
sessionId,
|
|
32797
|
-
runId,
|
|
32798
|
-
agentCwd,
|
|
32799
|
-
sendSessionUpdate,
|
|
32800
|
-
log: log2
|
|
32801
|
-
});
|
|
32802
|
-
}
|
|
32803
|
-
await maybeUploadE2eeSessionChangeSummariesAfterAgentSuccess({
|
|
33219
|
+
const prepared = await prepareAgentPromptText({
|
|
33220
|
+
promptText,
|
|
32804
33221
|
sessionId,
|
|
32805
33222
|
runId,
|
|
32806
|
-
|
|
32807
|
-
|
|
32808
|
-
|
|
33223
|
+
isNewSession,
|
|
33224
|
+
cloudApiBaseUrl,
|
|
33225
|
+
getCloudAccessToken
|
|
33226
|
+
});
|
|
33227
|
+
isPlanningSession = prepared.isPlanningSession;
|
|
33228
|
+
const imagesResolved = await resolveSendPromptImages({
|
|
33229
|
+
attachments,
|
|
33230
|
+
sessionId,
|
|
33231
|
+
promptId,
|
|
33232
|
+
runId,
|
|
33233
|
+
agentType,
|
|
33234
|
+
followUpCatalogPromptId,
|
|
32809
33235
|
cloudApiBaseUrl,
|
|
32810
33236
|
getCloudAccessToken,
|
|
33237
|
+
e2ee,
|
|
33238
|
+
log: log2
|
|
33239
|
+
});
|
|
33240
|
+
if (!imagesResolved.ok) {
|
|
33241
|
+
sendResult(imagesResolved.errorResult);
|
|
33242
|
+
return;
|
|
33243
|
+
}
|
|
33244
|
+
const result = await handle.sendPrompt(prepared.agentPromptText, imagesResolved.sendOpts);
|
|
33245
|
+
await finalizeAndSendPromptResult({
|
|
33246
|
+
result,
|
|
33247
|
+
sessionId,
|
|
33248
|
+
runId,
|
|
33249
|
+
promptId,
|
|
33250
|
+
agentType,
|
|
33251
|
+
agentCwd,
|
|
33252
|
+
isPlanningSession,
|
|
32811
33253
|
followUpCatalogPromptId,
|
|
32812
33254
|
sessionChangeSummaryFilePaths,
|
|
33255
|
+
cloudApiBaseUrl,
|
|
33256
|
+
getCloudAccessToken,
|
|
33257
|
+
e2ee,
|
|
33258
|
+
sendResult,
|
|
33259
|
+
sendSessionUpdate,
|
|
32813
33260
|
log: log2
|
|
32814
33261
|
});
|
|
32815
|
-
const errStr = typeof result.error === "string" ? result.error : void 0;
|
|
32816
|
-
const resultStop = typeof result.stopReason === "string" ? result.stopReason.trim() : "";
|
|
32817
|
-
const cancelledByAgent = resultStop.toLowerCase() === "cancelled" || errStr != null && isUserEndedSessionTurnErrorText(errStr);
|
|
32818
|
-
sendResult({
|
|
32819
|
-
type: "prompt_result",
|
|
32820
|
-
id: promptId,
|
|
32821
|
-
...sessionId ? { sessionId } : {},
|
|
32822
|
-
...runId ? { runId } : {},
|
|
32823
|
-
...result,
|
|
32824
|
-
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
32825
|
-
...augmentPromptResultAuthFields(agentType, errStr),
|
|
32826
|
-
...!result.success && cancelledByAgent ? { stopReason: "cancelled" } : {}
|
|
32827
|
-
});
|
|
32828
|
-
if (!result.success) {
|
|
32829
|
-
if (cancelledByAgent) {
|
|
32830
|
-
log2("[Agent] Run ended after stop request (stopped by user).");
|
|
32831
|
-
} else {
|
|
32832
|
-
log2(
|
|
32833
|
-
`[Agent] Prompt did not run successfully on the agent (no successful start/completion): ${result.error ?? "Unknown error"}`
|
|
32834
|
-
);
|
|
32835
|
-
}
|
|
32836
|
-
}
|
|
32837
33262
|
} catch (err) {
|
|
32838
33263
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
32839
33264
|
log2(`[Agent] Send failed: ${errMsg}`);
|
|
@@ -32847,6 +33272,8 @@ async function sendPromptToAgent(options) {
|
|
|
32847
33272
|
...followUpCatalogPromptId != null && followUpCatalogPromptId !== "" ? { followUpCatalogPromptId } : {},
|
|
32848
33273
|
...augmentPromptResultAuthFields(agentType, errMsg)
|
|
32849
33274
|
});
|
|
33275
|
+
} finally {
|
|
33276
|
+
if (runId && isPlanningSession) clearPlanningSessionTurn(runId);
|
|
32850
33277
|
}
|
|
32851
33278
|
}
|
|
32852
33279
|
|
|
@@ -32860,15 +33287,36 @@ function getAcpSessionAgentState(ctx, acpSessionAgentKey) {
|
|
|
32860
33287
|
return state;
|
|
32861
33288
|
}
|
|
32862
33289
|
|
|
32863
|
-
// src/agents/acp/manager/handle-prompt.ts
|
|
32864
|
-
function
|
|
33290
|
+
// src/agents/acp/manager/handle-pending-prompt-cancel.ts
|
|
33291
|
+
async function handlePendingPromptCancel(params) {
|
|
33292
|
+
const { ctx, activeRunId, promptId, sessionId, handle, sendResult } = params;
|
|
33293
|
+
if (!ctx.pendingCancelRunIds.has(activeRunId)) {
|
|
33294
|
+
return false;
|
|
33295
|
+
}
|
|
33296
|
+
ctx.pendingCancelRunIds.delete(activeRunId);
|
|
33297
|
+
try {
|
|
33298
|
+
await handle.cancel?.();
|
|
33299
|
+
} catch {
|
|
33300
|
+
}
|
|
33301
|
+
sendResult({
|
|
33302
|
+
type: "prompt_result",
|
|
33303
|
+
id: promptId,
|
|
33304
|
+
...sessionId ? { sessionId } : {},
|
|
33305
|
+
runId: activeRunId,
|
|
33306
|
+
success: false,
|
|
33307
|
+
error: "Stopped by user",
|
|
33308
|
+
stopReason: "cancelled"
|
|
33309
|
+
});
|
|
33310
|
+
return true;
|
|
33311
|
+
}
|
|
33312
|
+
|
|
33313
|
+
// src/agents/acp/manager/run-acp-prompt.ts
|
|
33314
|
+
async function runAcpPrompt(ctx, runCtx, opts) {
|
|
32865
33315
|
const {
|
|
32866
33316
|
promptText,
|
|
32867
33317
|
promptId,
|
|
32868
33318
|
sessionId,
|
|
32869
|
-
runId,
|
|
32870
33319
|
mode,
|
|
32871
|
-
agentType,
|
|
32872
33320
|
agentConfig,
|
|
32873
33321
|
sessionParentPath,
|
|
32874
33322
|
sendResult,
|
|
@@ -32878,109 +33326,99 @@ function handlePrompt(ctx, opts) {
|
|
|
32878
33326
|
cloudApiBaseUrl,
|
|
32879
33327
|
getCloudAccessToken,
|
|
32880
33328
|
e2ee,
|
|
32881
|
-
attachments
|
|
33329
|
+
attachments,
|
|
33330
|
+
isNewSession
|
|
32882
33331
|
} = opts;
|
|
32883
|
-
const
|
|
32884
|
-
|
|
32885
|
-
|
|
32886
|
-
|
|
32887
|
-
|
|
32888
|
-
|
|
32889
|
-
|
|
32890
|
-
|
|
33332
|
+
const { activeRunId, activeAcpAgentKey, activeAcpSessionAgentKey, preferredForPrompt } = runCtx;
|
|
33333
|
+
const acpAgentState = getAcpSessionAgentState(ctx, activeAcpSessionAgentKey);
|
|
33334
|
+
const handle = await ensureAcpClient({
|
|
33335
|
+
state: acpAgentState,
|
|
33336
|
+
acpAgentKey: activeAcpAgentKey,
|
|
33337
|
+
preferredAgentType: preferredForPrompt,
|
|
33338
|
+
mode,
|
|
33339
|
+
agentConfig: agentConfig ?? null,
|
|
33340
|
+
sessionParentPath,
|
|
33341
|
+
resolveRouting: () => ctx.promptRouting.resolveRouting(activeAcpSessionAgentKey),
|
|
33342
|
+
cloudSessionId: sessionId,
|
|
33343
|
+
bridgeAccessPort: ctx.getBridgeAccessPort(),
|
|
33344
|
+
sendSessionUpdate,
|
|
33345
|
+
sendRequest: sendSessionUpdate,
|
|
33346
|
+
log: ctx.log,
|
|
33347
|
+
reportAgentCapabilities: ctx.reportAgentCapabilities
|
|
33348
|
+
});
|
|
33349
|
+
if (!handle) {
|
|
33350
|
+
const errMsg = acpAgentState.lastAcpStartError || "No agent configured. Register local agents on this bridge in the app.";
|
|
33351
|
+
const evaluated = Boolean(preferredForPrompt && errMsg.trim());
|
|
33352
|
+
const suggestsAuth = evaluated ? localAgentErrorSuggestsAuth(preferredForPrompt, errMsg) : false;
|
|
33353
|
+
const auth = suggestsAuth && preferredForPrompt ? { agentAuthRequired: true, agentType: preferredForPrompt } : {};
|
|
32891
33354
|
sendResult({
|
|
32892
33355
|
type: "prompt_result",
|
|
32893
33356
|
id: promptId,
|
|
32894
33357
|
...sessionId ? { sessionId } : {},
|
|
32895
33358
|
runId: activeRunId,
|
|
32896
33359
|
success: false,
|
|
32897
|
-
error:
|
|
33360
|
+
error: errMsg,
|
|
33361
|
+
...auth
|
|
32898
33362
|
});
|
|
32899
33363
|
return;
|
|
32900
33364
|
}
|
|
32901
|
-
|
|
32902
|
-
|
|
32903
|
-
|
|
32904
|
-
|
|
32905
|
-
|
|
32906
|
-
|
|
32907
|
-
|
|
32908
|
-
|
|
32909
|
-
|
|
32910
|
-
|
|
32911
|
-
|
|
32912
|
-
|
|
32913
|
-
|
|
32914
|
-
|
|
32915
|
-
|
|
32916
|
-
|
|
32917
|
-
|
|
33365
|
+
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
33366
|
+
return;
|
|
33367
|
+
}
|
|
33368
|
+
const cancelled = await handlePendingPromptCancel({
|
|
33369
|
+
ctx,
|
|
33370
|
+
activeRunId,
|
|
33371
|
+
promptId,
|
|
33372
|
+
sessionId,
|
|
33373
|
+
handle,
|
|
33374
|
+
sendResult
|
|
33375
|
+
});
|
|
33376
|
+
if (cancelled) return;
|
|
33377
|
+
ctx.promptRouting.setStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
33378
|
+
try {
|
|
33379
|
+
await sendPromptToAgent({
|
|
33380
|
+
handle,
|
|
33381
|
+
promptText,
|
|
33382
|
+
promptId,
|
|
33383
|
+
sessionId,
|
|
33384
|
+
runId: activeRunId,
|
|
33385
|
+
agentType: preferredForPrompt,
|
|
33386
|
+
agentCwd: resolveSessionParentPathForAgentProcess(sessionParentPath),
|
|
33387
|
+
sendResult,
|
|
32918
33388
|
sendSessionUpdate,
|
|
32919
|
-
sendRequest: sendSessionUpdate,
|
|
32920
33389
|
log: ctx.log,
|
|
32921
|
-
|
|
33390
|
+
followUpCatalogPromptId,
|
|
33391
|
+
sessionChangeSummaryFilePaths,
|
|
33392
|
+
cloudApiBaseUrl,
|
|
33393
|
+
getCloudAccessToken,
|
|
33394
|
+
e2ee,
|
|
33395
|
+
attachments,
|
|
33396
|
+
isNewSession
|
|
32922
33397
|
});
|
|
32923
|
-
|
|
32924
|
-
|
|
32925
|
-
|
|
32926
|
-
|
|
32927
|
-
|
|
32928
|
-
|
|
32929
|
-
|
|
32930
|
-
|
|
32931
|
-
|
|
32932
|
-
|
|
32933
|
-
|
|
32934
|
-
error: errMsg,
|
|
32935
|
-
...auth
|
|
32936
|
-
});
|
|
32937
|
-
return;
|
|
32938
|
-
}
|
|
32939
|
-
if (!ctx.promptRouting.isRegisteredRun(activeRunId)) {
|
|
32940
|
-
return;
|
|
32941
|
-
}
|
|
32942
|
-
if (ctx.pendingCancelRunIds.has(activeRunId)) {
|
|
32943
|
-
ctx.pendingCancelRunIds.delete(activeRunId);
|
|
32944
|
-
try {
|
|
32945
|
-
await handle.cancel?.();
|
|
32946
|
-
} catch {
|
|
32947
|
-
}
|
|
33398
|
+
} finally {
|
|
33399
|
+
ctx.promptRouting.clearStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
33400
|
+
}
|
|
33401
|
+
}
|
|
33402
|
+
|
|
33403
|
+
// src/agents/acp/manager/handle-prompt.ts
|
|
33404
|
+
function handlePrompt(ctx, opts) {
|
|
33405
|
+
const { promptId, sessionId, runId, mode, agentType, agentConfig, sendResult } = opts;
|
|
33406
|
+
const runCtx = resolvePromptRunContext(ctx, { runId, mode, agentType, agentConfig, sessionId });
|
|
33407
|
+
if (!runCtx) {
|
|
33408
|
+
if (runId) {
|
|
32948
33409
|
sendResult({
|
|
32949
33410
|
type: "prompt_result",
|
|
32950
33411
|
id: promptId,
|
|
32951
33412
|
...sessionId ? { sessionId } : {},
|
|
32952
|
-
runId
|
|
33413
|
+
runId,
|
|
32953
33414
|
success: false,
|
|
32954
|
-
error: "
|
|
32955
|
-
stopReason: "cancelled"
|
|
33415
|
+
error: "No agent type: ensure the app sends agentType on prompts or agent_config for this bridge."
|
|
32956
33416
|
});
|
|
32957
|
-
return;
|
|
32958
|
-
}
|
|
32959
|
-
ctx.promptRouting.setStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
32960
|
-
try {
|
|
32961
|
-
await sendPromptToAgent({
|
|
32962
|
-
handle,
|
|
32963
|
-
promptText,
|
|
32964
|
-
promptId,
|
|
32965
|
-
sessionId,
|
|
32966
|
-
runId: activeRunId,
|
|
32967
|
-
agentType: preferredForPrompt,
|
|
32968
|
-
agentCwd: resolveSessionParentPathForAgentProcess(sessionParentPath),
|
|
32969
|
-
sendResult,
|
|
32970
|
-
sendSessionUpdate,
|
|
32971
|
-
log: ctx.log,
|
|
32972
|
-
followUpCatalogPromptId,
|
|
32973
|
-
sessionChangeSummaryFilePaths,
|
|
32974
|
-
cloudApiBaseUrl,
|
|
32975
|
-
getCloudAccessToken,
|
|
32976
|
-
e2ee,
|
|
32977
|
-
attachments
|
|
32978
|
-
});
|
|
32979
|
-
} finally {
|
|
32980
|
-
ctx.promptRouting.clearStreamingRunId(activeAcpSessionAgentKey, activeRunId);
|
|
32981
33417
|
}
|
|
33418
|
+
return;
|
|
32982
33419
|
}
|
|
32983
|
-
|
|
33420
|
+
const { activeRunId } = runCtx;
|
|
33421
|
+
void runAcpPrompt(ctx, runCtx, opts).finally(() => {
|
|
32984
33422
|
ctx.promptRouting.unregisterRun(activeRunId);
|
|
32985
33423
|
ctx.runDispatch.delete(activeRunId);
|
|
32986
33424
|
ctx.pendingCancelRunIds.delete(activeRunId);
|
|
@@ -33171,8 +33609,8 @@ function pathspec(...paths) {
|
|
|
33171
33609
|
cache.set(key, paths);
|
|
33172
33610
|
return key;
|
|
33173
33611
|
}
|
|
33174
|
-
function isPathSpec(
|
|
33175
|
-
return
|
|
33612
|
+
function isPathSpec(path74) {
|
|
33613
|
+
return path74 instanceof String && cache.has(path74);
|
|
33176
33614
|
}
|
|
33177
33615
|
function toPaths(pathSpec) {
|
|
33178
33616
|
return cache.get(pathSpec) || [];
|
|
@@ -33261,8 +33699,8 @@ function toLinesWithContent(input = "", trimmed2 = true, separator = "\n") {
|
|
|
33261
33699
|
function forEachLineWithContent(input, callback) {
|
|
33262
33700
|
return toLinesWithContent(input, true).map((line) => callback(line));
|
|
33263
33701
|
}
|
|
33264
|
-
function folderExists(
|
|
33265
|
-
return (0, import_file_exists.exists)(
|
|
33702
|
+
function folderExists(path74) {
|
|
33703
|
+
return (0, import_file_exists.exists)(path74, import_file_exists.FOLDER);
|
|
33266
33704
|
}
|
|
33267
33705
|
function append(target, item) {
|
|
33268
33706
|
if (Array.isArray(target)) {
|
|
@@ -33666,8 +34104,8 @@ function checkIsRepoRootTask() {
|
|
|
33666
34104
|
commands,
|
|
33667
34105
|
format: "utf-8",
|
|
33668
34106
|
onError,
|
|
33669
|
-
parser(
|
|
33670
|
-
return /^\.(git)?$/.test(
|
|
34107
|
+
parser(path74) {
|
|
34108
|
+
return /^\.(git)?$/.test(path74.trim());
|
|
33671
34109
|
}
|
|
33672
34110
|
};
|
|
33673
34111
|
}
|
|
@@ -34101,11 +34539,11 @@ function parseGrep(grep) {
|
|
|
34101
34539
|
const paths = /* @__PURE__ */ new Set();
|
|
34102
34540
|
const results = {};
|
|
34103
34541
|
forEachLineWithContent(grep, (input) => {
|
|
34104
|
-
const [
|
|
34105
|
-
paths.add(
|
|
34106
|
-
(results[
|
|
34542
|
+
const [path74, line, preview] = input.split(NULL);
|
|
34543
|
+
paths.add(path74);
|
|
34544
|
+
(results[path74] = results[path74] || []).push({
|
|
34107
34545
|
line: asNumber(line),
|
|
34108
|
-
path:
|
|
34546
|
+
path: path74,
|
|
34109
34547
|
preview
|
|
34110
34548
|
});
|
|
34111
34549
|
});
|
|
@@ -34870,14 +35308,14 @@ var init_hash_object = __esm2({
|
|
|
34870
35308
|
init_task();
|
|
34871
35309
|
}
|
|
34872
35310
|
});
|
|
34873
|
-
function parseInit(bare,
|
|
35311
|
+
function parseInit(bare, path74, text) {
|
|
34874
35312
|
const response = String(text).trim();
|
|
34875
35313
|
let result;
|
|
34876
35314
|
if (result = initResponseRegex.exec(response)) {
|
|
34877
|
-
return new InitSummary(bare,
|
|
35315
|
+
return new InitSummary(bare, path74, false, result[1]);
|
|
34878
35316
|
}
|
|
34879
35317
|
if (result = reInitResponseRegex.exec(response)) {
|
|
34880
|
-
return new InitSummary(bare,
|
|
35318
|
+
return new InitSummary(bare, path74, true, result[1]);
|
|
34881
35319
|
}
|
|
34882
35320
|
let gitDir = "";
|
|
34883
35321
|
const tokens = response.split(" ");
|
|
@@ -34888,7 +35326,7 @@ function parseInit(bare, path73, text) {
|
|
|
34888
35326
|
break;
|
|
34889
35327
|
}
|
|
34890
35328
|
}
|
|
34891
|
-
return new InitSummary(bare,
|
|
35329
|
+
return new InitSummary(bare, path74, /^re/i.test(response), gitDir);
|
|
34892
35330
|
}
|
|
34893
35331
|
var InitSummary;
|
|
34894
35332
|
var initResponseRegex;
|
|
@@ -34897,9 +35335,9 @@ var init_InitSummary = __esm2({
|
|
|
34897
35335
|
"src/lib/responses/InitSummary.ts"() {
|
|
34898
35336
|
"use strict";
|
|
34899
35337
|
InitSummary = class {
|
|
34900
|
-
constructor(bare,
|
|
35338
|
+
constructor(bare, path74, existing, gitDir) {
|
|
34901
35339
|
this.bare = bare;
|
|
34902
|
-
this.path =
|
|
35340
|
+
this.path = path74;
|
|
34903
35341
|
this.existing = existing;
|
|
34904
35342
|
this.gitDir = gitDir;
|
|
34905
35343
|
}
|
|
@@ -34911,7 +35349,7 @@ var init_InitSummary = __esm2({
|
|
|
34911
35349
|
function hasBareCommand(command) {
|
|
34912
35350
|
return command.includes(bareCommand);
|
|
34913
35351
|
}
|
|
34914
|
-
function initTask(bare = false,
|
|
35352
|
+
function initTask(bare = false, path74, customArgs) {
|
|
34915
35353
|
const commands = ["init", ...customArgs];
|
|
34916
35354
|
if (bare && !hasBareCommand(commands)) {
|
|
34917
35355
|
commands.splice(1, 0, bareCommand);
|
|
@@ -34920,7 +35358,7 @@ function initTask(bare = false, path73, customArgs) {
|
|
|
34920
35358
|
commands,
|
|
34921
35359
|
format: "utf-8",
|
|
34922
35360
|
parser(text) {
|
|
34923
|
-
return parseInit(commands.includes("--bare"),
|
|
35361
|
+
return parseInit(commands.includes("--bare"), path74, text);
|
|
34924
35362
|
}
|
|
34925
35363
|
};
|
|
34926
35364
|
}
|
|
@@ -35736,12 +36174,12 @@ var init_FileStatusSummary = __esm2({
|
|
|
35736
36174
|
"use strict";
|
|
35737
36175
|
fromPathRegex = /^(.+)\0(.+)$/;
|
|
35738
36176
|
FileStatusSummary = class {
|
|
35739
|
-
constructor(
|
|
35740
|
-
this.path =
|
|
36177
|
+
constructor(path74, index, working_dir) {
|
|
36178
|
+
this.path = path74;
|
|
35741
36179
|
this.index = index;
|
|
35742
36180
|
this.working_dir = working_dir;
|
|
35743
36181
|
if (index === "R" || working_dir === "R") {
|
|
35744
|
-
const detail = fromPathRegex.exec(
|
|
36182
|
+
const detail = fromPathRegex.exec(path74) || [null, path74, path74];
|
|
35745
36183
|
this.from = detail[2] || "";
|
|
35746
36184
|
this.path = detail[1] || "";
|
|
35747
36185
|
}
|
|
@@ -35772,14 +36210,14 @@ function splitLine(result, lineStr) {
|
|
|
35772
36210
|
default:
|
|
35773
36211
|
return;
|
|
35774
36212
|
}
|
|
35775
|
-
function data(index, workingDir,
|
|
36213
|
+
function data(index, workingDir, path74) {
|
|
35776
36214
|
const raw = `${index}${workingDir}`;
|
|
35777
36215
|
const handler = parsers6.get(raw);
|
|
35778
36216
|
if (handler) {
|
|
35779
|
-
handler(result,
|
|
36217
|
+
handler(result, path74);
|
|
35780
36218
|
}
|
|
35781
36219
|
if (raw !== "##" && raw !== "!!") {
|
|
35782
|
-
result.files.push(new FileStatusSummary(
|
|
36220
|
+
result.files.push(new FileStatusSummary(path74, index, workingDir));
|
|
35783
36221
|
}
|
|
35784
36222
|
}
|
|
35785
36223
|
}
|
|
@@ -36088,9 +36526,9 @@ var init_simple_git_api = __esm2({
|
|
|
36088
36526
|
next
|
|
36089
36527
|
);
|
|
36090
36528
|
}
|
|
36091
|
-
hashObject(
|
|
36529
|
+
hashObject(path74, write) {
|
|
36092
36530
|
return this._runTask(
|
|
36093
|
-
hashObjectTask(
|
|
36531
|
+
hashObjectTask(path74, write === true),
|
|
36094
36532
|
trailingFunctionArgument(arguments)
|
|
36095
36533
|
);
|
|
36096
36534
|
}
|
|
@@ -36443,8 +36881,8 @@ var init_branch = __esm2({
|
|
|
36443
36881
|
}
|
|
36444
36882
|
});
|
|
36445
36883
|
function toPath(input) {
|
|
36446
|
-
const
|
|
36447
|
-
return
|
|
36884
|
+
const path74 = input.trim().replace(/^["']|["']$/g, "");
|
|
36885
|
+
return path74 && normalize3(path74);
|
|
36448
36886
|
}
|
|
36449
36887
|
var parseCheckIgnore;
|
|
36450
36888
|
var init_CheckIgnore = __esm2({
|
|
@@ -36758,8 +37196,8 @@ __export2(sub_module_exports, {
|
|
|
36758
37196
|
subModuleTask: () => subModuleTask,
|
|
36759
37197
|
updateSubModuleTask: () => updateSubModuleTask
|
|
36760
37198
|
});
|
|
36761
|
-
function addSubModuleTask(repo,
|
|
36762
|
-
return subModuleTask(["add", repo,
|
|
37199
|
+
function addSubModuleTask(repo, path74) {
|
|
37200
|
+
return subModuleTask(["add", repo, path74]);
|
|
36763
37201
|
}
|
|
36764
37202
|
function initSubModuleTask(customArgs) {
|
|
36765
37203
|
return subModuleTask(["init", ...customArgs]);
|
|
@@ -37092,8 +37530,8 @@ var require_git = __commonJS2({
|
|
|
37092
37530
|
}
|
|
37093
37531
|
return this._runTask(straightThroughStringTask2(command, this._trimmed), next);
|
|
37094
37532
|
};
|
|
37095
|
-
Git2.prototype.submoduleAdd = function(repo,
|
|
37096
|
-
return this._runTask(addSubModuleTask2(repo,
|
|
37533
|
+
Git2.prototype.submoduleAdd = function(repo, path74, then) {
|
|
37534
|
+
return this._runTask(addSubModuleTask2(repo, path74), trailingFunctionArgument2(arguments));
|
|
37097
37535
|
};
|
|
37098
37536
|
Git2.prototype.submoduleUpdate = function(args, then) {
|
|
37099
37537
|
return this._runTask(
|
|
@@ -37829,8 +38267,8 @@ function parseNumstatEntries(lines) {
|
|
|
37829
38267
|
}
|
|
37830
38268
|
function parseNumstat(lines) {
|
|
37831
38269
|
const m = /* @__PURE__ */ new Map();
|
|
37832
|
-
for (const [
|
|
37833
|
-
m.set(
|
|
38270
|
+
for (const [path74, entry] of parseNumstatEntries(lines)) {
|
|
38271
|
+
m.set(path74, { additions: entry.additions, deletions: entry.deletions });
|
|
37834
38272
|
}
|
|
37835
38273
|
return m;
|
|
37836
38274
|
}
|
|
@@ -39137,18 +39575,32 @@ import * as fs27 from "node:fs";
|
|
|
39137
39575
|
// src/git/worktrees/worktree-remove.ts
|
|
39138
39576
|
import * as fs26 from "node:fs";
|
|
39139
39577
|
|
|
39578
|
+
// src/worktrees/is-removable-session-worktree-checkout-path.ts
|
|
39579
|
+
import path42 from "node:path";
|
|
39580
|
+
function isBridgeRootCheckoutPath(checkoutPath) {
|
|
39581
|
+
return normalizeResolvedPath(checkoutPath) === normalizeResolvedPath(getBridgeRoot());
|
|
39582
|
+
}
|
|
39583
|
+
function isRemovableSessionWorktreeCheckoutPath(checkoutPath, worktreesRootPath) {
|
|
39584
|
+
if (isBridgeRootCheckoutPath(checkoutPath)) return false;
|
|
39585
|
+
const normalized = normalizeResolvedPath(checkoutPath);
|
|
39586
|
+
const worktreesRoot = normalizeResolvedPath(worktreesRootPath);
|
|
39587
|
+
const rel = path42.relative(worktreesRoot, normalized);
|
|
39588
|
+
if (rel === "" || rel.startsWith("..") || path42.isAbsolute(rel)) return false;
|
|
39589
|
+
return true;
|
|
39590
|
+
}
|
|
39591
|
+
|
|
39140
39592
|
// src/git/worktrees/resolve-main-repo-from-git-file.ts
|
|
39141
39593
|
import * as fs25 from "node:fs";
|
|
39142
|
-
import * as
|
|
39594
|
+
import * as path43 from "node:path";
|
|
39143
39595
|
function resolveMainRepoFromWorktreeGitFile(wt) {
|
|
39144
|
-
const gitDirFile =
|
|
39596
|
+
const gitDirFile = path43.join(wt, ".git");
|
|
39145
39597
|
if (!fs25.existsSync(gitDirFile) || !fs25.statSync(gitDirFile).isFile()) return "";
|
|
39146
39598
|
const first2 = fs25.readFileSync(gitDirFile, "utf8").trim();
|
|
39147
39599
|
const m = first2.match(/^gitdir:\s*(.+)$/im);
|
|
39148
39600
|
if (!m) return "";
|
|
39149
|
-
const gitWorktreePath =
|
|
39150
|
-
const gitDir =
|
|
39151
|
-
return
|
|
39601
|
+
const gitWorktreePath = path43.resolve(wt, m[1].trim());
|
|
39602
|
+
const gitDir = path43.dirname(path43.dirname(gitWorktreePath));
|
|
39603
|
+
return path43.dirname(gitDir);
|
|
39152
39604
|
}
|
|
39153
39605
|
|
|
39154
39606
|
// src/git/worktrees/worktree-remove.ts
|
|
@@ -39156,32 +39608,44 @@ async function gitWorktreeRemoveForce(worktreePath) {
|
|
|
39156
39608
|
const mainRepo = resolveMainRepoFromWorktreeGitFile(worktreePath);
|
|
39157
39609
|
if (mainRepo) {
|
|
39158
39610
|
await cliSimpleGit(mainRepo).raw(["worktree", "remove", "--force", worktreePath]);
|
|
39159
|
-
|
|
39160
|
-
fs26.rmSync(worktreePath, { recursive: true, force: true });
|
|
39611
|
+
return true;
|
|
39161
39612
|
}
|
|
39613
|
+
if (isBridgeRootCheckoutPath(worktreePath)) return false;
|
|
39614
|
+
fs26.rmSync(worktreePath, { recursive: true, force: true });
|
|
39615
|
+
return true;
|
|
39162
39616
|
}
|
|
39163
39617
|
|
|
39164
39618
|
// src/worktrees/remove-session-worktrees.ts
|
|
39165
|
-
async function removeSessionWorktrees(paths, log2) {
|
|
39619
|
+
async function removeSessionWorktrees(paths, worktreesRootPath, log2) {
|
|
39166
39620
|
for (const wt of paths) {
|
|
39621
|
+
if (!isRemovableSessionWorktreeCheckoutPath(wt, worktreesRootPath)) {
|
|
39622
|
+
log2(`[worktrees] Skipping removal of ${wt} (bridge root or outside worktrees root).`);
|
|
39623
|
+
continue;
|
|
39624
|
+
}
|
|
39167
39625
|
try {
|
|
39168
|
-
await gitWorktreeRemoveForce(wt);
|
|
39169
|
-
|
|
39626
|
+
const removed = await gitWorktreeRemoveForce(wt);
|
|
39627
|
+
if (removed) {
|
|
39628
|
+
log2(`[worktrees] Removed worktree ${wt}`);
|
|
39629
|
+
} else {
|
|
39630
|
+
log2(`[worktrees] Skipping removal of ${wt} (bridge root).`);
|
|
39631
|
+
}
|
|
39170
39632
|
} catch (e) {
|
|
39171
39633
|
log2(`[worktrees] Remove failed for ${wt}: ${e instanceof Error ? e.message : String(e)}`);
|
|
39172
|
-
|
|
39173
|
-
|
|
39174
|
-
|
|
39634
|
+
if (isRemovableSessionWorktreeCheckoutPath(wt, worktreesRootPath)) {
|
|
39635
|
+
try {
|
|
39636
|
+
fs27.rmSync(wt, { recursive: true, force: true });
|
|
39637
|
+
} catch {
|
|
39638
|
+
}
|
|
39175
39639
|
}
|
|
39176
39640
|
}
|
|
39177
39641
|
}
|
|
39178
39642
|
}
|
|
39179
39643
|
|
|
39180
39644
|
// src/worktrees/manager/git/remove-session-worktree-checkouts.ts
|
|
39181
|
-
async function removeSessionWorktreeCheckouts(cache2, sessionId, log2) {
|
|
39645
|
+
async function removeSessionWorktreeCheckouts(cache2, sessionId, worktreesRootPath, log2) {
|
|
39182
39646
|
const paths = cache2.clearSession(sessionId);
|
|
39183
39647
|
if (!paths?.length) return;
|
|
39184
|
-
await removeSessionWorktrees(paths, log2);
|
|
39648
|
+
await removeSessionWorktrees(paths, worktreesRootPath, log2);
|
|
39185
39649
|
}
|
|
39186
39650
|
|
|
39187
39651
|
// src/git/branches/rename-branch.ts
|
|
@@ -39214,11 +39678,11 @@ async function renameSessionWorktreeBranch(cache2, sessionId, newBranch, log2) {
|
|
|
39214
39678
|
|
|
39215
39679
|
// src/worktrees/discovery/discover-session-worktree-on-disk.ts
|
|
39216
39680
|
import * as fs31 from "node:fs";
|
|
39217
|
-
import * as
|
|
39681
|
+
import * as path48 from "node:path";
|
|
39218
39682
|
|
|
39219
39683
|
// src/worktrees/discovery/collect-worktree-paths.ts
|
|
39220
39684
|
import * as fs29 from "node:fs";
|
|
39221
|
-
import * as
|
|
39685
|
+
import * as path45 from "node:path";
|
|
39222
39686
|
|
|
39223
39687
|
// src/worktrees/discovery/disk-walk-constants.ts
|
|
39224
39688
|
var DISK_WALK_YIELD_EVERY = 64;
|
|
@@ -39247,7 +39711,7 @@ function shouldSkipDiskWalkEntry(name) {
|
|
|
39247
39711
|
|
|
39248
39712
|
// src/worktrees/discovery/disk-walk-utils.ts
|
|
39249
39713
|
import * as fs28 from "node:fs";
|
|
39250
|
-
import * as
|
|
39714
|
+
import * as path44 from "node:path";
|
|
39251
39715
|
async function yieldDuringDiskWalk(state) {
|
|
39252
39716
|
state.entries++;
|
|
39253
39717
|
if (state.entries % DISK_WALK_YIELD_EVERY !== 0) return true;
|
|
@@ -39257,7 +39721,7 @@ async function yieldDuringDiskWalk(state) {
|
|
|
39257
39721
|
}
|
|
39258
39722
|
async function isGitDir(dirPath) {
|
|
39259
39723
|
try {
|
|
39260
|
-
await fs28.promises.access(
|
|
39724
|
+
await fs28.promises.access(path44.join(dirPath, ".git"));
|
|
39261
39725
|
return true;
|
|
39262
39726
|
} catch {
|
|
39263
39727
|
return false;
|
|
@@ -39271,7 +39735,7 @@ async function collectGitRepoRootsUnderDirectory(rootPath) {
|
|
|
39271
39735
|
const walk = async (dir) => {
|
|
39272
39736
|
if (!await yieldDuringDiskWalk(state)) return;
|
|
39273
39737
|
if (await isGitDir(dir)) {
|
|
39274
|
-
out.push(
|
|
39738
|
+
out.push(path45.resolve(dir));
|
|
39275
39739
|
return;
|
|
39276
39740
|
}
|
|
39277
39741
|
let entries;
|
|
@@ -39282,12 +39746,12 @@ async function collectGitRepoRootsUnderDirectory(rootPath) {
|
|
|
39282
39746
|
}
|
|
39283
39747
|
for (const e of entries) {
|
|
39284
39748
|
if (shouldSkipDiskWalkEntry(e.name)) continue;
|
|
39285
|
-
const full =
|
|
39749
|
+
const full = path45.join(dir, e.name);
|
|
39286
39750
|
if (!e.isDirectory()) continue;
|
|
39287
39751
|
await walk(full);
|
|
39288
39752
|
}
|
|
39289
39753
|
};
|
|
39290
|
-
await walk(
|
|
39754
|
+
await walk(path45.resolve(rootPath));
|
|
39291
39755
|
return { paths: [...new Set(out)], entriesVisited: state.entries };
|
|
39292
39756
|
}
|
|
39293
39757
|
async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK_MAX_DEPTH) {
|
|
@@ -39304,10 +39768,10 @@ async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK
|
|
|
39304
39768
|
}
|
|
39305
39769
|
for (const e of entries) {
|
|
39306
39770
|
if (shouldSkipDiskWalkEntry(e.name)) continue;
|
|
39307
|
-
const full =
|
|
39771
|
+
const full = path45.join(dir, e.name);
|
|
39308
39772
|
if (!e.isDirectory()) continue;
|
|
39309
39773
|
if (e.name === sessionId) {
|
|
39310
|
-
if (await isGitDir(full)) out.push(
|
|
39774
|
+
if (await isGitDir(full)) out.push(path45.resolve(full));
|
|
39311
39775
|
continue;
|
|
39312
39776
|
}
|
|
39313
39777
|
if (await isGitDir(full)) continue;
|
|
@@ -39319,14 +39783,14 @@ async function collectWorktreeRootsNamed(root, sessionId, maxDepth = LEGACY_WALK
|
|
|
39319
39783
|
}
|
|
39320
39784
|
|
|
39321
39785
|
// src/worktrees/discovery/layout-keys-for-bridge-root.ts
|
|
39322
|
-
import * as
|
|
39786
|
+
import * as path46 from "node:path";
|
|
39323
39787
|
function layoutKeysForBridgeRoot(layout, bridgeRoot, keysOnDisk) {
|
|
39324
|
-
const bridge =
|
|
39788
|
+
const bridge = path46.resolve(bridgeRoot);
|
|
39325
39789
|
const preferred = getLauncherDirNameIfPresent(layout, bridgeRoot);
|
|
39326
39790
|
const relevant = layout.launcherCwds.filter((e) => {
|
|
39327
|
-
const entry =
|
|
39328
|
-
return bridge === entry || bridge.startsWith(entry +
|
|
39329
|
-
}).sort((a, b) =>
|
|
39791
|
+
const entry = path46.resolve(e.absolutePath);
|
|
39792
|
+
return bridge === entry || bridge.startsWith(entry + path46.sep) || entry.startsWith(bridge + path46.sep);
|
|
39793
|
+
}).sort((a, b) => path46.resolve(b.absolutePath).length - path46.resolve(a.absolutePath).length).map((e) => e.dirName).filter((name) => keysOnDisk.includes(name));
|
|
39330
39794
|
const ordered = [];
|
|
39331
39795
|
const seen = /* @__PURE__ */ new Set();
|
|
39332
39796
|
const add = (k) => {
|
|
@@ -39345,7 +39809,7 @@ function layoutKeysForBridgeRoot(layout, bridgeRoot, keysOnDisk) {
|
|
|
39345
39809
|
|
|
39346
39810
|
// src/worktrees/discovery/try-binding-from-session-directory.ts
|
|
39347
39811
|
import * as fs30 from "node:fs";
|
|
39348
|
-
import * as
|
|
39812
|
+
import * as path47 from "node:path";
|
|
39349
39813
|
async function tryBindingFromSessionDirectory(sessionDir) {
|
|
39350
39814
|
let st;
|
|
39351
39815
|
try {
|
|
@@ -39356,7 +39820,7 @@ async function tryBindingFromSessionDirectory(sessionDir) {
|
|
|
39356
39820
|
if (!st.isDirectory()) return null;
|
|
39357
39821
|
const { paths: worktreePaths } = await collectGitRepoRootsUnderDirectory(sessionDir);
|
|
39358
39822
|
if (worktreePaths.length === 0) return null;
|
|
39359
|
-
const abs =
|
|
39823
|
+
const abs = path47.resolve(sessionDir);
|
|
39360
39824
|
return {
|
|
39361
39825
|
sessionParentPath: abs,
|
|
39362
39826
|
workingTreeRelRoot: abs,
|
|
@@ -39380,7 +39844,7 @@ async function discoverSessionWorktreeOnDisk(options) {
|
|
|
39380
39844
|
try {
|
|
39381
39845
|
for (const name of await fs31.promises.readdir(worktreesRootPath)) {
|
|
39382
39846
|
if (name.startsWith(".")) continue;
|
|
39383
|
-
const p =
|
|
39847
|
+
const p = path48.join(worktreesRootPath, name);
|
|
39384
39848
|
let st;
|
|
39385
39849
|
try {
|
|
39386
39850
|
st = await fs31.promises.stat(p);
|
|
@@ -39397,7 +39861,7 @@ async function discoverSessionWorktreeOnDisk(options) {
|
|
|
39397
39861
|
for (const key of keys) {
|
|
39398
39862
|
if (isCliImmediateShutdownRequested()) return null;
|
|
39399
39863
|
await yieldToEventLoop();
|
|
39400
|
-
const layoutRoot =
|
|
39864
|
+
const layoutRoot = path48.join(worktreesRootPath, key);
|
|
39401
39865
|
let layoutSt;
|
|
39402
39866
|
try {
|
|
39403
39867
|
layoutSt = await fs31.promises.stat(layoutRoot);
|
|
@@ -39405,16 +39869,16 @@ async function discoverSessionWorktreeOnDisk(options) {
|
|
|
39405
39869
|
continue;
|
|
39406
39870
|
}
|
|
39407
39871
|
if (!layoutSt.isDirectory()) continue;
|
|
39408
|
-
const sessionDir =
|
|
39872
|
+
const sessionDir = path48.join(layoutRoot, sid);
|
|
39409
39873
|
const nested = await tryBindingFromSessionDirectory(sessionDir);
|
|
39410
39874
|
if (nested) return nested;
|
|
39411
39875
|
const legacy = await collectWorktreeRootsNamed(layoutRoot, sid);
|
|
39412
39876
|
if (legacy.paths.length > 0) {
|
|
39413
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacy.paths) ??
|
|
39877
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacy.paths) ?? path48.resolve(legacy.paths[0]);
|
|
39414
39878
|
return {
|
|
39415
|
-
sessionParentPath:
|
|
39416
|
-
workingTreeRelRoot:
|
|
39417
|
-
repoCheckoutPaths: legacy.paths.map((p) =>
|
|
39879
|
+
sessionParentPath: path48.resolve(isolated),
|
|
39880
|
+
workingTreeRelRoot: path48.resolve(layoutRoot),
|
|
39881
|
+
repoCheckoutPaths: legacy.paths.map((p) => path48.resolve(p))
|
|
39418
39882
|
};
|
|
39419
39883
|
}
|
|
39420
39884
|
}
|
|
@@ -39423,29 +39887,29 @@ async function discoverSessionWorktreeOnDisk(options) {
|
|
|
39423
39887
|
|
|
39424
39888
|
// src/worktrees/discovery/discover-session-worktrees-under-session-worktree-root.ts
|
|
39425
39889
|
import * as fs32 from "node:fs";
|
|
39426
|
-
import * as
|
|
39890
|
+
import * as path50 from "node:path";
|
|
39427
39891
|
|
|
39428
39892
|
// src/worktrees/discovery/discover-legacy-binding-ascending-from-checkout.ts
|
|
39429
|
-
import * as
|
|
39893
|
+
import * as path49 from "node:path";
|
|
39430
39894
|
async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPath) {
|
|
39431
39895
|
const sid = sessionId.trim();
|
|
39432
39896
|
if (!sid) return null;
|
|
39433
|
-
const hintR =
|
|
39897
|
+
const hintR = path49.resolve(checkoutPath);
|
|
39434
39898
|
let best = null;
|
|
39435
|
-
let cur =
|
|
39899
|
+
let cur = path49.dirname(hintR);
|
|
39436
39900
|
for (let i = 0; i < 40; i++) {
|
|
39437
39901
|
if (isCliImmediateShutdownRequested()) return best;
|
|
39438
39902
|
await yieldToEventLoop();
|
|
39439
39903
|
const paths = await collectWorktreeRootsNamed(cur, sid);
|
|
39440
|
-
if (paths.paths.some((p) =>
|
|
39441
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths.paths) ??
|
|
39904
|
+
if (paths.paths.some((p) => path49.resolve(p) === hintR)) {
|
|
39905
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(paths.paths) ?? path49.resolve(paths.paths[0]);
|
|
39442
39906
|
best = {
|
|
39443
|
-
sessionParentPath:
|
|
39444
|
-
workingTreeRelRoot:
|
|
39445
|
-
repoCheckoutPaths: paths.paths.map((p) =>
|
|
39907
|
+
sessionParentPath: path49.resolve(isolated),
|
|
39908
|
+
workingTreeRelRoot: path49.resolve(cur),
|
|
39909
|
+
repoCheckoutPaths: paths.paths.map((p) => path49.resolve(p))
|
|
39446
39910
|
};
|
|
39447
39911
|
}
|
|
39448
|
-
const next =
|
|
39912
|
+
const next = path49.dirname(cur);
|
|
39449
39913
|
if (next === cur) break;
|
|
39450
39914
|
cur = next;
|
|
39451
39915
|
}
|
|
@@ -39456,12 +39920,12 @@ async function discoverLegacyBindingAscendingFromCheckout(sessionId, checkoutPat
|
|
|
39456
39920
|
async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeRootPathOrHint, sessionId) {
|
|
39457
39921
|
const sid = sessionId.trim();
|
|
39458
39922
|
if (!sid) return null;
|
|
39459
|
-
const hint =
|
|
39460
|
-
const underHint = await tryBindingFromSessionDirectory(
|
|
39923
|
+
const hint = path50.resolve(sessionWorktreeRootPathOrHint);
|
|
39924
|
+
const underHint = await tryBindingFromSessionDirectory(path50.join(hint, sid));
|
|
39461
39925
|
if (underHint) return underHint;
|
|
39462
39926
|
const direct = await tryBindingFromSessionDirectory(hint);
|
|
39463
39927
|
if (direct) {
|
|
39464
|
-
if (
|
|
39928
|
+
if (path50.basename(hint) === sid && await isGitDir(hint)) {
|
|
39465
39929
|
const legacyFromCheckout = await discoverLegacyBindingAscendingFromCheckout(sid, hint);
|
|
39466
39930
|
if (legacyFromCheckout && legacyFromCheckout.repoCheckoutPaths.length > direct.repoCheckoutPaths.length) {
|
|
39467
39931
|
return legacyFromCheckout;
|
|
@@ -39469,7 +39933,7 @@ async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeR
|
|
|
39469
39933
|
}
|
|
39470
39934
|
return direct;
|
|
39471
39935
|
}
|
|
39472
|
-
if (
|
|
39936
|
+
if (path50.basename(hint) === sid && await isGitDir(hint)) {
|
|
39473
39937
|
const legacyFromCheckout = await discoverLegacyBindingAscendingFromCheckout(sid, hint);
|
|
39474
39938
|
if (legacyFromCheckout) return legacyFromCheckout;
|
|
39475
39939
|
}
|
|
@@ -39482,11 +39946,11 @@ async function discoverSessionWorktreesUnderSessionWorktreeRoot(sessionWorktreeR
|
|
|
39482
39946
|
if (!st.isDirectory()) return null;
|
|
39483
39947
|
const legacyPaths = await collectWorktreeRootsNamed(hint, sid);
|
|
39484
39948
|
if (legacyPaths.paths.length === 0) return null;
|
|
39485
|
-
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths.paths) ??
|
|
39949
|
+
const isolated = resolveIsolatedSessionParentPathFromCheckouts(legacyPaths.paths) ?? path50.resolve(legacyPaths.paths[0]);
|
|
39486
39950
|
return {
|
|
39487
|
-
sessionParentPath:
|
|
39951
|
+
sessionParentPath: path50.resolve(isolated),
|
|
39488
39952
|
workingTreeRelRoot: hint,
|
|
39489
|
-
repoCheckoutPaths: legacyPaths.paths.map((p) =>
|
|
39953
|
+
repoCheckoutPaths: legacyPaths.paths.map((p) => path50.resolve(p))
|
|
39490
39954
|
};
|
|
39491
39955
|
}
|
|
39492
39956
|
|
|
@@ -39548,11 +40012,11 @@ function parseSessionParent(v) {
|
|
|
39548
40012
|
|
|
39549
40013
|
// src/worktrees/prepare-new-session-worktrees.ts
|
|
39550
40014
|
import * as fs34 from "node:fs";
|
|
39551
|
-
import * as
|
|
40015
|
+
import * as path52 from "node:path";
|
|
39552
40016
|
|
|
39553
40017
|
// src/git/discover-repos.ts
|
|
39554
40018
|
import * as fs33 from "node:fs";
|
|
39555
|
-
import * as
|
|
40019
|
+
import * as path51 from "node:path";
|
|
39556
40020
|
var GIT_DISCOVER_YIELD_EVERY = 32;
|
|
39557
40021
|
async function yieldGitDiscoverWork(entryCount) {
|
|
39558
40022
|
if (entryCount > 0 && entryCount % GIT_DISCOVER_YIELD_EVERY === 0) {
|
|
@@ -39561,7 +40025,7 @@ async function yieldGitDiscoverWork(entryCount) {
|
|
|
39561
40025
|
}
|
|
39562
40026
|
async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
39563
40027
|
const result = [];
|
|
39564
|
-
const cwdResolved =
|
|
40028
|
+
const cwdResolved = path51.resolve(cwd);
|
|
39565
40029
|
if (await isGitRepoDirectory(cwdResolved)) {
|
|
39566
40030
|
const remoteUrl = await getRemoteOriginUrl(cwdResolved);
|
|
39567
40031
|
result.push({ absolutePath: cwdResolved, remoteUrl });
|
|
@@ -39576,7 +40040,7 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
|
39576
40040
|
await yieldGitDiscoverWork(i + 1);
|
|
39577
40041
|
const ent = entries[i];
|
|
39578
40042
|
if (!ent.isDirectory()) continue;
|
|
39579
|
-
const childPath2 =
|
|
40043
|
+
const childPath2 = path51.join(cwdResolved, ent.name);
|
|
39580
40044
|
if (await isGitRepoDirectory(childPath2)) {
|
|
39581
40045
|
const remoteUrl = await getRemoteOriginUrl(childPath2);
|
|
39582
40046
|
result.push({ absolutePath: childPath2, remoteUrl });
|
|
@@ -39585,12 +40049,12 @@ async function discoverGitRepos(cwd = getBridgeRoot()) {
|
|
|
39585
40049
|
return result;
|
|
39586
40050
|
}
|
|
39587
40051
|
async function discoverGitReposUnderRoot(rootPath) {
|
|
39588
|
-
const root =
|
|
40052
|
+
const root = path51.resolve(rootPath);
|
|
39589
40053
|
const roots = [];
|
|
39590
40054
|
let walkEntries = 0;
|
|
39591
40055
|
async function walk(dir) {
|
|
39592
40056
|
if (await isGitRepoDirectory(dir)) {
|
|
39593
|
-
roots.push(
|
|
40057
|
+
roots.push(path51.resolve(dir));
|
|
39594
40058
|
return;
|
|
39595
40059
|
}
|
|
39596
40060
|
let entries;
|
|
@@ -39603,7 +40067,7 @@ async function discoverGitReposUnderRoot(rootPath) {
|
|
|
39603
40067
|
await yieldGitDiscoverWork(++walkEntries);
|
|
39604
40068
|
const ent = entries[i];
|
|
39605
40069
|
if (!ent.isDirectory() || ent.name === ".git") continue;
|
|
39606
|
-
await walk(
|
|
40070
|
+
await walk(path51.join(dir, ent.name));
|
|
39607
40071
|
}
|
|
39608
40072
|
}
|
|
39609
40073
|
await walk(root);
|
|
@@ -39638,10 +40102,10 @@ function resolveBaseRefForRepo(relNorm, baseBranches) {
|
|
|
39638
40102
|
}
|
|
39639
40103
|
async function prepareNewSessionWorktrees(options) {
|
|
39640
40104
|
const { worktreesRootPath, bridgeRoot, sessionId, layout, log: log2, worktreeBaseBranches } = options;
|
|
39641
|
-
const bridgeResolved =
|
|
40105
|
+
const bridgeResolved = path52.resolve(bridgeRoot);
|
|
39642
40106
|
const cwdKey = allocateDirNameForLauncherCwd(layout, bridgeResolved);
|
|
39643
|
-
const bridgeKeyDir =
|
|
39644
|
-
const sessionDir =
|
|
40107
|
+
const bridgeKeyDir = path52.join(worktreesRootPath, cwdKey);
|
|
40108
|
+
const sessionDir = path52.join(bridgeKeyDir, sessionId);
|
|
39645
40109
|
const repos = await discoverGitReposUnderRoot(bridgeResolved);
|
|
39646
40110
|
if (repos.length === 0) {
|
|
39647
40111
|
log2("[worktrees] No Git repositories under bridge root; skipping worktree creation.");
|
|
@@ -39651,12 +40115,12 @@ async function prepareNewSessionWorktrees(options) {
|
|
|
39651
40115
|
const worktreePaths = [];
|
|
39652
40116
|
fs34.mkdirSync(sessionDir, { recursive: true });
|
|
39653
40117
|
for (const repo of repos) {
|
|
39654
|
-
let rel =
|
|
39655
|
-
if (rel.startsWith("..") ||
|
|
40118
|
+
let rel = path52.relative(bridgeResolved, repo.absolutePath);
|
|
40119
|
+
if (rel.startsWith("..") || path52.isAbsolute(rel)) continue;
|
|
39656
40120
|
const relNorm = normalizeRepoRelPath2(rel === "" ? "." : rel);
|
|
39657
|
-
const wtPath = relNorm === "." ? sessionDir :
|
|
40121
|
+
const wtPath = relNorm === "." ? sessionDir : path52.join(sessionDir, relNorm);
|
|
39658
40122
|
if (relNorm !== ".") {
|
|
39659
|
-
fs34.mkdirSync(
|
|
40123
|
+
fs34.mkdirSync(path52.dirname(wtPath), { recursive: true });
|
|
39660
40124
|
}
|
|
39661
40125
|
const baseRef = resolveBaseRefForRepo(relNorm, worktreeBaseBranches);
|
|
39662
40126
|
try {
|
|
@@ -39709,9 +40173,9 @@ async function resolveExistingSessionParentPath(sessionId, cache2, discover) {
|
|
|
39709
40173
|
}
|
|
39710
40174
|
|
|
39711
40175
|
// src/worktrees/manager/resolve-explicit-session-parent-path.ts
|
|
39712
|
-
import * as
|
|
40176
|
+
import * as path53 from "node:path";
|
|
39713
40177
|
async function resolveExplicitSessionParentPath(params) {
|
|
39714
|
-
const resolved =
|
|
40178
|
+
const resolved = path53.resolve(params.parentPathRaw);
|
|
39715
40179
|
if (parseSessionParent(params.sessionParent) !== "worktrees_root") {
|
|
39716
40180
|
return resolved;
|
|
39717
40181
|
}
|
|
@@ -39728,7 +40192,7 @@ async function resolveExplicitSessionParentPath(params) {
|
|
|
39728
40192
|
await yieldToEventLoop();
|
|
39729
40193
|
const tryRoot = await discoverSessionWorktreesUnderSessionWorktreeRoot(cur, params.sessionId);
|
|
39730
40194
|
if (tryRoot) return rememberAndReturn(tryRoot);
|
|
39731
|
-
const next =
|
|
40195
|
+
const next = path53.dirname(cur);
|
|
39732
40196
|
if (next === cur) break;
|
|
39733
40197
|
cur = next;
|
|
39734
40198
|
}
|
|
@@ -39838,7 +40302,7 @@ function createSessionWorktreeGitApi(ctx) {
|
|
|
39838
40302
|
await renameSessionWorktreeBranch(ctx.cache, sessionId, newBranch, ctx.log);
|
|
39839
40303
|
},
|
|
39840
40304
|
async removeSessionWorktrees(sessionId) {
|
|
39841
|
-
await removeSessionWorktreeCheckouts(ctx.cache, sessionId, ctx.log);
|
|
40305
|
+
await removeSessionWorktreeCheckouts(ctx.cache, sessionId, ctx.worktreesRootPath, ctx.log);
|
|
39842
40306
|
},
|
|
39843
40307
|
async commitSession(params) {
|
|
39844
40308
|
return commitSessionWorktree(ctx.cache, params);
|
|
@@ -39867,17 +40331,17 @@ var SessionWorktreeManager = class {
|
|
|
39867
40331
|
};
|
|
39868
40332
|
|
|
39869
40333
|
// src/worktrees/manager/default-worktrees-root-path.ts
|
|
39870
|
-
import * as
|
|
40334
|
+
import * as path54 from "node:path";
|
|
39871
40335
|
import os9 from "node:os";
|
|
39872
40336
|
function defaultWorktreesRootPath() {
|
|
39873
|
-
return
|
|
40337
|
+
return path54.join(os9.homedir(), ".buildautomaton", "worktrees");
|
|
39874
40338
|
}
|
|
39875
40339
|
|
|
39876
40340
|
// src/files/watch-file-index.ts
|
|
39877
|
-
import
|
|
40341
|
+
import path59 from "node:path";
|
|
39878
40342
|
|
|
39879
40343
|
// src/files/index/build-file-index.ts
|
|
39880
|
-
import
|
|
40344
|
+
import path55 from "node:path";
|
|
39881
40345
|
|
|
39882
40346
|
// src/files/index/file-index-sqlite-lock.ts
|
|
39883
40347
|
var fileIndexChain = Promise.resolve();
|
|
@@ -39968,7 +40432,7 @@ function assertNotShutdown2() {
|
|
|
39968
40432
|
if (isCliImmediateShutdownRequested()) throw new CliSqliteInterrupted();
|
|
39969
40433
|
}
|
|
39970
40434
|
async function buildFileIndexAsync(cwd) {
|
|
39971
|
-
const resolved =
|
|
40435
|
+
const resolved = path55.resolve(cwd);
|
|
39972
40436
|
await yieldToEventLoop();
|
|
39973
40437
|
assertNotShutdown2();
|
|
39974
40438
|
const paths = await collectWorkspacePathsAsync(resolved);
|
|
@@ -39981,7 +40445,7 @@ async function buildFileIndexAsync(cwd) {
|
|
|
39981
40445
|
}
|
|
39982
40446
|
|
|
39983
40447
|
// src/files/index/ensure-file-index.ts
|
|
39984
|
-
import
|
|
40448
|
+
import path56 from "node:path";
|
|
39985
40449
|
|
|
39986
40450
|
// src/files/index/search-file-index.ts
|
|
39987
40451
|
function escapeLikePattern(fragment) {
|
|
@@ -40033,7 +40497,7 @@ async function searchBridgeFilePathsAsync(resolvedCwd, query, limit = 100) {
|
|
|
40033
40497
|
|
|
40034
40498
|
// src/files/index/ensure-file-index.ts
|
|
40035
40499
|
async function ensureFileIndexAsync(cwd) {
|
|
40036
|
-
const resolved =
|
|
40500
|
+
const resolved = path56.resolve(cwd);
|
|
40037
40501
|
if (await bridgeFileIndexIsPopulated(resolved)) {
|
|
40038
40502
|
return { fromCache: true, pathCount: await bridgeFileIndexPathCount(resolved) };
|
|
40039
40503
|
}
|
|
@@ -40082,10 +40546,10 @@ function createFileIndexFsWatcher(resolved, schedule) {
|
|
|
40082
40546
|
|
|
40083
40547
|
// src/files/index/file-index-incremental-symbol-updates.ts
|
|
40084
40548
|
import fs35 from "node:fs";
|
|
40085
|
-
import
|
|
40549
|
+
import path57 from "node:path";
|
|
40086
40550
|
async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
|
|
40087
40551
|
for (const rel of relPaths) {
|
|
40088
|
-
const absPath =
|
|
40552
|
+
const absPath = path57.join(resolved, rel);
|
|
40089
40553
|
try {
|
|
40090
40554
|
const stat2 = await fs35.promises.stat(absPath);
|
|
40091
40555
|
if (stat2.isFile()) {
|
|
@@ -40105,9 +40569,9 @@ async function applyIncrementalSymbolIndexUpdates(resolved, relPaths) {
|
|
|
40105
40569
|
}
|
|
40106
40570
|
|
|
40107
40571
|
// src/files/index/file-index-initial-builds.ts
|
|
40108
|
-
import
|
|
40572
|
+
import path58 from "node:path";
|
|
40109
40573
|
async function runInitialIndexBuilds(cwd = getBridgeRoot()) {
|
|
40110
|
-
const resolved =
|
|
40574
|
+
const resolved = path58.resolve(cwd);
|
|
40111
40575
|
try {
|
|
40112
40576
|
await buildFileIndexAsync(resolved);
|
|
40113
40577
|
await buildSymbolIndexAsync(resolved);
|
|
@@ -40125,7 +40589,7 @@ function scheduleInitialIndexBuilds(cwd = getBridgeRoot()) {
|
|
|
40125
40589
|
// src/files/watch-file-index.ts
|
|
40126
40590
|
var MAX_INCREMENTAL_SYMBOL_UPDATES = 512;
|
|
40127
40591
|
function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
40128
|
-
const resolved =
|
|
40592
|
+
const resolved = path59.resolve(cwd);
|
|
40129
40593
|
let timer = null;
|
|
40130
40594
|
const pendingSymbolUpdates = /* @__PURE__ */ new Set();
|
|
40131
40595
|
let needsFullSymbolRebuild = false;
|
|
@@ -40187,7 +40651,7 @@ function startFileIndexWatcher(cwd = getBridgeRoot()) {
|
|
|
40187
40651
|
}
|
|
40188
40652
|
|
|
40189
40653
|
// src/connection/create-bridge-connection.ts
|
|
40190
|
-
import * as
|
|
40654
|
+
import * as path73 from "node:path";
|
|
40191
40655
|
|
|
40192
40656
|
// src/dev-servers/manager/dev-server-manager.ts
|
|
40193
40657
|
import { rm as rm2 } from "node:fs/promises";
|
|
@@ -40497,10 +40961,10 @@ function trySpawnShellTruePiped(command, env, cwd, devNullFd, signal) {
|
|
|
40497
40961
|
import { spawn as spawn8 } from "node:child_process";
|
|
40498
40962
|
import fs38 from "node:fs";
|
|
40499
40963
|
import { tmpdir } from "node:os";
|
|
40500
|
-
import
|
|
40964
|
+
import path60 from "node:path";
|
|
40501
40965
|
function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
40502
|
-
const tmpRoot = fs38.mkdtempSync(
|
|
40503
|
-
const logPath =
|
|
40966
|
+
const tmpRoot = fs38.mkdtempSync(path60.join(tmpdir(), "ba-devsrv-log-"));
|
|
40967
|
+
const logPath = path60.join(tmpRoot, "combined.log");
|
|
40504
40968
|
let logFd;
|
|
40505
40969
|
try {
|
|
40506
40970
|
logFd = fs38.openSync(logPath, "a");
|
|
@@ -40544,15 +41008,15 @@ function trySpawnMergedLogFile(command, env, cwd, signal) {
|
|
|
40544
41008
|
import { spawn as spawn9 } from "node:child_process";
|
|
40545
41009
|
import fs39 from "node:fs";
|
|
40546
41010
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
40547
|
-
import
|
|
41011
|
+
import path61 from "node:path";
|
|
40548
41012
|
function shSingleQuote(s) {
|
|
40549
41013
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
40550
41014
|
}
|
|
40551
41015
|
function trySpawnShellScriptLogRedirectUnix(command, env, cwd, signal) {
|
|
40552
|
-
const tmpRoot = fs39.mkdtempSync(
|
|
40553
|
-
const logPath =
|
|
40554
|
-
const innerPath =
|
|
40555
|
-
const runnerPath =
|
|
41016
|
+
const tmpRoot = fs39.mkdtempSync(path61.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
41017
|
+
const logPath = path61.join(tmpRoot, "combined.log");
|
|
41018
|
+
const innerPath = path61.join(tmpRoot, "_cmd.sh");
|
|
41019
|
+
const runnerPath = path61.join(tmpRoot, "_run.sh");
|
|
40556
41020
|
try {
|
|
40557
41021
|
fs39.writeFileSync(innerPath, `#!/bin/sh
|
|
40558
41022
|
${command}
|
|
@@ -40583,9 +41047,9 @@ cd ${shSingleQuote(cwd)}
|
|
|
40583
41047
|
}
|
|
40584
41048
|
}
|
|
40585
41049
|
function trySpawnShellScriptLogRedirectWin(command, env, cwd, signal) {
|
|
40586
|
-
const tmpRoot = fs39.mkdtempSync(
|
|
40587
|
-
const logPath =
|
|
40588
|
-
const runnerPath =
|
|
41050
|
+
const tmpRoot = fs39.mkdtempSync(path61.join(tmpdir2(), "ba-devsrv-sh-"));
|
|
41051
|
+
const logPath = path61.join(tmpRoot, "combined.log");
|
|
41052
|
+
const runnerPath = path61.join(tmpRoot, "_run.bat");
|
|
40589
41053
|
const q = (p) => `"${p.replace(/"/g, '""')}"`;
|
|
40590
41054
|
const com = process.env.ComSpec || "cmd.exe";
|
|
40591
41055
|
try {
|
|
@@ -41367,15 +41831,15 @@ async function yieldSkillDiscoveryWork(entryCount) {
|
|
|
41367
41831
|
|
|
41368
41832
|
// src/skills/discovery/discover-local-skills.ts
|
|
41369
41833
|
import fs40 from "node:fs";
|
|
41370
|
-
import
|
|
41834
|
+
import path62 from "node:path";
|
|
41371
41835
|
function collectSkillFromDir(rel, base, name, seenKeys, out) {
|
|
41372
|
-
const dir =
|
|
41836
|
+
const dir = path62.join(base, name);
|
|
41373
41837
|
try {
|
|
41374
41838
|
if (!fs40.statSync(dir).isDirectory()) return;
|
|
41375
41839
|
} catch {
|
|
41376
41840
|
return;
|
|
41377
41841
|
}
|
|
41378
|
-
const skillMd =
|
|
41842
|
+
const skillMd = path62.join(dir, "SKILL.md");
|
|
41379
41843
|
if (!fs40.existsSync(skillMd)) return;
|
|
41380
41844
|
const key = `${rel}/${name}`;
|
|
41381
41845
|
if (seenKeys.has(key)) return;
|
|
@@ -41388,7 +41852,7 @@ async function discoverLocalSkillsAsync(cwd) {
|
|
|
41388
41852
|
let work = 0;
|
|
41389
41853
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
41390
41854
|
await yieldSkillDiscoveryWork(++work);
|
|
41391
|
-
const base =
|
|
41855
|
+
const base = path62.join(cwd, rel);
|
|
41392
41856
|
if (!fs40.existsSync(base) || !fs40.statSync(base).isDirectory()) continue;
|
|
41393
41857
|
let entries = [];
|
|
41394
41858
|
try {
|
|
@@ -41406,15 +41870,15 @@ async function discoverLocalSkillsAsync(cwd) {
|
|
|
41406
41870
|
|
|
41407
41871
|
// src/skills/discovery/discover-skill-layout-roots.ts
|
|
41408
41872
|
import fs41 from "node:fs";
|
|
41409
|
-
import
|
|
41873
|
+
import path63 from "node:path";
|
|
41410
41874
|
function collectLayoutSkill(rel, base, name, skills2) {
|
|
41411
|
-
const dir =
|
|
41875
|
+
const dir = path63.join(base, name);
|
|
41412
41876
|
try {
|
|
41413
41877
|
if (!fs41.statSync(dir).isDirectory()) return;
|
|
41414
41878
|
} catch {
|
|
41415
41879
|
return;
|
|
41416
41880
|
}
|
|
41417
|
-
if (!fs41.existsSync(
|
|
41881
|
+
if (!fs41.existsSync(path63.join(dir, "SKILL.md"))) return;
|
|
41418
41882
|
const relPath = `${rel}/${name}`.replace(/\\/g, "/");
|
|
41419
41883
|
skills2.push({ name, relPath });
|
|
41420
41884
|
}
|
|
@@ -41423,7 +41887,7 @@ async function discoverSkillLayoutRootsAsync(cwd) {
|
|
|
41423
41887
|
let work = 0;
|
|
41424
41888
|
for (const rel of SKILL_DISCOVERY_ROOTS) {
|
|
41425
41889
|
await yieldSkillDiscoveryWork(++work);
|
|
41426
|
-
const base =
|
|
41890
|
+
const base = path63.join(cwd, rel);
|
|
41427
41891
|
if (!fs41.existsSync(base) || !fs41.statSync(base).isDirectory()) continue;
|
|
41428
41892
|
let entries = [];
|
|
41429
41893
|
try {
|
|
@@ -41775,7 +42239,7 @@ import fs43 from "node:fs";
|
|
|
41775
42239
|
|
|
41776
42240
|
// src/git/snapshot/capture.ts
|
|
41777
42241
|
import * as fs42 from "node:fs";
|
|
41778
|
-
import * as
|
|
42242
|
+
import * as path64 from "node:path";
|
|
41779
42243
|
|
|
41780
42244
|
// src/git/snapshot/git.ts
|
|
41781
42245
|
async function gitStashCreate(repoRoot, log2) {
|
|
@@ -41815,7 +42279,7 @@ async function gitRun(repoRoot, args, log2, label) {
|
|
|
41815
42279
|
async function resolveSnapshotRepoRoots(options) {
|
|
41816
42280
|
const { worktreePaths, fallbackCwd, sessionId, log: log2 } = options;
|
|
41817
42281
|
if (worktreePaths?.length) {
|
|
41818
|
-
const uniq = [...new Set(worktreePaths.map((p) =>
|
|
42282
|
+
const uniq = [...new Set(worktreePaths.map((p) => path64.resolve(p)))];
|
|
41819
42283
|
return uniq;
|
|
41820
42284
|
}
|
|
41821
42285
|
try {
|
|
@@ -41823,7 +42287,7 @@ async function resolveSnapshotRepoRoots(options) {
|
|
|
41823
42287
|
const mapped = repos.map((r) => r.absolutePath);
|
|
41824
42288
|
const sid = sessionId?.trim();
|
|
41825
42289
|
if (sid) {
|
|
41826
|
-
const filtered = mapped.filter((root) =>
|
|
42290
|
+
const filtered = mapped.filter((root) => path64.basename(root) === sid);
|
|
41827
42291
|
if (filtered.length > 0) return filtered;
|
|
41828
42292
|
}
|
|
41829
42293
|
return mapped;
|
|
@@ -41854,7 +42318,7 @@ async function capturePreTurnSnapshot(options) {
|
|
|
41854
42318
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
41855
42319
|
repos
|
|
41856
42320
|
};
|
|
41857
|
-
const filePath =
|
|
42321
|
+
const filePath = path64.join(dir, `${runId}.json`);
|
|
41858
42322
|
try {
|
|
41859
42323
|
fs42.writeFileSync(filePath, JSON.stringify(payload, null, 2), "utf8");
|
|
41860
42324
|
} catch (e) {
|
|
@@ -42197,9 +42661,9 @@ function parseChangeSummarySnapshots(raw) {
|
|
|
42197
42661
|
for (const item of raw) {
|
|
42198
42662
|
if (!item || typeof item !== "object") continue;
|
|
42199
42663
|
const o = item;
|
|
42200
|
-
const
|
|
42201
|
-
if (!
|
|
42202
|
-
const row = { path:
|
|
42664
|
+
const path74 = typeof o.path === "string" && o.path.trim() !== "" ? o.path.trim() : "";
|
|
42665
|
+
if (!path74) continue;
|
|
42666
|
+
const row = { path: path74 };
|
|
42203
42667
|
if (typeof o.patchContent === "string") row.patchContent = o.patchContent;
|
|
42204
42668
|
if (typeof o.oldText === "string") row.oldText = o.oldText;
|
|
42205
42669
|
if (typeof o.newText === "string") row.newText = o.newText;
|
|
@@ -42278,7 +42742,8 @@ async function runPreambleAndPrompt(params) {
|
|
|
42278
42742
|
cloudApiBaseUrl: deps.cloudApiBaseUrl,
|
|
42279
42743
|
getCloudAccessToken: deps.getCloudAccessToken,
|
|
42280
42744
|
e2ee: deps.e2ee,
|
|
42281
|
-
...attachments.length > 0 ? { attachments } : {}
|
|
42745
|
+
...attachments.length > 0 ? { attachments } : {},
|
|
42746
|
+
isNewSession: msg.isNewSession === true
|
|
42282
42747
|
});
|
|
42283
42748
|
}
|
|
42284
42749
|
|
|
@@ -42427,11 +42892,11 @@ async function resolveFileBrowserSessionParent(sessionWorktreeManager, sessionId
|
|
|
42427
42892
|
import fs45 from "node:fs";
|
|
42428
42893
|
|
|
42429
42894
|
// src/files/ensure-under-cwd.ts
|
|
42430
|
-
import
|
|
42895
|
+
import path65 from "node:path";
|
|
42431
42896
|
function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
42432
|
-
const normalized =
|
|
42433
|
-
const resolved =
|
|
42434
|
-
if (!resolved.startsWith(cwd +
|
|
42897
|
+
const normalized = path65.normalize(relativePath).replace(/^(\.\/)+/, "");
|
|
42898
|
+
const resolved = path65.resolve(cwd, normalized);
|
|
42899
|
+
if (!resolved.startsWith(cwd + path65.sep) && resolved !== cwd) {
|
|
42435
42900
|
return null;
|
|
42436
42901
|
}
|
|
42437
42902
|
return resolved;
|
|
@@ -42441,11 +42906,11 @@ function ensureUnderCwd(relativePath, cwd = getBridgeRoot()) {
|
|
|
42441
42906
|
var LIST_DIR_YIELD_EVERY = 256;
|
|
42442
42907
|
|
|
42443
42908
|
// src/files/list-dir/map-dir-entry.ts
|
|
42444
|
-
import
|
|
42909
|
+
import path66 from "node:path";
|
|
42445
42910
|
import fs44 from "node:fs";
|
|
42446
42911
|
async function mapDirEntry(d, relativePath, resolved) {
|
|
42447
|
-
const entryPath =
|
|
42448
|
-
const fullPath =
|
|
42912
|
+
const entryPath = path66.join(relativePath || ".", d.name).replace(/\\/g, "/");
|
|
42913
|
+
const fullPath = path66.join(resolved, d.name);
|
|
42449
42914
|
let isDir = d.isDirectory();
|
|
42450
42915
|
if (d.isSymbolicLink()) {
|
|
42451
42916
|
try {
|
|
@@ -42495,13 +42960,13 @@ async function listDirAsync(relativePath, sessionParentPath = getBridgeRoot()) {
|
|
|
42495
42960
|
}
|
|
42496
42961
|
|
|
42497
42962
|
// src/files/handle-file-browser-search.ts
|
|
42498
|
-
import
|
|
42963
|
+
import path67 from "node:path";
|
|
42499
42964
|
var SEARCH_LIMIT = 100;
|
|
42500
42965
|
function handleFileBrowserSearch(msg, socket, e2ee, sessionWorktreeManager) {
|
|
42501
42966
|
void (async () => {
|
|
42502
42967
|
await yieldToEventLoop();
|
|
42503
42968
|
const q = typeof msg.q === "string" ? msg.q : "";
|
|
42504
|
-
const sessionParentPath =
|
|
42969
|
+
const sessionParentPath = path67.resolve(
|
|
42505
42970
|
sessionWorktreeManager != null ? await resolveFileBrowserSessionParent(sessionWorktreeManager, msg.sessionId) : getBridgeRoot()
|
|
42506
42971
|
);
|
|
42507
42972
|
if (!await bridgeFileIndexIsPopulated(sessionParentPath)) {
|
|
@@ -42711,13 +43176,13 @@ function triggerSymbolIndexBuild(parentPath) {
|
|
|
42711
43176
|
}
|
|
42712
43177
|
|
|
42713
43178
|
// src/git/tree/resolve-repo-abs-path.ts
|
|
42714
|
-
import * as
|
|
43179
|
+
import * as path68 from "node:path";
|
|
42715
43180
|
function resolveRepoAbsPathFromBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
42716
|
-
const bridgeResolved =
|
|
43181
|
+
const bridgeResolved = path68.resolve(bridgeRoot);
|
|
42717
43182
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
42718
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
42719
|
-
const resolved =
|
|
42720
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
43183
|
+
const repoPath = rel === "" ? bridgeResolved : path68.join(bridgeResolved, rel);
|
|
43184
|
+
const resolved = path68.resolve(repoPath);
|
|
43185
|
+
if (!resolved.startsWith(bridgeResolved + path68.sep) && resolved !== bridgeResolved) {
|
|
42721
43186
|
return null;
|
|
42722
43187
|
}
|
|
42723
43188
|
return resolved;
|
|
@@ -43500,7 +43965,7 @@ function isValidRemoteSkillInstallItem(item) {
|
|
|
43500
43965
|
|
|
43501
43966
|
// src/skills/install/install-remote-skills-async.ts
|
|
43502
43967
|
import fs49 from "node:fs";
|
|
43503
|
-
import
|
|
43968
|
+
import path69 from "node:path";
|
|
43504
43969
|
|
|
43505
43970
|
// src/skills/install/constants.ts
|
|
43506
43971
|
var INSTALL_SKILLS_YIELD_EVERY = 16;
|
|
@@ -43511,8 +43976,8 @@ async function writeInstallFileAsync(skillDir, f, filesWritten) {
|
|
|
43511
43976
|
if (++filesWritten.count % INSTALL_SKILLS_YIELD_EVERY === 0) {
|
|
43512
43977
|
await yieldToEventLoop();
|
|
43513
43978
|
}
|
|
43514
|
-
const dest =
|
|
43515
|
-
await fs49.promises.mkdir(
|
|
43979
|
+
const dest = path69.join(skillDir, f.path);
|
|
43980
|
+
await fs49.promises.mkdir(path69.dirname(dest), { recursive: true });
|
|
43516
43981
|
if (f.text !== void 0) {
|
|
43517
43982
|
await fs49.promises.writeFile(dest, f.text, "utf8");
|
|
43518
43983
|
} else if (f.base64) {
|
|
@@ -43528,7 +43993,7 @@ async function installRemoteSkillsAsync(cwd, targetDir, items) {
|
|
|
43528
43993
|
try {
|
|
43529
43994
|
for (const item of items) {
|
|
43530
43995
|
if (!isValidRemoteSkillInstallItem(item)) continue;
|
|
43531
|
-
const skillDir =
|
|
43996
|
+
const skillDir = path69.join(cwd, targetDir, item.skillName);
|
|
43532
43997
|
for (const f of item.files) {
|
|
43533
43998
|
await writeInstallFileAsync(skillDir, f, filesWritten);
|
|
43534
43999
|
}
|
|
@@ -43867,7 +44332,7 @@ var handleDevServersConfig = (msg, deps) => {
|
|
|
43867
44332
|
};
|
|
43868
44333
|
|
|
43869
44334
|
// src/git/bridge-git-context.ts
|
|
43870
|
-
import * as
|
|
44335
|
+
import * as path70 from "node:path";
|
|
43871
44336
|
|
|
43872
44337
|
// src/git/branches/get-current-branch.ts
|
|
43873
44338
|
async function getCurrentBranch(repoPath) {
|
|
@@ -43917,12 +44382,12 @@ async function listRepoBranchRefs(repoPath) {
|
|
|
43917
44382
|
// src/git/bridge-git-context.ts
|
|
43918
44383
|
function folderNameForRelPath(relPath, bridgeRoot) {
|
|
43919
44384
|
if (relPath === "." || relPath === "") {
|
|
43920
|
-
return
|
|
44385
|
+
return path70.basename(path70.resolve(bridgeRoot)) || "repo";
|
|
43921
44386
|
}
|
|
43922
|
-
return
|
|
44387
|
+
return path70.basename(relPath) || relPath;
|
|
43923
44388
|
}
|
|
43924
44389
|
async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
43925
|
-
const root =
|
|
44390
|
+
const root = path70.resolve(bridgeRoot);
|
|
43926
44391
|
if (await isGitRepoDirectory(root)) {
|
|
43927
44392
|
const remoteUrl = await getRemoteOriginUrl(root);
|
|
43928
44393
|
return [{ absolutePath: root, remoteUrl }];
|
|
@@ -43930,19 +44395,19 @@ async function discoverGitReposForBridgeContext(bridgeRoot) {
|
|
|
43930
44395
|
const [deep, shallow] = await Promise.all([discoverGitReposUnderRoot(root), discoverGitRepos(root)]);
|
|
43931
44396
|
const byPath = /* @__PURE__ */ new Map();
|
|
43932
44397
|
for (const repo of [...deep, ...shallow]) {
|
|
43933
|
-
byPath.set(
|
|
44398
|
+
byPath.set(path70.resolve(repo.absolutePath), repo);
|
|
43934
44399
|
}
|
|
43935
44400
|
return [...byPath.values()];
|
|
43936
44401
|
}
|
|
43937
44402
|
async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
43938
|
-
const bridgeResolved =
|
|
44403
|
+
const bridgeResolved = path70.resolve(bridgeRoot);
|
|
43939
44404
|
const repos = await discoverGitReposForBridgeContext(bridgeResolved);
|
|
43940
44405
|
const rows = [];
|
|
43941
44406
|
for (let i = 0; i < repos.length; i++) {
|
|
43942
44407
|
if (i > 0) await yieldToEventLoop();
|
|
43943
44408
|
const repo = repos[i];
|
|
43944
|
-
let rel =
|
|
43945
|
-
if (rel.startsWith("..") ||
|
|
44409
|
+
let rel = path70.relative(bridgeResolved, repo.absolutePath);
|
|
44410
|
+
if (rel.startsWith("..") || path70.isAbsolute(rel)) continue;
|
|
43946
44411
|
const relPath = rel === "" ? "." : rel.replace(/\\/g, "/");
|
|
43947
44412
|
const currentBranch = await getCurrentBranch(repo.absolutePath);
|
|
43948
44413
|
const remoteUrl = repo.remoteUrl.trim() || null;
|
|
@@ -43957,11 +44422,11 @@ async function getBridgeGitContext(bridgeRoot = getBridgeRoot()) {
|
|
|
43957
44422
|
return rows;
|
|
43958
44423
|
}
|
|
43959
44424
|
async function listRepoBranchesForBridge(repoRelPath, bridgeRoot = getBridgeRoot()) {
|
|
43960
|
-
const bridgeResolved =
|
|
44425
|
+
const bridgeResolved = path70.resolve(bridgeRoot);
|
|
43961
44426
|
const rel = repoRelPath.trim() === "." ? "" : repoRelPath.trim().replace(/\\/g, "/");
|
|
43962
|
-
const repoPath = rel === "" ? bridgeResolved :
|
|
43963
|
-
const resolved =
|
|
43964
|
-
if (!resolved.startsWith(bridgeResolved +
|
|
44427
|
+
const repoPath = rel === "" ? bridgeResolved : path70.join(bridgeResolved, rel);
|
|
44428
|
+
const resolved = path70.resolve(repoPath);
|
|
44429
|
+
if (!resolved.startsWith(bridgeResolved + path70.sep) && resolved !== bridgeResolved) {
|
|
43965
44430
|
return [];
|
|
43966
44431
|
}
|
|
43967
44432
|
return listRepoBranchRefs(resolved);
|
|
@@ -44917,7 +45382,7 @@ async function createBridgeAccessState(options = {}) {
|
|
|
44917
45382
|
}
|
|
44918
45383
|
|
|
44919
45384
|
// src/agents/capabilities/warmup-agent-capabilities-on-connect.ts
|
|
44920
|
-
import * as
|
|
45385
|
+
import * as path72 from "node:path";
|
|
44921
45386
|
|
|
44922
45387
|
// src/sqlite/hash-json-sha256.ts
|
|
44923
45388
|
import { createHash } from "node:crypto";
|
|
@@ -44984,7 +45449,7 @@ function listCliAgentCapabilityCacheForWorkspace(db, workspaceId) {
|
|
|
44984
45449
|
}
|
|
44985
45450
|
|
|
44986
45451
|
// src/agents/capabilities/probe-one-agent-type-for-capabilities.ts
|
|
44987
|
-
import * as
|
|
45452
|
+
import * as path71 from "node:path";
|
|
44988
45453
|
async function probeOneAgentTypeForCapabilities(params) {
|
|
44989
45454
|
const { agentType, cwd, workspaceId, log: log2, reportAgentCapabilities, bridgeReport = true, shouldContinue } = params;
|
|
44990
45455
|
const canContinue = () => shouldContinue?.() !== false;
|
|
@@ -45022,7 +45487,7 @@ async function probeOneAgentTypeForCapabilities(params) {
|
|
|
45022
45487
|
if (!canContinue()) return false;
|
|
45023
45488
|
handle = await resolved.createClient({
|
|
45024
45489
|
command: resolved.command,
|
|
45025
|
-
cwd:
|
|
45490
|
+
cwd: path71.resolve(cwd),
|
|
45026
45491
|
backendAgentType: agentType,
|
|
45027
45492
|
sessionMode: "agent",
|
|
45028
45493
|
persistedAcpSessionId: null,
|
|
@@ -45100,7 +45565,7 @@ async function warmupAgentCapabilitiesOnConnect(params) {
|
|
|
45100
45565
|
const { workspaceId, log: log2, getWs } = params;
|
|
45101
45566
|
const isCurrent = beginAgentCapabilityWarmupRun();
|
|
45102
45567
|
if (!isCurrent()) return;
|
|
45103
|
-
const cwd =
|
|
45568
|
+
const cwd = path72.resolve(getBridgeRoot());
|
|
45104
45569
|
async function sendBatchFromCache() {
|
|
45105
45570
|
if (!isCurrent()) return;
|
|
45106
45571
|
const socket = getWs();
|
|
@@ -45335,8 +45800,8 @@ async function createBridgeConnection(options) {
|
|
|
45335
45800
|
getCloudAccessToken: () => tokens.accessToken
|
|
45336
45801
|
});
|
|
45337
45802
|
const identifyReportedPaths = {
|
|
45338
|
-
bridgeRootPath:
|
|
45339
|
-
worktreesRootPath:
|
|
45803
|
+
bridgeRootPath: path73.resolve(getBridgeRoot()),
|
|
45804
|
+
worktreesRootPath: path73.resolve(worktreesRootPath)
|
|
45340
45805
|
};
|
|
45341
45806
|
const { connect } = createMainBridgeWebSocketLifecycle({
|
|
45342
45807
|
state,
|