@cortexkit/aft-pi 0.39.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.js +604 -433
- 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.`;
|
|
@@ -11704,18 +11742,87 @@ function commandInvokesCodeSearch(command) {
|
|
|
11704
11742
|
}
|
|
11705
11743
|
return false;
|
|
11706
11744
|
}
|
|
11707
|
-
function maybeAppendGrepSearchHint(output, command, aftSearchRegistered) {
|
|
11745
|
+
function maybeAppendGrepSearchHint(output, command, aftSearchRegistered, projectRoot) {
|
|
11708
11746
|
if (output === "")
|
|
11709
11747
|
return output;
|
|
11710
11748
|
if (!commandInvokesCodeSearch(command))
|
|
11711
11749
|
return output;
|
|
11712
11750
|
if (output.includes(GREP_SEARCH_HINT_PREFIX))
|
|
11713
11751
|
return output;
|
|
11752
|
+
if (shouldSuppressGrepSearchHint(command, projectRoot))
|
|
11753
|
+
return output;
|
|
11714
11754
|
const hint = aftSearchRegistered ? GREP_SEARCH_AFT_SEARCH_HINT : GREP_SEARCH_GREP_HINT;
|
|
11715
11755
|
return `${output}
|
|
11716
11756
|
|
|
11717
11757
|
${hint}`;
|
|
11718
11758
|
}
|
|
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
|
+
}
|
|
11719
11826
|
function splitTopLevelStatements(command) {
|
|
11720
11827
|
const statements = [];
|
|
11721
11828
|
let start = 0;
|
|
@@ -11895,8 +12002,8 @@ function resolveBashKillTimeout(modelTimeout, foregroundWaitMs) {
|
|
|
11895
12002
|
}
|
|
11896
12003
|
// ../aft-bridge/dist/bridge.js
|
|
11897
12004
|
import { spawn } from "node:child_process";
|
|
11898
|
-
import { homedir } from "node:os";
|
|
11899
|
-
import { join } from "node:path";
|
|
12005
|
+
import { homedir as homedir2 } from "node:os";
|
|
12006
|
+
import { join as join2 } from "node:path";
|
|
11900
12007
|
import { StringDecoder } from "node:string_decoder";
|
|
11901
12008
|
|
|
11902
12009
|
// ../aft-bridge/dist/command-timeouts.js
|
|
@@ -12269,7 +12376,7 @@ class BinaryBridge {
|
|
|
12269
12376
|
`;
|
|
12270
12377
|
const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
|
|
12271
12378
|
let requestSentAt = Date.now();
|
|
12272
|
-
const response = await new Promise((
|
|
12379
|
+
const response = await new Promise((resolve2, reject) => {
|
|
12273
12380
|
const timer = setTimeout(() => {
|
|
12274
12381
|
const entry = this.pending.get(id);
|
|
12275
12382
|
if (!entry)
|
|
@@ -12304,7 +12411,7 @@ class BinaryBridge {
|
|
|
12304
12411
|
entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
12305
12412
|
this.handleTimeout(requestSessionId);
|
|
12306
12413
|
}, effectiveTimeoutMs);
|
|
12307
|
-
this.pending.set(id, { resolve, reject, timer, onProgress: options?.onProgress, command });
|
|
12414
|
+
this.pending.set(id, { resolve: resolve2, reject, timer, onProgress: options?.onProgress, command });
|
|
12308
12415
|
if (!this.process?.stdin?.writable) {
|
|
12309
12416
|
this.pending.delete(id);
|
|
12310
12417
|
clearTimeout(timer);
|
|
@@ -12402,15 +12509,15 @@ class BinaryBridge {
|
|
|
12402
12509
|
if (this.process) {
|
|
12403
12510
|
const proc = this.process;
|
|
12404
12511
|
this.process = null;
|
|
12405
|
-
return new Promise((
|
|
12512
|
+
return new Promise((resolve2) => {
|
|
12406
12513
|
const forceKillTimer = setTimeout(() => {
|
|
12407
12514
|
proc.kill("SIGKILL");
|
|
12408
|
-
|
|
12515
|
+
resolve2();
|
|
12409
12516
|
}, 5000);
|
|
12410
12517
|
proc.once("exit", () => {
|
|
12411
12518
|
clearTimeout(forceKillTimer);
|
|
12412
12519
|
this.logVia("Process exited during shutdown");
|
|
12413
|
-
|
|
12520
|
+
resolve2();
|
|
12414
12521
|
});
|
|
12415
12522
|
proc.kill("SIGTERM");
|
|
12416
12523
|
});
|
|
@@ -12455,15 +12562,15 @@ class BinaryBridge {
|
|
|
12455
12562
|
return;
|
|
12456
12563
|
const proc = this.process;
|
|
12457
12564
|
this.process = null;
|
|
12458
|
-
await new Promise((
|
|
12565
|
+
await new Promise((resolve2) => {
|
|
12459
12566
|
const forceKillTimer = setTimeout(() => {
|
|
12460
12567
|
proc.kill("SIGKILL");
|
|
12461
|
-
|
|
12568
|
+
resolve2();
|
|
12462
12569
|
}, 5000);
|
|
12463
12570
|
proc.once("exit", () => {
|
|
12464
12571
|
clearTimeout(forceKillTimer);
|
|
12465
12572
|
this.logVia("Process exited during coordinated binary replacement");
|
|
12466
|
-
|
|
12573
|
+
resolve2();
|
|
12467
12574
|
});
|
|
12468
12575
|
proc.kill("SIGTERM");
|
|
12469
12576
|
});
|
|
@@ -12490,7 +12597,7 @@ class BinaryBridge {
|
|
|
12490
12597
|
})();
|
|
12491
12598
|
const useFastembedBackend = semanticBackend === undefined || semanticBackend === "fastembed" || semanticBackend === "";
|
|
12492
12599
|
const ortDir = typeof this.configOverrides._ort_dylib_dir === "string" && useFastembedBackend ? this.configOverrides._ort_dylib_dir : null;
|
|
12493
|
-
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");
|
|
12494
12601
|
const envPath = process.platform === "win32" && ortDir ? `${ortDir};${process.env.PATH ?? ""}` : process.env.PATH;
|
|
12495
12602
|
const env = {
|
|
12496
12603
|
...process.env,
|
|
@@ -12498,7 +12605,7 @@ class BinaryBridge {
|
|
|
12498
12605
|
};
|
|
12499
12606
|
this.logVia(`bridge.spawnProcess: useFastembedBackend=${useFastembedBackend}, ` + `parentORT=${process.env.ORT_DYLIB_PATH ?? "(unset)"}, ` + `ortLibraryPath=${ortLibraryPath ?? "(none)"}`);
|
|
12500
12607
|
if (useFastembedBackend) {
|
|
12501
|
-
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"));
|
|
12502
12609
|
if (process.env.ORT_DYLIB_PATH) {
|
|
12503
12610
|
this.logVia(`ORT_DYLIB_PATH inherited from parent env: ${process.env.ORT_DYLIB_PATH}`);
|
|
12504
12611
|
} else if (ortLibraryPath) {
|
|
@@ -12840,12 +12947,37 @@ function coerceStringArray(value) {
|
|
|
12840
12947
|
}
|
|
12841
12948
|
return [];
|
|
12842
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
|
+
}
|
|
12843
12975
|
// ../aft-bridge/dist/downloader.js
|
|
12844
12976
|
import { spawnSync } from "node:child_process";
|
|
12845
12977
|
import { createHash, randomUUID } from "node:crypto";
|
|
12846
12978
|
import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
|
|
12847
|
-
import { homedir as
|
|
12848
|
-
import { join as
|
|
12979
|
+
import { homedir as homedir3 } from "node:os";
|
|
12980
|
+
import { join as join3 } from "node:path";
|
|
12849
12981
|
import { Readable } from "node:stream";
|
|
12850
12982
|
import { pipeline } from "node:stream/promises";
|
|
12851
12983
|
|
|
@@ -12902,11 +13034,11 @@ function isExpectedCachedBinary(binaryPath, tag) {
|
|
|
12902
13034
|
function getCacheDir() {
|
|
12903
13035
|
if (process.platform === "win32") {
|
|
12904
13036
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
12905
|
-
const base2 = localAppData ||
|
|
12906
|
-
return
|
|
13037
|
+
const base2 = localAppData || join3(homedir3(), "AppData", "Local");
|
|
13038
|
+
return join3(base2, "aft", "bin");
|
|
12907
13039
|
}
|
|
12908
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
12909
|
-
return
|
|
13040
|
+
const base = process.env.XDG_CACHE_HOME || join3(homedir3(), ".cache");
|
|
13041
|
+
return join3(base, "aft", "bin");
|
|
12910
13042
|
}
|
|
12911
13043
|
function getBinaryName() {
|
|
12912
13044
|
return process.platform === "win32" ? "aft.exe" : "aft";
|
|
@@ -12914,7 +13046,7 @@ function getBinaryName() {
|
|
|
12914
13046
|
function getCachedBinaryPath(version) {
|
|
12915
13047
|
if (!version)
|
|
12916
13048
|
return null;
|
|
12917
|
-
const binaryPath =
|
|
13049
|
+
const binaryPath = join3(getCacheDir(), version, getBinaryName());
|
|
12918
13050
|
return existsSync(binaryPath) ? binaryPath : null;
|
|
12919
13051
|
}
|
|
12920
13052
|
async function downloadBinary(version) {
|
|
@@ -12931,16 +13063,16 @@ async function downloadBinary(version) {
|
|
|
12931
13063
|
return null;
|
|
12932
13064
|
}
|
|
12933
13065
|
const tag = rawTag.startsWith("v") ? rawTag : `v${rawTag}`;
|
|
12934
|
-
const versionedCacheDir =
|
|
13066
|
+
const versionedCacheDir = join3(getCacheDir(), tag);
|
|
12935
13067
|
const binaryName = getBinaryName();
|
|
12936
|
-
const binaryPath =
|
|
13068
|
+
const binaryPath = join3(versionedCacheDir, binaryName);
|
|
12937
13069
|
if (existsSync(binaryPath) && isExpectedCachedBinary(binaryPath, tag)) {
|
|
12938
13070
|
return binaryPath;
|
|
12939
13071
|
}
|
|
12940
13072
|
const downloadUrl = `https://github.com/${REPO}/releases/download/${tag}/${assetName}`;
|
|
12941
13073
|
const checksumUrl = `https://github.com/${REPO}/releases/download/${tag}/checksums.sha256`;
|
|
12942
13074
|
log(`Downloading AFT binary (${tag}) for ${platformKey}...`);
|
|
12943
|
-
const lockPath =
|
|
13075
|
+
const lockPath = join3(versionedCacheDir, ".download.lock");
|
|
12944
13076
|
let releaseLock = null;
|
|
12945
13077
|
let binaryController = null;
|
|
12946
13078
|
let checksumController = null;
|
|
@@ -13092,7 +13224,7 @@ async function acquireDownloadLock(lockPath) {
|
|
|
13092
13224
|
if (Date.now() - startedAt > DOWNLOAD_LOCK_TIMEOUT_MS) {
|
|
13093
13225
|
throw new Error(`Timed out waiting for download lock: ${lockPath}`);
|
|
13094
13226
|
}
|
|
13095
|
-
await new Promise((
|
|
13227
|
+
await new Promise((resolve2) => setTimeout(resolve2, 100));
|
|
13096
13228
|
}
|
|
13097
13229
|
}
|
|
13098
13230
|
}
|
|
@@ -13185,18 +13317,18 @@ function stripJsoncSymbols(value) {
|
|
|
13185
13317
|
// ../aft-bridge/dist/migration.js
|
|
13186
13318
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
13187
13319
|
import { existsSync as existsSync4, mkdirSync as mkdirSync4 } from "node:fs";
|
|
13188
|
-
import { homedir as
|
|
13189
|
-
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";
|
|
13190
13322
|
|
|
13191
13323
|
// ../aft-bridge/dist/paths.js
|
|
13192
13324
|
import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync as renameSync2, writeFileSync } from "node:fs";
|
|
13193
|
-
import { dirname, join as
|
|
13325
|
+
import { dirname, join as join4 } from "node:path";
|
|
13194
13326
|
function resolveHarnessStoragePath(storageRoot, harness, ...segments) {
|
|
13195
|
-
return
|
|
13327
|
+
return join4(storageRoot, harness, ...segments);
|
|
13196
13328
|
}
|
|
13197
13329
|
function repairRootScopedStorageFile(storageRoot, harness, fileName) {
|
|
13198
13330
|
const harnessPath = resolveHarnessStoragePath(storageRoot, harness, fileName);
|
|
13199
|
-
const rootPath =
|
|
13331
|
+
const rootPath = join4(storageRoot, fileName);
|
|
13200
13332
|
if (existsSync2(harnessPath) || !existsSync2(rootPath))
|
|
13201
13333
|
return harnessPath;
|
|
13202
13334
|
try {
|
|
@@ -13242,8 +13374,8 @@ function markAnnouncementSeen(storageRoot, harness, currentVersion) {
|
|
|
13242
13374
|
import { execSync } from "node:child_process";
|
|
13243
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";
|
|
13244
13376
|
import { createRequire as createRequire2 } from "node:module";
|
|
13245
|
-
import { homedir as
|
|
13246
|
-
import { join as
|
|
13377
|
+
import { homedir as homedir4 } from "node:os";
|
|
13378
|
+
import { join as join5 } from "node:path";
|
|
13247
13379
|
var ensureBinaryForResolver = ensureBinary;
|
|
13248
13380
|
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
13249
13381
|
try {
|
|
@@ -13252,9 +13384,9 @@ function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
|
13252
13384
|
return null;
|
|
13253
13385
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
13254
13386
|
const cacheDir = getCacheDir();
|
|
13255
|
-
const versionedDir =
|
|
13387
|
+
const versionedDir = join5(cacheDir, tag);
|
|
13256
13388
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
13257
|
-
const cachedPath =
|
|
13389
|
+
const cachedPath = join5(versionedDir, `aft${ext}`);
|
|
13258
13390
|
if (existsSync3(cachedPath)) {
|
|
13259
13391
|
const cachedVersion = readBinaryVersion(cachedPath);
|
|
13260
13392
|
if (cachedVersion === version)
|
|
@@ -13284,18 +13416,18 @@ function normalizeBareVersion(version) {
|
|
|
13284
13416
|
return version.startsWith("v") ? version.slice(1) : version;
|
|
13285
13417
|
}
|
|
13286
13418
|
function homeDirFromEnv(env) {
|
|
13287
|
-
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) ||
|
|
13419
|
+
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir4();
|
|
13288
13420
|
}
|
|
13289
13421
|
function cacheDirFromEnv(env) {
|
|
13290
13422
|
if (process.platform === "win32") {
|
|
13291
|
-
const base2 = env.LOCALAPPDATA || env.APPDATA ||
|
|
13292
|
-
return
|
|
13423
|
+
const base2 = env.LOCALAPPDATA || env.APPDATA || join5(homeDirFromEnv(env), "AppData", "Local");
|
|
13424
|
+
return join5(base2, "aft", "bin");
|
|
13293
13425
|
}
|
|
13294
|
-
const base = env.XDG_CACHE_HOME ||
|
|
13295
|
-
return
|
|
13426
|
+
const base = env.XDG_CACHE_HOME || join5(homeDirFromEnv(env), ".cache");
|
|
13427
|
+
return join5(base, "aft", "bin");
|
|
13296
13428
|
}
|
|
13297
13429
|
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
13298
|
-
const binaryPath =
|
|
13430
|
+
const binaryPath = join5(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
13299
13431
|
return existsSync3(binaryPath) ? binaryPath : null;
|
|
13300
13432
|
}
|
|
13301
13433
|
function isExpectedCachedBinary2(binaryPath, expectedVersion) {
|
|
@@ -13414,7 +13546,7 @@ function findBinarySync(expectedVersion) {
|
|
|
13414
13546
|
return usable;
|
|
13415
13547
|
}
|
|
13416
13548
|
} catch {}
|
|
13417
|
-
const cargoPath =
|
|
13549
|
+
const cargoPath = join5(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
13418
13550
|
if (existsSync3(cargoPath)) {
|
|
13419
13551
|
const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
|
|
13420
13552
|
if (usable)
|
|
@@ -13460,22 +13592,22 @@ function dataHome() {
|
|
|
13460
13592
|
if (process.env.XDG_DATA_HOME)
|
|
13461
13593
|
return process.env.XDG_DATA_HOME;
|
|
13462
13594
|
if (process.platform === "win32") {
|
|
13463
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA ||
|
|
13595
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join6(homeDir(), "AppData", "Local");
|
|
13464
13596
|
}
|
|
13465
|
-
return
|
|
13597
|
+
return join6(homeDir(), ".local", "share");
|
|
13466
13598
|
}
|
|
13467
13599
|
function homeDir() {
|
|
13468
13600
|
if (process.platform === "win32")
|
|
13469
|
-
return process.env.USERPROFILE || process.env.HOME ||
|
|
13470
|
-
return process.env.HOME ||
|
|
13601
|
+
return process.env.USERPROFILE || process.env.HOME || homedir5();
|
|
13602
|
+
return process.env.HOME || homedir5();
|
|
13471
13603
|
}
|
|
13472
13604
|
function resolveLegacyStorageRoot(harness) {
|
|
13473
13605
|
if (harness === "pi")
|
|
13474
|
-
return
|
|
13475
|
-
return
|
|
13606
|
+
return join6(homeDir(), ".pi", "agent", "aft");
|
|
13607
|
+
return join6(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
13476
13608
|
}
|
|
13477
13609
|
function resolveCortexKitStorageRoot() {
|
|
13478
|
-
return
|
|
13610
|
+
return join6(dataHome(), "cortexkit", "aft");
|
|
13479
13611
|
}
|
|
13480
13612
|
function tail(value) {
|
|
13481
13613
|
if (!value)
|
|
@@ -13489,12 +13621,12 @@ function spawnErrorLabel(error2) {
|
|
|
13489
13621
|
return [code, error2.message].filter(Boolean).join(": ");
|
|
13490
13622
|
}
|
|
13491
13623
|
function migrationLogPath(newRoot, harness, logger) {
|
|
13492
|
-
const desired =
|
|
13624
|
+
const desired = join6(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
13493
13625
|
try {
|
|
13494
13626
|
mkdirSync4(dirname2(desired), { recursive: true });
|
|
13495
13627
|
return desired;
|
|
13496
13628
|
} catch (err) {
|
|
13497
|
-
const fallback =
|
|
13629
|
+
const fallback = join6(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
13498
13630
|
logger?.warn?.(`Failed to create AFT migration log directory ${dirname2(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
13499
13631
|
return fallback;
|
|
13500
13632
|
}
|
|
@@ -13557,13 +13689,13 @@ async function ensureStorageMigrated(opts) {
|
|
|
13557
13689
|
}
|
|
13558
13690
|
// ../aft-bridge/dist/npm-resolver.js
|
|
13559
13691
|
import { readdirSync, statSync as statSync2 } from "node:fs";
|
|
13560
|
-
import { homedir as
|
|
13561
|
-
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";
|
|
13562
13694
|
function defaultDeps() {
|
|
13563
13695
|
return {
|
|
13564
13696
|
platform: process.platform,
|
|
13565
13697
|
env: process.env,
|
|
13566
|
-
home:
|
|
13698
|
+
home: homedir6(),
|
|
13567
13699
|
execPath: process.execPath
|
|
13568
13700
|
};
|
|
13569
13701
|
}
|
|
@@ -13582,16 +13714,16 @@ function npmFromPath(deps) {
|
|
|
13582
13714
|
const raw = deps.env.PATH ?? deps.env.Path ?? "";
|
|
13583
13715
|
for (const entry of raw.split(delimiter)) {
|
|
13584
13716
|
const dir = entry.trim().replace(/^"|"$/g, "");
|
|
13585
|
-
if (!dir || !
|
|
13717
|
+
if (!dir || !isAbsolute2(dir))
|
|
13586
13718
|
continue;
|
|
13587
|
-
if (isFile(
|
|
13719
|
+
if (isFile(join7(dir, name)))
|
|
13588
13720
|
return dir;
|
|
13589
13721
|
}
|
|
13590
13722
|
return null;
|
|
13591
13723
|
}
|
|
13592
13724
|
function npmAdjacentToNode(deps) {
|
|
13593
13725
|
const dir = dirname3(deps.execPath);
|
|
13594
|
-
return isFile(
|
|
13726
|
+
return isFile(join7(dir, npmBinaryName(deps.platform))) ? dir : null;
|
|
13595
13727
|
}
|
|
13596
13728
|
function highestVersionedNodeBin(installsDir, name) {
|
|
13597
13729
|
let entries;
|
|
@@ -13600,8 +13732,8 @@ function highestVersionedNodeBin(installsDir, name) {
|
|
|
13600
13732
|
} catch {
|
|
13601
13733
|
return null;
|
|
13602
13734
|
}
|
|
13603
|
-
const candidates = entries.filter((v) => isFile(
|
|
13604
|
-
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;
|
|
13605
13737
|
}
|
|
13606
13738
|
function compareVersionsDesc(a, b) {
|
|
13607
13739
|
const pa = a.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
|
|
@@ -13626,22 +13758,22 @@ function wellKnownNpmDirs(deps) {
|
|
|
13626
13758
|
const programFiles = env.ProgramFiles || "C:\\Program Files";
|
|
13627
13759
|
const appData = env.APPDATA;
|
|
13628
13760
|
const localAppData = env.LOCALAPPDATA;
|
|
13629
|
-
push(
|
|
13761
|
+
push(join7(programFiles, "nodejs"));
|
|
13630
13762
|
if (appData)
|
|
13631
|
-
push(
|
|
13763
|
+
push(join7(appData, "npm"));
|
|
13632
13764
|
if (localAppData)
|
|
13633
|
-
push(
|
|
13765
|
+
push(join7(localAppData, "Volta", "bin"));
|
|
13634
13766
|
if (env.NVM_SYMLINK)
|
|
13635
13767
|
push(env.NVM_SYMLINK);
|
|
13636
13768
|
} else {
|
|
13637
13769
|
if (env.NVM_BIN)
|
|
13638
13770
|
push(env.NVM_BIN);
|
|
13639
|
-
push(highestVersionedNodeBin(
|
|
13640
|
-
push(highestVersionedNodeBin(
|
|
13641
|
-
push(highestVersionedNodeBin(
|
|
13642
|
-
push(
|
|
13643
|
-
push(
|
|
13644
|
-
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")]);
|
|
13645
13777
|
for (const dir of systemDirs)
|
|
13646
13778
|
push(dir);
|
|
13647
13779
|
}
|
|
@@ -13651,12 +13783,12 @@ function resolveNpm(deps = defaultDeps()) {
|
|
|
13651
13783
|
const name = npmBinaryName(deps.platform);
|
|
13652
13784
|
const onPath = npmFromPath(deps);
|
|
13653
13785
|
if (onPath)
|
|
13654
|
-
return { command:
|
|
13786
|
+
return { command: join7(onPath, name), binDir: onPath };
|
|
13655
13787
|
const adjacent = npmAdjacentToNode(deps);
|
|
13656
13788
|
if (adjacent)
|
|
13657
|
-
return { command:
|
|
13789
|
+
return { command: join7(adjacent, name), binDir: adjacent };
|
|
13658
13790
|
for (const dir of wellKnownNpmDirs(deps)) {
|
|
13659
|
-
const candidate =
|
|
13791
|
+
const candidate = join7(dir, name);
|
|
13660
13792
|
if (isFile(candidate))
|
|
13661
13793
|
return { command: candidate, binDir: dir };
|
|
13662
13794
|
}
|
|
@@ -13673,7 +13805,7 @@ function npmSpawnEnv(resolved, baseEnv = process.env) {
|
|
|
13673
13805
|
import { execFileSync } from "node:child_process";
|
|
13674
13806
|
import { createHash as createHash2 } from "node:crypto";
|
|
13675
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";
|
|
13676
|
-
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";
|
|
13677
13809
|
import { Readable as Readable2 } from "node:stream";
|
|
13678
13810
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
13679
13811
|
var ORT_VERSION = "1.24.4";
|
|
@@ -13736,10 +13868,10 @@ function getManualInstallHint() {
|
|
|
13736
13868
|
}
|
|
13737
13869
|
async function ensureOnnxRuntime(storageDir) {
|
|
13738
13870
|
const info = getPlatformInfo();
|
|
13739
|
-
const ortVersionDir =
|
|
13871
|
+
const ortVersionDir = join8(storageDir, "onnxruntime", ORT_VERSION);
|
|
13740
13872
|
const libName = info?.libName ?? "libonnxruntime.dylib";
|
|
13741
13873
|
const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
|
|
13742
|
-
const libPath =
|
|
13874
|
+
const libPath = join8(resolvedOrtDir, libName);
|
|
13743
13875
|
if (existsSync5(libPath)) {
|
|
13744
13876
|
const meta = readOnnxInstalledMeta(ortVersionDir);
|
|
13745
13877
|
if (meta?.sha256) {
|
|
@@ -13769,9 +13901,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
13769
13901
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
13770
13902
|
return null;
|
|
13771
13903
|
}
|
|
13772
|
-
const onnxBaseDir =
|
|
13904
|
+
const onnxBaseDir = join8(storageDir, "onnxruntime");
|
|
13773
13905
|
mkdirSync5(onnxBaseDir, { recursive: true });
|
|
13774
|
-
const lockPath =
|
|
13906
|
+
const lockPath = join8(onnxBaseDir, ONNX_LOCK_FILE);
|
|
13775
13907
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
13776
13908
|
if (!acquireLock(lockPath)) {
|
|
13777
13909
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -13790,7 +13922,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
13790
13922
|
for (const entry of entries) {
|
|
13791
13923
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
13792
13924
|
continue;
|
|
13793
|
-
const stagingDir =
|
|
13925
|
+
const stagingDir = join8(onnxBaseDir, entry);
|
|
13794
13926
|
const parts = entry.split(".");
|
|
13795
13927
|
const pidStr = parts[parts.length - 2];
|
|
13796
13928
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -13827,7 +13959,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
13827
13959
|
}
|
|
13828
13960
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
13829
13961
|
try {
|
|
13830
|
-
if (existsSync5(ortDir) && !existsSync5(
|
|
13962
|
+
if (existsSync5(ortDir) && !existsSync5(join8(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
13831
13963
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
13832
13964
|
rmSync2(ortDir, { recursive: true, force: true });
|
|
13833
13965
|
}
|
|
@@ -13855,8 +13987,8 @@ function parseOnnxVersionFromDirectoryPath(value) {
|
|
|
13855
13987
|
return null;
|
|
13856
13988
|
}
|
|
13857
13989
|
function isPathInsideRoot(root, candidate) {
|
|
13858
|
-
const rel =
|
|
13859
|
-
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);
|
|
13860
13992
|
}
|
|
13861
13993
|
function detectOnnxVersion(libDir, libName) {
|
|
13862
13994
|
try {
|
|
@@ -13871,7 +14003,7 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
13871
14003
|
if (version)
|
|
13872
14004
|
return version;
|
|
13873
14005
|
}
|
|
13874
|
-
const base =
|
|
14006
|
+
const base = join8(libDir, libName);
|
|
13875
14007
|
if (existsSync5(base)) {
|
|
13876
14008
|
try {
|
|
13877
14009
|
const real = realpathSync(base);
|
|
@@ -13907,7 +14039,7 @@ function pathEntriesForPlatform() {
|
|
|
13907
14039
|
return pathEnvValue().split(delimiter2).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter((entry) => {
|
|
13908
14040
|
if (!entry || entry === "." || entry.includes("\x00"))
|
|
13909
14041
|
return false;
|
|
13910
|
-
return
|
|
14042
|
+
return isAbsolute3(entry) || win32.isAbsolute(entry);
|
|
13911
14043
|
});
|
|
13912
14044
|
}
|
|
13913
14045
|
function directoryContainsLibrary(dir, libName) {
|
|
@@ -13923,10 +14055,10 @@ function directoryContainsLibrary(dir, libName) {
|
|
|
13923
14055
|
}
|
|
13924
14056
|
}
|
|
13925
14057
|
function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
|
|
13926
|
-
if (existsSync5(
|
|
14058
|
+
if (existsSync5(join8(ortVersionDir, libName)))
|
|
13927
14059
|
return ortVersionDir;
|
|
13928
|
-
const libSubdir =
|
|
13929
|
-
if (existsSync5(
|
|
14060
|
+
const libSubdir = join8(ortVersionDir, "lib");
|
|
14061
|
+
if (existsSync5(join8(libSubdir, libName)))
|
|
13930
14062
|
return libSubdir;
|
|
13931
14063
|
return ortVersionDir;
|
|
13932
14064
|
}
|
|
@@ -13941,12 +14073,12 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13941
14073
|
} else if (process.platform === "win32") {
|
|
13942
14074
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
13943
14075
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
13944
|
-
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"), ...(() => {
|
|
13945
14077
|
const nugetPaths = [];
|
|
13946
14078
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
13947
14079
|
if (!userProfile)
|
|
13948
14080
|
return nugetPaths;
|
|
13949
|
-
const nugetPackageDir =
|
|
14081
|
+
const nugetPackageDir = join8(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
13950
14082
|
if (!existsSync5(nugetPackageDir))
|
|
13951
14083
|
return nugetPaths;
|
|
13952
14084
|
try {
|
|
@@ -13955,7 +14087,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13955
14087
|
continue;
|
|
13956
14088
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
13957
14089
|
continue;
|
|
13958
|
-
nugetPaths.push(
|
|
14090
|
+
nugetPaths.push(join8(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join8(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
13959
14091
|
}
|
|
13960
14092
|
} catch (err) {
|
|
13961
14093
|
warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -13967,7 +14099,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13967
14099
|
const normalizeCase = process.platform === "win32" || process.platform === "darwin";
|
|
13968
14100
|
const seen = new Set;
|
|
13969
14101
|
const uniquePaths = searchPaths.filter((p) => {
|
|
13970
|
-
let key =
|
|
14102
|
+
let key = resolve2(p).replace(/[/\\]+$/, "");
|
|
13971
14103
|
if (normalizeCase)
|
|
13972
14104
|
key = key.toLowerCase();
|
|
13973
14105
|
if (seen.has(key))
|
|
@@ -13977,7 +14109,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
13977
14109
|
});
|
|
13978
14110
|
const unknownVersionPaths = [];
|
|
13979
14111
|
for (const dir of uniquePaths) {
|
|
13980
|
-
const libPath =
|
|
14112
|
+
const libPath = join8(dir, libName);
|
|
13981
14113
|
if (process.platform === "win32") {
|
|
13982
14114
|
if (!directoryContainsLibrary(dir, libName))
|
|
13983
14115
|
continue;
|
|
@@ -14043,19 +14175,19 @@ function validateExtractedTree(stagingRoot) {
|
|
|
14043
14175
|
const walk = (dir) => {
|
|
14044
14176
|
const entries = readdirSync2(dir);
|
|
14045
14177
|
for (const entry of entries) {
|
|
14046
|
-
const fullPath =
|
|
14178
|
+
const fullPath = join8(dir, entry);
|
|
14047
14179
|
const lst = lstatSync(fullPath);
|
|
14048
14180
|
if (lst.isSymbolicLink()) {
|
|
14049
14181
|
const linkTarget = readlinkSync(fullPath);
|
|
14050
|
-
const resolvedTarget =
|
|
14051
|
-
const rel2 =
|
|
14052
|
-
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)) {
|
|
14053
14185
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
14054
14186
|
}
|
|
14055
14187
|
continue;
|
|
14056
14188
|
}
|
|
14057
|
-
const rel =
|
|
14058
|
-
if (rel.startsWith("..") ||
|
|
14189
|
+
const rel = relative2(realRoot, fullPath);
|
|
14190
|
+
if (rel.startsWith("..") || isAbsolute3(rel) || win32.isAbsolute(rel)) {
|
|
14059
14191
|
throw new Error(`extracted entry ${fullPath} escapes staging root`);
|
|
14060
14192
|
}
|
|
14061
14193
|
if (lst.isDirectory()) {
|
|
@@ -14078,7 +14210,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14078
14210
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
14079
14211
|
try {
|
|
14080
14212
|
mkdirSync5(tmpDir, { recursive: true });
|
|
14081
|
-
const archivePath =
|
|
14213
|
+
const archivePath = join8(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
14082
14214
|
await downloadFileWithCap(url, archivePath);
|
|
14083
14215
|
const archiveSha256 = sha256File(archivePath);
|
|
14084
14216
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -14094,7 +14226,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14094
14226
|
unlinkSync3(archivePath);
|
|
14095
14227
|
} catch {}
|
|
14096
14228
|
validateExtractedTree(tmpDir);
|
|
14097
|
-
const extractedDir =
|
|
14229
|
+
const extractedDir = join8(tmpDir, info.assetName, "lib");
|
|
14098
14230
|
if (!existsSync5(extractedDir)) {
|
|
14099
14231
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
14100
14232
|
}
|
|
@@ -14103,7 +14235,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14103
14235
|
const realFiles = [];
|
|
14104
14236
|
const symlinks = [];
|
|
14105
14237
|
for (const libFile of libFiles) {
|
|
14106
|
-
const src =
|
|
14238
|
+
const src = join8(extractedDir, libFile);
|
|
14107
14239
|
try {
|
|
14108
14240
|
const stat = lstatSync(src);
|
|
14109
14241
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -14118,7 +14250,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14118
14250
|
}
|
|
14119
14251
|
}
|
|
14120
14252
|
copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
|
|
14121
|
-
const libPath =
|
|
14253
|
+
const libPath = join8(targetDir, info.libName);
|
|
14122
14254
|
let libHash = null;
|
|
14123
14255
|
try {
|
|
14124
14256
|
libHash = sha256File(libPath);
|
|
@@ -14143,8 +14275,8 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
14143
14275
|
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
|
|
14144
14276
|
const requiredLibs = new Set([info.libName]);
|
|
14145
14277
|
for (const libFile of realFiles) {
|
|
14146
|
-
const src =
|
|
14147
|
-
const dst =
|
|
14278
|
+
const src = join8(extractedDir, libFile);
|
|
14279
|
+
const dst = join8(targetDir, libFile);
|
|
14148
14280
|
try {
|
|
14149
14281
|
copyFile(src, dst);
|
|
14150
14282
|
if (process.platform !== "win32") {
|
|
@@ -14160,12 +14292,12 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
14160
14292
|
}
|
|
14161
14293
|
const targetRoot = realpathSync(targetDir);
|
|
14162
14294
|
for (const link of symlinks) {
|
|
14163
|
-
const dst =
|
|
14295
|
+
const dst = join8(targetDir, link.name);
|
|
14164
14296
|
try {
|
|
14165
14297
|
unlinkSync3(dst);
|
|
14166
14298
|
} catch {}
|
|
14167
|
-
const dstForContainment =
|
|
14168
|
-
const resolvedTarget =
|
|
14299
|
+
const dstForContainment = join8(targetRoot, link.name);
|
|
14300
|
+
const resolvedTarget = resolve2(dirname4(dstForContainment), link.target);
|
|
14169
14301
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
14170
14302
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
14171
14303
|
if (requiredLibs.has(link.name)) {
|
|
@@ -14185,7 +14317,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
14185
14317
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
14186
14318
|
}
|
|
14187
14319
|
}
|
|
14188
|
-
const requiredPath =
|
|
14320
|
+
const requiredPath = join8(targetDir, info.libName);
|
|
14189
14321
|
if (!existsSync5(requiredPath)) {
|
|
14190
14322
|
rmSync2(targetDir, { recursive: true, force: true });
|
|
14191
14323
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
@@ -14212,17 +14344,17 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
14212
14344
|
...sha256 ? { sha256 } : {},
|
|
14213
14345
|
archiveSha256
|
|
14214
14346
|
};
|
|
14215
|
-
writeFileSync2(
|
|
14347
|
+
writeFileSync2(join8(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
14216
14348
|
} catch (err) {
|
|
14217
14349
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
14218
14350
|
}
|
|
14219
14351
|
}
|
|
14220
14352
|
function readOnnxInstalledMeta(installDir) {
|
|
14221
|
-
const
|
|
14353
|
+
const path2 = join8(installDir, ONNX_INSTALLED_META_FILE);
|
|
14222
14354
|
try {
|
|
14223
|
-
if (!statSync3(
|
|
14355
|
+
if (!statSync3(path2).isFile())
|
|
14224
14356
|
return null;
|
|
14225
|
-
const raw = readFileSync3(
|
|
14357
|
+
const raw = readFileSync3(path2, "utf8");
|
|
14226
14358
|
const parsed = JSON.parse(raw);
|
|
14227
14359
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
14228
14360
|
return null;
|
|
@@ -14236,9 +14368,9 @@ function readOnnxInstalledMeta(installDir) {
|
|
|
14236
14368
|
return null;
|
|
14237
14369
|
}
|
|
14238
14370
|
}
|
|
14239
|
-
function sha256File(
|
|
14371
|
+
function sha256File(path2) {
|
|
14240
14372
|
const hash = createHash2("sha256");
|
|
14241
|
-
hash.update(readFileSync3(
|
|
14373
|
+
hash.update(readFileSync3(path2));
|
|
14242
14374
|
return hash.digest("hex");
|
|
14243
14375
|
}
|
|
14244
14376
|
function acquireLock(lockPath) {
|
|
@@ -14898,13 +15030,13 @@ function tokenizeStage(stage) {
|
|
|
14898
15030
|
}
|
|
14899
15031
|
// ../aft-bridge/dist/pool.js
|
|
14900
15032
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
14901
|
-
import { homedir as
|
|
15033
|
+
import { homedir as homedir7 } from "node:os";
|
|
14902
15034
|
var DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1000;
|
|
14903
15035
|
var DEFAULT_MAX_POOL_SIZE = 8;
|
|
14904
15036
|
var CLEANUP_INTERVAL_MS = 60 * 1000;
|
|
14905
15037
|
function canonicalHomeDir() {
|
|
14906
15038
|
try {
|
|
14907
|
-
const home =
|
|
15039
|
+
const home = homedir7();
|
|
14908
15040
|
if (!home)
|
|
14909
15041
|
return null;
|
|
14910
15042
|
try {
|
|
@@ -15096,6 +15228,91 @@ function normalizeKey(projectRoot) {
|
|
|
15096
15228
|
return stripped;
|
|
15097
15229
|
}
|
|
15098
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
|
+
}
|
|
15099
15316
|
// ../aft-bridge/dist/zoom-format.js
|
|
15100
15317
|
function formatZoomText(targetLabel, response) {
|
|
15101
15318
|
const range = response.range;
|
|
@@ -15176,13 +15393,36 @@ function formatZoomMultiTargetResult(entries) {
|
|
|
15176
15393
|
|
|
15177
15394
|
`) };
|
|
15178
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
|
+
}
|
|
15179
15419
|
// src/logger.ts
|
|
15180
15420
|
import * as fs from "node:fs";
|
|
15181
|
-
import * as
|
|
15182
|
-
import * as
|
|
15421
|
+
import * as os2 from "node:os";
|
|
15422
|
+
import * as path2 from "node:path";
|
|
15183
15423
|
var TAG = "[aft-pi]";
|
|
15184
15424
|
var isTestEnv = process.env.BUN_TEST === "1" || false;
|
|
15185
|
-
var logFile =
|
|
15425
|
+
var logFile = path2.join(os2.tmpdir(), isTestEnv ? "aft-pi-test.log" : "aft-pi.log");
|
|
15186
15426
|
var useStderr = process.env.AFT_LOG_STDERR === "1";
|
|
15187
15427
|
var buffer = [];
|
|
15188
15428
|
var flushTimer = null;
|
|
@@ -15818,7 +16058,7 @@ import {
|
|
|
15818
16058
|
// package.json
|
|
15819
16059
|
var package_default = {
|
|
15820
16060
|
name: "@cortexkit/aft-pi",
|
|
15821
|
-
version: "0.39.
|
|
16061
|
+
version: "0.39.1",
|
|
15822
16062
|
type: "module",
|
|
15823
16063
|
description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
|
|
15824
16064
|
main: "dist/index.js",
|
|
@@ -15841,7 +16081,7 @@ var package_default = {
|
|
|
15841
16081
|
"test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
|
|
15842
16082
|
},
|
|
15843
16083
|
dependencies: {
|
|
15844
|
-
"@cortexkit/aft-bridge": "0.39.
|
|
16084
|
+
"@cortexkit/aft-bridge": "0.39.1",
|
|
15845
16085
|
"@xterm/headless": "^5.5.0",
|
|
15846
16086
|
"comment-json": "^5.0.0",
|
|
15847
16087
|
diff: "^8.0.4",
|
|
@@ -15849,12 +16089,12 @@ var package_default = {
|
|
|
15849
16089
|
zod: "^4.1.8"
|
|
15850
16090
|
},
|
|
15851
16091
|
optionalDependencies: {
|
|
15852
|
-
"@cortexkit/aft-darwin-arm64": "0.39.
|
|
15853
|
-
"@cortexkit/aft-darwin-x64": "0.39.
|
|
15854
|
-
"@cortexkit/aft-linux-arm64": "0.39.
|
|
15855
|
-
"@cortexkit/aft-linux-x64": "0.39.
|
|
15856
|
-
"@cortexkit/aft-win32-arm64": "0.39.
|
|
15857
|
-
"@cortexkit/aft-win32-x64": "0.39.
|
|
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"
|
|
15858
16098
|
},
|
|
15859
16099
|
devDependencies: {
|
|
15860
16100
|
"@earendil-works/pi-coding-agent": "*",
|
|
@@ -16087,101 +16327,6 @@ function formatStatusDialogMessage(status) {
|
|
|
16087
16327
|
// src/tools/_shared.ts
|
|
16088
16328
|
import { Type } from "typebox";
|
|
16089
16329
|
var optionalInt = (_min, _max) => Type.Optional(Type.Any({ description: "(integer)" }));
|
|
16090
|
-
function coerceOptionalInt(v, paramName, min, max) {
|
|
16091
|
-
if (v === undefined || v === null || v === "")
|
|
16092
|
-
return;
|
|
16093
|
-
if (typeof v === "number" && (!Number.isFinite(v) || v === 0 && min > 0))
|
|
16094
|
-
return;
|
|
16095
|
-
const n = typeof v === "string" ? Number(v) : v;
|
|
16096
|
-
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
16097
|
-
throw new Error(`${paramName} must be an integer between ${min} and ${max}`);
|
|
16098
|
-
}
|
|
16099
|
-
if (n < min || n > max) {
|
|
16100
|
-
throw new Error(`${paramName} must be between ${min} and ${max}`);
|
|
16101
|
-
}
|
|
16102
|
-
return n;
|
|
16103
|
-
}
|
|
16104
|
-
function isEmptyParam(value) {
|
|
16105
|
-
if (value === undefined || value === null)
|
|
16106
|
-
return true;
|
|
16107
|
-
if (typeof value === "string")
|
|
16108
|
-
return value.length === 0;
|
|
16109
|
-
if (Array.isArray(value))
|
|
16110
|
-
return value.length === 0;
|
|
16111
|
-
if (typeof value === "object")
|
|
16112
|
-
return Object.keys(value).length === 0;
|
|
16113
|
-
return false;
|
|
16114
|
-
}
|
|
16115
|
-
function asPlainObject(value) {
|
|
16116
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
16117
|
-
return;
|
|
16118
|
-
return value;
|
|
16119
|
-
}
|
|
16120
|
-
function candidateLocation(candidate) {
|
|
16121
|
-
const file = typeof candidate.file === "string" && candidate.file.length > 0 ? candidate.file : undefined;
|
|
16122
|
-
if (!file)
|
|
16123
|
-
return;
|
|
16124
|
-
const line = typeof candidate.line === "number" && Number.isFinite(candidate.line) ? candidate.line : undefined;
|
|
16125
|
-
return line === undefined ? file : `${file}:${line}`;
|
|
16126
|
-
}
|
|
16127
|
-
function stringifyData(data) {
|
|
16128
|
-
if (data === undefined)
|
|
16129
|
-
return;
|
|
16130
|
-
try {
|
|
16131
|
-
return JSON.stringify(data, null, 2);
|
|
16132
|
-
} catch {
|
|
16133
|
-
return String(data);
|
|
16134
|
-
}
|
|
16135
|
-
}
|
|
16136
|
-
function formatBridgeErrorMessage(command, response, params = {}) {
|
|
16137
|
-
const code = typeof response.code === "string" && response.code.length > 0 ? response.code : undefined;
|
|
16138
|
-
const message = typeof response.message === "string" && response.message.length > 0 ? response.message : `${command} failed`;
|
|
16139
|
-
const data = asPlainObject(response.data);
|
|
16140
|
-
const rawCandidates = Array.isArray(response.candidates) ? response.candidates : Array.isArray(data?.candidates) ? data.candidates : undefined;
|
|
16141
|
-
const rawSymbol = typeof response.symbol === "string" && response.symbol.length > 0 ? response.symbol : typeof data?.symbol === "string" && data.symbol.length > 0 ? data.symbol : undefined;
|
|
16142
|
-
if (code === "ambiguous_target" || code === "target_symbol_not_in_file") {
|
|
16143
|
-
const candidates = (rawCandidates ?? []).map(asPlainObject).filter((candidate) => candidate !== undefined).map(candidateLocation).filter((candidate) => candidate !== undefined);
|
|
16144
|
-
if (candidates.length > 0) {
|
|
16145
|
-
const symbol = typeof params.toSymbol === "string" && params.toSymbol.length > 0 ? params.toSymbol : rawSymbol;
|
|
16146
|
-
const target = symbol ? `multiple symbols named "${symbol}"` : message.replace(/[.!?]+$/, "");
|
|
16147
|
-
const action = code === "ambiguous_target" ? "Pass toFile to disambiguate" : "Try one of these files for toFile";
|
|
16148
|
-
return `${command}: ${code} — ${target}. ${action}:
|
|
16149
|
-
${candidates.map((candidate) => ` - ${candidate}`).join(`
|
|
16150
|
-
`)}`;
|
|
16151
|
-
}
|
|
16152
|
-
}
|
|
16153
|
-
if (!code)
|
|
16154
|
-
return message;
|
|
16155
|
-
const lines = [`${command}: ${code} — ${message}`];
|
|
16156
|
-
const extras = collectStructuredExtras(response);
|
|
16157
|
-
if (extras)
|
|
16158
|
-
lines.push(`data: ${extras}`);
|
|
16159
|
-
return lines.join(`
|
|
16160
|
-
`);
|
|
16161
|
-
}
|
|
16162
|
-
function collectStructuredExtras(response) {
|
|
16163
|
-
const reserved = new Set([
|
|
16164
|
-
"id",
|
|
16165
|
-
"success",
|
|
16166
|
-
"code",
|
|
16167
|
-
"message",
|
|
16168
|
-
"data",
|
|
16169
|
-
"status_bar",
|
|
16170
|
-
"bg_completions"
|
|
16171
|
-
]);
|
|
16172
|
-
const extras = {};
|
|
16173
|
-
for (const [key, value] of Object.entries(response)) {
|
|
16174
|
-
if (reserved.has(key))
|
|
16175
|
-
continue;
|
|
16176
|
-
extras[key] = value;
|
|
16177
|
-
}
|
|
16178
|
-
if (Object.keys(extras).length === 0) {
|
|
16179
|
-
return stringifyData(response.data);
|
|
16180
|
-
}
|
|
16181
|
-
if (response.data !== undefined)
|
|
16182
|
-
extras.data = response.data;
|
|
16183
|
-
return stringifyData(extras);
|
|
16184
|
-
}
|
|
16185
16330
|
function bridgeFor(ctx, cwd) {
|
|
16186
16331
|
return ctx.pool.getBridge(cwd);
|
|
16187
16332
|
}
|
|
@@ -16524,8 +16669,8 @@ function registerStatusCommand(pi, ctx) {
|
|
|
16524
16669
|
|
|
16525
16670
|
// src/config.ts
|
|
16526
16671
|
import { existsSync as existsSync6, readFileSync as readFileSync4, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
16527
|
-
import { homedir as
|
|
16528
|
-
import { join as
|
|
16672
|
+
import { homedir as homedir8 } from "node:os";
|
|
16673
|
+
import { join as join10 } from "node:path";
|
|
16529
16674
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
16530
16675
|
|
|
16531
16676
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
@@ -17293,10 +17438,10 @@ function mergeDefs(...defs) {
|
|
|
17293
17438
|
function cloneDef(schema) {
|
|
17294
17439
|
return mergeDefs(schema._zod.def);
|
|
17295
17440
|
}
|
|
17296
|
-
function getElementAtPath(obj,
|
|
17297
|
-
if (!
|
|
17441
|
+
function getElementAtPath(obj, path3) {
|
|
17442
|
+
if (!path3)
|
|
17298
17443
|
return obj;
|
|
17299
|
-
return
|
|
17444
|
+
return path3.reduce((acc, key) => acc?.[key], obj);
|
|
17300
17445
|
}
|
|
17301
17446
|
function promiseAllObject(promisesObj) {
|
|
17302
17447
|
const keys = Object.keys(promisesObj);
|
|
@@ -17677,11 +17822,11 @@ function aborted(x, startIndex = 0) {
|
|
|
17677
17822
|
}
|
|
17678
17823
|
return false;
|
|
17679
17824
|
}
|
|
17680
|
-
function prefixIssues(
|
|
17825
|
+
function prefixIssues(path3, issues) {
|
|
17681
17826
|
return issues.map((iss) => {
|
|
17682
17827
|
var _a;
|
|
17683
17828
|
(_a = iss).path ?? (_a.path = []);
|
|
17684
|
-
iss.path.unshift(
|
|
17829
|
+
iss.path.unshift(path3);
|
|
17685
17830
|
return iss;
|
|
17686
17831
|
});
|
|
17687
17832
|
}
|
|
@@ -17864,7 +18009,7 @@ function formatError(error3, mapper = (issue2) => issue2.message) {
|
|
|
17864
18009
|
}
|
|
17865
18010
|
function treeifyError(error3, mapper = (issue2) => issue2.message) {
|
|
17866
18011
|
const result = { errors: [] };
|
|
17867
|
-
const processError = (error4,
|
|
18012
|
+
const processError = (error4, path3 = []) => {
|
|
17868
18013
|
var _a, _b;
|
|
17869
18014
|
for (const issue2 of error4.issues) {
|
|
17870
18015
|
if (issue2.code === "invalid_union" && issue2.errors.length) {
|
|
@@ -17874,7 +18019,7 @@ function treeifyError(error3, mapper = (issue2) => issue2.message) {
|
|
|
17874
18019
|
} else if (issue2.code === "invalid_element") {
|
|
17875
18020
|
processError({ issues: issue2.issues }, issue2.path);
|
|
17876
18021
|
} else {
|
|
17877
|
-
const fullpath = [...
|
|
18022
|
+
const fullpath = [...path3, ...issue2.path];
|
|
17878
18023
|
if (fullpath.length === 0) {
|
|
17879
18024
|
result.errors.push(mapper(issue2));
|
|
17880
18025
|
continue;
|
|
@@ -17906,8 +18051,8 @@ function treeifyError(error3, mapper = (issue2) => issue2.message) {
|
|
|
17906
18051
|
}
|
|
17907
18052
|
function toDotPath(_path) {
|
|
17908
18053
|
const segs = [];
|
|
17909
|
-
const
|
|
17910
|
-
for (const seg of
|
|
18054
|
+
const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
18055
|
+
for (const seg of path3) {
|
|
17911
18056
|
if (typeof seg === "number")
|
|
17912
18057
|
segs.push(`[${seg}]`);
|
|
17913
18058
|
else if (typeof seg === "symbol")
|
|
@@ -29654,13 +29799,13 @@ function resolveRef(ref, ctx) {
|
|
|
29654
29799
|
if (!ref.startsWith("#")) {
|
|
29655
29800
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
29656
29801
|
}
|
|
29657
|
-
const
|
|
29658
|
-
if (
|
|
29802
|
+
const path3 = ref.slice(1).split("/").filter(Boolean);
|
|
29803
|
+
if (path3.length === 0) {
|
|
29659
29804
|
return ctx.rootSchema;
|
|
29660
29805
|
}
|
|
29661
29806
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
29662
|
-
if (
|
|
29663
|
-
const key =
|
|
29807
|
+
if (path3[0] === defsKey) {
|
|
29808
|
+
const key = path3[1];
|
|
29664
29809
|
if (!key || !ctx.defs[key]) {
|
|
29665
29810
|
throw new Error(`Reference not found: ${ref}`);
|
|
29666
29811
|
}
|
|
@@ -30317,9 +30462,9 @@ function extractCommentsForPreservation(content) {
|
|
|
30317
30462
|
}
|
|
30318
30463
|
return comments;
|
|
30319
30464
|
}
|
|
30320
|
-
function ensureRecordAtPath(root,
|
|
30465
|
+
function ensureRecordAtPath(root, path3) {
|
|
30321
30466
|
let current = root;
|
|
30322
|
-
for (const segment of
|
|
30467
|
+
for (const segment of path3) {
|
|
30323
30468
|
const existing = current[segment];
|
|
30324
30469
|
if (!existing || typeof existing !== "object" || Array.isArray(existing)) {
|
|
30325
30470
|
current[segment] = {};
|
|
@@ -30328,9 +30473,9 @@ function ensureRecordAtPath(root, path2) {
|
|
|
30328
30473
|
}
|
|
30329
30474
|
return current;
|
|
30330
30475
|
}
|
|
30331
|
-
function hasPath(root,
|
|
30476
|
+
function hasPath(root, path3) {
|
|
30332
30477
|
let current = root;
|
|
30333
|
-
for (const segment of
|
|
30478
|
+
for (const segment of path3) {
|
|
30334
30479
|
if (!current || typeof current !== "object" || Array.isArray(current))
|
|
30335
30480
|
return false;
|
|
30336
30481
|
const record2 = current;
|
|
@@ -30340,9 +30485,9 @@ function hasPath(root, path2) {
|
|
|
30340
30485
|
}
|
|
30341
30486
|
return true;
|
|
30342
30487
|
}
|
|
30343
|
-
function setPath(root,
|
|
30344
|
-
const parent = ensureRecordAtPath(root,
|
|
30345
|
-
parent[
|
|
30488
|
+
function setPath(root, path3, value) {
|
|
30489
|
+
const parent = ensureRecordAtPath(root, path3.slice(0, -1));
|
|
30490
|
+
parent[path3[path3.length - 1]] = value;
|
|
30346
30491
|
}
|
|
30347
30492
|
function migrateRawConfig(rawConfig, configPath, logger) {
|
|
30348
30493
|
const oldKeys = [];
|
|
@@ -30659,15 +30804,15 @@ function mergeConfigs(base, override) {
|
|
|
30659
30804
|
};
|
|
30660
30805
|
}
|
|
30661
30806
|
function getGlobalPiDir() {
|
|
30662
|
-
return
|
|
30807
|
+
return join10(homedir8(), ".pi", "agent");
|
|
30663
30808
|
}
|
|
30664
30809
|
function loadAftConfig(projectDirectory) {
|
|
30665
|
-
const userBasePath =
|
|
30810
|
+
const userBasePath = join10(getGlobalPiDir(), "aft");
|
|
30666
30811
|
migrateAftConfigFile(`${userBasePath}.jsonc`);
|
|
30667
30812
|
migrateAftConfigFile(`${userBasePath}.json`);
|
|
30668
30813
|
const userDetected = detectConfigFile(userBasePath);
|
|
30669
30814
|
const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
|
|
30670
|
-
const projectBasePath =
|
|
30815
|
+
const projectBasePath = join10(projectDirectory, ".pi", "aft");
|
|
30671
30816
|
migrateAftConfigFile(`${projectBasePath}.jsonc`);
|
|
30672
30817
|
migrateAftConfigFile(`${projectBasePath}.json`);
|
|
30673
30818
|
const projectDetected = detectConfigFile(projectBasePath);
|
|
@@ -30704,7 +30849,7 @@ import {
|
|
|
30704
30849
|
statSync as statSync5,
|
|
30705
30850
|
writeFileSync as writeFileSync5
|
|
30706
30851
|
} from "node:fs";
|
|
30707
|
-
import { join as
|
|
30852
|
+
import { join as join13 } from "node:path";
|
|
30708
30853
|
|
|
30709
30854
|
// src/lsp-cache.ts
|
|
30710
30855
|
import {
|
|
@@ -30716,36 +30861,36 @@ import {
|
|
|
30716
30861
|
unlinkSync as unlinkSync5,
|
|
30717
30862
|
writeFileSync as writeFileSync4
|
|
30718
30863
|
} from "node:fs";
|
|
30719
|
-
import { homedir as
|
|
30720
|
-
import { join as
|
|
30864
|
+
import { homedir as homedir9 } from "node:os";
|
|
30865
|
+
import { join as join11 } from "node:path";
|
|
30721
30866
|
function aftCacheBase() {
|
|
30722
30867
|
const override = process.env.AFT_CACHE_DIR;
|
|
30723
30868
|
if (override && override.length > 0)
|
|
30724
30869
|
return override;
|
|
30725
30870
|
if (process.platform === "win32") {
|
|
30726
30871
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
30727
|
-
const base2 = localAppData ||
|
|
30728
|
-
return
|
|
30872
|
+
const base2 = localAppData || join11(homedir9(), "AppData", "Local");
|
|
30873
|
+
return join11(base2, "aft");
|
|
30729
30874
|
}
|
|
30730
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
30731
|
-
return
|
|
30875
|
+
const base = process.env.XDG_CACHE_HOME || join11(homedir9(), ".cache");
|
|
30876
|
+
return join11(base, "aft");
|
|
30732
30877
|
}
|
|
30733
30878
|
function lspCacheRoot() {
|
|
30734
|
-
return
|
|
30879
|
+
return join11(aftCacheBase(), "lsp-packages");
|
|
30735
30880
|
}
|
|
30736
30881
|
function lspPackageDir(npmPackage) {
|
|
30737
|
-
return
|
|
30882
|
+
return join11(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
30738
30883
|
}
|
|
30739
30884
|
function lspBinaryPath(npmPackage, binary) {
|
|
30740
|
-
return
|
|
30885
|
+
return join11(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
30741
30886
|
}
|
|
30742
30887
|
function lspBinDir(npmPackage) {
|
|
30743
|
-
return
|
|
30888
|
+
return join11(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
30744
30889
|
}
|
|
30745
30890
|
function isInstalled(npmPackage, binary) {
|
|
30746
30891
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
30747
30892
|
try {
|
|
30748
|
-
if (statSync4(
|
|
30893
|
+
if (statSync4(join11(lspBinDir(npmPackage), candidate)).isFile())
|
|
30749
30894
|
return true;
|
|
30750
30895
|
} catch {}
|
|
30751
30896
|
}
|
|
@@ -30765,17 +30910,17 @@ function writeInstalledMetaIn(installDir, version2, sha256) {
|
|
|
30765
30910
|
installedAt: new Date().toISOString(),
|
|
30766
30911
|
...sha256 ? { sha256 } : {}
|
|
30767
30912
|
};
|
|
30768
|
-
writeFileSync4(
|
|
30913
|
+
writeFileSync4(join11(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
|
|
30769
30914
|
} catch (err) {
|
|
30770
30915
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
30771
30916
|
}
|
|
30772
30917
|
}
|
|
30773
30918
|
function readInstalledMetaIn(installDir) {
|
|
30774
|
-
const
|
|
30919
|
+
const path3 = join11(installDir, INSTALLED_META_FILE);
|
|
30775
30920
|
try {
|
|
30776
|
-
if (!statSync4(
|
|
30921
|
+
if (!statSync4(path3).isFile())
|
|
30777
30922
|
return null;
|
|
30778
|
-
const raw = readFileSync5(
|
|
30923
|
+
const raw = readFileSync5(path3, "utf8");
|
|
30779
30924
|
const parsed = JSON.parse(raw);
|
|
30780
30925
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
30781
30926
|
return null;
|
|
@@ -30795,7 +30940,7 @@ function readInstalledMeta(packageKey) {
|
|
|
30795
30940
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
30796
30941
|
}
|
|
30797
30942
|
function lockPath(npmPackage) {
|
|
30798
|
-
return
|
|
30943
|
+
return join11(lspPackageDir(npmPackage), ".aft-installing");
|
|
30799
30944
|
}
|
|
30800
30945
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
30801
30946
|
function acquireInstallLock(lockKey) {
|
|
@@ -30902,7 +31047,7 @@ async function withInstallLock(lockKey, task) {
|
|
|
30902
31047
|
}
|
|
30903
31048
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
30904
31049
|
function readVersionCheck(npmPackage) {
|
|
30905
|
-
const file2 =
|
|
31050
|
+
const file2 = join11(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
30906
31051
|
try {
|
|
30907
31052
|
const raw = readFileSync5(file2, "utf8");
|
|
30908
31053
|
const parsed = JSON.parse(raw);
|
|
@@ -30919,7 +31064,7 @@ function readVersionCheck(npmPackage) {
|
|
|
30919
31064
|
}
|
|
30920
31065
|
function writeVersionCheck(npmPackage, latest) {
|
|
30921
31066
|
mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
|
|
30922
|
-
const file2 =
|
|
31067
|
+
const file2 = join11(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
30923
31068
|
const record2 = {
|
|
30924
31069
|
last_checked: new Date().toISOString(),
|
|
30925
31070
|
latest_eligible: latest
|
|
@@ -31082,7 +31227,7 @@ var NPM_LSP_TABLE = [
|
|
|
31082
31227
|
|
|
31083
31228
|
// src/lsp-project-relevance.ts
|
|
31084
31229
|
import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "node:fs";
|
|
31085
|
-
import { join as
|
|
31230
|
+
import { join as join12 } from "node:path";
|
|
31086
31231
|
var MAX_WALK_DIRS = 200;
|
|
31087
31232
|
var MAX_WALK_DEPTH = 4;
|
|
31088
31233
|
var NOISE_DIRS = new Set([
|
|
@@ -31099,7 +31244,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
31099
31244
|
if (!rootMarkers)
|
|
31100
31245
|
return false;
|
|
31101
31246
|
for (const marker of rootMarkers) {
|
|
31102
|
-
if (existsSync7(
|
|
31247
|
+
if (existsSync7(join12(projectRoot, marker)))
|
|
31103
31248
|
return true;
|
|
31104
31249
|
}
|
|
31105
31250
|
return false;
|
|
@@ -31123,7 +31268,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
31123
31268
|
}
|
|
31124
31269
|
function readPackageJson(projectRoot) {
|
|
31125
31270
|
try {
|
|
31126
|
-
const raw = readFileSync6(
|
|
31271
|
+
const raw = readFileSync6(join12(projectRoot, "package.json"), "utf8");
|
|
31127
31272
|
const parsed = JSON.parse(raw);
|
|
31128
31273
|
if (typeof parsed !== "object" || parsed === null)
|
|
31129
31274
|
return null;
|
|
@@ -31153,7 +31298,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
31153
31298
|
for (const entry of entries) {
|
|
31154
31299
|
if (entry.isDirectory()) {
|
|
31155
31300
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
31156
|
-
queue.push({ dir:
|
|
31301
|
+
queue.push({ dir: join12(current.dir, entry.name), depth: current.depth + 1 });
|
|
31157
31302
|
}
|
|
31158
31303
|
continue;
|
|
31159
31304
|
}
|
|
@@ -31280,7 +31425,7 @@ async function resolveTargetVersion(spec, config2, fetchImpl = fetch) {
|
|
|
31280
31425
|
}
|
|
31281
31426
|
function ensureInstallAnchor(cwd) {
|
|
31282
31427
|
try {
|
|
31283
|
-
const stub =
|
|
31428
|
+
const stub = join13(cwd, "package.json");
|
|
31284
31429
|
if (!existsSync8(stub)) {
|
|
31285
31430
|
writeFileSync5(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
31286
31431
|
`);
|
|
@@ -31290,18 +31435,18 @@ function ensureInstallAnchor(cwd) {
|
|
|
31290
31435
|
}
|
|
31291
31436
|
}
|
|
31292
31437
|
function runInstall(spec, version2, cwd, signal) {
|
|
31293
|
-
return new Promise((
|
|
31438
|
+
return new Promise((resolve3) => {
|
|
31294
31439
|
const target = `${spec.npm}@${version2}`;
|
|
31295
31440
|
log2(`[lsp] installing ${target} to ${cwd}`);
|
|
31296
31441
|
if (signal?.aborted) {
|
|
31297
31442
|
warn2(`[lsp] install ${target} aborted before spawn`);
|
|
31298
|
-
|
|
31443
|
+
resolve3(false);
|
|
31299
31444
|
return;
|
|
31300
31445
|
}
|
|
31301
31446
|
const npm = resolveNpm();
|
|
31302
31447
|
if (!npm) {
|
|
31303
31448
|
warn2(`[lsp] npm not found on PATH or known locations; cannot install ${target}`);
|
|
31304
|
-
|
|
31449
|
+
resolve3(false);
|
|
31305
31450
|
return;
|
|
31306
31451
|
}
|
|
31307
31452
|
ensureInstallAnchor(cwd);
|
|
@@ -31324,7 +31469,7 @@ function runInstall(spec, version2, cwd, signal) {
|
|
|
31324
31469
|
return;
|
|
31325
31470
|
settled = true;
|
|
31326
31471
|
cleanup();
|
|
31327
|
-
|
|
31472
|
+
resolve3(ok);
|
|
31328
31473
|
};
|
|
31329
31474
|
const onAbort = () => {
|
|
31330
31475
|
warn2(`[lsp] install ${target} aborted during shutdown`);
|
|
@@ -31425,7 +31570,7 @@ function cachedPackageDir(npmPackage) {
|
|
|
31425
31570
|
return lspBinDir(npmPackage).replace(/[\\/]node_modules[\\/]\.bin[\\/]?$/, "");
|
|
31426
31571
|
}
|
|
31427
31572
|
function hashInstalledBinary(spec) {
|
|
31428
|
-
return new Promise((
|
|
31573
|
+
return new Promise((resolve3, reject) => {
|
|
31429
31574
|
const candidates = process.platform === "win32" ? [
|
|
31430
31575
|
lspBinaryPath(spec.npm, spec.binary),
|
|
31431
31576
|
lspBinaryPath(spec.npm, `${spec.binary}.cmd`),
|
|
@@ -31449,7 +31594,7 @@ function hashInstalledBinary(spec) {
|
|
|
31449
31594
|
const stream = createReadStream(pathToHash);
|
|
31450
31595
|
stream.on("error", reject);
|
|
31451
31596
|
stream.on("data", (chunk) => hash2.update(chunk));
|
|
31452
|
-
stream.on("end", () =>
|
|
31597
|
+
stream.on("end", () => resolve3(hash2.digest("hex")));
|
|
31453
31598
|
});
|
|
31454
31599
|
}
|
|
31455
31600
|
function installedBinaryPath(spec) {
|
|
@@ -31467,15 +31612,15 @@ function installedBinaryPath(spec) {
|
|
|
31467
31612
|
}
|
|
31468
31613
|
return null;
|
|
31469
31614
|
}
|
|
31470
|
-
function sha256OfFileSync(
|
|
31471
|
-
return createHash3("sha256").update(readFileSync7(
|
|
31615
|
+
function sha256OfFileSync(path3) {
|
|
31616
|
+
return createHash3("sha256").update(readFileSync7(path3)).digest("hex");
|
|
31472
31617
|
}
|
|
31473
31618
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
31474
31619
|
const packageDir = lspPackageDir(spec.npm);
|
|
31475
|
-
const dest =
|
|
31620
|
+
const dest = join13(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
31476
31621
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
31477
31622
|
try {
|
|
31478
|
-
mkdirSync7(
|
|
31623
|
+
mkdirSync7(join13(dest, ".."), { recursive: true });
|
|
31479
31624
|
rmSync3(dest, { recursive: true, force: true });
|
|
31480
31625
|
renameSync5(packageDir, dest);
|
|
31481
31626
|
} catch (err) {
|
|
@@ -31570,7 +31715,7 @@ import {
|
|
|
31570
31715
|
unlinkSync as unlinkSync6,
|
|
31571
31716
|
writeFileSync as writeFileSync6
|
|
31572
31717
|
} from "node:fs";
|
|
31573
|
-
import { dirname as dirname5, join as
|
|
31718
|
+
import { dirname as dirname5, join as join14, relative as relative3, resolve as resolve3 } from "node:path";
|
|
31574
31719
|
import { Readable as Readable3 } from "node:stream";
|
|
31575
31720
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
31576
31721
|
|
|
@@ -31660,26 +31805,26 @@ function detectHostPlatform() {
|
|
|
31660
31805
|
|
|
31661
31806
|
// src/lsp-github-install.ts
|
|
31662
31807
|
function ghCacheRoot() {
|
|
31663
|
-
return
|
|
31808
|
+
return join14(aftCacheBase(), "lsp-binaries");
|
|
31664
31809
|
}
|
|
31665
31810
|
function ghPackageDir(spec) {
|
|
31666
|
-
return
|
|
31811
|
+
return join14(ghCacheRoot(), spec.id);
|
|
31667
31812
|
}
|
|
31668
31813
|
function ghBinDir(spec) {
|
|
31669
|
-
return
|
|
31814
|
+
return join14(ghPackageDir(spec), "bin");
|
|
31670
31815
|
}
|
|
31671
31816
|
function ghExtractDir(spec) {
|
|
31672
|
-
return
|
|
31817
|
+
return join14(ghPackageDir(spec), "extracted");
|
|
31673
31818
|
}
|
|
31674
31819
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
31675
31820
|
function ghBinaryPath(spec, platform) {
|
|
31676
31821
|
const ext = platform === "win32" ? ".exe" : "";
|
|
31677
|
-
return
|
|
31822
|
+
return join14(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
31678
31823
|
}
|
|
31679
31824
|
function isGithubInstalled(spec, platform) {
|
|
31680
31825
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
31681
31826
|
try {
|
|
31682
|
-
if (statSync6(
|
|
31827
|
+
if (statSync6(join14(ghBinDir(spec), candidate)).isFile())
|
|
31683
31828
|
return true;
|
|
31684
31829
|
} catch {}
|
|
31685
31830
|
}
|
|
@@ -31692,10 +31837,10 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
31692
31837
|
}
|
|
31693
31838
|
function readGithubInstalledMetaIn(installDir) {
|
|
31694
31839
|
try {
|
|
31695
|
-
const
|
|
31696
|
-
if (!statSync6(
|
|
31840
|
+
const path3 = join14(installDir, INSTALLED_META_FILE2);
|
|
31841
|
+
if (!statSync6(path3).isFile())
|
|
31697
31842
|
return null;
|
|
31698
|
-
const parsed = JSON.parse(readFileSync8(
|
|
31843
|
+
const parsed = JSON.parse(readFileSync8(path3, "utf8"));
|
|
31699
31844
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
31700
31845
|
return null;
|
|
31701
31846
|
return {
|
|
@@ -31719,24 +31864,24 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
|
|
|
31719
31864
|
binarySha256,
|
|
31720
31865
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
31721
31866
|
};
|
|
31722
|
-
writeFileSync6(
|
|
31867
|
+
writeFileSync6(join14(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
|
|
31723
31868
|
} catch (err) {
|
|
31724
31869
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
31725
31870
|
}
|
|
31726
31871
|
}
|
|
31727
31872
|
var MAX_DOWNLOAD_BYTES3 = 256 * 1024 * 1024;
|
|
31728
31873
|
var MAX_EXTRACT_BYTES2 = 1024 * 1024 * 1024;
|
|
31729
|
-
function sha256OfFile(
|
|
31730
|
-
return new Promise((
|
|
31874
|
+
function sha256OfFile(path3) {
|
|
31875
|
+
return new Promise((resolve4, reject) => {
|
|
31731
31876
|
const hash2 = createHash4("sha256");
|
|
31732
|
-
const stream = createReadStream2(
|
|
31877
|
+
const stream = createReadStream2(path3);
|
|
31733
31878
|
stream.on("error", reject);
|
|
31734
31879
|
stream.on("data", (chunk) => hash2.update(chunk));
|
|
31735
|
-
stream.on("end", () =>
|
|
31880
|
+
stream.on("end", () => resolve4(hash2.digest("hex")));
|
|
31736
31881
|
});
|
|
31737
31882
|
}
|
|
31738
|
-
function sha256OfFileSync2(
|
|
31739
|
-
return createHash4("sha256").update(readFileSync8(
|
|
31883
|
+
function sha256OfFileSync2(path3) {
|
|
31884
|
+
return createHash4("sha256").update(readFileSync8(path3)).digest("hex");
|
|
31740
31885
|
}
|
|
31741
31886
|
async function fetchReleaseByTag(githubRepo, tag, fetchImpl, signal) {
|
|
31742
31887
|
const candidates = [];
|
|
@@ -31968,7 +32113,7 @@ function validateExtraction(stagingRoot) {
|
|
|
31968
32113
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
31969
32114
|
}
|
|
31970
32115
|
for (const entry of entries) {
|
|
31971
|
-
const full =
|
|
32116
|
+
const full = join14(dir, entry);
|
|
31972
32117
|
let lst;
|
|
31973
32118
|
try {
|
|
31974
32119
|
lst = lstatSync2(full);
|
|
@@ -31980,7 +32125,7 @@ function validateExtraction(stagingRoot) {
|
|
|
31980
32125
|
try {
|
|
31981
32126
|
target = readlinkSync2(full);
|
|
31982
32127
|
} catch {}
|
|
31983
|
-
throw new Error(`archive contains symlink ${
|
|
32128
|
+
throw new Error(`archive contains symlink ${relative3(realStagingRoot, full)} → ${target}; rejecting (zip-slip defense)`);
|
|
31984
32129
|
}
|
|
31985
32130
|
let realFull;
|
|
31986
32131
|
try {
|
|
@@ -31988,8 +32133,8 @@ function validateExtraction(stagingRoot) {
|
|
|
31988
32133
|
} catch (err) {
|
|
31989
32134
|
throw new Error(`failed to realpath ${full}: ${err}`);
|
|
31990
32135
|
}
|
|
31991
|
-
const rel =
|
|
31992
|
-
if (rel.startsWith("..") ||
|
|
32136
|
+
const rel = relative3(realStagingRoot, realFull);
|
|
32137
|
+
if (rel.startsWith("..") || resolve3(realStagingRoot, rel) !== realFull) {
|
|
31993
32138
|
throw new Error(`archive entry escapes staging root: ${full} → ${realFull} (zip-slip defense)`);
|
|
31994
32139
|
}
|
|
31995
32140
|
if (lst.isDirectory()) {
|
|
@@ -32056,7 +32201,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
32056
32201
|
}
|
|
32057
32202
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
32058
32203
|
const packageDir = ghPackageDir(spec);
|
|
32059
|
-
const dest =
|
|
32204
|
+
const dest = join14(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
32060
32205
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
32061
32206
|
try {
|
|
32062
32207
|
mkdirSync8(dirname5(dest), { recursive: true });
|
|
@@ -32069,7 +32214,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
32069
32214
|
function validateCachedGithubInstall(spec, platform) {
|
|
32070
32215
|
const packageDir = ghPackageDir(spec);
|
|
32071
32216
|
const meta3 = readGithubInstalledMetaIn(packageDir);
|
|
32072
|
-
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) =>
|
|
32217
|
+
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join14(ghBinDir(spec), candidate)).find((candidate) => {
|
|
32073
32218
|
try {
|
|
32074
32219
|
return statSync6(candidate).isFile();
|
|
32075
32220
|
} catch {
|
|
@@ -32147,7 +32292,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
32147
32292
|
}
|
|
32148
32293
|
const pkgDir = ghPackageDir(spec);
|
|
32149
32294
|
const extractDir = ghExtractDir(spec);
|
|
32150
|
-
const archivePath =
|
|
32295
|
+
const archivePath = join14(pkgDir, expected.name);
|
|
32151
32296
|
log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
|
|
32152
32297
|
try {
|
|
32153
32298
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
|
|
@@ -32187,7 +32332,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
32187
32332
|
unlinkSync6(archivePath);
|
|
32188
32333
|
} catch {}
|
|
32189
32334
|
}
|
|
32190
|
-
const innerBinaryPath =
|
|
32335
|
+
const innerBinaryPath = join14(extractDir, spec.binaryPathInArchive(platform, arch, version2));
|
|
32191
32336
|
if (!existsSync9(innerBinaryPath)) {
|
|
32192
32337
|
error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
|
|
32193
32338
|
return null;
|
|
@@ -32585,7 +32730,7 @@ function renderScreen(state, rows = state.rows, cols = state.cols) {
|
|
|
32585
32730
|
`);
|
|
32586
32731
|
}
|
|
32587
32732
|
function writeTerminal(terminal, data) {
|
|
32588
|
-
return new Promise((
|
|
32733
|
+
return new Promise((resolve4) => terminal.write(data, resolve4));
|
|
32589
32734
|
}
|
|
32590
32735
|
|
|
32591
32736
|
// src/shutdown-hooks.ts
|
|
@@ -32642,8 +32787,8 @@ function installProcessHandlers() {
|
|
|
32642
32787
|
}
|
|
32643
32788
|
signalShutdownStarted = true;
|
|
32644
32789
|
process.exitCode = SIGNAL_EXIT_CODES[sig];
|
|
32645
|
-
const timeout = new Promise((
|
|
32646
|
-
setTimeout(
|
|
32790
|
+
const timeout = new Promise((resolve4) => {
|
|
32791
|
+
setTimeout(resolve4, SIGNAL_CLEANUP_TIMEOUT_MS);
|
|
32647
32792
|
});
|
|
32648
32793
|
Promise.race([runCleanups(sig), timeout]).finally(() => {
|
|
32649
32794
|
process.exit(SIGNAL_EXIT_CODES[sig]);
|
|
@@ -32685,8 +32830,8 @@ import { Type as Type3 } from "typebox";
|
|
|
32685
32830
|
|
|
32686
32831
|
// src/tools/hoisted.ts
|
|
32687
32832
|
import { stat } from "node:fs/promises";
|
|
32688
|
-
import { homedir as
|
|
32689
|
-
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";
|
|
32690
32835
|
import {
|
|
32691
32836
|
renderDiff
|
|
32692
32837
|
} from "@earendil-works/pi-coding-agent";
|
|
@@ -32800,18 +32945,18 @@ function diagnosticsOnEditDefault(ctx) {
|
|
|
32800
32945
|
return ctx.config.lsp?.diagnostics_on_edit ?? false;
|
|
32801
32946
|
}
|
|
32802
32947
|
function containsPath(parent, child) {
|
|
32803
|
-
const rel =
|
|
32804
|
-
return rel === "" || !rel.startsWith("..") && !
|
|
32948
|
+
const rel = relative4(parent, child);
|
|
32949
|
+
return rel === "" || !rel.startsWith("..") && !isAbsolute4(rel);
|
|
32805
32950
|
}
|
|
32806
|
-
function
|
|
32807
|
-
if (!
|
|
32808
|
-
return
|
|
32809
|
-
if (
|
|
32810
|
-
return
|
|
32811
|
-
if (
|
|
32812
|
-
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));
|
|
32813
32958
|
}
|
|
32814
|
-
return
|
|
32959
|
+
return path3;
|
|
32815
32960
|
}
|
|
32816
32961
|
function externalDirectoryPromptTimeoutMs() {
|
|
32817
32962
|
const raw = process.env.AFT_PI_EXTERNAL_PROMPT_TIMEOUT_MS;
|
|
@@ -32823,8 +32968,8 @@ function externalDirectoryPromptTimeoutMs() {
|
|
|
32823
32968
|
async function assertExternalDirectoryPermission(extCtx, target, action = "modify", options = {}) {
|
|
32824
32969
|
if (!target)
|
|
32825
32970
|
return;
|
|
32826
|
-
const expanded =
|
|
32827
|
-
const absoluteTarget =
|
|
32971
|
+
const expanded = expandTilde2(target);
|
|
32972
|
+
const absoluteTarget = isAbsolute4(expanded) ? expanded : resolve4(extCtx.cwd, expanded);
|
|
32828
32973
|
if (containsPath(extCtx.cwd, absoluteTarget))
|
|
32829
32974
|
return;
|
|
32830
32975
|
if (options.restrictToProjectRoot === false)
|
|
@@ -32835,8 +32980,8 @@ async function assertExternalDirectoryPermission(extCtx, target, action = "modif
|
|
|
32835
32980
|
}
|
|
32836
32981
|
const timeoutMs = externalDirectoryPromptTimeoutMs();
|
|
32837
32982
|
let timer;
|
|
32838
|
-
const timeoutPromise = new Promise((
|
|
32839
|
-
timer = setTimeout(() =>
|
|
32983
|
+
const timeoutPromise = new Promise((resolve5) => {
|
|
32984
|
+
timer = setTimeout(() => resolve5("timeout"), timeoutMs);
|
|
32840
32985
|
});
|
|
32841
32986
|
try {
|
|
32842
32987
|
const result = await Promise.race([
|
|
@@ -32900,8 +33045,12 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
32900
33045
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
32901
33046
|
const offset = coerceOptionalInt(params.offset, "offset", 1, Number.MAX_SAFE_INTEGER);
|
|
32902
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
|
+
});
|
|
32903
33052
|
const req = {
|
|
32904
|
-
file:
|
|
33053
|
+
file: filePath
|
|
32905
33054
|
};
|
|
32906
33055
|
if (offset !== undefined) {
|
|
32907
33056
|
req.start_line = offset;
|
|
@@ -32918,7 +33067,7 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
32918
33067
|
}
|
|
32919
33068
|
let text = response.content ?? "";
|
|
32920
33069
|
const agentSpecifiedRange = offset !== undefined || limit !== undefined;
|
|
32921
|
-
const footer =
|
|
33070
|
+
const footer = formatReadFooter2(agentSpecifiedRange, response);
|
|
32922
33071
|
if (footer)
|
|
32923
33072
|
text += footer;
|
|
32924
33073
|
return textResult(text);
|
|
@@ -33174,15 +33323,15 @@ ${summary}${suffix}`);
|
|
|
33174
33323
|
container.addChild(new Text(renderDiff(diff), 1, 0));
|
|
33175
33324
|
return container;
|
|
33176
33325
|
}
|
|
33177
|
-
function shortenPath(
|
|
33178
|
-
const home =
|
|
33179
|
-
if (
|
|
33180
|
-
return `~${
|
|
33181
|
-
return
|
|
33326
|
+
function shortenPath(path3) {
|
|
33327
|
+
const home = homedir10();
|
|
33328
|
+
if (path3.startsWith(home))
|
|
33329
|
+
return `~${path3.slice(home.length)}`;
|
|
33330
|
+
return path3;
|
|
33182
33331
|
}
|
|
33183
|
-
async function resolvePathArg(cwd,
|
|
33184
|
-
const expanded =
|
|
33185
|
-
const abs =
|
|
33332
|
+
async function resolvePathArg(cwd, path3) {
|
|
33333
|
+
const expanded = expandTilde2(path3);
|
|
33334
|
+
const abs = isAbsolute4(expanded) ? expanded : resolve4(cwd, expanded);
|
|
33186
33335
|
try {
|
|
33187
33336
|
await stat(abs);
|
|
33188
33337
|
return abs;
|
|
@@ -33220,23 +33369,12 @@ function splitIncludeGlobs(include) {
|
|
|
33220
33369
|
out.push(tail2);
|
|
33221
33370
|
return out;
|
|
33222
33371
|
}
|
|
33223
|
-
function
|
|
33224
|
-
|
|
33225
|
-
return "";
|
|
33226
|
-
if (!data.truncated)
|
|
33227
|
-
return "";
|
|
33228
|
-
const startLine = data.start_line;
|
|
33229
|
-
const endLine = data.end_line;
|
|
33230
|
-
const totalLines = data.total_lines;
|
|
33231
|
-
if (startLine === undefined || endLine === undefined || totalLines === undefined) {
|
|
33232
|
-
return "";
|
|
33233
|
-
}
|
|
33234
|
-
return `
|
|
33235
|
-
(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" });
|
|
33236
33374
|
}
|
|
33237
33375
|
|
|
33238
33376
|
// src/tools/render-helpers.ts
|
|
33239
|
-
import { homedir as
|
|
33377
|
+
import { homedir as homedir11 } from "node:os";
|
|
33240
33378
|
import { renderDiff as renderDiff2 } from "@earendil-works/pi-coding-agent";
|
|
33241
33379
|
import { Container as Container2, Spacer as Spacer2, Text as Text2 } from "@earendil-works/pi-tui";
|
|
33242
33380
|
function reuseText2(last) {
|
|
@@ -33245,11 +33383,11 @@ function reuseText2(last) {
|
|
|
33245
33383
|
function reuseContainer2(last) {
|
|
33246
33384
|
return last instanceof Container2 ? last : new Container2;
|
|
33247
33385
|
}
|
|
33248
|
-
function shortenPath2(
|
|
33249
|
-
const home =
|
|
33250
|
-
if (
|
|
33251
|
-
return `~${
|
|
33252
|
-
return
|
|
33386
|
+
function shortenPath2(path3) {
|
|
33387
|
+
const home = homedir11();
|
|
33388
|
+
if (path3.startsWith(home))
|
|
33389
|
+
return `~${path3.slice(home.length)}`;
|
|
33390
|
+
return path3;
|
|
33253
33391
|
}
|
|
33254
33392
|
function renderToolCall(toolName, summary, theme, context) {
|
|
33255
33393
|
const text = reuseText2(context.lastComponent);
|
|
@@ -33257,10 +33395,10 @@ function renderToolCall(toolName, summary, theme, context) {
|
|
|
33257
33395
|
text.setText(`${theme.fg("toolTitle", theme.bold(toolName))}${suffix}`);
|
|
33258
33396
|
return text;
|
|
33259
33397
|
}
|
|
33260
|
-
function accentPath(theme,
|
|
33261
|
-
if (!
|
|
33398
|
+
function accentPath(theme, path3) {
|
|
33399
|
+
if (!path3)
|
|
33262
33400
|
return theme.fg("toolOutput", "...");
|
|
33263
|
-
return theme.fg("accent", shortenPath2(
|
|
33401
|
+
return theme.fg("accent", shortenPath2(path3));
|
|
33264
33402
|
}
|
|
33265
33403
|
function collectTextContent(result) {
|
|
33266
33404
|
return result.content.filter((part) => part.type === "text").map((part) => part.text ?? "").join(`
|
|
@@ -33407,7 +33545,7 @@ function renderUnifiedDiff(unifiedDiff) {
|
|
|
33407
33545
|
}
|
|
33408
33546
|
|
|
33409
33547
|
// src/tools/ast.ts
|
|
33410
|
-
var AstLang = StringEnum(["typescript", "tsx", "javascript", "python", "rust", "go", "pascal"], {
|
|
33548
|
+
var AstLang = StringEnum(["typescript", "tsx", "javascript", "python", "rust", "go", "pascal", "r"], {
|
|
33411
33549
|
description: "Target language"
|
|
33412
33550
|
});
|
|
33413
33551
|
var SearchParams = Type3.Object({
|
|
@@ -33448,17 +33586,17 @@ ${warningStrings.map((w) => ` ${w}`).join(`
|
|
|
33448
33586
|
async function resolveAstPaths(extCtx, paths) {
|
|
33449
33587
|
if (isEmptyParam(paths) || !Array.isArray(paths))
|
|
33450
33588
|
return;
|
|
33451
|
-
return Promise.all(paths.filter((
|
|
33589
|
+
return Promise.all(paths.filter((path3) => typeof path3 === "string").map((path3) => resolvePathArg(extCtx.cwd, path3)));
|
|
33452
33590
|
}
|
|
33453
33591
|
async function assertAstPathsPermission(extCtx, paths, action, restrictToProjectRoot) {
|
|
33454
33592
|
if (paths === undefined || paths.length === 0)
|
|
33455
33593
|
return;
|
|
33456
33594
|
const checked = new Set;
|
|
33457
|
-
for (const
|
|
33458
|
-
if (checked.has(
|
|
33595
|
+
for (const path3 of paths) {
|
|
33596
|
+
if (checked.has(path3))
|
|
33459
33597
|
continue;
|
|
33460
|
-
checked.add(
|
|
33461
|
-
await assertExternalDirectoryPermission(extCtx,
|
|
33598
|
+
checked.add(path3);
|
|
33599
|
+
await assertExternalDirectoryPermission(extCtx, path3, action, { restrictToProjectRoot });
|
|
33462
33600
|
}
|
|
33463
33601
|
}
|
|
33464
33602
|
function buildAstSearchSections(payload, theme) {
|
|
@@ -33641,6 +33779,7 @@ var FOREGROUND_POLL_INTERVAL_MS = 100;
|
|
|
33641
33779
|
var BASH_WAIT_POLL_INTERVAL_MS = 100;
|
|
33642
33780
|
var DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS = 30000;
|
|
33643
33781
|
var MAX_BASH_STATUS_WAIT_TIMEOUT_MS = 300000;
|
|
33782
|
+
var REGEX_WAIT_SCAN_WINDOW_BYTES = 64 * 1024;
|
|
33644
33783
|
function resolveForegroundWaitMs(configured) {
|
|
33645
33784
|
const override = process.env.AFT_TEST_FOREGROUND_WAIT_MS;
|
|
33646
33785
|
if (override !== undefined) {
|
|
@@ -33825,7 +33964,7 @@ DO NOT use bash for code search or code exploration. If you are about to run gre
|
|
|
33825
33964
|
throw new Error(status.message ?? "bash_status failed");
|
|
33826
33965
|
}
|
|
33827
33966
|
if (isTerminalStatus(status.status)) {
|
|
33828
|
-
return bashResult(appendPipeStripNote(withBashHints(formatForegroundResult(status), bridgeCommand, aftSearchRegistered), pipeStrip.note), {
|
|
33967
|
+
return bashResult(appendPipeStripNote(withBashHints(formatForegroundResult(status), bridgeCommand, aftSearchRegistered, extCtx.cwd), pipeStrip.note), {
|
|
33829
33968
|
exit_code: status.exit_code,
|
|
33830
33969
|
duration_ms: status.duration_ms,
|
|
33831
33970
|
truncated: status.output_truncated,
|
|
@@ -33852,7 +33991,7 @@ DO NOT use bash for code search or code exploration. If you are about to run gre
|
|
|
33852
33991
|
task_id: taskId
|
|
33853
33992
|
};
|
|
33854
33993
|
const output = response.output ?? "";
|
|
33855
|
-
return bashResult(appendPipeStripNote(withBashHints(output, bridgeCommand, aftSearchRegistered), pipeStrip.note), details);
|
|
33994
|
+
return bashResult(appendPipeStripNote(withBashHints(output, bridgeCommand, aftSearchRegistered, extCtx.cwd), pipeStrip.note), details);
|
|
33856
33995
|
},
|
|
33857
33996
|
renderCall(args, theme, context) {
|
|
33858
33997
|
return renderBashCall(args?.command, args?.description, theme, context);
|
|
@@ -33866,11 +34005,6 @@ DO NOT use bash for code search or code exploration. If you are about to run gre
|
|
|
33866
34005
|
pi.registerTool(createBashWriteTool(ctx));
|
|
33867
34006
|
pi.registerTool(createBashKillTool(ctx));
|
|
33868
34007
|
}
|
|
33869
|
-
function appendPipeStripNote(output, note) {
|
|
33870
|
-
return note ? `${output}
|
|
33871
|
-
|
|
33872
|
-
${note}` : output;
|
|
33873
|
-
}
|
|
33874
34008
|
function formatBackgroundLaunch(taskId, isPty) {
|
|
33875
34009
|
if (isPty) {
|
|
33876
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.`;
|
|
@@ -33881,35 +34015,8 @@ function formatPromotionMessage(taskId, timeout, waitWindowMs) {
|
|
|
33881
34015
|
const waited = timeout !== undefined ? Math.min(timeout, waitWindowMs) : waitWindowMs;
|
|
33882
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.`;
|
|
33883
34017
|
}
|
|
33884
|
-
function
|
|
33885
|
-
return
|
|
33886
|
-
}
|
|
33887
|
-
function withBashHints(output, command, aftSearchRegistered) {
|
|
33888
|
-
return maybeAppendGrepSearchHint(maybeAppendConflictsHint(output), command, aftSearchRegistered);
|
|
33889
|
-
}
|
|
33890
|
-
function formatForegroundResult(data) {
|
|
33891
|
-
const output = data.output_preview ?? "";
|
|
33892
|
-
const outputPath = data.output_path;
|
|
33893
|
-
const truncated = data.output_truncated === true;
|
|
33894
|
-
const status = data.status;
|
|
33895
|
-
const exit = data.exit_code;
|
|
33896
|
-
let rendered = output;
|
|
33897
|
-
if (truncated && outputPath) {
|
|
33898
|
-
rendered += `
|
|
33899
|
-
[output truncated; full output at ${outputPath}]`;
|
|
33900
|
-
}
|
|
33901
|
-
if (status === "timed_out") {
|
|
33902
|
-
rendered += `
|
|
33903
|
-
[command timed out]`;
|
|
33904
|
-
}
|
|
33905
|
-
if (typeof exit === "number" && exit !== 0) {
|
|
33906
|
-
rendered += `
|
|
33907
|
-
[exit code: ${exit}]`;
|
|
33908
|
-
}
|
|
33909
|
-
return rendered;
|
|
33910
|
-
}
|
|
33911
|
-
function sleep(ms) {
|
|
33912
|
-
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
34018
|
+
function withBashHints(output, command, aftSearchRegistered, projectRoot) {
|
|
34019
|
+
return maybeAppendGrepSearchHint(maybeAppendConflictsHint(output), command, aftSearchRegistered, projectRoot);
|
|
33913
34020
|
}
|
|
33914
34021
|
function createBashStatusTool(ctx) {
|
|
33915
34022
|
return {
|
|
@@ -34076,6 +34183,9 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
34076
34183
|
keepBridgeOnTimeout: true,
|
|
34077
34184
|
transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS
|
|
34078
34185
|
};
|
|
34186
|
+
if (waitFor?.kind === "regex") {
|
|
34187
|
+
await validateWaitRegex(bridge, extCtx, waitFor);
|
|
34188
|
+
}
|
|
34079
34189
|
const sessionId = resolveSessionId(extCtx);
|
|
34080
34190
|
clearSyncWatchAbort(sessionId);
|
|
34081
34191
|
if (waitForExit)
|
|
@@ -34092,7 +34202,12 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
34092
34202
|
if (scanText.length === 0)
|
|
34093
34203
|
scanBaseOffset = scan.baseOffset;
|
|
34094
34204
|
scanText += scan.text;
|
|
34095
|
-
|
|
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);
|
|
34096
34211
|
if (match) {
|
|
34097
34212
|
if (waitForExit && terminal) {
|
|
34098
34213
|
sawTerminal = true;
|
|
@@ -34103,9 +34218,14 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
34103
34218
|
reason: "matched",
|
|
34104
34219
|
elapsed_ms: Date.now() - startedAt,
|
|
34105
34220
|
match: match.text,
|
|
34106
|
-
match_offset: scanBaseOffset +
|
|
34221
|
+
match_offset: scanBaseOffset + match.byteOffset
|
|
34107
34222
|
});
|
|
34108
34223
|
}
|
|
34224
|
+
if (waitFor.kind === "substring") {
|
|
34225
|
+
const trimmed = trimWaitScanBuffer(scanText, scanBaseOffset, waitFor);
|
|
34226
|
+
scanText = trimmed.text;
|
|
34227
|
+
scanBaseOffset = trimmed.baseOffset;
|
|
34228
|
+
}
|
|
34109
34229
|
}
|
|
34110
34230
|
}
|
|
34111
34231
|
if (terminal) {
|
|
@@ -34191,20 +34311,69 @@ function parseWaitPattern(value) {
|
|
|
34191
34311
|
if (typeof value === "string")
|
|
34192
34312
|
return { kind: "substring", value };
|
|
34193
34313
|
if (isRegexWaitObject(value))
|
|
34194
|
-
return { kind: "regex",
|
|
34314
|
+
return { kind: "regex", source: value.regex };
|
|
34195
34315
|
return;
|
|
34196
34316
|
}
|
|
34197
34317
|
function isRegexWaitObject(value) {
|
|
34198
34318
|
return typeof value === "object" && value !== null && "regex" in value && typeof value.regex === "string";
|
|
34199
34319
|
}
|
|
34200
|
-
function
|
|
34320
|
+
async function validateWaitRegex(bridge, extCtx, pattern) {
|
|
34321
|
+
await matchRegexWithBridge(bridge, extCtx, pattern.source, "");
|
|
34322
|
+
}
|
|
34323
|
+
async function findWaitMatch(bridge, extCtx, text, pattern) {
|
|
34201
34324
|
if (pattern.kind === "substring") {
|
|
34202
34325
|
const index = text.indexOf(pattern.value);
|
|
34203
|
-
return index >= 0 ? { text: pattern.value, index } : undefined;
|
|
34326
|
+
return index >= 0 ? { text: pattern.value, byteOffset: Buffer.byteLength(text.slice(0, index), "utf8") } : undefined;
|
|
34204
34327
|
}
|
|
34205
|
-
pattern.
|
|
34206
|
-
|
|
34207
|
-
|
|
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;
|
|
34344
|
+
}
|
|
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;
|
|
34208
34377
|
}
|
|
34209
34378
|
function withWaited(data, waited) {
|
|
34210
34379
|
return { ...data, waited };
|
|
@@ -34280,9 +34449,6 @@ function ptyCacheKey(extCtx, taskId) {
|
|
|
34280
34449
|
function watchPtyCacheKey(extCtx, taskId) {
|
|
34281
34450
|
return `${ptyCacheKey(extCtx, taskId)}::watch`;
|
|
34282
34451
|
}
|
|
34283
|
-
function isTerminalStatus(status) {
|
|
34284
|
-
return status === "completed" || status === "failed" || status === "killed" || status === "timed_out";
|
|
34285
|
-
}
|
|
34286
34452
|
function renderBashCall(command, description, theme, context) {
|
|
34287
34453
|
const text = reuseText3(context.lastComponent);
|
|
34288
34454
|
const display = description ?? (command ? shortenCommand(command) : "...");
|
|
@@ -34386,12 +34552,12 @@ function registerConflictsTool(pi, ctx) {
|
|
|
34386
34552
|
async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
|
|
34387
34553
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
34388
34554
|
const reqParams = {};
|
|
34389
|
-
const
|
|
34390
|
-
if (typeof
|
|
34391
|
-
await assertExternalDirectoryPermission(extCtx,
|
|
34555
|
+
const path3 = params?.path;
|
|
34556
|
+
if (typeof path3 === "string" && path3.trim() !== "") {
|
|
34557
|
+
await assertExternalDirectoryPermission(extCtx, path3, "inspect", {
|
|
34392
34558
|
restrictToProjectRoot: ctx.config.restrict_to_project_root ?? false
|
|
34393
34559
|
});
|
|
34394
|
-
reqParams.path = await resolvePathArg(extCtx.cwd,
|
|
34560
|
+
reqParams.path = await resolvePathArg(extCtx.cwd, path3);
|
|
34395
34561
|
}
|
|
34396
34562
|
const response = await callBridge(bridge, "git_conflicts", reqParams, extCtx);
|
|
34397
34563
|
return textResult(response.text ?? JSON.stringify(response, null, 2));
|
|
@@ -34790,8 +34956,8 @@ function tier2SummaryPart(summary, key, label) {
|
|
|
34790
34956
|
return `${label} ${status ?? "unavailable"}`;
|
|
34791
34957
|
}
|
|
34792
34958
|
function shortDupOccurrence(entry) {
|
|
34793
|
-
const [
|
|
34794
|
-
return
|
|
34959
|
+
const [path3] = entry.split(":");
|
|
34960
|
+
return path3?.split("/").pop() ?? entry;
|
|
34795
34961
|
}
|
|
34796
34962
|
function tier2TopPreview(summary, theme) {
|
|
34797
34963
|
const lines = [];
|
|
@@ -35000,9 +35166,9 @@ function depthWarning(response, theme, depthField = "depth_limited", truncatedFi
|
|
|
35000
35166
|
const detail = truncated > 0 ? `, ${truncated} truncated` : "";
|
|
35001
35167
|
return theme.fg("warning", `(depth limited${detail})`);
|
|
35002
35168
|
}
|
|
35003
|
-
function renderTracePath(
|
|
35169
|
+
function renderTracePath(path3, index, lines) {
|
|
35004
35170
|
lines.push(`Path ${index + 1}`);
|
|
35005
|
-
asRecords(
|
|
35171
|
+
asRecords(path3.hops).forEach((hop, hopIndex) => {
|
|
35006
35172
|
const symbol2 = asString(hop.symbol) ?? "(unknown)";
|
|
35007
35173
|
const file2 = shortenPath2(asString(hop.file) ?? "(unknown file)");
|
|
35008
35174
|
const line = asNumber(hop.line);
|
|
@@ -35040,15 +35206,15 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
35040
35206
|
return sections2;
|
|
35041
35207
|
}
|
|
35042
35208
|
if (args.op === "trace_to_symbol") {
|
|
35043
|
-
const
|
|
35209
|
+
const path3 = asRecords(response.path);
|
|
35044
35210
|
const complete = asBoolean(response.complete);
|
|
35045
35211
|
const reason = asString(response.reason);
|
|
35046
|
-
if (
|
|
35212
|
+
if (path3.length === 0) {
|
|
35047
35213
|
const prefix = complete === false ? theme.fg("warning", "No complete path") : theme.fg("muted", "No path");
|
|
35048
35214
|
return [`${prefix}${reason ? ` (${reason})` : ""}`];
|
|
35049
35215
|
}
|
|
35050
|
-
const lines = [theme.fg("success", `${
|
|
35051
|
-
|
|
35216
|
+
const lines = [theme.fg("success", `${path3.length} hop${path3.length === 1 ? "" : "s"}`)];
|
|
35217
|
+
path3.forEach((hop, index) => {
|
|
35052
35218
|
const symbol2 = asString(hop.symbol) ?? "(unknown)";
|
|
35053
35219
|
const file2 = shortenPath2(asString(hop.file) ?? "(unknown file)");
|
|
35054
35220
|
const line = asNumber(hop.line);
|
|
@@ -35064,9 +35230,9 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
35064
35230
|
];
|
|
35065
35231
|
if (paths.length === 0)
|
|
35066
35232
|
sections2.push(theme.fg("muted", "No entry paths found."));
|
|
35067
|
-
paths.forEach((
|
|
35233
|
+
paths.forEach((path3, index) => {
|
|
35068
35234
|
const lines = [];
|
|
35069
|
-
renderTracePath(
|
|
35235
|
+
renderTracePath(path3, index, lines);
|
|
35070
35236
|
sections2.push(lines.join(`
|
|
35071
35237
|
`));
|
|
35072
35238
|
});
|
|
@@ -35524,6 +35690,11 @@ Pass a single \`target\`:
|
|
|
35524
35690
|
}));
|
|
35525
35691
|
if (symbolsArray.length === 1) {
|
|
35526
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
|
+
}
|
|
35527
35698
|
if (response2.success === false) {
|
|
35528
35699
|
throw new Error(response2.message || "zoom failed");
|
|
35529
35700
|
}
|
|
@@ -35759,7 +35930,7 @@ function registerRefactorTool(pi, ctx) {
|
|
|
35759
35930
|
import { StringEnum as StringEnum5 } from "@earendil-works/pi-ai";
|
|
35760
35931
|
import { Type as Type12 } from "typebox";
|
|
35761
35932
|
function responsePaths(response) {
|
|
35762
|
-
return Array.isArray(response.paths) ? response.paths.filter((
|
|
35933
|
+
return Array.isArray(response.paths) ? response.paths.filter((path3) => typeof path3 === "string" && path3.length > 0) : [];
|
|
35763
35934
|
}
|
|
35764
35935
|
var SafetyParams = Type12.Object({
|
|
35765
35936
|
op: StringEnum5(["undo", "history", "checkpoint", "restore", "list"], {
|
|
@@ -36225,18 +36396,18 @@ function createVersionMismatchHandler(getPool, ensureCompatibleBinary = ensureBi
|
|
|
36225
36396
|
const upgradePromise = (async () => {
|
|
36226
36397
|
warn2(`WARNING: aft binary v${binaryVersion} is older than plugin v${minVersion}. ` + "Some features may not work. Attempting to download a compatible binary...");
|
|
36227
36398
|
try {
|
|
36228
|
-
const
|
|
36229
|
-
if (!
|
|
36399
|
+
const path3 = await ensureCompatibleBinary(`v${minVersion}`);
|
|
36400
|
+
if (!path3) {
|
|
36230
36401
|
warn2(`Could not find or download v${minVersion}. Continuing with v${binaryVersion}.`);
|
|
36231
36402
|
return null;
|
|
36232
36403
|
}
|
|
36233
36404
|
const pool = getPool();
|
|
36234
36405
|
if (!pool) {
|
|
36235
|
-
warn2(`Found/downloaded compatible binary at ${
|
|
36406
|
+
warn2(`Found/downloaded compatible binary at ${path3}, but bridge pool is not ready.`);
|
|
36236
36407
|
return null;
|
|
36237
36408
|
}
|
|
36238
|
-
log2(`Found/downloaded compatible binary at ${
|
|
36239
|
-
const replaced = await pool.replaceBinary(
|
|
36409
|
+
log2(`Found/downloaded compatible binary at ${path3}. Replacing running bridges...`);
|
|
36410
|
+
const replaced = await pool.replaceBinary(path3);
|
|
36240
36411
|
log2("Binary replaced successfully. New bridges will use the updated binary.");
|
|
36241
36412
|
return replaced;
|
|
36242
36413
|
} catch (err) {
|
|
@@ -36561,7 +36732,7 @@ ${lines}
|
|
|
36561
36732
|
if (onnxRuntimePromise) {
|
|
36562
36733
|
await Promise.race([
|
|
36563
36734
|
onnxRuntimePromise,
|
|
36564
|
-
new Promise((
|
|
36735
|
+
new Promise((resolve5) => setTimeout(() => resolve5(null), 60000))
|
|
36565
36736
|
]);
|
|
36566
36737
|
}
|
|
36567
36738
|
const bridge = pool.getBridge(cwd);
|