@cortexkit/aft-opencode 0.56.1 → 0.57.0
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 +1 -0
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/entry/server.js +2682 -282
- package/dist/index.js +448 -244
- package/dist/lsp-github-install.d.ts.map +1 -1
- package/dist/permissions/v2-service.d.ts +30 -0
- package/dist/permissions/v2-service.d.ts.map +1 -0
- package/dist/permissions/v2.d.ts +121 -9
- package/dist/permissions/v2.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/status.d.ts +8 -1
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/subc-tool-schemas.d.ts +11 -0
- package/dist/subc-tool-schemas.d.ts.map +1 -1
- package/dist/tool-registration.d.ts.map +1 -1
- package/dist/tools/definitions/v2.d.ts +6 -0
- package/dist/tools/definitions/v2.d.ts.map +1 -1
- package/dist/tools/hoisted/v2.d.ts +12 -2
- package/dist/tools/hoisted/v2.d.ts.map +1 -1
- package/dist/tools/hoisted.d.ts.map +1 -1
- package/dist/tools/semantic.d.ts.map +1 -1
- package/dist/tui/v2-status.d.ts +8 -0
- package/dist/tui/v2-status.d.ts.map +1 -1
- package/index.js +14 -0
- package/package.json +14 -10
- package/server.js +8 -0
- package/src/entry/server-runtime.mjs +11 -0
- package/src/shared/rpc-server.ts +5 -0
- package/src/shared/status.ts +16 -9
- package/src/tui/index.tsx +1 -0
- package/src/tui/sidebar-view.tsx +722 -0
- package/src/tui/sidebar.tsx +42 -560
- package/src/tui/v2-status.ts +8 -1
- package/src/tui/v2.tsx +173 -30
- package/src/tui-compiled/index.tsx +1 -1
- package/src/tui-compiled/sidebar-view.tsx +815 -0
- package/src/tui-compiled/sidebar.tsx +45 -693
- package/src/tui-compiled/v2-status.ts +8 -1
- package/src/tui-compiled/v2.tsx +163 -54
- package/tui.js +7 -0
package/dist/index.js
CHANGED
|
@@ -44,6 +44,17 @@ var __export = (target, all) => {
|
|
|
44
44
|
set: __exportSetter.bind(all, name)
|
|
45
45
|
});
|
|
46
46
|
};
|
|
47
|
+
var __esm = (fn, res, err) => () => {
|
|
48
|
+
if (fn)
|
|
49
|
+
try {
|
|
50
|
+
res = fn(fn = 0);
|
|
51
|
+
} catch (e) {
|
|
52
|
+
err = [e];
|
|
53
|
+
}
|
|
54
|
+
if (err)
|
|
55
|
+
throw err[0];
|
|
56
|
+
return res;
|
|
57
|
+
};
|
|
47
58
|
|
|
48
59
|
// ../../node_modules/.bun/esprima@4.0.1/node_modules/esprima/dist/esprima.js
|
|
49
60
|
var require_esprima = __commonJS(function(exports, module) {
|
|
@@ -8677,6 +8688,7 @@ class BinaryBridge {
|
|
|
8677
8688
|
pending = new Map;
|
|
8678
8689
|
outstandingBackgroundTaskIds = new Set;
|
|
8679
8690
|
nextId = 1;
|
|
8691
|
+
processGeneration = 0;
|
|
8680
8692
|
stdoutBuffer = "";
|
|
8681
8693
|
stdoutReadOffset = 0;
|
|
8682
8694
|
stderrBuffer = "";
|
|
@@ -8989,6 +9001,7 @@ class BinaryBridge {
|
|
|
8989
9001
|
}
|
|
8990
9002
|
}
|
|
8991
9003
|
const id = String(this.nextId++);
|
|
9004
|
+
const tool = command === "tool_call" && typeof params.name === "string" ? params.name : command;
|
|
8992
9005
|
let request;
|
|
8993
9006
|
if (command === "cancel_request" || Object.hasOwn(params, "command") || Object.hasOwn(params, "method")) {
|
|
8994
9007
|
const nested = { ...params };
|
|
@@ -9042,14 +9055,20 @@ class BinaryBridge {
|
|
|
9042
9055
|
return;
|
|
9043
9056
|
}
|
|
9044
9057
|
entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
9045
|
-
this.handleTimeout(
|
|
9058
|
+
this.handleTimeout({
|
|
9059
|
+
requestId: id,
|
|
9060
|
+
tool: entry.tool,
|
|
9061
|
+
generation: entry.generation
|
|
9062
|
+
}, requestSessionId);
|
|
9046
9063
|
}, effectiveTimeoutMs);
|
|
9047
9064
|
const entry = {
|
|
9048
9065
|
resolve,
|
|
9049
9066
|
reject,
|
|
9050
9067
|
timer,
|
|
9051
9068
|
onProgress: options?.onProgress,
|
|
9052
|
-
command
|
|
9069
|
+
command,
|
|
9070
|
+
tool,
|
|
9071
|
+
generation: this.processGeneration
|
|
9053
9072
|
};
|
|
9054
9073
|
this.pending.set(id, entry);
|
|
9055
9074
|
if (!child?.stdin?.writable) {
|
|
@@ -9352,6 +9371,7 @@ class BinaryBridge {
|
|
|
9352
9371
|
this.handleCrash();
|
|
9353
9372
|
});
|
|
9354
9373
|
this.process = child;
|
|
9374
|
+
this.processGeneration += 1;
|
|
9355
9375
|
this.spawnedBinaryFingerprint = readBinaryFingerprint(this.binaryPath);
|
|
9356
9376
|
this.lastBinaryFingerprintCheckAt = Date.now();
|
|
9357
9377
|
this.stdoutBuffer = "";
|
|
@@ -9523,10 +9543,15 @@ class BinaryBridge {
|
|
|
9523
9543
|
this.outstandingBackgroundTaskIds.add(taskId);
|
|
9524
9544
|
}
|
|
9525
9545
|
}
|
|
9526
|
-
handleTimeout(triggeringSessionId) {
|
|
9546
|
+
handleTimeout(trigger, triggeringSessionId) {
|
|
9527
9547
|
this.consecutiveRequestTimeouts = 0;
|
|
9528
9548
|
this.spawnedBinaryFingerprint = null;
|
|
9529
|
-
|
|
9549
|
+
const abortedSiblings = Array.from(this.pending, ([requestId, entry]) => ({
|
|
9550
|
+
request_id: requestId,
|
|
9551
|
+
tool: entry.tool
|
|
9552
|
+
}));
|
|
9553
|
+
const attribution = `triggering_request_id=${trigger.requestId} ` + `triggering_tool=${JSON.stringify(trigger.tool)} ` + `bridge_generation=${trigger.generation} ` + `aborted_siblings=${JSON.stringify(abortedSiblings)}`;
|
|
9554
|
+
this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} bridge killed during sibling timeout — request aborted; ${attribution}`));
|
|
9530
9555
|
this.outstandingBackgroundTaskIds.clear();
|
|
9531
9556
|
if (this.process) {
|
|
9532
9557
|
this.process.kill("SIGKILL");
|
|
@@ -9536,17 +9561,11 @@ class BinaryBridge {
|
|
|
9536
9561
|
this.configured = false;
|
|
9537
9562
|
const tail = this.formatStderrTail();
|
|
9538
9563
|
this.stderrTail = [];
|
|
9539
|
-
const killedMsg = tail ? `Bridge killed after timeout.${tail}` : `Bridge killed after timeout (see ${this.getLogFilePathVia()})`;
|
|
9540
|
-
if (
|
|
9541
|
-
|
|
9542
|
-
this.sessionErrorVia(triggeringSessionId, killedMsg);
|
|
9543
|
-
} else {
|
|
9544
|
-
this.errorVia(killedMsg);
|
|
9545
|
-
}
|
|
9546
|
-
} else if (triggeringSessionId) {
|
|
9547
|
-
this.sessionWarnVia(triggeringSessionId, killedMsg);
|
|
9564
|
+
const killedMsg = tail ? `Bridge killed after timeout; ${attribution}.${tail}` : `Bridge killed after timeout; ${attribution} (see ${this.getLogFilePathVia()})`;
|
|
9565
|
+
if (triggeringSessionId) {
|
|
9566
|
+
this.sessionErrorVia(triggeringSessionId, killedMsg);
|
|
9548
9567
|
} else {
|
|
9549
|
-
this.
|
|
9568
|
+
this.errorVia(killedMsg);
|
|
9550
9569
|
}
|
|
9551
9570
|
}
|
|
9552
9571
|
handleCrash(cause) {
|
|
@@ -15535,12 +15554,36 @@ function isNpmAvailable(deps = defaultDeps()) {
|
|
|
15535
15554
|
return resolveNpm(deps) !== null;
|
|
15536
15555
|
}
|
|
15537
15556
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
15538
|
-
import { execFileSync } from "node:child_process";
|
|
15557
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
15539
15558
|
import { createHash as createHash4 } from "node:crypto";
|
|
15540
|
-
import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as
|
|
15541
|
-
import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute5, join as
|
|
15559
|
+
import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync10, lstatSync, mkdirSync as mkdirSync5, openSync as openSync4, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync, realpathSync as realpathSync2, renameSync as renameSync5, rmSync as rmSync3, statSync as statSync6, symlinkSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
|
|
15560
|
+
import { basename as basename2, dirname as dirname5, isAbsolute as isAbsolute5, join as join13, relative as relative2, resolve as resolve7, win32 } from "node:path";
|
|
15542
15561
|
import { Readable as Readable2 } from "node:stream";
|
|
15543
15562
|
import { pipeline as pipeline2 } from "node:stream/promises";
|
|
15563
|
+
|
|
15564
|
+
// ../aft-bridge/dist/tar-executable.js
|
|
15565
|
+
import { execFileSync } from "node:child_process";
|
|
15566
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
15567
|
+
import { join as join12 } from "node:path";
|
|
15568
|
+
function windowsTarExecutable(options = {}) {
|
|
15569
|
+
const platform = options.platform ?? process.platform;
|
|
15570
|
+
if (platform !== "win32")
|
|
15571
|
+
return "tar";
|
|
15572
|
+
const env = options.env ?? process.env;
|
|
15573
|
+
const systemTar = join12(env.SystemRoot ?? "C:\\Windows", "System32", "tar.exe");
|
|
15574
|
+
return (options.exists ?? existsSync9)(systemTar) ? systemTar : "tar";
|
|
15575
|
+
}
|
|
15576
|
+
function execTarExtractionSync(args, timeout) {
|
|
15577
|
+
const executable = windowsTarExecutable();
|
|
15578
|
+
try {
|
|
15579
|
+
execFileSync(executable, args, { stdio: "pipe", timeout });
|
|
15580
|
+
} catch (cause) {
|
|
15581
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
15582
|
+
throw new Error(`tar extraction failed using ${executable}: ${detail}`, { cause });
|
|
15583
|
+
}
|
|
15584
|
+
}
|
|
15585
|
+
|
|
15586
|
+
// ../aft-bridge/dist/onnx-runtime.js
|
|
15544
15587
|
var ORT_VERSION = "1.24.4";
|
|
15545
15588
|
var ORT_REPO = "microsoft/onnxruntime";
|
|
15546
15589
|
var MAX_DOWNLOAD_BYTES2 = 256 * 1024 * 1024;
|
|
@@ -15604,11 +15647,11 @@ function getManualInstallHint() {
|
|
|
15604
15647
|
}
|
|
15605
15648
|
async function ensureOnnxRuntime(storageDir) {
|
|
15606
15649
|
const info = getPlatformInfo();
|
|
15607
|
-
const ortVersionDir =
|
|
15650
|
+
const ortVersionDir = join13(storageDir, "onnxruntime", ORT_VERSION);
|
|
15608
15651
|
const libName = info?.libName ?? "libonnxruntime.dylib";
|
|
15609
15652
|
const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
|
|
15610
|
-
const libPath =
|
|
15611
|
-
if (
|
|
15653
|
+
const libPath = join13(resolvedOrtDir, libName);
|
|
15654
|
+
if (existsSync10(libPath)) {
|
|
15612
15655
|
const meta = readOnnxInstalledMeta(ortVersionDir);
|
|
15613
15656
|
if (meta?.sha256) {
|
|
15614
15657
|
try {
|
|
@@ -15637,9 +15680,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
15637
15680
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
15638
15681
|
return null;
|
|
15639
15682
|
}
|
|
15640
|
-
const onnxBaseDir =
|
|
15683
|
+
const onnxBaseDir = join13(storageDir, "onnxruntime");
|
|
15641
15684
|
mkdirSync5(onnxBaseDir, { recursive: true });
|
|
15642
|
-
const lockPath =
|
|
15685
|
+
const lockPath = join13(onnxBaseDir, ONNX_LOCK_FILE);
|
|
15643
15686
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
15644
15687
|
if (!acquireLock(lockPath)) {
|
|
15645
15688
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -15658,7 +15701,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
15658
15701
|
for (const entry of entries) {
|
|
15659
15702
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
15660
15703
|
continue;
|
|
15661
|
-
const stagingDir =
|
|
15704
|
+
const stagingDir = join13(onnxBaseDir, entry);
|
|
15662
15705
|
const parts = entry.split(".");
|
|
15663
15706
|
const pidStr = parts[parts.length - 2];
|
|
15664
15707
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -15695,7 +15738,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
15695
15738
|
}
|
|
15696
15739
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
15697
15740
|
try {
|
|
15698
|
-
if (
|
|
15741
|
+
if (existsSync10(ortDir) && !existsSync10(join13(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
15699
15742
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
15700
15743
|
rmSync3(ortDir, { recursive: true, force: true });
|
|
15701
15744
|
}
|
|
@@ -15739,8 +15782,8 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
15739
15782
|
if (version)
|
|
15740
15783
|
return version;
|
|
15741
15784
|
}
|
|
15742
|
-
const base =
|
|
15743
|
-
if (
|
|
15785
|
+
const base = join13(libDir, libName);
|
|
15786
|
+
if (existsSync10(base)) {
|
|
15744
15787
|
try {
|
|
15745
15788
|
const real = realpathSync2(base);
|
|
15746
15789
|
const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
|
|
@@ -15806,10 +15849,10 @@ function directoryContainsLibrary(dir, libName) {
|
|
|
15806
15849
|
}
|
|
15807
15850
|
}
|
|
15808
15851
|
function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
|
|
15809
|
-
if (
|
|
15852
|
+
if (existsSync10(join13(ortVersionDir, libName)))
|
|
15810
15853
|
return ortVersionDir;
|
|
15811
|
-
const libSubdir =
|
|
15812
|
-
if (
|
|
15854
|
+
const libSubdir = join13(ortVersionDir, "lib");
|
|
15855
|
+
if (existsSync10(join13(libSubdir, libName)))
|
|
15813
15856
|
return libSubdir;
|
|
15814
15857
|
return ortVersionDir;
|
|
15815
15858
|
}
|
|
@@ -15824,13 +15867,13 @@ function findSystemOnnxRuntime(libName) {
|
|
|
15824
15867
|
} else if (process.platform === "win32") {
|
|
15825
15868
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
15826
15869
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
15827
|
-
searchPaths.push(
|
|
15870
|
+
searchPaths.push(join13(programFiles, "onnxruntime", "lib"), join13(programFiles, "Microsoft ONNX Runtime", "lib"), join13(programFiles, "Microsoft Machine Learning", "lib"), join13(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
15828
15871
|
const nugetPaths = [];
|
|
15829
15872
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
15830
15873
|
if (!userProfile)
|
|
15831
15874
|
return nugetPaths;
|
|
15832
|
-
const nugetPackageDir =
|
|
15833
|
-
if (!
|
|
15875
|
+
const nugetPackageDir = join13(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
15876
|
+
if (!existsSync10(nugetPackageDir))
|
|
15834
15877
|
return nugetPaths;
|
|
15835
15878
|
try {
|
|
15836
15879
|
for (const entry of readdirSync3(nugetPackageDir, { withFileTypes: true })) {
|
|
@@ -15838,7 +15881,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
15838
15881
|
continue;
|
|
15839
15882
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
15840
15883
|
continue;
|
|
15841
|
-
nugetPaths.push(
|
|
15884
|
+
nugetPaths.push(join13(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join13(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
15842
15885
|
}
|
|
15843
15886
|
} catch (err) {
|
|
15844
15887
|
warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -15860,11 +15903,11 @@ function findSystemOnnxRuntime(libName) {
|
|
|
15860
15903
|
});
|
|
15861
15904
|
const unknownVersionPaths = [];
|
|
15862
15905
|
for (const dir of uniquePaths) {
|
|
15863
|
-
const libPath =
|
|
15906
|
+
const libPath = join13(dir, libName);
|
|
15864
15907
|
if (process.platform === "win32") {
|
|
15865
15908
|
if (!directoryContainsLibrary(dir, libName))
|
|
15866
15909
|
continue;
|
|
15867
|
-
} else if (!
|
|
15910
|
+
} else if (!existsSync10(libPath)) {
|
|
15868
15911
|
continue;
|
|
15869
15912
|
}
|
|
15870
15913
|
const version = detectOnnxVersion(dir, libName);
|
|
@@ -15930,7 +15973,7 @@ function validateExtractedTree(stagingRoot) {
|
|
|
15930
15973
|
const walk = (dir) => {
|
|
15931
15974
|
const entries = readdirSync3(dir);
|
|
15932
15975
|
for (const entry of entries) {
|
|
15933
|
-
const fullPath =
|
|
15976
|
+
const fullPath = join13(dir, entry);
|
|
15934
15977
|
const lst = lstatSync(fullPath);
|
|
15935
15978
|
if (lst.isSymbolicLink()) {
|
|
15936
15979
|
const linkTarget = readlinkSync(fullPath);
|
|
@@ -15963,34 +16006,32 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
15963
16006
|
const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
|
|
15964
16007
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
15965
16008
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
16009
|
+
const extractionRoot = join13(tmpDir, "extract");
|
|
16010
|
+
const stagedInstallDir = join13(tmpDir, "install");
|
|
15966
16011
|
try {
|
|
15967
|
-
mkdirSync5(
|
|
15968
|
-
const archivePath =
|
|
16012
|
+
mkdirSync5(extractionRoot, { recursive: true });
|
|
16013
|
+
const archivePath = join13(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
15969
16014
|
await downloadFileWithCap(url, archivePath);
|
|
15970
16015
|
const archiveSha256 = sha256File(archivePath);
|
|
15971
16016
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
15972
16017
|
if (info.archiveType === "tgz") {
|
|
15973
|
-
|
|
15974
|
-
stdio: "pipe",
|
|
15975
|
-
timeout: 120000
|
|
15976
|
-
});
|
|
16018
|
+
execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000);
|
|
15977
16019
|
} else {
|
|
15978
|
-
await extractZipArchive(archivePath,
|
|
16020
|
+
await extractZipArchive(archivePath, extractionRoot);
|
|
15979
16021
|
}
|
|
15980
16022
|
try {
|
|
15981
16023
|
unlinkSync4(archivePath);
|
|
15982
16024
|
} catch {}
|
|
15983
|
-
validateExtractedTree(
|
|
15984
|
-
const extractedDir =
|
|
15985
|
-
if (!
|
|
16025
|
+
validateExtractedTree(extractionRoot);
|
|
16026
|
+
const extractedDir = join13(extractionRoot, info.assetName, "lib");
|
|
16027
|
+
if (!existsSync10(extractedDir)) {
|
|
15986
16028
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
15987
16029
|
}
|
|
15988
|
-
mkdirSync5(targetDir, { recursive: true });
|
|
15989
16030
|
const libFiles = readdirSync3(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
|
|
15990
16031
|
const realFiles = [];
|
|
15991
16032
|
const symlinks = [];
|
|
15992
16033
|
for (const libFile of libFiles) {
|
|
15993
|
-
const src =
|
|
16034
|
+
const src = join13(extractedDir, libFile);
|
|
15994
16035
|
try {
|
|
15995
16036
|
const stat = lstatSync(src);
|
|
15996
16037
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -16004,15 +16045,11 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
16004
16045
|
realFiles.push(libFile);
|
|
16005
16046
|
}
|
|
16006
16047
|
}
|
|
16007
|
-
copyOnnxLibraries(info, extractedDir,
|
|
16008
|
-
const libPath =
|
|
16009
|
-
|
|
16010
|
-
|
|
16011
|
-
|
|
16012
|
-
} catch (err) {
|
|
16013
|
-
warn(`Could not hash newly-installed ONNX library at ${libPath}: ${err}`);
|
|
16014
|
-
}
|
|
16015
|
-
writeOnnxInstalledMeta(targetDir, ORT_VERSION, libHash, archiveSha256);
|
|
16048
|
+
copyOnnxLibraries(info, extractedDir, stagedInstallDir, realFiles, symlinks);
|
|
16049
|
+
const libPath = join13(stagedInstallDir, info.libName);
|
|
16050
|
+
const libHash = sha256File(libPath);
|
|
16051
|
+
writeOnnxInstalledMeta(stagedInstallDir, ORT_VERSION, libHash, archiveSha256);
|
|
16052
|
+
publishOnnxRuntime(stagedInstallDir, targetDir);
|
|
16016
16053
|
rmSync3(tmpDir, { recursive: true, force: true });
|
|
16017
16054
|
log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
|
|
16018
16055
|
return targetDir;
|
|
@@ -16021,17 +16058,39 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
16021
16058
|
try {
|
|
16022
16059
|
rmSync3(tmpDir, { recursive: true, force: true });
|
|
16023
16060
|
} catch {}
|
|
16024
|
-
try {
|
|
16025
|
-
rmSync3(targetDir, { recursive: true, force: true });
|
|
16026
|
-
} catch {}
|
|
16027
16061
|
return null;
|
|
16028
16062
|
}
|
|
16029
16063
|
}
|
|
16064
|
+
function publishOnnxRuntime(stagedInstallDir, targetDir) {
|
|
16065
|
+
const backupDir = `${targetDir}.backup.${process.pid}.${Date.now().toString(36)}`;
|
|
16066
|
+
const hadTarget = existsSync10(targetDir);
|
|
16067
|
+
if (hadTarget)
|
|
16068
|
+
renameSync5(targetDir, backupDir);
|
|
16069
|
+
try {
|
|
16070
|
+
renameSync5(stagedInstallDir, targetDir);
|
|
16071
|
+
} catch (installError) {
|
|
16072
|
+
if (hadTarget) {
|
|
16073
|
+
try {
|
|
16074
|
+
renameSync5(backupDir, targetDir);
|
|
16075
|
+
} catch (restoreError) {
|
|
16076
|
+
throw new Error(`ONNX Runtime replacement failed and the previous runtime could not be restored from ${backupDir}: ${restoreError}`, { cause: installError });
|
|
16077
|
+
}
|
|
16078
|
+
}
|
|
16079
|
+
throw installError;
|
|
16080
|
+
}
|
|
16081
|
+
if (hadTarget) {
|
|
16082
|
+
try {
|
|
16083
|
+
rmSync3(backupDir, { recursive: true, force: true });
|
|
16084
|
+
} catch (err) {
|
|
16085
|
+
warn(`Could not remove replaced ONNX Runtime backup at ${backupDir}: ${err}`);
|
|
16086
|
+
}
|
|
16087
|
+
}
|
|
16088
|
+
}
|
|
16030
16089
|
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
|
|
16031
16090
|
const requiredLibs = new Set([info.libName]);
|
|
16032
16091
|
for (const libFile of realFiles) {
|
|
16033
|
-
const src =
|
|
16034
|
-
const dst =
|
|
16092
|
+
const src = join13(extractedDir, libFile);
|
|
16093
|
+
const dst = join13(targetDir, libFile);
|
|
16035
16094
|
try {
|
|
16036
16095
|
copyFile(src, dst);
|
|
16037
16096
|
if (process.platform !== "win32") {
|
|
@@ -16047,11 +16106,11 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
16047
16106
|
}
|
|
16048
16107
|
const targetRoot = realpathSync2(targetDir);
|
|
16049
16108
|
for (const link of symlinks) {
|
|
16050
|
-
const dst =
|
|
16109
|
+
const dst = join13(targetDir, link.name);
|
|
16051
16110
|
try {
|
|
16052
16111
|
unlinkSync4(dst);
|
|
16053
16112
|
} catch {}
|
|
16054
|
-
const dstForContainment =
|
|
16113
|
+
const dstForContainment = join13(targetRoot, link.name);
|
|
16055
16114
|
const resolvedTarget = resolve7(dirname5(dstForContainment), link.target);
|
|
16056
16115
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
16057
16116
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
@@ -16072,21 +16131,18 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
16072
16131
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
16073
16132
|
}
|
|
16074
16133
|
}
|
|
16075
|
-
const requiredPath =
|
|
16076
|
-
if (!
|
|
16134
|
+
const requiredPath = join13(targetDir, info.libName);
|
|
16135
|
+
if (!existsSync10(requiredPath)) {
|
|
16077
16136
|
rmSync3(targetDir, { recursive: true, force: true });
|
|
16078
16137
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
16079
16138
|
}
|
|
16080
16139
|
}
|
|
16081
16140
|
async function extractZipArchive(archivePath, destinationDir) {
|
|
16082
16141
|
if (process.platform === "win32") {
|
|
16083
|
-
|
|
16084
|
-
stdio: "pipe",
|
|
16085
|
-
timeout: 120000
|
|
16086
|
-
});
|
|
16142
|
+
execTarExtractionSync(["-xf", archivePath, "-C", destinationDir], 120000);
|
|
16087
16143
|
return;
|
|
16088
16144
|
}
|
|
16089
|
-
|
|
16145
|
+
execFileSync2("unzip", ["-q", archivePath, "-d", destinationDir], {
|
|
16090
16146
|
stdio: "pipe",
|
|
16091
16147
|
timeout: 120000
|
|
16092
16148
|
});
|
|
@@ -16099,13 +16155,13 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
16099
16155
|
...sha256 ? { sha256 } : {},
|
|
16100
16156
|
archiveSha256
|
|
16101
16157
|
};
|
|
16102
|
-
writeFileSync3(
|
|
16158
|
+
writeFileSync3(join13(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
16103
16159
|
} catch (err) {
|
|
16104
16160
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
16105
16161
|
}
|
|
16106
16162
|
}
|
|
16107
16163
|
function readOnnxInstalledMeta(installDir) {
|
|
16108
|
-
const path =
|
|
16164
|
+
const path = join13(installDir, ONNX_INSTALLED_META_FILE);
|
|
16109
16165
|
try {
|
|
16110
16166
|
if (!statSync6(path).isFile())
|
|
16111
16167
|
return null;
|
|
@@ -16217,7 +16273,7 @@ function isWindowsProcessAlive(pid) {
|
|
|
16217
16273
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
16218
16274
|
return false;
|
|
16219
16275
|
try {
|
|
16220
|
-
const output =
|
|
16276
|
+
const output = execFileSync2("tasklist.exe", ["/FI", `PID eq ${pid}`, "/FO", "CSV", "/NH"], {
|
|
16221
16277
|
encoding: "utf8",
|
|
16222
16278
|
timeout: 2000,
|
|
16223
16279
|
windowsHide: true
|
|
@@ -16438,10 +16494,8 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
|
|
|
16438
16494
|
if (unknownRootKeys.length > 0) {
|
|
16439
16495
|
throw new InvalidRequestError(formatUnknownKeys(unknownRootKeys));
|
|
16440
16496
|
}
|
|
16497
|
+
validateSymbolModePair(record);
|
|
16441
16498
|
const modes = editModesPresent(record);
|
|
16442
|
-
if (hasOrphanedSymbolContent(record)) {
|
|
16443
|
-
throw new InvalidRequestError("edit: 'content' requires a non-empty string 'symbol' when symbol mode is selected");
|
|
16444
|
-
}
|
|
16445
16499
|
if (modes.length > 1) {
|
|
16446
16500
|
throw new InvalidRequestError(`edit: conflicting modes: ${modes.join(", ")}. ${OMIT_OPTIONAL_FIELDS_STEERING}`);
|
|
16447
16501
|
}
|
|
@@ -16461,7 +16515,7 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
|
|
|
16461
16515
|
throw new InvalidRequestError("edit: 'symbol' must be a string when symbol mode is selected");
|
|
16462
16516
|
}
|
|
16463
16517
|
if (!hasOwn(record, "content") || typeof record.content !== "string") {
|
|
16464
|
-
throw new InvalidRequestError("edit: symbol mode
|
|
16518
|
+
throw new InvalidRequestError("edit: incomplete symbol mode: property 'content' must be a string. " + "Retry with `symbol` + `content`, or use `edits[]`.");
|
|
16465
16519
|
}
|
|
16466
16520
|
} else {
|
|
16467
16521
|
const item = {};
|
|
@@ -16514,6 +16568,29 @@ function validateEditPath(record) {
|
|
|
16514
16568
|
function formatUnknownKeys(keys) {
|
|
16515
16569
|
return `Unrecognized keys: ${keys.map((key) => `"${key}"`).join(", ")}`;
|
|
16516
16570
|
}
|
|
16571
|
+
function validateSymbolModePair(record) {
|
|
16572
|
+
const completeShapes = "Retry with `symbol` + `content`, or use `edits[]`.";
|
|
16573
|
+
const hasSymbol = isNonEmptyString(record.symbol);
|
|
16574
|
+
const hasContent = isNonEmptyString(record.content);
|
|
16575
|
+
if (hasSymbol) {
|
|
16576
|
+
if (!hasOwn(record, "content")) {
|
|
16577
|
+
throw new InvalidRequestError(`edit: incomplete symbol mode: missing property 'content'. ${completeShapes}`);
|
|
16578
|
+
}
|
|
16579
|
+
if (record.content === null) {
|
|
16580
|
+
throw new InvalidRequestError(`edit: incomplete symbol mode: property 'content' is null. ${completeShapes}`);
|
|
16581
|
+
}
|
|
16582
|
+
return;
|
|
16583
|
+
}
|
|
16584
|
+
if (!hasContent)
|
|
16585
|
+
return;
|
|
16586
|
+
if (!hasOwn(record, "symbol")) {
|
|
16587
|
+
throw new InvalidRequestError(`edit: incomplete symbol mode: missing property 'symbol'. ${completeShapes}`);
|
|
16588
|
+
}
|
|
16589
|
+
if (record.symbol === null) {
|
|
16590
|
+
throw new InvalidRequestError(`edit: incomplete symbol mode: property 'symbol' is null. ${completeShapes}`);
|
|
16591
|
+
}
|
|
16592
|
+
throw new InvalidRequestError(`edit: incomplete symbol mode: property 'symbol' must be a non-empty string. ${completeShapes}`);
|
|
16593
|
+
}
|
|
16517
16594
|
function editModesPresent(record) {
|
|
16518
16595
|
const hasAppendContent = isNonEmptyString(record.appendContent);
|
|
16519
16596
|
if (!hasAppendContent)
|
|
@@ -16599,9 +16676,6 @@ function normalizeEditArraySentinels(record) {
|
|
|
16599
16676
|
return true;
|
|
16600
16677
|
}
|
|
16601
16678
|
}
|
|
16602
|
-
function hasOrphanedSymbolContent(record) {
|
|
16603
|
-
return isNonEmptyString(record.content) && !isNonEmptyString(record.symbol);
|
|
16604
|
-
}
|
|
16605
16679
|
function parseEditArray(value) {
|
|
16606
16680
|
if (typeof value === "string") {
|
|
16607
16681
|
let parsed;
|
|
@@ -16784,8 +16858,50 @@ function copyOwnProperties(source) {
|
|
|
16784
16858
|
copy[key] = source[key];
|
|
16785
16859
|
return copy;
|
|
16786
16860
|
}
|
|
16861
|
+
// ../aft-bridge/dist/semantic-status.js
|
|
16862
|
+
var MISSING_ONNX_RUNTIME_MARKER = "ONNX Runtime not found.";
|
|
16863
|
+
var MISSING_ONNX_RUNTIME_LABEL = "unavailable — ONNX Runtime missing (npx @cortexkit/aft doctor --fix)";
|
|
16864
|
+
var REBUILDING_LABEL = "Rebuilding (model changed)";
|
|
16865
|
+
var SEMANTIC_PROGRESS_STATUSES = new Set(["building", "loading"]);
|
|
16866
|
+
var SEMANTIC_READY_STATUSES = new Set(["ready", "empty"]);
|
|
16867
|
+
var SEMANTIC_INACTIVE_STATUSES = new Set(["disabled", "busy"]);
|
|
16868
|
+
var SEMANTIC_FAILURE_LABELS = {
|
|
16869
|
+
backend_unavailable: "backend unavailable",
|
|
16870
|
+
degraded: "degraded",
|
|
16871
|
+
error: "error",
|
|
16872
|
+
failed: "failed",
|
|
16873
|
+
unavailable: "unavailable"
|
|
16874
|
+
};
|
|
16875
|
+
function semanticIndexStatusKind(status) {
|
|
16876
|
+
if (SEMANTIC_READY_STATUSES.has(status))
|
|
16877
|
+
return "ready";
|
|
16878
|
+
if (SEMANTIC_PROGRESS_STATUSES.has(status))
|
|
16879
|
+
return "progress";
|
|
16880
|
+
if (status in SEMANTIC_FAILURE_LABELS)
|
|
16881
|
+
return "failure";
|
|
16882
|
+
if (SEMANTIC_INACTIVE_STATUSES.has(status))
|
|
16883
|
+
return "inactive";
|
|
16884
|
+
return "unrecognized";
|
|
16885
|
+
}
|
|
16886
|
+
function mentionsMissingOnnxRuntime(...values) {
|
|
16887
|
+
return values.some((value) => typeof value === "string" && value.includes(MISSING_ONNX_RUNTIME_MARKER));
|
|
16888
|
+
}
|
|
16889
|
+
function semanticFailureLabel(status, stage, error) {
|
|
16890
|
+
if (mentionsMissingOnnxRuntime(error, stage))
|
|
16891
|
+
return MISSING_ONNX_RUNTIME_LABEL;
|
|
16892
|
+
return SEMANTIC_FAILURE_LABELS[status] ?? null;
|
|
16893
|
+
}
|
|
16894
|
+
function formatSemanticIndexStatus(status, stage, error) {
|
|
16895
|
+
const failure = semanticFailureLabel(status, stage, error);
|
|
16896
|
+
if (failure)
|
|
16897
|
+
return failure;
|
|
16898
|
+
if (semanticIndexStatusKind(status) === "progress" && stage === "fingerprint_change") {
|
|
16899
|
+
return REBUILDING_LABEL;
|
|
16900
|
+
}
|
|
16901
|
+
return status;
|
|
16902
|
+
}
|
|
16787
16903
|
// src/config.ts
|
|
16788
|
-
import { existsSync as
|
|
16904
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
16789
16905
|
import { homedir as homedir10 } from "node:os";
|
|
16790
16906
|
import { isAbsolute as isAbsolute6, parse as parsePath, resolve as resolvePath } from "node:path";
|
|
16791
16907
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
@@ -21492,6 +21608,9 @@ function write(level, message, data, sessionId) {
|
|
|
21492
21608
|
function log2(message, data) {
|
|
21493
21609
|
write("INFO", message, data);
|
|
21494
21610
|
}
|
|
21611
|
+
function debug2(message, data) {
|
|
21612
|
+
write("DEBUG", message, data);
|
|
21613
|
+
}
|
|
21495
21614
|
function warn2(message, data) {
|
|
21496
21615
|
write("WARN", message, data);
|
|
21497
21616
|
}
|
|
@@ -21690,6 +21809,7 @@ var InspectConfigSchema = object({
|
|
|
21690
21809
|
enabled: boolean2().optional(),
|
|
21691
21810
|
diagnostics_timeout_ms: number2().int().positive().optional().transform((value) => value === undefined ? undefined : clampInspectDiagnosticsTimeoutMs(value)),
|
|
21692
21811
|
tier2_idle_minutes: number2().min(0).optional(),
|
|
21812
|
+
tier2_pass_timeout_ms: number2().int().positive().optional(),
|
|
21693
21813
|
categories: record(string2(), boolean2()).optional(),
|
|
21694
21814
|
tier2_soft_deadline_ms: number2().int().positive().optional(),
|
|
21695
21815
|
max_drill_down_items: number2().int().positive().max(100).optional(),
|
|
@@ -22012,7 +22132,7 @@ function migrateExperimentalBashBlock(rawConfig, configPath, logger) {
|
|
|
22012
22132
|
return movedKeys;
|
|
22013
22133
|
}
|
|
22014
22134
|
function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 }) {
|
|
22015
|
-
if (!
|
|
22135
|
+
if (!existsSync11(configPath)) {
|
|
22016
22136
|
return { migrated: false, oldKeys: [] };
|
|
22017
22137
|
}
|
|
22018
22138
|
let tmpPath = null;
|
|
@@ -22036,7 +22156,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
|
|
|
22036
22156
|
${serialized}` : serialized;
|
|
22037
22157
|
tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
22038
22158
|
writeFileSync4(tmpPath, nextContent, "utf-8");
|
|
22039
|
-
|
|
22159
|
+
renameSync6(tmpPath, configPath);
|
|
22040
22160
|
logger.log(`Migrated config at ${configPath}: removed ${oldKeys.join(", ")}`);
|
|
22041
22161
|
return { migrated: true, oldKeys };
|
|
22042
22162
|
} catch (err) {
|
|
@@ -22097,7 +22217,7 @@ function recordConfigParseFailure(configPath, errorMessage) {
|
|
|
22097
22217
|
}
|
|
22098
22218
|
function loadConfigFromPath(configPath) {
|
|
22099
22219
|
try {
|
|
22100
|
-
if (!
|
|
22220
|
+
if (!existsSync11(configPath)) {
|
|
22101
22221
|
return null;
|
|
22102
22222
|
}
|
|
22103
22223
|
const content = readFileSync7(configPath, "utf-8");
|
|
@@ -22437,7 +22557,7 @@ function loadAftConfig(projectDirectory) {
|
|
|
22437
22557
|
}
|
|
22438
22558
|
|
|
22439
22559
|
// src/tools/_shared.ts
|
|
22440
|
-
import { existsSync as
|
|
22560
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
22441
22561
|
import * as os2 from "node:os";
|
|
22442
22562
|
import * as path2 from "node:path";
|
|
22443
22563
|
|
|
@@ -34850,6 +34970,7 @@ var DEBOUNCE_STEP_MS = 200;
|
|
|
34850
34970
|
var DEBOUNCE_CAP_MS = 1000;
|
|
34851
34971
|
var MAX_WAKE_SEND_ATTEMPTS = 5;
|
|
34852
34972
|
var DEFAULT_WAKE_CONFIRMATION_WINDOW_MS = 5000;
|
|
34973
|
+
var BUSY_WAKE_DEFER_CEILING_MS = 60000;
|
|
34853
34974
|
var UNKNOWN_COMPLETION_TTL_MS = 5000;
|
|
34854
34975
|
var UNKNOWN_COMPLETION_CAP = 32;
|
|
34855
34976
|
var DEFAULT_SESSION_ID2 = "__default__";
|
|
@@ -34881,10 +35002,12 @@ function logDroppedForeignSessionFrame(drainContext, droppedSessionId, liveSessi
|
|
|
34881
35002
|
var DEFAULT_BG_HOP_TIMEOUT_MS = 15000;
|
|
34882
35003
|
var bgHopTimeoutMs = DEFAULT_BG_HOP_TIMEOUT_MS;
|
|
34883
35004
|
var wakeConfirmationWindowMs = DEFAULT_WAKE_CONFIRMATION_WINDOW_MS;
|
|
35005
|
+
var busyWakeDeferCeilingMs = BUSY_WAKE_DEFER_CEILING_MS;
|
|
34884
35006
|
var lastWakeMessageTimestamp = 0;
|
|
34885
35007
|
var wakeMessageCounter = 0;
|
|
34886
35008
|
var subcNudgesInFlight = new Map;
|
|
34887
35009
|
var subcNudgeLogState = new Map;
|
|
35010
|
+
var deferredBusyWakes = new Map;
|
|
34888
35011
|
function consumeBgCompletion(sessionID, taskId) {
|
|
34889
35012
|
const state = stateFor(sessionID);
|
|
34890
35013
|
state.pendingCompletions = state.pendingCompletions.filter((c) => c.task_id !== taskId);
|
|
@@ -34899,6 +35022,9 @@ function consumeBgCompletion(sessionID, taskId) {
|
|
|
34899
35022
|
}
|
|
34900
35023
|
}
|
|
34901
35024
|
clearWakeTimerIfNoPending(state);
|
|
35025
|
+
if (state.pendingCompletions.length === 0 && state.pendingLongRunning.length === 0 && state.pendingPatternMatches.length === 0) {
|
|
35026
|
+
clearDeferredBusyWake(sessionID || DEFAULT_SESSION_ID2);
|
|
35027
|
+
}
|
|
34902
35028
|
}
|
|
34903
35029
|
async function markBgCompletionDelivered(drainContext, taskId) {
|
|
34904
35030
|
const state = stateFor(drainContext.sessionID);
|
|
@@ -35004,7 +35130,7 @@ async function handlePushedPatternMatch(drainContext, frame) {
|
|
|
35004
35130
|
}
|
|
35005
35131
|
const state = stateFor(drainContext.sessionID);
|
|
35006
35132
|
queuePendingPatternMatch(state, { ...frame, ackCompletionOnDelivery: true });
|
|
35007
|
-
await triggerWakeIfPending(drainContext, true);
|
|
35133
|
+
await triggerWakeIfPending(drainContext, true, true, false, true);
|
|
35008
35134
|
}
|
|
35009
35135
|
function ingestBgCompletions(sessionID, completions) {
|
|
35010
35136
|
if (!Array.isArray(completions) || completions.length === 0)
|
|
@@ -35042,11 +35168,11 @@ function ingestBgCompletions(sessionID, completions) {
|
|
|
35042
35168
|
}
|
|
35043
35169
|
async function handlePushedBgCompletion(drainContext, completion) {
|
|
35044
35170
|
ingestBgCompletions(drainContext.sessionID, [completion]);
|
|
35045
|
-
await triggerWakeIfPending(drainContext, true, false);
|
|
35171
|
+
await triggerWakeIfPending(drainContext, true, false, false, true);
|
|
35046
35172
|
}
|
|
35047
35173
|
async function handlePushedBgLongRunning(drainContext, reminder) {
|
|
35048
35174
|
stateFor(drainContext.sessionID).pendingLongRunning.push(reminder);
|
|
35049
|
-
await triggerWakeIfPending(drainContext, true);
|
|
35175
|
+
await triggerWakeIfPending(drainContext, true, true, false, true);
|
|
35050
35176
|
}
|
|
35051
35177
|
async function appendInTurnBgCompletions(drainContext, output) {
|
|
35052
35178
|
if (!output)
|
|
@@ -35091,6 +35217,7 @@ async function appendInTurnBgCompletions(drainContext, output) {
|
|
|
35091
35217
|
if (inTurnAcked)
|
|
35092
35218
|
confirmAcked(state, inTurnAckIds);
|
|
35093
35219
|
clearWakeTimerIfNoPending(state);
|
|
35220
|
+
clearDeferredBusyWake(drainContext.sessionID);
|
|
35094
35221
|
}
|
|
35095
35222
|
async function handleIdleBgCompletions(drainContext) {
|
|
35096
35223
|
stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
|
|
@@ -35118,7 +35245,7 @@ async function handleSubcBgEventsNudgeOnce(drainContext) {
|
|
|
35118
35245
|
const state = stateFor(drainContext.sessionID);
|
|
35119
35246
|
state.wakeDeferredTaskIds.clear();
|
|
35120
35247
|
rearmHardStoppedWake(state, drainContext);
|
|
35121
|
-
await triggerWakeIfPending(drainContext, false, true, true);
|
|
35248
|
+
await triggerWakeIfPending(drainContext, false, true, true, true);
|
|
35122
35249
|
}
|
|
35123
35250
|
function logSubcNudgeLifecycle(drainContext, kind, message) {
|
|
35124
35251
|
logDeliveryHop(drainContext, kind, message, {
|
|
@@ -35333,6 +35460,42 @@ function registerWakeAdmission(state, admission) {
|
|
|
35333
35460
|
}, wakeConfirmationWindowMs);
|
|
35334
35461
|
tracked.confirmationTimer.unref?.();
|
|
35335
35462
|
}
|
|
35463
|
+
function clearDeferredBusyWake(sessionID) {
|
|
35464
|
+
const deferred = deferredBusyWakes.get(sessionID);
|
|
35465
|
+
if (!deferred)
|
|
35466
|
+
return;
|
|
35467
|
+
deferredBusyWakes.delete(sessionID);
|
|
35468
|
+
clearTimeout(deferred.timer);
|
|
35469
|
+
return deferred;
|
|
35470
|
+
}
|
|
35471
|
+
function deferBusyWake(drainContext) {
|
|
35472
|
+
const existing = deferredBusyWakes.get(drainContext.sessionID);
|
|
35473
|
+
if (existing) {
|
|
35474
|
+
existing.context = drainContext;
|
|
35475
|
+
return;
|
|
35476
|
+
}
|
|
35477
|
+
const deferredAt = Date.now();
|
|
35478
|
+
const deferred = {
|
|
35479
|
+
context: drainContext,
|
|
35480
|
+
deferredAt,
|
|
35481
|
+
timer: setTimeout(() => {
|
|
35482
|
+
if (deferredBusyWakes.get(drainContext.sessionID) !== deferred)
|
|
35483
|
+
return;
|
|
35484
|
+
deferredBusyWakes.delete(drainContext.sessionID);
|
|
35485
|
+
const waitMs = Math.max(0, Date.now() - deferredAt);
|
|
35486
|
+
sessionLog(drainContext.sessionID, `${LOG_PREFIX} busy wake defer ceiling reached`, {
|
|
35487
|
+
event: "bash_completion_wake_deferred_ceiling",
|
|
35488
|
+
wait_ms: waitMs,
|
|
35489
|
+
ceiling_ms: busyWakeDeferCeilingMs
|
|
35490
|
+
});
|
|
35491
|
+
triggerWakeIfPending(deferred.context, true).catch(() => {
|
|
35492
|
+
return;
|
|
35493
|
+
});
|
|
35494
|
+
}, busyWakeDeferCeilingMs)
|
|
35495
|
+
};
|
|
35496
|
+
deferred.timer.unref?.();
|
|
35497
|
+
deferredBusyWakes.set(drainContext.sessionID, deferred);
|
|
35498
|
+
}
|
|
35336
35499
|
function observeOpenCodeBgNotificationEvent(event) {
|
|
35337
35500
|
try {
|
|
35338
35501
|
if (!event || typeof event !== "object")
|
|
@@ -35381,12 +35544,17 @@ function observeOpenCodeBgNotificationEvent(event) {
|
|
|
35381
35544
|
return;
|
|
35382
35545
|
}
|
|
35383
35546
|
if (nextStatus === "idle") {
|
|
35547
|
+
const deferred = clearDeferredBusyWake(sessionID);
|
|
35548
|
+
if (deferred)
|
|
35549
|
+
triggerWakeIfPending(deferred.context, true).catch(() => {
|
|
35550
|
+
return;
|
|
35551
|
+
});
|
|
35384
35552
|
for (const admission of state.wakeAdmissions.values())
|
|
35385
35553
|
queueWakeRefire(state, admission);
|
|
35386
35554
|
}
|
|
35387
35555
|
} catch {}
|
|
35388
35556
|
}
|
|
35389
|
-
async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false) {
|
|
35557
|
+
async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false, deferWhileBusy = false) {
|
|
35390
35558
|
const state = stateFor(drainContext.sessionID);
|
|
35391
35559
|
if (!skipDrain && (forceDrain || state.outstandingTaskIds.size > 0 || !state.forcedDrainCompleted)) {
|
|
35392
35560
|
await drainCompletions(drainContext);
|
|
@@ -35394,6 +35562,10 @@ async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredComp
|
|
|
35394
35562
|
routeExplicitControlCompletions(state);
|
|
35395
35563
|
if (!hasWakeEligiblePending(state, includeDeferredCompletions))
|
|
35396
35564
|
return;
|
|
35565
|
+
if (deferWhileBusy && state.hostStatus === "busy") {
|
|
35566
|
+
deferBusyWake(drainContext);
|
|
35567
|
+
return;
|
|
35568
|
+
}
|
|
35397
35569
|
scheduleWake(state, async (reminder, deliveredCompletions, deliveredPatternMatches) => {
|
|
35398
35570
|
const liveSession = getActiveSessionId() ?? drainContext.sessionID;
|
|
35399
35571
|
if (liveSession && drainContext.sessionID && drainContext.sessionID !== liveSession) {
|
|
@@ -36235,7 +36407,7 @@ function bridgeFor(ctx, runtime) {
|
|
|
36235
36407
|
if (ctx.isProjectEnabled?.(projectRoot) === false) {
|
|
36236
36408
|
throw new Error(`AFT disabled by config for ${projectRoot}`);
|
|
36237
36409
|
}
|
|
36238
|
-
if (!
|
|
36410
|
+
if (!existsSync12(projectRoot)) {
|
|
36239
36411
|
throw new Error(`project directory no longer exists: ${projectRoot} (stale restored session?)`);
|
|
36240
36412
|
}
|
|
36241
36413
|
return ctx.pool.getBridge(projectRoot);
|
|
@@ -36392,9 +36564,9 @@ async function signalBashWaitDetachForProject(pool, projectRoot, sessionID) {
|
|
|
36392
36564
|
}
|
|
36393
36565
|
|
|
36394
36566
|
// src/notifications.ts
|
|
36395
|
-
import { existsSync as
|
|
36567
|
+
import { existsSync as existsSync13, readFileSync as readFileSync8 } from "node:fs";
|
|
36396
36568
|
import { homedir as homedir12, platform } from "node:os";
|
|
36397
|
-
import { join as
|
|
36569
|
+
import { join as join14 } from "node:path";
|
|
36398
36570
|
function isTuiMode() {
|
|
36399
36571
|
return process.env.OPENCODE_CLIENT === "cli";
|
|
36400
36572
|
}
|
|
@@ -36416,21 +36588,21 @@ function getDesktopStatePath() {
|
|
|
36416
36588
|
const os = platform();
|
|
36417
36589
|
const home = homedir12();
|
|
36418
36590
|
if (os === "darwin") {
|
|
36419
|
-
return
|
|
36591
|
+
return join14(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
|
|
36420
36592
|
}
|
|
36421
36593
|
if (os === "linux") {
|
|
36422
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
36423
|
-
return
|
|
36594
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join14(home, ".config");
|
|
36595
|
+
return join14(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
|
|
36424
36596
|
}
|
|
36425
36597
|
if (os === "win32") {
|
|
36426
|
-
const appData = process.env.APPDATA ||
|
|
36427
|
-
return
|
|
36598
|
+
const appData = process.env.APPDATA || join14(home, "AppData", "Roaming");
|
|
36599
|
+
return join14(appData, "ai.opencode.desktop", "opencode.global.dat");
|
|
36428
36600
|
}
|
|
36429
36601
|
return null;
|
|
36430
36602
|
}
|
|
36431
36603
|
function readDesktopState() {
|
|
36432
36604
|
const statePath = getDesktopStatePath();
|
|
36433
|
-
if (!statePath || !
|
|
36605
|
+
if (!statePath || !existsSync13(statePath)) {
|
|
36434
36606
|
return { serverUrl: null };
|
|
36435
36607
|
}
|
|
36436
36608
|
try {
|
|
@@ -36930,11 +37102,11 @@ async function flushConfigureWarningsOnIdle(sessionId) {
|
|
|
36930
37102
|
// src/hooks/auto-update-checker/index.ts
|
|
36931
37103
|
import {
|
|
36932
37104
|
closeSync as closeSync5,
|
|
36933
|
-
existsSync as
|
|
37105
|
+
existsSync as existsSync16,
|
|
36934
37106
|
mkdirSync as mkdirSync6,
|
|
36935
37107
|
openSync as openSync5,
|
|
36936
37108
|
readFileSync as readFileSync11,
|
|
36937
|
-
renameSync as
|
|
37109
|
+
renameSync as renameSync7,
|
|
36938
37110
|
rmSync as rmSync5,
|
|
36939
37111
|
statSync as statSync8,
|
|
36940
37112
|
writeFileSync as writeFileSync7
|
|
@@ -36943,30 +37115,30 @@ import { dirname as dirname8 } from "node:path";
|
|
|
36943
37115
|
|
|
36944
37116
|
// src/hooks/auto-update-checker/cache.ts
|
|
36945
37117
|
import { spawn as spawn4 } from "node:child_process";
|
|
36946
|
-
import { cpSync, existsSync as
|
|
37118
|
+
import { cpSync, existsSync as existsSync15, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
36947
37119
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
36948
|
-
import { basename as basename3, dirname as dirname7, join as
|
|
37120
|
+
import { basename as basename3, dirname as dirname7, join as join17 } from "node:path";
|
|
36949
37121
|
var import_comment_json3 = __toESM(require_src2(), 1);
|
|
36950
37122
|
|
|
36951
37123
|
// src/hooks/auto-update-checker/checker.ts
|
|
36952
|
-
import { existsSync as
|
|
36953
|
-
import { dirname as dirname6, isAbsolute as isAbsolute8, join as
|
|
37124
|
+
import { existsSync as existsSync14, readFileSync as readFileSync9, statSync as statSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
37125
|
+
import { dirname as dirname6, isAbsolute as isAbsolute8, join as join16, resolve as resolve9 } from "node:path";
|
|
36954
37126
|
import { fileURLToPath } from "node:url";
|
|
36955
37127
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
36956
37128
|
|
|
36957
37129
|
// src/hooks/auto-update-checker/constants.ts
|
|
36958
|
-
import { join as
|
|
37130
|
+
import { join as join15 } from "node:path";
|
|
36959
37131
|
var PACKAGE_NAME = "@cortexkit/aft-opencode";
|
|
36960
37132
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
36961
37133
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
36962
37134
|
function cacheDir() {
|
|
36963
|
-
return
|
|
37135
|
+
return join15(getOpenCodeCacheRoot(), "packages");
|
|
36964
37136
|
}
|
|
36965
37137
|
function userOpenCodeConfig() {
|
|
36966
|
-
return
|
|
37138
|
+
return join15(getOpenCodeConfigRoot(), "opencode.json");
|
|
36967
37139
|
}
|
|
36968
37140
|
function userOpenCodeConfigJsonc() {
|
|
36969
|
-
return
|
|
37141
|
+
return join15(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
36970
37142
|
}
|
|
36971
37143
|
|
|
36972
37144
|
// src/hooks/auto-update-checker/types.ts
|
|
@@ -37025,8 +37197,8 @@ function extractChannel(version) {
|
|
|
37025
37197
|
}
|
|
37026
37198
|
function getConfigPaths(directory) {
|
|
37027
37199
|
return [
|
|
37028
|
-
|
|
37029
|
-
|
|
37200
|
+
join16(directory, ".opencode", "opencode.json"),
|
|
37201
|
+
join16(directory, ".opencode", "opencode.jsonc"),
|
|
37030
37202
|
userOpenCodeConfig(),
|
|
37031
37203
|
userOpenCodeConfigJsonc()
|
|
37032
37204
|
];
|
|
@@ -37046,7 +37218,7 @@ function resolvePathPluginSpec(spec, configPath) {
|
|
|
37046
37218
|
function getLocalDevPath(directory) {
|
|
37047
37219
|
for (const configPath of getConfigPaths(directory)) {
|
|
37048
37220
|
try {
|
|
37049
|
-
if (!
|
|
37221
|
+
if (!existsSync14(configPath))
|
|
37050
37222
|
continue;
|
|
37051
37223
|
const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
|
|
37052
37224
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -37072,8 +37244,8 @@ function findPackageJsonUp(startPath) {
|
|
|
37072
37244
|
const stat = statSync7(startPath);
|
|
37073
37245
|
let dir = stat.isDirectory() ? startPath : dirname6(startPath);
|
|
37074
37246
|
for (let i = 0;i < 10; i++) {
|
|
37075
|
-
const pkgPath =
|
|
37076
|
-
if (
|
|
37247
|
+
const pkgPath = join16(dir, "package.json");
|
|
37248
|
+
if (existsSync14(pkgPath)) {
|
|
37077
37249
|
try {
|
|
37078
37250
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
|
|
37079
37251
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
@@ -37113,7 +37285,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
|
37113
37285
|
function findPluginEntry(directory) {
|
|
37114
37286
|
for (const configPath of getConfigPaths(directory)) {
|
|
37115
37287
|
try {
|
|
37116
|
-
if (!
|
|
37288
|
+
if (!existsSync14(configPath))
|
|
37117
37289
|
continue;
|
|
37118
37290
|
const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
|
|
37119
37291
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -37133,7 +37305,7 @@ function findPluginEntry(directory) {
|
|
|
37133
37305
|
}
|
|
37134
37306
|
var cachedPackageVersion = null;
|
|
37135
37307
|
function getSpecCachePackageJsonPath(spec) {
|
|
37136
|
-
return
|
|
37308
|
+
return join16(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
|
|
37137
37309
|
}
|
|
37138
37310
|
function getCachedVersion(spec) {
|
|
37139
37311
|
if (!spec && cachedPackageVersion)
|
|
@@ -37142,11 +37314,11 @@ function getCachedVersion(spec) {
|
|
|
37142
37314
|
getCurrentRuntimePackageJsonPath(),
|
|
37143
37315
|
spec ? getSpecCachePackageJsonPath(spec) : null,
|
|
37144
37316
|
getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
|
|
37145
|
-
|
|
37317
|
+
join16(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
|
|
37146
37318
|
].filter(isString);
|
|
37147
37319
|
for (const packageJsonPath of candidates) {
|
|
37148
37320
|
try {
|
|
37149
|
-
if (!
|
|
37321
|
+
if (!existsSync14(packageJsonPath))
|
|
37150
37322
|
continue;
|
|
37151
37323
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(packageJsonPath, "utf-8")));
|
|
37152
37324
|
if (pkg.success && pkg.data.version) {
|
|
@@ -37191,17 +37363,17 @@ async function getLatestVersion(channel = "latest", options = {}) {
|
|
|
37191
37363
|
var pendingSnapshots = new Map;
|
|
37192
37364
|
var quarantinedInstallDirs = new Set;
|
|
37193
37365
|
function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
|
|
37194
|
-
const packageDir =
|
|
37195
|
-
const lockfilePath =
|
|
37196
|
-
const tempDir = mkdtempSync(
|
|
37197
|
-
const stagedPackageDir =
|
|
37366
|
+
const packageDir = join17(installDir, "node_modules", packageName);
|
|
37367
|
+
const lockfilePath = join17(installDir, "package-lock.json");
|
|
37368
|
+
const tempDir = mkdtempSync(join17(tmpdir2(), "aft-auto-update-"));
|
|
37369
|
+
const stagedPackageDir = existsSync15(packageDir) ? join17(tempDir, "package") : null;
|
|
37198
37370
|
if (stagedPackageDir)
|
|
37199
37371
|
cpSync(packageDir, stagedPackageDir, { recursive: true });
|
|
37200
37372
|
return {
|
|
37201
37373
|
packageJsonPath,
|
|
37202
|
-
packageJson:
|
|
37374
|
+
packageJson: existsSync15(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
|
|
37203
37375
|
lockfilePath,
|
|
37204
|
-
lockfile:
|
|
37376
|
+
lockfile: existsSync15(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
|
|
37205
37377
|
packageDir,
|
|
37206
37378
|
stagedPackageDir,
|
|
37207
37379
|
tempDir
|
|
@@ -37235,8 +37407,8 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
37235
37407
|
return current;
|
|
37236
37408
|
}
|
|
37237
37409
|
function removeFromPackageLock(installDir, packageName) {
|
|
37238
|
-
const lockPath =
|
|
37239
|
-
if (!
|
|
37410
|
+
const lockPath = join17(installDir, "package-lock.json");
|
|
37411
|
+
if (!existsSync15(lockPath))
|
|
37240
37412
|
return false;
|
|
37241
37413
|
try {
|
|
37242
37414
|
const lock = import_comment_json3.parse(readFileSync10(lockPath, "utf-8"));
|
|
@@ -37262,7 +37434,7 @@ function removeFromPackageLock(installDir, packageName) {
|
|
|
37262
37434
|
}
|
|
37263
37435
|
}
|
|
37264
37436
|
function ensureDependencyVersion(packageJsonPath, packageName, version) {
|
|
37265
|
-
if (!
|
|
37437
|
+
if (!existsSync15(packageJsonPath))
|
|
37266
37438
|
return false;
|
|
37267
37439
|
try {
|
|
37268
37440
|
const raw = import_comment_json3.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
@@ -37291,8 +37463,8 @@ function restorePendingSnapshot(installDir) {
|
|
|
37291
37463
|
restoreAutoUpdateSnapshot(snapshot);
|
|
37292
37464
|
}
|
|
37293
37465
|
function removeInstalledPackage(installDir, packageName) {
|
|
37294
|
-
const packageDir =
|
|
37295
|
-
if (!
|
|
37466
|
+
const packageDir = join17(installDir, "node_modules", packageName);
|
|
37467
|
+
if (!existsSync15(packageDir))
|
|
37296
37468
|
return false;
|
|
37297
37469
|
rmSync4(packageDir, { recursive: true, force: true });
|
|
37298
37470
|
log2(`[auto-update-checker] Package removed: ${packageDir}`);
|
|
@@ -37304,15 +37476,15 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
|
|
|
37304
37476
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
37305
37477
|
if (nodeModulesDir && basename3(nodeModulesDir) === "node_modules") {
|
|
37306
37478
|
const installDir = dirname7(nodeModulesDir);
|
|
37307
|
-
const packageJsonPath =
|
|
37308
|
-
if (
|
|
37479
|
+
const packageJsonPath = join17(installDir, "package.json");
|
|
37480
|
+
if (existsSync15(packageJsonPath))
|
|
37309
37481
|
return { installDir, packageJsonPath };
|
|
37310
37482
|
}
|
|
37311
37483
|
return null;
|
|
37312
37484
|
}
|
|
37313
37485
|
const cacheRoot = dirname7(cacheDir());
|
|
37314
|
-
const legacyPackageJsonPath =
|
|
37315
|
-
if (
|
|
37486
|
+
const legacyPackageJsonPath = join17(cacheRoot, "package.json");
|
|
37487
|
+
if (existsSync15(legacyPackageJsonPath)) {
|
|
37316
37488
|
return { installDir: cacheRoot, packageJsonPath: legacyPackageJsonPath };
|
|
37317
37489
|
}
|
|
37318
37490
|
return null;
|
|
@@ -37535,7 +37707,7 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
37535
37707
|
const replacementPath = `${lockPath}.tmp.${process.pid}`;
|
|
37536
37708
|
writeFileSync7(replacementPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
37537
37709
|
try {
|
|
37538
|
-
|
|
37710
|
+
renameSync7(replacementPath, lockPath);
|
|
37539
37711
|
} catch (replaceError) {
|
|
37540
37712
|
rmSync5(replacementPath, { force: true });
|
|
37541
37713
|
throw replaceError;
|
|
@@ -37603,7 +37775,7 @@ function checkLockIsOwnedBy(lockPath, owner) {
|
|
|
37603
37775
|
}
|
|
37604
37776
|
}
|
|
37605
37777
|
function hasRecentCheckTimestamp(file, intervalMs) {
|
|
37606
|
-
if (!
|
|
37778
|
+
if (!existsSync16(file))
|
|
37607
37779
|
return false;
|
|
37608
37780
|
try {
|
|
37609
37781
|
const raw = JSON.parse(readFileSync11(file, "utf-8"));
|
|
@@ -37616,7 +37788,7 @@ function hasRecentCheckTimestamp(file, intervalMs) {
|
|
|
37616
37788
|
function writeCheckTimestamp(file) {
|
|
37617
37789
|
const tmp = `${file}.tmp.${process.pid}`;
|
|
37618
37790
|
writeFileSync7(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
|
|
37619
|
-
|
|
37791
|
+
renameSync7(tmp, file);
|
|
37620
37792
|
}
|
|
37621
37793
|
async function runStartupCheck(ctx, options) {
|
|
37622
37794
|
if (options.signal.aborted)
|
|
@@ -37713,15 +37885,15 @@ import { spawn as spawn5 } from "node:child_process";
|
|
|
37713
37885
|
import { createHash as createHash6 } from "node:crypto";
|
|
37714
37886
|
import {
|
|
37715
37887
|
createReadStream,
|
|
37716
|
-
existsSync as
|
|
37888
|
+
existsSync as existsSync18,
|
|
37717
37889
|
mkdirSync as mkdirSync8,
|
|
37718
37890
|
readFileSync as readFileSync14,
|
|
37719
|
-
renameSync as
|
|
37891
|
+
renameSync as renameSync9,
|
|
37720
37892
|
rmSync as rmSync7,
|
|
37721
37893
|
statSync as statSync10,
|
|
37722
37894
|
writeFileSync as writeFileSync9
|
|
37723
37895
|
} from "node:fs";
|
|
37724
|
-
import { join as
|
|
37896
|
+
import { join as join20 } from "node:path";
|
|
37725
37897
|
|
|
37726
37898
|
// src/lsp-cache.ts
|
|
37727
37899
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
@@ -37730,13 +37902,13 @@ import {
|
|
|
37730
37902
|
mkdirSync as mkdirSync7,
|
|
37731
37903
|
openSync as openSync6,
|
|
37732
37904
|
readFileSync as readFileSync12,
|
|
37733
|
-
renameSync as
|
|
37905
|
+
renameSync as renameSync8,
|
|
37734
37906
|
rmSync as rmSync6,
|
|
37735
37907
|
statSync as statSync9,
|
|
37736
37908
|
unlinkSync as unlinkSync6,
|
|
37737
37909
|
writeFileSync as writeFileSync8
|
|
37738
37910
|
} from "node:fs";
|
|
37739
|
-
import { join as
|
|
37911
|
+
import { join as join18 } from "node:path";
|
|
37740
37912
|
function aftCacheBase() {
|
|
37741
37913
|
return getAftCacheRoot();
|
|
37742
37914
|
}
|
|
@@ -37744,18 +37916,18 @@ function lspCacheRoot() {
|
|
|
37744
37916
|
return getAftLspPackagesDir();
|
|
37745
37917
|
}
|
|
37746
37918
|
function lspPackageDir(npmPackage) {
|
|
37747
|
-
return
|
|
37919
|
+
return join18(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
37748
37920
|
}
|
|
37749
37921
|
function lspBinaryPath(npmPackage, binary) {
|
|
37750
|
-
return
|
|
37922
|
+
return join18(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
37751
37923
|
}
|
|
37752
37924
|
function lspBinDir(npmPackage) {
|
|
37753
|
-
return
|
|
37925
|
+
return join18(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
37754
37926
|
}
|
|
37755
37927
|
function isInstalled(npmPackage, binary) {
|
|
37756
37928
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
37757
37929
|
try {
|
|
37758
|
-
if (statSync9(
|
|
37930
|
+
if (statSync9(join18(lspBinDir(npmPackage), candidate)).isFile())
|
|
37759
37931
|
return true;
|
|
37760
37932
|
} catch {}
|
|
37761
37933
|
}
|
|
@@ -37775,13 +37947,13 @@ function writeInstalledMetaIn(installDir, version, sha256) {
|
|
|
37775
37947
|
installedAt: new Date().toISOString(),
|
|
37776
37948
|
...sha256 ? { sha256 } : {}
|
|
37777
37949
|
};
|
|
37778
|
-
writeFileSync8(
|
|
37950
|
+
writeFileSync8(join18(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
37779
37951
|
} catch (err) {
|
|
37780
37952
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
37781
37953
|
}
|
|
37782
37954
|
}
|
|
37783
37955
|
function readInstalledMetaIn(installDir) {
|
|
37784
|
-
const path =
|
|
37956
|
+
const path = join18(installDir, INSTALLED_META_FILE);
|
|
37785
37957
|
try {
|
|
37786
37958
|
if (!statSync9(path).isFile())
|
|
37787
37959
|
return null;
|
|
@@ -37805,7 +37977,7 @@ function readInstalledMeta(packageKey) {
|
|
|
37805
37977
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
37806
37978
|
}
|
|
37807
37979
|
function lockPath(npmPackage) {
|
|
37808
|
-
return
|
|
37980
|
+
return join18(lspPackageDir(npmPackage), ".aft-installing");
|
|
37809
37981
|
}
|
|
37810
37982
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
37811
37983
|
function acquireInstallLock(lockKey) {
|
|
@@ -37936,7 +38108,7 @@ var AUTO_INSTALL_STAMP_FILE = "last-lsp-autoinstall.json";
|
|
|
37936
38108
|
var AUTO_INSTALL_WINDOW_MS = 60 * 1000;
|
|
37937
38109
|
var AUTO_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000;
|
|
37938
38110
|
function autoInstallStampPath() {
|
|
37939
|
-
return
|
|
38111
|
+
return join18(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
|
|
37940
38112
|
}
|
|
37941
38113
|
function hasRecentAutoInstallStamp(path) {
|
|
37942
38114
|
try {
|
|
@@ -38022,7 +38194,7 @@ function claimLspAutoInstallPass() {
|
|
|
38022
38194
|
encoding: "utf8",
|
|
38023
38195
|
mode: 384
|
|
38024
38196
|
});
|
|
38025
|
-
|
|
38197
|
+
renameSync8(tempPath, stampPath);
|
|
38026
38198
|
return { release };
|
|
38027
38199
|
} catch (err) {
|
|
38028
38200
|
if (claimed) {
|
|
@@ -38037,7 +38209,7 @@ function claimLspAutoInstallPass() {
|
|
|
38037
38209
|
}
|
|
38038
38210
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
38039
38211
|
function readVersionCheck(npmPackage) {
|
|
38040
|
-
const file =
|
|
38212
|
+
const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
38041
38213
|
try {
|
|
38042
38214
|
const raw = readFileSync12(file, "utf8");
|
|
38043
38215
|
const parsed = JSON.parse(raw);
|
|
@@ -38054,7 +38226,7 @@ function readVersionCheck(npmPackage) {
|
|
|
38054
38226
|
}
|
|
38055
38227
|
function writeVersionCheck(npmPackage, latest) {
|
|
38056
38228
|
mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
|
|
38057
|
-
const file =
|
|
38229
|
+
const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
38058
38230
|
const record = {
|
|
38059
38231
|
last_checked: new Date().toISOString(),
|
|
38060
38232
|
latest_eligible: latest
|
|
@@ -38216,8 +38388,8 @@ var NPM_LSP_TABLE = [
|
|
|
38216
38388
|
];
|
|
38217
38389
|
|
|
38218
38390
|
// src/lsp-project-relevance.ts
|
|
38219
|
-
import { existsSync as
|
|
38220
|
-
import { join as
|
|
38391
|
+
import { existsSync as existsSync17, readdirSync as readdirSync4, readFileSync as readFileSync13 } from "node:fs";
|
|
38392
|
+
import { join as join19 } from "node:path";
|
|
38221
38393
|
var MAX_WALK_DIRS = 200;
|
|
38222
38394
|
var MAX_WALK_DEPTH = 4;
|
|
38223
38395
|
var NOISE_DIRS = new Set([
|
|
@@ -38234,7 +38406,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
38234
38406
|
if (!rootMarkers)
|
|
38235
38407
|
return false;
|
|
38236
38408
|
for (const marker of rootMarkers) {
|
|
38237
|
-
if (
|
|
38409
|
+
if (existsSync17(join19(projectRoot, marker)))
|
|
38238
38410
|
return true;
|
|
38239
38411
|
}
|
|
38240
38412
|
return false;
|
|
@@ -38258,7 +38430,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
38258
38430
|
}
|
|
38259
38431
|
function readPackageJson(projectRoot) {
|
|
38260
38432
|
try {
|
|
38261
|
-
const raw = readFileSync13(
|
|
38433
|
+
const raw = readFileSync13(join19(projectRoot, "package.json"), "utf8");
|
|
38262
38434
|
const parsed = JSON.parse(raw);
|
|
38263
38435
|
if (typeof parsed !== "object" || parsed === null)
|
|
38264
38436
|
return null;
|
|
@@ -38288,7 +38460,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
38288
38460
|
for (const entry of entries) {
|
|
38289
38461
|
if (entry.isDirectory()) {
|
|
38290
38462
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
38291
|
-
queue.push({ dir:
|
|
38463
|
+
queue.push({ dir: join19(current.dir, entry.name), depth: current.depth + 1 });
|
|
38292
38464
|
}
|
|
38293
38465
|
continue;
|
|
38294
38466
|
}
|
|
@@ -38416,8 +38588,8 @@ async function resolveTargetVersion(spec, config, fetchImpl = fetch) {
|
|
|
38416
38588
|
}
|
|
38417
38589
|
function ensureInstallAnchor(cwd) {
|
|
38418
38590
|
try {
|
|
38419
|
-
const stub =
|
|
38420
|
-
if (!
|
|
38591
|
+
const stub = join20(cwd, "package.json");
|
|
38592
|
+
if (!existsSync18(stub)) {
|
|
38421
38593
|
writeFileSync9(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
38422
38594
|
`);
|
|
38423
38595
|
}
|
|
@@ -38643,12 +38815,12 @@ function sha256OfFileSync(path) {
|
|
|
38643
38815
|
}
|
|
38644
38816
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
38645
38817
|
const packageDir = lspPackageDir(spec.npm);
|
|
38646
|
-
const dest =
|
|
38818
|
+
const dest = join20(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
38647
38819
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
38648
38820
|
try {
|
|
38649
|
-
mkdirSync8(
|
|
38821
|
+
mkdirSync8(join20(dest, ".."), { recursive: true });
|
|
38650
38822
|
rmSync7(dest, { recursive: true, force: true });
|
|
38651
|
-
|
|
38823
|
+
renameSync9(packageDir, dest);
|
|
38652
38824
|
} catch (err) {
|
|
38653
38825
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: failed to quarantine cache entry: ${err}`);
|
|
38654
38826
|
}
|
|
@@ -38729,26 +38901,26 @@ async function pushLspPathsAfterAutoInstall(pool, projectRoot, cachedBinDirs) {
|
|
|
38729
38901
|
}
|
|
38730
38902
|
|
|
38731
38903
|
// src/lsp-github-install.ts
|
|
38732
|
-
import { execFileSync as
|
|
38904
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
38733
38905
|
import { createHash as createHash7, randomBytes as randomBytes3 } from "node:crypto";
|
|
38734
38906
|
import {
|
|
38735
38907
|
copyFileSync as copyFileSync4,
|
|
38736
38908
|
createReadStream as createReadStream2,
|
|
38737
38909
|
createWriteStream as createWriteStream3,
|
|
38738
|
-
existsSync as
|
|
38910
|
+
existsSync as existsSync19,
|
|
38739
38911
|
lstatSync as lstatSync2,
|
|
38740
38912
|
mkdirSync as mkdirSync9,
|
|
38741
38913
|
readdirSync as readdirSync5,
|
|
38742
38914
|
readFileSync as readFileSync15,
|
|
38743
38915
|
readlinkSync as readlinkSync2,
|
|
38744
38916
|
realpathSync as realpathSync3,
|
|
38745
|
-
renameSync as
|
|
38917
|
+
renameSync as renameSync10,
|
|
38746
38918
|
rmSync as rmSync8,
|
|
38747
38919
|
statSync as statSync11,
|
|
38748
38920
|
unlinkSync as unlinkSync7,
|
|
38749
38921
|
writeFileSync as writeFileSync10
|
|
38750
38922
|
} from "node:fs";
|
|
38751
|
-
import { dirname as dirname9, join as
|
|
38923
|
+
import { dirname as dirname9, join as join21, relative as relative3, resolve as resolve10 } from "node:path";
|
|
38752
38924
|
import { Readable as Readable3 } from "node:stream";
|
|
38753
38925
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
38754
38926
|
|
|
@@ -38841,19 +39013,19 @@ function ghCacheRoot() {
|
|
|
38841
39013
|
return getAftLspBinariesDir();
|
|
38842
39014
|
}
|
|
38843
39015
|
function ghPackageDir(spec) {
|
|
38844
|
-
return
|
|
39016
|
+
return join21(ghCacheRoot(), spec.id);
|
|
38845
39017
|
}
|
|
38846
39018
|
function ghBinDir(spec) {
|
|
38847
|
-
return
|
|
39019
|
+
return join21(ghPackageDir(spec), "bin");
|
|
38848
39020
|
}
|
|
38849
39021
|
function ghExtractDir(spec) {
|
|
38850
|
-
return
|
|
39022
|
+
return join21(ghPackageDir(spec), "extracted");
|
|
38851
39023
|
}
|
|
38852
39024
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
38853
39025
|
var INSTALL_FAILED_FILE = ".aft-install-failed.json";
|
|
38854
39026
|
var INSTALL_FAILURE_BACKOFF_MS = 6 * 60 * 60 * 1000;
|
|
38855
39027
|
function installFailureMarkerPath(spec) {
|
|
38856
|
-
return
|
|
39028
|
+
return join21(ghPackageDir(spec), INSTALL_FAILED_FILE);
|
|
38857
39029
|
}
|
|
38858
39030
|
function readInstallFailureMarker(spec) {
|
|
38859
39031
|
try {
|
|
@@ -38874,7 +39046,7 @@ function writeInstallFailureMarker(spec, release, sha256, installError) {
|
|
|
38874
39046
|
mkdirSync9(dirname9(path), { recursive: true });
|
|
38875
39047
|
writeFileSync10(tempPath, `${JSON.stringify({ release, sha256, error: markerError, at: new Date().toISOString() })}
|
|
38876
39048
|
`, { encoding: "utf8", mode: 384 });
|
|
38877
|
-
|
|
39049
|
+
renameSync10(tempPath, path);
|
|
38878
39050
|
} catch (err) {
|
|
38879
39051
|
try {
|
|
38880
39052
|
rmSync8(tempPath, { force: true });
|
|
@@ -38895,12 +39067,12 @@ function isFreshInstallFailure(marker) {
|
|
|
38895
39067
|
}
|
|
38896
39068
|
function ghBinaryPath(spec, platform) {
|
|
38897
39069
|
const ext = platform === "win32" ? ".exe" : "";
|
|
38898
|
-
return
|
|
39070
|
+
return join21(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
38899
39071
|
}
|
|
38900
39072
|
function isGithubInstalled(spec, platform) {
|
|
38901
39073
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
38902
39074
|
try {
|
|
38903
|
-
if (statSync11(
|
|
39075
|
+
if (statSync11(join21(ghBinDir(spec), candidate)).isFile())
|
|
38904
39076
|
return true;
|
|
38905
39077
|
} catch {}
|
|
38906
39078
|
}
|
|
@@ -38913,7 +39085,7 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
38913
39085
|
}
|
|
38914
39086
|
function readGithubInstalledMetaIn(installDir) {
|
|
38915
39087
|
try {
|
|
38916
|
-
const path =
|
|
39088
|
+
const path = join21(installDir, INSTALLED_META_FILE2);
|
|
38917
39089
|
if (!statSync11(path).isFile())
|
|
38918
39090
|
return null;
|
|
38919
39091
|
const parsed = JSON.parse(readFileSync15(path, "utf8"));
|
|
@@ -38940,7 +39112,7 @@ function writeGithubInstalledMetaIn(installDir, version, binarySha256, archiveSh
|
|
|
38940
39112
|
binarySha256,
|
|
38941
39113
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
38942
39114
|
};
|
|
38943
|
-
writeFileSync10(
|
|
39115
|
+
writeFileSync10(join21(installDir, INSTALLED_META_FILE2), JSON.stringify(meta), "utf8");
|
|
38944
39116
|
} catch (err) {
|
|
38945
39117
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
38946
39118
|
}
|
|
@@ -39189,7 +39361,7 @@ function validateExtraction(stagingRoot) {
|
|
|
39189
39361
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
39190
39362
|
}
|
|
39191
39363
|
for (const entry of entries) {
|
|
39192
|
-
const full =
|
|
39364
|
+
const full = join21(dir, entry);
|
|
39193
39365
|
let lst;
|
|
39194
39366
|
try {
|
|
39195
39367
|
lst = lstatSync2(full);
|
|
@@ -39235,7 +39407,7 @@ function assertArchiveEntryPath(entry) {
|
|
|
39235
39407
|
}
|
|
39236
39408
|
function precheckWithTar(archivePath, command) {
|
|
39237
39409
|
let totalBytes = 0;
|
|
39238
|
-
const verbose =
|
|
39410
|
+
const verbose = execFileSync3(command, ["-tvf", archivePath], { encoding: "utf8" });
|
|
39239
39411
|
for (const line of verbose.split(`
|
|
39240
39412
|
`)) {
|
|
39241
39413
|
if (line.startsWith("h")) {
|
|
@@ -39248,7 +39420,7 @@ function precheckWithTar(archivePath, command) {
|
|
|
39248
39420
|
totalBytes += Math.max(...numeric);
|
|
39249
39421
|
}
|
|
39250
39422
|
}
|
|
39251
|
-
const names =
|
|
39423
|
+
const names = execFileSync3(command, ["-tf", archivePath], { encoding: "utf8" });
|
|
39252
39424
|
for (const entry of names.split(`
|
|
39253
39425
|
`)) {
|
|
39254
39426
|
if (entry.length > 0)
|
|
@@ -39259,19 +39431,18 @@ function precheckWithTar(archivePath, command) {
|
|
|
39259
39431
|
function precheckArchiveContents(archivePath, archiveType, zipListingMode = "platform") {
|
|
39260
39432
|
let totalBytes = 0;
|
|
39261
39433
|
if (archiveType === "zip" && zipListingMode === "platform" && process.platform !== "win32") {
|
|
39262
|
-
const out =
|
|
39434
|
+
const out = execFileSync3("unzip", ["-l", archivePath], { encoding: "utf8" });
|
|
39263
39435
|
const match = out.match(/^\s*(\d+)\s+\d+\s+files?\s*$/m);
|
|
39264
39436
|
if (match)
|
|
39265
39437
|
totalBytes = Number.parseInt(match[1] ?? "0", 10);
|
|
39266
|
-
const names =
|
|
39438
|
+
const names = execFileSync3("unzip", ["-Z1", archivePath], { encoding: "utf8" });
|
|
39267
39439
|
for (const entry of names.split(`
|
|
39268
39440
|
`)) {
|
|
39269
39441
|
if (entry.length > 0)
|
|
39270
39442
|
assertArchiveEntryPath(entry);
|
|
39271
39443
|
}
|
|
39272
39444
|
} else {
|
|
39273
|
-
|
|
39274
|
-
totalBytes = precheckWithTar(archivePath, command);
|
|
39445
|
+
totalBytes = precheckWithTar(archivePath, windowsTarExecutable());
|
|
39275
39446
|
}
|
|
39276
39447
|
if (totalBytes > MAX_EXTRACT_BYTES2) {
|
|
39277
39448
|
throw new Error(`archive uncompressed size ${totalBytes} exceeds ${MAX_EXTRACT_BYTES2}`);
|
|
@@ -39291,7 +39462,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
39291
39462
|
try {
|
|
39292
39463
|
rmSync8(destDir, { recursive: true, force: true });
|
|
39293
39464
|
} catch {}
|
|
39294
|
-
|
|
39465
|
+
renameSync10(stagingDir, destDir);
|
|
39295
39466
|
} catch (err) {
|
|
39296
39467
|
try {
|
|
39297
39468
|
rmSync8(stagingDir, { recursive: true, force: true });
|
|
@@ -39301,12 +39472,12 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
39301
39472
|
}
|
|
39302
39473
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
39303
39474
|
const packageDir = ghPackageDir(spec);
|
|
39304
|
-
const dest =
|
|
39475
|
+
const dest = join21(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
39305
39476
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
39306
39477
|
try {
|
|
39307
39478
|
mkdirSync9(dirname9(dest), { recursive: true });
|
|
39308
39479
|
rmSync8(dest, { recursive: true, force: true });
|
|
39309
|
-
|
|
39480
|
+
renameSync10(packageDir, dest);
|
|
39310
39481
|
} catch (err) {
|
|
39311
39482
|
warn2(`[lsp] tofu_mismatch ${spec.id}: failed to quarantine cache entry: ${err}`);
|
|
39312
39483
|
}
|
|
@@ -39314,7 +39485,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
39314
39485
|
function validateCachedGithubInstall(spec, platform) {
|
|
39315
39486
|
const packageDir = ghPackageDir(spec);
|
|
39316
39487
|
const meta = readGithubInstalledMetaIn(packageDir);
|
|
39317
|
-
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) =>
|
|
39488
|
+
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join21(ghBinDir(spec), candidate)).find((candidate) => {
|
|
39318
39489
|
try {
|
|
39319
39490
|
return statSync11(candidate).isFile();
|
|
39320
39491
|
} catch {
|
|
@@ -39350,30 +39521,21 @@ function validateCachedGithubInstall(spec, platform) {
|
|
|
39350
39521
|
function runPlatformExtractor(archivePath, destDir, archiveType) {
|
|
39351
39522
|
if (archiveType === "zip") {
|
|
39352
39523
|
if (process.platform === "win32") {
|
|
39353
|
-
|
|
39354
|
-
stdio: "pipe",
|
|
39355
|
-
timeout: 180000
|
|
39356
|
-
});
|
|
39524
|
+
execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
|
|
39357
39525
|
return;
|
|
39358
39526
|
}
|
|
39359
|
-
|
|
39527
|
+
execFileSync3("unzip", ["-q", "-o", archivePath, "-d", destDir], {
|
|
39360
39528
|
stdio: "pipe",
|
|
39361
39529
|
timeout: 180000
|
|
39362
39530
|
});
|
|
39363
39531
|
return;
|
|
39364
39532
|
}
|
|
39365
39533
|
if (archiveType === "tar.gz") {
|
|
39366
|
-
|
|
39367
|
-
stdio: "pipe",
|
|
39368
|
-
timeout: 180000
|
|
39369
|
-
});
|
|
39534
|
+
execTarExtractionSync(["-xzf", archivePath, "-C", destDir], 180000);
|
|
39370
39535
|
return;
|
|
39371
39536
|
}
|
|
39372
39537
|
if (archiveType === "tar.xz") {
|
|
39373
|
-
|
|
39374
|
-
stdio: "pipe",
|
|
39375
|
-
timeout: 180000
|
|
39376
|
-
});
|
|
39538
|
+
execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
|
|
39377
39539
|
return;
|
|
39378
39540
|
}
|
|
39379
39541
|
throw new Error(`unsupported archive type: ${archiveType}`);
|
|
@@ -39394,7 +39556,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
39394
39556
|
}
|
|
39395
39557
|
const pkgDir = ghPackageDir(spec);
|
|
39396
39558
|
const extractDir = ghExtractDir(spec);
|
|
39397
|
-
const archivePath =
|
|
39559
|
+
const archivePath = join21(pkgDir, expected.name);
|
|
39398
39560
|
log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
|
|
39399
39561
|
try {
|
|
39400
39562
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
|
|
@@ -39436,8 +39598,8 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
39436
39598
|
unlinkSync7(archivePath);
|
|
39437
39599
|
} catch {}
|
|
39438
39600
|
}
|
|
39439
|
-
const innerBinaryPath =
|
|
39440
|
-
if (!
|
|
39601
|
+
const innerBinaryPath = join21(extractDir, spec.binaryPathInArchive(platform, arch, version));
|
|
39602
|
+
if (!existsSync19(innerBinaryPath)) {
|
|
39441
39603
|
const message = `extracted binary not found at ${innerBinaryPath}`;
|
|
39442
39604
|
error2(`[lsp] ${spec.id}: ${message}`);
|
|
39443
39605
|
return { ok: false, sha256: archiveSha256, error: message };
|
|
@@ -39542,7 +39704,7 @@ function runGithubAutoInstall(relevantServers, config, fetchImpl = fetch) {
|
|
|
39542
39704
|
if (!host) {
|
|
39543
39705
|
for (const spec of GITHUB_LSP_TABLE) {
|
|
39544
39706
|
try {
|
|
39545
|
-
if (
|
|
39707
|
+
if (existsSync19(ghBinDir(spec))) {
|
|
39546
39708
|
cachedBinDirs.push(ghBinDir(spec));
|
|
39547
39709
|
}
|
|
39548
39710
|
} catch {}
|
|
@@ -39859,25 +40021,25 @@ function isTuiConnected(sessionId) {
|
|
|
39859
40021
|
// src/shared/rpc-server.ts
|
|
39860
40022
|
import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
39861
40023
|
import {
|
|
39862
|
-
existsSync as
|
|
40024
|
+
existsSync as existsSync20,
|
|
39863
40025
|
mkdirSync as mkdirSync10,
|
|
39864
40026
|
readdirSync as readdirSync6,
|
|
39865
40027
|
readFileSync as readFileSync16,
|
|
39866
|
-
renameSync as
|
|
40028
|
+
renameSync as renameSync11,
|
|
39867
40029
|
unlinkSync as unlinkSync8,
|
|
39868
40030
|
writeFileSync as writeFileSync11
|
|
39869
40031
|
} from "node:fs";
|
|
39870
40032
|
import { createServer } from "node:http";
|
|
39871
|
-
import { dirname as dirname10, join as
|
|
40033
|
+
import { dirname as dirname10, join as join23 } from "node:path";
|
|
39872
40034
|
|
|
39873
40035
|
// src/shared/rpc-utils.ts
|
|
39874
|
-
import { join as
|
|
40036
|
+
import { join as join22 } from "node:path";
|
|
39875
40037
|
function projectHash(directory) {
|
|
39876
40038
|
return projectRootKeyHash(directory);
|
|
39877
40039
|
}
|
|
39878
40040
|
function rpcPortFileDir(storageDir, directory) {
|
|
39879
40041
|
const hash = projectHash(directory);
|
|
39880
|
-
return
|
|
40042
|
+
return join22(storageDir, "rpc", hash, "ports");
|
|
39881
40043
|
}
|
|
39882
40044
|
function isPidAlive(pid) {
|
|
39883
40045
|
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
|
|
@@ -39951,7 +40113,7 @@ class AftRpcServer {
|
|
|
39951
40113
|
constructor(storageDir, directory) {
|
|
39952
40114
|
this.portsDir = rpcPortFileDir(storageDir, directory);
|
|
39953
40115
|
this.instanceId = randomBytes4(8).toString("hex");
|
|
39954
|
-
this.portFilePath =
|
|
40116
|
+
this.portFilePath = join23(this.portsDir, `${this.instanceId}.json`);
|
|
39955
40117
|
}
|
|
39956
40118
|
handle(method, handler) {
|
|
39957
40119
|
this.handlers.set(method, handler);
|
|
@@ -39981,6 +40143,7 @@ class AftRpcServer {
|
|
|
39981
40143
|
});
|
|
39982
40144
|
this.bunServer = server;
|
|
39983
40145
|
this.port = server.port ?? 0;
|
|
40146
|
+
server.unref?.();
|
|
39984
40147
|
this.afterServerStarted();
|
|
39985
40148
|
return this.port;
|
|
39986
40149
|
}
|
|
@@ -40026,7 +40189,7 @@ class AftRpcServer {
|
|
|
40026
40189
|
pid: process.pid,
|
|
40027
40190
|
started_at: Date.now()
|
|
40028
40191
|
}), { encoding: "utf-8", mode: 384 });
|
|
40029
|
-
|
|
40192
|
+
renameSync11(tmpPath, this.portFilePath);
|
|
40030
40193
|
}
|
|
40031
40194
|
sweepDeadPortFiles() {
|
|
40032
40195
|
let entries;
|
|
@@ -40038,7 +40201,7 @@ class AftRpcServer {
|
|
|
40038
40201
|
for (const entry of entries) {
|
|
40039
40202
|
if (!entry.endsWith(".json"))
|
|
40040
40203
|
continue;
|
|
40041
|
-
const filePath =
|
|
40204
|
+
const filePath = join23(this.portsDir, entry);
|
|
40042
40205
|
if (filePath === this.portFilePath)
|
|
40043
40206
|
continue;
|
|
40044
40207
|
try {
|
|
@@ -40057,7 +40220,7 @@ class AftRpcServer {
|
|
|
40057
40220
|
if (!this.nodeServer && !this.bunServer || this.port <= 0)
|
|
40058
40221
|
return;
|
|
40059
40222
|
try {
|
|
40060
|
-
if (
|
|
40223
|
+
if (existsSync20(this.portFilePath))
|
|
40061
40224
|
return;
|
|
40062
40225
|
this.writePortFile();
|
|
40063
40226
|
log2(`RPC port file was missing; rewrote ${this.portFilePath}`);
|
|
@@ -40324,12 +40487,6 @@ function formatCacheRoleLabel(role) {
|
|
|
40324
40487
|
}
|
|
40325
40488
|
return role;
|
|
40326
40489
|
}
|
|
40327
|
-
function formatSemanticIndexStatus(status, stage) {
|
|
40328
|
-
if ((status === "loading" || status === "building") && stage === "fingerprint_change") {
|
|
40329
|
-
return "Rebuilding (model changed)";
|
|
40330
|
-
}
|
|
40331
|
-
return status;
|
|
40332
|
-
}
|
|
40333
40490
|
function formatSemanticRefreshing(refreshingCount) {
|
|
40334
40491
|
if (!Number.isFinite(refreshingCount) || refreshingCount <= 0)
|
|
40335
40492
|
return null;
|
|
@@ -40441,7 +40598,7 @@ function formatStatusMarkdown(status) {
|
|
|
40441
40598
|
`- **Cache role:** \`${formatCacheRoleLabel(status.cache_role)}\``
|
|
40442
40599
|
];
|
|
40443
40600
|
appendDegradedStatus(lines, status, true);
|
|
40444
|
-
lines.push("", "### Enabled features", `- \`format_on_edit\`: ${formatFlag(status.features.format_on_edit)}`, `- \`search_index\`: ${formatFlag(status.features.search_index)}`, `- \`semantic_search\`: ${formatFlag(status.features.semantic_search)}`, `- \`callgraph_store\`: ${formatFlag(status.features.callgraph_store)}`, "", "### Search index", `- **Status:** \`${status.search_index.status}\``, `- **Files:** ${formatCount(status.search_index.files)}`, `- **Trigrams:** ${formatCount(status.search_index.trigrams)}`, "", "### Semantic index", `- **Status:** \`${formatSemanticIndexStatus(status.semantic_index.status, status.semantic_index.stage)}\``);
|
|
40601
|
+
lines.push("", "### Enabled features", `- \`format_on_edit\`: ${formatFlag(status.features.format_on_edit)}`, `- \`search_index\`: ${formatFlag(status.features.search_index)}`, `- \`semantic_search\`: ${formatFlag(status.features.semantic_search)}`, `- \`callgraph_store\`: ${formatFlag(status.features.callgraph_store)}`, "", "### Search index", `- **Status:** \`${status.search_index.status}\``, `- **Files:** ${formatCount(status.search_index.files)}`, `- **Trigrams:** ${formatCount(status.search_index.trigrams)}`, "", "### Semantic index", `- **Status:** \`${formatSemanticIndexStatus(status.semantic_index.status, status.semantic_index.stage, status.semantic_index.error)}\``);
|
|
40445
40602
|
const refreshing = formatSemanticRefreshing(status.semantic_index.refreshing_count);
|
|
40446
40603
|
if (refreshing) {
|
|
40447
40604
|
lines.push(`- **Refresh:** ${refreshing}`);
|
|
@@ -40610,7 +40767,7 @@ function isSyncWatchAborted(sessionID) {
|
|
|
40610
40767
|
}
|
|
40611
40768
|
|
|
40612
40769
|
// src/tools/permissions.ts
|
|
40613
|
-
import { execFileSync as
|
|
40770
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
40614
40771
|
import * as fs4 from "node:fs";
|
|
40615
40772
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
40616
40773
|
import * as path3 from "node:path";
|
|
@@ -40865,7 +41022,7 @@ function gitRootForNearestExistingParent(resolved) {
|
|
|
40865
41022
|
cwd = path3.dirname(nearest);
|
|
40866
41023
|
} catch {}
|
|
40867
41024
|
try {
|
|
40868
|
-
const out =
|
|
41025
|
+
const out = execFileSync4("git", ["rev-parse", "--show-toplevel"], {
|
|
40869
41026
|
cwd,
|
|
40870
41027
|
encoding: "utf8",
|
|
40871
41028
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -41178,6 +41335,26 @@ function failure(error) {
|
|
|
41178
41335
|
})();
|
|
41179
41336
|
return new Error(`V2 tool execution rejected with a non-Error value: ${detail}`);
|
|
41180
41337
|
}
|
|
41338
|
+
function isPlainObject3(value) {
|
|
41339
|
+
if (typeof value !== "object" || value === null)
|
|
41340
|
+
return false;
|
|
41341
|
+
const prototype = Object.getPrototypeOf(value);
|
|
41342
|
+
return prototype === Object.prototype || prototype === null;
|
|
41343
|
+
}
|
|
41344
|
+
function jsonSafeMetadata(value) {
|
|
41345
|
+
if (Array.isArray(value)) {
|
|
41346
|
+
return value.map((entry) => entry === undefined ? null : jsonSafeMetadata(entry));
|
|
41347
|
+
}
|
|
41348
|
+
if (!isPlainObject3(value))
|
|
41349
|
+
return value;
|
|
41350
|
+
const cleaned = {};
|
|
41351
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
41352
|
+
if (entry === undefined)
|
|
41353
|
+
continue;
|
|
41354
|
+
cleaned[key] = jsonSafeMetadata(entry);
|
|
41355
|
+
}
|
|
41356
|
+
return cleaned;
|
|
41357
|
+
}
|
|
41181
41358
|
function resultContent(result) {
|
|
41182
41359
|
if (typeof result === "string")
|
|
41183
41360
|
return { content: result };
|
|
@@ -41188,15 +41365,39 @@ function resultContent(result) {
|
|
|
41188
41365
|
...attachment.filename ? { name: attachment.filename } : {}
|
|
41189
41366
|
}));
|
|
41190
41367
|
const content = attachments.length ? [{ type: "text", text: result.output }, ...attachments] : result.output;
|
|
41191
|
-
const metadata = {
|
|
41368
|
+
const metadata = jsonSafeMetadata({
|
|
41192
41369
|
...result.metadata ?? {},
|
|
41193
41370
|
...result.title ? { title: result.title } : {}
|
|
41194
|
-
};
|
|
41371
|
+
});
|
|
41195
41372
|
return {
|
|
41196
41373
|
content,
|
|
41197
41374
|
...Object.keys(metadata).length ? { metadata } : {}
|
|
41198
41375
|
};
|
|
41199
41376
|
}
|
|
41377
|
+
function failureEnvelopeMessage(result) {
|
|
41378
|
+
const output = typeof result === "string" ? result : result.output;
|
|
41379
|
+
if (typeof output !== "string")
|
|
41380
|
+
return;
|
|
41381
|
+
const trimmed = output.trim();
|
|
41382
|
+
if (!trimmed.startsWith("{") || !trimmed.includes('"success"'))
|
|
41383
|
+
return;
|
|
41384
|
+
let parsed;
|
|
41385
|
+
try {
|
|
41386
|
+
parsed = JSON.parse(trimmed);
|
|
41387
|
+
} catch {
|
|
41388
|
+
return;
|
|
41389
|
+
}
|
|
41390
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
41391
|
+
return;
|
|
41392
|
+
const envelope = parsed;
|
|
41393
|
+
if (envelope.success !== false)
|
|
41394
|
+
return;
|
|
41395
|
+
for (const field of [envelope.message, envelope.error, envelope.code]) {
|
|
41396
|
+
if (typeof field === "string" && field.length > 0)
|
|
41397
|
+
return field;
|
|
41398
|
+
}
|
|
41399
|
+
return "The tool call failed.";
|
|
41400
|
+
}
|
|
41200
41401
|
function bareToolName3(name) {
|
|
41201
41402
|
return name.startsWith("aft_") ? name.slice(4) : name;
|
|
41202
41403
|
}
|
|
@@ -41259,15 +41460,15 @@ function runtimeFor(location, context, signal, consumers) {
|
|
|
41259
41460
|
abort: signal,
|
|
41260
41461
|
effectAbort: signal,
|
|
41261
41462
|
metadata: (update) => {
|
|
41262
|
-
Effect.runPromise(context.progress({
|
|
41463
|
+
Effect.runPromise(context.progress(jsonSafeMetadata({
|
|
41263
41464
|
...update.metadata ?? {},
|
|
41264
41465
|
...update.title ? { title: update.title } : {}
|
|
41265
|
-
}));
|
|
41466
|
+
})));
|
|
41266
41467
|
},
|
|
41267
41468
|
ask: (request) => {
|
|
41268
41469
|
if (consumers.requestPermission)
|
|
41269
41470
|
return consumers.requestPermission(request, context);
|
|
41270
|
-
return Promise.reject(new Error(`The "${request.permission}" operation was refused because
|
|
41471
|
+
return Promise.reject(new Error(`The "${request.permission}" operation was refused because this AFT runtime has no permission evaluator bound, so the host's permission rules for it could not be consulted.`));
|
|
41271
41472
|
},
|
|
41272
41473
|
progress: context.progress
|
|
41273
41474
|
};
|
|
@@ -41296,6 +41497,9 @@ function projectV2Tool(name, definition, location, consumers = {}) {
|
|
|
41296
41497
|
context: runtime,
|
|
41297
41498
|
definition
|
|
41298
41499
|
}) : await definition.execute(input, runtime);
|
|
41500
|
+
const refusal = failureEnvelopeMessage(result);
|
|
41501
|
+
if (refusal)
|
|
41502
|
+
throw new Error(refusal);
|
|
41299
41503
|
return resultContent(result);
|
|
41300
41504
|
},
|
|
41301
41505
|
catch: failure
|
|
@@ -42390,7 +42594,7 @@ function createReadTool(ctx) {
|
|
|
42390
42594
|
try {
|
|
42391
42595
|
await runAsk(context.ask({
|
|
42392
42596
|
permission: "read",
|
|
42393
|
-
patterns: [filePath],
|
|
42597
|
+
patterns: [permissionPath(context, filePath)],
|
|
42394
42598
|
always: ["*"],
|
|
42395
42599
|
metadata: {}
|
|
42396
42600
|
}));
|
|
@@ -42551,7 +42755,7 @@ function getEditDescription(ctx, writeToolName) {
|
|
|
42551
42755
|
|
|
42552
42756
|
**Modes** (determined by which parameters you provide):
|
|
42553
42757
|
|
|
42554
|
-
Provide exactly one mode per call: appendContent, edits[], or symbol plus content. Mixing modes or providing none is rejected — there is no implicit "write" fallback. To edit multiple files, make parallel \`edit\` calls in one response.
|
|
42758
|
+
Provide exactly one mode per call: appendContent, edits[], or symbol plus content. \`symbol\` and \`content\` are only meaningful together; a call carrying one without the other is incomplete. Mixing modes or providing none is rejected — there is no implicit "write" fallback. To edit multiple files, make parallel \`edit\` calls in one response.
|
|
42555
42759
|
|
|
42556
42760
|
1. **Append** — pass \`path\` + \`appendContent\`
|
|
42557
42761
|
Appends text to the end of a file, creating it if it does not exist.
|
|
@@ -42652,8 +42856,8 @@ function createEditTool(ctx, writeToolName = "write") {
|
|
|
42652
42856
|
description: getEditDescription(ctx, writeToolName),
|
|
42653
42857
|
args: {
|
|
42654
42858
|
filePath: z7.string().describe("Path to the file to edit (absolute or relative to project root)"),
|
|
42655
|
-
symbol: z7.string().optional().describe("Named symbol to replace
|
|
42656
|
-
content: z7.string().optional().describe("Replacement content for symbol mode. For whole-file writes, use the `write` tool."),
|
|
42859
|
+
symbol: z7.string().optional().describe("Named symbol to replace; only meaningful together with `content`. A call carrying one without the other is incomplete."),
|
|
42860
|
+
content: z7.string().optional().describe("Replacement content for symbol mode; only meaningful together with `symbol`. A call carrying one without the other is incomplete. For whole-file writes, use the `write` tool."),
|
|
42657
42861
|
appendContent: z7.string().optional().describe("Text to append to the end of path; creates the file if needed"),
|
|
42658
42862
|
edits: z7.array(z7.object({
|
|
42659
42863
|
oldString: z7.string().optional().describe("Text to find for a batch find/replace edit"),
|
|
@@ -42895,7 +43099,7 @@ function createDeleteTool(ctx) {
|
|
|
42895
43099
|
}
|
|
42896
43100
|
await runAsk(context.ask({
|
|
42897
43101
|
permission: "edit",
|
|
42898
|
-
patterns: absolutePaths,
|
|
43102
|
+
patterns: resolveRelativePatterns(context, absolutePaths),
|
|
42899
43103
|
always: ["*"],
|
|
42900
43104
|
metadata: { action: "delete", count: absolutePaths.length }
|
|
42901
43105
|
}));
|
|
@@ -42948,7 +43152,7 @@ function createMoveTool(ctx) {
|
|
|
42948
43152
|
}
|
|
42949
43153
|
await runAsk(context.ask({
|
|
42950
43154
|
permission: "edit",
|
|
42951
|
-
patterns: [filePath, destPath],
|
|
43155
|
+
patterns: resolveRelativePatterns(context, [filePath, destPath]),
|
|
42952
43156
|
always: ["*"],
|
|
42953
43157
|
metadata: { action: "move" }
|
|
42954
43158
|
}));
|
|
@@ -43278,7 +43482,7 @@ function inspectTools(ctx) {
|
|
|
43278
43482
|
` + "Treat `dead_code` as a hint, not proof: reachability is call-based, so symbols reached only via method dispatch or referenced only in type position may be false positives — verify before deleting.\n\n" + "When a list is cut, the reply ends with `shown N of M <unit> (<reason>) · narrow: <knobs>`; absence of that line means the list is complete.",
|
|
43279
43483
|
args: {
|
|
43280
43484
|
sections: arg(z9.union([z9.string(), z9.array(z9.string())]).optional().describe("Categories to include in detailed drill-down (e.g. 'todos' or ['todos', 'dead_code', 'cycles']). Use 'all' for every active category. Omit for summary-only mode. `sections` changes detail, not the categories verified.")),
|
|
43281
|
-
scope: arg(z9.union([z9.string(), z9.array(z9.string())]).optional().describe("Restrict returned results to paths under this scope (file or directory
|
|
43485
|
+
scope: arg(z9.union([z9.string(), z9.array(z9.string())]).optional().describe("Restrict returned results to paths under this scope (one path, or an array of paths — not a space-separated list; file or directory; absolute or relative to project root). `scope=` narrows results and limits Rust LSP startup to owning Cargo workspaces; it does not trigger per-file diagnostic collection. Scoped files no producer has authoritatively analyzed are reported as named gaps (complete: false), never as a clean empty result.")),
|
|
43282
43486
|
topK: arg(z9.number().int().positive().max(100).optional().describe("Max drill-down items per category. Default 20, max 100."))
|
|
43283
43487
|
},
|
|
43284
43488
|
execute: async (args, context) => {
|
|
@@ -43671,7 +43875,7 @@ function safetyTools(ctx) {
|
|
|
43671
43875
|
` + `- 'undo': Undo the entire last tool call when 'path' is omitted (typical), or undo the last edit to one file when 'path' is provided. Note: pops from the undo stack (irreversible, no redo). Use 'history' to inspect per-file history before undoing.
|
|
43672
43876
|
` + `- 'history': List all edit snapshots for a file. Requires 'path'.
|
|
43673
43877
|
` + `- 'checkpoint': Save a named snapshot. Explicit 'files' may be untracked or gitignored; omit them to snapshot backup-tracked files. Checkpoints are session-scoped and lost on bridge or daemon restart. Requires 'name'.
|
|
43674
|
-
` + `- 'restore': Restore files to a previously saved checkpoint. Requires 'name'.
|
|
43878
|
+
` + `- 'restore': Restore files to a previously saved checkpoint. Optional 'path'/'files' scopes the restore; omitted scope restores the whole checkpoint. Requires 'name'.
|
|
43675
43879
|
` + `- 'list': List all available named checkpoints. No extra params needed.
|
|
43676
43880
|
|
|
43677
43881
|
` + `Each op requires specific parameters — see parameter descriptions for requirements.
|
|
@@ -43679,9 +43883,9 @@ function safetyTools(ctx) {
|
|
|
43679
43883
|
` + "Use checkpoint before risky multi-file changes. Use undo for quick single-file rollback.",
|
|
43680
43884
|
args: {
|
|
43681
43885
|
op: z12.enum(["undo", "history", "checkpoint", "restore", "list"]).describe("Safety operation"),
|
|
43682
|
-
path: z12.string().optional().describe("File path (required for history, optional for undo). Absolute or relative to project root"),
|
|
43886
|
+
path: z12.string().optional().describe("File path (required for history, optional for undo, optional for restore — restores only that file). Absolute or relative to project root"),
|
|
43683
43887
|
name: z12.string().optional().describe("Checkpoint name (required for checkpoint, restore)"),
|
|
43684
|
-
files: z12.array(z12.string()).optional().describe("Specific files to include in checkpoint (optional
|
|
43888
|
+
files: z12.array(z12.string()).optional().describe("Specific files to include in checkpoint, or to restore from a checkpoint (optional; restore without path/files restores the whole checkpoint; explicit checkpoint files may be untracked or gitignored)")
|
|
43685
43889
|
},
|
|
43686
43890
|
execute: async (args, context) => {
|
|
43687
43891
|
const op = args.op;
|
|
@@ -44000,7 +44204,7 @@ function semanticTools(ctx) {
|
|
|
44000
44204
|
`),
|
|
44001
44205
|
args: {
|
|
44002
44206
|
query: arg3(z13.string().describe("Concept, regex, literal text, filename, or capability to find. Examples: 'fuzzy match with whitespace tolerance', '^export', 'Cargo.lock'.")),
|
|
44003
|
-
topK: arg3(optionalInt(1,
|
|
44207
|
+
topK: arg3(optionalInt(1, 50).describe("Number of results (default: 10, max: 50)")),
|
|
44004
44208
|
offset: arg3(optionalInt(0, 1e5).describe("Zero-based result offset (default: 0, max: 100000).")),
|
|
44005
44209
|
includeTests: arg3(z13.boolean().optional().describe("Include test files (*.test.*, *_test.rs, __tests__/, …) plus test-support, fixture, mock, snapshot, and corpus files. Defaults to false.")),
|
|
44006
44210
|
path: arg3(z13.string().optional().describe("Only set this to search a different Git project (absolute or ~ path). Omit it for the current configured workspace, including non-Git workspace roots; this is not a subdirectory filter. Unindexed external projects use a bounded lexical fallback."))
|
|
@@ -44016,9 +44220,9 @@ function semanticTools(ctx) {
|
|
|
44016
44220
|
if (denied)
|
|
44017
44221
|
return permissionDeniedResponse(denied);
|
|
44018
44222
|
const rawArgs = { query };
|
|
44019
|
-
const topK = coerceOptionalInt(args.topK, "topK", 1,
|
|
44223
|
+
const topK = coerceOptionalInt(args.topK, "topK", 1, 50);
|
|
44020
44224
|
const offset = coerceOptionalInt(args.offset, "offset", 0, 1e5);
|
|
44021
|
-
const includeTests =
|
|
44225
|
+
const includeTests = !isEmptyParam(args.includeTests) ? coerceBoolean(args.includeTests) : undefined;
|
|
44022
44226
|
if (topK !== undefined)
|
|
44023
44227
|
rawArgs.topK = topK;
|
|
44024
44228
|
if (offset !== undefined)
|
|
@@ -44258,11 +44462,11 @@ function throwSentinel(command) {
|
|
|
44258
44462
|
throw sentinel;
|
|
44259
44463
|
}
|
|
44260
44464
|
var PLUGIN_VERSION = resolvePluginVersion(import.meta.url);
|
|
44261
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
44465
|
+
var ANNOUNCEMENT_VERSION = "0.57.0";
|
|
44262
44466
|
var ANNOUNCEMENT_FEATURES = [
|
|
44263
|
-
"
|
|
44264
|
-
"
|
|
44265
|
-
"
|
|
44467
|
+
"OpenCode 2 is supported: tools, permission prompts, the sidebar and cancellation all work on the GA host, and an end-to-end matrix guards them.",
|
|
44468
|
+
"`doctor` configures a machine that has only OpenCode 2 installed, and `--fix` no longer skips unrelated repairs when it cannot decide the generation.",
|
|
44469
|
+
"A code-health scan no longer starts while the same project is still building its call graph, which cost about 90 MB of peak memory on large repositories."
|
|
44266
44470
|
];
|
|
44267
44471
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
44268
44472
|
var plugin = async (input) => initializePluginForDirectory(input);
|