@cortexkit/aft-pi 0.30.0 → 0.30.2
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 +2 -0
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/commands/aft-status.d.ts.map +1 -1
- package/dist/dialogs/status-dialog.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +658 -453
- package/dist/lsp-auto-install.d.ts.map +1 -1
- package/dist/lsp-github-install.d.ts.map +1 -1
- package/dist/notifications.d.ts +1 -1
- package/dist/notifications.d.ts.map +1 -1
- package/dist/shutdown-hooks.d.ts +2 -0
- package/dist/shutdown-hooks.d.ts.map +1 -1
- package/dist/tools/_shared.d.ts +3 -0
- package/dist/tools/_shared.d.ts.map +1 -1
- package/dist/tools/bash.d.ts +2 -2
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tools/navigate.d.ts +1 -1
- package/dist/tools/navigate.d.ts.map +1 -1
- package/dist/tools/refactor.d.ts +3 -3
- package/dist/tools/refactor.d.ts.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -12399,7 +12399,7 @@ var require_snapshot_utils = __commonJS((exports, module) => {
|
|
|
12399
12399
|
// ../../node_modules/.bun/undici@7.25.0/node_modules/undici/lib/mock/snapshot-recorder.js
|
|
12400
12400
|
var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
12401
12401
|
var { writeFile, readFile, mkdir } = __require("node:fs/promises");
|
|
12402
|
-
var { dirname:
|
|
12402
|
+
var { dirname: dirname4, resolve: resolve2 } = __require("node:path");
|
|
12403
12403
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
|
|
12404
12404
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
12405
12405
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -12594,7 +12594,7 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
|
|
|
12594
12594
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
12595
12595
|
}
|
|
12596
12596
|
const resolvedPath = resolve2(path);
|
|
12597
|
-
await mkdir(
|
|
12597
|
+
await mkdir(dirname4(resolvedPath), { recursive: true });
|
|
12598
12598
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
12599
12599
|
hash,
|
|
12600
12600
|
snapshot
|
|
@@ -29886,10 +29886,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
29886
29886
|
replacer = null;
|
|
29887
29887
|
indent = EMPTY;
|
|
29888
29888
|
};
|
|
29889
|
-
var
|
|
29889
|
+
var join9 = (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;
|
|
29890
29890
|
var join_content = (inside, value, gap) => {
|
|
29891
29891
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
29892
|
-
return
|
|
29892
|
+
return join9(comment, inside, gap);
|
|
29893
29893
|
};
|
|
29894
29894
|
var stringify_string = (holder, key, value) => {
|
|
29895
29895
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -29911,13 +29911,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
29911
29911
|
if (i !== 0) {
|
|
29912
29912
|
inside += COMMA;
|
|
29913
29913
|
}
|
|
29914
|
-
const before =
|
|
29914
|
+
const before = join9(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
29915
29915
|
inside += before || LF + deeper_gap;
|
|
29916
29916
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
29917
29917
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
29918
29918
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
29919
29919
|
}
|
|
29920
|
-
inside +=
|
|
29920
|
+
inside += join9(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
29921
29921
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
29922
29922
|
};
|
|
29923
29923
|
var object_stringify = (value, gap) => {
|
|
@@ -29938,13 +29938,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
29938
29938
|
inside += COMMA;
|
|
29939
29939
|
}
|
|
29940
29940
|
first = false;
|
|
29941
|
-
const before =
|
|
29941
|
+
const before = join9(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
29942
29942
|
inside += before || LF + deeper_gap;
|
|
29943
29943
|
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);
|
|
29944
29944
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
29945
29945
|
};
|
|
29946
29946
|
keys.forEach(iteratee);
|
|
29947
|
-
inside +=
|
|
29947
|
+
inside += join9(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
29948
29948
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
29949
29949
|
};
|
|
29950
29950
|
function stringify(key, holder, gap) {
|
|
@@ -34061,6 +34061,11 @@ class BinaryBridge {
|
|
|
34061
34061
|
if (requestSessionId && options?.configureWarningClient !== undefined) {
|
|
34062
34062
|
this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
|
|
34063
34063
|
}
|
|
34064
|
+
const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
|
|
34065
|
+
const implicitTransportOptions = {
|
|
34066
|
+
...options?.transportTimeoutMs !== undefined || options?.timeoutMs !== undefined ? { transportTimeoutMs: effectiveTimeoutMs } : {},
|
|
34067
|
+
markConfiguredOnSuccess: false
|
|
34068
|
+
};
|
|
34064
34069
|
if (!this.configured) {
|
|
34065
34070
|
if (command !== "configure" && command !== "version") {
|
|
34066
34071
|
if (!this._configurePromise) {
|
|
@@ -34071,12 +34076,12 @@ class BinaryBridge {
|
|
|
34071
34076
|
project_root: this.cwd,
|
|
34072
34077
|
...this.configOverrides,
|
|
34073
34078
|
...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
|
|
34074
|
-
});
|
|
34079
|
+
}, implicitTransportOptions);
|
|
34075
34080
|
if (configResult.success === false) {
|
|
34076
34081
|
throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
|
|
34077
34082
|
}
|
|
34078
34083
|
await this.deliverConfigureWarnings(configResult, params, options);
|
|
34079
|
-
await this.checkVersion();
|
|
34084
|
+
await this.checkVersion(implicitTransportOptions);
|
|
34080
34085
|
if (!this.isAlive()) {
|
|
34081
34086
|
throw new Error(`${this.errorPrefix} Bridge died during version check. Check logs: ${this.getLogFilePathVia()}`);
|
|
34082
34087
|
}
|
|
@@ -34106,9 +34111,8 @@ class BinaryBridge {
|
|
|
34106
34111
|
}
|
|
34107
34112
|
const line = `${JSON.stringify(request)}
|
|
34108
34113
|
`;
|
|
34109
|
-
const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
|
|
34110
34114
|
const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
|
|
34111
|
-
|
|
34115
|
+
const response = await new Promise((resolve, reject) => {
|
|
34112
34116
|
const timer = setTimeout(() => {
|
|
34113
34117
|
this.pending.delete(id);
|
|
34114
34118
|
const restartSuffix = keepBridgeOnTimeout ? "" : " — restarting bridge";
|
|
@@ -34141,6 +34145,10 @@ class BinaryBridge {
|
|
|
34141
34145
|
}
|
|
34142
34146
|
});
|
|
34143
34147
|
});
|
|
34148
|
+
if (command === "configure" && response.success === true && options?.markConfiguredOnSuccess !== false) {
|
|
34149
|
+
this.configured = true;
|
|
34150
|
+
}
|
|
34151
|
+
return response;
|
|
34144
34152
|
} catch (err) {
|
|
34145
34153
|
if (err instanceof BridgeReplacedDuringVersionCheck && canRetryAfterVersionSwap && command !== "configure" && command !== "version") {
|
|
34146
34154
|
this.logVia(`Retrying request "${command}" once after coordinated binary replacement: ${err.newBinaryPath}`);
|
|
@@ -34231,11 +34239,11 @@ class BinaryBridge {
|
|
|
34231
34239
|
});
|
|
34232
34240
|
}
|
|
34233
34241
|
}
|
|
34234
|
-
async checkVersion() {
|
|
34242
|
+
async checkVersion(options) {
|
|
34235
34243
|
if (!this.minVersion)
|
|
34236
34244
|
return;
|
|
34237
34245
|
try {
|
|
34238
|
-
const resp = await this.send("version");
|
|
34246
|
+
const resp = await this.send("version", {}, options);
|
|
34239
34247
|
if (resp.success === false) {
|
|
34240
34248
|
throw new Error(`Binary version check failed: ${String(resp.code ?? "unknown")} — likely too old`);
|
|
34241
34249
|
}
|
|
@@ -34310,10 +34318,14 @@ class BinaryBridge {
|
|
|
34310
34318
|
...process.env,
|
|
34311
34319
|
...envPath ? { PATH: envPath } : {}
|
|
34312
34320
|
};
|
|
34321
|
+
this.logVia(`bridge.spawnProcess: useFastembedBackend=${useFastembedBackend}, ` + `parentORT=${process.env.ORT_DYLIB_PATH ?? "(unset)"}, ` + `ortLibraryPath=${ortLibraryPath ?? "(none)"}`);
|
|
34313
34322
|
if (useFastembedBackend) {
|
|
34314
34323
|
env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ? join(this.configOverrides.storage_dir, "semantic", "models") : join(homedir() || "", ".cache", "fastembed"));
|
|
34315
|
-
if (
|
|
34324
|
+
if (process.env.ORT_DYLIB_PATH) {
|
|
34325
|
+
this.logVia(`ORT_DYLIB_PATH inherited from parent env: ${process.env.ORT_DYLIB_PATH}`);
|
|
34326
|
+
} else if (ortLibraryPath) {
|
|
34316
34327
|
env.ORT_DYLIB_PATH = ortLibraryPath;
|
|
34328
|
+
this.logVia(`ORT_DYLIB_PATH set from managed ONNX Runtime: ${ortLibraryPath}`);
|
|
34317
34329
|
}
|
|
34318
34330
|
}
|
|
34319
34331
|
const child = spawn(this.binaryPath, [], {
|
|
@@ -34559,8 +34571,9 @@ class BinaryBridge {
|
|
|
34559
34571
|
}
|
|
34560
34572
|
}
|
|
34561
34573
|
// ../aft-bridge/dist/downloader.js
|
|
34562
|
-
import {
|
|
34563
|
-
import {
|
|
34574
|
+
import { spawnSync } from "node:child_process";
|
|
34575
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
34576
|
+
import { chmodSync, closeSync, createWriteStream, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
|
|
34564
34577
|
import { homedir as homedir2 } from "node:os";
|
|
34565
34578
|
import { join as join2 } from "node:path";
|
|
34566
34579
|
import { Readable } from "node:stream";
|
|
@@ -34588,6 +34601,34 @@ var LATEST_TAG_TIMEOUT_MS = 30000;
|
|
|
34588
34601
|
var MAX_DOWNLOAD_BYTES = 200 * 1024 * 1024;
|
|
34589
34602
|
var DOWNLOAD_LOCK_TIMEOUT_MS = 120000;
|
|
34590
34603
|
var DOWNLOAD_LOCK_STALE_MS = 10 * 60000;
|
|
34604
|
+
function readBinaryVersion(binaryPath) {
|
|
34605
|
+
try {
|
|
34606
|
+
const result = spawnSync(binaryPath, ["--version"], {
|
|
34607
|
+
encoding: "utf-8",
|
|
34608
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
34609
|
+
timeout: 5000
|
|
34610
|
+
});
|
|
34611
|
+
const stdoutVersion = result.stdout?.trim();
|
|
34612
|
+
const stderrVersion = result.stderr?.trim();
|
|
34613
|
+
const rawVersion = stdoutVersion || stderrVersion;
|
|
34614
|
+
if (!rawVersion)
|
|
34615
|
+
return null;
|
|
34616
|
+
return rawVersion.replace(/^aft\s+/, "");
|
|
34617
|
+
} catch {
|
|
34618
|
+
return null;
|
|
34619
|
+
}
|
|
34620
|
+
}
|
|
34621
|
+
function expectedVersionFromTag(tag) {
|
|
34622
|
+
return tag.startsWith("v") ? tag.slice(1) : tag;
|
|
34623
|
+
}
|
|
34624
|
+
function isExpectedCachedBinary(binaryPath, tag) {
|
|
34625
|
+
const expected = expectedVersionFromTag(tag);
|
|
34626
|
+
const actual = readBinaryVersion(binaryPath);
|
|
34627
|
+
if (actual === expected)
|
|
34628
|
+
return true;
|
|
34629
|
+
warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; refreshing cache entry`);
|
|
34630
|
+
return false;
|
|
34631
|
+
}
|
|
34591
34632
|
function getCacheDir() {
|
|
34592
34633
|
if (process.platform === "win32") {
|
|
34593
34634
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
@@ -34623,7 +34664,7 @@ async function downloadBinary(version) {
|
|
|
34623
34664
|
const versionedCacheDir = join2(getCacheDir(), tag);
|
|
34624
34665
|
const binaryName = getBinaryName();
|
|
34625
34666
|
const binaryPath = join2(versionedCacheDir, binaryName);
|
|
34626
|
-
if (existsSync(binaryPath)) {
|
|
34667
|
+
if (existsSync(binaryPath) && isExpectedCachedBinary(binaryPath, tag)) {
|
|
34627
34668
|
return binaryPath;
|
|
34628
34669
|
}
|
|
34629
34670
|
const downloadUrl = `https://github.com/${REPO}/releases/download/${tag}/${assetName}`;
|
|
@@ -34641,7 +34682,7 @@ async function downloadBinary(version) {
|
|
|
34641
34682
|
mkdirSync(versionedCacheDir, { recursive: true });
|
|
34642
34683
|
}
|
|
34643
34684
|
releaseLock = await acquireDownloadLock(lockPath);
|
|
34644
|
-
if (existsSync(binaryPath)) {
|
|
34685
|
+
if (existsSync(binaryPath) && isExpectedCachedBinary(binaryPath, tag)) {
|
|
34645
34686
|
return binaryPath;
|
|
34646
34687
|
}
|
|
34647
34688
|
binaryController = new AbortController;
|
|
@@ -34730,7 +34771,7 @@ async function ensureBinary(version) {
|
|
|
34730
34771
|
if (version) {
|
|
34731
34772
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
34732
34773
|
const versionCached = getCachedBinaryPath(tag);
|
|
34733
|
-
if (versionCached) {
|
|
34774
|
+
if (versionCached && isExpectedCachedBinary(versionCached, tag)) {
|
|
34734
34775
|
log(`Found cached binary for ${tag}: ${versionCached}`);
|
|
34735
34776
|
return versionCached;
|
|
34736
34777
|
}
|
|
@@ -34744,13 +34785,17 @@ async function acquireDownloadLock(lockPath) {
|
|
|
34744
34785
|
const startedAt = Date.now();
|
|
34745
34786
|
while (true) {
|
|
34746
34787
|
try {
|
|
34788
|
+
const owner = `${process.pid}:${Date.now()}:${randomUUID()}`;
|
|
34747
34789
|
const fd = openSync(lockPath, "wx");
|
|
34790
|
+
writeSync(fd, owner);
|
|
34748
34791
|
return () => {
|
|
34749
34792
|
try {
|
|
34750
34793
|
closeSync(fd);
|
|
34751
34794
|
} catch {}
|
|
34752
34795
|
try {
|
|
34753
|
-
|
|
34796
|
+
if (readFileSync(lockPath, "utf-8") === owner) {
|
|
34797
|
+
rmSync(lockPath, { force: true });
|
|
34798
|
+
}
|
|
34754
34799
|
} catch {}
|
|
34755
34800
|
};
|
|
34756
34801
|
} catch (err) {
|
|
@@ -34813,34 +34858,35 @@ function compressionSavingsPercent(original, compressed) {
|
|
|
34813
34858
|
}
|
|
34814
34859
|
// ../aft-bridge/dist/migration.js
|
|
34815
34860
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
34816
|
-
import { existsSync as
|
|
34861
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync4 } from "node:fs";
|
|
34817
34862
|
import { homedir as homedir4, tmpdir } from "node:os";
|
|
34818
|
-
import { dirname, join as
|
|
34863
|
+
import { dirname as dirname2, join as join5 } from "node:path";
|
|
34864
|
+
|
|
34865
|
+
// ../aft-bridge/dist/paths.js
|
|
34866
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync as renameSync2 } from "node:fs";
|
|
34867
|
+
import { dirname, join as join3 } from "node:path";
|
|
34868
|
+
function resolveHarnessStoragePath(storageRoot, harness, ...segments) {
|
|
34869
|
+
return join3(storageRoot, harness, ...segments);
|
|
34870
|
+
}
|
|
34871
|
+
function repairRootScopedStorageFile(storageRoot, harness, fileName) {
|
|
34872
|
+
const harnessPath = resolveHarnessStoragePath(storageRoot, harness, fileName);
|
|
34873
|
+
const rootPath = join3(storageRoot, fileName);
|
|
34874
|
+
if (existsSync2(harnessPath) || !existsSync2(rootPath))
|
|
34875
|
+
return harnessPath;
|
|
34876
|
+
try {
|
|
34877
|
+
mkdirSync2(dirname(harnessPath), { recursive: true });
|
|
34878
|
+
renameSync2(rootPath, harnessPath);
|
|
34879
|
+
} catch {}
|
|
34880
|
+
return harnessPath;
|
|
34881
|
+
}
|
|
34819
34882
|
|
|
34820
34883
|
// ../aft-bridge/dist/resolver.js
|
|
34821
|
-
import { execSync
|
|
34822
|
-
import { chmodSync as chmodSync2, copyFileSync, existsSync as
|
|
34884
|
+
import { execSync } from "node:child_process";
|
|
34885
|
+
import { chmodSync as chmodSync2, copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync3 } from "node:fs";
|
|
34823
34886
|
import { createRequire as createRequire2 } from "node:module";
|
|
34824
34887
|
import { homedir as homedir3 } from "node:os";
|
|
34825
|
-
import { join as
|
|
34888
|
+
import { join as join4 } from "node:path";
|
|
34826
34889
|
var ensureBinaryForResolver = ensureBinary;
|
|
34827
|
-
function readBinaryVersion(binaryPath) {
|
|
34828
|
-
try {
|
|
34829
|
-
const result = spawnSync(binaryPath, ["--version"], {
|
|
34830
|
-
encoding: "utf-8",
|
|
34831
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
34832
|
-
timeout: 5000
|
|
34833
|
-
});
|
|
34834
|
-
const stdoutVersion = result.stdout?.trim();
|
|
34835
|
-
const stderrVersion = result.stderr?.trim();
|
|
34836
|
-
const rawVersion = stdoutVersion || stderrVersion;
|
|
34837
|
-
if (!rawVersion)
|
|
34838
|
-
return null;
|
|
34839
|
-
return rawVersion.replace(/^aft\s+/, "");
|
|
34840
|
-
} catch {
|
|
34841
|
-
return null;
|
|
34842
|
-
}
|
|
34843
|
-
}
|
|
34844
34890
|
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
34845
34891
|
try {
|
|
34846
34892
|
const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
|
|
@@ -34848,22 +34894,22 @@ function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
|
34848
34894
|
return null;
|
|
34849
34895
|
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
34850
34896
|
const cacheDir = getCacheDir();
|
|
34851
|
-
const versionedDir =
|
|
34897
|
+
const versionedDir = join4(cacheDir, tag);
|
|
34852
34898
|
const ext = process.platform === "win32" ? ".exe" : "";
|
|
34853
|
-
const cachedPath =
|
|
34854
|
-
if (
|
|
34899
|
+
const cachedPath = join4(versionedDir, `aft${ext}`);
|
|
34900
|
+
if (existsSync3(cachedPath)) {
|
|
34855
34901
|
const cachedVersion = readBinaryVersion(cachedPath);
|
|
34856
34902
|
if (cachedVersion === version)
|
|
34857
34903
|
return cachedPath;
|
|
34858
34904
|
warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
|
|
34859
34905
|
}
|
|
34860
|
-
|
|
34906
|
+
mkdirSync3(versionedDir, { recursive: true });
|
|
34861
34907
|
const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
|
|
34862
34908
|
copyFileSync(npmBinaryPath, tmpPath);
|
|
34863
34909
|
if (process.platform !== "win32") {
|
|
34864
34910
|
chmodSync2(tmpPath, 493);
|
|
34865
34911
|
}
|
|
34866
|
-
|
|
34912
|
+
renameSync3(tmpPath, cachedPath);
|
|
34867
34913
|
log(`Copied npm binary to versioned cache: ${cachedPath}`);
|
|
34868
34914
|
return cachedPath;
|
|
34869
34915
|
} catch (err) {
|
|
@@ -34879,17 +34925,17 @@ function homeDirFromEnv(env) {
|
|
|
34879
34925
|
}
|
|
34880
34926
|
function cacheDirFromEnv(env) {
|
|
34881
34927
|
if (process.platform === "win32") {
|
|
34882
|
-
const base2 = env.LOCALAPPDATA || env.APPDATA ||
|
|
34883
|
-
return
|
|
34928
|
+
const base2 = env.LOCALAPPDATA || env.APPDATA || join4(homeDirFromEnv(env), "AppData", "Local");
|
|
34929
|
+
return join4(base2, "aft", "bin");
|
|
34884
34930
|
}
|
|
34885
|
-
const base = env.XDG_CACHE_HOME ||
|
|
34886
|
-
return
|
|
34931
|
+
const base = env.XDG_CACHE_HOME || join4(homeDirFromEnv(env), ".cache");
|
|
34932
|
+
return join4(base, "aft", "bin");
|
|
34887
34933
|
}
|
|
34888
34934
|
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
34889
|
-
const binaryPath =
|
|
34890
|
-
return
|
|
34935
|
+
const binaryPath = join4(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
34936
|
+
return existsSync3(binaryPath) ? binaryPath : null;
|
|
34891
34937
|
}
|
|
34892
|
-
function
|
|
34938
|
+
function isExpectedCachedBinary2(binaryPath, expectedVersion) {
|
|
34893
34939
|
const expected = normalizeBareVersion(expectedVersion);
|
|
34894
34940
|
const actual = readBinaryVersion(binaryPath);
|
|
34895
34941
|
if (actual === expected)
|
|
@@ -34897,6 +34943,21 @@ function isExpectedCachedBinary(binaryPath, expectedVersion) {
|
|
|
34897
34943
|
warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
|
|
34898
34944
|
return false;
|
|
34899
34945
|
}
|
|
34946
|
+
function probeBinaryCandidate(binaryPath, source, expectedVersion) {
|
|
34947
|
+
const actual = readBinaryVersion(binaryPath);
|
|
34948
|
+
if (actual === null) {
|
|
34949
|
+
warn(`${source} binary at ${binaryPath} did not report a version; skipping`);
|
|
34950
|
+
return null;
|
|
34951
|
+
}
|
|
34952
|
+
if (expectedVersion && actual !== normalizeBareVersion(expectedVersion)) {
|
|
34953
|
+
warn(`${source} binary at ${binaryPath} reports ${actual}, expected ${normalizeBareVersion(expectedVersion)}; skipping`);
|
|
34954
|
+
return null;
|
|
34955
|
+
}
|
|
34956
|
+
return binaryPath;
|
|
34957
|
+
}
|
|
34958
|
+
function parsePathLookupOutput(output) {
|
|
34959
|
+
return output.split(/\r?\n/).map((candidate) => candidate.trim()).filter(Boolean);
|
|
34960
|
+
}
|
|
34900
34961
|
function platformKey(platform = process.platform, arch = process.arch) {
|
|
34901
34962
|
const archMap = PLATFORM_ARCH_MAP[platform];
|
|
34902
34963
|
if (!archMap) {
|
|
@@ -34922,7 +34983,7 @@ function findBinarySync(expectedVersion) {
|
|
|
34922
34983
|
if (pluginVersion) {
|
|
34923
34984
|
const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
|
|
34924
34985
|
const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
|
|
34925
|
-
if (versionCached &&
|
|
34986
|
+
if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion))
|
|
34926
34987
|
return versionCached;
|
|
34927
34988
|
}
|
|
34928
34989
|
try {
|
|
@@ -34930,7 +34991,7 @@ function findBinarySync(expectedVersion) {
|
|
|
34930
34991
|
const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
|
|
34931
34992
|
const req = createRequire2(import.meta.url);
|
|
34932
34993
|
const resolved = req.resolve(packageBin);
|
|
34933
|
-
if (
|
|
34994
|
+
if (existsSync3(resolved)) {
|
|
34934
34995
|
const npmVersion = readBinaryVersion(resolved);
|
|
34935
34996
|
if (npmVersion === null) {
|
|
34936
34997
|
warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
|
|
@@ -34949,12 +35010,18 @@ function findBinarySync(expectedVersion) {
|
|
|
34949
35010
|
env,
|
|
34950
35011
|
stdio: ["pipe", "pipe", "pipe"]
|
|
34951
35012
|
}).trim();
|
|
34952
|
-
|
|
34953
|
-
|
|
35013
|
+
for (const candidate of parsePathLookupOutput(result)) {
|
|
35014
|
+
const usable = probeBinaryCandidate(candidate, "PATH", expectedVersion);
|
|
35015
|
+
if (usable)
|
|
35016
|
+
return usable;
|
|
35017
|
+
}
|
|
34954
35018
|
} catch {}
|
|
34955
|
-
const cargoPath =
|
|
34956
|
-
if (
|
|
34957
|
-
|
|
35019
|
+
const cargoPath = join4(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
35020
|
+
if (existsSync3(cargoPath)) {
|
|
35021
|
+
const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
|
|
35022
|
+
if (usable)
|
|
35023
|
+
return usable;
|
|
35024
|
+
}
|
|
34958
35025
|
return null;
|
|
34959
35026
|
}
|
|
34960
35027
|
async function findBinary(expectedVersion) {
|
|
@@ -34995,9 +35062,9 @@ function dataHome() {
|
|
|
34995
35062
|
if (process.env.XDG_DATA_HOME)
|
|
34996
35063
|
return process.env.XDG_DATA_HOME;
|
|
34997
35064
|
if (process.platform === "win32") {
|
|
34998
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA ||
|
|
35065
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join5(homeDir(), "AppData", "Local");
|
|
34999
35066
|
}
|
|
35000
|
-
return
|
|
35067
|
+
return join5(homeDir(), ".local", "share");
|
|
35001
35068
|
}
|
|
35002
35069
|
function homeDir() {
|
|
35003
35070
|
if (process.platform === "win32")
|
|
@@ -35006,11 +35073,11 @@ function homeDir() {
|
|
|
35006
35073
|
}
|
|
35007
35074
|
function resolveLegacyStorageRoot(harness) {
|
|
35008
35075
|
if (harness === "pi")
|
|
35009
|
-
return
|
|
35010
|
-
return
|
|
35076
|
+
return join5(homeDir(), ".pi", "agent", "aft");
|
|
35077
|
+
return join5(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
35011
35078
|
}
|
|
35012
35079
|
function resolveCortexKitStorageRoot() {
|
|
35013
|
-
return
|
|
35080
|
+
return join5(dataHome(), "cortexkit", "aft");
|
|
35014
35081
|
}
|
|
35015
35082
|
function tail(value) {
|
|
35016
35083
|
if (!value)
|
|
@@ -35024,26 +35091,26 @@ function spawnErrorLabel(error2) {
|
|
|
35024
35091
|
return [code, error2.message].filter(Boolean).join(": ");
|
|
35025
35092
|
}
|
|
35026
35093
|
function migrationLogPath(newRoot, harness, logger) {
|
|
35027
|
-
const desired =
|
|
35094
|
+
const desired = join5(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
35028
35095
|
try {
|
|
35029
|
-
|
|
35096
|
+
mkdirSync4(dirname2(desired), { recursive: true });
|
|
35030
35097
|
return desired;
|
|
35031
35098
|
} catch (err) {
|
|
35032
|
-
const fallback =
|
|
35033
|
-
logger?.warn?.(`Failed to create AFT migration log directory ${
|
|
35099
|
+
const fallback = join5(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
35100
|
+
logger?.warn?.(`Failed to create AFT migration log directory ${dirname2(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
35034
35101
|
return fallback;
|
|
35035
35102
|
}
|
|
35036
35103
|
}
|
|
35037
35104
|
async function ensureStorageMigrated(opts) {
|
|
35038
35105
|
const legacyRoot = resolveLegacyStorageRoot(opts.harness);
|
|
35039
35106
|
const newRoot = resolveCortexKitStorageRoot();
|
|
35040
|
-
const targetMarker =
|
|
35107
|
+
const targetMarker = resolveHarnessStoragePath(newRoot, opts.harness, TARGET_MARKER);
|
|
35041
35108
|
const info = opts.logger?.info ?? opts.logger?.log;
|
|
35042
|
-
if (
|
|
35109
|
+
if (existsSync4(targetMarker)) {
|
|
35043
35110
|
info?.(`AFT storage already migrated for ${opts.harness}; using ${newRoot}`);
|
|
35044
35111
|
return;
|
|
35045
35112
|
}
|
|
35046
|
-
if (!
|
|
35113
|
+
if (!existsSync4(legacyRoot)) {
|
|
35047
35114
|
info?.(`AFT storage migration skipped for ${opts.harness}: no legacy data at ${legacyRoot}; ` + `using ${newRoot} for fresh install`);
|
|
35048
35115
|
return;
|
|
35049
35116
|
}
|
|
@@ -35093,8 +35160,8 @@ async function ensureStorageMigrated(opts) {
|
|
|
35093
35160
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
35094
35161
|
import { execFileSync } from "node:child_process";
|
|
35095
35162
|
import { createHash as createHash2 } from "node:crypto";
|
|
35096
|
-
import { chmodSync as chmodSync3, closeSync as closeSync2, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as
|
|
35097
|
-
import { dirname as
|
|
35163
|
+
import { chmodSync as chmodSync3, closeSync as closeSync2, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, openSync as openSync2, readdirSync, readFileSync as readFileSync2, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
|
|
35164
|
+
import { basename, dirname as dirname3, join as join6, relative, resolve } from "node:path";
|
|
35098
35165
|
import { Readable as Readable2 } from "node:stream";
|
|
35099
35166
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
35100
35167
|
var ORT_VERSION = "1.24.4";
|
|
@@ -35157,9 +35224,9 @@ function getManualInstallHint() {
|
|
|
35157
35224
|
}
|
|
35158
35225
|
async function ensureOnnxRuntime(storageDir) {
|
|
35159
35226
|
const info = getPlatformInfo();
|
|
35160
|
-
const ortDir =
|
|
35161
|
-
const libPath =
|
|
35162
|
-
if (
|
|
35227
|
+
const ortDir = join6(storageDir, "onnxruntime", ORT_VERSION);
|
|
35228
|
+
const libPath = join6(ortDir, info?.libName ?? "libonnxruntime.dylib");
|
|
35229
|
+
if (existsSync5(libPath)) {
|
|
35163
35230
|
const meta = readOnnxInstalledMeta(ortDir);
|
|
35164
35231
|
if (meta?.sha256) {
|
|
35165
35232
|
try {
|
|
@@ -35188,9 +35255,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
35188
35255
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
35189
35256
|
return null;
|
|
35190
35257
|
}
|
|
35191
|
-
const onnxBaseDir =
|
|
35192
|
-
|
|
35193
|
-
const lockPath =
|
|
35258
|
+
const onnxBaseDir = join6(storageDir, "onnxruntime");
|
|
35259
|
+
mkdirSync5(onnxBaseDir, { recursive: true });
|
|
35260
|
+
const lockPath = join6(onnxBaseDir, ONNX_LOCK_FILE);
|
|
35194
35261
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
35195
35262
|
if (!acquireLock(lockPath)) {
|
|
35196
35263
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -35209,7 +35276,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
35209
35276
|
for (const entry of entries) {
|
|
35210
35277
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
35211
35278
|
continue;
|
|
35212
|
-
const stagingDir =
|
|
35279
|
+
const stagingDir = join6(onnxBaseDir, entry);
|
|
35213
35280
|
const parts = entry.split(".");
|
|
35214
35281
|
const pidStr = parts[parts.length - 2];
|
|
35215
35282
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -35241,7 +35308,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
35241
35308
|
}
|
|
35242
35309
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
35243
35310
|
try {
|
|
35244
|
-
if (
|
|
35311
|
+
if (existsSync5(ortDir) && !existsSync5(join6(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
35245
35312
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
35246
35313
|
rmSync2(ortDir, { recursive: true, force: true });
|
|
35247
35314
|
}
|
|
@@ -35251,6 +35318,14 @@ function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
|
35251
35318
|
}
|
|
35252
35319
|
var REQUIRED_ORT_MAJOR = 1;
|
|
35253
35320
|
var REQUIRED_ORT_MIN_MINOR = 20;
|
|
35321
|
+
var INVALID_ORT_VERSION = "<invalid>";
|
|
35322
|
+
function parseOnnxVersionFromPath(value) {
|
|
35323
|
+
const name = basename(value);
|
|
35324
|
+
const semverish = name.match(/\.(\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?)(?:\.dylib)?$/);
|
|
35325
|
+
if (semverish)
|
|
35326
|
+
return semverish[1].split(/[-+]/, 1)[0];
|
|
35327
|
+
return /\d+\.\d+\.\d+/.test(name) ? INVALID_ORT_VERSION : null;
|
|
35328
|
+
}
|
|
35254
35329
|
function detectOnnxVersion(libDir, libName) {
|
|
35255
35330
|
try {
|
|
35256
35331
|
const entries = readdirSync(libDir);
|
|
@@ -35258,23 +35333,23 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
35258
35333
|
for (const entry of entries) {
|
|
35259
35334
|
if (!entry.startsWith(barePrefix))
|
|
35260
35335
|
continue;
|
|
35261
|
-
const
|
|
35262
|
-
if (
|
|
35263
|
-
return
|
|
35336
|
+
const version = parseOnnxVersionFromPath(entry);
|
|
35337
|
+
if (version)
|
|
35338
|
+
return version;
|
|
35264
35339
|
}
|
|
35265
|
-
const base =
|
|
35266
|
-
if (
|
|
35340
|
+
const base = join6(libDir, libName);
|
|
35341
|
+
if (existsSync5(base)) {
|
|
35267
35342
|
try {
|
|
35268
35343
|
const real = realpathSync(base);
|
|
35269
|
-
const
|
|
35270
|
-
if (
|
|
35271
|
-
return
|
|
35344
|
+
const version = parseOnnxVersionFromPath(real);
|
|
35345
|
+
if (version)
|
|
35346
|
+
return version;
|
|
35272
35347
|
} catch {}
|
|
35273
35348
|
try {
|
|
35274
35349
|
const target = readlinkSync(base);
|
|
35275
|
-
const
|
|
35276
|
-
if (
|
|
35277
|
-
return
|
|
35350
|
+
const version = parseOnnxVersionFromPath(target);
|
|
35351
|
+
if (version)
|
|
35352
|
+
return version;
|
|
35278
35353
|
} catch {}
|
|
35279
35354
|
}
|
|
35280
35355
|
} catch {}
|
|
@@ -35299,7 +35374,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
35299
35374
|
searchPaths.push("/usr/lib", "/usr/lib/x86_64-linux-gnu", "/usr/lib/aarch64-linux-gnu", "/usr/local/lib");
|
|
35300
35375
|
}
|
|
35301
35376
|
for (const dir of searchPaths) {
|
|
35302
|
-
if (!
|
|
35377
|
+
if (!existsSync5(join6(dir, libName)))
|
|
35303
35378
|
continue;
|
|
35304
35379
|
const version = detectOnnxVersion(dir, libName);
|
|
35305
35380
|
if (version && !isOnnxVersionCompatible(version)) {
|
|
@@ -35326,7 +35401,7 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
35326
35401
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
|
|
35327
35402
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
|
|
35328
35403
|
}
|
|
35329
|
-
|
|
35404
|
+
mkdirSync5(dirname3(destPath), { recursive: true });
|
|
35330
35405
|
let bytesWritten = 0;
|
|
35331
35406
|
const guard = new TransformStream({
|
|
35332
35407
|
transform(chunk, transformController) {
|
|
@@ -35356,11 +35431,11 @@ function validateExtractedTree(stagingRoot) {
|
|
|
35356
35431
|
const walk = (dir) => {
|
|
35357
35432
|
const entries = readdirSync(dir);
|
|
35358
35433
|
for (const entry of entries) {
|
|
35359
|
-
const fullPath =
|
|
35434
|
+
const fullPath = join6(dir, entry);
|
|
35360
35435
|
const lst = lstatSync(fullPath);
|
|
35361
35436
|
if (lst.isSymbolicLink()) {
|
|
35362
35437
|
const linkTarget = readlinkSync(fullPath);
|
|
35363
|
-
const resolvedTarget = resolve(
|
|
35438
|
+
const resolvedTarget = resolve(dirname3(fullPath), linkTarget);
|
|
35364
35439
|
const rel2 = relative(realRoot, resolvedTarget);
|
|
35365
35440
|
if (rel2.startsWith("..") || process.platform !== "win32" && rel2.startsWith("/")) {
|
|
35366
35441
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
@@ -35390,8 +35465,8 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
35390
35465
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
35391
35466
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
35392
35467
|
try {
|
|
35393
|
-
|
|
35394
|
-
const archivePath =
|
|
35468
|
+
mkdirSync5(tmpDir, { recursive: true });
|
|
35469
|
+
const archivePath = join6(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
35395
35470
|
await downloadFileWithCap(url, archivePath);
|
|
35396
35471
|
const archiveSha256 = sha256File(archivePath);
|
|
35397
35472
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -35407,16 +35482,16 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
35407
35482
|
unlinkSync2(archivePath);
|
|
35408
35483
|
} catch {}
|
|
35409
35484
|
validateExtractedTree(tmpDir);
|
|
35410
|
-
const extractedDir =
|
|
35411
|
-
if (!
|
|
35485
|
+
const extractedDir = join6(tmpDir, info.assetName, "lib");
|
|
35486
|
+
if (!existsSync5(extractedDir)) {
|
|
35412
35487
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
35413
35488
|
}
|
|
35414
|
-
|
|
35489
|
+
mkdirSync5(targetDir, { recursive: true });
|
|
35415
35490
|
const libFiles = readdirSync(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
|
|
35416
35491
|
const realFiles = [];
|
|
35417
35492
|
const symlinks = [];
|
|
35418
35493
|
for (const libFile of libFiles) {
|
|
35419
|
-
const src =
|
|
35494
|
+
const src = join6(extractedDir, libFile);
|
|
35420
35495
|
try {
|
|
35421
35496
|
const stat = lstatSync(src);
|
|
35422
35497
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -35431,7 +35506,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
35431
35506
|
}
|
|
35432
35507
|
}
|
|
35433
35508
|
copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
|
|
35434
|
-
const libPath =
|
|
35509
|
+
const libPath = join6(targetDir, info.libName);
|
|
35435
35510
|
let libHash = null;
|
|
35436
35511
|
try {
|
|
35437
35512
|
libHash = sha256File(libPath);
|
|
@@ -35456,8 +35531,8 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
35456
35531
|
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync2) {
|
|
35457
35532
|
const requiredLibs = new Set([info.libName]);
|
|
35458
35533
|
for (const libFile of realFiles) {
|
|
35459
|
-
const src =
|
|
35460
|
-
const dst =
|
|
35534
|
+
const src = join6(extractedDir, libFile);
|
|
35535
|
+
const dst = join6(targetDir, libFile);
|
|
35461
35536
|
try {
|
|
35462
35537
|
copyFile(src, dst);
|
|
35463
35538
|
if (process.platform !== "win32") {
|
|
@@ -35472,7 +35547,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
35472
35547
|
}
|
|
35473
35548
|
}
|
|
35474
35549
|
for (const link of symlinks) {
|
|
35475
|
-
const dst =
|
|
35550
|
+
const dst = join6(targetDir, link.name);
|
|
35476
35551
|
try {
|
|
35477
35552
|
unlinkSync2(dst);
|
|
35478
35553
|
} catch {}
|
|
@@ -35486,8 +35561,8 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
35486
35561
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
35487
35562
|
}
|
|
35488
35563
|
}
|
|
35489
|
-
const requiredPath =
|
|
35490
|
-
if (!
|
|
35564
|
+
const requiredPath = join6(targetDir, info.libName);
|
|
35565
|
+
if (!existsSync5(requiredPath)) {
|
|
35491
35566
|
rmSync2(targetDir, { recursive: true, force: true });
|
|
35492
35567
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
35493
35568
|
}
|
|
@@ -35513,17 +35588,17 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
35513
35588
|
...sha256 ? { sha256 } : {},
|
|
35514
35589
|
archiveSha256
|
|
35515
35590
|
};
|
|
35516
|
-
writeFileSync(
|
|
35591
|
+
writeFileSync(join6(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
35517
35592
|
} catch (err) {
|
|
35518
35593
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
35519
35594
|
}
|
|
35520
35595
|
}
|
|
35521
35596
|
function readOnnxInstalledMeta(installDir) {
|
|
35522
|
-
const path =
|
|
35597
|
+
const path = join6(installDir, ONNX_INSTALLED_META_FILE);
|
|
35523
35598
|
try {
|
|
35524
35599
|
if (!statSync2(path).isFile())
|
|
35525
35600
|
return null;
|
|
35526
|
-
const raw =
|
|
35601
|
+
const raw = readFileSync2(path, "utf8");
|
|
35527
35602
|
const parsed = JSON.parse(raw);
|
|
35528
35603
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
35529
35604
|
return null;
|
|
@@ -35539,7 +35614,7 @@ function readOnnxInstalledMeta(installDir) {
|
|
|
35539
35614
|
}
|
|
35540
35615
|
function sha256File(path) {
|
|
35541
35616
|
const hash = createHash2("sha256");
|
|
35542
|
-
hash.update(
|
|
35617
|
+
hash.update(readFileSync2(path));
|
|
35543
35618
|
return hash.digest("hex");
|
|
35544
35619
|
}
|
|
35545
35620
|
function acquireLock(lockPath) {
|
|
@@ -35567,7 +35642,7 @@ ${new Date().toISOString()}
|
|
|
35567
35642
|
let owningPid = null;
|
|
35568
35643
|
let lockMtimeMs = 0;
|
|
35569
35644
|
try {
|
|
35570
|
-
const raw =
|
|
35645
|
+
const raw = readFileSync2(lockPath, "utf8");
|
|
35571
35646
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
35572
35647
|
const parsed = Number.parseInt(firstLine, 10);
|
|
35573
35648
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
@@ -35593,7 +35668,7 @@ function releaseLock(lockPath) {
|
|
|
35593
35668
|
try {
|
|
35594
35669
|
let owningPid = null;
|
|
35595
35670
|
try {
|
|
35596
|
-
const raw =
|
|
35671
|
+
const raw = readFileSync2(lockPath, "utf8");
|
|
35597
35672
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
35598
35673
|
const parsed = Number.parseInt(firstLine, 10);
|
|
35599
35674
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
@@ -35661,6 +35736,7 @@ function isHomeDirectoryRoot(normalizedKey) {
|
|
|
35661
35736
|
|
|
35662
35737
|
class BridgePool {
|
|
35663
35738
|
bridges = new Map;
|
|
35739
|
+
staleBridges = new Set;
|
|
35664
35740
|
binaryPath;
|
|
35665
35741
|
maxPoolSize;
|
|
35666
35742
|
idleTimeoutMs;
|
|
@@ -35683,6 +35759,7 @@ class BridgePool {
|
|
|
35683
35759
|
onConfigureWarnings: options.onConfigureWarnings,
|
|
35684
35760
|
onBashCompletion: options.onBashCompletion,
|
|
35685
35761
|
onBashLongRunning: options.onBashLongRunning,
|
|
35762
|
+
onBashPatternMatch: options.onBashPatternMatch,
|
|
35686
35763
|
errorPrefix: options.errorPrefix,
|
|
35687
35764
|
logger: options.logger
|
|
35688
35765
|
};
|
|
@@ -35734,6 +35811,12 @@ class BridgePool {
|
|
|
35734
35811
|
this.bridges.delete(dir);
|
|
35735
35812
|
}
|
|
35736
35813
|
}
|
|
35814
|
+
for (const bridge of this.staleBridges) {
|
|
35815
|
+
if (bridge.hasPendingRequests())
|
|
35816
|
+
continue;
|
|
35817
|
+
bridge.shutdown().catch((err) => this.error("stale cleanup shutdown failed:", err));
|
|
35818
|
+
this.staleBridges.delete(bridge);
|
|
35819
|
+
}
|
|
35737
35820
|
}
|
|
35738
35821
|
evictLRU() {
|
|
35739
35822
|
let oldestDir = null;
|
|
@@ -35757,14 +35840,21 @@ class BridgePool {
|
|
|
35757
35840
|
clearInterval(this.cleanupTimer);
|
|
35758
35841
|
this.cleanupTimer = null;
|
|
35759
35842
|
}
|
|
35760
|
-
const shutdowns =
|
|
35843
|
+
const shutdowns = [
|
|
35844
|
+
...Array.from(this.bridges.values(), (e) => e.bridge.shutdown()),
|
|
35845
|
+
...Array.from(this.staleBridges.values(), (bridge) => bridge.shutdown())
|
|
35846
|
+
];
|
|
35761
35847
|
this.bridges.clear();
|
|
35848
|
+
this.staleBridges.clear();
|
|
35762
35849
|
await Promise.allSettled(shutdowns);
|
|
35763
35850
|
}
|
|
35764
35851
|
async replaceBinary(newPath) {
|
|
35765
35852
|
this.binaryPath = newPath;
|
|
35853
|
+
for (const entry of this.bridges.values()) {
|
|
35854
|
+
this.staleBridges.add(entry.bridge);
|
|
35855
|
+
}
|
|
35766
35856
|
this.bridges.clear();
|
|
35767
|
-
this.log(`Binary path updated to ${newPath}.
|
|
35857
|
+
this.log(`Binary path updated to ${newPath}. Active bridges marked stale — next calls will use the new binary.`);
|
|
35768
35858
|
return newPath;
|
|
35769
35859
|
}
|
|
35770
35860
|
log(message, meta) {
|
|
@@ -35814,11 +35904,11 @@ function normalizeKey(projectRoot) {
|
|
|
35814
35904
|
}
|
|
35815
35905
|
}
|
|
35816
35906
|
// ../aft-bridge/dist/url-fetch.js
|
|
35817
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
35907
|
+
import { createHash as createHash3, randomBytes } from "node:crypto";
|
|
35818
35908
|
import { lookup } from "node:dns/promises";
|
|
35819
|
-
import { existsSync as
|
|
35909
|
+
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync2, readFileSync as readFileSync3, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
|
|
35820
35910
|
import { isIP } from "node:net";
|
|
35821
|
-
import { join as
|
|
35911
|
+
import { join as join7 } from "node:path";
|
|
35822
35912
|
|
|
35823
35913
|
// ../../node_modules/.bun/undici@7.25.0/node_modules/undici/index.js
|
|
35824
35914
|
var __filename = "/home/runner/work/aft/aft/node_modules/.bun/undici@7.25.0/node_modules/undici/index.js";
|
|
@@ -35968,16 +36058,16 @@ var FETCH_TIMEOUT_MS = 30000;
|
|
|
35968
36058
|
var BODY_CHUNK_TIMEOUT_MS = 15000;
|
|
35969
36059
|
var MAX_REDIRECTS = 5;
|
|
35970
36060
|
function cacheDir(storageDir) {
|
|
35971
|
-
return
|
|
36061
|
+
return join7(storageDir, "url_cache");
|
|
35972
36062
|
}
|
|
35973
36063
|
function hashUrl(url) {
|
|
35974
36064
|
return createHash3("sha256").update(url).digest("hex").slice(0, 16);
|
|
35975
36065
|
}
|
|
35976
36066
|
function metaPath(storageDir, hash) {
|
|
35977
|
-
return
|
|
36067
|
+
return join7(cacheDir(storageDir), `${hash}.meta.json`);
|
|
35978
36068
|
}
|
|
35979
36069
|
function contentPath(storageDir, hash, extension) {
|
|
35980
|
-
return
|
|
36070
|
+
return join7(cacheDir(storageDir), `${hash}${extension}`);
|
|
35981
36071
|
}
|
|
35982
36072
|
function _isPrivateIpv4(address) {
|
|
35983
36073
|
const parts = address.split(".").map((part) => Number.parseInt(part, 10));
|
|
@@ -36102,13 +36192,21 @@ function resolveRedirectUrl(currentUrl, location) {
|
|
|
36102
36192
|
}
|
|
36103
36193
|
return new URL(location, currentUrl);
|
|
36104
36194
|
}
|
|
36195
|
+
var isBunRuntime = typeof globalThis.Bun !== "undefined";
|
|
36105
36196
|
async function fetchWithRedirects(startUrl, allowPrivate, deps = {}) {
|
|
36106
36197
|
let currentUrl = startUrl;
|
|
36107
|
-
const fetchImpl2 = deps.fetchImpl ?? $fetch;
|
|
36198
|
+
const fetchImpl2 = deps.fetchImpl ?? (isBunRuntime ? globalThis.fetch : $fetch);
|
|
36108
36199
|
const dnsLookup = deps.lookup ?? lookup;
|
|
36109
36200
|
for (let redirectCount = 0;redirectCount <= MAX_REDIRECTS; redirectCount++) {
|
|
36110
36201
|
const validatedIp = await assertPublicUrl(currentUrl, allowPrivate, dnsLookup);
|
|
36111
|
-
|
|
36202
|
+
let dispatcher;
|
|
36203
|
+
if (validatedIp) {
|
|
36204
|
+
if (deps.dispatcherFactory) {
|
|
36205
|
+
dispatcher = deps.dispatcherFactory(validatedIp);
|
|
36206
|
+
} else if (!isBunRuntime) {
|
|
36207
|
+
dispatcher = createPinnedDispatcher(validatedIp);
|
|
36208
|
+
}
|
|
36209
|
+
}
|
|
36112
36210
|
const controller = new AbortController;
|
|
36113
36211
|
const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
36114
36212
|
let response;
|
|
@@ -36119,7 +36217,7 @@ async function fetchWithRedirects(startUrl, allowPrivate, deps = {}) {
|
|
|
36119
36217
|
dispatcher,
|
|
36120
36218
|
headers: {
|
|
36121
36219
|
"user-agent": "aft-opencode-plugin",
|
|
36122
|
-
accept: "application/vnd.github.raw, text/markdown, text/x-markdown, text/html;q=0.9, text/plain;q=0.5"
|
|
36220
|
+
accept: "application/vnd.github.raw, text/markdown, text/x-markdown, text/html;q=0.9, application/json;q=0.8, text/plain;q=0.5"
|
|
36123
36221
|
}
|
|
36124
36222
|
});
|
|
36125
36223
|
} catch (err) {
|
|
@@ -36160,6 +36258,9 @@ function resolveExtension(contentType) {
|
|
|
36160
36258
|
if (lower === "text/plain") {
|
|
36161
36259
|
return ".md";
|
|
36162
36260
|
}
|
|
36261
|
+
if (lower === "application/json" || lower === "application/ld+json" || lower.endsWith("+json")) {
|
|
36262
|
+
return ".json";
|
|
36263
|
+
}
|
|
36163
36264
|
return null;
|
|
36164
36265
|
}
|
|
36165
36266
|
async function fetchUrlToTempFile(url, storageDir, options = {}) {
|
|
@@ -36175,15 +36276,15 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
|
|
|
36175
36276
|
const allowPrivate = options.allowPrivate === true;
|
|
36176
36277
|
await assertPublicUrl(parsed, allowPrivate, options.lookup);
|
|
36177
36278
|
const dir = cacheDir(storageDir);
|
|
36178
|
-
|
|
36279
|
+
mkdirSync6(dir, { recursive: true });
|
|
36179
36280
|
const hash = hashUrl(url);
|
|
36180
36281
|
const metaFile = metaPath(storageDir, hash);
|
|
36181
|
-
if (
|
|
36282
|
+
if (existsSync6(metaFile)) {
|
|
36182
36283
|
try {
|
|
36183
|
-
const meta2 = JSON.parse(
|
|
36284
|
+
const meta2 = JSON.parse(readFileSync3(metaFile, "utf8"));
|
|
36184
36285
|
const age = Date.now() - meta2.fetchedAt;
|
|
36185
36286
|
const cached = contentPath(storageDir, hash, meta2.extension);
|
|
36186
|
-
if (age < CACHE_TTL_MS &&
|
|
36287
|
+
if (age < CACHE_TTL_MS && existsSync6(cached)) {
|
|
36187
36288
|
log(`URL cache hit: ${url} (${Math.round(age / 1000)}s old)`);
|
|
36188
36289
|
return cached;
|
|
36189
36290
|
}
|
|
@@ -36249,19 +36350,20 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
|
|
|
36249
36350
|
}
|
|
36250
36351
|
const body = Buffer.concat(chunks);
|
|
36251
36352
|
const contentFile = contentPath(storageDir, hash, extension);
|
|
36252
|
-
const
|
|
36353
|
+
const nonce = randomBytes(8).toString("hex");
|
|
36354
|
+
const tmpContent = `${contentFile}.tmp-${process.pid}-${nonce}`;
|
|
36253
36355
|
writeFileSync2(tmpContent, body);
|
|
36254
|
-
const { renameSync:
|
|
36255
|
-
|
|
36356
|
+
const { renameSync: renameSync4 } = await import("node:fs");
|
|
36357
|
+
renameSync4(tmpContent, contentFile);
|
|
36256
36358
|
const meta = {
|
|
36257
36359
|
url,
|
|
36258
36360
|
contentType,
|
|
36259
36361
|
extension,
|
|
36260
36362
|
fetchedAt: Date.now()
|
|
36261
36363
|
};
|
|
36262
|
-
const tmpMeta = `${metaFile}.tmp-${process.pid}`;
|
|
36364
|
+
const tmpMeta = `${metaFile}.tmp-${process.pid}-${nonce}`;
|
|
36263
36365
|
writeFileSync2(tmpMeta, JSON.stringify(meta));
|
|
36264
|
-
|
|
36366
|
+
renameSync4(tmpMeta, metaFile);
|
|
36265
36367
|
log(`URL cached (${total} bytes): ${url}`);
|
|
36266
36368
|
return contentFile;
|
|
36267
36369
|
}
|
|
@@ -36499,7 +36601,7 @@ function markExplicitControl(sessionID, taskId, trackOutstanding = true) {
|
|
|
36499
36601
|
if (idx >= 0) {
|
|
36500
36602
|
const completion = state.pendingCompletions[idx];
|
|
36501
36603
|
state.pendingCompletions.splice(idx, 1);
|
|
36502
|
-
queuePendingPatternMatch(state, completionToExitPattern(completion));
|
|
36604
|
+
queuePendingPatternMatch(state, completionToExitPattern(completion, true));
|
|
36503
36605
|
state.wakeDeferredTaskIds.delete(taskId);
|
|
36504
36606
|
}
|
|
36505
36607
|
}
|
|
@@ -36527,13 +36629,18 @@ function routeExplicitControlCompletions(state) {
|
|
|
36527
36629
|
state.outstandingTaskIds.delete(completion.task_id);
|
|
36528
36630
|
state.explicitControlTasks.delete(completion.task_id);
|
|
36529
36631
|
state.wakeDeferredTaskIds.delete(completion.task_id);
|
|
36530
|
-
queuePendingPatternMatch(state, completionToExitPattern(completion));
|
|
36632
|
+
queuePendingPatternMatch(state, completionToExitPattern(completion, true));
|
|
36531
36633
|
} else {
|
|
36532
36634
|
remaining.push(completion);
|
|
36533
36635
|
}
|
|
36534
36636
|
}
|
|
36535
36637
|
state.pendingCompletions = remaining;
|
|
36536
36638
|
}
|
|
36639
|
+
async function handlePushedPatternMatch(drainContext, frame) {
|
|
36640
|
+
const state = stateFor(drainContext.sessionID);
|
|
36641
|
+
queuePendingPatternMatch(state, frame);
|
|
36642
|
+
await triggerWakeIfPending(drainContext, true);
|
|
36643
|
+
}
|
|
36537
36644
|
function ingestBgCompletions(sessionID, completions) {
|
|
36538
36645
|
if (!Array.isArray(completions) || completions.length === 0)
|
|
36539
36646
|
return [];
|
|
@@ -36549,7 +36656,7 @@ function ingestBgCompletions(sessionID, completions) {
|
|
|
36549
36656
|
if (state.explicitControlTasks.has(completion.task_id)) {
|
|
36550
36657
|
state.outstandingTaskIds.delete(completion.task_id);
|
|
36551
36658
|
state.explicitControlTasks.delete(completion.task_id);
|
|
36552
|
-
queuePendingPatternMatch(state, completionToExitPattern(completion));
|
|
36659
|
+
queuePendingPatternMatch(state, completionToExitPattern(completion, true));
|
|
36553
36660
|
continue;
|
|
36554
36661
|
}
|
|
36555
36662
|
if (!state.outstandingTaskIds.has(completion.task_id)) {
|
|
@@ -36585,6 +36692,8 @@ async function appendToolResultBgCompletions(drainContext, content) {
|
|
|
36585
36692
|
if (state.pendingCompletions.length === 0 && state.pendingLongRunning.length === 0 && state.pendingPatternMatches.length === 0)
|
|
36586
36693
|
return;
|
|
36587
36694
|
const deliveredCompletions = [...state.pendingCompletions];
|
|
36695
|
+
const deliveredPatternMatches = [...state.pendingPatternMatches];
|
|
36696
|
+
const completionAcks = completionAcksForDelivery(deliveredCompletions, deliveredPatternMatches);
|
|
36588
36697
|
const reminder = formatCombinedSystemReminder(state.pendingCompletions, state.pendingLongRunning, state.pendingPatternMatches);
|
|
36589
36698
|
state.pendingCompletions = [];
|
|
36590
36699
|
for (const completion of deliveredCompletions) {
|
|
@@ -36594,7 +36703,7 @@ async function appendToolResultBgCompletions(drainContext, content) {
|
|
|
36594
36703
|
state.pendingPatternMatches = [];
|
|
36595
36704
|
state.wakeRetryAttempts = 0;
|
|
36596
36705
|
state.wakeHardStopped = false;
|
|
36597
|
-
await ackCompletions(drainContext,
|
|
36706
|
+
await ackCompletions(drainContext, completionAcks);
|
|
36598
36707
|
if (state.debounceTimer) {
|
|
36599
36708
|
clearTimeout(state.debounceTimer);
|
|
36600
36709
|
state.debounceTimer = null;
|
|
@@ -36757,7 +36866,8 @@ function scheduleWake(state, sendWake, onSendFailure, includeDeferredCompletions
|
|
|
36757
36866
|
state.wakeDeferredTaskIds.delete(taskId);
|
|
36758
36867
|
state.pendingLongRunning = [];
|
|
36759
36868
|
state.pendingPatternMatches = [];
|
|
36760
|
-
|
|
36869
|
+
const completionAcks = completionAcksForDelivery(pending, pendingPatternMatches);
|
|
36870
|
+
sendWake(reminder, completionAcks).then(() => {
|
|
36761
36871
|
state.retryDelayMs = null;
|
|
36762
36872
|
state.wakeRetryAttempts = 0;
|
|
36763
36873
|
state.wakeHardStopped = false;
|
|
@@ -36822,7 +36932,7 @@ function ingestDrainedBgCompletions(sessionID, completions) {
|
|
|
36822
36932
|
state.outstandingTaskIds.delete(completion.task_id);
|
|
36823
36933
|
if (state.explicitControlTasks.has(completion.task_id)) {
|
|
36824
36934
|
state.explicitControlTasks.delete(completion.task_id);
|
|
36825
|
-
queuePendingPatternMatch(state, completionToExitPattern(completion));
|
|
36935
|
+
queuePendingPatternMatch(state, completionToExitPattern(completion, true));
|
|
36826
36936
|
continue;
|
|
36827
36937
|
}
|
|
36828
36938
|
if (state.consumedTaskIds.has(completion.task_id))
|
|
@@ -36858,10 +36968,10 @@ function bufferUnknownCompletion(state, completion) {
|
|
|
36858
36968
|
function pruneUnknownCompletions(state, now) {
|
|
36859
36969
|
state.unknownCompletions = state.unknownCompletions.filter((entry) => now - entry.receivedAt <= UNKNOWN_COMPLETION_TTL_MS);
|
|
36860
36970
|
}
|
|
36861
|
-
function completionToExitPattern(completion) {
|
|
36971
|
+
function completionToExitPattern(completion, ackCompletionOnDelivery = false) {
|
|
36862
36972
|
const status = formatStatus(completion);
|
|
36863
36973
|
const preview = formatOutputPreview(completion).replace(/^ {4}/gm, "").slice(-300);
|
|
36864
|
-
|
|
36974
|
+
const entry = {
|
|
36865
36975
|
task_id: completion.task_id,
|
|
36866
36976
|
session_id: "",
|
|
36867
36977
|
watch_id: "exit",
|
|
@@ -36872,6 +36982,20 @@ ${preview}` : `task ${completion.task_id} exited (${status})`,
|
|
|
36872
36982
|
once: true,
|
|
36873
36983
|
reason: "task_exit"
|
|
36874
36984
|
};
|
|
36985
|
+
if (ackCompletionOnDelivery)
|
|
36986
|
+
entry.ackCompletionOnDelivery = true;
|
|
36987
|
+
return entry;
|
|
36988
|
+
}
|
|
36989
|
+
function completionAcksForDelivery(completions, patternMatches) {
|
|
36990
|
+
const acks = [...completions];
|
|
36991
|
+
const ackedTaskIds = new Set(acks.map((completion) => completion.task_id));
|
|
36992
|
+
for (const match of patternMatches) {
|
|
36993
|
+
if (!match.ackCompletionOnDelivery || ackedTaskIds.has(match.task_id))
|
|
36994
|
+
continue;
|
|
36995
|
+
acks.push({ task_id: match.task_id, status: "unknown", exit_code: null, command: "" });
|
|
36996
|
+
ackedTaskIds.add(match.task_id);
|
|
36997
|
+
}
|
|
36998
|
+
return acks;
|
|
36875
36999
|
}
|
|
36876
37000
|
function isBgCompletion(value) {
|
|
36877
37001
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
@@ -36941,7 +37065,7 @@ import {
|
|
|
36941
37065
|
// package.json
|
|
36942
37066
|
var package_default = {
|
|
36943
37067
|
name: "@cortexkit/aft-pi",
|
|
36944
|
-
version: "0.30.
|
|
37068
|
+
version: "0.30.2",
|
|
36945
37069
|
type: "module",
|
|
36946
37070
|
description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
|
|
36947
37071
|
main: "dist/index.js",
|
|
@@ -36963,7 +37087,7 @@ var package_default = {
|
|
|
36963
37087
|
prepublishOnly: "bun run build"
|
|
36964
37088
|
},
|
|
36965
37089
|
dependencies: {
|
|
36966
|
-
"@cortexkit/aft-bridge": "0.30.
|
|
37090
|
+
"@cortexkit/aft-bridge": "0.30.2",
|
|
36967
37091
|
"@xterm/headless": "^5.5.0",
|
|
36968
37092
|
"comment-json": "^5.0.0",
|
|
36969
37093
|
diff: "^8.0.4",
|
|
@@ -36971,12 +37095,12 @@ var package_default = {
|
|
|
36971
37095
|
zod: "^4.1.8"
|
|
36972
37096
|
},
|
|
36973
37097
|
optionalDependencies: {
|
|
36974
|
-
"@cortexkit/aft-darwin-arm64": "0.30.
|
|
36975
|
-
"@cortexkit/aft-darwin-x64": "0.30.
|
|
36976
|
-
"@cortexkit/aft-linux-arm64": "0.30.
|
|
36977
|
-
"@cortexkit/aft-linux-x64": "0.30.
|
|
36978
|
-
"@cortexkit/aft-win32-arm64": "0.30.
|
|
36979
|
-
"@cortexkit/aft-win32-x64": "0.30.
|
|
37098
|
+
"@cortexkit/aft-darwin-arm64": "0.30.2",
|
|
37099
|
+
"@cortexkit/aft-darwin-x64": "0.30.2",
|
|
37100
|
+
"@cortexkit/aft-linux-arm64": "0.30.2",
|
|
37101
|
+
"@cortexkit/aft-linux-x64": "0.30.2",
|
|
37102
|
+
"@cortexkit/aft-win32-arm64": "0.30.2",
|
|
37103
|
+
"@cortexkit/aft-win32-x64": "0.30.2"
|
|
36980
37104
|
},
|
|
36981
37105
|
devDependencies: {
|
|
36982
37106
|
"@earendil-works/pi-coding-agent": "*",
|
|
@@ -37170,6 +37294,22 @@ function formatStatusDialogMessage(status) {
|
|
|
37170
37294
|
}
|
|
37171
37295
|
|
|
37172
37296
|
// src/tools/_shared.ts
|
|
37297
|
+
import { Type } from "typebox";
|
|
37298
|
+
var optionalInt = (_min, _max) => Type.Optional(Type.Any({ description: "(integer)" }));
|
|
37299
|
+
function coerceOptionalInt(v, paramName, min, max) {
|
|
37300
|
+
if (v === undefined || v === null || v === "")
|
|
37301
|
+
return;
|
|
37302
|
+
if (typeof v === "number" && (v === 0 || !Number.isFinite(v)))
|
|
37303
|
+
return;
|
|
37304
|
+
const n = typeof v === "string" ? Number(v) : v;
|
|
37305
|
+
if (typeof n !== "number" || !Number.isInteger(n)) {
|
|
37306
|
+
throw new Error(`${paramName} must be an integer between ${min} and ${max}`);
|
|
37307
|
+
}
|
|
37308
|
+
if (n < min || n > max) {
|
|
37309
|
+
throw new Error(`${paramName} must be between ${min} and ${max}`);
|
|
37310
|
+
}
|
|
37311
|
+
return n;
|
|
37312
|
+
}
|
|
37173
37313
|
var LONG_RUNNING_COMMAND_TIMEOUT_MS = {
|
|
37174
37314
|
callers: 60000,
|
|
37175
37315
|
trace_to: 60000,
|
|
@@ -37252,9 +37392,13 @@ class AftStatusDialogComponent {
|
|
|
37252
37392
|
async fetchOnce() {
|
|
37253
37393
|
try {
|
|
37254
37394
|
const bridge = bridgeFor(this.props.pluginCtx, this.props.extCtx.cwd);
|
|
37395
|
+
const sessionId = resolveSessionId(this.props.extCtx);
|
|
37255
37396
|
const cached = bridge.getCachedStatus();
|
|
37256
|
-
const
|
|
37257
|
-
|
|
37397
|
+
const cachedSession = cached?.session;
|
|
37398
|
+
const cachedSessionId = cachedSession?.id;
|
|
37399
|
+
const cacheUsable = cached !== null && cachedSessionId !== undefined && cachedSessionId === sessionId;
|
|
37400
|
+
const response = cacheUsable ? { success: true, ...cached } : await callBridge(bridge, "status", {}, this.props.extCtx);
|
|
37401
|
+
if (!cacheUsable) {
|
|
37258
37402
|
bridge.cacheStatusSnapshot(response);
|
|
37259
37403
|
}
|
|
37260
37404
|
if (this.closed)
|
|
@@ -37483,9 +37627,13 @@ function registerStatusCommand(pi, ctx) {
|
|
|
37483
37627
|
return;
|
|
37484
37628
|
}
|
|
37485
37629
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
37630
|
+
const sessionId = resolveSessionId(extCtx);
|
|
37486
37631
|
const cached = bridge.getCachedStatus();
|
|
37487
|
-
const
|
|
37488
|
-
|
|
37632
|
+
const cachedSession = cached?.session;
|
|
37633
|
+
const cachedSessionId = cachedSession?.id;
|
|
37634
|
+
const cacheUsable = cached !== null && cachedSessionId !== undefined && cachedSessionId === sessionId;
|
|
37635
|
+
const response = cacheUsable ? { success: true, ...cached } : await callBridge(bridge, "status", {}, extCtx);
|
|
37636
|
+
if (!cacheUsable) {
|
|
37489
37637
|
bridge.cacheStatusSnapshot(response);
|
|
37490
37638
|
}
|
|
37491
37639
|
const snapshot = coerceAftStatus(response);
|
|
@@ -37505,9 +37653,9 @@ function registerStatusCommand(pi, ctx) {
|
|
|
37505
37653
|
|
|
37506
37654
|
// src/config.ts
|
|
37507
37655
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
37508
|
-
import { existsSync as
|
|
37656
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
37509
37657
|
import { homedir as homedir6 } from "node:os";
|
|
37510
|
-
import { join as
|
|
37658
|
+
import { join as join9 } from "node:path";
|
|
37511
37659
|
|
|
37512
37660
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
37513
37661
|
var exports_external = {};
|
|
@@ -51351,13 +51499,13 @@ function migrateExperimentalBashBlock(rawConfig, configPath, logger) {
|
|
|
51351
51499
|
return movedKeys;
|
|
51352
51500
|
}
|
|
51353
51501
|
function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
|
|
51354
|
-
if (!
|
|
51502
|
+
if (!existsSync7(configPath)) {
|
|
51355
51503
|
return { migrated: false, oldKeys: [] };
|
|
51356
51504
|
}
|
|
51357
51505
|
let tmpPath = null;
|
|
51358
51506
|
let oldKeys = [];
|
|
51359
51507
|
try {
|
|
51360
|
-
const content =
|
|
51508
|
+
const content = readFileSync4(configPath, "utf-8");
|
|
51361
51509
|
const rawConfig = import_comment_json.parse(content);
|
|
51362
51510
|
if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
|
|
51363
51511
|
return { migrated: false, oldKeys: [] };
|
|
@@ -51374,7 +51522,7 @@ function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
|
|
|
51374
51522
|
${serialized}` : serialized;
|
|
51375
51523
|
tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
51376
51524
|
writeFileSync3(tmpPath, nextContent, "utf-8");
|
|
51377
|
-
|
|
51525
|
+
renameSync4(tmpPath, configPath);
|
|
51378
51526
|
logger.log(`Migrated config at ${configPath}: removed ${oldKeys.join(", ")}`);
|
|
51379
51527
|
return { migrated: true, oldKeys };
|
|
51380
51528
|
} catch (err) {
|
|
@@ -51394,17 +51542,17 @@ ${serialized}` : serialized;
|
|
|
51394
51542
|
function detectConfigFile(basePath) {
|
|
51395
51543
|
const jsoncPath = `${basePath}.jsonc`;
|
|
51396
51544
|
const jsonPath = `${basePath}.json`;
|
|
51397
|
-
if (
|
|
51545
|
+
if (existsSync7(jsoncPath))
|
|
51398
51546
|
return { format: "jsonc", path: jsoncPath };
|
|
51399
|
-
if (
|
|
51547
|
+
if (existsSync7(jsonPath))
|
|
51400
51548
|
return { format: "json", path: jsonPath };
|
|
51401
51549
|
return { format: "none", path: jsonPath };
|
|
51402
51550
|
}
|
|
51403
51551
|
function loadConfigFromPath(configPath) {
|
|
51404
51552
|
try {
|
|
51405
|
-
if (!
|
|
51553
|
+
if (!existsSync7(configPath))
|
|
51406
51554
|
return null;
|
|
51407
|
-
const content =
|
|
51555
|
+
const content = readFileSync4(configPath, "utf-8");
|
|
51408
51556
|
const rawConfig = import_comment_json.parse(content);
|
|
51409
51557
|
if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
|
|
51410
51558
|
warn2(`Config validation error in ${configPath}: root must be an object`);
|
|
@@ -51575,15 +51723,15 @@ function mergeConfigs(base, override) {
|
|
|
51575
51723
|
};
|
|
51576
51724
|
}
|
|
51577
51725
|
function getGlobalPiDir() {
|
|
51578
|
-
return
|
|
51726
|
+
return join9(homedir6(), ".pi", "agent");
|
|
51579
51727
|
}
|
|
51580
51728
|
function loadAftConfig(projectDirectory) {
|
|
51581
|
-
const userBasePath =
|
|
51729
|
+
const userBasePath = join9(getGlobalPiDir(), "aft");
|
|
51582
51730
|
migrateAftConfigFile(`${userBasePath}.jsonc`);
|
|
51583
51731
|
migrateAftConfigFile(`${userBasePath}.json`);
|
|
51584
51732
|
const userDetected = detectConfigFile(userBasePath);
|
|
51585
51733
|
const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
|
|
51586
|
-
const projectBasePath =
|
|
51734
|
+
const projectBasePath = join9(projectDirectory, ".pi", "aft");
|
|
51587
51735
|
migrateAftConfigFile(`${projectBasePath}.jsonc`);
|
|
51588
51736
|
migrateAftConfigFile(`${projectBasePath}.json`);
|
|
51589
51737
|
const projectDetected = detectConfigFile(projectBasePath);
|
|
@@ -51610,49 +51758,49 @@ function loadAftConfig(projectDirectory) {
|
|
|
51610
51758
|
// src/lsp-auto-install.ts
|
|
51611
51759
|
import { spawn as spawn2 } from "node:child_process";
|
|
51612
51760
|
import { createHash as createHash4 } from "node:crypto";
|
|
51613
|
-
import { createReadStream, mkdirSync as
|
|
51614
|
-
import { join as
|
|
51761
|
+
import { createReadStream, mkdirSync as mkdirSync8, readFileSync as readFileSync7, renameSync as renameSync5, rmSync as rmSync3, statSync as statSync4 } from "node:fs";
|
|
51762
|
+
import { join as join12 } from "node:path";
|
|
51615
51763
|
|
|
51616
51764
|
// src/lsp-cache.ts
|
|
51617
51765
|
import {
|
|
51618
51766
|
closeSync as closeSync3,
|
|
51619
|
-
mkdirSync as
|
|
51767
|
+
mkdirSync as mkdirSync7,
|
|
51620
51768
|
openSync as openSync3,
|
|
51621
|
-
readFileSync as
|
|
51769
|
+
readFileSync as readFileSync5,
|
|
51622
51770
|
statSync as statSync3,
|
|
51623
51771
|
unlinkSync as unlinkSync5,
|
|
51624
51772
|
writeFileSync as writeFileSync4
|
|
51625
51773
|
} from "node:fs";
|
|
51626
51774
|
import { homedir as homedir7 } from "node:os";
|
|
51627
|
-
import { join as
|
|
51775
|
+
import { join as join10 } from "node:path";
|
|
51628
51776
|
function aftCacheBase() {
|
|
51629
51777
|
const override = process.env.AFT_CACHE_DIR;
|
|
51630
51778
|
if (override && override.length > 0)
|
|
51631
51779
|
return override;
|
|
51632
51780
|
if (process.platform === "win32") {
|
|
51633
51781
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
51634
|
-
const base2 = localAppData ||
|
|
51635
|
-
return
|
|
51782
|
+
const base2 = localAppData || join10(homedir7(), "AppData", "Local");
|
|
51783
|
+
return join10(base2, "aft");
|
|
51636
51784
|
}
|
|
51637
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
51638
|
-
return
|
|
51785
|
+
const base = process.env.XDG_CACHE_HOME || join10(homedir7(), ".cache");
|
|
51786
|
+
return join10(base, "aft");
|
|
51639
51787
|
}
|
|
51640
51788
|
function lspCacheRoot() {
|
|
51641
|
-
return
|
|
51789
|
+
return join10(aftCacheBase(), "lsp-packages");
|
|
51642
51790
|
}
|
|
51643
51791
|
function lspPackageDir(npmPackage) {
|
|
51644
|
-
return
|
|
51792
|
+
return join10(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
51645
51793
|
}
|
|
51646
51794
|
function lspBinaryPath(npmPackage, binary) {
|
|
51647
|
-
return
|
|
51795
|
+
return join10(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
51648
51796
|
}
|
|
51649
51797
|
function lspBinDir(npmPackage) {
|
|
51650
|
-
return
|
|
51798
|
+
return join10(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
51651
51799
|
}
|
|
51652
51800
|
function isInstalled(npmPackage, binary) {
|
|
51653
51801
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
51654
51802
|
try {
|
|
51655
|
-
if (statSync3(
|
|
51803
|
+
if (statSync3(join10(lspBinDir(npmPackage), candidate)).isFile())
|
|
51656
51804
|
return true;
|
|
51657
51805
|
} catch {}
|
|
51658
51806
|
}
|
|
@@ -51666,23 +51814,23 @@ function lspBinaryCandidates(binary) {
|
|
|
51666
51814
|
var INSTALLED_META_FILE = ".aft-installed";
|
|
51667
51815
|
function writeInstalledMetaIn(installDir, version2, sha256) {
|
|
51668
51816
|
try {
|
|
51669
|
-
|
|
51817
|
+
mkdirSync7(installDir, { recursive: true });
|
|
51670
51818
|
const meta3 = {
|
|
51671
51819
|
version: version2,
|
|
51672
51820
|
installedAt: new Date().toISOString(),
|
|
51673
51821
|
...sha256 ? { sha256 } : {}
|
|
51674
51822
|
};
|
|
51675
|
-
writeFileSync4(
|
|
51823
|
+
writeFileSync4(join10(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
|
|
51676
51824
|
} catch (err) {
|
|
51677
51825
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
51678
51826
|
}
|
|
51679
51827
|
}
|
|
51680
51828
|
function readInstalledMetaIn(installDir) {
|
|
51681
|
-
const path2 =
|
|
51829
|
+
const path2 = join10(installDir, INSTALLED_META_FILE);
|
|
51682
51830
|
try {
|
|
51683
51831
|
if (!statSync3(path2).isFile())
|
|
51684
51832
|
return null;
|
|
51685
|
-
const raw =
|
|
51833
|
+
const raw = readFileSync5(path2, "utf8");
|
|
51686
51834
|
const parsed = JSON.parse(raw);
|
|
51687
51835
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
51688
51836
|
return null;
|
|
@@ -51702,11 +51850,11 @@ function readInstalledMeta(packageKey) {
|
|
|
51702
51850
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
51703
51851
|
}
|
|
51704
51852
|
function lockPath(npmPackage) {
|
|
51705
|
-
return
|
|
51853
|
+
return join10(lspPackageDir(npmPackage), ".aft-installing");
|
|
51706
51854
|
}
|
|
51707
51855
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
51708
51856
|
function acquireInstallLock(lockKey) {
|
|
51709
|
-
|
|
51857
|
+
mkdirSync7(lspPackageDir(lockKey), { recursive: true });
|
|
51710
51858
|
const lock = lockPath(lockKey);
|
|
51711
51859
|
const tryClaim = () => {
|
|
51712
51860
|
try {
|
|
@@ -51732,7 +51880,7 @@ ${new Date().toISOString()}
|
|
|
51732
51880
|
let owningPid = null;
|
|
51733
51881
|
let lockMtimeMs = 0;
|
|
51734
51882
|
try {
|
|
51735
|
-
const raw =
|
|
51883
|
+
const raw = readFileSync5(lock, "utf8");
|
|
51736
51884
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
51737
51885
|
const parsed = Number.parseInt(firstLine, 10);
|
|
51738
51886
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
@@ -51770,7 +51918,7 @@ function releaseInstallLock(lockKey) {
|
|
|
51770
51918
|
try {
|
|
51771
51919
|
let owningPid = null;
|
|
51772
51920
|
try {
|
|
51773
|
-
const raw =
|
|
51921
|
+
const raw = readFileSync5(lock, "utf8");
|
|
51774
51922
|
const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
|
|
51775
51923
|
const parsed = Number.parseInt(firstLine, 10);
|
|
51776
51924
|
if (Number.isFinite(parsed) && parsed > 0)
|
|
@@ -51809,9 +51957,9 @@ async function withInstallLock(lockKey, task) {
|
|
|
51809
51957
|
}
|
|
51810
51958
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
51811
51959
|
function readVersionCheck(npmPackage) {
|
|
51812
|
-
const file2 =
|
|
51960
|
+
const file2 = join10(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
51813
51961
|
try {
|
|
51814
|
-
const raw =
|
|
51962
|
+
const raw = readFileSync5(file2, "utf8");
|
|
51815
51963
|
const parsed = JSON.parse(raw);
|
|
51816
51964
|
if (typeof parsed.last_checked === "string") {
|
|
51817
51965
|
return {
|
|
@@ -51825,8 +51973,8 @@ function readVersionCheck(npmPackage) {
|
|
|
51825
51973
|
}
|
|
51826
51974
|
}
|
|
51827
51975
|
function writeVersionCheck(npmPackage, latest) {
|
|
51828
|
-
|
|
51829
|
-
const file2 =
|
|
51976
|
+
mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
|
|
51977
|
+
const file2 = join10(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
51830
51978
|
const record2 = {
|
|
51831
51979
|
last_checked: new Date().toISOString(),
|
|
51832
51980
|
latest_eligible: latest
|
|
@@ -51988,8 +52136,8 @@ var NPM_LSP_TABLE = [
|
|
|
51988
52136
|
];
|
|
51989
52137
|
|
|
51990
52138
|
// src/lsp-project-relevance.ts
|
|
51991
|
-
import { existsSync as
|
|
51992
|
-
import { join as
|
|
52139
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "node:fs";
|
|
52140
|
+
import { join as join11 } from "node:path";
|
|
51993
52141
|
var MAX_WALK_DIRS = 200;
|
|
51994
52142
|
var MAX_WALK_DEPTH = 4;
|
|
51995
52143
|
var NOISE_DIRS = new Set([
|
|
@@ -52006,7 +52154,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
52006
52154
|
if (!rootMarkers)
|
|
52007
52155
|
return false;
|
|
52008
52156
|
for (const marker of rootMarkers) {
|
|
52009
|
-
if (
|
|
52157
|
+
if (existsSync8(join11(projectRoot, marker)))
|
|
52010
52158
|
return true;
|
|
52011
52159
|
}
|
|
52012
52160
|
return false;
|
|
@@ -52030,7 +52178,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
52030
52178
|
}
|
|
52031
52179
|
function readPackageJson(projectRoot) {
|
|
52032
52180
|
try {
|
|
52033
|
-
const raw =
|
|
52181
|
+
const raw = readFileSync6(join11(projectRoot, "package.json"), "utf8");
|
|
52034
52182
|
const parsed = JSON.parse(raw);
|
|
52035
52183
|
if (typeof parsed !== "object" || parsed === null)
|
|
52036
52184
|
return null;
|
|
@@ -52060,7 +52208,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
52060
52208
|
for (const entry of entries) {
|
|
52061
52209
|
if (entry.isDirectory()) {
|
|
52062
52210
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
52063
|
-
queue.push({ dir:
|
|
52211
|
+
queue.push({ dir: join11(current.dir, entry.name), depth: current.depth + 1 });
|
|
52064
52212
|
}
|
|
52065
52213
|
continue;
|
|
52066
52214
|
}
|
|
@@ -52357,16 +52505,16 @@ function installedBinaryPath(spec) {
|
|
|
52357
52505
|
return null;
|
|
52358
52506
|
}
|
|
52359
52507
|
function sha256OfFileSync(path2) {
|
|
52360
|
-
return createHash4("sha256").update(
|
|
52508
|
+
return createHash4("sha256").update(readFileSync7(path2)).digest("hex");
|
|
52361
52509
|
}
|
|
52362
52510
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
52363
52511
|
const packageDir = lspPackageDir(spec.npm);
|
|
52364
|
-
const dest =
|
|
52512
|
+
const dest = join12(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
52365
52513
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
52366
52514
|
try {
|
|
52367
|
-
|
|
52515
|
+
mkdirSync8(join12(dest, ".."), { recursive: true });
|
|
52368
52516
|
rmSync3(dest, { recursive: true, force: true });
|
|
52369
|
-
|
|
52517
|
+
renameSync5(packageDir, dest);
|
|
52370
52518
|
} catch (err) {
|
|
52371
52519
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: failed to quarantine cache entry: ${err}`);
|
|
52372
52520
|
}
|
|
@@ -52413,7 +52561,6 @@ function runAutoInstall(projectRoot, config2, fetchImpl2 = fetch) {
|
|
|
52413
52561
|
continue;
|
|
52414
52562
|
}
|
|
52415
52563
|
installsStarted += 1;
|
|
52416
|
-
installingBinaries.push(spec.binary);
|
|
52417
52564
|
const controller = new AbortController;
|
|
52418
52565
|
const promise2 = ensureServerInstalled(spec, config2, fetchImpl2, controller.signal).then((outcome) => {
|
|
52419
52566
|
if (!outcome.started)
|
|
@@ -52442,25 +52589,25 @@ function runAutoInstall(projectRoot, config2, fetchImpl2 = fetch) {
|
|
|
52442
52589
|
|
|
52443
52590
|
// src/lsp-github-install.ts
|
|
52444
52591
|
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
52445
|
-
import { createHash as createHash5, randomBytes } from "node:crypto";
|
|
52592
|
+
import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
|
|
52446
52593
|
import {
|
|
52447
52594
|
copyFileSync as copyFileSync3,
|
|
52448
52595
|
createReadStream as createReadStream2,
|
|
52449
52596
|
createWriteStream as createWriteStream3,
|
|
52450
|
-
existsSync as
|
|
52597
|
+
existsSync as existsSync9,
|
|
52451
52598
|
lstatSync as lstatSync2,
|
|
52452
|
-
mkdirSync as
|
|
52599
|
+
mkdirSync as mkdirSync9,
|
|
52453
52600
|
readdirSync as readdirSync4,
|
|
52454
|
-
readFileSync as
|
|
52601
|
+
readFileSync as readFileSync8,
|
|
52455
52602
|
readlinkSync as readlinkSync2,
|
|
52456
52603
|
realpathSync as realpathSync3,
|
|
52457
|
-
renameSync as
|
|
52604
|
+
renameSync as renameSync6,
|
|
52458
52605
|
rmSync as rmSync4,
|
|
52459
52606
|
statSync as statSync5,
|
|
52460
52607
|
unlinkSync as unlinkSync6,
|
|
52461
52608
|
writeFileSync as writeFileSync5
|
|
52462
52609
|
} from "node:fs";
|
|
52463
|
-
import { dirname as
|
|
52610
|
+
import { dirname as dirname4, join as join13, relative as relative2, resolve as resolve2 } from "node:path";
|
|
52464
52611
|
import { Readable as Readable3 } from "node:stream";
|
|
52465
52612
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
52466
52613
|
|
|
@@ -52550,26 +52697,26 @@ function detectHostPlatform() {
|
|
|
52550
52697
|
|
|
52551
52698
|
// src/lsp-github-install.ts
|
|
52552
52699
|
function ghCacheRoot() {
|
|
52553
|
-
return
|
|
52700
|
+
return join13(aftCacheBase(), "lsp-binaries");
|
|
52554
52701
|
}
|
|
52555
52702
|
function ghPackageDir(spec) {
|
|
52556
|
-
return
|
|
52703
|
+
return join13(ghCacheRoot(), spec.id);
|
|
52557
52704
|
}
|
|
52558
52705
|
function ghBinDir(spec) {
|
|
52559
|
-
return
|
|
52706
|
+
return join13(ghPackageDir(spec), "bin");
|
|
52560
52707
|
}
|
|
52561
52708
|
function ghExtractDir(spec) {
|
|
52562
|
-
return
|
|
52709
|
+
return join13(ghPackageDir(spec), "extracted");
|
|
52563
52710
|
}
|
|
52564
52711
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
52565
52712
|
function ghBinaryPath(spec, platform) {
|
|
52566
52713
|
const ext = platform === "win32" ? ".exe" : "";
|
|
52567
|
-
return
|
|
52714
|
+
return join13(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
52568
52715
|
}
|
|
52569
52716
|
function isGithubInstalled(spec, platform) {
|
|
52570
52717
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
52571
52718
|
try {
|
|
52572
|
-
if (statSync5(
|
|
52719
|
+
if (statSync5(join13(ghBinDir(spec), candidate)).isFile())
|
|
52573
52720
|
return true;
|
|
52574
52721
|
} catch {}
|
|
52575
52722
|
}
|
|
@@ -52582,10 +52729,10 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
52582
52729
|
}
|
|
52583
52730
|
function readGithubInstalledMetaIn(installDir) {
|
|
52584
52731
|
try {
|
|
52585
|
-
const path2 =
|
|
52732
|
+
const path2 = join13(installDir, INSTALLED_META_FILE2);
|
|
52586
52733
|
if (!statSync5(path2).isFile())
|
|
52587
52734
|
return null;
|
|
52588
|
-
const parsed = JSON.parse(
|
|
52735
|
+
const parsed = JSON.parse(readFileSync8(path2, "utf8"));
|
|
52589
52736
|
if (typeof parsed.version !== "string" || parsed.version.length === 0)
|
|
52590
52737
|
return null;
|
|
52591
52738
|
return {
|
|
@@ -52601,7 +52748,7 @@ function readGithubInstalledMetaIn(installDir) {
|
|
|
52601
52748
|
}
|
|
52602
52749
|
function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveSha256) {
|
|
52603
52750
|
try {
|
|
52604
|
-
|
|
52751
|
+
mkdirSync9(installDir, { recursive: true });
|
|
52605
52752
|
const meta3 = {
|
|
52606
52753
|
version: version2,
|
|
52607
52754
|
installedAt: new Date().toISOString(),
|
|
@@ -52609,7 +52756,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
|
|
|
52609
52756
|
binarySha256,
|
|
52610
52757
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
52611
52758
|
};
|
|
52612
|
-
writeFileSync5(
|
|
52759
|
+
writeFileSync5(join13(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
|
|
52613
52760
|
} catch (err) {
|
|
52614
52761
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
52615
52762
|
}
|
|
@@ -52626,7 +52773,7 @@ function sha256OfFile(path2) {
|
|
|
52626
52773
|
});
|
|
52627
52774
|
}
|
|
52628
52775
|
function sha256OfFileSync2(path2) {
|
|
52629
|
-
return createHash5("sha256").update(
|
|
52776
|
+
return createHash5("sha256").update(readFileSync8(path2)).digest("hex");
|
|
52630
52777
|
}
|
|
52631
52778
|
async function fetchReleaseByTag(githubRepo, tag, fetchImpl2, signal) {
|
|
52632
52779
|
const candidates = [];
|
|
@@ -52802,7 +52949,7 @@ async function downloadFile(url2, destPath, fetchImpl2, assetSize, signal) {
|
|
|
52802
52949
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
|
|
52803
52950
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
|
|
52804
52951
|
}
|
|
52805
|
-
|
|
52952
|
+
mkdirSync9(dirname4(destPath), { recursive: true });
|
|
52806
52953
|
let bytesWritten = 0;
|
|
52807
52954
|
const guard = new TransformStream({
|
|
52808
52955
|
transform(chunk, controller) {
|
|
@@ -52858,7 +53005,7 @@ function validateExtraction(stagingRoot) {
|
|
|
52858
53005
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
52859
53006
|
}
|
|
52860
53007
|
for (const entry of entries) {
|
|
52861
|
-
const full =
|
|
53008
|
+
const full = join13(dir, entry);
|
|
52862
53009
|
let lst;
|
|
52863
53010
|
try {
|
|
52864
53011
|
lst = lstatSync2(full);
|
|
@@ -52923,12 +53070,12 @@ function precheckArchiveContents(archivePath, archiveType) {
|
|
|
52923
53070
|
}
|
|
52924
53071
|
}
|
|
52925
53072
|
function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
52926
|
-
const suffix =
|
|
53073
|
+
const suffix = randomBytes2(8).toString("hex");
|
|
52927
53074
|
const stagingDir = `${destDir}.staging-${suffix}`;
|
|
52928
53075
|
try {
|
|
52929
53076
|
rmSync4(stagingDir, { recursive: true, force: true });
|
|
52930
53077
|
} catch {}
|
|
52931
|
-
|
|
53078
|
+
mkdirSync9(stagingDir, { recursive: true });
|
|
52932
53079
|
try {
|
|
52933
53080
|
precheckArchiveContents(archivePath, archiveType);
|
|
52934
53081
|
runPlatformExtractor(archivePath, stagingDir, archiveType);
|
|
@@ -52936,7 +53083,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
52936
53083
|
try {
|
|
52937
53084
|
rmSync4(destDir, { recursive: true, force: true });
|
|
52938
53085
|
} catch {}
|
|
52939
|
-
|
|
53086
|
+
renameSync6(stagingDir, destDir);
|
|
52940
53087
|
} catch (err) {
|
|
52941
53088
|
try {
|
|
52942
53089
|
rmSync4(stagingDir, { recursive: true, force: true });
|
|
@@ -52946,12 +53093,12 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
52946
53093
|
}
|
|
52947
53094
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
52948
53095
|
const packageDir = ghPackageDir(spec);
|
|
52949
|
-
const dest =
|
|
53096
|
+
const dest = join13(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
52950
53097
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
52951
53098
|
try {
|
|
52952
|
-
|
|
53099
|
+
mkdirSync9(dirname4(dest), { recursive: true });
|
|
52953
53100
|
rmSync4(dest, { recursive: true, force: true });
|
|
52954
|
-
|
|
53101
|
+
renameSync6(packageDir, dest);
|
|
52955
53102
|
} catch (err) {
|
|
52956
53103
|
warn2(`[lsp] tofu_mismatch ${spec.id}: failed to quarantine cache entry: ${err}`);
|
|
52957
53104
|
}
|
|
@@ -52959,7 +53106,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
52959
53106
|
function validateCachedGithubInstall(spec, platform) {
|
|
52960
53107
|
const packageDir = ghPackageDir(spec);
|
|
52961
53108
|
const meta3 = readGithubInstalledMetaIn(packageDir);
|
|
52962
|
-
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) =>
|
|
53109
|
+
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join13(ghBinDir(spec), candidate)).find((candidate) => {
|
|
52963
53110
|
try {
|
|
52964
53111
|
return statSync5(candidate).isFile();
|
|
52965
53112
|
} catch {
|
|
@@ -53037,7 +53184,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl2,
|
|
|
53037
53184
|
}
|
|
53038
53185
|
const pkgDir = ghPackageDir(spec);
|
|
53039
53186
|
const extractDir = ghExtractDir(spec);
|
|
53040
|
-
const archivePath =
|
|
53187
|
+
const archivePath = join13(pkgDir, expected.name);
|
|
53041
53188
|
log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
|
|
53042
53189
|
try {
|
|
53043
53190
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl2, matchingAsset.size, signal);
|
|
@@ -53077,13 +53224,13 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl2,
|
|
|
53077
53224
|
unlinkSync6(archivePath);
|
|
53078
53225
|
} catch {}
|
|
53079
53226
|
}
|
|
53080
|
-
const innerBinaryPath =
|
|
53081
|
-
if (!
|
|
53227
|
+
const innerBinaryPath = join13(extractDir, spec.binaryPathInArchive(platform, arch, version2));
|
|
53228
|
+
if (!existsSync9(innerBinaryPath)) {
|
|
53082
53229
|
error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
|
|
53083
53230
|
return null;
|
|
53084
53231
|
}
|
|
53085
53232
|
const targetBinary = ghBinaryPath(spec, platform);
|
|
53086
|
-
|
|
53233
|
+
mkdirSync9(dirname4(targetBinary), { recursive: true });
|
|
53087
53234
|
try {
|
|
53088
53235
|
copyFileSync3(innerBinaryPath, targetBinary);
|
|
53089
53236
|
if (platform !== "win32") {
|
|
@@ -53162,7 +53309,7 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl2 = fetch) {
|
|
|
53162
53309
|
if (!host) {
|
|
53163
53310
|
for (const spec of GITHUB_LSP_TABLE) {
|
|
53164
53311
|
try {
|
|
53165
|
-
if (
|
|
53312
|
+
if (existsSync9(ghBinDir(spec))) {
|
|
53166
53313
|
cachedBinDirs.push(ghBinDir(spec));
|
|
53167
53314
|
}
|
|
53168
53315
|
} catch {}
|
|
@@ -53192,7 +53339,6 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl2 = fetch) {
|
|
|
53192
53339
|
continue;
|
|
53193
53340
|
}
|
|
53194
53341
|
installsStarted += 1;
|
|
53195
|
-
installingBinaries.push(spec.binary);
|
|
53196
53342
|
const controller = new AbortController;
|
|
53197
53343
|
const promise2 = ensureGithubInstalled(spec, config2, fetchImpl2, host.platform, host.arch, controller.signal).then((outcome) => {
|
|
53198
53344
|
if (!outcome.started)
|
|
@@ -53260,8 +53406,8 @@ function discoverRelevantGithubServers(projectRoot) {
|
|
|
53260
53406
|
}
|
|
53261
53407
|
|
|
53262
53408
|
// src/notifications.ts
|
|
53263
|
-
import { existsSync as
|
|
53264
|
-
import {
|
|
53409
|
+
import { existsSync as existsSync10, mkdirSync as mkdirSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
|
|
53410
|
+
import { dirname as dirname5 } from "node:path";
|
|
53265
53411
|
var WARNING_MARKER = "\uD83D\uDD27 AFT: ⚠️";
|
|
53266
53412
|
var FEATURE_MARKER = "\uD83D\uDD27 AFT: ✨";
|
|
53267
53413
|
function sendIgnoredMessage(client, sessionId, text) {
|
|
@@ -53354,10 +53500,10 @@ async function deliverConfigureWarnings(opts, warnings) {
|
|
|
53354
53500
|
}
|
|
53355
53501
|
}
|
|
53356
53502
|
function sendFeatureAnnouncement(version2, features, footer, storageDir) {
|
|
53357
|
-
const versionFile =
|
|
53503
|
+
const versionFile = repairRootScopedStorageFile(storageDir, "pi", "last_announced_version");
|
|
53358
53504
|
try {
|
|
53359
|
-
if (
|
|
53360
|
-
const lastVersion =
|
|
53505
|
+
if (existsSync10(versionFile)) {
|
|
53506
|
+
const lastVersion = readFileSync9(versionFile, "utf-8").trim();
|
|
53361
53507
|
if (lastVersion === version2)
|
|
53362
53508
|
return;
|
|
53363
53509
|
}
|
|
@@ -53372,7 +53518,7 @@ function sendFeatureAnnouncement(version2, features, footer, storageDir) {
|
|
|
53372
53518
|
log2(sections.join(`
|
|
53373
53519
|
`));
|
|
53374
53520
|
try {
|
|
53375
|
-
|
|
53521
|
+
mkdirSync10(dirname5(versionFile), { recursive: true });
|
|
53376
53522
|
writeFileSync6(versionFile, version2);
|
|
53377
53523
|
} catch {}
|
|
53378
53524
|
}
|
|
@@ -53515,7 +53661,7 @@ function registerShutdownCleanup(fn) {
|
|
|
53515
53661
|
|
|
53516
53662
|
// src/tools/ast.ts
|
|
53517
53663
|
import { StringEnum } from "@earendil-works/pi-ai";
|
|
53518
|
-
import { Type } from "typebox";
|
|
53664
|
+
import { Type as Type2 } from "typebox";
|
|
53519
53665
|
|
|
53520
53666
|
// src/tools/render-helpers.ts
|
|
53521
53667
|
import { homedir as homedir8 } from "node:os";
|
|
@@ -53710,22 +53856,22 @@ function renderUnifiedDiff(unifiedDiff) {
|
|
|
53710
53856
|
var AstLang = StringEnum(["typescript", "tsx", "javascript", "python", "rust", "go"], {
|
|
53711
53857
|
description: "Target language"
|
|
53712
53858
|
});
|
|
53713
|
-
var SearchParams =
|
|
53714
|
-
pattern:
|
|
53859
|
+
var SearchParams = Type2.Object({
|
|
53860
|
+
pattern: Type2.String({
|
|
53715
53861
|
description: "AST pattern with meta-variables (`$VAR` matches one node, `$$$` matches many). Must be a complete AST node."
|
|
53716
53862
|
}),
|
|
53717
53863
|
lang: AstLang,
|
|
53718
|
-
paths:
|
|
53719
|
-
globs:
|
|
53720
|
-
contextLines:
|
|
53864
|
+
paths: Type2.Optional(Type2.Array(Type2.String(), { description: "Paths to search (default: ['.'])" })),
|
|
53865
|
+
globs: Type2.Optional(Type2.Array(Type2.String(), { description: "Include/exclude globs (prefix `!` to exclude)" })),
|
|
53866
|
+
contextLines: Type2.Optional(Type2.Number({ description: "Number of context lines around each match" }))
|
|
53721
53867
|
});
|
|
53722
|
-
var ReplaceParams =
|
|
53723
|
-
pattern:
|
|
53724
|
-
rewrite:
|
|
53868
|
+
var ReplaceParams = Type2.Object({
|
|
53869
|
+
pattern: Type2.String({ description: "AST pattern with meta-variables" }),
|
|
53870
|
+
rewrite: Type2.String({ description: "Replacement pattern, can reference $VAR from pattern" }),
|
|
53725
53871
|
lang: AstLang,
|
|
53726
|
-
paths:
|
|
53727
|
-
globs:
|
|
53728
|
-
dryRun:
|
|
53872
|
+
paths: Type2.Optional(Type2.Array(Type2.String(), { description: "Paths (default: ['.'])" })),
|
|
53873
|
+
globs: Type2.Optional(Type2.Array(Type2.String(), { description: "Include/exclude globs" })),
|
|
53874
|
+
dryRun: Type2.Optional(Type2.Boolean({ description: "Preview without applying (default: false)" }))
|
|
53729
53875
|
});
|
|
53730
53876
|
function appendHintSection(response, sections, theme) {
|
|
53731
53877
|
const hint = asString(response.hint);
|
|
@@ -53916,79 +54062,68 @@ function registerAstTools(pi, ctx, surface) {
|
|
|
53916
54062
|
// src/tools/bash.ts
|
|
53917
54063
|
import * as fs3 from "node:fs/promises";
|
|
53918
54064
|
import { Container as Container2, Spacer as Spacer2, Text as Text2 } from "@earendil-works/pi-tui";
|
|
53919
|
-
import { Type as
|
|
54065
|
+
import { Type as Type3 } from "typebox";
|
|
53920
54066
|
var FOREGROUND_WAIT_WINDOW_MS = 5000;
|
|
53921
54067
|
var FOREGROUND_POLL_INTERVAL_MS = 100;
|
|
53922
54068
|
var BASH_WAIT_POLL_INTERVAL_MS = 100;
|
|
53923
54069
|
var DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS = 30000;
|
|
53924
54070
|
var MAX_BASH_STATUS_WAIT_TIMEOUT_MS = 300000;
|
|
53925
54071
|
var BASH_TRANSPORT_TIMEOUT_MS = 30000;
|
|
53926
|
-
var BashParams =
|
|
53927
|
-
command:
|
|
54072
|
+
var BashParams = Type3.Object({
|
|
54073
|
+
command: Type3.String({
|
|
53928
54074
|
description: "Shell command to execute. Supports pipes, redirections, and shell syntax."
|
|
53929
54075
|
}),
|
|
53930
|
-
timeout:
|
|
53931
|
-
|
|
53932
|
-
description: "Hard kill cap in milliseconds (positive integer). When omitted, the task can run up to 30 minutes. Foreground bash returns inline if the command finishes within ~5s; otherwise it's automatically promoted to background and a completion reminder is delivered when the task actually finishes."
|
|
53933
|
-
})),
|
|
53934
|
-
workdir: Type2.Optional(Type2.String({
|
|
54076
|
+
timeout: optionalInt(1, Number.MAX_SAFE_INTEGER),
|
|
54077
|
+
workdir: Type3.Optional(Type3.String({
|
|
53935
54078
|
description: "Working directory for command execution. Relative paths resolve against the project root. Defaults to the current session's working directory."
|
|
53936
54079
|
})),
|
|
53937
|
-
description:
|
|
54080
|
+
description: Type3.Optional(Type3.String({
|
|
53938
54081
|
description: "Human-readable description shown in UI logs. Helps users understand what the command does without reading shell syntax."
|
|
53939
54082
|
})),
|
|
53940
|
-
background:
|
|
54083
|
+
background: Type3.Optional(Type3.Boolean({
|
|
53941
54084
|
description: "Spawn command in background and return immediately with a task_id. Use bash_status to poll completion and bash_kill to terminate. Ideal for long-running tasks like builds or dev servers."
|
|
53942
54085
|
})),
|
|
53943
|
-
compressed:
|
|
54086
|
+
compressed: Type3.Optional(Type3.Boolean({
|
|
53944
54087
|
description: "Compress output by removing ANSI codes, carriage returns, and excessive blank lines. Default: true. Set to false for raw terminal output including color codes."
|
|
53945
54088
|
})),
|
|
53946
|
-
pty:
|
|
53947
|
-
description: 'Spawn the command in a real PTY for interactive programs.
|
|
54089
|
+
pty: Type3.Optional(Type3.Boolean({
|
|
54090
|
+
description: 'Spawn the command in a real PTY for interactive programs. Implies background: true automatically. Inspect with bash_status({ task_id, output_mode: "screen" }) and send input with bash_write.'
|
|
53948
54091
|
})),
|
|
53949
|
-
ptyRows:
|
|
53950
|
-
|
|
53951
|
-
maximum: 60,
|
|
53952
|
-
description: "PTY terminal height in rows. Applies only when pty: true; defaults to 24. Minimum 1, maximum 60."
|
|
53953
|
-
})),
|
|
53954
|
-
ptyCols: Type2.Optional(Type2.Integer({
|
|
53955
|
-
minimum: 1,
|
|
53956
|
-
maximum: 140,
|
|
53957
|
-
description: "PTY terminal width in columns. Applies only when pty: true; defaults to 80. Minimum 1, maximum 140."
|
|
53958
|
-
}))
|
|
54092
|
+
ptyRows: optionalInt(1, 60),
|
|
54093
|
+
ptyCols: optionalInt(1, 140)
|
|
53959
54094
|
});
|
|
53960
|
-
var BashTaskParams =
|
|
53961
|
-
task_id:
|
|
54095
|
+
var BashTaskParams = Type3.Object({
|
|
54096
|
+
task_id: Type3.String({
|
|
53962
54097
|
description: "Background bash task id returned by bash({ background: true })."
|
|
53963
54098
|
})
|
|
53964
54099
|
});
|
|
53965
|
-
var BashStatusParams =
|
|
53966
|
-
task_id:
|
|
54100
|
+
var BashStatusParams = Type3.Object({
|
|
54101
|
+
task_id: Type3.String({
|
|
53967
54102
|
description: "Background bash task id returned by bash({ background: true })."
|
|
53968
54103
|
}),
|
|
53969
|
-
output_mode:
|
|
54104
|
+
output_mode: Type3.Optional(Type3.Union([Type3.Literal("screen"), Type3.Literal("raw"), Type3.Literal("both")], {
|
|
53970
54105
|
description: "PTY output rendering mode. Defaults to screen for PTY tasks and preserves existing behavior for piped tasks when omitted."
|
|
53971
54106
|
}))
|
|
53972
54107
|
});
|
|
53973
|
-
var BashWatchParams =
|
|
53974
|
-
task_id:
|
|
54108
|
+
var BashWatchParams = Type3.Object({
|
|
54109
|
+
task_id: Type3.String({
|
|
53975
54110
|
description: "Background bash task id returned by bash({ background: true })."
|
|
53976
54111
|
}),
|
|
53977
|
-
pattern:
|
|
53978
|
-
background:
|
|
53979
|
-
timeout_ms:
|
|
53980
|
-
once:
|
|
54112
|
+
pattern: Type3.Optional(Type3.Union([Type3.String(), Type3.Object({ regex: Type3.String() })])),
|
|
54113
|
+
background: Type3.Optional(Type3.Boolean()),
|
|
54114
|
+
timeout_ms: optionalInt(1, MAX_BASH_STATUS_WAIT_TIMEOUT_MS),
|
|
54115
|
+
once: Type3.Optional(Type3.Boolean())
|
|
53981
54116
|
});
|
|
53982
|
-
var BashWriteParams =
|
|
53983
|
-
task_id:
|
|
54117
|
+
var BashWriteParams = Type3.Object({
|
|
54118
|
+
task_id: Type3.String({
|
|
53984
54119
|
description: "Background PTY task id returned by bash({ pty: true, background: true })."
|
|
53985
54120
|
}),
|
|
53986
|
-
input:
|
|
53987
|
-
|
|
53988
|
-
|
|
53989
|
-
|
|
53990
|
-
|
|
53991
|
-
key:
|
|
54121
|
+
input: Type3.Union([
|
|
54122
|
+
Type3.String(),
|
|
54123
|
+
Type3.Array(Type3.Union([
|
|
54124
|
+
Type3.String(),
|
|
54125
|
+
Type3.Object({
|
|
54126
|
+
key: Type3.String({
|
|
53992
54127
|
description: "Named control key, e.g. 'esc', 'enter', 'up', 'ctrl-c'. Case-insensitive."
|
|
53993
54128
|
})
|
|
53994
54129
|
})
|
|
@@ -54032,12 +54167,10 @@ function registerBashTool(pi, ctx) {
|
|
|
54032
54167
|
parameters: BashParams,
|
|
54033
54168
|
async execute(_toolCallId, params, _signal, onUpdate, extCtx) {
|
|
54034
54169
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
54035
|
-
|
|
54036
|
-
|
|
54037
|
-
|
|
54038
|
-
|
|
54039
|
-
throw new Error("PTY mode requires background: true");
|
|
54040
|
-
}
|
|
54170
|
+
const timeout = coerceOptionalInt(params.timeout, "timeout", 1, Number.MAX_SAFE_INTEGER);
|
|
54171
|
+
const ptyRows = coerceOptionalInt(params.ptyRows, "ptyRows", 1, 60);
|
|
54172
|
+
const ptyCols = coerceOptionalInt(params.ptyCols, "ptyCols", 1, 140);
|
|
54173
|
+
const effectiveBackground = params.background === true || params.pty === true;
|
|
54041
54174
|
let spawnContext = {
|
|
54042
54175
|
command: params.command,
|
|
54043
54176
|
cwd: params.workdir
|
|
@@ -54052,16 +54185,16 @@ function registerBashTool(pi, ctx) {
|
|
|
54052
54185
|
let streamed = "";
|
|
54053
54186
|
const response = await callBridge(bridge, "bash", {
|
|
54054
54187
|
command: spawnContext.command,
|
|
54055
|
-
timeout
|
|
54188
|
+
timeout,
|
|
54056
54189
|
workdir: spawnContext.cwd ?? params.workdir,
|
|
54057
54190
|
env: spawnContext.env,
|
|
54058
54191
|
description: params.description,
|
|
54059
|
-
background:
|
|
54060
|
-
notify_on_completion:
|
|
54192
|
+
background: effectiveBackground,
|
|
54193
|
+
notify_on_completion: effectiveBackground,
|
|
54061
54194
|
compressed: params.compressed,
|
|
54062
54195
|
pty: params.pty,
|
|
54063
|
-
pty_rows:
|
|
54064
|
-
pty_cols:
|
|
54196
|
+
pty_rows: ptyRows,
|
|
54197
|
+
pty_cols: ptyCols
|
|
54065
54198
|
}, extCtx, {
|
|
54066
54199
|
transportTimeoutMs: BASH_TRANSPORT_TIMEOUT_MS,
|
|
54067
54200
|
keepBridgeOnTimeout: true,
|
|
@@ -54081,13 +54214,13 @@ function registerBashTool(pi, ctx) {
|
|
|
54081
54214
|
}
|
|
54082
54215
|
const taskId = response.task_id;
|
|
54083
54216
|
if (response.status === "running" && taskId) {
|
|
54084
|
-
if (
|
|
54217
|
+
if (effectiveBackground) {
|
|
54085
54218
|
trackBgTask(resolveSessionId(extCtx), taskId);
|
|
54086
54219
|
return bashResult(formatBackgroundLaunch(taskId, params.pty === true), {
|
|
54087
54220
|
task_id: taskId
|
|
54088
54221
|
});
|
|
54089
54222
|
}
|
|
54090
|
-
const waitTimeoutMs =
|
|
54223
|
+
const waitTimeoutMs = timeout !== undefined ? Math.min(timeout, FOREGROUND_WAIT_WINDOW_MS) : FOREGROUND_WAIT_WINDOW_MS;
|
|
54091
54224
|
const startedAt = Date.now();
|
|
54092
54225
|
while (true) {
|
|
54093
54226
|
const status = await callBridge(bridge, "bash_status", { task_id: taskId }, extCtx);
|
|
@@ -54228,7 +54361,7 @@ function createBashWatchTool(ctx) {
|
|
|
54228
54361
|
return textResult(`Watch registered: ${registered.watch_id} on task ${params.task_id}
|
|
54229
54362
|
A notification will fire when the pattern matches or the task exits.`, watchDetails);
|
|
54230
54363
|
}
|
|
54231
|
-
const data = await waitForBashStatus(ctx, bridge, extCtx, params.task_id, undefined, waitFor, true, Math.min(params.timeout_ms ?? DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS, MAX_BASH_STATUS_WAIT_TIMEOUT_MS));
|
|
54364
|
+
const data = await waitForBashStatus(ctx, bridge, extCtx, params.task_id, undefined, waitFor, true, Math.min(coerceOptionalInt(params.timeout_ms, "timeout_ms", 1, MAX_BASH_STATUS_WAIT_TIMEOUT_MS) ?? DEFAULT_BASH_STATUS_WAIT_TIMEOUT_MS, MAX_BASH_STATUS_WAIT_TIMEOUT_MS));
|
|
54232
54365
|
const text = await formatBashStatus(extCtx, params.task_id, data, undefined);
|
|
54233
54366
|
return textResult(text, data);
|
|
54234
54367
|
}
|
|
@@ -54301,7 +54434,7 @@ async function bashStatusSnapshot(bridge, extCtx, taskId, outputMode, options) {
|
|
|
54301
54434
|
async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFor, waitForExit, effectiveWaitMs) {
|
|
54302
54435
|
const startedAt = Date.now();
|
|
54303
54436
|
const deadline = startedAt + effectiveWaitMs;
|
|
54304
|
-
let spillCursor = 0;
|
|
54437
|
+
let spillCursor = { output: 0, stderr: 0, combined: 0 };
|
|
54305
54438
|
let scanText = "";
|
|
54306
54439
|
let scanBaseOffset = 0;
|
|
54307
54440
|
const bridgeOptions = {
|
|
@@ -54315,12 +54448,7 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
54315
54448
|
try {
|
|
54316
54449
|
while (true) {
|
|
54317
54450
|
const data = await bashStatusSnapshot(bridge, extCtx, taskId, outputMode, bridgeOptions);
|
|
54318
|
-
|
|
54319
|
-
sawTerminal = true;
|
|
54320
|
-
consumeBgCompletion(sessionId, taskId);
|
|
54321
|
-
await markBgCompletionDelivered({ ctx, directory: extCtx.cwd, sessionID: sessionId }, taskId);
|
|
54322
|
-
return withWaited(data, { reason: "exited", elapsed_ms: Date.now() - startedAt });
|
|
54323
|
-
}
|
|
54451
|
+
const terminal = isTerminalStatus(data.status);
|
|
54324
54452
|
if (waitFor) {
|
|
54325
54453
|
const scan = await readNewTaskOutput(extCtx, taskId, data, spillCursor);
|
|
54326
54454
|
if (scan) {
|
|
@@ -54330,6 +54458,11 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
54330
54458
|
scanText += scan.text;
|
|
54331
54459
|
const match = findWaitMatch(scanText, waitFor);
|
|
54332
54460
|
if (match) {
|
|
54461
|
+
if (waitForExit && terminal) {
|
|
54462
|
+
sawTerminal = true;
|
|
54463
|
+
consumeBgCompletion(sessionId, taskId);
|
|
54464
|
+
await markBgCompletionDelivered({ ctx, directory: extCtx.cwd, sessionID: sessionId }, taskId);
|
|
54465
|
+
}
|
|
54333
54466
|
return withWaited(data, {
|
|
54334
54467
|
reason: "matched",
|
|
54335
54468
|
elapsed_ms: Date.now() - startedAt,
|
|
@@ -54338,9 +54471,14 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
54338
54471
|
});
|
|
54339
54472
|
}
|
|
54340
54473
|
}
|
|
54341
|
-
|
|
54342
|
-
|
|
54474
|
+
}
|
|
54475
|
+
if (terminal) {
|
|
54476
|
+
if (waitForExit) {
|
|
54477
|
+
sawTerminal = true;
|
|
54478
|
+
consumeBgCompletion(sessionId, taskId);
|
|
54479
|
+
await markBgCompletionDelivered({ ctx, directory: extCtx.cwd, sessionID: sessionId }, taskId);
|
|
54343
54480
|
}
|
|
54481
|
+
return withWaited(data, { reason: "exited", elapsed_ms: Date.now() - startedAt });
|
|
54344
54482
|
}
|
|
54345
54483
|
if (Date.now() >= deadline) {
|
|
54346
54484
|
return withWaited(data, { reason: "timeout", elapsed_ms: Date.now() - startedAt });
|
|
@@ -54350,21 +54488,45 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
|
|
|
54350
54488
|
} finally {
|
|
54351
54489
|
if (waitForExit && !sawTerminal)
|
|
54352
54490
|
unmarkTaskWaiting(sessionId, taskId);
|
|
54491
|
+
if (waitFor) {
|
|
54492
|
+
await disposePtyTerminal(watchPtyCacheKey(extCtx, taskId));
|
|
54493
|
+
}
|
|
54353
54494
|
}
|
|
54354
54495
|
}
|
|
54355
54496
|
async function readNewTaskOutput(extCtx, taskId, data, cursor) {
|
|
54356
54497
|
const outputPath = data.output_path;
|
|
54357
|
-
if (!outputPath)
|
|
54358
|
-
return;
|
|
54359
54498
|
if (data.mode === "pty") {
|
|
54499
|
+
if (!outputPath)
|
|
54500
|
+
return;
|
|
54360
54501
|
const { rows, cols } = ptyDimensions(data);
|
|
54361
|
-
const state = await getOrCreatePtyTerminal(
|
|
54502
|
+
const state = await getOrCreatePtyTerminal(watchPtyCacheKey(extCtx, taskId), outputPath, rows, cols);
|
|
54362
54503
|
const baseOffset = state.offset;
|
|
54363
|
-
const
|
|
54364
|
-
|
|
54504
|
+
const bytes = await readPtyBytes(state);
|
|
54505
|
+
if (bytes.length === 0)
|
|
54506
|
+
return;
|
|
54507
|
+
return {
|
|
54508
|
+
text: bytes.toString("utf8"),
|
|
54509
|
+
baseOffset,
|
|
54510
|
+
nextCursor: { output: state.offset, stderr: 0, combined: state.offset }
|
|
54511
|
+
};
|
|
54365
54512
|
}
|
|
54366
|
-
const
|
|
54367
|
-
|
|
54513
|
+
const stderrPath = data.stderr_path;
|
|
54514
|
+
if (!outputPath && !stderrPath)
|
|
54515
|
+
return;
|
|
54516
|
+
const stdoutBytes = outputPath ? await readFileBytesFrom(outputPath, cursor.output) : Buffer.alloc(0);
|
|
54517
|
+
const stderrBytes = stderrPath ? await readFileBytesFrom(stderrPath, cursor.stderr) : Buffer.alloc(0);
|
|
54518
|
+
const bytesRead = stdoutBytes.length + stderrBytes.length;
|
|
54519
|
+
if (bytesRead === 0)
|
|
54520
|
+
return;
|
|
54521
|
+
return {
|
|
54522
|
+
text: Buffer.concat([stdoutBytes, stderrBytes]).toString("utf8"),
|
|
54523
|
+
baseOffset: cursor.combined,
|
|
54524
|
+
nextCursor: {
|
|
54525
|
+
output: cursor.output + stdoutBytes.length,
|
|
54526
|
+
stderr: cursor.stderr + stderrBytes.length,
|
|
54527
|
+
combined: cursor.combined + bytesRead
|
|
54528
|
+
}
|
|
54529
|
+
};
|
|
54368
54530
|
}
|
|
54369
54531
|
async function readFileBytesFrom(outputPath, cursor) {
|
|
54370
54532
|
const handle = await fs3.open(outputPath, "r");
|
|
@@ -54476,6 +54638,9 @@ function ptyDimensions(data) {
|
|
|
54476
54638
|
function ptyCacheKey(extCtx, taskId) {
|
|
54477
54639
|
return `${extCtx.cwd}::${resolveSessionId(extCtx) ?? "__default__"}::${taskId}`;
|
|
54478
54640
|
}
|
|
54641
|
+
function watchPtyCacheKey(extCtx, taskId) {
|
|
54642
|
+
return `${ptyCacheKey(extCtx, taskId)}::watch`;
|
|
54643
|
+
}
|
|
54479
54644
|
function isTerminalStatus(status) {
|
|
54480
54645
|
return status === "completed" || status === "failed" || status === "killed" || status === "timed_out";
|
|
54481
54646
|
}
|
|
@@ -54546,8 +54711,8 @@ function shortenCommand(command) {
|
|
|
54546
54711
|
}
|
|
54547
54712
|
|
|
54548
54713
|
// src/tools/conflicts.ts
|
|
54549
|
-
import { Type as
|
|
54550
|
-
var ConflictsParams =
|
|
54714
|
+
import { Type as Type4 } from "typebox";
|
|
54715
|
+
var ConflictsParams = Type4.Object({});
|
|
54551
54716
|
function renderConflictCall(theme, context) {
|
|
54552
54717
|
return renderToolCall("conflicts", undefined, theme, context);
|
|
54553
54718
|
}
|
|
@@ -54595,19 +54760,19 @@ function registerConflictsTool(pi, ctx) {
|
|
|
54595
54760
|
}
|
|
54596
54761
|
|
|
54597
54762
|
// src/tools/fs.ts
|
|
54598
|
-
import { Type as
|
|
54599
|
-
var DeleteParams =
|
|
54600
|
-
files:
|
|
54763
|
+
import { Type as Type5 } from "typebox";
|
|
54764
|
+
var DeleteParams = Type5.Object({
|
|
54765
|
+
files: Type5.Array(Type5.String(), {
|
|
54601
54766
|
description: "Paths to delete (one or more). May include directories when recursive=true.",
|
|
54602
54767
|
minItems: 1
|
|
54603
54768
|
}),
|
|
54604
|
-
recursive:
|
|
54769
|
+
recursive: Type5.Optional(Type5.Boolean({
|
|
54605
54770
|
description: "Required to delete a directory and its contents. Defaults to false; passing a directory without this returns an error."
|
|
54606
54771
|
}))
|
|
54607
54772
|
});
|
|
54608
|
-
var MoveParams =
|
|
54609
|
-
filePath:
|
|
54610
|
-
destination:
|
|
54773
|
+
var MoveParams = Type5.Object({
|
|
54774
|
+
filePath: Type5.String({ description: "Source file path to move" }),
|
|
54775
|
+
destination: Type5.String({ description: "Destination file path" })
|
|
54611
54776
|
});
|
|
54612
54777
|
function renderFsCall(toolName, args, theme, context) {
|
|
54613
54778
|
if (toolName === "aft_delete") {
|
|
@@ -54715,7 +54880,7 @@ import {
|
|
|
54715
54880
|
renderDiff as renderDiff2
|
|
54716
54881
|
} from "@earendil-works/pi-coding-agent";
|
|
54717
54882
|
import { Container as Container3, Spacer as Spacer3, Text as Text3 } from "@earendil-works/pi-tui";
|
|
54718
|
-
import { Type as
|
|
54883
|
+
import { Type as Type6 } from "typebox";
|
|
54719
54884
|
|
|
54720
54885
|
// src/tools/diff-format.ts
|
|
54721
54886
|
import { diffLines } from "diff";
|
|
@@ -54835,33 +55000,33 @@ async function assertExternalDirectoryPermission(extCtx, target, action = "modif
|
|
|
54835
55000
|
return;
|
|
54836
55001
|
throw new Error("Permission denied: external directory access was cancelled.");
|
|
54837
55002
|
}
|
|
54838
|
-
var ReadParams =
|
|
54839
|
-
path:
|
|
54840
|
-
offset:
|
|
54841
|
-
limit:
|
|
55003
|
+
var ReadParams = Type6.Object({
|
|
55004
|
+
path: Type6.String({ description: "Path to the file to read (relative or absolute)" }),
|
|
55005
|
+
offset: optionalInt(1, Number.MAX_SAFE_INTEGER),
|
|
55006
|
+
limit: optionalInt(1, Number.MAX_SAFE_INTEGER)
|
|
54842
55007
|
});
|
|
54843
|
-
var WriteParams =
|
|
54844
|
-
filePath:
|
|
55008
|
+
var WriteParams = Type6.Object({
|
|
55009
|
+
filePath: Type6.String({
|
|
54845
55010
|
description: "Path to the file to write (absolute or project-relative)"
|
|
54846
55011
|
}),
|
|
54847
|
-
content:
|
|
54848
|
-
});
|
|
54849
|
-
var EditParams =
|
|
54850
|
-
filePath:
|
|
54851
|
-
oldString:
|
|
54852
|
-
newString:
|
|
54853
|
-
replaceAll:
|
|
54854
|
-
occurrence:
|
|
54855
|
-
appendContent:
|
|
55012
|
+
content: Type6.String({ description: "Full file contents to write" })
|
|
55013
|
+
});
|
|
55014
|
+
var EditParams = Type6.Object({
|
|
55015
|
+
filePath: Type6.String({ description: "Path to the file to edit" }),
|
|
55016
|
+
oldString: Type6.Optional(Type6.String({ description: "Text to find (exact match, fuzzy fallback)" })),
|
|
55017
|
+
newString: Type6.Optional(Type6.String({ description: "Replacement text (omit to delete match)" })),
|
|
55018
|
+
replaceAll: Type6.Optional(Type6.Boolean({ description: "Replace every occurrence" })),
|
|
55019
|
+
occurrence: optionalInt(0, Number.MAX_SAFE_INTEGER),
|
|
55020
|
+
appendContent: Type6.Optional(Type6.String({
|
|
54856
55021
|
description: "Append text to the end of the file (creates the file if missing, parent dirs auto-created). When set, oldString/newString are ignored."
|
|
54857
55022
|
}))
|
|
54858
55023
|
});
|
|
54859
|
-
var GrepParams =
|
|
54860
|
-
pattern:
|
|
54861
|
-
path:
|
|
54862
|
-
include:
|
|
54863
|
-
caseSensitive:
|
|
54864
|
-
contextLines:
|
|
55024
|
+
var GrepParams = Type6.Object({
|
|
55025
|
+
pattern: Type6.String({ description: "Regex pattern to search for" }),
|
|
55026
|
+
path: Type6.Optional(Type6.String({ description: "Path scope (file or directory)" })),
|
|
55027
|
+
include: Type6.Optional(Type6.String({ description: "Glob filter for included files (e.g. '*.ts,*.tsx')" })),
|
|
55028
|
+
caseSensitive: Type6.Optional(Type6.Boolean({ description: "Case-sensitive matching" })),
|
|
55029
|
+
contextLines: optionalInt(1, Number.MAX_SAFE_INTEGER)
|
|
54865
55030
|
});
|
|
54866
55031
|
function registerHoistedTools(pi, ctx, surface) {
|
|
54867
55032
|
if (surface.hoistRead) {
|
|
@@ -54874,14 +55039,16 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
54874
55039
|
parameters: ReadParams,
|
|
54875
55040
|
async execute(_toolCallId, params, _signal, _onUpdate, extCtx) {
|
|
54876
55041
|
const bridge = bridgeFor(ctx, extCtx.cwd);
|
|
55042
|
+
const offset = coerceOptionalInt(params.offset, "offset", 1, Number.MAX_SAFE_INTEGER);
|
|
55043
|
+
const limit = coerceOptionalInt(params.limit, "limit", 1, Number.MAX_SAFE_INTEGER);
|
|
54877
55044
|
const req = { file: params.path };
|
|
54878
|
-
if (
|
|
54879
|
-
req.start_line =
|
|
54880
|
-
if (
|
|
54881
|
-
req.end_line =
|
|
55045
|
+
if (offset !== undefined) {
|
|
55046
|
+
req.start_line = offset;
|
|
55047
|
+
if (limit !== undefined) {
|
|
55048
|
+
req.end_line = offset + limit - 1;
|
|
54882
55049
|
}
|
|
54883
|
-
} else if (
|
|
54884
|
-
req.end_line =
|
|
55050
|
+
} else if (limit !== undefined) {
|
|
55051
|
+
req.end_line = limit;
|
|
54885
55052
|
}
|
|
54886
55053
|
const response = await callBridge(bridge, "read", req, extCtx);
|
|
54887
55054
|
if (Array.isArray(response.entries)) {
|
|
@@ -54889,7 +55056,7 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
54889
55056
|
`));
|
|
54890
55057
|
}
|
|
54891
55058
|
let text = response.content ?? "";
|
|
54892
|
-
const agentSpecifiedRange =
|
|
55059
|
+
const agentSpecifiedRange = offset !== undefined || limit !== undefined;
|
|
54893
55060
|
const footer = formatReadFooter(agentSpecifiedRange, response);
|
|
54894
55061
|
if (footer)
|
|
54895
55062
|
text += footer;
|
|
@@ -54959,8 +55126,9 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
54959
55126
|
};
|
|
54960
55127
|
if (params.replaceAll === true)
|
|
54961
55128
|
req.replace_all = true;
|
|
54962
|
-
|
|
54963
|
-
|
|
55129
|
+
const occurrence = coerceOptionalInt(params.occurrence, "occurrence", 0, Number.MAX_SAFE_INTEGER);
|
|
55130
|
+
if (occurrence !== undefined)
|
|
55131
|
+
req.occurrence = occurrence;
|
|
54964
55132
|
const response = await callBridge(bridge, "edit_match", req, extCtx);
|
|
54965
55133
|
return buildMutationResult(params.filePath, response);
|
|
54966
55134
|
},
|
|
@@ -54991,8 +55159,9 @@ function registerHoistedTools(pi, ctx, surface) {
|
|
|
54991
55159
|
req.include = splitIncludeGlobs(params.include);
|
|
54992
55160
|
if (params.caseSensitive !== undefined)
|
|
54993
55161
|
req.case_sensitive = params.caseSensitive;
|
|
54994
|
-
|
|
54995
|
-
|
|
55162
|
+
const contextLines = coerceOptionalInt(params.contextLines, "contextLines", 1, Number.MAX_SAFE_INTEGER);
|
|
55163
|
+
if (contextLines !== undefined)
|
|
55164
|
+
req.context_lines = contextLines;
|
|
54996
55165
|
const response = await callBridge(bridge, "grep", req, extCtx);
|
|
54997
55166
|
const text = response.text ?? "";
|
|
54998
55167
|
return textResult(text);
|
|
@@ -55211,16 +55380,16 @@ function formatReadFooter(agentSpecifiedRange, data) {
|
|
|
55211
55380
|
|
|
55212
55381
|
// src/tools/imports.ts
|
|
55213
55382
|
import { StringEnum as StringEnum2 } from "@earendil-works/pi-ai";
|
|
55214
|
-
import { Type as
|
|
55215
|
-
var ImportParams =
|
|
55383
|
+
import { Type as Type7 } from "typebox";
|
|
55384
|
+
var ImportParams = Type7.Object({
|
|
55216
55385
|
op: StringEnum2(["add", "remove", "organize"], { description: "Import operation" }),
|
|
55217
|
-
filePath:
|
|
55218
|
-
module:
|
|
55219
|
-
names:
|
|
55220
|
-
defaultImport:
|
|
55221
|
-
removeName:
|
|
55222
|
-
typeOnly:
|
|
55223
|
-
validate:
|
|
55386
|
+
filePath: Type7.String({ description: "Path to the file" }),
|
|
55387
|
+
module: Type7.Optional(Type7.String({ description: "Module path (required for add/remove), e.g. 'react', './utils'" })),
|
|
55388
|
+
names: Type7.Optional(Type7.Array(Type7.String(), { description: "Named imports to add, e.g. ['useState']" })),
|
|
55389
|
+
defaultImport: Type7.Optional(Type7.String({ description: "Default import name (e.g. 'React')" })),
|
|
55390
|
+
removeName: Type7.Optional(Type7.String({ description: "Named import to remove; omit to remove entire import" })),
|
|
55391
|
+
typeOnly: Type7.Optional(Type7.Boolean({ description: "Type-only import (TS only)" })),
|
|
55392
|
+
validate: Type7.Optional(StringEnum2(["syntax", "full"], {
|
|
55224
55393
|
description: "Post-edit validation level (default: syntax)"
|
|
55225
55394
|
}))
|
|
55226
55395
|
});
|
|
@@ -55309,16 +55478,16 @@ function registerImportTools(pi, ctx) {
|
|
|
55309
55478
|
|
|
55310
55479
|
// src/tools/lsp.ts
|
|
55311
55480
|
import { StringEnum as StringEnum3 } from "@earendil-works/pi-ai";
|
|
55312
|
-
import { Type as
|
|
55313
|
-
var LspDiagnosticsParams =
|
|
55314
|
-
filePath:
|
|
55315
|
-
directory:
|
|
55481
|
+
import { Type as Type8 } from "typebox";
|
|
55482
|
+
var LspDiagnosticsParams = Type8.Object({
|
|
55483
|
+
filePath: Type8.Optional(Type8.String({ description: "File to get diagnostics for (mutually exclusive with directory)" })),
|
|
55484
|
+
directory: Type8.Optional(Type8.String({
|
|
55316
55485
|
description: "Directory to get diagnostics for (mutually exclusive with filePath)"
|
|
55317
55486
|
})),
|
|
55318
|
-
severity:
|
|
55487
|
+
severity: Type8.Optional(StringEnum3(["error", "warning", "information", "hint", "all"], {
|
|
55319
55488
|
description: "Filter by severity (default: all)"
|
|
55320
55489
|
})),
|
|
55321
|
-
waitMs:
|
|
55490
|
+
waitMs: Type8.Optional(Type8.Number({
|
|
55322
55491
|
description: "Wait N ms for fresh diagnostics (max 10000, default: 0)"
|
|
55323
55492
|
}))
|
|
55324
55493
|
});
|
|
@@ -55403,16 +55572,16 @@ function registerLspTools(pi, ctx) {
|
|
|
55403
55572
|
|
|
55404
55573
|
// src/tools/navigate.ts
|
|
55405
55574
|
import { StringEnum as StringEnum4 } from "@earendil-works/pi-ai";
|
|
55406
|
-
import { Type as
|
|
55575
|
+
import { Type as Type9 } from "typebox";
|
|
55407
55576
|
function navigateParamsSchema() {
|
|
55408
|
-
return
|
|
55577
|
+
return Type9.Object({
|
|
55409
55578
|
op: StringEnum4(["call_tree", "callers", "trace_to", "impact", "trace_data"], {
|
|
55410
55579
|
description: "Navigation operation"
|
|
55411
55580
|
}),
|
|
55412
|
-
filePath:
|
|
55413
|
-
symbol:
|
|
55414
|
-
depth:
|
|
55415
|
-
expression:
|
|
55581
|
+
filePath: Type9.String({ description: "Source file containing the symbol" }),
|
|
55582
|
+
symbol: Type9.String({ description: "Name of the symbol to analyze" }),
|
|
55583
|
+
depth: optionalInt(1, Number.MAX_SAFE_INTEGER),
|
|
55584
|
+
expression: Type9.Optional(Type9.String({ description: "Expression to track (required for trace_data)" }))
|
|
55416
55585
|
});
|
|
55417
55586
|
}
|
|
55418
55587
|
function treeLine(depth, text) {
|
|
@@ -55427,6 +55596,14 @@ function renderCallTreeNode(node, depth, lines) {
|
|
|
55427
55596
|
renderCallTreeNode(child, depth + 1, lines);
|
|
55428
55597
|
});
|
|
55429
55598
|
}
|
|
55599
|
+
function depthWarning(response, theme, depthField = "depth_limited", truncatedField = "truncated") {
|
|
55600
|
+
const limited = asBoolean(response[depthField]);
|
|
55601
|
+
const truncated = asNumber(response[truncatedField]) ?? 0;
|
|
55602
|
+
if (!limited && truncated === 0)
|
|
55603
|
+
return "";
|
|
55604
|
+
const detail = truncated > 0 ? `, ${truncated} truncated` : "";
|
|
55605
|
+
return theme.fg("warning", `(depth limited${detail})`);
|
|
55606
|
+
}
|
|
55430
55607
|
function renderTracePath(path2, index, lines) {
|
|
55431
55608
|
lines.push(`Path ${index + 1}`);
|
|
55432
55609
|
asRecords(path2.hops).forEach((hop, hopIndex) => {
|
|
@@ -55444,12 +55621,16 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
55444
55621
|
if (args.op === "call_tree") {
|
|
55445
55622
|
const lines = [];
|
|
55446
55623
|
renderCallTreeNode(response, 0, lines);
|
|
55624
|
+
const warning = depthWarning(response, theme);
|
|
55625
|
+
if (warning)
|
|
55626
|
+
lines.push(warning);
|
|
55447
55627
|
return lines.length > 0 ? lines : [theme.fg("muted", "No call tree available.")];
|
|
55448
55628
|
}
|
|
55449
55629
|
if (args.op === "callers") {
|
|
55450
55630
|
const groups = asRecords(response.callers);
|
|
55631
|
+
const warning = depthWarning(response, theme);
|
|
55451
55632
|
const sections2 = [
|
|
55452
|
-
`${theme.fg("success", `${asNumber(response.total_callers) ?? 0} caller${(asNumber(response.total_callers) ?? 0) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${groups.length} file group${groups.length === 1 ? "" : "s"}`)}
|
|
55633
|
+
`${theme.fg("success", `${asNumber(response.total_callers) ?? 0} caller${(asNumber(response.total_callers) ?? 0) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${groups.length} file group${groups.length === 1 ? "" : "s"}`)} ${warning}`.trim()
|
|
55453
55634
|
];
|
|
55454
55635
|
groups.forEach((group) => {
|
|
55455
55636
|
const file2 = shortenPath(asString(group.file) ?? "(unknown file)");
|
|
@@ -55464,8 +55645,9 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
55464
55645
|
}
|
|
55465
55646
|
if (args.op === "trace_to") {
|
|
55466
55647
|
const paths = asRecords(response.paths);
|
|
55648
|
+
const warning = depthWarning(response, theme, "max_depth_reached", "truncated_paths");
|
|
55467
55649
|
const sections2 = [
|
|
55468
|
-
`${theme.fg("success", `${asNumber(response.total_paths) ?? paths.length} path${(asNumber(response.total_paths) ?? paths.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.entry_points_found) ?? 0} entry point${(asNumber(response.entry_points_found) ?? 0) === 1 ? "" : "s"}`)}
|
|
55650
|
+
`${theme.fg("success", `${asNumber(response.total_paths) ?? paths.length} path${(asNumber(response.total_paths) ?? paths.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.entry_points_found) ?? 0} entry point${(asNumber(response.entry_points_found) ?? 0) === 1 ? "" : "s"}`)} ${warning}`.trim()
|
|
55469
55651
|
];
|
|
55470
55652
|
if (paths.length === 0)
|
|
55471
55653
|
sections2.push(theme.fg("muted", "No entry paths found."));
|
|
@@ -55479,8 +55661,9 @@ function buildNavigateSections(args, payload, theme) {
|
|
|
55479
55661
|
}
|
|
55480
55662
|
if (args.op === "impact") {
|
|
55481
55663
|
const callers = asRecords(response.callers);
|
|
55664
|
+
const warning = depthWarning(response, theme);
|
|
55482
55665
|
const sections2 = [
|
|
55483
|
-
`${theme.fg("warning", `${asNumber(response.total_affected) ?? callers.length} affected call site${(asNumber(response.total_affected) ?? callers.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.affected_files) ?? 0} file${(asNumber(response.affected_files) ?? 0) === 1 ? "" : "s"}`)}
|
|
55666
|
+
`${theme.fg("warning", `${asNumber(response.total_affected) ?? callers.length} affected call site${(asNumber(response.total_affected) ?? callers.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.affected_files) ?? 0} file${(asNumber(response.affected_files) ?? 0) === 1 ? "" : "s"}`)} ${warning}`.trim()
|
|
55484
55667
|
];
|
|
55485
55668
|
if (callers.length === 0)
|
|
55486
55669
|
sections2.push(theme.fg("muted", "No impacted callers found."));
|
|
@@ -55546,8 +55729,9 @@ function registerNavigateTool(pi, ctx) {
|
|
|
55546
55729
|
file: params.filePath,
|
|
55547
55730
|
symbol: params.symbol
|
|
55548
55731
|
};
|
|
55549
|
-
|
|
55550
|
-
|
|
55732
|
+
const depth = coerceOptionalInt(params.depth, "depth", 1, Number.MAX_SAFE_INTEGER);
|
|
55733
|
+
if (depth !== undefined)
|
|
55734
|
+
req.depth = depth;
|
|
55551
55735
|
if (params.expression !== undefined)
|
|
55552
55736
|
req.expression = params.expression;
|
|
55553
55737
|
const response = await callBridge(bridge, params.op, req, extCtx);
|
|
@@ -55565,20 +55749,20 @@ function registerNavigateTool(pi, ctx) {
|
|
|
55565
55749
|
// src/tools/reading.ts
|
|
55566
55750
|
import { stat as stat2 } from "node:fs/promises";
|
|
55567
55751
|
import { resolve as resolve4 } from "node:path";
|
|
55568
|
-
import { Type as
|
|
55569
|
-
var OutlineParams =
|
|
55570
|
-
target:
|
|
55752
|
+
import { Type as Type10 } from "typebox";
|
|
55753
|
+
var OutlineParams = Type10.Object({
|
|
55754
|
+
target: Type10.Union([Type10.String(), Type10.Array(Type10.String())], {
|
|
55571
55755
|
description: "What to outline: a file path, directory path, URL (http:// or https://), or array of file paths. The mode is auto-detected: URLs by `http://`/`https://` prefix, directories by stat, arrays as multi-file. Directory walks cap at 200 files."
|
|
55572
55756
|
})
|
|
55573
55757
|
});
|
|
55574
|
-
var ZoomParams =
|
|
55575
|
-
filePath:
|
|
55576
|
-
url:
|
|
55758
|
+
var ZoomParams = Type10.Object({
|
|
55759
|
+
filePath: Type10.Optional(Type10.String({ description: "Path to file (absolute or project-relative)" })),
|
|
55760
|
+
url: Type10.Optional(Type10.String({
|
|
55577
55761
|
description: "HTTP/HTTPS URL of an HTML or Markdown document to fetch and zoom into"
|
|
55578
55762
|
})),
|
|
55579
|
-
symbol:
|
|
55580
|
-
symbols:
|
|
55581
|
-
contextLines:
|
|
55763
|
+
symbol: Type10.Optional(Type10.String({ description: "Symbol name (function/class/type) or Markdown heading" })),
|
|
55764
|
+
symbols: Type10.Optional(Type10.Array(Type10.String(), { description: "Multiple symbols — returns array of matches" })),
|
|
55765
|
+
contextLines: Type10.Optional(Type10.Number({ description: "Lines of context before/after (default: 3)" }))
|
|
55582
55766
|
});
|
|
55583
55767
|
function isUrl(s) {
|
|
55584
55768
|
return s.startsWith("http://") || s.startsWith("https://");
|
|
@@ -55826,17 +56010,17 @@ ${lines}`;
|
|
|
55826
56010
|
|
|
55827
56011
|
// src/tools/refactor.ts
|
|
55828
56012
|
import { StringEnum as StringEnum5 } from "@earendil-works/pi-ai";
|
|
55829
|
-
import { Type as
|
|
55830
|
-
var RefactorParams =
|
|
56013
|
+
import { Type as Type11 } from "typebox";
|
|
56014
|
+
var RefactorParams = Type11.Object({
|
|
55831
56015
|
op: StringEnum5(["move", "extract", "inline"], { description: "Refactoring operation" }),
|
|
55832
|
-
filePath:
|
|
55833
|
-
symbol:
|
|
55834
|
-
destination:
|
|
55835
|
-
scope:
|
|
55836
|
-
name:
|
|
55837
|
-
startLine:
|
|
55838
|
-
endLine:
|
|
55839
|
-
callSiteLine:
|
|
56016
|
+
filePath: Type11.String({ description: "Source file" }),
|
|
56017
|
+
symbol: Type11.Optional(Type11.String({ description: "Symbol name (for move, inline)" })),
|
|
56018
|
+
destination: Type11.Optional(Type11.String({ description: "Target file (for move)" })),
|
|
56019
|
+
scope: Type11.Optional(Type11.String({ description: "Disambiguation scope for move op" })),
|
|
56020
|
+
name: Type11.Optional(Type11.String({ description: "New function name (for extract)" })),
|
|
56021
|
+
startLine: optionalInt(1, Number.MAX_SAFE_INTEGER),
|
|
56022
|
+
endLine: optionalInt(1, Number.MAX_SAFE_INTEGER),
|
|
56023
|
+
callSiteLine: optionalInt(1, Number.MAX_SAFE_INTEGER)
|
|
55840
56024
|
});
|
|
55841
56025
|
function buildRefactorSections(args, payload, theme) {
|
|
55842
56026
|
const response = asRecord2(payload);
|
|
@@ -55902,13 +56086,16 @@ function registerRefactorTool(pi, ctx) {
|
|
|
55902
56086
|
req.scope = params.scope;
|
|
55903
56087
|
if (params.name !== undefined)
|
|
55904
56088
|
req.name = params.name;
|
|
55905
|
-
|
|
55906
|
-
|
|
55907
|
-
|
|
55908
|
-
|
|
55909
|
-
|
|
55910
|
-
if (
|
|
55911
|
-
req.
|
|
56089
|
+
const startLine = coerceOptionalInt(params.startLine, "startLine", 1, Number.MAX_SAFE_INTEGER);
|
|
56090
|
+
const endLine = coerceOptionalInt(params.endLine, "endLine", 1, Number.MAX_SAFE_INTEGER);
|
|
56091
|
+
const callSiteLine = coerceOptionalInt(params.callSiteLine, "callSiteLine", 1, Number.MAX_SAFE_INTEGER);
|
|
56092
|
+
if (startLine !== undefined)
|
|
56093
|
+
req.start_line = startLine;
|
|
56094
|
+
if (endLine !== undefined) {
|
|
56095
|
+
req.end_line = params.op === "extract" ? endLine + 1 : endLine;
|
|
56096
|
+
}
|
|
56097
|
+
if (callSiteLine !== undefined)
|
|
56098
|
+
req.call_site_line = callSiteLine;
|
|
55912
56099
|
const response = await callBridge(bridge, commandMap[params.op], req, extCtx);
|
|
55913
56100
|
return textResult(JSON.stringify(response, null, 2));
|
|
55914
56101
|
},
|
|
@@ -55923,14 +56110,14 @@ function registerRefactorTool(pi, ctx) {
|
|
|
55923
56110
|
|
|
55924
56111
|
// src/tools/safety.ts
|
|
55925
56112
|
import { StringEnum as StringEnum6 } from "@earendil-works/pi-ai";
|
|
55926
|
-
import { Type as
|
|
55927
|
-
var SafetyParams =
|
|
56113
|
+
import { Type as Type12 } from "typebox";
|
|
56114
|
+
var SafetyParams = Type12.Object({
|
|
55928
56115
|
op: StringEnum6(["undo", "history", "checkpoint", "restore", "list"], {
|
|
55929
56116
|
description: "Safety operation"
|
|
55930
56117
|
}),
|
|
55931
|
-
filePath:
|
|
55932
|
-
name:
|
|
55933
|
-
files:
|
|
56118
|
+
filePath: Type12.Optional(Type12.String({ description: "File path (required for history, optional for undo)" })),
|
|
56119
|
+
name: Type12.Optional(Type12.String({ description: "Checkpoint name (required for checkpoint, restore)" })),
|
|
56120
|
+
files: Type12.Optional(Type12.Array(Type12.String(), {
|
|
55934
56121
|
description: "Specific files for checkpoint (optional, defaults to all tracked)"
|
|
55935
56122
|
}))
|
|
55936
56123
|
});
|
|
@@ -56061,12 +56248,12 @@ function registerSafetyTool(pi, ctx) {
|
|
|
56061
56248
|
}
|
|
56062
56249
|
|
|
56063
56250
|
// src/tools/semantic.ts
|
|
56064
|
-
import { Type as
|
|
56065
|
-
var SearchParams2 =
|
|
56066
|
-
query:
|
|
56251
|
+
import { Type as Type13 } from "typebox";
|
|
56252
|
+
var SearchParams2 = Type13.Object({
|
|
56253
|
+
query: Type13.String({
|
|
56067
56254
|
description: "Concept or capability to find, phrased as a programmer would describe the code. Examples: 'fuzzy match with whitespace tolerance', 'undo backup before edit', 'retry failed network request'."
|
|
56068
56255
|
}),
|
|
56069
|
-
topK:
|
|
56256
|
+
topK: Type13.Optional(Type13.Number({ description: "Maximum number of results (default: 10, max: 100)" }))
|
|
56070
56257
|
});
|
|
56071
56258
|
function buildSemanticSections(args, payload, theme) {
|
|
56072
56259
|
const response = asRecord2(payload);
|
|
@@ -56167,23 +56354,23 @@ function registerSemanticTool(pi, ctx) {
|
|
|
56167
56354
|
|
|
56168
56355
|
// src/tools/structure.ts
|
|
56169
56356
|
import { StringEnum as StringEnum7 } from "@earendil-works/pi-ai";
|
|
56170
|
-
import { Type as
|
|
56171
|
-
var TransformParams =
|
|
56357
|
+
import { Type as Type14 } from "typebox";
|
|
56358
|
+
var TransformParams = Type14.Object({
|
|
56172
56359
|
op: StringEnum7(["add_member", "add_derive", "wrap_try_catch", "add_decorator", "add_struct_tags"], { description: "Transformation operation" }),
|
|
56173
|
-
filePath:
|
|
56174
|
-
container:
|
|
56175
|
-
code:
|
|
56176
|
-
target:
|
|
56177
|
-
derives:
|
|
56178
|
-
catchBody:
|
|
56179
|
-
decorator:
|
|
56180
|
-
field:
|
|
56181
|
-
tag:
|
|
56182
|
-
value:
|
|
56183
|
-
position:
|
|
56360
|
+
filePath: Type14.String({ description: "Path to the source file" }),
|
|
56361
|
+
container: Type14.Optional(Type14.String({ description: "Class/struct/impl name for add_member" })),
|
|
56362
|
+
code: Type14.Optional(Type14.String({ description: "Member code to insert (add_member)" })),
|
|
56363
|
+
target: Type14.Optional(Type14.String({ description: "Target symbol name" })),
|
|
56364
|
+
derives: Type14.Optional(Type14.Array(Type14.String(), { description: "Derive macro names (add_derive)" })),
|
|
56365
|
+
catchBody: Type14.Optional(Type14.String({ description: "Catch block body (wrap_try_catch, default: 'throw error;')" })),
|
|
56366
|
+
decorator: Type14.Optional(Type14.String({ description: "Decorator text without @ (add_decorator)" })),
|
|
56367
|
+
field: Type14.Optional(Type14.String({ description: "Struct field name (add_struct_tags)" })),
|
|
56368
|
+
tag: Type14.Optional(Type14.String({ description: "Tag key (add_struct_tags)" })),
|
|
56369
|
+
value: Type14.Optional(Type14.String({ description: "Tag value (add_struct_tags)" })),
|
|
56370
|
+
position: Type14.Optional(Type14.String({
|
|
56184
56371
|
description: "Position hint: 'first', 'last' (default), 'before:name', 'after:name' for add_member"
|
|
56185
56372
|
})),
|
|
56186
|
-
validate:
|
|
56373
|
+
validate: Type14.Optional(StringEnum7(["syntax", "full"], {
|
|
56187
56374
|
description: "Validation level (default: syntax)"
|
|
56188
56375
|
}))
|
|
56189
56376
|
});
|
|
@@ -56448,6 +56635,10 @@ function shouldPrepareOnnxRuntime(config2) {
|
|
|
56448
56635
|
const isFastembedSemanticBackend = (config2.semantic?.backend ?? "fastembed") === "fastembed";
|
|
56449
56636
|
return config2.semantic_search === true && isFastembedSemanticBackend;
|
|
56450
56637
|
}
|
|
56638
|
+
function bridgeDirectoryFromCallback(bridge, fallback) {
|
|
56639
|
+
const cwd = bridge?.cwd;
|
|
56640
|
+
return typeof cwd === "string" && cwd.length > 0 ? cwd : fallback;
|
|
56641
|
+
}
|
|
56451
56642
|
async function handleConfigureWarningsForSession(context) {
|
|
56452
56643
|
const validWarnings = coerceConfigureWarnings(context.warnings);
|
|
56453
56644
|
if (!context.sessionId) {
|
|
@@ -56664,21 +56855,32 @@ ${lines}
|
|
|
56664
56855
|
});
|
|
56665
56856
|
}, 0);
|
|
56666
56857
|
},
|
|
56667
|
-
onBashCompletion: (completion) => {
|
|
56858
|
+
onBashCompletion: (completion, bridge) => {
|
|
56859
|
+
const directory = bridgeDirectoryFromCallback(bridge, process.cwd());
|
|
56668
56860
|
handlePushedBgCompletion({
|
|
56669
56861
|
ctx,
|
|
56670
|
-
directory
|
|
56862
|
+
directory,
|
|
56671
56863
|
sessionID: completion.session_id,
|
|
56672
56864
|
runtime: pi
|
|
56673
56865
|
}, completion);
|
|
56674
56866
|
},
|
|
56675
|
-
onBashLongRunning: (reminder) => {
|
|
56867
|
+
onBashLongRunning: (reminder, bridge) => {
|
|
56868
|
+
const directory = bridgeDirectoryFromCallback(bridge, process.cwd());
|
|
56676
56869
|
handlePushedBgLongRunning({
|
|
56677
56870
|
ctx,
|
|
56678
|
-
directory
|
|
56871
|
+
directory,
|
|
56679
56872
|
sessionID: reminder.session_id,
|
|
56680
56873
|
runtime: pi
|
|
56681
56874
|
}, reminder);
|
|
56875
|
+
},
|
|
56876
|
+
onBashPatternMatch: (frame, bridge) => {
|
|
56877
|
+
const directory = bridgeDirectoryFromCallback(bridge, process.cwd());
|
|
56878
|
+
handlePushedPatternMatch({
|
|
56879
|
+
ctx,
|
|
56880
|
+
directory,
|
|
56881
|
+
sessionID: frame.session_id,
|
|
56882
|
+
runtime: pi
|
|
56883
|
+
}, frame);
|
|
56682
56884
|
}
|
|
56683
56885
|
};
|
|
56684
56886
|
pool = new BridgePool(binaryPath, poolOptions, configOverrides);
|
|
@@ -56775,28 +56977,31 @@ ${lines}
|
|
|
56775
56977
|
runtime: pi
|
|
56776
56978
|
});
|
|
56777
56979
|
});
|
|
56778
|
-
|
|
56980
|
+
const unregisterShutdownCleanup = registerShutdownCleanup(async () => {
|
|
56779
56981
|
try {
|
|
56780
56982
|
await Promise.allSettled([abortInFlightAutoInstalls(), abortInFlightGithubInstalls()]);
|
|
56781
56983
|
await disposeAllPtyTerminals();
|
|
56782
56984
|
await pool.shutdown();
|
|
56783
|
-
log2("Bridge pool shut down");
|
|
56784
56985
|
} catch (err) {
|
|
56785
|
-
warn2(`Error during
|
|
56986
|
+
warn2(`Error during process shutdown: ${err instanceof Error ? err.message : String(err)}`);
|
|
56786
56987
|
}
|
|
56787
56988
|
});
|
|
56788
|
-
|
|
56989
|
+
pi.on("session_shutdown", async () => {
|
|
56789
56990
|
try {
|
|
56790
56991
|
await Promise.allSettled([abortInFlightAutoInstalls(), abortInFlightGithubInstalls()]);
|
|
56791
56992
|
await disposeAllPtyTerminals();
|
|
56792
56993
|
await pool.shutdown();
|
|
56994
|
+
log2("Bridge pool shut down");
|
|
56793
56995
|
} catch (err) {
|
|
56794
|
-
warn2(`Error during
|
|
56996
|
+
warn2(`Error during bridge shutdown: ${err instanceof Error ? err.message : String(err)}`);
|
|
56997
|
+
} finally {
|
|
56998
|
+
unregisterShutdownCleanup();
|
|
56795
56999
|
}
|
|
56796
57000
|
});
|
|
56797
57001
|
log2(`AFT extension ready (surface=${config2.tool_surface ?? "recommended"})`);
|
|
56798
57002
|
}
|
|
56799
57003
|
var __test__2 = {
|
|
57004
|
+
bridgeDirectoryFromCallback,
|
|
56800
57005
|
resolveToolSurface,
|
|
56801
57006
|
handleConfigureWarningsForSession,
|
|
56802
57007
|
shouldPrepareOnnxRuntime,
|