@cortexkit/aft-pi 0.38.0 → 0.39.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +694 -466
- package/dist/tools/_shared.d.ts +1 -17
- package/dist/tools/_shared.d.ts.map +1 -1
- package/dist/tools/ast.d.ts +3 -3
- package/dist/tools/bash.d.ts +12 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts +5 -5
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tools/reading.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -7728,10 +7728,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7728
7728
|
replacer = null;
|
|
7729
7729
|
indent = EMPTY;
|
|
7730
7730
|
};
|
|
7731
|
-
var
|
|
7731
|
+
var join10 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
|
|
7732
7732
|
var join_content = (inside, value, gap) => {
|
|
7733
7733
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
7734
|
-
return
|
|
7734
|
+
return join10(comment, inside, gap);
|
|
7735
7735
|
};
|
|
7736
7736
|
var stringify_string = (holder, key, value) => {
|
|
7737
7737
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -7753,13 +7753,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7753
7753
|
if (i !== 0) {
|
|
7754
7754
|
inside += COMMA;
|
|
7755
7755
|
}
|
|
7756
|
-
const before =
|
|
7756
|
+
const before = join10(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
7757
7757
|
inside += before || LF + deeper_gap;
|
|
7758
7758
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
7759
7759
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
7760
7760
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
7761
7761
|
}
|
|
7762
|
-
inside +=
|
|
7762
|
+
inside += join10(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7763
7763
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
7764
7764
|
};
|
|
7765
7765
|
var object_stringify = (value, gap) => {
|
|
@@ -7780,13 +7780,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7780
7780
|
inside += COMMA;
|
|
7781
7781
|
}
|
|
7782
7782
|
first = false;
|
|
7783
|
-
const before =
|
|
7783
|
+
const before = join10(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
7784
7784
|
inside += before || LF + deeper_gap;
|
|
7785
7785
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
7786
7786
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
7787
7787
|
};
|
|
7788
7788
|
keys.forEach(iteratee);
|
|
7789
|
-
inside +=
|
|
7789
|
+
inside += join10(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7790
7790
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
7791
7791
|
};
|
|
7792
7792
|
function stringify(key, holder, gap) {
|
|
@@ -11674,7 +11674,45 @@ function error(message, meta) {
|
|
|
11674
11674
|
console.error(`[aft-bridge] ERROR: ${message}`);
|
|
11675
11675
|
}
|
|
11676
11676
|
}
|
|
11677
|
+
// ../aft-bridge/dist/bash-format.js
|
|
11678
|
+
function appendPipeStripNote(output, note) {
|
|
11679
|
+
return note ? `${output}
|
|
11680
|
+
|
|
11681
|
+
${note}` : output;
|
|
11682
|
+
}
|
|
11683
|
+
function formatSeconds(ms) {
|
|
11684
|
+
return `${Number((ms / 1000).toFixed(1))}s`;
|
|
11685
|
+
}
|
|
11686
|
+
function formatForegroundResult(data) {
|
|
11687
|
+
const output = data.output_preview ?? "";
|
|
11688
|
+
const outputPath = data.output_path;
|
|
11689
|
+
const truncated = data.output_truncated === true;
|
|
11690
|
+
const status = data.status;
|
|
11691
|
+
const exit = data.exit_code;
|
|
11692
|
+
let rendered = output;
|
|
11693
|
+
if (truncated && outputPath) {
|
|
11694
|
+
rendered += `
|
|
11695
|
+
[output truncated; full output at ${outputPath}]`;
|
|
11696
|
+
}
|
|
11697
|
+
if (status === "timed_out") {
|
|
11698
|
+
rendered += `
|
|
11699
|
+
[command timed out]`;
|
|
11700
|
+
}
|
|
11701
|
+
if (typeof exit === "number" && exit !== 0) {
|
|
11702
|
+
rendered += `
|
|
11703
|
+
[exit code: ${exit}]`;
|
|
11704
|
+
}
|
|
11705
|
+
return rendered;
|
|
11706
|
+
}
|
|
11707
|
+
function isTerminalStatus(status) {
|
|
11708
|
+
return status === "completed" || status === "failed" || status === "killed" || status === "timed_out";
|
|
11709
|
+
}
|
|
11710
|
+
function sleep(ms) {
|
|
11711
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
11712
|
+
}
|
|
11677
11713
|
// ../aft-bridge/dist/bash-hints.js
|
|
11714
|
+
import * as os from "node:os";
|
|
11715
|
+
import * as path from "node:path";
|
|
11678
11716
|
var CONFLICT_HINT = `
|
|
11679
11717
|
|
|
11680
11718
|
[Hint] Use aft_conflicts to see all conflict regions across files in a single call.`;
|
|
@@ -11688,48 +11726,175 @@ function maybeAppendConflictsHint(output) {
|
|
|
11688
11726
|
return output;
|
|
11689
11727
|
return output + CONFLICT_HINT;
|
|
11690
11728
|
}
|
|
11691
|
-
function
|
|
11692
|
-
const
|
|
11693
|
-
if (
|
|
11694
|
-
return false;
|
|
11695
|
-
const afterCd = peelLeadingCdAnd(trimmed);
|
|
11696
|
-
if (afterCd === null)
|
|
11697
|
-
return false;
|
|
11698
|
-
const firstStage = firstPipelineStage(afterCd);
|
|
11699
|
-
if (firstStage === null)
|
|
11729
|
+
function commandInvokesCodeSearch(command) {
|
|
11730
|
+
const statements = splitTopLevelStatements(command);
|
|
11731
|
+
if (statements === null)
|
|
11700
11732
|
return false;
|
|
11701
|
-
const
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11733
|
+
for (const statement of statements) {
|
|
11734
|
+
const firstStage = firstPipelineStage(statement);
|
|
11735
|
+
if (firstStage === null)
|
|
11736
|
+
continue;
|
|
11737
|
+
const firstToken = readShellToken(firstStage, skipSpaces(firstStage, 0));
|
|
11738
|
+
if (firstToken === null)
|
|
11739
|
+
continue;
|
|
11740
|
+
if (firstToken.token === "grep" || firstToken.token === "rg")
|
|
11741
|
+
return true;
|
|
11742
|
+
}
|
|
11743
|
+
return false;
|
|
11705
11744
|
}
|
|
11706
|
-
function maybeAppendGrepSearchHint(output, command, aftSearchRegistered) {
|
|
11745
|
+
function maybeAppendGrepSearchHint(output, command, aftSearchRegistered, projectRoot) {
|
|
11707
11746
|
if (output === "")
|
|
11708
11747
|
return output;
|
|
11709
|
-
if (!
|
|
11748
|
+
if (!commandInvokesCodeSearch(command))
|
|
11710
11749
|
return output;
|
|
11711
11750
|
if (output.includes(GREP_SEARCH_HINT_PREFIX))
|
|
11712
11751
|
return output;
|
|
11752
|
+
if (shouldSuppressGrepSearchHint(command, projectRoot))
|
|
11753
|
+
return output;
|
|
11713
11754
|
const hint = aftSearchRegistered ? GREP_SEARCH_AFT_SEARCH_HINT : GREP_SEARCH_GREP_HINT;
|
|
11714
11755
|
return `${output}
|
|
11715
11756
|
|
|
11716
11757
|
${hint}`;
|
|
11717
11758
|
}
|
|
11718
|
-
function
|
|
11719
|
-
const
|
|
11720
|
-
if (
|
|
11721
|
-
return
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
11759
|
+
function shouldSuppressGrepSearchHint(command, projectRoot) {
|
|
11760
|
+
const root = projectRoot?.trim();
|
|
11761
|
+
if (!root)
|
|
11762
|
+
return false;
|
|
11763
|
+
const statements = splitTopLevelStatements(command);
|
|
11764
|
+
if (statements === null)
|
|
11765
|
+
return false;
|
|
11766
|
+
let sawCodeSearchStatement = false;
|
|
11767
|
+
for (const statement of statements) {
|
|
11768
|
+
const firstStage = firstPipelineStage(statement);
|
|
11769
|
+
if (firstStage === null)
|
|
11770
|
+
continue;
|
|
11771
|
+
const firstToken = readShellToken(firstStage, skipSpaces(firstStage, 0));
|
|
11772
|
+
if (firstToken === null)
|
|
11773
|
+
continue;
|
|
11774
|
+
if (firstToken.token !== "grep" && firstToken.token !== "rg")
|
|
11775
|
+
continue;
|
|
11776
|
+
sawCodeSearchStatement = true;
|
|
11777
|
+
const operands = collectPathOperands(firstStage, firstToken.end);
|
|
11778
|
+
if (operands.length === 0)
|
|
11779
|
+
return false;
|
|
11780
|
+
for (const operand of operands) {
|
|
11781
|
+
if (isPathInsideProject(root, operand))
|
|
11782
|
+
return false;
|
|
11783
|
+
}
|
|
11784
|
+
}
|
|
11785
|
+
return sawCodeSearchStatement;
|
|
11786
|
+
}
|
|
11787
|
+
function collectPathOperands(firstStage, startAfterCommand) {
|
|
11788
|
+
const operands = [];
|
|
11789
|
+
let index = skipSpaces(firstStage, startAfterCommand);
|
|
11790
|
+
while (index < firstStage.length) {
|
|
11791
|
+
const tokenResult = readShellToken(firstStage, index);
|
|
11792
|
+
if (tokenResult === null)
|
|
11793
|
+
break;
|
|
11794
|
+
const { token, end } = tokenResult;
|
|
11795
|
+
if (end <= index)
|
|
11796
|
+
break;
|
|
11797
|
+
index = skipSpaces(firstStage, end);
|
|
11798
|
+
if (token.startsWith("-"))
|
|
11799
|
+
continue;
|
|
11800
|
+
if (looksLikePathOperand(token))
|
|
11801
|
+
operands.push(token);
|
|
11802
|
+
}
|
|
11803
|
+
return operands;
|
|
11804
|
+
}
|
|
11805
|
+
function looksLikePathOperand(token) {
|
|
11806
|
+
return token.includes("/") || token.startsWith("~") || token.startsWith("./") || token.startsWith("../");
|
|
11807
|
+
}
|
|
11808
|
+
function expandTilde(target) {
|
|
11809
|
+
if (!target.startsWith("~"))
|
|
11810
|
+
return target;
|
|
11811
|
+
if (target === "~" || target.startsWith("~/")) {
|
|
11812
|
+
return path.join(os.homedir(), target.slice(1));
|
|
11813
|
+
}
|
|
11814
|
+
return target;
|
|
11815
|
+
}
|
|
11816
|
+
function resolvePathOperand(projectRoot, operand) {
|
|
11817
|
+
const expanded = expandTilde(operand);
|
|
11818
|
+
return path.isAbsolute(expanded) ? path.resolve(expanded) : path.resolve(projectRoot, expanded);
|
|
11819
|
+
}
|
|
11820
|
+
function isPathInsideProject(projectRoot, operand) {
|
|
11821
|
+
const root = path.resolve(projectRoot);
|
|
11822
|
+
const resolved = resolvePathOperand(root, operand);
|
|
11823
|
+
const rel = path.relative(root, resolved);
|
|
11824
|
+
return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
11825
|
+
}
|
|
11826
|
+
function splitTopLevelStatements(command) {
|
|
11827
|
+
const statements = [];
|
|
11828
|
+
let start = 0;
|
|
11829
|
+
let quote = "none";
|
|
11830
|
+
let escaped = false;
|
|
11831
|
+
let inBacktick = false;
|
|
11832
|
+
let parenDepth = 0;
|
|
11833
|
+
for (let index = 0;index < command.length; index++) {
|
|
11834
|
+
const ch = command[index];
|
|
11835
|
+
if (escaped) {
|
|
11836
|
+
escaped = false;
|
|
11837
|
+
continue;
|
|
11838
|
+
}
|
|
11839
|
+
if (quote === "single") {
|
|
11840
|
+
if (ch === "'")
|
|
11841
|
+
quote = "none";
|
|
11842
|
+
continue;
|
|
11843
|
+
}
|
|
11844
|
+
if (quote === "double") {
|
|
11845
|
+
if (ch === "\\")
|
|
11846
|
+
escaped = true;
|
|
11847
|
+
else if (ch === '"')
|
|
11848
|
+
quote = "none";
|
|
11849
|
+
continue;
|
|
11850
|
+
}
|
|
11851
|
+
if (inBacktick) {
|
|
11852
|
+
if (ch === "`")
|
|
11853
|
+
inBacktick = false;
|
|
11854
|
+
continue;
|
|
11855
|
+
}
|
|
11856
|
+
if (ch === "\\") {
|
|
11857
|
+
escaped = true;
|
|
11858
|
+
continue;
|
|
11859
|
+
}
|
|
11860
|
+
if (ch === "'") {
|
|
11861
|
+
quote = "single";
|
|
11862
|
+
continue;
|
|
11863
|
+
}
|
|
11864
|
+
if (ch === '"') {
|
|
11865
|
+
quote = "double";
|
|
11866
|
+
continue;
|
|
11867
|
+
}
|
|
11868
|
+
if (ch === "`") {
|
|
11869
|
+
inBacktick = true;
|
|
11870
|
+
continue;
|
|
11871
|
+
}
|
|
11872
|
+
if (ch === "(") {
|
|
11873
|
+
parenDepth++;
|
|
11874
|
+
continue;
|
|
11875
|
+
}
|
|
11876
|
+
if (ch === ")") {
|
|
11877
|
+
if (parenDepth > 0)
|
|
11878
|
+
parenDepth--;
|
|
11879
|
+
continue;
|
|
11880
|
+
}
|
|
11881
|
+
if (parenDepth > 0)
|
|
11882
|
+
continue;
|
|
11883
|
+
const next = command[index + 1];
|
|
11884
|
+
if (ch === "&" && next === "&" || ch === "|" && next === "|") {
|
|
11885
|
+
statements.push(command.slice(start, index));
|
|
11886
|
+
index++;
|
|
11887
|
+
start = index + 1;
|
|
11888
|
+
} else if (ch === ";" || ch === `
|
|
11889
|
+
` || ch === "&") {
|
|
11890
|
+
statements.push(command.slice(start, index));
|
|
11891
|
+
start = index + 1;
|
|
11892
|
+
}
|
|
11893
|
+
}
|
|
11894
|
+
if (quote !== "none" || inBacktick || escaped)
|
|
11726
11895
|
return null;
|
|
11727
|
-
|
|
11728
|
-
|
|
11729
|
-
const afterDir = skipSpaces(command, dir.end);
|
|
11730
|
-
if (!command.startsWith("&&", afterDir))
|
|
11731
|
-
return command;
|
|
11732
|
-
return command.slice(afterDir + 2).trim();
|
|
11896
|
+
statements.push(command.slice(start));
|
|
11897
|
+
return statements;
|
|
11733
11898
|
}
|
|
11734
11899
|
function firstPipelineStage(command) {
|
|
11735
11900
|
let quote = "none";
|
|
@@ -11837,8 +12002,8 @@ function resolveBashKillTimeout(modelTimeout, foregroundWaitMs) {
|
|
|
11837
12002
|
}
|
|
11838
12003
|
// ../aft-bridge/dist/bridge.js
|
|
11839
12004
|
import { spawn } from "node:child_process";
|
|
11840
|
-
import { homedir } from "node:os";
|
|
11841
|
-
import { join } from "node:path";
|
|
12005
|
+
import { homedir as homedir2 } from "node:os";
|
|
12006
|
+
import { join as join2 } from "node:path";
|
|
11842
12007
|
import { StringDecoder } from "node:string_decoder";
|
|
11843
12008
|
|
|
11844
12009
|
// ../aft-bridge/dist/command-timeouts.js
|
|
@@ -12211,7 +12376,7 @@ class BinaryBridge {
|
|
|
12211
12376
|
`;
|
|
12212
12377
|
const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
|
|
12213
12378
|
let requestSentAt = Date.now();
|
|
12214
|
-
const response = await new Promise((
|
|
12379
|
+
const response = await new Promise((resolve2, reject) => {
|
|
12215
12380
|
const timer = setTimeout(() => {
|
|
12216
12381
|
const entry = this.pending.get(id);
|
|
12217
12382
|
if (!entry)
|
|
@@ -12246,7 +12411,7 @@ class BinaryBridge {
|
|
|
12246
12411
|
entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
12247
12412
|
this.handleTimeout(requestSessionId);
|
|
12248
12413
|
}, effectiveTimeoutMs);
|
|
12249
|
-
this.pending.set(id, { resolve, reject, timer, onProgress: options?.onProgress, command });
|
|
12414
|
+
this.pending.set(id, { resolve: resolve2, reject, timer, onProgress: options?.onProgress, command });
|
|
12250
12415
|
if (!this.process?.stdin?.writable) {
|
|
12251
12416
|
this.pending.delete(id);
|
|
12252
12417
|
clearTimeout(timer);
|
|
@@ -12344,15 +12509,15 @@ class BinaryBridge {
|
|
|
12344
12509
|
if (this.process) {
|
|
12345
12510
|
const proc = this.process;
|
|
12346
12511
|
this.process = null;
|
|
12347
|
-
return new Promise((
|
|
12512
|
+
return new Promise((resolve2) => {
|
|
12348
12513
|
const forceKillTimer = setTimeout(() => {
|
|
12349
12514
|
proc.kill("SIGKILL");
|
|
12350
|
-
|
|
12515
|
+
resolve2();
|
|
12351
12516
|
}, 5000);
|
|
12352
12517
|
proc.once("exit", () => {
|
|
12353
12518
|
clearTimeout(forceKillTimer);
|
|
12354
12519
|
this.logVia("Process exited during shutdown");
|
|
12355
|
-
|
|
12520
|
+
resolve2();
|
|
12356
12521
|
});
|
|
12357
12522
|
proc.kill("SIGTERM");
|
|
12358
12523
|
});
|
|
@@ -12397,15 +12562,15 @@ class BinaryBridge {
|
|
|
12397
12562
|
return;
|
|
12398
12563
|
const proc = this.process;
|
|
12399
12564
|
this.process = null;
|
|
12400
|
-
await new Promise((
|
|
12565
|
+
await new Promise((resolve2) => {
|
|
12401
12566
|
const forceKillTimer = setTimeout(() => {
|
|
12402
12567
|
proc.kill("SIGKILL");
|
|
12403
|
-
|
|
12568
|
+
resolve2();
|
|
12404
12569
|
}, 5000);
|
|
12405
12570
|
proc.once("exit", () => {
|
|
12406
12571
|
clearTimeout(forceKillTimer);
|
|
12407
12572
|
this.logVia("Process exited during coordinated binary replacement");
|
|
12408
|
-
|
|
12573
|
+
resolve2();
|
|
12409
12574
|
});
|
|
12410
12575
|
proc.kill("SIGTERM");
|
|
12411
12576
|
});
|
|
@@ -12432,7 +12597,7 @@ class BinaryBridge {
|
|
|
12432
12597
|
})();
|
|
12433
12598
|
const useFastembedBackend = semanticBackend === undefined || semanticBackend === "fastembed" || semanticBackend === "";
|
|
12434
12599
|
const ortDir = typeof this.configOverrides._ort_dylib_dir === "string" && useFastembedBackend ? this.configOverrides._ort_dylib_dir : null;
|
|
12435
|
-
const ortLibraryPath = ortDir == null ? null :
|
|
12600
|
+
const ortLibraryPath = ortDir == null ? null : join2(ortDir, process.platform === "win32" ? "onnxruntime.dll" : process.platform === "darwin" ? "libonnxruntime.dylib" : "libonnxruntime.so");
|
|
12436
12601
|
const envPath = process.platform === "win32" && ortDir ? `${ortDir};${process.env.PATH ?? ""}` : process.env.PATH;
|
|
12437
12602
|
const env = {
|
|
12438
12603
|
...process.env,
|
|
@@ -12440,7 +12605,7 @@ class BinaryBridge {
|
|
|
12440
12605
|
};
|
|
12441
12606
|
this.logVia(`bridge.spawnProcess: useFastembedBackend=${useFastembedBackend}, ` + `parentORT=${process.env.ORT_DYLIB_PATH ?? "(unset)"}, ` + `ortLibraryPath=${ortLibraryPath ?? "(none)"}`);
|
|
12442
12607
|
if (useFastembedBackend) {
|
|
12443
|
-
env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ?
|
|
12608
|
+
env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ? join2(this.configOverrides.storage_dir, "semantic", "models") : join2(homedir2() || "", ".cache", "fastembed"));
|
|
12444
12609
|
if (process.env.ORT_DYLIB_PATH) {
|
|
12445
12610
|
this.logVia(`ORT_DYLIB_PATH inherited from parent env: ${process.env.ORT_DYLIB_PATH}`);
|
|
12446
12611
|
} else if (ortLibraryPath) {
|
|
@@ -12782,12 +12947,37 @@ function coerceStringArray(value) {
|
|
|
12782
12947
|
}
|
|
12783
12948
|
return [];
|
|
12784
12949
|
}
|
|
12950
|
+
function coerceOptionalInt(v, paramName, min, max) {
|
|
12951
|
+
if (v === undefined || v === null || v === "")
|
|
12952
|
+
return;
|
|
12953
|
+
if (typeof v === "number" && (!Number.isFinite(v) || v === 0 && min > 0))
|
|
12954
|
+
return;
|
|
12955
|
+
const n = typeof v === "string" ? Number(v) : v;
|
|
12956
|
+
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
12957
|
+
throw new Error(`${paramName} must be an integer between ${min} and ${max}`);
|
|
12958
|
+
}
|
|
12959
|
+
if (n < min || n > max) {
|
|
12960
|
+
throw new Error(`${paramName} must be between ${min} and ${max}`);
|
|
12961
|
+
}
|
|
12962
|
+
return n;
|
|
12963
|
+
}
|
|
12964
|
+
function isEmptyParam(value) {
|
|
12965
|
+
if (value === undefined || value === null)
|
|
12966
|
+
return true;
|
|
12967
|
+
if (typeof value === "string")
|
|
12968
|
+
return value.length === 0;
|
|
12969
|
+
if (Array.isArray(value))
|
|
12970
|
+
return value.length === 0;
|
|
12971
|
+
if (typeof value === "object")
|
|
12972
|
+
return Object.keys(value).length === 0;
|
|
12973
|
+
return false;
|
|
12974
|
+
}
|
|
12785
12975
|
// ../aft-bridge/dist/downloader.js
|
|
12786
12976
|
import { spawnSync } from "node:child_process";
|
|
12787
12977
|
import { createHash, randomUUID } from "node:crypto";
|
|
12788
12978
|
import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
|
|
12789
|
-
import { homedir as
|
|
12790
|
-
import { join as
|
|
12979
|
+
import { homedir as homedir3 } from "node:os";
|
|
12980
|
+
import { join as join3 } from "node:path";
|
|
12791
12981
|
import { Readable } from "node:stream";
|
|
12792
12982
|
import { pipeline } from "node:stream/promises";
|
|
12793
12983
|
|
|
@@ -12844,11 +13034,11 @@ function isExpectedCachedBinary(binaryPath, tag) {
|
|
|
12844
13034
|
function getCacheDir() {
|
|
12845
13035
|
if (process.platform === "win32") {
|
|
12846
13036
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
12847
|
-
const base2 = localAppData ||
|
|
12848
|
-
return
|
|
13037
|
+
const base2 = localAppData || join3(homedir3(), "AppData", "Local");
|
|
13038
|
+
return join3(base2, "aft", "bin");
|
|
12849
13039
|
}
|
|
12850
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
12851
|
-
return
|
|
13040
|
+
const base = process.env.XDG_CACHE_HOME || join3(homedir3(), ".cache");
|
|
13041
|
+
return join3(base, "aft", "bin");
|
|
12852
13042
|
}
|
|
12853
13043
|
function getBinaryName() {
|
|
12854
13044
|
return process.platform === "win32" ? "aft.exe" : "aft";
|
|
@@ -12856,7 +13046,7 @@ function getBinaryName() {
|
|
|
12856
13046
|
function getCachedBinaryPath(version) {
|
|
12857
13047
|
if (!version)
|
|
12858
13048
|
return null;
|
|
12859
|
-
const binaryPath =
|
|
13049
|
+
const binaryPath = join3(getCacheDir(), version, getBinaryName());
|
|
12860
13050
|
return existsSync(binaryPath) ? binaryPath : null;
|
|
12861
13051
|
}
|
|
12862
13052
|
async function downloadBinary(version) {
|
|
@@ -12873,16 +13063,16 @@ async function downloadBinary(version) {
|
|
|
12873
13063
|
return null;
|
|
12874
13064
|
}
|
|
12875
13065
|
const tag = rawTag.startsWith("v") ? rawTag : `v${rawTag}`;
|
|
12876
|
-
const versionedCacheDir =
|
|
13066
|
+
const versionedCacheDir = join3(getCacheDir(), tag);
|
|
12877
13067
|
const binaryName = getBinaryName();
|
|
12878
|
-
const binaryPath =
|
|
13068
|
+
const binaryPath = join3(versionedCacheDir, binaryName);
|
|
12879
13069
|
if (existsSync(binaryPath) && isExpectedCachedBinary(binaryPath, tag)) {
|
|
12880
13070
|
return binaryPath;
|
|
12881
13071
|
}
|
|
12882
13072
|
const downloadUrl = `https://github.com/${REPO}/releases/download/${tag}/${assetName}`;
|
|
12883
13073
|
const checksumUrl = `https://github.com/${REPO}/releases/download/${tag}/checksums.sha256`;
|
|
12884
13074
|
log(`Downloading AFT binary (${tag}) for ${platformKey}...`);
|
|
12885
|
-
const lockPath =
|
|
13075
|
+
const lockPath = join3(versionedCacheDir, ".download.lock");
|
|
12886
13076
|
let releaseLock = null;
|
|
12887
13077
|
let binaryController = null;
|
|
12888
13078
|
let checksumController = null;
|
|
@@ -13034,7 +13224,7 @@ async function acquireDownloadLock(lockPath) {
|
|
|
13034
13224
|
if (Date.now() - startedAt > DOWNLOAD_LOCK_TIMEOUT_MS) {
|
|
13035
13225
|
throw new Error(`Timed out waiting for download lock: ${lockPath}`);
|
|
13036
13226
|
}
|
|
13037
|
-
await new Promise((
|
|
13227
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
13038
13228
|
}
|
|
13039
13229
|
}
|
|
13040
13230
|
}
|
|
@@ -13127,18 +13317,18 @@ function stripJsoncSymbols(value) {
|
|
|
13127
13317
|
// ../aft-bridge/dist/migration.js
|
|
13128
13318
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
13129
13319
|
import { existsSync as existsSync4, mkdirSync as mkdirSync4 } from "node:fs";
|
|
13130
|
-
import { homedir as
|
|
13131
|
-
import { dirname as dirname2, join as
|
|
13320
|
+
import { homedir as homedir5, tmpdir } from "node:os";
|
|
13321
|
+
import { dirname as dirname2, join as join6 } from "node:path";
|
|
13132
13322
|
|
|
13133
13323
|
// ../aft-bridge/dist/paths.js
|
|
13134
13324
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, writeFileSync } from "node:fs";
|
|
13135
|
-
import { dirname, join as
|
|
13325
|
+
import { dirname, join as join4 } from "node:path";
|
|
13136
13326
|
function resolveHarnessStoragePath(storageRoot, harness, ...segments) {
|
|
13137
|
-
return
|
|
13327
|
+
return join4(storageRoot, harness, ...segments);
|
|
13138
13328
|
}
|
|
13139
13329
|
function repairRootScopedStorageFile(storageRoot, harness, fileName) {
|
|
13140
13330
|
const harnessPath = resolveHarnessStoragePath(storageRoot, harness, fileName);
|
|
13141
|
-
const rootPath =
|
|
13331
|
+
const rootPath = join4(storageRoot, fileName);
|
|
13142
13332
|
if (existsSync2(harnessPath) || !existsSync2(rootPath))
|
|
13143
13333
|
return harnessPath;
|
|
13144
13334
|
try {
|
|
@@ -13184,8 +13374,8 @@ function markAnnouncementSeen(storageRoot, harness, currentVersion) {
|
|
|
13184
13374
|
import { execSync } from "node:child_process";
|
|
13185
13375
|
import { chmodSync as chmodSync2, closeSync as closeSync2, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, openSync as openSync2, readSync, renameSync as renameSync3, unlinkSync as unlinkSync2 } from "node:fs";
|
|
13186
13376
|
import { createRequire as createRequire2 } from "node:module";
|
|
13187
|
-
import { homedir as
|
|
13188
|
-
import { join as
|
|
13377
|
+
import { homedir as homedir4 } from "node:os";
|
|
13378
|
+
import { join as join5 } from "node:path";
|
|
13189
13379
|
var ensureBinaryForResolver = ensureBinary;
|
|
13190
13380
|
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
13191
13381
|
try {
|
|
@@ -13194,9 +13384,9 @@ function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
|
13194
13384
|
return null;
|
|
13195
13385
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
13196
13386
|
const cacheDir = getCacheDir();
|
|
13197
|
-
const versionedDir =
|
|
13387
|
+
const versionedDir = join5(cacheDir, tag);
|
|
13198
13388
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
13199
|
-
const cachedPath =
|
|
13389
|
+
const cachedPath = join5(versionedDir, `aft${ext}`);
|
|
13200
13390
|
if (existsSync3(cachedPath)) {
|
|
13201
13391
|
const cachedVersion = readBinaryVersion(cachedPath);
|
|
13202
13392
|
if (cachedVersion === version)
|
|
@@ -13226,18 +13416,18 @@ function normalizeBareVersion(version) {
|
|
|
13226
13416
|
return version.startsWith("v") ? version.slice(1) : version;
|
|
13227
13417
|
}
|
|
13228
13418
|
function homeDirFromEnv(env) {
|
|
13229
|
-
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) ||
|
|
13419
|
+
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir4();
|
|
13230
13420
|
}
|
|
13231
13421
|
function cacheDirFromEnv(env) {
|
|
13232
13422
|
if (process.platform === "win32") {
|
|
13233
|
-
const base2 = env.LOCALAPPDATA || env.APPDATA ||
|
|
13234
|
-
return
|
|
13423
|
+
const base2 = env.LOCALAPPDATA || env.APPDATA || join5(homeDirFromEnv(env), "AppData", "Local");
|
|
13424
|
+
return join5(base2, "aft", "bin");
|
|
13235
13425
|
}
|
|
13236
|
-
const base = env.XDG_CACHE_HOME ||
|
|
13237
|
-
return
|
|
13426
|
+
const base = env.XDG_CACHE_HOME || join5(homeDirFromEnv(env), ".cache");
|
|
13427
|
+
return join5(base, "aft", "bin");
|
|
13238
13428
|
}
|
|
13239
13429
|
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
13240
|
-
const binaryPath =
|
|
13430
|
+
const binaryPath = join5(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
13241
13431
|
return existsSync3(binaryPath) ? binaryPath : null;
|
|
13242
13432
|
}
|
|
13243
13433
|
function isExpectedCachedBinary2(binaryPath, expectedVersion) {
|
|
@@ -13356,7 +13546,7 @@ function findBinarySync(expectedVersion) {
|
|
|
13356
13546
|
return usable;
|
|
13357
13547
|
}
|
|
13358
13548
|
} catch {}
|
|
13359
|
-
const cargoPath =
|
|
13549
|
+
const cargoPath = join5(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
13360
13550
|
if (existsSync3(cargoPath)) {
|
|
13361
13551
|
const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
|
|
13362
13552
|
if (usable)
|
|
@@ -13402,22 +13592,22 @@ function dataHome() {
|
|
|
13402
13592
|
if (process.env.XDG_DATA_HOME)
|
|
13403
13593
|
return process.env.XDG_DATA_HOME;
|
|
13404
13594
|
if (process.platform === "win32") {
|
|
13405
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA ||
|
|
13595
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join6(homeDir(), "AppData", "Local");
|
|
13406
13596
|
}
|
|
13407
|
-
return
|
|
13597
|
+
return join6(homeDir(), ".local", "share");
|
|
13408
13598
|
}
|
|
13409
13599
|
function homeDir() {
|
|
13410
13600
|
if (process.platform === "win32")
|
|
13411
|
-
return process.env.USERPROFILE || process.env.HOME ||
|
|
13412
|
-
return process.env.HOME ||
|
|
13601
|
+
return process.env.USERPROFILE || process.env.HOME || homedir5();
|
|
13602
|
+
return process.env.HOME || homedir5();
|
|
13413
13603
|
}
|
|
13414
13604
|
function resolveLegacyStorageRoot(harness) {
|
|
13415
13605
|
if (harness === "pi")
|
|
13416
|
-
return
|
|
13417
|
-
return
|
|
13606
|
+
return join6(homeDir(), ".pi", "agent", "aft");
|
|
13607
|
+
return join6(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
13418
13608
|
}
|
|
13419
13609
|
function resolveCortexKitStorageRoot() {
|
|
13420
|
-
return
|
|
13610
|
+
return join6(dataHome(), "cortexkit", "aft");
|
|
13421
13611
|
}
|
|
13422
13612
|
function tail(value) {
|
|
13423
13613
|
if (!value)
|
|
@@ -13431,12 +13621,12 @@ function spawnErrorLabel(error2) {
|
|
|
13431
13621
|
return [code, error2.message].filter(Boolean).join(": ");
|
|
13432
13622
|
}
|
|
13433
13623
|
function migrationLogPath(newRoot, harness, logger) {
|
|
13434
|
-
const desired =
|
|
13624
|
+
const desired = join6(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
13435
13625
|
try {
|
|
13436
13626
|
mkdirSync4(dirname2(desired), { recursive: true });
|
|
13437
13627
|
return desired;
|
|
13438
13628
|
} catch (err) {
|
|
13439
|
-
const fallback =
|
|
13629
|
+
const fallback = join6(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
13440
13630
|
logger?.warn?.(`Failed to create AFT migration log directory ${dirname2(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
13441
13631
|
return fallback;
|
|
13442
13632
|
}
|
|
@@ -13499,13 +13689,13 @@ async function ensureStorageMigrated(opts) {
|
|
|
13499
13689
|
}
|
|
13500
13690
|
// ../aft-bridge/dist/npm-resolver.js
|
|
13501
13691
|
import { readdirSync, statSync as statSync2 } from "node:fs";
|
|
13502
|
-
import { homedir as
|
|
13503
|
-
import { delimiter, dirname as dirname3, isAbsolute, join as
|
|
13692
|
+
import { homedir as homedir6 } from "node:os";
|
|
13693
|
+
import { delimiter, dirname as dirname3, isAbsolute as isAbsolute2, join as join7 } from "node:path";
|
|
13504
13694
|
function defaultDeps() {
|
|
13505
13695
|
return {
|
|
13506
13696
|
platform: process.platform,
|
|
13507
13697
|
env: process.env,
|
|
13508
|
-
home:
|
|
13698
|
+
home: homedir6(),
|
|
13509
13699
|
execPath: process.execPath
|
|
13510
13700
|
};
|
|
13511
13701
|
}
|
|
@@ -13524,16 +13714,16 @@ function npmFromPath(deps) {
|
|
|
13524
13714
|
const raw = deps.env.PATH ?? deps.env.Path ?? "";
|
|
13525
13715
|
for (const entry of raw.split(delimiter)) {
|
|
13526
13716
|
const dir = entry.trim().replace(/^"|"$/g, "");
|
|
13527
|
-
if (!dir || !
|
|
13717
|
+
if (!dir || !isAbsolute2(dir))
|
|
13528
13718
|
continue;
|
|
13529
|
-
if (isFile(
|
|
13719
|
+
if (isFile(join7(dir, name)))
|
|
13530
13720
|
return dir;
|
|
13531
13721
|
}
|
|
13532
13722
|
return null;
|
|
13533
13723
|
}
|
|
13534
13724
|
function npmAdjacentToNode(deps) {
|
|
13535
13725
|
const dir = dirname3(deps.execPath);
|
|
13536
|
-
return isFile(
|
|
13726
|
+
return isFile(join7(dir, npmBinaryName(deps.platform))) ? dir : null;
|
|
13537
13727
|
}
|
|
13538
13728
|
function highestVersionedNodeBin(installsDir, name) {
|
|
13539
13729
|
let entries;
|
|
@@ -13542,8 +13732,8 @@ function highestVersionedNodeBin(installsDir, name) {
|
|
|
13542
13732
|
} catch {
|
|
13543
13733
|
return null;
|
|
13544
13734
|
}
|
|
13545
|
-
const candidates = entries.filter((v) => isFile(
|
|
13546
|
-
return candidates.length > 0 ?
|
|
13735
|
+
const candidates = entries.filter((v) => isFile(join7(installsDir, v, "bin", name))).sort((a, b) => compareVersionsDesc(a, b));
|
|
13736
|
+
return candidates.length > 0 ? join7(installsDir, candidates[0], "bin") : null;
|
|
13547
13737
|
}
|
|
13548
13738
|
function compareVersionsDesc(a, b) {
|
|
13549
13739
|
const pa = a.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
|
|
@@ -13568,22 +13758,22 @@ function wellKnownNpmDirs(deps) {
|
|
|
13568
13758
|
const programFiles = env.ProgramFiles || "C:\\Program Files";
|
|
13569
13759
|
const appData = env.APPDATA;
|
|
13570
13760
|
const localAppData = env.LOCALAPPDATA;
|
|
13571
|
-
push(
|
|
13761
|
+
push(join7(programFiles, "nodejs"));
|
|
13572
13762
|
if (appData)
|
|
13573
|
-
push(
|
|
13763
|
+
push(join7(appData, "npm"));
|
|
13574
13764
|
if (localAppData)
|
|
13575
|
-
push(
|
|
13765
|
+
push(join7(localAppData, "Volta", "bin"));
|
|
13576
13766
|
if (env.NVM_SYMLINK)
|
|
13577
13767
|
push(env.NVM_SYMLINK);
|
|
13578
13768
|
} else {
|
|
13579
13769
|
if (env.NVM_BIN)
|
|
13580
13770
|
push(env.NVM_BIN);
|
|
13581
|
-
push(highestVersionedNodeBin(
|
|
13582
|
-
push(highestVersionedNodeBin(
|
|
13583
|
-
push(highestVersionedNodeBin(
|
|
13584
|
-
push(
|
|
13585
|
-
push(
|
|
13586
|
-
const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin",
|
|
13771
|
+
push(highestVersionedNodeBin(join7(home, ".nvm", "versions", "node"), name));
|
|
13772
|
+
push(highestVersionedNodeBin(join7(home, ".local", "share", "mise", "installs", "node"), name));
|
|
13773
|
+
push(highestVersionedNodeBin(join7(home, ".asdf", "installs", "nodejs"), name));
|
|
13774
|
+
push(join7(home, ".volta", "bin"));
|
|
13775
|
+
push(join7(home, ".asdf", "shims"));
|
|
13776
|
+
const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin", join7(home, ".local", "bin")]);
|
|
13587
13777
|
for (const dir of systemDirs)
|
|
13588
13778
|
push(dir);
|
|
13589
13779
|
}
|
|
@@ -13593,12 +13783,12 @@ function resolveNpm(deps = defaultDeps()) {
|
|
|
13593
13783
|
const name = npmBinaryName(deps.platform);
|
|
13594
13784
|
const onPath = npmFromPath(deps);
|
|
13595
13785
|
if (onPath)
|
|
13596
|
-
return { command:
|
|
13786
|
+
return { command: join7(onPath, name), binDir: onPath };
|
|
13597
13787
|
const adjacent = npmAdjacentToNode(deps);
|
|
13598
13788
|
if (adjacent)
|
|
13599
|
-
return { command:
|
|
13789
|
+
return { command: join7(adjacent, name), binDir: adjacent };
|
|
13600
13790
|
for (const dir of wellKnownNpmDirs(deps)) {
|
|
13601
|
-
const candidate =
|
|
13791
|
+
const candidate = join7(dir, name);
|
|
13602
13792
|
if (isFile(candidate))
|
|
13603
13793
|
return { command: candidate, binDir: dir };
|
|
13604
13794
|
}
|
|
@@ -13615,7 +13805,7 @@ function npmSpawnEnv(resolved, baseEnv = process.env) {
|
|
|
13615
13805
|
import { execFileSync } from "node:child_process";
|
|
13616
13806
|
import { createHash as createHash2 } from "node:crypto";
|
|
13617
13807
|
import { chmodSync as chmodSync3, closeSync as closeSync3, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, openSync as openSync3, readdirSync as readdirSync2, readFileSync as readFileSync3, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync3, symlinkSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
13618
|
-
import { basename, dirname as dirname4, isAbsolute as
|
|
13808
|
+
import { basename, dirname as dirname4, isAbsolute as isAbsolute3, join as join8, relative as relative2, resolve as resolve2, win32 } from "node:path";
|
|
13619
13809
|
import { Readable as Readable2 } from "node:stream";
|
|
13620
13810
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
13621
13811
|
var ORT_VERSION = "1.24.4";
|
|
@@ -13678,10 +13868,10 @@ function getManualInstallHint() {
|
|
|
13678
13868
|
}
|
|
13679
13869
|
async function ensureOnnxRuntime(storageDir) {
|
|
13680
13870
|
const info = getPlatformInfo();
|
|
13681
|
-
const ortVersionDir =
|
|
13871
|
+
const ortVersionDir = join8(storageDir, "onnxruntime", ORT_VERSION);
|
|
13682
13872
|
const libName = info?.libName ?? "libonnxruntime.dylib";
|
|
13683
13873
|
const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
|
|
13684
|
-
const libPath =
|
|
13874
|
+
const libPath = join8(resolvedOrtDir, libName);
|
|
13685
13875
|
if (existsSync5(libPath)) {
|
|
13686
13876
|
const meta = readOnnxInstalledMeta(ortVersionDir);
|
|
13687
13877
|
if (meta?.sha256) {
|
|
@@ -13711,9 +13901,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
13711
13901
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
13712
13902
|
return null;
|
|
13713
13903
|
}
|
|
13714
|
-
const onnxBaseDir =
|
|
13904
|
+
const onnxBaseDir = join8(storageDir, "onnxruntime");
|
|
13715
13905
|
mkdirSync5(onnxBaseDir, { recursive: true });
|
|
13716
|
-
const lockPath =
|
|
13906
|
+
const lockPath = join8(onnxBaseDir, ONNX_LOCK_FILE);
|
|
13717
13907
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
13718
13908
|
if (!acquireLock(lockPath)) {
|
|
13719
13909
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -13732,7 +13922,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
13732
13922
|
for (const entry of entries) {
|
|
13733
13923
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
13734
13924
|
continue;
|
|
13735
|
-
const stagingDir =
|
|
13925
|
+
const stagingDir = join8(onnxBaseDir, entry);
|
|
13736
13926
|
const parts = entry.split(".");
|
|
13737
13927
|
const pidStr = parts[parts.length - 2];
|
|
13738
13928
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -13769,7 +13959,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
13769
13959
|
}
|
|
13770
13960
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
13771
13961
|
try {
|
|
13772
|
-
if (existsSync5(ortDir) && !existsSync5(
|
|
13962
|
+
if (existsSync5(ortDir) && !existsSync5(join8(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
13773
13963
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
13774
13964
|
rmSync2(ortDir, { recursive: true, force: true });
|
|
13775
13965
|
}
|
|
@@ -13797,8 +13987,8 @@ function parseOnnxVersionFromDirectoryPath(value) {
|
|
|
13797
13987
|
return null;
|
|
13798
13988
|
}
|
|
13799
13989
|
function isPathInsideRoot(root, candidate) {
|
|
13800
|
-
const rel =
|
|
13801
|
-
return rel === "" || !rel.startsWith("../") && !rel.startsWith("..\\") && rel !== ".." && !
|
|
13990
|
+
const rel = relative2(root, candidate);
|
|
13991
|
+
return rel === "" || !rel.startsWith("../") && !rel.startsWith("..\\") && rel !== ".." && !isAbsolute3(rel) && !win32.isAbsolute(rel);
|
|
13802
13992
|
}
|
|
13803
13993
|
function detectOnnxVersion(libDir, libName) {
|
|
13804
13994
|
try {
|
|
@@ -13813,7 +14003,7 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
13813
14003
|
if (version)
|
|
13814
14004
|
return version;
|
|
13815
14005
|
}
|
|
13816
|
-
const base =
|
|
14006
|
+
const base = join8(libDir, libName);
|
|
13817
14007
|
if (existsSync5(base)) {
|
|
13818
14008
|
try {
|
|
13819
14009
|
const real = realpathSync(base);
|
|
@@ -13849,7 +14039,7 @@ function pathEntriesForPlatform() {
|
|
|
13849
14039
|
return pathEnvValue().split(delimiter2).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter((entry) => {
|
|
13850
14040
|
if (!entry || entry === "." || entry.includes("\x00"))
|
|
13851
14041
|
return false;
|
|
13852
|
-
return
|
|
14042
|
+
return isAbsolute3(entry) || win32.isAbsolute(entry);
|
|
13853
14043
|
});
|
|
13854
14044
|
}
|
|
13855
14045
|
function directoryContainsLibrary(dir, libName) {
|
|
@@ -13865,10 +14055,10 @@ function directoryContainsLibrary(dir, libName) {
|
|
|
13865
14055
|
}
|
|
13866
14056
|
}
|
|
13867
14057
|
function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
|
|
13868
|
-
if (existsSync5(
|
|
14058
|
+
if (existsSync5(join8(ortVersionDir, libName)))
|
|
13869
14059
|
return ortVersionDir;
|
|
13870
|
-
const libSubdir =
|
|
13871
|
-
if (existsSync5(
|
|
14060
|
+
const libSubdir = join8(ortVersionDir, "lib");
|
|
14061
|
+
if (existsSync5(join8(libSubdir, libName)))
|
|
13872
14062
|
return libSubdir;
|
|
13873
14063
|
return ortVersionDir;
|
|
13874
14064
|
}
|
|
@@ -13883,12 +14073,12 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13883
14073
|
} else if (process.platform === "win32") {
|
|
13884
14074
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
13885
14075
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
13886
|
-
searchPaths.push(
|
|
14076
|
+
searchPaths.push(join8(programFiles, "onnxruntime", "lib"), join8(programFiles, "Microsoft ONNX Runtime", "lib"), join8(programFiles, "Microsoft Machine Learning", "lib"), join8(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
13887
14077
|
const nugetPaths = [];
|
|
13888
14078
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
13889
14079
|
if (!userProfile)
|
|
13890
14080
|
return nugetPaths;
|
|
13891
|
-
const nugetPackageDir =
|
|
14081
|
+
const nugetPackageDir = join8(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
13892
14082
|
if (!existsSync5(nugetPackageDir))
|
|
13893
14083
|
return nugetPaths;
|
|
13894
14084
|
try {
|
|
@@ -13897,7 +14087,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13897
14087
|
continue;
|
|
13898
14088
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
13899
14089
|
continue;
|
|
13900
|
-
nugetPaths.push(
|
|
14090
|
+
nugetPaths.push(join8(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join8(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
13901
14091
|
}
|
|
13902
14092
|
} catch (err) {
|
|
13903
14093
|
warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -13909,7 +14099,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13909
14099
|
const normalizeCase = process.platform === "win32" || process.platform === "darwin";
|
|
13910
14100
|
const seen = new Set;
|
|
13911
14101
|
const uniquePaths = searchPaths.filter((p) => {
|
|
13912
|
-
let key =
|
|
14102
|
+
let key = resolve2(p).replace(/[/\\]+$/, "");
|
|
13913
14103
|
if (normalizeCase)
|
|
13914
14104
|
key = key.toLowerCase();
|
|
13915
14105
|
if (seen.has(key))
|
|
@@ -13919,7 +14109,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13919
14109
|
});
|
|
13920
14110
|
const unknownVersionPaths = [];
|
|
13921
14111
|
for (const dir of uniquePaths) {
|
|
13922
|
-
const libPath =
|
|
14112
|
+
const libPath = join8(dir, libName);
|
|
13923
14113
|
if (process.platform === "win32") {
|
|
13924
14114
|
if (!directoryContainsLibrary(dir, libName))
|
|
13925
14115
|
continue;
|
|
@@ -13985,19 +14175,19 @@ function validateExtractedTree(stagingRoot) {
|
|
|
13985
14175
|
const walk = (dir) => {
|
|
13986
14176
|
const entries = readdirSync2(dir);
|
|
13987
14177
|
for (const entry of entries) {
|
|
13988
|
-
const fullPath =
|
|
14178
|
+
const fullPath = join8(dir, entry);
|
|
13989
14179
|
const lst = lstatSync(fullPath);
|
|
13990
14180
|
if (lst.isSymbolicLink()) {
|
|
13991
14181
|
const linkTarget = readlinkSync(fullPath);
|
|
13992
|
-
const resolvedTarget =
|
|
13993
|
-
const rel2 =
|
|
13994
|
-
if (rel2.startsWith("..") ||
|
|
14182
|
+
const resolvedTarget = resolve2(dirname4(fullPath), linkTarget);
|
|
14183
|
+
const rel2 = relative2(realRoot, resolvedTarget);
|
|
14184
|
+
if (rel2.startsWith("..") || isAbsolute3(rel2) || win32.isAbsolute(rel2)) {
|
|
13995
14185
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
13996
14186
|
}
|
|
13997
14187
|
continue;
|
|
13998
14188
|
}
|
|
13999
|
-
const rel =
|
|
14000
|
-
if (rel.startsWith("..") ||
|
|
14189
|
+
const rel = relative2(realRoot, fullPath);
|
|
14190
|
+
if (rel.startsWith("..") || isAbsolute3(rel) || win32.isAbsolute(rel)) {
|
|
14001
14191
|
throw new Error(`extracted entry ${fullPath} escapes staging root`);
|
|
14002
14192
|
}
|
|
14003
14193
|
if (lst.isDirectory()) {
|
|
@@ -14020,7 +14210,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14020
14210
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
14021
14211
|
try {
|
|
14022
14212
|
mkdirSync5(tmpDir, { recursive: true });
|
|
14023
|
-
const archivePath =
|
|
14213
|
+
const archivePath = join8(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
14024
14214
|
await downloadFileWithCap(url, archivePath);
|
|
14025
14215
|
const archiveSha256 = sha256File(archivePath);
|
|
14026
14216
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -14036,7 +14226,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14036
14226
|
unlinkSync3(archivePath);
|
|
14037
14227
|
} catch {}
|
|
14038
14228
|
validateExtractedTree(tmpDir);
|
|
14039
|
-
const extractedDir =
|
|
14229
|
+
const extractedDir = join8(tmpDir, info.assetName, "lib");
|
|
14040
14230
|
if (!existsSync5(extractedDir)) {
|
|
14041
14231
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
14042
14232
|
}
|
|
@@ -14045,7 +14235,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14045
14235
|
const realFiles = [];
|
|
14046
14236
|
const symlinks = [];
|
|
14047
14237
|
for (const libFile of libFiles) {
|
|
14048
|
-
const src =
|
|
14238
|
+
const src = join8(extractedDir, libFile);
|
|
14049
14239
|
try {
|
|
14050
14240
|
const stat = lstatSync(src);
|
|
14051
14241
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -14060,7 +14250,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14060
14250
|
}
|
|
14061
14251
|
}
|
|
14062
14252
|
copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
|
|
14063
|
-
const libPath =
|
|
14253
|
+
const libPath = join8(targetDir, info.libName);
|
|
14064
14254
|
let libHash = null;
|
|
14065
14255
|
try {
|
|
14066
14256
|
libHash = sha256File(libPath);
|
|
@@ -14085,8 +14275,8 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14085
14275
|
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
|
|
14086
14276
|
const requiredLibs = new Set([info.libName]);
|
|
14087
14277
|
for (const libFile of realFiles) {
|
|
14088
|
-
const src =
|
|
14089
|
-
const dst =
|
|
14278
|
+
const src = join8(extractedDir, libFile);
|
|
14279
|
+
const dst = join8(targetDir, libFile);
|
|
14090
14280
|
try {
|
|
14091
14281
|
copyFile(src, dst);
|
|
14092
14282
|
if (process.platform !== "win32") {
|
|
@@ -14102,12 +14292,12 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
14102
14292
|
}
|
|
14103
14293
|
const targetRoot = realpathSync(targetDir);
|
|
14104
14294
|
for (const link of symlinks) {
|
|
14105
|
-
const dst =
|
|
14295
|
+
const dst = join8(targetDir, link.name);
|
|
14106
14296
|
try {
|
|
14107
14297
|
unlinkSync3(dst);
|
|
14108
14298
|
} catch {}
|
|
14109
|
-
const dstForContainment =
|
|
14110
|
-
const resolvedTarget =
|
|
14299
|
+
const dstForContainment = join8(targetRoot, link.name);
|
|
14300
|
+
const resolvedTarget = resolve2(dirname4(dstForContainment), link.target);
|
|
14111
14301
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
14112
14302
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
14113
14303
|
if (requiredLibs.has(link.name)) {
|
|
@@ -14127,7 +14317,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
14127
14317
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
14128
14318
|
}
|
|
14129
14319
|
}
|
|
14130
|
-
const requiredPath =
|
|
14320
|
+
const requiredPath = join8(targetDir, info.libName);
|
|
14131
14321
|
if (!existsSync5(requiredPath)) {
|
|
14132
14322
|
rmSync2(targetDir, { recursive: true, force: true });
|
|
14133
14323
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
@@ -14154,17 +14344,17 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
14154
14344
|
...sha256 ? { sha256 } : {},
|
|
14155
14345
|
archiveSha256
|
|
14156
14346
|
};
|
|
14157
|
-
writeFileSync2(
|
|
14347
|
+
writeFileSync2(join8(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
14158
14348
|
} catch (err) {
|
|
14159
14349
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
14160
14350
|
}
|
|
14161
14351
|
}
|
|
14162
14352
|
function readOnnxInstalledMeta(installDir) {
|
|
14163
|
-
const
|
|
14353
|
+
const path2 = join8(installDir, ONNX_INSTALLED_META_FILE);
|
|
14164
14354
|
try {
|
|
14165
|
-
if (!statSync3(
|
|
14355
|
+
if (!statSync3(path2).isFile())
|
|
14166
14356
|
return null;
|
|
14167
|
-
const raw = readFileSync3(
|
|
14357
|
+
const raw = readFileSync3(path2, "utf8");
|
|
14168
14358
|
const parsed = JSON.parse(raw);
|
|
14169
14359
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
14170
14360
|
return null;
|
|
@@ -14178,9 +14368,9 @@ function readOnnxInstalledMeta(installDir) {
|
|
|
14178
14368
|
return null;
|
|
14179
14369
|
}
|
|
14180
14370
|
}
|
|
14181
|
-
function sha256File(
|
|
14371
|
+
function sha256File(path2) {
|
|
14182
14372
|
const hash = createHash2("sha256");
|
|
14183
|
-
hash.update(readFileSync3(
|
|
14373
|
+
hash.update(readFileSync3(path2));
|
|
14184
14374
|
return hash.digest("hex");
|
|
14185
14375
|
}
|
|
14186
14376
|
function acquireLock(lockPath) {
|
|
@@ -14840,13 +15030,13 @@ function tokenizeStage(stage) {
|
|
|
14840
15030
|
}
|
|
14841
15031
|
// ../aft-bridge/dist/pool.js
|
|
14842
15032
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
14843
|
-
import { homedir as
|
|
15033
|
+
import { homedir as homedir7 } from "node:os";
|
|
14844
15034
|
var DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
14845
15035
|
var DEFAULT_MAX_POOL_SIZE = 8;
|
|
14846
15036
|
var CLEANUP_INTERVAL_MS = 60 * 1000;
|
|
14847
15037
|
function canonicalHomeDir() {
|
|
14848
15038
|
try {
|
|
14849
|
-
const home =
|
|
15039
|
+
const home = homedir7();
|
|
14850
15040
|
if (!home)
|
|
14851
15041
|
return null;
|
|
14852
15042
|
try {
|
|
@@ -15038,6 +15228,91 @@ function normalizeKey(projectRoot) {
|
|
|
15038
15228
|
return stripped;
|
|
15039
15229
|
}
|
|
15040
15230
|
}
|
|
15231
|
+
// ../aft-bridge/dist/tool-format.js
|
|
15232
|
+
function asPlainObject(value) {
|
|
15233
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
15234
|
+
return;
|
|
15235
|
+
return value;
|
|
15236
|
+
}
|
|
15237
|
+
function candidateLocation(candidate) {
|
|
15238
|
+
const file = typeof candidate.file === "string" && candidate.file.length > 0 ? candidate.file : undefined;
|
|
15239
|
+
if (!file)
|
|
15240
|
+
return;
|
|
15241
|
+
const line = typeof candidate.line === "number" && Number.isFinite(candidate.line) ? candidate.line : undefined;
|
|
15242
|
+
return line === undefined ? file : `${file}:${line}`;
|
|
15243
|
+
}
|
|
15244
|
+
function stringifyData(data) {
|
|
15245
|
+
if (data === undefined)
|
|
15246
|
+
return;
|
|
15247
|
+
try {
|
|
15248
|
+
return JSON.stringify(data, null, 2);
|
|
15249
|
+
} catch {
|
|
15250
|
+
return String(data);
|
|
15251
|
+
}
|
|
15252
|
+
}
|
|
15253
|
+
function formatBridgeErrorMessage(command, response, params = {}) {
|
|
15254
|
+
const code = typeof response.code === "string" && response.code.length > 0 ? response.code : undefined;
|
|
15255
|
+
const message = typeof response.message === "string" && response.message.length > 0 ? response.message : `${command} failed`;
|
|
15256
|
+
const data = asPlainObject(response.data);
|
|
15257
|
+
const rawCandidates = Array.isArray(response.candidates) ? response.candidates : Array.isArray(data?.candidates) ? data.candidates : undefined;
|
|
15258
|
+
const rawSymbol = typeof response.symbol === "string" && response.symbol.length > 0 ? response.symbol : typeof data?.symbol === "string" && data.symbol.length > 0 ? data.symbol : undefined;
|
|
15259
|
+
if (code === "ambiguous_target" || code === "target_symbol_not_in_file") {
|
|
15260
|
+
const candidates = (rawCandidates ?? []).map(asPlainObject).filter((candidate) => candidate !== undefined).map(candidateLocation).filter((candidate) => candidate !== undefined);
|
|
15261
|
+
if (candidates.length > 0) {
|
|
15262
|
+
const symbol = typeof params.toSymbol === "string" && params.toSymbol.length > 0 ? params.toSymbol : rawSymbol;
|
|
15263
|
+
const target = symbol ? `multiple symbols named "${symbol}"` : message.replace(/[.!?]+$/, "");
|
|
15264
|
+
const action = code === "ambiguous_target" ? "Pass toFile to disambiguate" : "Try one of these files for toFile";
|
|
15265
|
+
return `${command}: ${code} — ${target}. ${action}:
|
|
15266
|
+
${candidates.map((candidate) => ` - ${candidate}`).join(`
|
|
15267
|
+
`)}`;
|
|
15268
|
+
}
|
|
15269
|
+
}
|
|
15270
|
+
if (!code)
|
|
15271
|
+
return message;
|
|
15272
|
+
const lines = [`${command}: ${code} — ${message}`];
|
|
15273
|
+
const extras = collectStructuredExtras(response);
|
|
15274
|
+
if (extras)
|
|
15275
|
+
lines.push(`data: ${extras}`);
|
|
15276
|
+
return lines.join(`
|
|
15277
|
+
`);
|
|
15278
|
+
}
|
|
15279
|
+
function collectStructuredExtras(response) {
|
|
15280
|
+
const reserved = new Set([
|
|
15281
|
+
"id",
|
|
15282
|
+
"success",
|
|
15283
|
+
"code",
|
|
15284
|
+
"message",
|
|
15285
|
+
"data",
|
|
15286
|
+
"status_bar",
|
|
15287
|
+
"bg_completions"
|
|
15288
|
+
]);
|
|
15289
|
+
const extras = {};
|
|
15290
|
+
for (const [key, value] of Object.entries(response)) {
|
|
15291
|
+
if (reserved.has(key))
|
|
15292
|
+
continue;
|
|
15293
|
+
extras[key] = value;
|
|
15294
|
+
}
|
|
15295
|
+
if (Object.keys(extras).length === 0) {
|
|
15296
|
+
return stringifyData(response.data);
|
|
15297
|
+
}
|
|
15298
|
+
if (response.data !== undefined)
|
|
15299
|
+
extras.data = response.data;
|
|
15300
|
+
return stringifyData(extras);
|
|
15301
|
+
}
|
|
15302
|
+
function formatReadFooter(agentSpecifiedRange, data, options) {
|
|
15303
|
+
if (agentSpecifiedRange)
|
|
15304
|
+
return "";
|
|
15305
|
+
if (!data.truncated)
|
|
15306
|
+
return "";
|
|
15307
|
+
const startLine = data.start_line;
|
|
15308
|
+
const endLine = data.end_line;
|
|
15309
|
+
const totalLines = data.total_lines;
|
|
15310
|
+
if (startLine === undefined || endLine === undefined || totalLines === undefined) {
|
|
15311
|
+
return "";
|
|
15312
|
+
}
|
|
15313
|
+
return `
|
|
15314
|
+
(Showing lines ${startLine}-${endLine} of ${totalLines}. Use ${options.rangeHint} to read other sections.)`;
|
|
15315
|
+
}
|
|
15041
15316
|
// ../aft-bridge/dist/zoom-format.js
|
|
15042
15317
|
function formatZoomText(targetLabel, response) {
|
|
15043
15318
|
const range = response.range;
|
|
@@ -15118,13 +15393,36 @@ function formatZoomMultiTargetResult(entries) {
|
|
|
15118
15393
|
|
|
15119
15394
|
`) };
|
|
15120
15395
|
}
|
|
15396
|
+
function isRustZoomBatchEnvelope(response) {
|
|
15397
|
+
if (!Array.isArray(response.symbols) || response.symbols.length === 0) {
|
|
15398
|
+
return false;
|
|
15399
|
+
}
|
|
15400
|
+
return response.symbols.every((entry) => {
|
|
15401
|
+
if (!entry || typeof entry !== "object")
|
|
15402
|
+
return false;
|
|
15403
|
+
const row = entry;
|
|
15404
|
+
return typeof row.name === "string" && row.response !== undefined && row.response !== null;
|
|
15405
|
+
});
|
|
15406
|
+
}
|
|
15407
|
+
function unwrapRustZoomBatchEnvelope(response) {
|
|
15408
|
+
if (!isRustZoomBatchEnvelope(response)) {
|
|
15409
|
+
return null;
|
|
15410
|
+
}
|
|
15411
|
+
const names = [];
|
|
15412
|
+
const responses = [];
|
|
15413
|
+
for (const entry of response.symbols) {
|
|
15414
|
+
names.push(entry.name);
|
|
15415
|
+
responses.push(entry.response);
|
|
15416
|
+
}
|
|
15417
|
+
return { names, responses };
|
|
15418
|
+
}
|
|
15121
15419
|
// src/logger.ts
|
|
15122
15420
|
import * as fs from "node:fs";
|
|
15123
|
-
import * as
|
|
15124
|
-
import * as
|
|
15421
|
+
import * as os2 from "node:os";
|
|
15422
|
+
import * as path2 from "node:path";
|
|
15125
15423
|
var TAG = "[aft-pi]";
|
|
15126
15424
|
var isTestEnv = process.env.BUN_TEST === "1" || false;
|
|
15127
|
-
var logFile =
|
|
15425
|
+
var logFile = path2.join(os2.tmpdir(), isTestEnv ? "aft-pi-test.log" : "aft-pi.log");
|
|
15128
15426
|
var useStderr = process.env.AFT_LOG_STDERR === "1";
|
|
15129
15427
|
var buffer = [];
|
|
15130
15428
|
var flushTimer = null;
|
|
@@ -15760,7 +16058,7 @@ import {
|
|
|
15760
16058
|
// package.json
|
|
15761
16059
|
var package_default = {
|
|
15762
16060
|
name: "@cortexkit/aft-pi",
|
|
15763
|
-
version: "0.
|
|
16061
|
+
version: "0.39.1",
|
|
15764
16062
|
type: "module",
|
|
15765
16063
|
description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
|
|
15766
16064
|
main: "dist/index.js",
|
|
@@ -15783,7 +16081,7 @@ var package_default = {
|
|
|
15783
16081
|
"test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
|
|
15784
16082
|
},
|
|
15785
16083
|
dependencies: {
|
|
15786
|
-
"@cortexkit/aft-bridge": "0.
|
|
16084
|
+
"@cortexkit/aft-bridge": "0.39.1",
|
|
15787
16085
|
"@xterm/headless": "^5.5.0",
|
|
15788
16086
|
"comment-json": "^5.0.0",
|
|
15789
16087
|
diff: "^8.0.4",
|
|
@@ -15791,12 +16089,12 @@ var package_default = {
|
|
|
15791
16089
|
zod: "^4.1.8"
|
|
15792
16090
|
},
|
|
15793
16091
|
optionalDependencies: {
|
|
15794
|
-
"@cortexkit/aft-darwin-arm64": "0.
|
|
15795
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
15796
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
15797
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
15798
|
-
"@cortexkit/aft-win32-arm64": "0.
|
|
15799
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
16092
|
+
"@cortexkit/aft-darwin-arm64": "0.39.1",
|
|
16093
|
+
"@cortexkit/aft-darwin-x64": "0.39.1",
|
|
16094
|
+
"@cortexkit/aft-linux-arm64": "0.39.1",
|
|
16095
|
+
"@cortexkit/aft-linux-x64": "0.39.1",
|
|
16096
|
+
"@cortexkit/aft-win32-arm64": "0.39.1",
|
|
16097
|
+
"@cortexkit/aft-win32-x64": "0.39.1"
|
|
15800
16098
|
},
|
|
15801
16099
|
devDependencies: {
|
|
15802
16100
|
"@earendil-works/pi-coding-agent": "*",
|
|
@@ -16029,101 +16327,6 @@ function formatStatusDialogMessage(status) {
|
|
|
16029
16327
|
// src/tools/_shared.ts
|
|
16030
16328
|
import { Type } from "typebox";
|
|
16031
16329
|
var optionalInt = (_min, _max) => Type.Optional(Type.Any({ description: "(integer)" }));
|
|
16032
|
-
function coerceOptionalInt(v, paramName, min, max) {
|
|
16033
|
-
if (v === undefined || v === null || v === "")
|
|
16034
|
-
return;
|
|
16035
|
-
if (typeof v === "number" && (!Number.isFinite(v) || v === 0 && min > 0))
|
|
16036
|
-
return;
|
|
16037
|
-
const n = typeof v === "string" ? Number(v) : v;
|
|
16038
|
-
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
16039
|
-
throw new Error(`${paramName} must be an integer between ${min} and ${max}`);
|
|
16040
|
-
}
|
|
16041
|
-
if (n < min || n > max) {
|
|
16042
|
-
throw new Error(`${paramName} must be between ${min} and ${max}`);
|
|
16043
|
-
}
|
|
16044
|
-
return n;
|
|
16045
|
-
}
|
|
16046
|
-
function isEmptyParam(value) {
|
|
16047
|
-
if (value === undefined || value === null)
|
|
16048
|
-
return true;
|
|
16049
|
-
if (typeof value === "string")
|
|
16050
|
-
return value.length === 0;
|
|
16051
|
-
if (Array.isArray(value))
|
|
16052
|
-
return value.length === 0;
|
|
16053
|
-
if (typeof value === "object")
|
|
16054
|
-
return Object.keys(value).length === 0;
|
|
16055
|
-
return false;
|
|
16056
|
-
}
|
|
16057
|
-
function asPlainObject(value) {
|
|
16058
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
16059
|
-
return;
|
|
16060
|
-
return value;
|
|
16061
|
-
}
|
|
16062
|
-
function candidateLocation(candidate) {
|
|
16063
|
-
const file = typeof candidate.file === "string" && candidate.file.length > 0 ? candidate.file : undefined;
|
|
16064
|
-
if (!file)
|
|
16065
|
-
return;
|
|
16066
|
-
const line = typeof candidate.line === "number" && Number.isFinite(candidate.line) ? candidate.line : undefined;
|
|
16067
|
-
return line === undefined ? file : `${file}:${line}`;
|
|
16068
|
-
}
|
|
16069
|
-
function stringifyData(data) {
|
|
16070
|
-
if (data === undefined)
|
|
16071
|
-
return;
|
|
16072
|
-
try {
|
|
16073
|
-
return JSON.stringify(data, null, 2);
|
|
16074
|
-
} catch {
|
|
16075
|
-
return String(data);
|
|
16076
|
-
}
|
|
16077
|
-
}
|
|
16078
|
-
function formatBridgeErrorMessage(command, response, params = {}) {
|
|
16079
|
-
const code = typeof response.code === "string" && response.code.length > 0 ? response.code : undefined;
|
|
16080
|
-
const message = typeof response.message === "string" && response.message.length > 0 ? response.message : `${command} failed`;
|
|
16081
|
-
const data = asPlainObject(response.data);
|
|
16082
|
-
const rawCandidates = Array.isArray(response.candidates) ? response.candidates : Array.isArray(data?.candidates) ? data.candidates : undefined;
|
|
16083
|
-
const rawSymbol = typeof response.symbol === "string" && response.symbol.length > 0 ? response.symbol : typeof data?.symbol === "string" && data.symbol.length > 0 ? data.symbol : undefined;
|
|
16084
|
-
if (code === "ambiguous_target" || code === "target_symbol_not_in_file") {
|
|
16085
|
-
const candidates = (rawCandidates ?? []).map(asPlainObject).filter((candidate) => candidate !== undefined).map(candidateLocation).filter((candidate) => candidate !== undefined);
|
|
16086
|
-
if (candidates.length > 0) {
|
|
16087
|
-
const symbol = typeof params.toSymbol === "string" && params.toSymbol.length > 0 ? params.toSymbol : rawSymbol;
|
|
16088
|
-
const target = symbol ? `multiple symbols named "${symbol}"` : message.replace(/[.!?]+$/, "");
|
|
16089
|
-
const action = code === "ambiguous_target" ? "Pass toFile to disambiguate" : "Try one of these files for toFile";
|
|
16090
|
-
return `${command}: ${code} — ${target}. ${action}:
|
|
16091
|
-
${candidates.map((candidate) => ` - ${candidate}`).join(`
|
|
16092
|
-
`)}`;
|
|
16093
|
-
}
|
|
16094
|
-
}
|
|
16095
|
-
if (!code)
|
|
16096
|
-
return message;
|
|
16097
|
-
const lines = [`${command}: ${code} — ${message}`];
|
|
16098
|
-
const extras = collectStructuredExtras(response);
|
|
16099
|
-
if (extras)
|
|
16100
|
-
lines.push(`data: ${extras}`);
|
|
16101
|
-
return lines.join(`
|
|
16102
|
-
`);
|
|
16103
|
-
}
|
|
16104
|
-
function collectStructuredExtras(response) {
|
|
16105
|
-
const reserved = new Set([
|
|
16106
|
-
"id",
|
|
16107
|
-
"success",
|
|
16108
|
-
"code",
|
|
16109
|
-
"message",
|
|
16110
|
-
"data",
|
|
16111
|
-
"status_bar",
|
|
16112
|
-
"bg_completions"
|
|
16113
|
-
]);
|
|
16114
|
-
const extras = {};
|
|
16115
|
-
for (const [key, value] of Object.entries(response)) {
|
|
16116
|
-
if (reserved.has(key))
|
|
16117
|
-
continue;
|
|
16118
|
-
extras[key] = value;
|
|
16119
|
-
}
|
|
16120
|
-
if (Object.keys(extras).length === 0) {
|
|
16121
|
-
return stringifyData(response.data);
|
|
16122
|
-
}
|
|
16123
|
-
if (response.data !== undefined)
|
|
16124
|
-
extras.data = response.data;
|
|
16125
|
-
return stringifyData(extras);
|
|
16126
|
-
}
|
|
16127
16330
|
function bridgeFor(ctx, cwd) {
|
|
16128
16331
|
return ctx.pool.getBridge(cwd);
|
|
16129
16332
|
}
|
|
@@ -16466,8 +16669,8 @@ function registerStatusCommand(pi, ctx) {
|
|
|
16466
16669
|
|
|
16467
16670
|
// src/config.ts
|
|
16468
16671
|
import { existsSync as existsSync6, readFileSync as readFileSync4, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
16469
|
-
import { homedir as
|
|
16470
|
-
import { join as
|
|
16672
|
+
import { homedir as homedir8 } from "node:os";
|
|
16673
|
+
import { join as join10 } from "node:path";
|
|
16471
16674
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
16472
16675
|
|
|
16473
16676
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
@@ -17235,10 +17438,10 @@ function mergeDefs(...defs) {
|
|
|
17235
17438
|
function cloneDef(schema) {
|
|
17236
17439
|
return mergeDefs(schema._zod.def);
|
|
17237
17440
|
}
|
|
17238
|
-
function getElementAtPath(obj,
|
|
17239
|
-
if (!
|
|
17441
|
+
function getElementAtPath(obj, path3) {
|
|
17442
|
+
if (!path3)
|
|
17240
17443
|
return obj;
|
|
17241
|
-
return
|
|
17444
|
+
return path3.reduce((acc, key) => acc?.[key], obj);
|
|
17242
17445
|
}
|
|
17243
17446
|
function promiseAllObject(promisesObj) {
|
|
17244
17447
|
const keys = Object.keys(promisesObj);
|
|
@@ -17619,11 +17822,11 @@ function aborted(x, startIndex = 0) {
|
|
|
17619
17822
|
}
|
|
17620
17823
|
return false;
|
|
17621
17824
|
}
|
|
17622
|
-
function prefixIssues(
|
|
17825
|
+
function prefixIssues(path3, issues) {
|
|
17623
17826
|
return issues.map((iss) => {
|
|
17624
17827
|
var _a;
|
|
17625
17828
|
(_a = iss).path ?? (_a.path = []);
|
|
17626
|
-
iss.path.unshift(
|
|
17829
|
+
iss.path.unshift(path3);
|
|
17627
17830
|
return iss;
|
|
17628
17831
|
});
|
|
17629
17832
|
}
|
|
@@ -17806,7 +18009,7 @@ function formatError(error3, mapper = (issue2) => issue2.message) {
|
|
|
17806
18009
|
}
|
|
17807
18010
|
function treeifyError(error3, mapper = (issue2) => issue2.message) {
|
|
17808
18011
|
const result = { errors: [] };
|
|
17809
|
-
const processError = (error4,
|
|
18012
|
+
const processError = (error4, path3 = []) => {
|
|
17810
18013
|
var _a, _b;
|
|
17811
18014
|
for (const issue2 of error4.issues) {
|
|
17812
18015
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -17816,7 +18019,7 @@ function treeifyError(error3, mapper = (issue2) => issue2.message) {
|
|
|
17816
18019
|
} else if (issue2.code === "invalid_element") {
|
|
17817
18020
|
processError({ issues: issue2.issues }, issue2.path);
|
|
17818
18021
|
} else {
|
|
17819
|
-
const fullpath = [...
|
|
18022
|
+
const fullpath = [...path3, ...issue2.path];
|
|
17820
18023
|
if (fullpath.length === 0) {
|
|
17821
18024
|
result.errors.push(mapper(issue2));
|
|
17822
18025
|
continue;
|
|
@@ -17848,8 +18051,8 @@ function treeifyError(error3, mapper = (issue2) => issue2.message) {
|
|
|
17848
18051
|
}
|
|
17849
18052
|
function toDotPath(_path) {
|
|
17850
18053
|
const segs = [];
|
|
17851
|
-
const
|
|
17852
|
-
for (const seg of
|
|
18054
|
+
const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
18055
|
+
for (const seg of path3) {
|
|
17853
18056
|
if (typeof seg === "number")
|
|
17854
18057
|
segs.push(`[${seg}]`);
|
|
17855
18058
|
else if (typeof seg === "symbol")
|
|
@@ -29596,13 +29799,13 @@ function resolveRef(ref, ctx) {
|
|
|
29596
29799
|
if (!ref.startsWith("#")) {
|
|
29597
29800
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
29598
29801
|
}
|
|
29599
|
-
const
|
|
29600
|
-
if (
|
|
29802
|
+
const path3 = ref.slice(1).split("/").filter(Boolean);
|
|
29803
|
+
if (path3.length === 0) {
|
|
29601
29804
|
return ctx.rootSchema;
|
|
29602
29805
|
}
|
|
29603
29806
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
29604
|
-
if (
|
|
29605
|
-
const key =
|
|
29807
|
+
if (path3[0] === defsKey) {
|
|
29808
|
+
const key = path3[1];
|
|
29606
29809
|
if (!key || !ctx.defs[key]) {
|
|
29607
29810
|
throw new Error(`Reference not found: ${ref}`);
|
|
29608
29811
|
}
|
|
@@ -30259,9 +30462,9 @@ function extractCommentsForPreservation(content) {
|
|
|
30259
30462
|
}
|
|
30260
30463
|
return comments;
|
|
30261
30464
|
}
|
|
30262
|
-
function ensureRecordAtPath(root,
|
|
30465
|
+
function ensureRecordAtPath(root, path3) {
|
|
30263
30466
|
let current = root;
|
|
30264
|
-
for (const segment of
|
|
30467
|
+
for (const segment of path3) {
|
|
30265
30468
|
const existing = current[segment];
|
|
30266
30469
|
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
30267
30470
|
current[segment] = {};
|
|
@@ -30270,9 +30473,9 @@ function ensureRecordAtPath(root, path2) {
|
|
|
30270
30473
|
}
|
|
30271
30474
|
return current;
|
|
30272
30475
|
}
|
|
30273
|
-
function hasPath(root,
|
|
30476
|
+
function hasPath(root, path3) {
|
|
30274
30477
|
let current = root;
|
|
30275
|
-
for (const segment of
|
|
30478
|
+
for (const segment of path3) {
|
|
30276
30479
|
if (!current || typeof current !== "object" || Array.isArray(current))
|
|
30277
30480
|
return false;
|
|
30278
30481
|
const record2 = current;
|
|
@@ -30282,9 +30485,9 @@ function hasPath(root, path2) {
|
|
|
30282
30485
|
}
|
|
30283
30486
|
return true;
|
|
30284
30487
|
}
|
|
30285
|
-
function setPath(root,
|
|
30286
|
-
const parent = ensureRecordAtPath(root,
|
|
30287
|
-
parent[
|
|
30488
|
+
function setPath(root, path3, value) {
|
|
30489
|
+
const parent = ensureRecordAtPath(root, path3.slice(0, -1));
|
|
30490
|
+
parent[path3[path3.length - 1]] = value;
|
|
30288
30491
|
}
|
|
30289
30492
|
function migrateRawConfig(rawConfig, configPath, logger) {
|
|
30290
30493
|
const oldKeys = [];
|
|
@@ -30601,15 +30804,15 @@ function mergeConfigs(base, override) {
|
|
|
30601
30804
|
};
|
|
30602
30805
|
}
|
|
30603
30806
|
function getGlobalPiDir() {
|
|
30604
|
-
return
|
|
30807
|
+
return join10(homedir8(), ".pi", "agent");
|
|
30605
30808
|
}
|
|
30606
30809
|
function loadAftConfig(projectDirectory) {
|
|
30607
|
-
const userBasePath =
|
|
30810
|
+
const userBasePath = join10(getGlobalPiDir(), "aft");
|
|
30608
30811
|
migrateAftConfigFile(`${userBasePath}.jsonc`);
|
|
30609
30812
|
migrateAftConfigFile(`${userBasePath}.json`);
|
|
30610
30813
|
const userDetected = detectConfigFile(userBasePath);
|
|
30611
30814
|
const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
|
|
30612
|
-
const projectBasePath =
|
|
30815
|
+
const projectBasePath = join10(projectDirectory, ".pi", "aft");
|
|
30613
30816
|
migrateAftConfigFile(`${projectBasePath}.jsonc`);
|
|
30614
30817
|
migrateAftConfigFile(`${projectBasePath}.json`);
|
|
30615
30818
|
const projectDetected = detectConfigFile(projectBasePath);
|
|
@@ -30646,7 +30849,7 @@ import {
|
|
|
30646
30849
|
statSync as statSync5,
|
|
30647
30850
|
writeFileSync as writeFileSync5
|
|
30648
30851
|
} from "node:fs";
|
|
30649
|
-
import { join as
|
|
30852
|
+
import { join as join13 } from "node:path";
|
|
30650
30853
|
|
|
30651
30854
|
// src/lsp-cache.ts
|
|
30652
30855
|
import {
|
|
@@ -30658,36 +30861,36 @@ import {
|
|
|
30658
30861
|
unlinkSync as unlinkSync5,
|
|
30659
30862
|
writeFileSync as writeFileSync4
|
|
30660
30863
|
} from "node:fs";
|
|
30661
|
-
import { homedir as
|
|
30662
|
-
import { join as
|
|
30864
|
+
import { homedir as homedir9 } from "node:os";
|
|
30865
|
+
import { join as join11 } from "node:path";
|
|
30663
30866
|
function aftCacheBase() {
|
|
30664
30867
|
const override = process.env.AFT_CACHE_DIR;
|
|
30665
30868
|
if (override && override.length > 0)
|
|
30666
30869
|
return override;
|
|
30667
30870
|
if (process.platform === "win32") {
|
|
30668
30871
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
30669
|
-
const base2 = localAppData ||
|
|
30670
|
-
return
|
|
30872
|
+
const base2 = localAppData || join11(homedir9(), "AppData", "Local");
|
|
30873
|
+
return join11(base2, "aft");
|
|
30671
30874
|
}
|
|
30672
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
30673
|
-
return
|
|
30875
|
+
const base = process.env.XDG_CACHE_HOME || join11(homedir9(), ".cache");
|
|
30876
|
+
return join11(base, "aft");
|
|
30674
30877
|
}
|
|
30675
30878
|
function lspCacheRoot() {
|
|
30676
|
-
return
|
|
30879
|
+
return join11(aftCacheBase(), "lsp-packages");
|
|
30677
30880
|
}
|
|
30678
30881
|
function lspPackageDir(npmPackage) {
|
|
30679
|
-
return
|
|
30882
|
+
return join11(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
30680
30883
|
}
|
|
30681
30884
|
function lspBinaryPath(npmPackage, binary) {
|
|
30682
|
-
return
|
|
30885
|
+
return join11(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
30683
30886
|
}
|
|
30684
30887
|
function lspBinDir(npmPackage) {
|
|
30685
|
-
return
|
|
30888
|
+
return join11(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
30686
30889
|
}
|
|
30687
30890
|
function isInstalled(npmPackage, binary) {
|
|
30688
30891
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
30689
30892
|
try {
|
|
30690
|
-
if (statSync4(
|
|
30893
|
+
if (statSync4(join11(lspBinDir(npmPackage), candidate)).isFile())
|
|
30691
30894
|
return true;
|
|
30692
30895
|
} catch {}
|
|
30693
30896
|
}
|
|
@@ -30707,17 +30910,17 @@ function writeInstalledMetaIn(installDir, version2, sha256) {
|
|
|
30707
30910
|
installedAt: new Date().toISOString(),
|
|
30708
30911
|
...sha256 ? { sha256 } : {}
|
|
30709
30912
|
};
|
|
30710
|
-
writeFileSync4(
|
|
30913
|
+
writeFileSync4(join11(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
|
|
30711
30914
|
} catch (err) {
|
|
30712
30915
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
30713
30916
|
}
|
|
30714
30917
|
}
|
|
30715
30918
|
function readInstalledMetaIn(installDir) {
|
|
30716
|
-
const
|
|
30919
|
+
const path3 = join11(installDir, INSTALLED_META_FILE);
|
|
30717
30920
|
try {
|
|
30718
|
-
if (!statSync4(
|
|
30921
|
+
if (!statSync4(path3).isFile())
|
|
30719
30922
|
return null;
|
|
30720
|
-
const raw = readFileSync5(
|
|
30923
|
+
const raw = readFileSync5(path3, "utf8");
|
|
30721
30924
|
const parsed = JSON.parse(raw);
|
|
30722
30925
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
30723
30926
|
return null;
|
|
@@ -30737,7 +30940,7 @@ function readInstalledMeta(packageKey) {
|
|
|
30737
30940
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
30738
30941
|
}
|
|
30739
30942
|
function lockPath(npmPackage) {
|
|
30740
|
-
return
|
|
30943
|
+
return join11(lspPackageDir(npmPackage), ".aft-installing");
|
|
30741
30944
|
}
|
|
30742
30945
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
30743
30946
|
function acquireInstallLock(lockKey) {
|
|
@@ -30844,7 +31047,7 @@ async function withInstallLock(lockKey, task) {
|
|
|
30844
31047
|
}
|
|
30845
31048
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
30846
31049
|
function readVersionCheck(npmPackage) {
|
|
30847
|
-
const file2 =
|
|
31050
|
+
const file2 = join11(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
30848
31051
|
try {
|
|
30849
31052
|
const raw = readFileSync5(file2, "utf8");
|
|
30850
31053
|
const parsed = JSON.parse(raw);
|
|
@@ -30861,7 +31064,7 @@ function readVersionCheck(npmPackage) {
|
|
|
30861
31064
|
}
|
|
30862
31065
|
function writeVersionCheck(npmPackage, latest) {
|
|
30863
31066
|
mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
|
|
30864
|
-
const file2 =
|
|
31067
|
+
const file2 = join11(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
30865
31068
|
const record2 = {
|
|
30866
31069
|
last_checked: new Date().toISOString(),
|
|
30867
31070
|
latest_eligible: latest
|
|
@@ -31024,7 +31227,7 @@ var NPM_LSP_TABLE = [
|
|
|
31024
31227
|
|
|
31025
31228
|
// src/lsp-project-relevance.ts
|
|
31026
31229
|
import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "node:fs";
|
|
31027
|
-
import { join as
|
|
31230
|
+
import { join as join12 } from "node:path";
|
|
31028
31231
|
var MAX_WALK_DIRS = 200;
|
|
31029
31232
|
var MAX_WALK_DEPTH = 4;
|
|
31030
31233
|
var NOISE_DIRS = new Set([
|
|
@@ -31041,7 +31244,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
31041
31244
|
if (!rootMarkers)
|
|
31042
31245
|
return false;
|
|
31043
31246
|
for (const marker of rootMarkers) {
|
|
31044
|
-
if (existsSync7(
|
|
31247
|
+
if (existsSync7(join12(projectRoot, marker)))
|
|
31045
31248
|
return true;
|
|
31046
31249
|
}
|
|
31047
31250
|
return false;
|
|
@@ -31065,7 +31268,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
31065
31268
|
}
|
|
31066
31269
|
function readPackageJson(projectRoot) {
|
|
31067
31270
|
try {
|
|
31068
|
-
const raw = readFileSync6(
|
|
31271
|
+
const raw = readFileSync6(join12(projectRoot, "package.json"), "utf8");
|
|
31069
31272
|
const parsed = JSON.parse(raw);
|
|
31070
31273
|
if (typeof parsed !== "object" || parsed === null)
|
|
31071
31274
|
return null;
|
|
@@ -31095,7 +31298,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
31095
31298
|
for (const entry of entries) {
|
|
31096
31299
|
if (entry.isDirectory()) {
|
|
31097
31300
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
31098
|
-
queue.push({ dir:
|
|
31301
|
+
queue.push({ dir: join12(current.dir, entry.name), depth: current.depth + 1 });
|
|
31099
31302
|
}
|
|
31100
31303
|
continue;
|
|
31101
31304
|
}
|
|
@@ -31222,7 +31425,7 @@ async function resolveTargetVersion(spec, config2, fetchImpl = fetch) {
|
|
|
31222
31425
|
}
|
|
31223
31426
|
function ensureInstallAnchor(cwd) {
|
|
31224
31427
|
try {
|
|
31225
|
-
const stub =
|
|
31428
|
+
const stub = join13(cwd, "package.json");
|
|
31226
31429
|
if (!existsSync8(stub)) {
|
|
31227
31430
|
writeFileSync5(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
31228
31431
|
`);
|
|
@@ -31232,18 +31435,18 @@ function ensureInstallAnchor(cwd) {
|
|
|
31232
31435
|
}
|
|
31233
31436
|
}
|
|
31234
31437
|
function runInstall(spec, version2, cwd, signal) {
|
|
31235
|
-
return new Promise((
|
|
31438
|
+
return new Promise((resolve3) => {
|
|
31236
31439
|
const target = `${spec.npm}@${version2}`;
|
|
31237
31440
|
log2(`[lsp] installing ${target} to ${cwd}`);
|
|
31238
31441
|
if (signal?.aborted) {
|
|
31239
31442
|
warn2(`[lsp] install ${target} aborted before spawn`);
|
|
31240
|
-
|
|
31443
|
+
resolve3(false);
|
|
31241
31444
|
return;
|
|
31242
31445
|
}
|
|
31243
31446
|
const npm = resolveNpm();
|
|
31244
31447
|
if (!npm) {
|
|
31245
31448
|
warn2(`[lsp] npm not found on PATH or known locations; cannot install ${target}`);
|
|
31246
|
-
|
|
31449
|
+
resolve3(false);
|
|
31247
31450
|
return;
|
|
31248
31451
|
}
|
|
31249
31452
|
ensureInstallAnchor(cwd);
|
|
@@ -31266,7 +31469,7 @@ function runInstall(spec, version2, cwd, signal) {
|
|
|
31266
31469
|
return;
|
|
31267
31470
|
settled = true;
|
|
31268
31471
|
cleanup();
|
|
31269
|
-
|
|
31472
|
+
resolve3(ok);
|
|
31270
31473
|
};
|
|
31271
31474
|
const onAbort = () => {
|
|
31272
31475
|
warn2(`[lsp] install ${target} aborted during shutdown`);
|
|
@@ -31367,7 +31570,7 @@ function cachedPackageDir(npmPackage) {
|
|
|
31367
31570
|
return lspBinDir(npmPackage).replace(/[\\/]node_modules[\\/]\.bin[\\/]?$/, "");
|
|
31368
31571
|
}
|
|
31369
31572
|
function hashInstalledBinary(spec) {
|
|
31370
|
-
return new Promise((
|
|
31573
|
+
return new Promise((resolve3, reject) => {
|
|
31371
31574
|
const candidates = process.platform === "win32" ? [
|
|
31372
31575
|
lspBinaryPath(spec.npm, spec.binary),
|
|
31373
31576
|
lspBinaryPath(spec.npm, `${spec.binary}.cmd`),
|
|
@@ -31391,7 +31594,7 @@ function hashInstalledBinary(spec) {
|
|
|
31391
31594
|
const stream = createReadStream(pathToHash);
|
|
31392
31595
|
stream.on("error", reject);
|
|
31393
31596
|
stream.on("data", (chunk) => hash2.update(chunk));
|
|
31394
|
-
stream.on("end", () =>
|
|
31597
|
+
stream.on("end", () => resolve3(hash2.digest("hex")));
|
|
31395
31598
|
});
|
|
31396
31599
|
}
|
|
31397
31600
|
function installedBinaryPath(spec) {
|
|
@@ -31409,15 +31612,15 @@ function installedBinaryPath(spec) {
|
|
|
31409
31612
|
}
|
|
31410
31613
|
return null;
|
|
31411
31614
|
}
|
|
31412
|
-
function sha256OfFileSync(
|
|
31413
|
-
return createHash3("sha256").update(readFileSync7(
|
|
31615
|
+
function sha256OfFileSync(path3) {
|
|
31616
|
+
return createHash3("sha256").update(readFileSync7(path3)).digest("hex");
|
|
31414
31617
|
}
|
|
31415
31618
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
31416
31619
|
const packageDir = lspPackageDir(spec.npm);
|
|
31417
|
-
const dest =
|
|
31620
|
+
const dest = join13(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
31418
31621
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
31419
31622
|
try {
|
|
31420
|
-
mkdirSync7(
|
|
31623
|
+
mkdirSync7(join13(dest, ".."), { recursive: true });
|
|
31421
31624
|
rmSync3(dest, { recursive: true, force: true });
|
|
31422
31625
|
renameSync5(packageDir, dest);
|
|
31423
31626
|
} catch (err) {
|
|
@@ -31512,7 +31715,7 @@ import {
|
|
|
31512
31715
|
unlinkSync as unlinkSync6,
|
|
31513
31716
|
writeFileSync as writeFileSync6
|
|
31514
31717
|
} from "node:fs";
|
|
31515
|
-
import { dirname as dirname5, join as
|
|
31718
|
+
import { dirname as dirname5, join as join14, relative as relative3, resolve as resolve3 } from "node:path";
|
|
31516
31719
|
import { Readable as Readable3 } from "node:stream";
|
|
31517
31720
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
31518
31721
|
|
|
@@ -31602,26 +31805,26 @@ function detectHostPlatform() {
|
|
|
31602
31805
|
|
|
31603
31806
|
// src/lsp-github-install.ts
|
|
31604
31807
|
function ghCacheRoot() {
|
|
31605
|
-
return
|
|
31808
|
+
return join14(aftCacheBase(), "lsp-binaries");
|
|
31606
31809
|
}
|
|
31607
31810
|
function ghPackageDir(spec) {
|
|
31608
|
-
return
|
|
31811
|
+
return join14(ghCacheRoot(), spec.id);
|
|
31609
31812
|
}
|
|
31610
31813
|
function ghBinDir(spec) {
|
|
31611
|
-
return
|
|
31814
|
+
return join14(ghPackageDir(spec), "bin");
|
|
31612
31815
|
}
|
|
31613
31816
|
function ghExtractDir(spec) {
|
|
31614
|
-
return
|
|
31817
|
+
return join14(ghPackageDir(spec), "extracted");
|
|
31615
31818
|
}
|
|
31616
31819
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
31617
31820
|
function ghBinaryPath(spec, platform) {
|
|
31618
31821
|
const ext = platform === "win32" ? ".exe" : "";
|
|
31619
|
-
return
|
|
31822
|
+
return join14(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
31620
31823
|
}
|
|
31621
31824
|
function isGithubInstalled(spec, platform) {
|
|
31622
31825
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
31623
31826
|
try {
|
|
31624
|
-
if (statSync6(
|
|
31827
|
+
if (statSync6(join14(ghBinDir(spec), candidate)).isFile())
|
|
31625
31828
|
return true;
|
|
31626
31829
|
} catch {}
|
|
31627
31830
|
}
|
|
@@ -31634,10 +31837,10 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
31634
31837
|
}
|
|
31635
31838
|
function readGithubInstalledMetaIn(installDir) {
|
|
31636
31839
|
try {
|
|
31637
|
-
const
|
|
31638
|
-
if (!statSync6(
|
|
31840
|
+
const path3 = join14(installDir, INSTALLED_META_FILE2);
|
|
31841
|
+
if (!statSync6(path3).isFile())
|
|
31639
31842
|
return null;
|
|
31640
|
-
const parsed = JSON.parse(readFileSync8(
|
|
31843
|
+
const parsed = JSON.parse(readFileSync8(path3, "utf8"));
|
|
31641
31844
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
31642
31845
|
return null;
|
|
31643
31846
|
return {
|
|
@@ -31661,24 +31864,24 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
|
|
|
31661
31864
|
binarySha256,
|
|
31662
31865
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
31663
31866
|
};
|
|
31664
|
-
writeFileSync6(
|
|
31867
|
+
writeFileSync6(join14(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
|
|
31665
31868
|
} catch (err) {
|
|
31666
31869
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
31667
31870
|
}
|
|
31668
31871
|
}
|
|
31669
31872
|
var MAX_DOWNLOAD_BYTES3 = 256 * 1024 * 1024;
|
|
31670
31873
|
var MAX_EXTRACT_BYTES2 = 1024 * 1024 * 1024;
|
|
31671
|
-
function sha256OfFile(
|
|
31672
|
-
return new Promise((
|
|
31874
|
+
function sha256OfFile(path3) {
|
|
31875
|
+
return new Promise((resolve4, reject) => {
|
|
31673
31876
|
const hash2 = createHash4("sha256");
|
|
31674
|
-
const stream = createReadStream2(
|
|
31877
|
+
const stream = createReadStream2(path3);
|
|
31675
31878
|
stream.on("error", reject);
|
|
31676
31879
|
stream.on("data", (chunk) => hash2.update(chunk));
|
|
31677
|
-
stream.on("end", () =>
|
|
31880
|
+
stream.on("end", () => resolve4(hash2.digest("hex")));
|
|
31678
31881
|
});
|
|
31679
31882
|
}
|
|
31680
|
-
function sha256OfFileSync2(
|
|
31681
|
-
return createHash4("sha256").update(readFileSync8(
|
|
31883
|
+
function sha256OfFileSync2(path3) {
|
|
31884
|
+
return createHash4("sha256").update(readFileSync8(path3)).digest("hex");
|
|
31682
31885
|
}
|
|
31683
31886
|
async function fetchReleaseByTag(githubRepo, tag, fetchImpl, signal) {
|
|
31684
31887
|
const candidates = [];
|
|
@@ -31910,7 +32113,7 @@ function validateExtraction(stagingRoot) {
|
|
|
31910
32113
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
31911
32114
|
}
|
|
31912
32115
|
for (const entry of entries) {
|
|
31913
|
-
const full =
|
|
32116
|
+
const full = join14(dir, entry);
|
|
31914
32117
|
let lst;
|
|
31915
32118
|
try {
|
|
31916
32119
|
lst = lstatSync2(full);
|
|
@@ -31922,7 +32125,7 @@ function validateExtraction(stagingRoot) {
|
|
|
31922
32125
|
try {
|
|
31923
32126
|
target = readlinkSync2(full);
|
|
31924
32127
|
} catch {}
|
|
31925
|
-
throw new Error(`archive contains symlink ${
|
|
32128
|
+
throw new Error(`archive contains symlink ${relative3(realStagingRoot, full)} → ${target}; rejecting (zip-slip defense)`);
|
|
31926
32129
|
}
|
|
31927
32130
|
let realFull;
|
|
31928
32131
|
try {
|
|
@@ -31930,8 +32133,8 @@ function validateExtraction(stagingRoot) {
|
|
|
31930
32133
|
} catch (err) {
|
|
31931
32134
|
throw new Error(`failed to realpath ${full}: ${err}`);
|
|
31932
32135
|
}
|
|
31933
|
-
const rel =
|
|
31934
|
-
if (rel.startsWith("..") ||
|
|
32136
|
+
const rel = relative3(realStagingRoot, realFull);
|
|
32137
|
+
if (rel.startsWith("..") || resolve3(realStagingRoot, rel) !== realFull) {
|
|
31935
32138
|
throw new Error(`archive entry escapes staging root: ${full} → ${realFull} (zip-slip defense)`);
|
|
31936
32139
|
}
|
|
31937
32140
|
if (lst.isDirectory()) {
|
|
@@ -31998,7 +32201,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
31998
32201
|
}
|
|
31999
32202
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
32000
32203
|
const packageDir = ghPackageDir(spec);
|
|
32001
|
-
const dest =
|
|
32204
|
+
const dest = join14(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
32002
32205
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
32003
32206
|
try {
|
|
32004
32207
|
mkdirSync8(dirname5(dest), { recursive: true });
|
|
@@ -32011,7 +32214,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
32011
32214
|
function validateCachedGithubInstall(spec, platform) {
|
|
32012
32215
|
const packageDir = ghPackageDir(spec);
|
|
32013
32216
|
const meta3 = readGithubInstalledMetaIn(packageDir);
|
|
32014
|
-
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) =>
|
|
32217
|
+
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join14(ghBinDir(spec), candidate)).find((candidate) => {
|
|
32015
32218
|
try {
|
|
32016
32219
|
return statSync6(candidate).isFile();
|
|
32017
32220
|
} catch {
|
|
@@ -32089,7 +32292,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
32089
32292
|
}
|
|
32090
32293
|
const pkgDir = ghPackageDir(spec);
|
|
32091
32294
|
const extractDir = ghExtractDir(spec);
|
|
32092
|
-
const archivePath =
|
|
32295
|
+
const archivePath = join14(pkgDir, expected.name);
|
|
32093
32296
|
log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
|
|
32094
32297
|
try {
|
|
32095
32298
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
|
|
@@ -32129,7 +32332,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
32129
32332
|
unlinkSync6(archivePath);
|
|
32130
32333
|
} catch {}
|
|
32131
32334
|
}
|
|
32132
|
-
const innerBinaryPath =
|
|
32335
|
+
const innerBinaryPath = join14(extractDir, spec.binaryPathInArchive(platform, arch, version2));
|
|
32133
32336
|
if (!existsSync9(innerBinaryPath)) {
|
|
32134
32337
|
error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
|
|
32135
32338
|
return null;
|
|
@@ -32527,7 +32730,7 @@ function renderScreen(state, rows = state.rows, cols = state.cols) {
|
|
|
32527
32730
|
`);
|
|
32528
32731
|
}
|
|
32529
32732
|
function writeTerminal(terminal, data) {
|
|
32530
|
-
return new Promise((
|
|
32733
|
+
return new Promise((resolve4) => terminal.write(data, resolve4));
|
|
32531
32734
|
}
|
|
32532
32735
|
|
|
32533
32736
|
// src/shutdown-hooks.ts
|
|
@@ -32584,8 +32787,8 @@ function installProcessHandlers() {
|
|
|
32584
32787
|
}
|
|
32585
32788
|
signalShutdownStarted = true;
|
|
32586
32789
|
process.exitCode = SIGNAL_EXIT_CODES[sig];
|
|
32587
|
-
const timeout = new Promise((
|
|
32588
|
-
setTimeout(
|
|
32790
|
+
const timeout = new Promise((resolve4) => {
|
|
32791
|
+
setTimeout(resolve4, SIGNAL_CLEANUP_TIMEOUT_MS);
|
|
32589
32792
|
});
|
|
32590
32793
|
Promise.race([runCleanups(sig), timeout]).finally(() => {
|
|
32591
32794
|
process.exit(SIGNAL_EXIT_CODES[sig]);
|
|
@@ -32627,8 +32830,8 @@ import { Type as Type3 } from "typebox";
|
|
|
32627
32830
|
|
|
32628
32831
|
// src/tools/hoisted.ts
|
|
32629
32832
|
import { stat } from "node:fs/promises";
|
|
32630
|
-
import { homedir as
|
|
32631
|
-
import { isAbsolute as
|
|
32833
|
+
import { homedir as homedir10 } from "node:os";
|
|
32834
|
+
import { isAbsolute as isAbsolute4, relative as relative4, resolve as resolve4, sep } from "node:path";
|
|
32632
32835
|
import {
|
|
32633
32836
|
renderDiff
|
|
32634
32837
|
} from "@earendil-works/pi-coding-agent";
|
|
@@ -32742,18 +32945,18 @@ function diagnosticsOnEditDefault(ctx) {
|
|
|
32742
32945
|
return ctx.config.lsp?.diagnostics_on_edit ?? false;
|
|
32743
32946
|
}
|
|
32744
32947
|
function containsPath(parent, child) {
|
|
32745
|
-
const rel =
|
|
32746
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
32948
|
+
const rel = relative4(parent, child);
|
|
32949
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute4(rel);
|
|
32747
32950
|
}
|
|
32748
|
-
function
|
|
32749
|
-
if (!
|
|
32750
|
-
return
|
|
32751
|
-
if (
|
|
32752
|
-
return
|
|
32753
|
-
if (
|
|
32754
|
-
return
|
|
32951
|
+
function expandTilde2(path3) {
|
|
32952
|
+
if (!path3 || !path3.startsWith("~"))
|
|
32953
|
+
return path3;
|
|
32954
|
+
if (path3 === "~")
|
|
32955
|
+
return homedir10();
|
|
32956
|
+
if (path3.startsWith(`~${sep}`) || path3.startsWith("~/")) {
|
|
32957
|
+
return resolve4(homedir10(), path3.slice(2));
|
|
32755
32958
|
}
|
|
32756
|
-
return
|
|
32959
|
+
return path3;
|
|
32757
32960
|
}
|
|
32758
32961
|
function externalDirectoryPromptTimeoutMs() {
|
|
32759
32962
|
const raw = process.env.AFT_PI_EXTERNAL_PROMPT_TIMEOUT_MS;
|
|
@@ -32765,8 +32968,8 @@ function externalDirectoryPromptTimeoutMs() {
|
|
|
32765
32968
|
async function assertExternalDirectoryPermission(extCtx, target, action = "modify", options = {}) {
|
|
32766
32969
|
if (!target)
|
|
32767
32970
|
return;
|
|
32768
|
-
const expanded =
|
|
32769
|
-
const absoluteTarget =
|
|
32971
|
+
const expanded = expandTilde2(target);
|
|
32972
|
+
const absoluteTarget = isAbsolute4(expanded) ? expanded : resolve4(extCtx.cwd, expanded);
|
|
32770
32973
|
if (containsPath(extCtx.cwd, absoluteTarget))
|
|
32771
32974
|
return;
|
|
32772
32975
|
if (options.restrictToProjectRoot === false)
|
|
@@ -32777,8 +32980,8 @@ async function assertExternalDirectoryPermission(extCtx, target, action = "modif
|
|
|
32777
32980
|
}
|
|
32778
32981
|
const timeoutMs = externalDirectoryPromptTimeoutMs();
|
|
32779
32982
|
let timer;
|
|
32780
|
-
const timeoutPromise = new Promise((
|
|
32781
|
-
timer = setTimeout(() =>
|
|
32983
|
+
const timeoutPromise = new Promise((resolve5) => {
|
|
32984
|
+
timer = setTimeout(() => resolve5("timeout"), timeoutMs);
|
|
32782
32985
|
});
|
|
32783
32986
|
try {
|
|
32784
32987
|
const result = await Promise.race([
|
|
@@ -32842,8 +33045,12 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
32842
33045
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
32843
33046
|
const offset = coerceOptionalInt(params.offset, "offset", 1, Number.MAX_SAFE_INTEGER);
|
|
32844
33047
|
const limit = coerceOptionalInt(params.limit, "limit", 1, Number.MAX_SAFE_INTEGER);
|
|
33048
|
+
const filePath = await resolvePathArg(extCtx.cwd, params.path);
|
|
33049
|
+
await assertExternalDirectoryPermission(extCtx, filePath, "read", {
|
|
33050
|
+
restrictToProjectRoot: surface.restrictToProjectRoot
|
|
33051
|
+
});
|
|
32845
33052
|
const req = {
|
|
32846
|
-
file:
|
|
33053
|
+
file: filePath
|
|
32847
33054
|
};
|
|
32848
33055
|
if (offset !== undefined) {
|
|
32849
33056
|
req.start_line = offset;
|
|
@@ -32860,7 +33067,7 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
32860
33067
|
}
|
|
32861
33068
|
let text = response.content ?? "";
|
|
32862
33069
|
const agentSpecifiedRange = offset !== undefined || limit !== undefined;
|
|
32863
|
-
const footer =
|
|
33070
|
+
const footer = formatReadFooter2(agentSpecifiedRange, response);
|
|
32864
33071
|
if (footer)
|
|
32865
33072
|
text += footer;
|
|
32866
33073
|
return textResult(text);
|
|
@@ -33116,15 +33323,15 @@ ${summary}${suffix}`);
|
|
|
33116
33323
|
container.addChild(new Text(renderDiff(diff), 1, 0));
|
|
33117
33324
|
return container;
|
|
33118
33325
|
}
|
|
33119
|
-
function shortenPath(
|
|
33120
|
-
const home =
|
|
33121
|
-
if (
|
|
33122
|
-
return `~${
|
|
33123
|
-
return
|
|
33326
|
+
function shortenPath(path3) {
|
|
33327
|
+
const home = homedir10();
|
|
33328
|
+
if (path3.startsWith(home))
|
|
33329
|
+
return `~${path3.slice(home.length)}`;
|
|
33330
|
+
return path3;
|
|
33124
33331
|
}
|
|
33125
|
-
async function resolvePathArg(cwd,
|
|
33126
|
-
const expanded =
|
|
33127
|
-
const abs =
|
|
33332
|
+
async function resolvePathArg(cwd, path3) {
|
|
33333
|
+
const expanded = expandTilde2(path3);
|
|
33334
|
+
const abs = isAbsolute4(expanded) ? expanded : resolve4(cwd, expanded);
|
|
33128
33335
|
try {
|
|
33129
33336
|
await stat(abs);
|
|
33130
33337
|
return abs;
|
|
@@ -33162,23 +33369,12 @@ function splitIncludeGlobs(include) {
|
|
|
33162
33369
|
out.push(tail2);
|
|
33163
33370
|
return out;
|
|
33164
33371
|
}
|
|
33165
|
-
function
|
|
33166
|
-
|
|
33167
|
-
return "";
|
|
33168
|
-
if (!data.truncated)
|
|
33169
|
-
return "";
|
|
33170
|
-
const startLine = data.start_line;
|
|
33171
|
-
const endLine = data.end_line;
|
|
33172
|
-
const totalLines = data.total_lines;
|
|
33173
|
-
if (startLine === undefined || endLine === undefined || totalLines === undefined) {
|
|
33174
|
-
return "";
|
|
33175
|
-
}
|
|
33176
|
-
return `
|
|
33177
|
-
(Showing lines ${startLine}-${endLine} of ${totalLines}. Use offset/limit to read other sections.)`;
|
|
33372
|
+
function formatReadFooter2(agentSpecifiedRange, data) {
|
|
33373
|
+
return formatReadFooter(agentSpecifiedRange, data, { rangeHint: "offset/limit" });
|
|
33178
33374
|
}
|
|
33179
33375
|
|
|
33180
33376
|
// src/tools/render-helpers.ts
|
|
33181
|
-
import { homedir as
|
|
33377
|
+
import { homedir as homedir11 } from "node:os";
|
|
33182
33378
|
import { renderDiff as renderDiff2 } from "@earendil-works/pi-coding-agent";
|
|
33183
33379
|
import { Container as Container2, Spacer as Spacer2, Text as Text2 } from "@earendil-works/pi-tui";
|
|
33184
33380
|
function reuseText2(last) {
|
|
@@ -33187,11 +33383,11 @@ function reuseText2(last) {
|
|
|
33187
33383
|
function reuseContainer2(last) {
|
|
33188
33384
|
return last instanceof Container2 ? last : new Container2;
|
|
33189
33385
|
}
|
|
33190
|
-
function shortenPath2(
|
|
33191
|
-
const home =
|
|
33192
|
-
if (
|
|
33193
|
-
return `~${
|
|
33194
|
-
return
|
|
33386
|
+
function shortenPath2(path3) {
|
|
33387
|
+
const home = homedir11();
|
|
33388
|
+
if (path3.startsWith(home))
|
|
33389
|
+
return `~${path3.slice(home.length)}`;
|
|
33390
|
+
return path3;
|
|
33195
33391
|
}
|
|
33196
33392
|
function renderToolCall(toolName, summary, theme, context) {
|
|
33197
33393
|
const text = reuseText2(context.lastComponent);
|
|
@@ -33199,10 +33395,10 @@ function renderToolCall(toolName, summary, theme, context) {
|
|
|
33199
33395
|
text.setText(`${theme.fg("toolTitle", theme.bold(toolName))}${suffix}`);
|
|
33200
33396
|
return text;
|
|
33201
33397
|
}
|
|
33202
|
-
function accentPath(theme,
|
|
33203
|
-
if (!
|
|
33398
|
+
function accentPath(theme, path3) {
|
|
33399
|
+
if (!path3)
|
|
33204
33400
|
return theme.fg("toolOutput", "...");
|
|
33205
|
-
return theme.fg("accent", shortenPath2(
|
|
33401
|
+
return theme.fg("accent", shortenPath2(path3));
|
|
33206
33402
|
}
|
|
33207
33403
|
function collectTextContent(result) {
|
|
33208
33404
|
return result.content.filter((part) => part.type === "text").map((part) => part.text ?? "").join(`
|
|
@@ -33349,7 +33545,7 @@ function renderUnifiedDiff(unifiedDiff) {
|
|
|
33349
33545
|
}
|
|
33350
33546
|
|
|
33351
33547
|
// src/tools/ast.ts
|
|
33352
|
-
var AstLang = StringEnum(["typescript", "tsx", "javascript", "python", "rust", "go", "pascal"], {
|
|
33548
|
+
var AstLang = StringEnum(["typescript", "tsx", "javascript", "python", "rust", "go", "pascal", "r"], {
|
|
33353
33549
|
description: "Target language"
|
|
33354
33550
|
});
|
|
33355
33551
|
var SearchParams = Type3.Object({
|
|
@@ -33390,17 +33586,17 @@ ${warningStrings.map((w) => ` ${w}`).join(`
|
|
|
33390
33586
|
async function resolveAstPaths(extCtx, paths) {
|
|
33391
33587
|
if (isEmptyParam(paths) || !Array.isArray(paths))
|
|
33392
33588
|
return;
|
|
33393
|
-
return Promise.all(paths.filter((
|
|
33589
|
+
return Promise.all(paths.filter((path3) => typeof path3 === "string").map((path3) => resolvePathArg(extCtx.cwd, path3)));
|
|
33394
33590
|
}
|
|
33395
33591
|
async function assertAstPathsPermission(extCtx, paths, action, restrictToProjectRoot) {
|
|
33396
33592
|
if (paths === undefined || paths.length === 0)
|
|
33397
33593
|
return;
|
|
33398
33594
|
const checked = new Set;
|
|
33399
|
-
for (const
|
|
33400
|
-
if (checked.has(
|
|
33595
|
+
for (const path3 of paths) {
|
|
33596
|
+
if (checked.has(path3))
|
|
33401
33597
|
continue;
|
|
33402
|
-
checked.add(
|
|
33403
|
-
await assertExternalDirectoryPermission(extCtx,
|
|
33598
|
+
checked.add(path3);
|
|
33599
|
+
await assertExternalDirectoryPermission(extCtx, path3, action, { restrictToProjectRoot });
|
|
33404
33600
|
}
|
|
33405
33601
|
}
|
|
33406
33602
|
function buildAstSearchSections(payload, theme) {
|
|
@@ -33583,6 +33779,7 @@ var FOREGROUND_POLL_INTERVAL_MS = 100;
|
|
|
33583
33779
|
var BASH_WAIT_POLL_INTERVAL_MS = 100;
|
|
33584
33780
|
var DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS = 30000;
|
|
33585
33781
|
var MAX_BASH_STATUS_WAIT_TIMEOUT_MS = 300000;
|
|
33782
|
+
var REGEX_WAIT_SCAN_WINDOW_BYTES = 64 * 1024;
|
|
33586
33783
|
function resolveForegroundWaitMs(configured) {
|
|
33587
33784
|
const override = process.env.AFT_TEST_FOREGROUND_WAIT_MS;
|
|
33588
33785
|
if (override !== undefined) {
|
|
@@ -33767,7 +33964,7 @@ DO NOT use bash for code search or code exploration. If you are about to run gre
|
|
|
33767
33964
|
throw new Error(status.message ?? "bash_status failed");
|
|
33768
33965
|
}
|
|
33769
33966
|
if (isTerminalStatus(status.status)) {
|
|
33770
|
-
return bashResult(appendPipeStripNote(withBashHints(formatForegroundResult(status), bridgeCommand, aftSearchRegistered), pipeStrip.note), {
|
|
33967
|
+
return bashResult(appendPipeStripNote(withBashHints(formatForegroundResult(status), bridgeCommand, aftSearchRegistered, extCtx.cwd), pipeStrip.note), {
|
|
33771
33968
|
exit_code: status.exit_code,
|
|
33772
33969
|
duration_ms: status.duration_ms,
|
|
33773
33970
|
truncated: status.output_truncated,
|
|
@@ -33794,7 +33991,7 @@ DO NOT use bash for code search or code exploration. If you are about to run gre
|
|
|
33794
33991
|
task_id: taskId
|
|
33795
33992
|
};
|
|
33796
33993
|
const output = response.output ?? "";
|
|
33797
|
-
return bashResult(appendPipeStripNote(withBashHints(output, bridgeCommand, aftSearchRegistered), pipeStrip.note), details);
|
|
33994
|
+
return bashResult(appendPipeStripNote(withBashHints(output, bridgeCommand, aftSearchRegistered, extCtx.cwd), pipeStrip.note), details);
|
|
33798
33995
|
},
|
|
33799
33996
|
renderCall(args, theme, context) {
|
|
33800
33997
|
return renderBashCall(args?.command, args?.description, theme, context);
|
|
@@ -33808,11 +34005,6 @@ DO NOT use bash for code search or code exploration. If you are about to run gre
|
|
|
33808
34005
|
pi.registerTool(createBashWriteTool(ctx));
|
|
33809
34006
|
pi.registerTool(createBashKillTool(ctx));
|
|
33810
34007
|
}
|
|
33811
|
-
function appendPipeStripNote(output, note) {
|
|
33812
|
-
return note ? `${output}
|
|
33813
|
-
|
|
33814
|
-
${note}` : output;
|
|
33815
|
-
}
|
|
33816
34008
|
function formatBackgroundLaunch(taskId, isPty) {
|
|
33817
34009
|
if (isPty) {
|
|
33818
34010
|
return `PTY task started: ${taskId}. Use bash_status({ task_id: "${taskId}", output_mode: "screen" }) to see the visible terminal, bash_write({ task_id: "${taskId}", input: ... }) to send keystrokes. A completion reminder fires automatically when the task exits.`;
|
|
@@ -33823,35 +34015,8 @@ function formatPromotionMessage(taskId, timeout, waitWindowMs) {
|
|
|
33823
34015
|
const waited = timeout !== undefined ? Math.min(timeout, waitWindowMs) : waitWindowMs;
|
|
33824
34016
|
return `Foreground bash didn't finish within ${formatSeconds(waited)} and was promoted to background: ${taskId}. A completion reminder will be delivered automatically; use bash_status({ task_id: "${taskId}" }) to inspect output or bash_kill({ task_id: "${taskId}" }) to terminate.`;
|
|
33825
34017
|
}
|
|
33826
|
-
function
|
|
33827
|
-
return
|
|
33828
|
-
}
|
|
33829
|
-
function withBashHints(output, command, aftSearchRegistered) {
|
|
33830
|
-
return maybeAppendGrepSearchHint(maybeAppendConflictsHint(output), command, aftSearchRegistered);
|
|
33831
|
-
}
|
|
33832
|
-
function formatForegroundResult(data) {
|
|
33833
|
-
const output = data.output_preview ?? "";
|
|
33834
|
-
const outputPath = data.output_path;
|
|
33835
|
-
const truncated = data.output_truncated === true;
|
|
33836
|
-
const status = data.status;
|
|
33837
|
-
const exit = data.exit_code;
|
|
33838
|
-
let rendered = output;
|
|
33839
|
-
if (truncated && outputPath) {
|
|
33840
|
-
rendered += `
|
|
33841
|
-
[output truncated; full output at ${outputPath}]`;
|
|
33842
|
-
}
|
|
33843
|
-
if (status === "timed_out") {
|
|
33844
|
-
rendered += `
|
|
33845
|
-
[command timed out]`;
|
|
33846
|
-
}
|
|
33847
|
-
if (typeof exit === "number" && exit !== 0) {
|
|
33848
|
-
rendered += `
|
|
33849
|
-
[exit code: ${exit}]`;
|
|
33850
|
-
}
|
|
33851
|
-
return rendered;
|
|
33852
|
-
}
|
|
33853
|
-
function sleep(ms) {
|
|
33854
|
-
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
34018
|
+
function withBashHints(output, command, aftSearchRegistered, projectRoot) {
|
|
34019
|
+
return maybeAppendGrepSearchHint(maybeAppendConflictsHint(output), command, aftSearchRegistered, projectRoot);
|
|
33855
34020
|
}
|
|
33856
34021
|
function createBashStatusTool(ctx) {
|
|
33857
34022
|
return {
|
|
@@ -34018,6 +34183,9 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
34018
34183
|
keepBridgeOnTimeout: true,
|
|
34019
34184
|
transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS
|
|
34020
34185
|
};
|
|
34186
|
+
if (waitFor?.kind === "regex") {
|
|
34187
|
+
await validateWaitRegex(bridge, extCtx, waitFor);
|
|
34188
|
+
}
|
|
34021
34189
|
const sessionId = resolveSessionId(extCtx);
|
|
34022
34190
|
clearSyncWatchAbort(sessionId);
|
|
34023
34191
|
if (waitForExit)
|
|
@@ -34034,7 +34202,12 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
34034
34202
|
if (scanText.length === 0)
|
|
34035
34203
|
scanBaseOffset = scan.baseOffset;
|
|
34036
34204
|
scanText += scan.text;
|
|
34037
|
-
|
|
34205
|
+
if (waitFor.kind === "regex") {
|
|
34206
|
+
const trimmed = trimWaitScanBuffer(scanText, scanBaseOffset, waitFor);
|
|
34207
|
+
scanText = trimmed.text;
|
|
34208
|
+
scanBaseOffset = trimmed.baseOffset;
|
|
34209
|
+
}
|
|
34210
|
+
const match = await findWaitMatch(bridge, extCtx, scanText, waitFor);
|
|
34038
34211
|
if (match) {
|
|
34039
34212
|
if (waitForExit && terminal) {
|
|
34040
34213
|
sawTerminal = true;
|
|
@@ -34045,9 +34218,14 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
34045
34218
|
reason: "matched",
|
|
34046
34219
|
elapsed_ms: Date.now() - startedAt,
|
|
34047
34220
|
match: match.text,
|
|
34048
|
-
match_offset: scanBaseOffset +
|
|
34221
|
+
match_offset: scanBaseOffset + match.byteOffset
|
|
34049
34222
|
});
|
|
34050
34223
|
}
|
|
34224
|
+
if (waitFor.kind === "substring") {
|
|
34225
|
+
const trimmed = trimWaitScanBuffer(scanText, scanBaseOffset, waitFor);
|
|
34226
|
+
scanText = trimmed.text;
|
|
34227
|
+
scanBaseOffset = trimmed.baseOffset;
|
|
34228
|
+
}
|
|
34051
34229
|
}
|
|
34052
34230
|
}
|
|
34053
34231
|
if (terminal) {
|
|
@@ -34133,20 +34311,69 @@ function parseWaitPattern(value) {
|
|
|
34133
34311
|
if (typeof value === "string")
|
|
34134
34312
|
return { kind: "substring", value };
|
|
34135
34313
|
if (isRegexWaitObject(value))
|
|
34136
|
-
return { kind: "regex",
|
|
34314
|
+
return { kind: "regex", source: value.regex };
|
|
34137
34315
|
return;
|
|
34138
34316
|
}
|
|
34139
34317
|
function isRegexWaitObject(value) {
|
|
34140
34318
|
return typeof value === "object" && value !== null && "regex" in value && typeof value.regex === "string";
|
|
34141
34319
|
}
|
|
34142
|
-
function
|
|
34320
|
+
async function validateWaitRegex(bridge, extCtx, pattern) {
|
|
34321
|
+
await matchRegexWithBridge(bridge, extCtx, pattern.source, "");
|
|
34322
|
+
}
|
|
34323
|
+
async function findWaitMatch(bridge, extCtx, text, pattern) {
|
|
34143
34324
|
if (pattern.kind === "substring") {
|
|
34144
34325
|
const index = text.indexOf(pattern.value);
|
|
34145
|
-
return index >= 0 ? { text: pattern.value, index } : undefined;
|
|
34326
|
+
return index >= 0 ? { text: pattern.value, byteOffset: Buffer.byteLength(text.slice(0, index), "utf8") } : undefined;
|
|
34327
|
+
}
|
|
34328
|
+
return await matchRegexWithBridge(bridge, extCtx, pattern.source, text);
|
|
34329
|
+
}
|
|
34330
|
+
async function matchRegexWithBridge(bridge, extCtx, pattern, text) {
|
|
34331
|
+
try {
|
|
34332
|
+
const result = await callBashBridge(bridge, "bash_regex_match", { pattern, text }, extCtx);
|
|
34333
|
+
if (result.matched !== true)
|
|
34334
|
+
return;
|
|
34335
|
+
return {
|
|
34336
|
+
text: typeof result.match_text === "string" ? result.match_text : "",
|
|
34337
|
+
byteOffset: coerceMatchOffset(result.match_offset)
|
|
34338
|
+
};
|
|
34339
|
+
} catch (err) {
|
|
34340
|
+
if (err instanceof BridgeError && err.code === "invalid_regex") {
|
|
34341
|
+
throw new Error(`invalid_request: invalid_regex: ${err.message}`);
|
|
34342
|
+
}
|
|
34343
|
+
throw err;
|
|
34146
34344
|
}
|
|
34147
|
-
|
|
34148
|
-
|
|
34149
|
-
|
|
34345
|
+
}
|
|
34346
|
+
function coerceMatchOffset(value) {
|
|
34347
|
+
const offset = typeof value === "number" ? value : Number(value ?? 0);
|
|
34348
|
+
return Number.isFinite(offset) && offset >= 0 ? offset : 0;
|
|
34349
|
+
}
|
|
34350
|
+
function trimWaitScanBuffer(text, baseOffset, pattern) {
|
|
34351
|
+
const keepFrom = pattern.kind === "substring" ? substringKeepStart(text, pattern.value) : regexKeepStart(text, REGEX_WAIT_SCAN_WINDOW_BYTES);
|
|
34352
|
+
if (keepFrom <= 0)
|
|
34353
|
+
return { text, baseOffset };
|
|
34354
|
+
return {
|
|
34355
|
+
text: text.slice(keepFrom),
|
|
34356
|
+
baseOffset: baseOffset + Buffer.byteLength(text.slice(0, keepFrom), "utf8")
|
|
34357
|
+
};
|
|
34358
|
+
}
|
|
34359
|
+
function substringKeepStart(text, pattern) {
|
|
34360
|
+
const keepChars = Math.max(0, pattern.length - 1);
|
|
34361
|
+
return text.length > keepChars ? text.length - keepChars : 0;
|
|
34362
|
+
}
|
|
34363
|
+
function regexKeepStart(text, maxBytes) {
|
|
34364
|
+
if (Buffer.byteLength(text, "utf8") <= maxBytes)
|
|
34365
|
+
return 0;
|
|
34366
|
+
let low = 0;
|
|
34367
|
+
let high = text.length;
|
|
34368
|
+
while (low < high) {
|
|
34369
|
+
const mid = Math.floor((low + high) / 2);
|
|
34370
|
+
if (Buffer.byteLength(text.slice(mid), "utf8") > maxBytes) {
|
|
34371
|
+
low = mid + 1;
|
|
34372
|
+
} else {
|
|
34373
|
+
high = mid;
|
|
34374
|
+
}
|
|
34375
|
+
}
|
|
34376
|
+
return low;
|
|
34150
34377
|
}
|
|
34151
34378
|
function withWaited(data, waited) {
|
|
34152
34379
|
return { ...data, waited };
|
|
@@ -34222,9 +34449,6 @@ function ptyCacheKey(extCtx, taskId) {
|
|
|
34222
34449
|
function watchPtyCacheKey(extCtx, taskId) {
|
|
34223
34450
|
return `${ptyCacheKey(extCtx, taskId)}::watch`;
|
|
34224
34451
|
}
|
|
34225
|
-
function isTerminalStatus(status) {
|
|
34226
|
-
return status === "completed" || status === "failed" || status === "killed" || status === "timed_out";
|
|
34227
|
-
}
|
|
34228
34452
|
function renderBashCall(command, description, theme, context) {
|
|
34229
34453
|
const text = reuseText3(context.lastComponent);
|
|
34230
34454
|
const display = description ?? (command ? shortenCommand(command) : "...");
|
|
@@ -34328,12 +34552,12 @@ function registerConflictsTool(pi, ctx) {
|
|
|
34328
34552
|
async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
|
|
34329
34553
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
34330
34554
|
const reqParams = {};
|
|
34331
|
-
const
|
|
34332
|
-
if (typeof
|
|
34333
|
-
await assertExternalDirectoryPermission(extCtx,
|
|
34555
|
+
const path3 = params?.path;
|
|
34556
|
+
if (typeof path3 === "string" && path3.trim() !== "") {
|
|
34557
|
+
await assertExternalDirectoryPermission(extCtx, path3, "inspect", {
|
|
34334
34558
|
restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
|
|
34335
34559
|
});
|
|
34336
|
-
reqParams.path = await resolvePathArg(extCtx.cwd,
|
|
34560
|
+
reqParams.path = await resolvePathArg(extCtx.cwd, path3);
|
|
34337
34561
|
}
|
|
34338
34562
|
const response = await callBridge(bridge, "git_conflicts", reqParams, extCtx);
|
|
34339
34563
|
return textResult(response.text ?? JSON.stringify(response, null, 2));
|
|
@@ -34732,8 +34956,8 @@ function tier2SummaryPart(summary, key, label) {
|
|
|
34732
34956
|
return `${label} ${status ?? "unavailable"}`;
|
|
34733
34957
|
}
|
|
34734
34958
|
function shortDupOccurrence(entry) {
|
|
34735
|
-
const [
|
|
34736
|
-
return
|
|
34959
|
+
const [path3] = entry.split(":");
|
|
34960
|
+
return path3?.split("/").pop() ?? entry;
|
|
34737
34961
|
}
|
|
34738
34962
|
function tier2TopPreview(summary, theme) {
|
|
34739
34963
|
const lines = [];
|
|
@@ -34942,9 +35166,9 @@ function depthWarning(response, theme, depthField = "depth_limited", truncatedFi
|
|
|
34942
35166
|
const detail = truncated > 0 ? `, ${truncated} truncated` : "";
|
|
34943
35167
|
return theme.fg("warning", `(depth limited${detail})`);
|
|
34944
35168
|
}
|
|
34945
|
-
function renderTracePath(
|
|
35169
|
+
function renderTracePath(path3, index, lines) {
|
|
34946
35170
|
lines.push(`Path ${index + 1}`);
|
|
34947
|
-
asRecords(
|
|
35171
|
+
asRecords(path3.hops).forEach((hop, hopIndex) => {
|
|
34948
35172
|
const symbol2 = asString(hop.symbol) ?? "(unknown)";
|
|
34949
35173
|
const file2 = shortenPath2(asString(hop.file) ?? "(unknown file)");
|
|
34950
35174
|
const line = asNumber(hop.line);
|
|
@@ -34982,15 +35206,15 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
34982
35206
|
return sections2;
|
|
34983
35207
|
}
|
|
34984
35208
|
if (args.op === "trace_to_symbol") {
|
|
34985
|
-
const
|
|
35209
|
+
const path3 = asRecords(response.path);
|
|
34986
35210
|
const complete = asBoolean(response.complete);
|
|
34987
35211
|
const reason = asString(response.reason);
|
|
34988
|
-
if (
|
|
35212
|
+
if (path3.length === 0) {
|
|
34989
35213
|
const prefix = complete === false ? theme.fg("warning", "No complete path") : theme.fg("muted", "No path");
|
|
34990
35214
|
return [`${prefix}${reason ? ` (${reason})` : ""}`];
|
|
34991
35215
|
}
|
|
34992
|
-
const lines = [theme.fg("success", `${
|
|
34993
|
-
|
|
35216
|
+
const lines = [theme.fg("success", `${path3.length} hop${path3.length === 1 ? "" : "s"}`)];
|
|
35217
|
+
path3.forEach((hop, index) => {
|
|
34994
35218
|
const symbol2 = asString(hop.symbol) ?? "(unknown)";
|
|
34995
35219
|
const file2 = shortenPath2(asString(hop.file) ?? "(unknown file)");
|
|
34996
35220
|
const line = asNumber(hop.line);
|
|
@@ -35006,9 +35230,9 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
35006
35230
|
];
|
|
35007
35231
|
if (paths.length === 0)
|
|
35008
35232
|
sections2.push(theme.fg("muted", "No entry paths found."));
|
|
35009
|
-
paths.forEach((
|
|
35233
|
+
paths.forEach((path3, index) => {
|
|
35010
35234
|
const lines = [];
|
|
35011
|
-
renderTracePath(
|
|
35235
|
+
renderTracePath(path3, index, lines);
|
|
35012
35236
|
sections2.push(lines.join(`
|
|
35013
35237
|
`));
|
|
35014
35238
|
});
|
|
@@ -35466,6 +35690,11 @@ Pass a single \`target\`:
|
|
|
35466
35690
|
}));
|
|
35467
35691
|
if (symbolsArray.length === 1) {
|
|
35468
35692
|
const response2 = results[0] ?? { success: false, message: "missing zoom response" };
|
|
35693
|
+
const rustBatch = unwrapRustZoomBatchEnvelope(response2);
|
|
35694
|
+
if (rustBatch) {
|
|
35695
|
+
const batch2 = formatZoomBatchResult(targetLabel, rustBatch.names, rustBatch.responses);
|
|
35696
|
+
return textResult(batch2.text, batch2);
|
|
35697
|
+
}
|
|
35469
35698
|
if (response2.success === false) {
|
|
35470
35699
|
throw new Error(response2.message || "zoom failed");
|
|
35471
35700
|
}
|
|
@@ -35701,7 +35930,7 @@ function registerRefactorTool(pi, ctx) {
|
|
|
35701
35930
|
import { StringEnum as StringEnum5 } from "@earendil-works/pi-ai";
|
|
35702
35931
|
import { Type as Type12 } from "typebox";
|
|
35703
35932
|
function responsePaths(response) {
|
|
35704
|
-
return Array.isArray(response.paths) ? response.paths.filter((
|
|
35933
|
+
return Array.isArray(response.paths) ? response.paths.filter((path3) => typeof path3 === "string" && path3.length > 0) : [];
|
|
35705
35934
|
}
|
|
35706
35935
|
var SafetyParams = Type12.Object({
|
|
35707
35936
|
op: StringEnum5(["undo", "history", "checkpoint", "restore", "list"], {
|
|
@@ -36167,18 +36396,18 @@ function createVersionMismatchHandler(getPool, ensureCompatibleBinary = ensureBi
|
|
|
36167
36396
|
const upgradePromise = (async () => {
|
|
36168
36397
|
warn2(`WARNING: aft binary v${binaryVersion} is older than plugin v${minVersion}. ` + "Some features may not work. Attempting to download a compatible binary...");
|
|
36169
36398
|
try {
|
|
36170
|
-
const
|
|
36171
|
-
if (!
|
|
36399
|
+
const path3 = await ensureCompatibleBinary(`v${minVersion}`);
|
|
36400
|
+
if (!path3) {
|
|
36172
36401
|
warn2(`Could not find or download v${minVersion}. Continuing with v${binaryVersion}.`);
|
|
36173
36402
|
return null;
|
|
36174
36403
|
}
|
|
36175
36404
|
const pool = getPool();
|
|
36176
36405
|
if (!pool) {
|
|
36177
|
-
warn2(`Found/downloaded compatible binary at ${
|
|
36406
|
+
warn2(`Found/downloaded compatible binary at ${path3}, but bridge pool is not ready.`);
|
|
36178
36407
|
return null;
|
|
36179
36408
|
}
|
|
36180
|
-
log2(`Found/downloaded compatible binary at ${
|
|
36181
|
-
const replaced = await pool.replaceBinary(
|
|
36409
|
+
log2(`Found/downloaded compatible binary at ${path3}. Replacing running bridges...`);
|
|
36410
|
+
const replaced = await pool.replaceBinary(path3);
|
|
36182
36411
|
log2("Binary replaced successfully. New bridges will use the updated binary.");
|
|
36183
36412
|
return replaced;
|
|
36184
36413
|
} catch (err) {
|
|
@@ -36200,12 +36429,11 @@ var PLUGIN_VERSION = (() => {
|
|
|
36200
36429
|
return "0.0.0";
|
|
36201
36430
|
}
|
|
36202
36431
|
})();
|
|
36203
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
36432
|
+
var ANNOUNCEMENT_VERSION = "0.39.0";
|
|
36204
36433
|
var ANNOUNCEMENT_FEATURES = [
|
|
36205
|
-
"
|
|
36206
|
-
"
|
|
36207
|
-
"
|
|
36208
|
-
"Transient environment errors (schema fetch timeouts) no longer count as code errors in the status bar."
|
|
36434
|
+
"Accurate Rust dead code: constructors and associated functions reached through receiver-type inference are no longer mis-reported as dead.",
|
|
36435
|
+
"Code Health scans reparse only the file you changed instead of the whole project on every edit — a single-file edit dropped from ~3s of scan work to ~130ms on this repo, byte-identical results.",
|
|
36436
|
+
"R language support in outline, zoom, and the AST tools."
|
|
36209
36437
|
];
|
|
36210
36438
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
36211
36439
|
var ALL_ONLY_TOOLS = new Set(["aft_callgraph", "aft_delete", "aft_move", "aft_refactor"]);
|
|
@@ -36504,7 +36732,7 @@ ${lines}
|
|
|
36504
36732
|
if (onnxRuntimePromise) {
|
|
36505
36733
|
await Promise.race([
|
|
36506
36734
|
onnxRuntimePromise,
|
|
36507
|
-
new Promise((
|
|
36735
|
+
new Promise((resolve5) => setTimeout(() => resolve5(null), 60000))
|
|
36508
36736
|
]);
|
|
36509
36737
|
}
|
|
36510
36738
|
const bridge = pool.getBridge(cwd);
|