@cortexkit/aft-pi 0.26.4 → 0.27.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/bg-notifications.d.ts +3 -0
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/dialogs/status-dialog.d.ts +4 -1
- package/dist/dialogs/status-dialog.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +556 -407
- package/dist/notifications.d.ts +2 -0
- package/dist/notifications.d.ts.map +1 -1
- package/dist/shared/status.d.ts +12 -0
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts +7 -0
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -8301,11 +8301,11 @@ var require_fixed_queue = __commonJS((exports, module) => {
|
|
|
8301
8301
|
this.head.push(data);
|
|
8302
8302
|
}
|
|
8303
8303
|
shift() {
|
|
8304
|
-
const
|
|
8305
|
-
const next =
|
|
8306
|
-
if (
|
|
8307
|
-
this.tail =
|
|
8308
|
-
|
|
8304
|
+
const tail2 = this.tail;
|
|
8305
|
+
const next = tail2.shift();
|
|
8306
|
+
if (tail2.isEmpty() && tail2.next !== null) {
|
|
8307
|
+
this.tail = tail2.next;
|
|
8308
|
+
tail2.next = null;
|
|
8309
8309
|
}
|
|
8310
8310
|
return next;
|
|
8311
8311
|
}
|
|
@@ -12716,7 +12716,7 @@ var require_snapshot_utils = __commonJS((exports, module) => {
|
|
|
12716
12716
|
// ../../node_modules/.bun/undici@8.2.0/node_modules/undici/lib/mock/snapshot-recorder.js
|
|
12717
12717
|
var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
12718
12718
|
var { writeFile, readFile, mkdir } = __require("node:fs/promises");
|
|
12719
|
-
var { dirname:
|
|
12719
|
+
var { dirname: dirname3, resolve: resolve2 } = __require("node:path");
|
|
12720
12720
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
12721
12721
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
12722
12722
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -12911,7 +12911,7 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
|
12911
12911
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
12912
12912
|
}
|
|
12913
12913
|
const resolvedPath = resolve2(path);
|
|
12914
|
-
await mkdir(
|
|
12914
|
+
await mkdir(dirname3(resolvedPath), { recursive: true });
|
|
12915
12915
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
12916
12916
|
hash,
|
|
12917
12917
|
snapshot
|
|
@@ -20784,7 +20784,7 @@ var require_permessage_deflate = __commonJS((exports, module) => {
|
|
|
20784
20784
|
var { createInflateRaw, Z_DEFAULT_WINDOWBITS } = __require("node:zlib");
|
|
20785
20785
|
var { isValidClientWindowBits } = require_util5();
|
|
20786
20786
|
var { MessageSizeExceededError } = require_errors();
|
|
20787
|
-
var
|
|
20787
|
+
var tail2 = Buffer.from([0, 0, 255, 255]);
|
|
20788
20788
|
var kBuffer = Symbol("kBuffer");
|
|
20789
20789
|
var kLength = Symbol("kLength");
|
|
20790
20790
|
|
|
@@ -20832,7 +20832,7 @@ var require_permessage_deflate = __commonJS((exports, module) => {
|
|
|
20832
20832
|
}
|
|
20833
20833
|
this.#inflate.write(chunk);
|
|
20834
20834
|
if (fin) {
|
|
20835
|
-
this.#inflate.write(
|
|
20835
|
+
this.#inflate.write(tail2);
|
|
20836
20836
|
}
|
|
20837
20837
|
this.#inflate.flush(() => {
|
|
20838
20838
|
if (!this.#inflate) {
|
|
@@ -24197,10 +24197,10 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
24197
24197
|
}();
|
|
24198
24198
|
exports2.TaggedTemplateExpression = TaggedTemplateExpression;
|
|
24199
24199
|
var TemplateElement = function() {
|
|
24200
|
-
function TemplateElement2(value,
|
|
24200
|
+
function TemplateElement2(value, tail2) {
|
|
24201
24201
|
this.type = syntax_1.Syntax.TemplateElement;
|
|
24202
24202
|
this.value = value;
|
|
24203
|
-
this.tail =
|
|
24203
|
+
this.tail = tail2;
|
|
24204
24204
|
}
|
|
24205
24205
|
return TemplateElement2;
|
|
24206
24206
|
}();
|
|
@@ -28040,14 +28040,14 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
28040
28040
|
var terminated = false;
|
|
28041
28041
|
var start = this.index;
|
|
28042
28042
|
var head = this.source[start] === "`";
|
|
28043
|
-
var
|
|
28043
|
+
var tail2 = false;
|
|
28044
28044
|
var rawOffset = 2;
|
|
28045
28045
|
++this.index;
|
|
28046
28046
|
while (!this.eof()) {
|
|
28047
28047
|
var ch = this.source[this.index++];
|
|
28048
28048
|
if (ch === "`") {
|
|
28049
28049
|
rawOffset = 1;
|
|
28050
|
-
|
|
28050
|
+
tail2 = true;
|
|
28051
28051
|
terminated = true;
|
|
28052
28052
|
break;
|
|
28053
28053
|
} else if (ch === "$") {
|
|
@@ -28148,7 +28148,7 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
28148
28148
|
value: this.source.slice(start + 1, this.index - rawOffset),
|
|
28149
28149
|
cooked,
|
|
28150
28150
|
head,
|
|
28151
|
-
tail,
|
|
28151
|
+
tail: tail2,
|
|
28152
28152
|
lineNumber: this.lineNumber,
|
|
28153
28153
|
lineStart: this.lineStart,
|
|
28154
28154
|
start,
|
|
@@ -30318,10 +30318,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
30318
30318
|
replacer = null;
|
|
30319
30319
|
indent = EMPTY;
|
|
30320
30320
|
};
|
|
30321
|
-
var
|
|
30321
|
+
var join8 = (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;
|
|
30322
30322
|
var join_content = (inside, value, gap) => {
|
|
30323
30323
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
30324
|
-
return
|
|
30324
|
+
return join8(comment, inside, gap);
|
|
30325
30325
|
};
|
|
30326
30326
|
var stringify_string = (holder, key, value) => {
|
|
30327
30327
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -30343,13 +30343,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
30343
30343
|
if (i !== 0) {
|
|
30344
30344
|
inside += COMMA;
|
|
30345
30345
|
}
|
|
30346
|
-
const before =
|
|
30346
|
+
const before = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
30347
30347
|
inside += before || LF + deeper_gap;
|
|
30348
30348
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
30349
30349
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
30350
30350
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
30351
30351
|
}
|
|
30352
|
-
inside +=
|
|
30352
|
+
inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
30353
30353
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
30354
30354
|
};
|
|
30355
30355
|
var object_stringify = (value, gap) => {
|
|
@@ -30370,13 +30370,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
30370
30370
|
inside += COMMA;
|
|
30371
30371
|
}
|
|
30372
30372
|
first = false;
|
|
30373
|
-
const before =
|
|
30373
|
+
const before = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
30374
30374
|
inside += before || LF + deeper_gap;
|
|
30375
30375
|
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);
|
|
30376
30376
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
30377
30377
|
};
|
|
30378
30378
|
keys.forEach(iteratee);
|
|
30379
|
-
inside +=
|
|
30379
|
+
inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
30380
30380
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
30381
30381
|
};
|
|
30382
30382
|
function stringify(key, holder, gap) {
|
|
@@ -30475,8 +30475,6 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
30475
30475
|
|
|
30476
30476
|
// src/index.ts
|
|
30477
30477
|
import { createRequire as createRequire3 } from "node:module";
|
|
30478
|
-
import { homedir as homedir9 } from "node:os";
|
|
30479
|
-
import { join as join13 } from "node:path";
|
|
30480
30478
|
|
|
30481
30479
|
// ../aft-bridge/dist/active-logger.js
|
|
30482
30480
|
var ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
|
|
@@ -31501,11 +31499,295 @@ async function fetchLatestTag() {
|
|
|
31501
31499
|
clearTimeout(timeout);
|
|
31502
31500
|
}
|
|
31503
31501
|
}
|
|
31502
|
+
// ../aft-bridge/dist/format.js
|
|
31503
|
+
function compressionSavingsPercent(original, compressed) {
|
|
31504
|
+
if (original <= 0)
|
|
31505
|
+
return null;
|
|
31506
|
+
const saved = Math.max(0, original - compressed);
|
|
31507
|
+
return Math.round(saved / original * 100);
|
|
31508
|
+
}
|
|
31509
|
+
// ../aft-bridge/dist/migration.js
|
|
31510
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
31511
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3 } from "node:fs";
|
|
31512
|
+
import { homedir as homedir4, tmpdir } from "node:os";
|
|
31513
|
+
import { dirname, join as join4 } from "node:path";
|
|
31514
|
+
|
|
31515
|
+
// ../aft-bridge/dist/resolver.js
|
|
31516
|
+
import { execSync, spawnSync } from "node:child_process";
|
|
31517
|
+
import { chmodSync as chmodSync2, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync as renameSync2 } from "node:fs";
|
|
31518
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
31519
|
+
import { homedir as homedir3 } from "node:os";
|
|
31520
|
+
import { join as join3 } from "node:path";
|
|
31521
|
+
function readBinaryVersion(binaryPath) {
|
|
31522
|
+
try {
|
|
31523
|
+
const result = spawnSync(binaryPath, ["--version"], {
|
|
31524
|
+
encoding: "utf-8",
|
|
31525
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
31526
|
+
timeout: 5000
|
|
31527
|
+
});
|
|
31528
|
+
const stdoutVersion = result.stdout?.trim();
|
|
31529
|
+
const stderrVersion = result.stderr?.trim();
|
|
31530
|
+
const rawVersion = stdoutVersion || stderrVersion;
|
|
31531
|
+
if (!rawVersion)
|
|
31532
|
+
return null;
|
|
31533
|
+
return rawVersion.replace(/^aft\s+/, "");
|
|
31534
|
+
} catch {
|
|
31535
|
+
return null;
|
|
31536
|
+
}
|
|
31537
|
+
}
|
|
31538
|
+
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
31539
|
+
try {
|
|
31540
|
+
const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
|
|
31541
|
+
if (!version)
|
|
31542
|
+
return null;
|
|
31543
|
+
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
31544
|
+
const cacheDir = getCacheDir();
|
|
31545
|
+
const versionedDir = join3(cacheDir, tag);
|
|
31546
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
31547
|
+
const cachedPath = join3(versionedDir, `aft${ext}`);
|
|
31548
|
+
if (existsSync2(cachedPath)) {
|
|
31549
|
+
const cachedVersion = readBinaryVersion(cachedPath);
|
|
31550
|
+
if (cachedVersion === version)
|
|
31551
|
+
return cachedPath;
|
|
31552
|
+
warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
|
|
31553
|
+
}
|
|
31554
|
+
mkdirSync2(versionedDir, { recursive: true });
|
|
31555
|
+
const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
|
|
31556
|
+
copyFileSync(npmBinaryPath, tmpPath);
|
|
31557
|
+
if (process.platform !== "win32") {
|
|
31558
|
+
chmodSync2(tmpPath, 493);
|
|
31559
|
+
}
|
|
31560
|
+
renameSync2(tmpPath, cachedPath);
|
|
31561
|
+
log(`Copied npm binary to versioned cache: ${cachedPath}`);
|
|
31562
|
+
return cachedPath;
|
|
31563
|
+
} catch (err) {
|
|
31564
|
+
warn(`Failed to copy binary to cache: ${err instanceof Error ? err.message : String(err)}`);
|
|
31565
|
+
return null;
|
|
31566
|
+
}
|
|
31567
|
+
}
|
|
31568
|
+
function normalizeBareVersion(version) {
|
|
31569
|
+
return version.startsWith("v") ? version.slice(1) : version;
|
|
31570
|
+
}
|
|
31571
|
+
function homeDirFromEnv(env) {
|
|
31572
|
+
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir3();
|
|
31573
|
+
}
|
|
31574
|
+
function cacheDirFromEnv(env) {
|
|
31575
|
+
if (process.platform === "win32") {
|
|
31576
|
+
const base2 = env.LOCALAPPDATA || env.APPDATA || join3(homeDirFromEnv(env), "AppData", "Local");
|
|
31577
|
+
return join3(base2, "aft", "bin");
|
|
31578
|
+
}
|
|
31579
|
+
const base = env.XDG_CACHE_HOME || join3(homeDirFromEnv(env), ".cache");
|
|
31580
|
+
return join3(base, "aft", "bin");
|
|
31581
|
+
}
|
|
31582
|
+
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
31583
|
+
const binaryPath = join3(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
31584
|
+
return existsSync2(binaryPath) ? binaryPath : null;
|
|
31585
|
+
}
|
|
31586
|
+
function isExpectedCachedBinary(binaryPath, expectedVersion) {
|
|
31587
|
+
const expected = normalizeBareVersion(expectedVersion);
|
|
31588
|
+
const actual = readBinaryVersion(binaryPath);
|
|
31589
|
+
if (actual === expected)
|
|
31590
|
+
return true;
|
|
31591
|
+
warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
|
|
31592
|
+
return false;
|
|
31593
|
+
}
|
|
31594
|
+
function platformKey(platform = process.platform, arch = process.arch) {
|
|
31595
|
+
const archMap = PLATFORM_ARCH_MAP[platform];
|
|
31596
|
+
if (!archMap) {
|
|
31597
|
+
throw new Error(`Unsupported platform: ${platform} (arch: ${arch}). ` + `Supported platforms: ${Object.keys(PLATFORM_ARCH_MAP).join(", ")}`);
|
|
31598
|
+
}
|
|
31599
|
+
const key = archMap[arch];
|
|
31600
|
+
if (!key) {
|
|
31601
|
+
throw new Error(`Unsupported architecture: ${arch} on platform ${platform}. ` + `Supported architectures for ${platform}: ${Object.keys(archMap).join(", ")}`);
|
|
31602
|
+
}
|
|
31603
|
+
return key;
|
|
31604
|
+
}
|
|
31605
|
+
function findBinarySync(expectedVersion) {
|
|
31606
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
31607
|
+
const env = { ...process.env };
|
|
31608
|
+
const pluginVersion = expectedVersion ?? (() => {
|
|
31609
|
+
try {
|
|
31610
|
+
const req = createRequire2(import.meta.url);
|
|
31611
|
+
return req("../package.json").version;
|
|
31612
|
+
} catch {
|
|
31613
|
+
return null;
|
|
31614
|
+
}
|
|
31615
|
+
})();
|
|
31616
|
+
if (pluginVersion) {
|
|
31617
|
+
const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
|
|
31618
|
+
const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
|
|
31619
|
+
if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
|
|
31620
|
+
return versionCached;
|
|
31621
|
+
}
|
|
31622
|
+
try {
|
|
31623
|
+
const key = platformKey();
|
|
31624
|
+
const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
|
|
31625
|
+
const req = createRequire2(import.meta.url);
|
|
31626
|
+
const resolved = req.resolve(packageBin);
|
|
31627
|
+
if (existsSync2(resolved)) {
|
|
31628
|
+
const npmVersion = readBinaryVersion(resolved);
|
|
31629
|
+
if (npmVersion === null) {
|
|
31630
|
+
warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
|
|
31631
|
+
} else if (pluginVersion && npmVersion !== normalizeBareVersion(pluginVersion)) {
|
|
31632
|
+
warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
|
|
31633
|
+
} else {
|
|
31634
|
+
const copied = copyToVersionedCache(resolved, npmVersion);
|
|
31635
|
+
return copied ?? resolved;
|
|
31636
|
+
}
|
|
31637
|
+
}
|
|
31638
|
+
} catch {}
|
|
31639
|
+
try {
|
|
31640
|
+
const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
|
|
31641
|
+
const result = execSync(whichCmd, {
|
|
31642
|
+
encoding: "utf-8",
|
|
31643
|
+
env,
|
|
31644
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
31645
|
+
}).trim();
|
|
31646
|
+
if (result)
|
|
31647
|
+
return result;
|
|
31648
|
+
} catch {}
|
|
31649
|
+
const cargoPath = join3(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
31650
|
+
if (existsSync2(cargoPath))
|
|
31651
|
+
return cargoPath;
|
|
31652
|
+
return null;
|
|
31653
|
+
}
|
|
31654
|
+
async function findBinary(expectedVersion) {
|
|
31655
|
+
const syncResult = findBinarySync(expectedVersion);
|
|
31656
|
+
if (syncResult) {
|
|
31657
|
+
log(`Resolved binary: ${syncResult}`);
|
|
31658
|
+
return syncResult;
|
|
31659
|
+
}
|
|
31660
|
+
log("Binary not found locally, attempting auto-download...");
|
|
31661
|
+
const downloaded = await ensureBinary(expectedVersion);
|
|
31662
|
+
if (downloaded)
|
|
31663
|
+
return downloaded;
|
|
31664
|
+
throw new Error([
|
|
31665
|
+
"Could not find the `aft` binary.",
|
|
31666
|
+
"",
|
|
31667
|
+
"Attempted sources:",
|
|
31668
|
+
" - Cache directory (~/.cache/aft/bin/)",
|
|
31669
|
+
" - npm platform package (@cortexkit/aft-<platform>)",
|
|
31670
|
+
" - PATH lookup (which aft)",
|
|
31671
|
+
" - ~/.cargo/bin/aft",
|
|
31672
|
+
" - Auto-download from GitHub releases (failed)",
|
|
31673
|
+
"",
|
|
31674
|
+
"Install it using one of these methods:",
|
|
31675
|
+
" npm install @cortexkit/aft-opencode # installs platform-specific binary via npm",
|
|
31676
|
+
" cargo install agent-file-tools # from crates.io",
|
|
31677
|
+
" cargo build --release # from source (binary at target/release/aft)",
|
|
31678
|
+
"",
|
|
31679
|
+
"Or add the aft directory to your PATH."
|
|
31680
|
+
].join(`
|
|
31681
|
+
`));
|
|
31682
|
+
}
|
|
31683
|
+
|
|
31684
|
+
// ../aft-bridge/dist/migration.js
|
|
31685
|
+
var TARGET_MARKER = ".migrated_from_legacy";
|
|
31686
|
+
var DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
31687
|
+
function dataHome() {
|
|
31688
|
+
if (process.env.XDG_DATA_HOME)
|
|
31689
|
+
return process.env.XDG_DATA_HOME;
|
|
31690
|
+
if (process.platform === "win32") {
|
|
31691
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join4(homeDir(), "AppData", "Local");
|
|
31692
|
+
}
|
|
31693
|
+
return join4(homeDir(), ".local", "share");
|
|
31694
|
+
}
|
|
31695
|
+
function homeDir() {
|
|
31696
|
+
if (process.platform === "win32")
|
|
31697
|
+
return process.env.USERPROFILE || process.env.HOME || homedir4();
|
|
31698
|
+
return process.env.HOME || homedir4();
|
|
31699
|
+
}
|
|
31700
|
+
function resolveLegacyStorageRoot(harness) {
|
|
31701
|
+
if (harness === "pi")
|
|
31702
|
+
return join4(homeDir(), ".pi", "agent", "aft");
|
|
31703
|
+
return join4(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
31704
|
+
}
|
|
31705
|
+
function resolveCortexKitStorageRoot() {
|
|
31706
|
+
return join4(dataHome(), "cortexkit", "aft");
|
|
31707
|
+
}
|
|
31708
|
+
function tail(value) {
|
|
31709
|
+
if (!value)
|
|
31710
|
+
return "";
|
|
31711
|
+
return value.split(`
|
|
31712
|
+
`).slice(-20).join(`
|
|
31713
|
+
`).trim();
|
|
31714
|
+
}
|
|
31715
|
+
function spawnErrorLabel(error2) {
|
|
31716
|
+
const code = "code" in error2 ? String(error2.code ?? "") : "";
|
|
31717
|
+
return [code, error2.message].filter(Boolean).join(": ");
|
|
31718
|
+
}
|
|
31719
|
+
function migrationLogPath(newRoot, harness, logger) {
|
|
31720
|
+
const desired = join4(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
31721
|
+
try {
|
|
31722
|
+
mkdirSync3(dirname(desired), { recursive: true });
|
|
31723
|
+
return desired;
|
|
31724
|
+
} catch (err) {
|
|
31725
|
+
const fallback = join4(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
31726
|
+
logger?.warn?.(`Failed to create AFT migration log directory ${dirname(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
31727
|
+
return fallback;
|
|
31728
|
+
}
|
|
31729
|
+
}
|
|
31730
|
+
async function ensureStorageMigrated(opts) {
|
|
31731
|
+
const legacyRoot = resolveLegacyStorageRoot(opts.harness);
|
|
31732
|
+
const newRoot = resolveCortexKitStorageRoot();
|
|
31733
|
+
const targetMarker = join4(newRoot, opts.harness, TARGET_MARKER);
|
|
31734
|
+
const info = opts.logger?.info ?? opts.logger?.log;
|
|
31735
|
+
if (existsSync3(targetMarker)) {
|
|
31736
|
+
info?.(`AFT storage already migrated for ${opts.harness}; using ${newRoot}`);
|
|
31737
|
+
return;
|
|
31738
|
+
}
|
|
31739
|
+
if (!existsSync3(legacyRoot)) {
|
|
31740
|
+
info?.(`AFT storage migration skipped for ${opts.harness}: no legacy data at ${legacyRoot}; ` + `using ${newRoot} for fresh install`);
|
|
31741
|
+
return;
|
|
31742
|
+
}
|
|
31743
|
+
const logPath = migrationLogPath(newRoot, opts.harness, opts.logger);
|
|
31744
|
+
const binaryPath = opts.binaryPath ?? await findBinary();
|
|
31745
|
+
const startMs = Date.now();
|
|
31746
|
+
info?.(`AFT storage migration starting for ${opts.harness}: ${legacyRoot} -> ${newRoot} ` + `(binary=${binaryPath}, log=${logPath})`);
|
|
31747
|
+
try {
|
|
31748
|
+
process.stderr.write(`
|
|
31749
|
+
[AFT] Migrating ${opts.harness} storage to ${newRoot}.
|
|
31750
|
+
` + `[AFT] This may take several minutes for large indexes — please do not close ${opts.harness === "pi" ? "Pi" : "OpenCode"}.
|
|
31751
|
+
` + `[AFT] Source: ${legacyRoot}
|
|
31752
|
+
` + `[AFT] Log: ${logPath}
|
|
31753
|
+
|
|
31754
|
+
`);
|
|
31755
|
+
} catch {}
|
|
31756
|
+
const result = spawnSync2(binaryPath, [
|
|
31757
|
+
"migrate-storage",
|
|
31758
|
+
"--from",
|
|
31759
|
+
legacyRoot,
|
|
31760
|
+
"--to",
|
|
31761
|
+
newRoot,
|
|
31762
|
+
"--harness",
|
|
31763
|
+
opts.harness,
|
|
31764
|
+
"--log",
|
|
31765
|
+
logPath
|
|
31766
|
+
], {
|
|
31767
|
+
encoding: "utf8",
|
|
31768
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
31769
|
+
timeout: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS
|
|
31770
|
+
});
|
|
31771
|
+
if (!result.error && result.status === 0) {
|
|
31772
|
+
const elapsedMs = Date.now() - startMs;
|
|
31773
|
+
info?.(`AFT storage migration completed for ${opts.harness} in ${elapsedMs}ms (log=${logPath})`);
|
|
31774
|
+
try {
|
|
31775
|
+
process.stderr.write(`[AFT] Migration complete (${(elapsedMs / 1000).toFixed(1)}s).
|
|
31776
|
+
|
|
31777
|
+
`);
|
|
31778
|
+
} catch {}
|
|
31779
|
+
return;
|
|
31780
|
+
}
|
|
31781
|
+
const detail = result.error ? `spawn error ${spawnErrorLabel(result.error)}` : result.status === null ? `terminated by signal ${result.signal ?? "unknown"}` : `exit ${result.status}`;
|
|
31782
|
+
const stderrTail = tail(result.stderr);
|
|
31783
|
+
const stdoutTail = tail(result.stdout);
|
|
31784
|
+
throw new Error(`AFT storage migration failed (${detail}). ` + `Harness: ${opts.harness}. Legacy: ${legacyRoot}. Target: ${newRoot}. ` + `See log: ${logPath}. ` + `Plugin load aborted to prevent legacy/new state divergence.` + (stderrTail ? ` Stderr tail: ${stderrTail}` : "") + (stdoutTail ? ` Stdout tail: ${stdoutTail}` : ""));
|
|
31785
|
+
}
|
|
31504
31786
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
31505
31787
|
import { execFileSync } from "node:child_process";
|
|
31506
31788
|
import { createHash as createHash2 } from "node:crypto";
|
|
31507
|
-
import { chmodSync as
|
|
31508
|
-
import { dirname, join as
|
|
31789
|
+
import { chmodSync as chmodSync3, closeSync as closeSync2, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, openSync as openSync2, readdirSync, readFileSync, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
|
|
31790
|
+
import { dirname as dirname2, join as join5, relative, resolve } from "node:path";
|
|
31509
31791
|
import { Readable as Readable2 } from "node:stream";
|
|
31510
31792
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
31511
31793
|
var ORT_VERSION = "1.24.4";
|
|
@@ -31553,8 +31835,8 @@ function getPlatformInfo() {
|
|
|
31553
31835
|
if (!platformMap)
|
|
31554
31836
|
return null;
|
|
31555
31837
|
const archMap = PLATFORM_ARCH_MAP[process.platform] ?? {};
|
|
31556
|
-
const
|
|
31557
|
-
const ortArch =
|
|
31838
|
+
const platformKey2 = archMap[process.arch];
|
|
31839
|
+
const ortArch = platformKey2 ? platformKey2.split("-")[1] : process.arch;
|
|
31558
31840
|
return platformMap[ortArch] || null;
|
|
31559
31841
|
}
|
|
31560
31842
|
function getManualInstallHint() {
|
|
@@ -31568,9 +31850,9 @@ function getManualInstallHint() {
|
|
|
31568
31850
|
}
|
|
31569
31851
|
async function ensureOnnxRuntime(storageDir) {
|
|
31570
31852
|
const info = getPlatformInfo();
|
|
31571
|
-
const ortDir =
|
|
31572
|
-
const libPath =
|
|
31573
|
-
if (
|
|
31853
|
+
const ortDir = join5(storageDir, "onnxruntime", ORT_VERSION);
|
|
31854
|
+
const libPath = join5(ortDir, info?.libName ?? "libonnxruntime.dylib");
|
|
31855
|
+
if (existsSync4(libPath)) {
|
|
31574
31856
|
const meta = readOnnxInstalledMeta(ortDir);
|
|
31575
31857
|
if (meta?.sha256) {
|
|
31576
31858
|
try {
|
|
@@ -31599,9 +31881,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
31599
31881
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
31600
31882
|
return null;
|
|
31601
31883
|
}
|
|
31602
|
-
const onnxBaseDir =
|
|
31603
|
-
|
|
31604
|
-
const lockPath =
|
|
31884
|
+
const onnxBaseDir = join5(storageDir, "onnxruntime");
|
|
31885
|
+
mkdirSync4(onnxBaseDir, { recursive: true });
|
|
31886
|
+
const lockPath = join5(onnxBaseDir, ONNX_LOCK_FILE);
|
|
31605
31887
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
31606
31888
|
if (!acquireLock(lockPath)) {
|
|
31607
31889
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -31620,7 +31902,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
31620
31902
|
for (const entry of entries) {
|
|
31621
31903
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
31622
31904
|
continue;
|
|
31623
|
-
const stagingDir =
|
|
31905
|
+
const stagingDir = join5(onnxBaseDir, entry);
|
|
31624
31906
|
const parts = entry.split(".");
|
|
31625
31907
|
const pidStr = parts[parts.length - 2];
|
|
31626
31908
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -31652,7 +31934,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
31652
31934
|
}
|
|
31653
31935
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
31654
31936
|
try {
|
|
31655
|
-
if (
|
|
31937
|
+
if (existsSync4(ortDir) && !existsSync4(join5(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
31656
31938
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
31657
31939
|
rmSync2(ortDir, { recursive: true, force: true });
|
|
31658
31940
|
}
|
|
@@ -31673,8 +31955,8 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
31673
31955
|
if (match)
|
|
31674
31956
|
return match[1];
|
|
31675
31957
|
}
|
|
31676
|
-
const base =
|
|
31677
|
-
if (
|
|
31958
|
+
const base = join5(libDir, libName);
|
|
31959
|
+
if (existsSync4(base)) {
|
|
31678
31960
|
try {
|
|
31679
31961
|
const real = realpathSync(base);
|
|
31680
31962
|
const m = real.match(/\.(\d+\.\d+\.\d+)(?:\.dylib)?$/);
|
|
@@ -31710,7 +31992,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
31710
31992
|
searchPaths.push("/usr/lib", "/usr/lib/x86_64-linux-gnu", "/usr/lib/aarch64-linux-gnu", "/usr/local/lib");
|
|
31711
31993
|
}
|
|
31712
31994
|
for (const dir of searchPaths) {
|
|
31713
|
-
if (!
|
|
31995
|
+
if (!existsSync4(join5(dir, libName)))
|
|
31714
31996
|
continue;
|
|
31715
31997
|
const version = detectOnnxVersion(dir, libName);
|
|
31716
31998
|
if (version && !isOnnxVersionCompatible(version)) {
|
|
@@ -31737,7 +32019,7 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
31737
32019
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
|
|
31738
32020
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
|
|
31739
32021
|
}
|
|
31740
|
-
|
|
32022
|
+
mkdirSync4(dirname2(destPath), { recursive: true });
|
|
31741
32023
|
let bytesWritten = 0;
|
|
31742
32024
|
const guard = new TransformStream({
|
|
31743
32025
|
transform(chunk, transformController) {
|
|
@@ -31767,11 +32049,11 @@ function validateExtractedTree(stagingRoot) {
|
|
|
31767
32049
|
const walk = (dir) => {
|
|
31768
32050
|
const entries = readdirSync(dir);
|
|
31769
32051
|
for (const entry of entries) {
|
|
31770
|
-
const fullPath =
|
|
32052
|
+
const fullPath = join5(dir, entry);
|
|
31771
32053
|
const lst = lstatSync(fullPath);
|
|
31772
32054
|
if (lst.isSymbolicLink()) {
|
|
31773
32055
|
const linkTarget = readlinkSync(fullPath);
|
|
31774
|
-
const resolvedTarget = resolve(
|
|
32056
|
+
const resolvedTarget = resolve(dirname2(fullPath), linkTarget);
|
|
31775
32057
|
const rel2 = relative(realRoot, resolvedTarget);
|
|
31776
32058
|
if (rel2.startsWith("..") || process.platform !== "win32" && rel2.startsWith("/")) {
|
|
31777
32059
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
@@ -31801,8 +32083,8 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
31801
32083
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
31802
32084
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
31803
32085
|
try {
|
|
31804
|
-
|
|
31805
|
-
const archivePath =
|
|
32086
|
+
mkdirSync4(tmpDir, { recursive: true });
|
|
32087
|
+
const archivePath = join5(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
31806
32088
|
await downloadFileWithCap(url, archivePath);
|
|
31807
32089
|
const archiveSha256 = sha256File(archivePath);
|
|
31808
32090
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -31818,16 +32100,16 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
31818
32100
|
unlinkSync2(archivePath);
|
|
31819
32101
|
} catch {}
|
|
31820
32102
|
validateExtractedTree(tmpDir);
|
|
31821
|
-
const extractedDir =
|
|
31822
|
-
if (!
|
|
32103
|
+
const extractedDir = join5(tmpDir, info.assetName, "lib");
|
|
32104
|
+
if (!existsSync4(extractedDir)) {
|
|
31823
32105
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
31824
32106
|
}
|
|
31825
|
-
|
|
32107
|
+
mkdirSync4(targetDir, { recursive: true });
|
|
31826
32108
|
const libFiles = readdirSync(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
|
|
31827
32109
|
const realFiles = [];
|
|
31828
32110
|
const symlinks = [];
|
|
31829
32111
|
for (const libFile of libFiles) {
|
|
31830
|
-
const src =
|
|
32112
|
+
const src = join5(extractedDir, libFile);
|
|
31831
32113
|
try {
|
|
31832
32114
|
const stat = lstatSync(src);
|
|
31833
32115
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -31842,7 +32124,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
31842
32124
|
}
|
|
31843
32125
|
}
|
|
31844
32126
|
copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
|
|
31845
|
-
const libPath =
|
|
32127
|
+
const libPath = join5(targetDir, info.libName);
|
|
31846
32128
|
let libHash = null;
|
|
31847
32129
|
try {
|
|
31848
32130
|
libHash = sha256File(libPath);
|
|
@@ -31864,15 +32146,15 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
31864
32146
|
return null;
|
|
31865
32147
|
}
|
|
31866
32148
|
}
|
|
31867
|
-
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile =
|
|
32149
|
+
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync2) {
|
|
31868
32150
|
const requiredLibs = new Set([info.libName]);
|
|
31869
32151
|
for (const libFile of realFiles) {
|
|
31870
|
-
const src =
|
|
31871
|
-
const dst =
|
|
32152
|
+
const src = join5(extractedDir, libFile);
|
|
32153
|
+
const dst = join5(targetDir, libFile);
|
|
31872
32154
|
try {
|
|
31873
32155
|
copyFile(src, dst);
|
|
31874
32156
|
if (process.platform !== "win32") {
|
|
31875
|
-
|
|
32157
|
+
chmodSync3(dst, 493);
|
|
31876
32158
|
}
|
|
31877
32159
|
} catch (copyErr) {
|
|
31878
32160
|
if (requiredLibs.has(libFile)) {
|
|
@@ -31883,7 +32165,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
31883
32165
|
}
|
|
31884
32166
|
}
|
|
31885
32167
|
for (const link of symlinks) {
|
|
31886
|
-
const dst =
|
|
32168
|
+
const dst = join5(targetDir, link.name);
|
|
31887
32169
|
try {
|
|
31888
32170
|
unlinkSync2(dst);
|
|
31889
32171
|
} catch {}
|
|
@@ -31897,8 +32179,8 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
31897
32179
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
31898
32180
|
}
|
|
31899
32181
|
}
|
|
31900
|
-
const requiredPath =
|
|
31901
|
-
if (!
|
|
32182
|
+
const requiredPath = join5(targetDir, info.libName);
|
|
32183
|
+
if (!existsSync4(requiredPath)) {
|
|
31902
32184
|
rmSync2(targetDir, { recursive: true, force: true });
|
|
31903
32185
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
31904
32186
|
}
|
|
@@ -31924,13 +32206,13 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
31924
32206
|
...sha256 ? { sha256 } : {},
|
|
31925
32207
|
archiveSha256
|
|
31926
32208
|
};
|
|
31927
|
-
writeFileSync(
|
|
32209
|
+
writeFileSync(join5(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
31928
32210
|
} catch (err) {
|
|
31929
32211
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
31930
32212
|
}
|
|
31931
32213
|
}
|
|
31932
32214
|
function readOnnxInstalledMeta(installDir) {
|
|
31933
|
-
const path =
|
|
32215
|
+
const path = join5(installDir, ONNX_INSTALLED_META_FILE);
|
|
31934
32216
|
try {
|
|
31935
32217
|
if (!statSync2(path).isFile())
|
|
31936
32218
|
return null;
|
|
@@ -32045,13 +32327,13 @@ function isProcessAlive(pid) {
|
|
|
32045
32327
|
}
|
|
32046
32328
|
// ../aft-bridge/dist/pool.js
|
|
32047
32329
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
32048
|
-
import { homedir as
|
|
32330
|
+
import { homedir as homedir5 } from "node:os";
|
|
32049
32331
|
var DEFAULT_IDLE_TIMEOUT_MS = Infinity;
|
|
32050
32332
|
var DEFAULT_MAX_POOL_SIZE = 8;
|
|
32051
32333
|
var CLEANUP_INTERVAL_MS = 60 * 1000;
|
|
32052
32334
|
function canonicalHomeDir() {
|
|
32053
32335
|
try {
|
|
32054
|
-
const home =
|
|
32336
|
+
const home = homedir5();
|
|
32055
32337
|
if (!home)
|
|
32056
32338
|
return null;
|
|
32057
32339
|
try {
|
|
@@ -32077,6 +32359,7 @@ class BridgePool {
|
|
|
32077
32359
|
idleTimeoutMs;
|
|
32078
32360
|
bridgeOptions;
|
|
32079
32361
|
configOverrides;
|
|
32362
|
+
projectConfigLoader;
|
|
32080
32363
|
logger;
|
|
32081
32364
|
cleanupTimer = null;
|
|
32082
32365
|
constructor(binaryPath, options = {}, configOverrides = {}) {
|
|
@@ -32084,6 +32367,7 @@ class BridgePool {
|
|
|
32084
32367
|
this.maxPoolSize = options.maxPoolSize ?? DEFAULT_MAX_POOL_SIZE;
|
|
32085
32368
|
this.idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
32086
32369
|
this.logger = options.logger;
|
|
32370
|
+
this.projectConfigLoader = options.projectConfigLoader;
|
|
32087
32371
|
this.bridgeOptions = {
|
|
32088
32372
|
timeoutMs: options.timeoutMs,
|
|
32089
32373
|
maxRestarts: options.maxRestarts,
|
|
@@ -32119,7 +32403,17 @@ class BridgePool {
|
|
|
32119
32403
|
if (this.bridges.size >= this.maxPoolSize) {
|
|
32120
32404
|
this.evictLRU();
|
|
32121
32405
|
}
|
|
32122
|
-
|
|
32406
|
+
let projectOverrides = {};
|
|
32407
|
+
if (this.projectConfigLoader) {
|
|
32408
|
+
try {
|
|
32409
|
+
projectOverrides = this.projectConfigLoader(key) ?? {};
|
|
32410
|
+
} catch (err) {
|
|
32411
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
32412
|
+
this.error(`projectConfigLoader failed; using global overrides only: ${message}`);
|
|
32413
|
+
}
|
|
32414
|
+
}
|
|
32415
|
+
const mergedOverrides = { ...this.configOverrides, ...projectOverrides };
|
|
32416
|
+
const bridge = new BinaryBridge(this.binaryPath, key, this.bridgeOptions, mergedOverrides);
|
|
32123
32417
|
this.bridges.set(key, { bridge, lastUsed: Date.now() });
|
|
32124
32418
|
return bridge;
|
|
32125
32419
|
}
|
|
@@ -32212,180 +32506,12 @@ function normalizeKey(projectRoot) {
|
|
|
32212
32506
|
return stripped;
|
|
32213
32507
|
}
|
|
32214
32508
|
}
|
|
32215
|
-
// ../aft-bridge/dist/resolver.js
|
|
32216
|
-
import { execSync, spawnSync } from "node:child_process";
|
|
32217
|
-
import { chmodSync as chmodSync3, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync2 } from "node:fs";
|
|
32218
|
-
import { createRequire as createRequire2 } from "node:module";
|
|
32219
|
-
import { homedir as homedir4 } from "node:os";
|
|
32220
|
-
import { join as join4 } from "node:path";
|
|
32221
|
-
function readBinaryVersion(binaryPath) {
|
|
32222
|
-
try {
|
|
32223
|
-
const result = spawnSync(binaryPath, ["--version"], {
|
|
32224
|
-
encoding: "utf-8",
|
|
32225
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
32226
|
-
timeout: 5000
|
|
32227
|
-
});
|
|
32228
|
-
const stdoutVersion = result.stdout?.trim();
|
|
32229
|
-
const stderrVersion = result.stderr?.trim();
|
|
32230
|
-
const rawVersion = stdoutVersion || stderrVersion;
|
|
32231
|
-
if (!rawVersion)
|
|
32232
|
-
return null;
|
|
32233
|
-
return rawVersion.replace(/^aft\s+/, "");
|
|
32234
|
-
} catch {
|
|
32235
|
-
return null;
|
|
32236
|
-
}
|
|
32237
|
-
}
|
|
32238
|
-
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
32239
|
-
try {
|
|
32240
|
-
const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
|
|
32241
|
-
if (!version)
|
|
32242
|
-
return null;
|
|
32243
|
-
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
32244
|
-
const cacheDir = getCacheDir();
|
|
32245
|
-
const versionedDir = join4(cacheDir, tag);
|
|
32246
|
-
const ext = process.platform === "win32" ? ".exe" : "";
|
|
32247
|
-
const cachedPath = join4(versionedDir, `aft${ext}`);
|
|
32248
|
-
if (existsSync3(cachedPath)) {
|
|
32249
|
-
const cachedVersion = readBinaryVersion(cachedPath);
|
|
32250
|
-
if (cachedVersion === version)
|
|
32251
|
-
return cachedPath;
|
|
32252
|
-
warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
|
|
32253
|
-
}
|
|
32254
|
-
mkdirSync3(versionedDir, { recursive: true });
|
|
32255
|
-
const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
|
|
32256
|
-
copyFileSync2(npmBinaryPath, tmpPath);
|
|
32257
|
-
if (process.platform !== "win32") {
|
|
32258
|
-
chmodSync3(tmpPath, 493);
|
|
32259
|
-
}
|
|
32260
|
-
renameSync2(tmpPath, cachedPath);
|
|
32261
|
-
log(`Copied npm binary to versioned cache: ${cachedPath}`);
|
|
32262
|
-
return cachedPath;
|
|
32263
|
-
} catch (err) {
|
|
32264
|
-
warn(`Failed to copy binary to cache: ${err instanceof Error ? err.message : String(err)}`);
|
|
32265
|
-
return null;
|
|
32266
|
-
}
|
|
32267
|
-
}
|
|
32268
|
-
function normalizeBareVersion(version) {
|
|
32269
|
-
return version.startsWith("v") ? version.slice(1) : version;
|
|
32270
|
-
}
|
|
32271
|
-
function homeDirFromEnv(env) {
|
|
32272
|
-
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir4();
|
|
32273
|
-
}
|
|
32274
|
-
function cacheDirFromEnv(env) {
|
|
32275
|
-
if (process.platform === "win32") {
|
|
32276
|
-
const base2 = env.LOCALAPPDATA || env.APPDATA || join4(homeDirFromEnv(env), "AppData", "Local");
|
|
32277
|
-
return join4(base2, "aft", "bin");
|
|
32278
|
-
}
|
|
32279
|
-
const base = env.XDG_CACHE_HOME || join4(homeDirFromEnv(env), ".cache");
|
|
32280
|
-
return join4(base, "aft", "bin");
|
|
32281
|
-
}
|
|
32282
|
-
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
32283
|
-
const binaryPath = join4(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
32284
|
-
return existsSync3(binaryPath) ? binaryPath : null;
|
|
32285
|
-
}
|
|
32286
|
-
function isExpectedCachedBinary(binaryPath, expectedVersion) {
|
|
32287
|
-
const expected = normalizeBareVersion(expectedVersion);
|
|
32288
|
-
const actual = readBinaryVersion(binaryPath);
|
|
32289
|
-
if (actual === expected)
|
|
32290
|
-
return true;
|
|
32291
|
-
warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
|
|
32292
|
-
return false;
|
|
32293
|
-
}
|
|
32294
|
-
function platformKey(platform = process.platform, arch = process.arch) {
|
|
32295
|
-
const archMap = PLATFORM_ARCH_MAP[platform];
|
|
32296
|
-
if (!archMap) {
|
|
32297
|
-
throw new Error(`Unsupported platform: ${platform} (arch: ${arch}). ` + `Supported platforms: ${Object.keys(PLATFORM_ARCH_MAP).join(", ")}`);
|
|
32298
|
-
}
|
|
32299
|
-
const key = archMap[arch];
|
|
32300
|
-
if (!key) {
|
|
32301
|
-
throw new Error(`Unsupported architecture: ${arch} on platform ${platform}. ` + `Supported architectures for ${platform}: ${Object.keys(archMap).join(", ")}`);
|
|
32302
|
-
}
|
|
32303
|
-
return key;
|
|
32304
|
-
}
|
|
32305
|
-
function findBinarySync(expectedVersion) {
|
|
32306
|
-
const ext = process.platform === "win32" ? ".exe" : "";
|
|
32307
|
-
const env = { ...process.env };
|
|
32308
|
-
const pluginVersion = expectedVersion ?? (() => {
|
|
32309
|
-
try {
|
|
32310
|
-
const req = createRequire2(import.meta.url);
|
|
32311
|
-
return req("../package.json").version;
|
|
32312
|
-
} catch {
|
|
32313
|
-
return null;
|
|
32314
|
-
}
|
|
32315
|
-
})();
|
|
32316
|
-
if (pluginVersion) {
|
|
32317
|
-
const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
|
|
32318
|
-
const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
|
|
32319
|
-
if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
|
|
32320
|
-
return versionCached;
|
|
32321
|
-
}
|
|
32322
|
-
try {
|
|
32323
|
-
const key = platformKey();
|
|
32324
|
-
const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
|
|
32325
|
-
const req = createRequire2(import.meta.url);
|
|
32326
|
-
const resolved = req.resolve(packageBin);
|
|
32327
|
-
if (existsSync3(resolved)) {
|
|
32328
|
-
const npmVersion = readBinaryVersion(resolved);
|
|
32329
|
-
if (npmVersion === null) {
|
|
32330
|
-
warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
|
|
32331
|
-
} else if (pluginVersion && npmVersion !== normalizeBareVersion(pluginVersion)) {
|
|
32332
|
-
warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
|
|
32333
|
-
} else {
|
|
32334
|
-
const copied = copyToVersionedCache(resolved, npmVersion);
|
|
32335
|
-
return copied ?? resolved;
|
|
32336
|
-
}
|
|
32337
|
-
}
|
|
32338
|
-
} catch {}
|
|
32339
|
-
try {
|
|
32340
|
-
const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
|
|
32341
|
-
const result = execSync(whichCmd, {
|
|
32342
|
-
encoding: "utf-8",
|
|
32343
|
-
env,
|
|
32344
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
32345
|
-
}).trim();
|
|
32346
|
-
if (result)
|
|
32347
|
-
return result;
|
|
32348
|
-
} catch {}
|
|
32349
|
-
const cargoPath = join4(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
32350
|
-
if (existsSync3(cargoPath))
|
|
32351
|
-
return cargoPath;
|
|
32352
|
-
return null;
|
|
32353
|
-
}
|
|
32354
|
-
async function findBinary(expectedVersion) {
|
|
32355
|
-
const syncResult = findBinarySync(expectedVersion);
|
|
32356
|
-
if (syncResult) {
|
|
32357
|
-
log(`Resolved binary: ${syncResult}`);
|
|
32358
|
-
return syncResult;
|
|
32359
|
-
}
|
|
32360
|
-
log("Binary not found locally, attempting auto-download...");
|
|
32361
|
-
const downloaded = await ensureBinary(expectedVersion);
|
|
32362
|
-
if (downloaded)
|
|
32363
|
-
return downloaded;
|
|
32364
|
-
throw new Error([
|
|
32365
|
-
"Could not find the `aft` binary.",
|
|
32366
|
-
"",
|
|
32367
|
-
"Attempted sources:",
|
|
32368
|
-
" - Cache directory (~/.cache/aft/bin/)",
|
|
32369
|
-
" - npm platform package (@cortexkit/aft-<platform>)",
|
|
32370
|
-
" - PATH lookup (which aft)",
|
|
32371
|
-
" - ~/.cargo/bin/aft",
|
|
32372
|
-
" - Auto-download from GitHub releases (failed)",
|
|
32373
|
-
"",
|
|
32374
|
-
"Install it using one of these methods:",
|
|
32375
|
-
" npm install @cortexkit/aft-opencode # installs platform-specific binary via npm",
|
|
32376
|
-
" cargo install agent-file-tools # from crates.io",
|
|
32377
|
-
" cargo build --release # from source (binary at target/release/aft)",
|
|
32378
|
-
"",
|
|
32379
|
-
"Or add the aft directory to your PATH."
|
|
32380
|
-
].join(`
|
|
32381
|
-
`));
|
|
32382
|
-
}
|
|
32383
32509
|
// ../aft-bridge/dist/url-fetch.js
|
|
32384
32510
|
import { createHash as createHash3 } from "node:crypto";
|
|
32385
32511
|
import { lookup } from "node:dns/promises";
|
|
32386
|
-
import { existsSync as
|
|
32512
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
32387
32513
|
import { isIP } from "node:net";
|
|
32388
|
-
import { join as
|
|
32514
|
+
import { join as join6 } from "node:path";
|
|
32389
32515
|
|
|
32390
32516
|
// ../../node_modules/.bun/undici@8.2.0/node_modules/undici/index.js
|
|
32391
32517
|
var __filename = "/home/runner/work/aft/aft/node_modules/.bun/undici@8.2.0/node_modules/undici/index.js";
|
|
@@ -32535,16 +32661,16 @@ var CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
|
32535
32661
|
var FETCH_TIMEOUT_MS = 30000;
|
|
32536
32662
|
var MAX_REDIRECTS = 5;
|
|
32537
32663
|
function cacheDir(storageDir) {
|
|
32538
|
-
return
|
|
32664
|
+
return join6(storageDir, "url_cache");
|
|
32539
32665
|
}
|
|
32540
32666
|
function hashUrl(url) {
|
|
32541
32667
|
return createHash3("sha256").update(url).digest("hex").slice(0, 16);
|
|
32542
32668
|
}
|
|
32543
32669
|
function metaPath(storageDir, hash) {
|
|
32544
|
-
return
|
|
32670
|
+
return join6(cacheDir(storageDir), `${hash}.meta.json`);
|
|
32545
32671
|
}
|
|
32546
32672
|
function contentPath(storageDir, hash, extension) {
|
|
32547
|
-
return
|
|
32673
|
+
return join6(cacheDir(storageDir), `${hash}${extension}`);
|
|
32548
32674
|
}
|
|
32549
32675
|
function _isPrivateIpv4(address) {
|
|
32550
32676
|
const parts = address.split(".").map((part) => Number.parseInt(part, 10));
|
|
@@ -32562,9 +32688,9 @@ function expandIpv6(addr) {
|
|
|
32562
32688
|
let normalized = addr;
|
|
32563
32689
|
const lastColon = normalized.lastIndexOf(":");
|
|
32564
32690
|
if (lastColon !== -1) {
|
|
32565
|
-
const
|
|
32566
|
-
if (
|
|
32567
|
-
const octets =
|
|
32691
|
+
const tail2 = normalized.slice(lastColon + 1);
|
|
32692
|
+
if (tail2.includes(".")) {
|
|
32693
|
+
const octets = tail2.split(".").map((p) => Number.parseInt(p, 10));
|
|
32568
32694
|
if (octets.length !== 4 || octets.some((o) => Number.isNaN(o) || o < 0 || o > 255)) {
|
|
32569
32695
|
return null;
|
|
32570
32696
|
}
|
|
@@ -32742,15 +32868,15 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
|
|
|
32742
32868
|
const allowPrivate = options.allowPrivate === true;
|
|
32743
32869
|
await assertPublicUrl(parsed, allowPrivate, options.lookup);
|
|
32744
32870
|
const dir = cacheDir(storageDir);
|
|
32745
|
-
|
|
32871
|
+
mkdirSync5(dir, { recursive: true });
|
|
32746
32872
|
const hash = hashUrl(url);
|
|
32747
32873
|
const metaFile = metaPath(storageDir, hash);
|
|
32748
|
-
if (
|
|
32874
|
+
if (existsSync5(metaFile)) {
|
|
32749
32875
|
try {
|
|
32750
32876
|
const meta2 = JSON.parse(readFileSync2(metaFile, "utf8"));
|
|
32751
32877
|
const age = Date.now() - meta2.fetchedAt;
|
|
32752
32878
|
const cached = contentPath(storageDir, hash, meta2.extension);
|
|
32753
|
-
if (age < CACHE_TTL_MS &&
|
|
32879
|
+
if (age < CACHE_TTL_MS && existsSync5(cached)) {
|
|
32754
32880
|
log(`URL cache hit: ${url} (${Math.round(age / 1000)}s old)`);
|
|
32755
32881
|
return cached;
|
|
32756
32882
|
}
|
|
@@ -33056,12 +33182,12 @@ function formatSystemReminder(completions) {
|
|
|
33056
33182
|
const bullets = completions.map((completion) => formatCompletion(completion)).join(`
|
|
33057
33183
|
`);
|
|
33058
33184
|
const anyTruncated = completions.some((c) => c.output_truncated === true);
|
|
33059
|
-
const
|
|
33185
|
+
const tail2 = anyTruncated ? `
|
|
33060
33186
|
|
|
33061
33187
|
For truncated tasks, use bash_status({ task_id: "..." }) to retrieve full output.` : "";
|
|
33062
33188
|
return `<system-reminder>
|
|
33063
33189
|
[BACKGROUND BASH COMPLETED]
|
|
33064
|
-
${bullets}${
|
|
33190
|
+
${bullets}${tail2}
|
|
33065
33191
|
</system-reminder>`;
|
|
33066
33192
|
}
|
|
33067
33193
|
function formatLongRunningReminder(reminders) {
|
|
@@ -33299,7 +33425,7 @@ import {
|
|
|
33299
33425
|
// package.json
|
|
33300
33426
|
var package_default = {
|
|
33301
33427
|
name: "@cortexkit/aft-pi",
|
|
33302
|
-
version: "0.
|
|
33428
|
+
version: "0.27.1",
|
|
33303
33429
|
type: "module",
|
|
33304
33430
|
description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
|
|
33305
33431
|
main: "dist/index.js",
|
|
@@ -33321,18 +33447,18 @@ var package_default = {
|
|
|
33321
33447
|
prepublishOnly: "bun run build"
|
|
33322
33448
|
},
|
|
33323
33449
|
dependencies: {
|
|
33324
|
-
"@cortexkit/aft-bridge": "0.
|
|
33450
|
+
"@cortexkit/aft-bridge": "0.27.1",
|
|
33325
33451
|
typebox: "^1.1.24",
|
|
33326
33452
|
"comment-json": "^5.0.0",
|
|
33327
33453
|
diff: "^8.0.4",
|
|
33328
33454
|
zod: "^4.1.8"
|
|
33329
33455
|
},
|
|
33330
33456
|
optionalDependencies: {
|
|
33331
|
-
"@cortexkit/aft-darwin-arm64": "0.
|
|
33332
|
-
"@cortexkit/aft-darwin-x64": "0.
|
|
33333
|
-
"@cortexkit/aft-linux-arm64": "0.
|
|
33334
|
-
"@cortexkit/aft-linux-x64": "0.
|
|
33335
|
-
"@cortexkit/aft-win32-x64": "0.
|
|
33457
|
+
"@cortexkit/aft-darwin-arm64": "0.27.1",
|
|
33458
|
+
"@cortexkit/aft-darwin-x64": "0.27.1",
|
|
33459
|
+
"@cortexkit/aft-linux-arm64": "0.27.1",
|
|
33460
|
+
"@cortexkit/aft-linux-x64": "0.27.1",
|
|
33461
|
+
"@cortexkit/aft-win32-x64": "0.27.1"
|
|
33336
33462
|
},
|
|
33337
33463
|
devDependencies: {
|
|
33338
33464
|
"@earendil-works/pi-coding-agent": "*",
|
|
@@ -33377,6 +33503,24 @@ function readNumber(value, fallback = 0) {
|
|
|
33377
33503
|
function readOptionalNumber(value) {
|
|
33378
33504
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
33379
33505
|
}
|
|
33506
|
+
function readCompressionAggregate(value) {
|
|
33507
|
+
const aggregate = asRecord(value);
|
|
33508
|
+
return {
|
|
33509
|
+
events: readNumber(aggregate.events),
|
|
33510
|
+
original_tokens: readNumber(aggregate.original_tokens),
|
|
33511
|
+
compressed_tokens: readNumber(aggregate.compressed_tokens),
|
|
33512
|
+
savings_tokens: readNumber(aggregate.savings_tokens)
|
|
33513
|
+
};
|
|
33514
|
+
}
|
|
33515
|
+
function readCompression(value) {
|
|
33516
|
+
if (typeof value !== "object" || value === null)
|
|
33517
|
+
return;
|
|
33518
|
+
const compression = asRecord(value);
|
|
33519
|
+
return {
|
|
33520
|
+
project: readCompressionAggregate(compression.project),
|
|
33521
|
+
session: readCompressionAggregate(compression.session)
|
|
33522
|
+
};
|
|
33523
|
+
}
|
|
33380
33524
|
function formatFlag(enabled) {
|
|
33381
33525
|
return enabled ? "enabled" : "disabled";
|
|
33382
33526
|
}
|
|
@@ -33452,7 +33596,8 @@ function coerceAftStatus(response) {
|
|
|
33452
33596
|
id: readString(session.id, "__default__"),
|
|
33453
33597
|
tracked_files: readNumber(session.tracked_files),
|
|
33454
33598
|
checkpoints: readNumber(session.checkpoints)
|
|
33455
|
-
}
|
|
33599
|
+
},
|
|
33600
|
+
compression: readCompression(response.compression)
|
|
33456
33601
|
};
|
|
33457
33602
|
}
|
|
33458
33603
|
function formatStatusDialogMessage(status) {
|
|
@@ -33688,6 +33833,13 @@ function renderInner(s, error3, theme, innerWidth) {
|
|
|
33688
33833
|
lines.push("");
|
|
33689
33834
|
lines.push(theme.fg("muted", "Features"));
|
|
33690
33835
|
lines.push(` ${featureBadge("format_on_edit", s.features.format_on_edit, theme)} ${featureBadge("search_index", s.features.search_index, theme)} ${featureBadge("semantic_search", s.features.semantic_search, theme)}`);
|
|
33836
|
+
const compressionRows = formatCompressionStatusRows(s.compression);
|
|
33837
|
+
if (compressionRows.length > 0) {
|
|
33838
|
+
lines.push("");
|
|
33839
|
+
lines.push(theme.fg("muted", "Compression"));
|
|
33840
|
+
for (const row of compressionRows)
|
|
33841
|
+
lines.push(row);
|
|
33842
|
+
}
|
|
33691
33843
|
if (s.semantic_index.stage) {
|
|
33692
33844
|
lines.push("");
|
|
33693
33845
|
lines.push(theme.fg("muted", "Semantic build progress"));
|
|
@@ -33711,6 +33863,23 @@ function renderInner(s, error3, theme, innerWidth) {
|
|
|
33711
33863
|
lines.push(theme.fg("muted", "Press Escape to close"));
|
|
33712
33864
|
return lines;
|
|
33713
33865
|
}
|
|
33866
|
+
function appendCompressionScope(rows, label, aggregate) {
|
|
33867
|
+
const pct = compressionSavingsPercent(aggregate.original_tokens, aggregate.compressed_tokens);
|
|
33868
|
+
const savings = aggregate.savings_tokens;
|
|
33869
|
+
rows.push(label);
|
|
33870
|
+
rows.push(` Tokens Saved ${savings.toLocaleString("en-US")}`);
|
|
33871
|
+
rows.push(` Compression Ratio ${pct ?? 0}%`);
|
|
33872
|
+
}
|
|
33873
|
+
function formatCompressionStatusRows(compression) {
|
|
33874
|
+
if (!compression || compression.project.events <= 0)
|
|
33875
|
+
return [];
|
|
33876
|
+
const rows = [];
|
|
33877
|
+
if (compression.session.events > 0) {
|
|
33878
|
+
appendCompressionScope(rows, "Session", compression.session);
|
|
33879
|
+
}
|
|
33880
|
+
appendCompressionScope(rows, "Project", compression.project);
|
|
33881
|
+
return rows;
|
|
33882
|
+
}
|
|
33714
33883
|
function colorStatus(status, theme) {
|
|
33715
33884
|
switch (status) {
|
|
33716
33885
|
case "ready":
|
|
@@ -33817,9 +33986,9 @@ function registerStatusCommand(pi, ctx) {
|
|
|
33817
33986
|
|
|
33818
33987
|
// src/config.ts
|
|
33819
33988
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
33820
|
-
import { existsSync as
|
|
33821
|
-
import { homedir as
|
|
33822
|
-
import { join as
|
|
33989
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
33990
|
+
import { homedir as homedir6 } from "node:os";
|
|
33991
|
+
import { join as join8 } from "node:path";
|
|
33823
33992
|
|
|
33824
33993
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
33825
33994
|
var exports_external = {};
|
|
@@ -47417,6 +47586,7 @@ var ExperimentalConfigSchema = exports_external.object({
|
|
|
47417
47586
|
lsp_ty: exports_external.boolean().optional()
|
|
47418
47587
|
});
|
|
47419
47588
|
var AftConfigSchema = exports_external.object({
|
|
47589
|
+
$schema: exports_external.string().optional(),
|
|
47420
47590
|
format_on_edit: exports_external.boolean().optional(),
|
|
47421
47591
|
formatter_timeout_secs: exports_external.number().int().min(1).max(600).optional(),
|
|
47422
47592
|
validate_on_edit: exports_external.enum(["syntax", "full"]).optional(),
|
|
@@ -47569,7 +47739,7 @@ function migrateRawConfig(rawConfig, configPath, logger) {
|
|
|
47569
47739
|
return oldKeys;
|
|
47570
47740
|
}
|
|
47571
47741
|
function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
|
|
47572
|
-
if (!
|
|
47742
|
+
if (!existsSync6(configPath)) {
|
|
47573
47743
|
return { migrated: false, oldKeys: [] };
|
|
47574
47744
|
}
|
|
47575
47745
|
let tmpPath = null;
|
|
@@ -47612,15 +47782,15 @@ ${serialized}` : serialized;
|
|
|
47612
47782
|
function detectConfigFile(basePath) {
|
|
47613
47783
|
const jsoncPath = `${basePath}.jsonc`;
|
|
47614
47784
|
const jsonPath = `${basePath}.json`;
|
|
47615
|
-
if (
|
|
47785
|
+
if (existsSync6(jsoncPath))
|
|
47616
47786
|
return { format: "jsonc", path: jsoncPath };
|
|
47617
|
-
if (
|
|
47787
|
+
if (existsSync6(jsonPath))
|
|
47618
47788
|
return { format: "json", path: jsonPath };
|
|
47619
47789
|
return { format: "none", path: jsonPath };
|
|
47620
47790
|
}
|
|
47621
47791
|
function loadConfigFromPath(configPath) {
|
|
47622
47792
|
try {
|
|
47623
|
-
if (!
|
|
47793
|
+
if (!existsSync6(configPath))
|
|
47624
47794
|
return null;
|
|
47625
47795
|
const content = readFileSync3(configPath, "utf-8");
|
|
47626
47796
|
const rawConfig = import_comment_json.parse(content);
|
|
@@ -47773,15 +47943,15 @@ function mergeConfigs(base, override) {
|
|
|
47773
47943
|
};
|
|
47774
47944
|
}
|
|
47775
47945
|
function getGlobalPiDir() {
|
|
47776
|
-
return
|
|
47946
|
+
return join8(homedir6(), ".pi", "agent");
|
|
47777
47947
|
}
|
|
47778
47948
|
function loadAftConfig(projectDirectory) {
|
|
47779
|
-
const userBasePath =
|
|
47949
|
+
const userBasePath = join8(getGlobalPiDir(), "aft");
|
|
47780
47950
|
migrateAftConfigFile(`${userBasePath}.jsonc`);
|
|
47781
47951
|
migrateAftConfigFile(`${userBasePath}.json`);
|
|
47782
47952
|
const userDetected = detectConfigFile(userBasePath);
|
|
47783
47953
|
const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
|
|
47784
|
-
const projectBasePath =
|
|
47954
|
+
const projectBasePath = join8(projectDirectory, ".pi", "aft");
|
|
47785
47955
|
migrateAftConfigFile(`${projectBasePath}.jsonc`);
|
|
47786
47956
|
migrateAftConfigFile(`${projectBasePath}.json`);
|
|
47787
47957
|
const projectDetected = detectConfigFile(projectBasePath);
|
|
@@ -47808,49 +47978,49 @@ function loadAftConfig(projectDirectory) {
|
|
|
47808
47978
|
// src/lsp-auto-install.ts
|
|
47809
47979
|
import { spawn as spawn2 } from "node:child_process";
|
|
47810
47980
|
import { createHash as createHash4 } from "node:crypto";
|
|
47811
|
-
import { createReadStream, mkdirSync as
|
|
47812
|
-
import { join as
|
|
47981
|
+
import { createReadStream, mkdirSync as mkdirSync7, readFileSync as readFileSync5, renameSync as renameSync4, rmSync as rmSync3, statSync as statSync4 } from "node:fs";
|
|
47982
|
+
import { join as join11 } from "node:path";
|
|
47813
47983
|
|
|
47814
47984
|
// src/lsp-cache.ts
|
|
47815
47985
|
import {
|
|
47816
47986
|
closeSync as closeSync3,
|
|
47817
|
-
mkdirSync as
|
|
47987
|
+
mkdirSync as mkdirSync6,
|
|
47818
47988
|
openSync as openSync3,
|
|
47819
47989
|
readFileSync as readFileSync4,
|
|
47820
47990
|
statSync as statSync3,
|
|
47821
47991
|
unlinkSync as unlinkSync5,
|
|
47822
47992
|
writeFileSync as writeFileSync4
|
|
47823
47993
|
} from "node:fs";
|
|
47824
|
-
import { homedir as
|
|
47825
|
-
import { join as
|
|
47994
|
+
import { homedir as homedir7 } from "node:os";
|
|
47995
|
+
import { join as join9 } from "node:path";
|
|
47826
47996
|
function aftCacheBase() {
|
|
47827
47997
|
const override = process.env.AFT_CACHE_DIR;
|
|
47828
47998
|
if (override && override.length > 0)
|
|
47829
47999
|
return override;
|
|
47830
48000
|
if (process.platform === "win32") {
|
|
47831
48001
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
47832
|
-
const base2 = localAppData ||
|
|
47833
|
-
return
|
|
48002
|
+
const base2 = localAppData || join9(homedir7(), "AppData", "Local");
|
|
48003
|
+
return join9(base2, "aft");
|
|
47834
48004
|
}
|
|
47835
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
47836
|
-
return
|
|
48005
|
+
const base = process.env.XDG_CACHE_HOME || join9(homedir7(), ".cache");
|
|
48006
|
+
return join9(base, "aft");
|
|
47837
48007
|
}
|
|
47838
48008
|
function lspCacheRoot() {
|
|
47839
|
-
return
|
|
48009
|
+
return join9(aftCacheBase(), "lsp-packages");
|
|
47840
48010
|
}
|
|
47841
48011
|
function lspPackageDir(npmPackage) {
|
|
47842
|
-
return
|
|
48012
|
+
return join9(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
47843
48013
|
}
|
|
47844
48014
|
function lspBinaryPath(npmPackage, binary) {
|
|
47845
|
-
return
|
|
48015
|
+
return join9(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
47846
48016
|
}
|
|
47847
48017
|
function lspBinDir(npmPackage) {
|
|
47848
|
-
return
|
|
48018
|
+
return join9(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
47849
48019
|
}
|
|
47850
48020
|
function isInstalled(npmPackage, binary) {
|
|
47851
48021
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
47852
48022
|
try {
|
|
47853
|
-
if (statSync3(
|
|
48023
|
+
if (statSync3(join9(lspBinDir(npmPackage), candidate)).isFile())
|
|
47854
48024
|
return true;
|
|
47855
48025
|
} catch {}
|
|
47856
48026
|
}
|
|
@@ -47864,19 +48034,19 @@ function lspBinaryCandidates(binary) {
|
|
|
47864
48034
|
var INSTALLED_META_FILE = ".aft-installed";
|
|
47865
48035
|
function writeInstalledMetaIn(installDir, version2, sha256) {
|
|
47866
48036
|
try {
|
|
47867
|
-
|
|
48037
|
+
mkdirSync6(installDir, { recursive: true });
|
|
47868
48038
|
const meta3 = {
|
|
47869
48039
|
version: version2,
|
|
47870
48040
|
installedAt: new Date().toISOString(),
|
|
47871
48041
|
...sha256 ? { sha256 } : {}
|
|
47872
48042
|
};
|
|
47873
|
-
writeFileSync4(
|
|
48043
|
+
writeFileSync4(join9(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
|
|
47874
48044
|
} catch (err) {
|
|
47875
48045
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
47876
48046
|
}
|
|
47877
48047
|
}
|
|
47878
48048
|
function readInstalledMetaIn(installDir) {
|
|
47879
|
-
const path2 =
|
|
48049
|
+
const path2 = join9(installDir, INSTALLED_META_FILE);
|
|
47880
48050
|
try {
|
|
47881
48051
|
if (!statSync3(path2).isFile())
|
|
47882
48052
|
return null;
|
|
@@ -47900,11 +48070,11 @@ function readInstalledMeta(packageKey) {
|
|
|
47900
48070
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
47901
48071
|
}
|
|
47902
48072
|
function lockPath(npmPackage) {
|
|
47903
|
-
return
|
|
48073
|
+
return join9(lspPackageDir(npmPackage), ".aft-installing");
|
|
47904
48074
|
}
|
|
47905
48075
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
47906
48076
|
function acquireInstallLock(lockKey) {
|
|
47907
|
-
|
|
48077
|
+
mkdirSync6(lspPackageDir(lockKey), { recursive: true });
|
|
47908
48078
|
const lock = lockPath(lockKey);
|
|
47909
48079
|
const tryClaim = () => {
|
|
47910
48080
|
try {
|
|
@@ -48007,7 +48177,7 @@ async function withInstallLock(lockKey, task) {
|
|
|
48007
48177
|
}
|
|
48008
48178
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
48009
48179
|
function readVersionCheck(npmPackage) {
|
|
48010
|
-
const file2 =
|
|
48180
|
+
const file2 = join9(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
48011
48181
|
try {
|
|
48012
48182
|
const raw = readFileSync4(file2, "utf8");
|
|
48013
48183
|
const parsed = JSON.parse(raw);
|
|
@@ -48023,8 +48193,8 @@ function readVersionCheck(npmPackage) {
|
|
|
48023
48193
|
}
|
|
48024
48194
|
}
|
|
48025
48195
|
function writeVersionCheck(npmPackage, latest) {
|
|
48026
|
-
|
|
48027
|
-
const file2 =
|
|
48196
|
+
mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
|
|
48197
|
+
const file2 = join9(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
48028
48198
|
const record2 = {
|
|
48029
48199
|
last_checked: new Date().toISOString(),
|
|
48030
48200
|
latest_eligible: latest
|
|
@@ -48172,8 +48342,8 @@ var NPM_LSP_TABLE = [
|
|
|
48172
48342
|
];
|
|
48173
48343
|
|
|
48174
48344
|
// src/lsp-project-relevance.ts
|
|
48175
|
-
import { existsSync as
|
|
48176
|
-
import { join as
|
|
48345
|
+
import { existsSync as existsSync7, readdirSync as readdirSync3 } from "node:fs";
|
|
48346
|
+
import { join as join10 } from "node:path";
|
|
48177
48347
|
var MAX_WALK_DIRS = 200;
|
|
48178
48348
|
var MAX_WALK_DEPTH = 4;
|
|
48179
48349
|
var NOISE_DIRS = new Set([
|
|
@@ -48190,7 +48360,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
48190
48360
|
if (!rootMarkers)
|
|
48191
48361
|
return false;
|
|
48192
48362
|
for (const marker of rootMarkers) {
|
|
48193
|
-
if (
|
|
48363
|
+
if (existsSync7(join10(projectRoot, marker)))
|
|
48194
48364
|
return true;
|
|
48195
48365
|
}
|
|
48196
48366
|
return false;
|
|
@@ -48216,7 +48386,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
48216
48386
|
for (const entry of entries) {
|
|
48217
48387
|
if (entry.isDirectory()) {
|
|
48218
48388
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
48219
|
-
queue.push({ dir:
|
|
48389
|
+
queue.push({ dir: join10(current.dir, entry.name), depth: current.depth + 1 });
|
|
48220
48390
|
}
|
|
48221
48391
|
continue;
|
|
48222
48392
|
}
|
|
@@ -48514,10 +48684,10 @@ function sha256OfFileSync(path2) {
|
|
|
48514
48684
|
}
|
|
48515
48685
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
48516
48686
|
const packageDir = lspPackageDir(spec.npm);
|
|
48517
|
-
const dest =
|
|
48687
|
+
const dest = join11(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
48518
48688
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
48519
48689
|
try {
|
|
48520
|
-
|
|
48690
|
+
mkdirSync7(join11(dest, ".."), { recursive: true });
|
|
48521
48691
|
rmSync3(dest, { recursive: true, force: true });
|
|
48522
48692
|
renameSync4(packageDir, dest);
|
|
48523
48693
|
} catch (err) {
|
|
@@ -48600,9 +48770,9 @@ import {
|
|
|
48600
48770
|
copyFileSync as copyFileSync3,
|
|
48601
48771
|
createReadStream as createReadStream2,
|
|
48602
48772
|
createWriteStream as createWriteStream3,
|
|
48603
|
-
existsSync as
|
|
48773
|
+
existsSync as existsSync8,
|
|
48604
48774
|
lstatSync as lstatSync2,
|
|
48605
|
-
mkdirSync as
|
|
48775
|
+
mkdirSync as mkdirSync8,
|
|
48606
48776
|
readdirSync as readdirSync4,
|
|
48607
48777
|
readFileSync as readFileSync6,
|
|
48608
48778
|
readlinkSync as readlinkSync2,
|
|
@@ -48613,7 +48783,7 @@ import {
|
|
|
48613
48783
|
unlinkSync as unlinkSync6,
|
|
48614
48784
|
writeFileSync as writeFileSync5
|
|
48615
48785
|
} from "node:fs";
|
|
48616
|
-
import { dirname as
|
|
48786
|
+
import { dirname as dirname3, join as join12, relative as relative2, resolve as resolve2 } from "node:path";
|
|
48617
48787
|
import { Readable as Readable3 } from "node:stream";
|
|
48618
48788
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
48619
48789
|
|
|
@@ -48703,26 +48873,26 @@ function detectHostPlatform() {
|
|
|
48703
48873
|
|
|
48704
48874
|
// src/lsp-github-install.ts
|
|
48705
48875
|
function ghCacheRoot() {
|
|
48706
|
-
return
|
|
48876
|
+
return join12(aftCacheBase(), "lsp-binaries");
|
|
48707
48877
|
}
|
|
48708
48878
|
function ghPackageDir(spec) {
|
|
48709
|
-
return
|
|
48879
|
+
return join12(ghCacheRoot(), spec.id);
|
|
48710
48880
|
}
|
|
48711
48881
|
function ghBinDir(spec) {
|
|
48712
|
-
return
|
|
48882
|
+
return join12(ghPackageDir(spec), "bin");
|
|
48713
48883
|
}
|
|
48714
48884
|
function ghExtractDir(spec) {
|
|
48715
|
-
return
|
|
48885
|
+
return join12(ghPackageDir(spec), "extracted");
|
|
48716
48886
|
}
|
|
48717
48887
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
48718
48888
|
function ghBinaryPath(spec, platform) {
|
|
48719
48889
|
const ext = platform === "win32" ? ".exe" : "";
|
|
48720
|
-
return
|
|
48890
|
+
return join12(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
48721
48891
|
}
|
|
48722
48892
|
function isGithubInstalled(spec, platform) {
|
|
48723
48893
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
48724
48894
|
try {
|
|
48725
|
-
if (statSync5(
|
|
48895
|
+
if (statSync5(join12(ghBinDir(spec), candidate)).isFile())
|
|
48726
48896
|
return true;
|
|
48727
48897
|
} catch {}
|
|
48728
48898
|
}
|
|
@@ -48735,7 +48905,7 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
48735
48905
|
}
|
|
48736
48906
|
function readGithubInstalledMetaIn(installDir) {
|
|
48737
48907
|
try {
|
|
48738
|
-
const path2 =
|
|
48908
|
+
const path2 = join12(installDir, INSTALLED_META_FILE2);
|
|
48739
48909
|
if (!statSync5(path2).isFile())
|
|
48740
48910
|
return null;
|
|
48741
48911
|
const parsed = JSON.parse(readFileSync6(path2, "utf8"));
|
|
@@ -48754,7 +48924,7 @@ function readGithubInstalledMetaIn(installDir) {
|
|
|
48754
48924
|
}
|
|
48755
48925
|
function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveSha256) {
|
|
48756
48926
|
try {
|
|
48757
|
-
|
|
48927
|
+
mkdirSync8(installDir, { recursive: true });
|
|
48758
48928
|
const meta3 = {
|
|
48759
48929
|
version: version2,
|
|
48760
48930
|
installedAt: new Date().toISOString(),
|
|
@@ -48762,7 +48932,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
|
|
|
48762
48932
|
binarySha256,
|
|
48763
48933
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
48764
48934
|
};
|
|
48765
|
-
writeFileSync5(
|
|
48935
|
+
writeFileSync5(join12(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
|
|
48766
48936
|
} catch (err) {
|
|
48767
48937
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
48768
48938
|
}
|
|
@@ -48955,7 +49125,7 @@ async function downloadFile(url2, destPath, fetchImpl2, assetSize, signal) {
|
|
|
48955
49125
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
|
|
48956
49126
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
|
|
48957
49127
|
}
|
|
48958
|
-
|
|
49128
|
+
mkdirSync8(dirname3(destPath), { recursive: true });
|
|
48959
49129
|
let bytesWritten = 0;
|
|
48960
49130
|
const guard = new TransformStream({
|
|
48961
49131
|
transform(chunk, controller) {
|
|
@@ -49011,7 +49181,7 @@ function validateExtraction(stagingRoot) {
|
|
|
49011
49181
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
49012
49182
|
}
|
|
49013
49183
|
for (const entry of entries) {
|
|
49014
|
-
const full =
|
|
49184
|
+
const full = join12(dir, entry);
|
|
49015
49185
|
let lst;
|
|
49016
49186
|
try {
|
|
49017
49187
|
lst = lstatSync2(full);
|
|
@@ -49081,7 +49251,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
49081
49251
|
try {
|
|
49082
49252
|
rmSync4(stagingDir, { recursive: true, force: true });
|
|
49083
49253
|
} catch {}
|
|
49084
|
-
|
|
49254
|
+
mkdirSync8(stagingDir, { recursive: true });
|
|
49085
49255
|
try {
|
|
49086
49256
|
precheckArchiveContents(archivePath, archiveType);
|
|
49087
49257
|
runPlatformExtractor(archivePath, stagingDir, archiveType);
|
|
@@ -49099,10 +49269,10 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
49099
49269
|
}
|
|
49100
49270
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
49101
49271
|
const packageDir = ghPackageDir(spec);
|
|
49102
|
-
const dest =
|
|
49272
|
+
const dest = join12(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
49103
49273
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
49104
49274
|
try {
|
|
49105
|
-
|
|
49275
|
+
mkdirSync8(dirname3(dest), { recursive: true });
|
|
49106
49276
|
rmSync4(dest, { recursive: true, force: true });
|
|
49107
49277
|
renameSync5(packageDir, dest);
|
|
49108
49278
|
} catch (err) {
|
|
@@ -49112,7 +49282,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
49112
49282
|
function validateCachedGithubInstall(spec, platform) {
|
|
49113
49283
|
const packageDir = ghPackageDir(spec);
|
|
49114
49284
|
const meta3 = readGithubInstalledMetaIn(packageDir);
|
|
49115
|
-
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) =>
|
|
49285
|
+
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join12(ghBinDir(spec), candidate)).find((candidate) => {
|
|
49116
49286
|
try {
|
|
49117
49287
|
return statSync5(candidate).isFile();
|
|
49118
49288
|
} catch {
|
|
@@ -49190,7 +49360,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl2,
|
|
|
49190
49360
|
}
|
|
49191
49361
|
const pkgDir = ghPackageDir(spec);
|
|
49192
49362
|
const extractDir = ghExtractDir(spec);
|
|
49193
|
-
const archivePath =
|
|
49363
|
+
const archivePath = join12(pkgDir, expected.name);
|
|
49194
49364
|
log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
|
|
49195
49365
|
try {
|
|
49196
49366
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl2, matchingAsset.size, signal);
|
|
@@ -49230,13 +49400,13 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl2,
|
|
|
49230
49400
|
unlinkSync6(archivePath);
|
|
49231
49401
|
} catch {}
|
|
49232
49402
|
}
|
|
49233
|
-
const innerBinaryPath =
|
|
49234
|
-
if (!
|
|
49403
|
+
const innerBinaryPath = join12(extractDir, spec.binaryPathInArchive(platform, arch, version2));
|
|
49404
|
+
if (!existsSync8(innerBinaryPath)) {
|
|
49235
49405
|
error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
|
|
49236
49406
|
return null;
|
|
49237
49407
|
}
|
|
49238
49408
|
const targetBinary = ghBinaryPath(spec, platform);
|
|
49239
|
-
|
|
49409
|
+
mkdirSync8(dirname3(targetBinary), { recursive: true });
|
|
49240
49410
|
try {
|
|
49241
49411
|
copyFileSync3(innerBinaryPath, targetBinary);
|
|
49242
49412
|
if (platform !== "win32") {
|
|
@@ -49315,7 +49485,7 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl2 = fetch) {
|
|
|
49315
49485
|
if (!host) {
|
|
49316
49486
|
for (const spec of GITHUB_LSP_TABLE) {
|
|
49317
49487
|
try {
|
|
49318
|
-
if (
|
|
49488
|
+
if (existsSync8(ghBinDir(spec))) {
|
|
49319
49489
|
cachedBinDirs.push(ghBinDir(spec));
|
|
49320
49490
|
}
|
|
49321
49491
|
} catch {}
|
|
@@ -49413,11 +49583,10 @@ function discoverRelevantGithubServers(projectRoot) {
|
|
|
49413
49583
|
}
|
|
49414
49584
|
|
|
49415
49585
|
// src/notifications.ts
|
|
49416
|
-
import { existsSync as
|
|
49417
|
-
import { join as
|
|
49586
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "node:fs";
|
|
49587
|
+
import { join as join13 } from "node:path";
|
|
49418
49588
|
var WARNING_MARKER = "\uD83D\uDD27 AFT: ⚠️";
|
|
49419
49589
|
var FEATURE_MARKER = "\uD83D\uDD27 AFT: ✨";
|
|
49420
|
-
var WARNED_TOOLS_FILE = "warned_tools.json";
|
|
49421
49590
|
function sendIgnoredMessage(client, sessionId, text) {
|
|
49422
49591
|
const typedClient = client;
|
|
49423
49592
|
if (typeof typedClient.ui?.notify !== "function")
|
|
@@ -49430,55 +49599,36 @@ function sendIgnoredMessage(client, sessionId, text) {
|
|
|
49430
49599
|
return false;
|
|
49431
49600
|
}
|
|
49432
49601
|
}
|
|
49433
|
-
function readWarnedTools(
|
|
49602
|
+
async function readWarnedTools(bridge) {
|
|
49434
49603
|
try {
|
|
49435
|
-
const
|
|
49436
|
-
if (
|
|
49604
|
+
const resp = await bridge.send("db_get_state", { key: "warned_tools" });
|
|
49605
|
+
if (resp.success === false)
|
|
49606
|
+
return {};
|
|
49607
|
+
const value = resp.data?.value;
|
|
49608
|
+
if (typeof value !== "string")
|
|
49437
49609
|
return {};
|
|
49438
|
-
const parsed = JSON.parse(
|
|
49610
|
+
const parsed = JSON.parse(value);
|
|
49439
49611
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
49440
49612
|
return {};
|
|
49441
|
-
|
|
49442
|
-
for (const [key, version2] of Object.entries(parsed)) {
|
|
49443
|
-
if (typeof version2 === "string") {
|
|
49444
|
-
warned[key] = version2;
|
|
49445
|
-
}
|
|
49446
|
-
}
|
|
49447
|
-
return warned;
|
|
49613
|
+
return parsed;
|
|
49448
49614
|
} catch {
|
|
49449
49615
|
return {};
|
|
49450
49616
|
}
|
|
49451
49617
|
}
|
|
49452
|
-
function
|
|
49618
|
+
async function hasWarnedFor(bridge, key) {
|
|
49619
|
+
const warned = await readWarnedTools(bridge);
|
|
49620
|
+
return warned[key] === true || typeof warned[key] === "string";
|
|
49621
|
+
}
|
|
49622
|
+
async function recordWarning(bridge, key) {
|
|
49623
|
+
const warned = await readWarnedTools(bridge);
|
|
49624
|
+
warned[key] = true;
|
|
49453
49625
|
try {
|
|
49454
|
-
|
|
49455
|
-
|
|
49456
|
-
|
|
49457
|
-
|
|
49458
|
-
`);
|
|
49459
|
-
renameSync6(tmpPath, warnedToolsPath);
|
|
49626
|
+
await bridge.send("db_set_state", {
|
|
49627
|
+
key: "warned_tools",
|
|
49628
|
+
value: JSON.stringify(warned)
|
|
49629
|
+
});
|
|
49460
49630
|
} catch {}
|
|
49461
49631
|
}
|
|
49462
|
-
async function withWarnedToolsLock(storageDir, fn) {
|
|
49463
|
-
const lockDir = join12(storageDir, "warned_tools.lock");
|
|
49464
|
-
for (let attempt = 0;attempt < 5; attempt++) {
|
|
49465
|
-
try {
|
|
49466
|
-
mkdirSync8(storageDir, { recursive: true });
|
|
49467
|
-
mkdirSync8(lockDir, { mode: 448 });
|
|
49468
|
-
try {
|
|
49469
|
-
return await fn();
|
|
49470
|
-
} finally {
|
|
49471
|
-
rmSync5(lockDir, { recursive: true, force: true });
|
|
49472
|
-
}
|
|
49473
|
-
} catch (err) {
|
|
49474
|
-
const code = err.code;
|
|
49475
|
-
if (code !== "EEXIST")
|
|
49476
|
-
return null;
|
|
49477
|
-
await new Promise((resolve3) => setTimeout(resolve3, 10 * (attempt + 1)));
|
|
49478
|
-
}
|
|
49479
|
-
}
|
|
49480
|
-
return null;
|
|
49481
|
-
}
|
|
49482
49632
|
function warningKey(warning, projectRoot) {
|
|
49483
49633
|
const scope = warning.kind === "lsp_binary_missing" ? "_" : projectRoot ?? "_";
|
|
49484
49634
|
return [
|
|
@@ -49517,35 +49667,19 @@ ${warning.hint}`;
|
|
|
49517
49667
|
async function deliverConfigureWarnings(opts, warnings) {
|
|
49518
49668
|
if (warnings.length === 0)
|
|
49519
49669
|
return;
|
|
49520
|
-
const deliveredWithLock = await withWarnedToolsLock(opts.storageDir, async () => {
|
|
49521
|
-
const warned = readWarnedTools(opts.storageDir);
|
|
49522
|
-
let changed = false;
|
|
49523
|
-
for (const warning of warnings) {
|
|
49524
|
-
const key = warningKey(warning, opts.projectRoot);
|
|
49525
|
-
if (Object.hasOwn(warned, key))
|
|
49526
|
-
continue;
|
|
49527
|
-
if (!sendIgnoredMessage(opts.client, opts.sessionId, formatConfigureWarning(warning))) {
|
|
49528
|
-
continue;
|
|
49529
|
-
}
|
|
49530
|
-
warned[key] = opts.pluginVersion;
|
|
49531
|
-
changed = true;
|
|
49532
|
-
}
|
|
49533
|
-
if (changed) {
|
|
49534
|
-
const merged = { ...readWarnedTools(opts.storageDir), ...warned };
|
|
49535
|
-
writeWarnedTools(opts.storageDir, merged);
|
|
49536
|
-
}
|
|
49537
|
-
return true;
|
|
49538
|
-
});
|
|
49539
|
-
if (deliveredWithLock)
|
|
49540
|
-
return;
|
|
49541
49670
|
for (const warning of warnings) {
|
|
49542
|
-
|
|
49671
|
+
const key = warningKey(warning, opts.projectRoot);
|
|
49672
|
+
if (await hasWarnedFor(opts.bridge, key))
|
|
49673
|
+
continue;
|
|
49674
|
+
if (!sendIgnoredMessage(opts.client, opts.sessionId, formatConfigureWarning(warning)))
|
|
49675
|
+
continue;
|
|
49676
|
+
await recordWarning(opts.bridge, key);
|
|
49543
49677
|
}
|
|
49544
49678
|
}
|
|
49545
49679
|
function sendFeatureAnnouncement(version2, features, storageDir) {
|
|
49546
|
-
const versionFile =
|
|
49680
|
+
const versionFile = join13(storageDir, "last_announced_version");
|
|
49547
49681
|
try {
|
|
49548
|
-
if (
|
|
49682
|
+
if (existsSync9(versionFile)) {
|
|
49549
49683
|
const lastVersion = readFileSync7(versionFile, "utf-8").trim();
|
|
49550
49684
|
if (lastVersion === version2)
|
|
49551
49685
|
return;
|
|
@@ -49554,7 +49688,7 @@ function sendFeatureAnnouncement(version2, features, storageDir) {
|
|
|
49554
49688
|
log2([`${FEATURE_MARKER} v${version2}:`, ...features.map((feature) => ` • ${feature}`)].join(`
|
|
49555
49689
|
`));
|
|
49556
49690
|
try {
|
|
49557
|
-
|
|
49691
|
+
mkdirSync9(storageDir, { recursive: true });
|
|
49558
49692
|
writeFileSync6(versionFile, version2);
|
|
49559
49693
|
} catch {}
|
|
49560
49694
|
}
|
|
@@ -49616,7 +49750,7 @@ import { StringEnum } from "@earendil-works/pi-ai";
|
|
|
49616
49750
|
import { Type } from "typebox";
|
|
49617
49751
|
|
|
49618
49752
|
// src/tools/render-helpers.ts
|
|
49619
|
-
import { homedir as
|
|
49753
|
+
import { homedir as homedir8 } from "node:os";
|
|
49620
49754
|
import { renderDiff } from "@earendil-works/pi-coding-agent";
|
|
49621
49755
|
import { Container, Spacer, Text } from "@earendil-works/pi-tui";
|
|
49622
49756
|
function reuseText(last) {
|
|
@@ -49626,7 +49760,7 @@ function reuseContainer(last) {
|
|
|
49626
49760
|
return last instanceof Container ? last : new Container;
|
|
49627
49761
|
}
|
|
49628
49762
|
function shortenPath(path2) {
|
|
49629
|
-
const home =
|
|
49763
|
+
const home = homedir8();
|
|
49630
49764
|
if (path2.startsWith(home))
|
|
49631
49765
|
return `~${path2.slice(home.length)}`;
|
|
49632
49766
|
return path2;
|
|
@@ -50510,7 +50644,7 @@ function registerFsTools(pi, ctx, surface) {
|
|
|
50510
50644
|
|
|
50511
50645
|
// src/tools/hoisted.ts
|
|
50512
50646
|
import { stat } from "node:fs/promises";
|
|
50513
|
-
import { homedir as
|
|
50647
|
+
import { homedir as homedir9 } from "node:os";
|
|
50514
50648
|
import { isAbsolute, relative as relative3, resolve as resolve3 } from "node:path";
|
|
50515
50649
|
import {
|
|
50516
50650
|
renderDiff as renderDiff2
|
|
@@ -50707,7 +50841,7 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
50707
50841
|
promptGuidelines: ["Use write only for new files or complete rewrites."],
|
|
50708
50842
|
parameters: WriteParams,
|
|
50709
50843
|
async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
|
|
50710
|
-
await assertExternalDirectoryPermission(extCtx, params.filePath);
|
|
50844
|
+
await assertExternalDirectoryPermission(extCtx, params.filePath, "modify");
|
|
50711
50845
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
50712
50846
|
const response = await callBridge(bridge, "write", {
|
|
50713
50847
|
file: params.filePath,
|
|
@@ -50738,7 +50872,7 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
50738
50872
|
],
|
|
50739
50873
|
parameters: EditParams,
|
|
50740
50874
|
async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
|
|
50741
|
-
await assertExternalDirectoryPermission(extCtx, params.filePath);
|
|
50875
|
+
await assertExternalDirectoryPermission(extCtx, params.filePath, "modify");
|
|
50742
50876
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
50743
50877
|
if (typeof params.appendContent === "string") {
|
|
50744
50878
|
const req2 = {
|
|
@@ -50808,6 +50942,7 @@ function buildMutationResult(filePath, response) {
|
|
|
50808
50942
|
const replacements = response.replacements;
|
|
50809
50943
|
const diagnostics = response.lsp_diagnostics;
|
|
50810
50944
|
const truncated = diffObj?.truncated === true;
|
|
50945
|
+
const noOp = response.no_op === true;
|
|
50811
50946
|
const formatted = response.formatted;
|
|
50812
50947
|
const formatSkippedReason = response.format_skipped_reason;
|
|
50813
50948
|
const globFormatSkipReasons = response.format_skip_reasons;
|
|
@@ -50828,6 +50963,11 @@ ${diffText}`;
|
|
|
50828
50963
|
text += `
|
|
50829
50964
|
|
|
50830
50965
|
(diff truncated — file too large to include before/after content)`;
|
|
50966
|
+
}
|
|
50967
|
+
if (noOp) {
|
|
50968
|
+
text += `
|
|
50969
|
+
|
|
50970
|
+
Note: no net file change — the match was found and applied, but the file content is byte-identical to before. Likely causes: oldString and newString are identical, or a formatter normalized the change away.`;
|
|
50831
50971
|
}
|
|
50832
50972
|
const skipNote = formatSkipReasonNote(formatSkippedReason);
|
|
50833
50973
|
if (skipNote)
|
|
@@ -50856,7 +50996,8 @@ ${formatDiagnosticsText(diagnostics)}`;
|
|
|
50856
50996
|
diagnostics,
|
|
50857
50997
|
truncated: truncated || undefined,
|
|
50858
50998
|
formatted,
|
|
50859
|
-
formatSkippedReason
|
|
50999
|
+
formatSkippedReason,
|
|
51000
|
+
noOp: noOp || undefined
|
|
50860
51001
|
}
|
|
50861
51002
|
};
|
|
50862
51003
|
}
|
|
@@ -50927,7 +51068,12 @@ ${theme.fg("error", errorText || "edit failed")}`);
|
|
|
50927
51068
|
const deletions = details?.deletions ?? 0;
|
|
50928
51069
|
const text = reuseText3(context.lastComponent);
|
|
50929
51070
|
const summary = theme.fg("success", `+${additions}/-${deletions}`);
|
|
50930
|
-
|
|
51071
|
+
let suffix = "";
|
|
51072
|
+
if (details?.truncated) {
|
|
51073
|
+
suffix = ` ${theme.fg("muted", "(diff truncated)")}`;
|
|
51074
|
+
} else if (details?.noOp) {
|
|
51075
|
+
suffix = ` ${theme.fg("muted", "(no net change)")}`;
|
|
51076
|
+
}
|
|
50931
51077
|
text.setText(`
|
|
50932
51078
|
${summary}${suffix}`);
|
|
50933
51079
|
return text;
|
|
@@ -50939,7 +51085,7 @@ ${summary}${suffix}`);
|
|
|
50939
51085
|
return container;
|
|
50940
51086
|
}
|
|
50941
51087
|
function shortenPath2(path2) {
|
|
50942
|
-
const home =
|
|
51088
|
+
const home = homedir9();
|
|
50943
51089
|
if (path2.startsWith(home))
|
|
50944
51090
|
return `~${path2.slice(home.length)}`;
|
|
50945
51091
|
return path2;
|
|
@@ -50978,9 +51124,9 @@ function splitIncludeGlobs(include) {
|
|
|
50978
51124
|
}
|
|
50979
51125
|
buf += ch;
|
|
50980
51126
|
}
|
|
50981
|
-
const
|
|
50982
|
-
if (
|
|
50983
|
-
out.push(
|
|
51127
|
+
const tail2 = buf.trim();
|
|
51128
|
+
if (tail2.length > 0)
|
|
51129
|
+
out.push(tail2);
|
|
50984
51130
|
return out;
|
|
50985
51131
|
}
|
|
50986
51132
|
function formatReadFooter(agentSpecifiedRange, data) {
|
|
@@ -52201,15 +52347,12 @@ var PLUGIN_VERSION = (() => {
|
|
|
52201
52347
|
return "0.0.0";
|
|
52202
52348
|
}
|
|
52203
52349
|
})();
|
|
52204
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
52350
|
+
var ANNOUNCEMENT_VERSION = "0.27.0";
|
|
52205
52351
|
var ANNOUNCEMENT_FEATURES = [
|
|
52206
|
-
|
|
52207
|
-
|
|
52208
|
-
|
|
52209
|
-
|
|
52210
|
-
Check GitHub for how to enable.`,
|
|
52211
|
-
"Trigram grep/glob and semantic search (aft_search) graduated out of experimental.",
|
|
52212
|
-
"Lots of bugfixes and new end-to-end test coverage."
|
|
52352
|
+
"Storage moved to ~/.local/share/cortexkit/aft (~/Library/Application Support/cortexkit/aft on macOS, %APPDATA%/cortexkit/aft on Windows). Your existing data migrated automatically on first launch.",
|
|
52353
|
+
"Bash output compression now reports token savings — visible in /aft-status (Session + Project totals).",
|
|
52354
|
+
"Seven new languages supported by aft_outline / aft_zoom / aft_search / ast_grep: Java, Ruby, Kotlin, Swift, PHP, Lua, Perl.",
|
|
52355
|
+
"Join us on Discord: https://discord.gg/F2uWxjGnU"
|
|
52213
52356
|
];
|
|
52214
52357
|
var ALL_ONLY_TOOLS = new Set([
|
|
52215
52358
|
"aft_navigate",
|
|
@@ -52259,14 +52402,12 @@ async function handleConfigureWarningsForSession(context) {
|
|
|
52259
52402
|
await deliverConfigureWarnings({
|
|
52260
52403
|
client: context.client,
|
|
52261
52404
|
sessionId: context.sessionId,
|
|
52405
|
+
bridge: context.bridge,
|
|
52262
52406
|
storageDir: context.storageDir,
|
|
52263
52407
|
pluginVersion: context.pluginVersion,
|
|
52264
52408
|
projectRoot: context.projectRoot
|
|
52265
52409
|
}, combinedWarnings);
|
|
52266
52410
|
}
|
|
52267
|
-
function resolveStorageDir() {
|
|
52268
|
-
return join13(homedir9(), ".pi", "agent", "aft");
|
|
52269
|
-
}
|
|
52270
52411
|
function resolveToolSurface(config2) {
|
|
52271
52412
|
const surface = config2.tool_surface ?? "recommended";
|
|
52272
52413
|
const disabled = new Set(config2.disabled_tools ?? []);
|
|
@@ -52337,8 +52478,9 @@ async function src_default(pi) {
|
|
|
52337
52478
|
warn2(`Failed to resolve AFT binary: ${err instanceof Error ? err.message : String(err)}. ` + "Tools will not be registered.");
|
|
52338
52479
|
return;
|
|
52339
52480
|
}
|
|
52481
|
+
await ensureStorageMigrated({ harness: "pi", binaryPath, logger: bridgeLogger });
|
|
52340
52482
|
const config2 = loadAftConfig(process.cwd());
|
|
52341
|
-
const storageDir =
|
|
52483
|
+
const storageDir = resolveCortexKitStorageRoot();
|
|
52342
52484
|
let onnxRuntimePromise = null;
|
|
52343
52485
|
if (shouldPrepareOnnxRuntime(config2)) {
|
|
52344
52486
|
onnxRuntimePromise = ensureOnnxRuntime(storageDir).catch((err) => {
|
|
@@ -52439,16 +52581,22 @@ ${lines}
|
|
|
52439
52581
|
errorPrefix: "[aft-pi]",
|
|
52440
52582
|
minVersion: PLUGIN_VERSION,
|
|
52441
52583
|
onVersionMismatch: createVersionMismatchHandler(() => pool),
|
|
52442
|
-
onConfigureWarnings:
|
|
52584
|
+
onConfigureWarnings: ({ projectRoot, sessionId, client, warnings }) => {
|
|
52585
|
+
const bridge = pool.getActiveBridgeForRoot(projectRoot);
|
|
52586
|
+
if (!bridge)
|
|
52587
|
+
return;
|
|
52443
52588
|
const pendingWarnings = sessionId ? drainPendingEagerWarnings(projectRoot) : [];
|
|
52444
|
-
|
|
52445
|
-
|
|
52446
|
-
|
|
52447
|
-
|
|
52448
|
-
|
|
52449
|
-
|
|
52450
|
-
|
|
52451
|
-
|
|
52589
|
+
setTimeout(() => {
|
|
52590
|
+
handleConfigureWarningsForSession({
|
|
52591
|
+
projectRoot,
|
|
52592
|
+
sessionId,
|
|
52593
|
+
client,
|
|
52594
|
+
bridge,
|
|
52595
|
+
warnings: [...pendingWarnings, ...warnings],
|
|
52596
|
+
storageDir,
|
|
52597
|
+
pluginVersion: PLUGIN_VERSION
|
|
52598
|
+
});
|
|
52599
|
+
}, 0);
|
|
52452
52600
|
},
|
|
52453
52601
|
onBashCompletion: (completion) => {
|
|
52454
52602
|
handlePushedBgCompletion({
|
|
@@ -52468,6 +52616,7 @@ ${lines}
|
|
|
52468
52616
|
}
|
|
52469
52617
|
};
|
|
52470
52618
|
pool = new BridgePool(binaryPath, poolOptions, configOverrides);
|
|
52619
|
+
pool.setConfigureOverride("harness", "pi");
|
|
52471
52620
|
const ctx = { pool, config: config2, storageDir };
|
|
52472
52621
|
if (onnxRuntimePromise) {
|
|
52473
52622
|
onnxRuntimePromise.then((ortDylibDir) => {
|