@cortexkit/aft-opencode 0.56.2 → 0.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bg-notifications.d.ts +1 -0
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/entry/server.js +2650 -267
- package/dist/index.js +420 -228
- 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/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) {
|
|
@@ -15543,12 +15554,36 @@ function isNpmAvailable(deps = defaultDeps()) {
|
|
|
15543
15554
|
return resolveNpm(deps) !== null;
|
|
15544
15555
|
}
|
|
15545
15556
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
15546
|
-
import { execFileSync } from "node:child_process";
|
|
15557
|
+
import { execFileSync as execFileSync2 } from "node:child_process";
|
|
15547
15558
|
import { createHash as createHash4 } from "node:crypto";
|
|
15548
|
-
import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as
|
|
15549
|
-
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";
|
|
15550
15561
|
import { Readable as Readable2 } from "node:stream";
|
|
15551
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
|
|
15552
15587
|
var ORT_VERSION = "1.24.4";
|
|
15553
15588
|
var ORT_REPO = "microsoft/onnxruntime";
|
|
15554
15589
|
var MAX_DOWNLOAD_BYTES2 = 256 * 1024 * 1024;
|
|
@@ -15612,11 +15647,11 @@ function getManualInstallHint() {
|
|
|
15612
15647
|
}
|
|
15613
15648
|
async function ensureOnnxRuntime(storageDir) {
|
|
15614
15649
|
const info = getPlatformInfo();
|
|
15615
|
-
const ortVersionDir =
|
|
15650
|
+
const ortVersionDir = join13(storageDir, "onnxruntime", ORT_VERSION);
|
|
15616
15651
|
const libName = info?.libName ?? "libonnxruntime.dylib";
|
|
15617
15652
|
const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
|
|
15618
|
-
const libPath =
|
|
15619
|
-
if (
|
|
15653
|
+
const libPath = join13(resolvedOrtDir, libName);
|
|
15654
|
+
if (existsSync10(libPath)) {
|
|
15620
15655
|
const meta = readOnnxInstalledMeta(ortVersionDir);
|
|
15621
15656
|
if (meta?.sha256) {
|
|
15622
15657
|
try {
|
|
@@ -15645,9 +15680,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
15645
15680
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
15646
15681
|
return null;
|
|
15647
15682
|
}
|
|
15648
|
-
const onnxBaseDir =
|
|
15683
|
+
const onnxBaseDir = join13(storageDir, "onnxruntime");
|
|
15649
15684
|
mkdirSync5(onnxBaseDir, { recursive: true });
|
|
15650
|
-
const lockPath =
|
|
15685
|
+
const lockPath = join13(onnxBaseDir, ONNX_LOCK_FILE);
|
|
15651
15686
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
15652
15687
|
if (!acquireLock(lockPath)) {
|
|
15653
15688
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -15666,7 +15701,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
15666
15701
|
for (const entry of entries) {
|
|
15667
15702
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
15668
15703
|
continue;
|
|
15669
|
-
const stagingDir =
|
|
15704
|
+
const stagingDir = join13(onnxBaseDir, entry);
|
|
15670
15705
|
const parts = entry.split(".");
|
|
15671
15706
|
const pidStr = parts[parts.length - 2];
|
|
15672
15707
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -15703,7 +15738,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
15703
15738
|
}
|
|
15704
15739
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
15705
15740
|
try {
|
|
15706
|
-
if (
|
|
15741
|
+
if (existsSync10(ortDir) && !existsSync10(join13(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
15707
15742
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
15708
15743
|
rmSync3(ortDir, { recursive: true, force: true });
|
|
15709
15744
|
}
|
|
@@ -15747,8 +15782,8 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
15747
15782
|
if (version)
|
|
15748
15783
|
return version;
|
|
15749
15784
|
}
|
|
15750
|
-
const base =
|
|
15751
|
-
if (
|
|
15785
|
+
const base = join13(libDir, libName);
|
|
15786
|
+
if (existsSync10(base)) {
|
|
15752
15787
|
try {
|
|
15753
15788
|
const real = realpathSync2(base);
|
|
15754
15789
|
const version = parseOnnxVersionFromPath(real) ?? parseOnnxVersionFromDirectoryPath(real);
|
|
@@ -15814,10 +15849,10 @@ function directoryContainsLibrary(dir, libName) {
|
|
|
15814
15849
|
}
|
|
15815
15850
|
}
|
|
15816
15851
|
function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
|
|
15817
|
-
if (
|
|
15852
|
+
if (existsSync10(join13(ortVersionDir, libName)))
|
|
15818
15853
|
return ortVersionDir;
|
|
15819
|
-
const libSubdir =
|
|
15820
|
-
if (
|
|
15854
|
+
const libSubdir = join13(ortVersionDir, "lib");
|
|
15855
|
+
if (existsSync10(join13(libSubdir, libName)))
|
|
15821
15856
|
return libSubdir;
|
|
15822
15857
|
return ortVersionDir;
|
|
15823
15858
|
}
|
|
@@ -15832,13 +15867,13 @@ function findSystemOnnxRuntime(libName) {
|
|
|
15832
15867
|
} else if (process.platform === "win32") {
|
|
15833
15868
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
15834
15869
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
15835
|
-
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"), ...(() => {
|
|
15836
15871
|
const nugetPaths = [];
|
|
15837
15872
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
15838
15873
|
if (!userProfile)
|
|
15839
15874
|
return nugetPaths;
|
|
15840
|
-
const nugetPackageDir =
|
|
15841
|
-
if (!
|
|
15875
|
+
const nugetPackageDir = join13(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
15876
|
+
if (!existsSync10(nugetPackageDir))
|
|
15842
15877
|
return nugetPaths;
|
|
15843
15878
|
try {
|
|
15844
15879
|
for (const entry of readdirSync3(nugetPackageDir, { withFileTypes: true })) {
|
|
@@ -15846,7 +15881,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
15846
15881
|
continue;
|
|
15847
15882
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
15848
15883
|
continue;
|
|
15849
|
-
nugetPaths.push(
|
|
15884
|
+
nugetPaths.push(join13(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join13(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
15850
15885
|
}
|
|
15851
15886
|
} catch (err) {
|
|
15852
15887
|
warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -15868,11 +15903,11 @@ function findSystemOnnxRuntime(libName) {
|
|
|
15868
15903
|
});
|
|
15869
15904
|
const unknownVersionPaths = [];
|
|
15870
15905
|
for (const dir of uniquePaths) {
|
|
15871
|
-
const libPath =
|
|
15906
|
+
const libPath = join13(dir, libName);
|
|
15872
15907
|
if (process.platform === "win32") {
|
|
15873
15908
|
if (!directoryContainsLibrary(dir, libName))
|
|
15874
15909
|
continue;
|
|
15875
|
-
} else if (!
|
|
15910
|
+
} else if (!existsSync10(libPath)) {
|
|
15876
15911
|
continue;
|
|
15877
15912
|
}
|
|
15878
15913
|
const version = detectOnnxVersion(dir, libName);
|
|
@@ -15938,7 +15973,7 @@ function validateExtractedTree(stagingRoot) {
|
|
|
15938
15973
|
const walk = (dir) => {
|
|
15939
15974
|
const entries = readdirSync3(dir);
|
|
15940
15975
|
for (const entry of entries) {
|
|
15941
|
-
const fullPath =
|
|
15976
|
+
const fullPath = join13(dir, entry);
|
|
15942
15977
|
const lst = lstatSync(fullPath);
|
|
15943
15978
|
if (lst.isSymbolicLink()) {
|
|
15944
15979
|
const linkTarget = readlinkSync(fullPath);
|
|
@@ -15971,34 +16006,32 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
15971
16006
|
const url = `https://github.com/${ORT_REPO}/releases/download/v${ORT_VERSION}/${info.assetName}.${info.archiveType === "tgz" ? "tgz" : "zip"}`;
|
|
15972
16007
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
15973
16008
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
16009
|
+
const extractionRoot = join13(tmpDir, "extract");
|
|
16010
|
+
const stagedInstallDir = join13(tmpDir, "install");
|
|
15974
16011
|
try {
|
|
15975
|
-
mkdirSync5(
|
|
15976
|
-
const archivePath =
|
|
16012
|
+
mkdirSync5(extractionRoot, { recursive: true });
|
|
16013
|
+
const archivePath = join13(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
15977
16014
|
await downloadFileWithCap(url, archivePath);
|
|
15978
16015
|
const archiveSha256 = sha256File(archivePath);
|
|
15979
16016
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
15980
16017
|
if (info.archiveType === "tgz") {
|
|
15981
|
-
|
|
15982
|
-
stdio: "pipe",
|
|
15983
|
-
timeout: 120000
|
|
15984
|
-
});
|
|
16018
|
+
execTarExtractionSync(["xzf", archivePath, "-C", extractionRoot], 120000);
|
|
15985
16019
|
} else {
|
|
15986
|
-
await extractZipArchive(archivePath,
|
|
16020
|
+
await extractZipArchive(archivePath, extractionRoot);
|
|
15987
16021
|
}
|
|
15988
16022
|
try {
|
|
15989
16023
|
unlinkSync4(archivePath);
|
|
15990
16024
|
} catch {}
|
|
15991
|
-
validateExtractedTree(
|
|
15992
|
-
const extractedDir =
|
|
15993
|
-
if (!
|
|
16025
|
+
validateExtractedTree(extractionRoot);
|
|
16026
|
+
const extractedDir = join13(extractionRoot, info.assetName, "lib");
|
|
16027
|
+
if (!existsSync10(extractedDir)) {
|
|
15994
16028
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
15995
16029
|
}
|
|
15996
|
-
mkdirSync5(targetDir, { recursive: true });
|
|
15997
16030
|
const libFiles = readdirSync3(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
|
|
15998
16031
|
const realFiles = [];
|
|
15999
16032
|
const symlinks = [];
|
|
16000
16033
|
for (const libFile of libFiles) {
|
|
16001
|
-
const src =
|
|
16034
|
+
const src = join13(extractedDir, libFile);
|
|
16002
16035
|
try {
|
|
16003
16036
|
const stat = lstatSync(src);
|
|
16004
16037
|
log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -16012,15 +16045,11 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
16012
16045
|
realFiles.push(libFile);
|
|
16013
16046
|
}
|
|
16014
16047
|
}
|
|
16015
|
-
copyOnnxLibraries(info, extractedDir,
|
|
16016
|
-
const libPath =
|
|
16017
|
-
|
|
16018
|
-
|
|
16019
|
-
|
|
16020
|
-
} catch (err) {
|
|
16021
|
-
warn(`Could not hash newly-installed ONNX library at ${libPath}: ${err}`);
|
|
16022
|
-
}
|
|
16023
|
-
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);
|
|
16024
16053
|
rmSync3(tmpDir, { recursive: true, force: true });
|
|
16025
16054
|
log(`ONNX Runtime v${ORT_VERSION} installed to ${targetDir}`);
|
|
16026
16055
|
return targetDir;
|
|
@@ -16029,17 +16058,39 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
16029
16058
|
try {
|
|
16030
16059
|
rmSync3(tmpDir, { recursive: true, force: true });
|
|
16031
16060
|
} catch {}
|
|
16032
|
-
try {
|
|
16033
|
-
rmSync3(targetDir, { recursive: true, force: true });
|
|
16034
|
-
} catch {}
|
|
16035
16061
|
return null;
|
|
16036
16062
|
}
|
|
16037
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
|
+
}
|
|
16038
16089
|
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
|
|
16039
16090
|
const requiredLibs = new Set([info.libName]);
|
|
16040
16091
|
for (const libFile of realFiles) {
|
|
16041
|
-
const src =
|
|
16042
|
-
const dst =
|
|
16092
|
+
const src = join13(extractedDir, libFile);
|
|
16093
|
+
const dst = join13(targetDir, libFile);
|
|
16043
16094
|
try {
|
|
16044
16095
|
copyFile(src, dst);
|
|
16045
16096
|
if (process.platform !== "win32") {
|
|
@@ -16055,11 +16106,11 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
16055
16106
|
}
|
|
16056
16107
|
const targetRoot = realpathSync2(targetDir);
|
|
16057
16108
|
for (const link of symlinks) {
|
|
16058
|
-
const dst =
|
|
16109
|
+
const dst = join13(targetDir, link.name);
|
|
16059
16110
|
try {
|
|
16060
16111
|
unlinkSync4(dst);
|
|
16061
16112
|
} catch {}
|
|
16062
|
-
const dstForContainment =
|
|
16113
|
+
const dstForContainment = join13(targetRoot, link.name);
|
|
16063
16114
|
const resolvedTarget = resolve7(dirname5(dstForContainment), link.target);
|
|
16064
16115
|
if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
|
|
16065
16116
|
const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
|
|
@@ -16080,21 +16131,18 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
16080
16131
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
16081
16132
|
}
|
|
16082
16133
|
}
|
|
16083
|
-
const requiredPath =
|
|
16084
|
-
if (!
|
|
16134
|
+
const requiredPath = join13(targetDir, info.libName);
|
|
16135
|
+
if (!existsSync10(requiredPath)) {
|
|
16085
16136
|
rmSync3(targetDir, { recursive: true, force: true });
|
|
16086
16137
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
16087
16138
|
}
|
|
16088
16139
|
}
|
|
16089
16140
|
async function extractZipArchive(archivePath, destinationDir) {
|
|
16090
16141
|
if (process.platform === "win32") {
|
|
16091
|
-
|
|
16092
|
-
stdio: "pipe",
|
|
16093
|
-
timeout: 120000
|
|
16094
|
-
});
|
|
16142
|
+
execTarExtractionSync(["-xf", archivePath, "-C", destinationDir], 120000);
|
|
16095
16143
|
return;
|
|
16096
16144
|
}
|
|
16097
|
-
|
|
16145
|
+
execFileSync2("unzip", ["-q", archivePath, "-d", destinationDir], {
|
|
16098
16146
|
stdio: "pipe",
|
|
16099
16147
|
timeout: 120000
|
|
16100
16148
|
});
|
|
@@ -16107,13 +16155,13 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
16107
16155
|
...sha256 ? { sha256 } : {},
|
|
16108
16156
|
archiveSha256
|
|
16109
16157
|
};
|
|
16110
|
-
writeFileSync3(
|
|
16158
|
+
writeFileSync3(join13(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
16111
16159
|
} catch (err) {
|
|
16112
16160
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
16113
16161
|
}
|
|
16114
16162
|
}
|
|
16115
16163
|
function readOnnxInstalledMeta(installDir) {
|
|
16116
|
-
const path =
|
|
16164
|
+
const path = join13(installDir, ONNX_INSTALLED_META_FILE);
|
|
16117
16165
|
try {
|
|
16118
16166
|
if (!statSync6(path).isFile())
|
|
16119
16167
|
return null;
|
|
@@ -16225,7 +16273,7 @@ function isWindowsProcessAlive(pid) {
|
|
|
16225
16273
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
16226
16274
|
return false;
|
|
16227
16275
|
try {
|
|
16228
|
-
const output =
|
|
16276
|
+
const output = execFileSync2("tasklist.exe", ["/FI", `PID eq ${pid}`, "/FO", "CSV", "/NH"], {
|
|
16229
16277
|
encoding: "utf8",
|
|
16230
16278
|
timeout: 2000,
|
|
16231
16279
|
windowsHide: true
|
|
@@ -16446,10 +16494,8 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
|
|
|
16446
16494
|
if (unknownRootKeys.length > 0) {
|
|
16447
16495
|
throw new InvalidRequestError(formatUnknownKeys(unknownRootKeys));
|
|
16448
16496
|
}
|
|
16497
|
+
validateSymbolModePair(record);
|
|
16449
16498
|
const modes = editModesPresent(record);
|
|
16450
|
-
if (hasOrphanedSymbolContent(record)) {
|
|
16451
|
-
throw new InvalidRequestError("edit: 'content' requires a non-empty string 'symbol' when symbol mode is selected");
|
|
16452
|
-
}
|
|
16453
16499
|
if (modes.length > 1) {
|
|
16454
16500
|
throw new InvalidRequestError(`edit: conflicting modes: ${modes.join(", ")}. ${OMIT_OPTIONAL_FIELDS_STEERING}`);
|
|
16455
16501
|
}
|
|
@@ -16469,7 +16515,7 @@ function prepareCanonicalEditArguments(toolName, rawArguments) {
|
|
|
16469
16515
|
throw new InvalidRequestError("edit: 'symbol' must be a string when symbol mode is selected");
|
|
16470
16516
|
}
|
|
16471
16517
|
if (!hasOwn(record, "content") || typeof record.content !== "string") {
|
|
16472
|
-
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[]`.");
|
|
16473
16519
|
}
|
|
16474
16520
|
} else {
|
|
16475
16521
|
const item = {};
|
|
@@ -16522,6 +16568,29 @@ function validateEditPath(record) {
|
|
|
16522
16568
|
function formatUnknownKeys(keys) {
|
|
16523
16569
|
return `Unrecognized keys: ${keys.map((key) => `"${key}"`).join(", ")}`;
|
|
16524
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
|
+
}
|
|
16525
16594
|
function editModesPresent(record) {
|
|
16526
16595
|
const hasAppendContent = isNonEmptyString(record.appendContent);
|
|
16527
16596
|
if (!hasAppendContent)
|
|
@@ -16607,9 +16676,6 @@ function normalizeEditArraySentinels(record) {
|
|
|
16607
16676
|
return true;
|
|
16608
16677
|
}
|
|
16609
16678
|
}
|
|
16610
|
-
function hasOrphanedSymbolContent(record) {
|
|
16611
|
-
return isNonEmptyString(record.content) && !isNonEmptyString(record.symbol);
|
|
16612
|
-
}
|
|
16613
16679
|
function parseEditArray(value) {
|
|
16614
16680
|
if (typeof value === "string") {
|
|
16615
16681
|
let parsed;
|
|
@@ -16792,8 +16858,50 @@ function copyOwnProperties(source) {
|
|
|
16792
16858
|
copy[key] = source[key];
|
|
16793
16859
|
return copy;
|
|
16794
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
|
+
}
|
|
16795
16903
|
// src/config.ts
|
|
16796
|
-
import { existsSync as
|
|
16904
|
+
import { existsSync as existsSync11, readFileSync as readFileSync7, renameSync as renameSync6, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
16797
16905
|
import { homedir as homedir10 } from "node:os";
|
|
16798
16906
|
import { isAbsolute as isAbsolute6, parse as parsePath, resolve as resolvePath } from "node:path";
|
|
16799
16907
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
@@ -22024,7 +22132,7 @@ function migrateExperimentalBashBlock(rawConfig, configPath, logger) {
|
|
|
22024
22132
|
return movedKeys;
|
|
22025
22133
|
}
|
|
22026
22134
|
function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 }) {
|
|
22027
|
-
if (!
|
|
22135
|
+
if (!existsSync11(configPath)) {
|
|
22028
22136
|
return { migrated: false, oldKeys: [] };
|
|
22029
22137
|
}
|
|
22030
22138
|
let tmpPath = null;
|
|
@@ -22048,7 +22156,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
|
|
|
22048
22156
|
${serialized}` : serialized;
|
|
22049
22157
|
tmpPath = `${configPath}.tmp.${process.pid}`;
|
|
22050
22158
|
writeFileSync4(tmpPath, nextContent, "utf-8");
|
|
22051
|
-
|
|
22159
|
+
renameSync6(tmpPath, configPath);
|
|
22052
22160
|
logger.log(`Migrated config at ${configPath}: removed ${oldKeys.join(", ")}`);
|
|
22053
22161
|
return { migrated: true, oldKeys };
|
|
22054
22162
|
} catch (err) {
|
|
@@ -22109,7 +22217,7 @@ function recordConfigParseFailure(configPath, errorMessage) {
|
|
|
22109
22217
|
}
|
|
22110
22218
|
function loadConfigFromPath(configPath) {
|
|
22111
22219
|
try {
|
|
22112
|
-
if (!
|
|
22220
|
+
if (!existsSync11(configPath)) {
|
|
22113
22221
|
return null;
|
|
22114
22222
|
}
|
|
22115
22223
|
const content = readFileSync7(configPath, "utf-8");
|
|
@@ -22449,7 +22557,7 @@ function loadAftConfig(projectDirectory) {
|
|
|
22449
22557
|
}
|
|
22450
22558
|
|
|
22451
22559
|
// src/tools/_shared.ts
|
|
22452
|
-
import { existsSync as
|
|
22560
|
+
import { existsSync as existsSync12 } from "node:fs";
|
|
22453
22561
|
import * as os2 from "node:os";
|
|
22454
22562
|
import * as path2 from "node:path";
|
|
22455
22563
|
|
|
@@ -34862,6 +34970,7 @@ var DEBOUNCE_STEP_MS = 200;
|
|
|
34862
34970
|
var DEBOUNCE_CAP_MS = 1000;
|
|
34863
34971
|
var MAX_WAKE_SEND_ATTEMPTS = 5;
|
|
34864
34972
|
var DEFAULT_WAKE_CONFIRMATION_WINDOW_MS = 5000;
|
|
34973
|
+
var BUSY_WAKE_DEFER_CEILING_MS = 60000;
|
|
34865
34974
|
var UNKNOWN_COMPLETION_TTL_MS = 5000;
|
|
34866
34975
|
var UNKNOWN_COMPLETION_CAP = 32;
|
|
34867
34976
|
var DEFAULT_SESSION_ID2 = "__default__";
|
|
@@ -34893,10 +35002,12 @@ function logDroppedForeignSessionFrame(drainContext, droppedSessionId, liveSessi
|
|
|
34893
35002
|
var DEFAULT_BG_HOP_TIMEOUT_MS = 15000;
|
|
34894
35003
|
var bgHopTimeoutMs = DEFAULT_BG_HOP_TIMEOUT_MS;
|
|
34895
35004
|
var wakeConfirmationWindowMs = DEFAULT_WAKE_CONFIRMATION_WINDOW_MS;
|
|
35005
|
+
var busyWakeDeferCeilingMs = BUSY_WAKE_DEFER_CEILING_MS;
|
|
34896
35006
|
var lastWakeMessageTimestamp = 0;
|
|
34897
35007
|
var wakeMessageCounter = 0;
|
|
34898
35008
|
var subcNudgesInFlight = new Map;
|
|
34899
35009
|
var subcNudgeLogState = new Map;
|
|
35010
|
+
var deferredBusyWakes = new Map;
|
|
34900
35011
|
function consumeBgCompletion(sessionID, taskId) {
|
|
34901
35012
|
const state = stateFor(sessionID);
|
|
34902
35013
|
state.pendingCompletions = state.pendingCompletions.filter((c) => c.task_id !== taskId);
|
|
@@ -34911,6 +35022,9 @@ function consumeBgCompletion(sessionID, taskId) {
|
|
|
34911
35022
|
}
|
|
34912
35023
|
}
|
|
34913
35024
|
clearWakeTimerIfNoPending(state);
|
|
35025
|
+
if (state.pendingCompletions.length === 0 && state.pendingLongRunning.length === 0 && state.pendingPatternMatches.length === 0) {
|
|
35026
|
+
clearDeferredBusyWake(sessionID || DEFAULT_SESSION_ID2);
|
|
35027
|
+
}
|
|
34914
35028
|
}
|
|
34915
35029
|
async function markBgCompletionDelivered(drainContext, taskId) {
|
|
34916
35030
|
const state = stateFor(drainContext.sessionID);
|
|
@@ -35016,7 +35130,7 @@ async function handlePushedPatternMatch(drainContext, frame) {
|
|
|
35016
35130
|
}
|
|
35017
35131
|
const state = stateFor(drainContext.sessionID);
|
|
35018
35132
|
queuePendingPatternMatch(state, { ...frame, ackCompletionOnDelivery: true });
|
|
35019
|
-
await triggerWakeIfPending(drainContext, true);
|
|
35133
|
+
await triggerWakeIfPending(drainContext, true, true, false, true);
|
|
35020
35134
|
}
|
|
35021
35135
|
function ingestBgCompletions(sessionID, completions) {
|
|
35022
35136
|
if (!Array.isArray(completions) || completions.length === 0)
|
|
@@ -35054,11 +35168,11 @@ function ingestBgCompletions(sessionID, completions) {
|
|
|
35054
35168
|
}
|
|
35055
35169
|
async function handlePushedBgCompletion(drainContext, completion) {
|
|
35056
35170
|
ingestBgCompletions(drainContext.sessionID, [completion]);
|
|
35057
|
-
await triggerWakeIfPending(drainContext, true, false);
|
|
35171
|
+
await triggerWakeIfPending(drainContext, true, false, false, true);
|
|
35058
35172
|
}
|
|
35059
35173
|
async function handlePushedBgLongRunning(drainContext, reminder) {
|
|
35060
35174
|
stateFor(drainContext.sessionID).pendingLongRunning.push(reminder);
|
|
35061
|
-
await triggerWakeIfPending(drainContext, true);
|
|
35175
|
+
await triggerWakeIfPending(drainContext, true, true, false, true);
|
|
35062
35176
|
}
|
|
35063
35177
|
async function appendInTurnBgCompletions(drainContext, output) {
|
|
35064
35178
|
if (!output)
|
|
@@ -35103,6 +35217,7 @@ async function appendInTurnBgCompletions(drainContext, output) {
|
|
|
35103
35217
|
if (inTurnAcked)
|
|
35104
35218
|
confirmAcked(state, inTurnAckIds);
|
|
35105
35219
|
clearWakeTimerIfNoPending(state);
|
|
35220
|
+
clearDeferredBusyWake(drainContext.sessionID);
|
|
35106
35221
|
}
|
|
35107
35222
|
async function handleIdleBgCompletions(drainContext) {
|
|
35108
35223
|
stateFor(drainContext.sessionID).wakeDeferredTaskIds.clear();
|
|
@@ -35130,7 +35245,7 @@ async function handleSubcBgEventsNudgeOnce(drainContext) {
|
|
|
35130
35245
|
const state = stateFor(drainContext.sessionID);
|
|
35131
35246
|
state.wakeDeferredTaskIds.clear();
|
|
35132
35247
|
rearmHardStoppedWake(state, drainContext);
|
|
35133
|
-
await triggerWakeIfPending(drainContext, false, true, true);
|
|
35248
|
+
await triggerWakeIfPending(drainContext, false, true, true, true);
|
|
35134
35249
|
}
|
|
35135
35250
|
function logSubcNudgeLifecycle(drainContext, kind, message) {
|
|
35136
35251
|
logDeliveryHop(drainContext, kind, message, {
|
|
@@ -35345,6 +35460,42 @@ function registerWakeAdmission(state, admission) {
|
|
|
35345
35460
|
}, wakeConfirmationWindowMs);
|
|
35346
35461
|
tracked.confirmationTimer.unref?.();
|
|
35347
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
|
+
}
|
|
35348
35499
|
function observeOpenCodeBgNotificationEvent(event) {
|
|
35349
35500
|
try {
|
|
35350
35501
|
if (!event || typeof event !== "object")
|
|
@@ -35393,12 +35544,17 @@ function observeOpenCodeBgNotificationEvent(event) {
|
|
|
35393
35544
|
return;
|
|
35394
35545
|
}
|
|
35395
35546
|
if (nextStatus === "idle") {
|
|
35547
|
+
const deferred = clearDeferredBusyWake(sessionID);
|
|
35548
|
+
if (deferred)
|
|
35549
|
+
triggerWakeIfPending(deferred.context, true).catch(() => {
|
|
35550
|
+
return;
|
|
35551
|
+
});
|
|
35396
35552
|
for (const admission of state.wakeAdmissions.values())
|
|
35397
35553
|
queueWakeRefire(state, admission);
|
|
35398
35554
|
}
|
|
35399
35555
|
} catch {}
|
|
35400
35556
|
}
|
|
35401
|
-
async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false) {
|
|
35557
|
+
async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredCompletions = true, forceDrain = false, deferWhileBusy = false) {
|
|
35402
35558
|
const state = stateFor(drainContext.sessionID);
|
|
35403
35559
|
if (!skipDrain && (forceDrain || state.outstandingTaskIds.size > 0 || !state.forcedDrainCompleted)) {
|
|
35404
35560
|
await drainCompletions(drainContext);
|
|
@@ -35406,6 +35562,10 @@ async function triggerWakeIfPending(drainContext, skipDrain, includeDeferredComp
|
|
|
35406
35562
|
routeExplicitControlCompletions(state);
|
|
35407
35563
|
if (!hasWakeEligiblePending(state, includeDeferredCompletions))
|
|
35408
35564
|
return;
|
|
35565
|
+
if (deferWhileBusy && state.hostStatus === "busy") {
|
|
35566
|
+
deferBusyWake(drainContext);
|
|
35567
|
+
return;
|
|
35568
|
+
}
|
|
35409
35569
|
scheduleWake(state, async (reminder, deliveredCompletions, deliveredPatternMatches) => {
|
|
35410
35570
|
const liveSession = getActiveSessionId() ?? drainContext.sessionID;
|
|
35411
35571
|
if (liveSession && drainContext.sessionID && drainContext.sessionID !== liveSession) {
|
|
@@ -36247,7 +36407,7 @@ function bridgeFor(ctx, runtime) {
|
|
|
36247
36407
|
if (ctx.isProjectEnabled?.(projectRoot) === false) {
|
|
36248
36408
|
throw new Error(`AFT disabled by config for ${projectRoot}`);
|
|
36249
36409
|
}
|
|
36250
|
-
if (!
|
|
36410
|
+
if (!existsSync12(projectRoot)) {
|
|
36251
36411
|
throw new Error(`project directory no longer exists: ${projectRoot} (stale restored session?)`);
|
|
36252
36412
|
}
|
|
36253
36413
|
return ctx.pool.getBridge(projectRoot);
|
|
@@ -36404,9 +36564,9 @@ async function signalBashWaitDetachForProject(pool, projectRoot, sessionID) {
|
|
|
36404
36564
|
}
|
|
36405
36565
|
|
|
36406
36566
|
// src/notifications.ts
|
|
36407
|
-
import { existsSync as
|
|
36567
|
+
import { existsSync as existsSync13, readFileSync as readFileSync8 } from "node:fs";
|
|
36408
36568
|
import { homedir as homedir12, platform } from "node:os";
|
|
36409
|
-
import { join as
|
|
36569
|
+
import { join as join14 } from "node:path";
|
|
36410
36570
|
function isTuiMode() {
|
|
36411
36571
|
return process.env.OPENCODE_CLIENT === "cli";
|
|
36412
36572
|
}
|
|
@@ -36428,21 +36588,21 @@ function getDesktopStatePath() {
|
|
|
36428
36588
|
const os = platform();
|
|
36429
36589
|
const home = homedir12();
|
|
36430
36590
|
if (os === "darwin") {
|
|
36431
|
-
return
|
|
36591
|
+
return join14(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
|
|
36432
36592
|
}
|
|
36433
36593
|
if (os === "linux") {
|
|
36434
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
36435
|
-
return
|
|
36594
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join14(home, ".config");
|
|
36595
|
+
return join14(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
|
|
36436
36596
|
}
|
|
36437
36597
|
if (os === "win32") {
|
|
36438
|
-
const appData = process.env.APPDATA ||
|
|
36439
|
-
return
|
|
36598
|
+
const appData = process.env.APPDATA || join14(home, "AppData", "Roaming");
|
|
36599
|
+
return join14(appData, "ai.opencode.desktop", "opencode.global.dat");
|
|
36440
36600
|
}
|
|
36441
36601
|
return null;
|
|
36442
36602
|
}
|
|
36443
36603
|
function readDesktopState() {
|
|
36444
36604
|
const statePath = getDesktopStatePath();
|
|
36445
|
-
if (!statePath || !
|
|
36605
|
+
if (!statePath || !existsSync13(statePath)) {
|
|
36446
36606
|
return { serverUrl: null };
|
|
36447
36607
|
}
|
|
36448
36608
|
try {
|
|
@@ -36942,11 +37102,11 @@ async function flushConfigureWarningsOnIdle(sessionId) {
|
|
|
36942
37102
|
// src/hooks/auto-update-checker/index.ts
|
|
36943
37103
|
import {
|
|
36944
37104
|
closeSync as closeSync5,
|
|
36945
|
-
existsSync as
|
|
37105
|
+
existsSync as existsSync16,
|
|
36946
37106
|
mkdirSync as mkdirSync6,
|
|
36947
37107
|
openSync as openSync5,
|
|
36948
37108
|
readFileSync as readFileSync11,
|
|
36949
|
-
renameSync as
|
|
37109
|
+
renameSync as renameSync7,
|
|
36950
37110
|
rmSync as rmSync5,
|
|
36951
37111
|
statSync as statSync8,
|
|
36952
37112
|
writeFileSync as writeFileSync7
|
|
@@ -36955,30 +37115,30 @@ import { dirname as dirname8 } from "node:path";
|
|
|
36955
37115
|
|
|
36956
37116
|
// src/hooks/auto-update-checker/cache.ts
|
|
36957
37117
|
import { spawn as spawn4 } from "node:child_process";
|
|
36958
|
-
import { cpSync, existsSync as
|
|
37118
|
+
import { cpSync, existsSync as existsSync15, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
|
|
36959
37119
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
36960
|
-
import { basename as basename3, dirname as dirname7, join as
|
|
37120
|
+
import { basename as basename3, dirname as dirname7, join as join17 } from "node:path";
|
|
36961
37121
|
var import_comment_json3 = __toESM(require_src2(), 1);
|
|
36962
37122
|
|
|
36963
37123
|
// src/hooks/auto-update-checker/checker.ts
|
|
36964
|
-
import { existsSync as
|
|
36965
|
-
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";
|
|
36966
37126
|
import { fileURLToPath } from "node:url";
|
|
36967
37127
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
36968
37128
|
|
|
36969
37129
|
// src/hooks/auto-update-checker/constants.ts
|
|
36970
|
-
import { join as
|
|
37130
|
+
import { join as join15 } from "node:path";
|
|
36971
37131
|
var PACKAGE_NAME = "@cortexkit/aft-opencode";
|
|
36972
37132
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
36973
37133
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
36974
37134
|
function cacheDir() {
|
|
36975
|
-
return
|
|
37135
|
+
return join15(getOpenCodeCacheRoot(), "packages");
|
|
36976
37136
|
}
|
|
36977
37137
|
function userOpenCodeConfig() {
|
|
36978
|
-
return
|
|
37138
|
+
return join15(getOpenCodeConfigRoot(), "opencode.json");
|
|
36979
37139
|
}
|
|
36980
37140
|
function userOpenCodeConfigJsonc() {
|
|
36981
|
-
return
|
|
37141
|
+
return join15(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
36982
37142
|
}
|
|
36983
37143
|
|
|
36984
37144
|
// src/hooks/auto-update-checker/types.ts
|
|
@@ -37037,8 +37197,8 @@ function extractChannel(version) {
|
|
|
37037
37197
|
}
|
|
37038
37198
|
function getConfigPaths(directory) {
|
|
37039
37199
|
return [
|
|
37040
|
-
|
|
37041
|
-
|
|
37200
|
+
join16(directory, ".opencode", "opencode.json"),
|
|
37201
|
+
join16(directory, ".opencode", "opencode.jsonc"),
|
|
37042
37202
|
userOpenCodeConfig(),
|
|
37043
37203
|
userOpenCodeConfigJsonc()
|
|
37044
37204
|
];
|
|
@@ -37058,7 +37218,7 @@ function resolvePathPluginSpec(spec, configPath) {
|
|
|
37058
37218
|
function getLocalDevPath(directory) {
|
|
37059
37219
|
for (const configPath of getConfigPaths(directory)) {
|
|
37060
37220
|
try {
|
|
37061
|
-
if (!
|
|
37221
|
+
if (!existsSync14(configPath))
|
|
37062
37222
|
continue;
|
|
37063
37223
|
const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
|
|
37064
37224
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -37084,8 +37244,8 @@ function findPackageJsonUp(startPath) {
|
|
|
37084
37244
|
const stat = statSync7(startPath);
|
|
37085
37245
|
let dir = stat.isDirectory() ? startPath : dirname6(startPath);
|
|
37086
37246
|
for (let i = 0;i < 10; i++) {
|
|
37087
|
-
const pkgPath =
|
|
37088
|
-
if (
|
|
37247
|
+
const pkgPath = join16(dir, "package.json");
|
|
37248
|
+
if (existsSync14(pkgPath)) {
|
|
37089
37249
|
try {
|
|
37090
37250
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
|
|
37091
37251
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
@@ -37125,7 +37285,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
|
37125
37285
|
function findPluginEntry(directory) {
|
|
37126
37286
|
for (const configPath of getConfigPaths(directory)) {
|
|
37127
37287
|
try {
|
|
37128
|
-
if (!
|
|
37288
|
+
if (!existsSync14(configPath))
|
|
37129
37289
|
continue;
|
|
37130
37290
|
const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
|
|
37131
37291
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -37145,7 +37305,7 @@ function findPluginEntry(directory) {
|
|
|
37145
37305
|
}
|
|
37146
37306
|
var cachedPackageVersion = null;
|
|
37147
37307
|
function getSpecCachePackageJsonPath(spec) {
|
|
37148
|
-
return
|
|
37308
|
+
return join16(cacheDir(), spec, "node_modules", PACKAGE_NAME, "package.json");
|
|
37149
37309
|
}
|
|
37150
37310
|
function getCachedVersion(spec) {
|
|
37151
37311
|
if (!spec && cachedPackageVersion)
|
|
@@ -37154,11 +37314,11 @@ function getCachedVersion(spec) {
|
|
|
37154
37314
|
getCurrentRuntimePackageJsonPath(),
|
|
37155
37315
|
spec ? getSpecCachePackageJsonPath(spec) : null,
|
|
37156
37316
|
getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
|
|
37157
|
-
|
|
37317
|
+
join16(getOpenCodeCacheRoot(), "node_modules", PACKAGE_NAME, "package.json")
|
|
37158
37318
|
].filter(isString);
|
|
37159
37319
|
for (const packageJsonPath of candidates) {
|
|
37160
37320
|
try {
|
|
37161
|
-
if (!
|
|
37321
|
+
if (!existsSync14(packageJsonPath))
|
|
37162
37322
|
continue;
|
|
37163
37323
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(packageJsonPath, "utf-8")));
|
|
37164
37324
|
if (pkg.success && pkg.data.version) {
|
|
@@ -37203,17 +37363,17 @@ async function getLatestVersion(channel = "latest", options = {}) {
|
|
|
37203
37363
|
var pendingSnapshots = new Map;
|
|
37204
37364
|
var quarantinedInstallDirs = new Set;
|
|
37205
37365
|
function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
|
|
37206
|
-
const packageDir =
|
|
37207
|
-
const lockfilePath =
|
|
37208
|
-
const tempDir = mkdtempSync(
|
|
37209
|
-
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;
|
|
37210
37370
|
if (stagedPackageDir)
|
|
37211
37371
|
cpSync(packageDir, stagedPackageDir, { recursive: true });
|
|
37212
37372
|
return {
|
|
37213
37373
|
packageJsonPath,
|
|
37214
|
-
packageJson:
|
|
37374
|
+
packageJson: existsSync15(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
|
|
37215
37375
|
lockfilePath,
|
|
37216
|
-
lockfile:
|
|
37376
|
+
lockfile: existsSync15(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
|
|
37217
37377
|
packageDir,
|
|
37218
37378
|
stagedPackageDir,
|
|
37219
37379
|
tempDir
|
|
@@ -37247,8 +37407,8 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
37247
37407
|
return current;
|
|
37248
37408
|
}
|
|
37249
37409
|
function removeFromPackageLock(installDir, packageName) {
|
|
37250
|
-
const lockPath =
|
|
37251
|
-
if (!
|
|
37410
|
+
const lockPath = join17(installDir, "package-lock.json");
|
|
37411
|
+
if (!existsSync15(lockPath))
|
|
37252
37412
|
return false;
|
|
37253
37413
|
try {
|
|
37254
37414
|
const lock = import_comment_json3.parse(readFileSync10(lockPath, "utf-8"));
|
|
@@ -37274,7 +37434,7 @@ function removeFromPackageLock(installDir, packageName) {
|
|
|
37274
37434
|
}
|
|
37275
37435
|
}
|
|
37276
37436
|
function ensureDependencyVersion(packageJsonPath, packageName, version) {
|
|
37277
|
-
if (!
|
|
37437
|
+
if (!existsSync15(packageJsonPath))
|
|
37278
37438
|
return false;
|
|
37279
37439
|
try {
|
|
37280
37440
|
const raw = import_comment_json3.parse(readFileSync10(packageJsonPath, "utf-8"));
|
|
@@ -37303,8 +37463,8 @@ function restorePendingSnapshot(installDir) {
|
|
|
37303
37463
|
restoreAutoUpdateSnapshot(snapshot);
|
|
37304
37464
|
}
|
|
37305
37465
|
function removeInstalledPackage(installDir, packageName) {
|
|
37306
|
-
const packageDir =
|
|
37307
|
-
if (!
|
|
37466
|
+
const packageDir = join17(installDir, "node_modules", packageName);
|
|
37467
|
+
if (!existsSync15(packageDir))
|
|
37308
37468
|
return false;
|
|
37309
37469
|
rmSync4(packageDir, { recursive: true, force: true });
|
|
37310
37470
|
log2(`[auto-update-checker] Package removed: ${packageDir}`);
|
|
@@ -37316,15 +37476,15 @@ function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackage
|
|
|
37316
37476
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
37317
37477
|
if (nodeModulesDir && basename3(nodeModulesDir) === "node_modules") {
|
|
37318
37478
|
const installDir = dirname7(nodeModulesDir);
|
|
37319
|
-
const packageJsonPath =
|
|
37320
|
-
if (
|
|
37479
|
+
const packageJsonPath = join17(installDir, "package.json");
|
|
37480
|
+
if (existsSync15(packageJsonPath))
|
|
37321
37481
|
return { installDir, packageJsonPath };
|
|
37322
37482
|
}
|
|
37323
37483
|
return null;
|
|
37324
37484
|
}
|
|
37325
37485
|
const cacheRoot = dirname7(cacheDir());
|
|
37326
|
-
const legacyPackageJsonPath =
|
|
37327
|
-
if (
|
|
37486
|
+
const legacyPackageJsonPath = join17(cacheRoot, "package.json");
|
|
37487
|
+
if (existsSync15(legacyPackageJsonPath)) {
|
|
37328
37488
|
return { installDir: cacheRoot, packageJsonPath: legacyPackageJsonPath };
|
|
37329
37489
|
}
|
|
37330
37490
|
return null;
|
|
@@ -37547,7 +37707,7 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
37547
37707
|
const replacementPath = `${lockPath}.tmp.${process.pid}`;
|
|
37548
37708
|
writeFileSync7(replacementPath, JSON.stringify(owner), { encoding: "utf-8", mode: 384 });
|
|
37549
37709
|
try {
|
|
37550
|
-
|
|
37710
|
+
renameSync7(replacementPath, lockPath);
|
|
37551
37711
|
} catch (replaceError) {
|
|
37552
37712
|
rmSync5(replacementPath, { force: true });
|
|
37553
37713
|
throw replaceError;
|
|
@@ -37615,7 +37775,7 @@ function checkLockIsOwnedBy(lockPath, owner) {
|
|
|
37615
37775
|
}
|
|
37616
37776
|
}
|
|
37617
37777
|
function hasRecentCheckTimestamp(file, intervalMs) {
|
|
37618
|
-
if (!
|
|
37778
|
+
if (!existsSync16(file))
|
|
37619
37779
|
return false;
|
|
37620
37780
|
try {
|
|
37621
37781
|
const raw = JSON.parse(readFileSync11(file, "utf-8"));
|
|
@@ -37628,7 +37788,7 @@ function hasRecentCheckTimestamp(file, intervalMs) {
|
|
|
37628
37788
|
function writeCheckTimestamp(file) {
|
|
37629
37789
|
const tmp = `${file}.tmp.${process.pid}`;
|
|
37630
37790
|
writeFileSync7(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
|
|
37631
|
-
|
|
37791
|
+
renameSync7(tmp, file);
|
|
37632
37792
|
}
|
|
37633
37793
|
async function runStartupCheck(ctx, options) {
|
|
37634
37794
|
if (options.signal.aborted)
|
|
@@ -37725,15 +37885,15 @@ import { spawn as spawn5 } from "node:child_process";
|
|
|
37725
37885
|
import { createHash as createHash6 } from "node:crypto";
|
|
37726
37886
|
import {
|
|
37727
37887
|
createReadStream,
|
|
37728
|
-
existsSync as
|
|
37888
|
+
existsSync as existsSync18,
|
|
37729
37889
|
mkdirSync as mkdirSync8,
|
|
37730
37890
|
readFileSync as readFileSync14,
|
|
37731
|
-
renameSync as
|
|
37891
|
+
renameSync as renameSync9,
|
|
37732
37892
|
rmSync as rmSync7,
|
|
37733
37893
|
statSync as statSync10,
|
|
37734
37894
|
writeFileSync as writeFileSync9
|
|
37735
37895
|
} from "node:fs";
|
|
37736
|
-
import { join as
|
|
37896
|
+
import { join as join20 } from "node:path";
|
|
37737
37897
|
|
|
37738
37898
|
// src/lsp-cache.ts
|
|
37739
37899
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
@@ -37742,13 +37902,13 @@ import {
|
|
|
37742
37902
|
mkdirSync as mkdirSync7,
|
|
37743
37903
|
openSync as openSync6,
|
|
37744
37904
|
readFileSync as readFileSync12,
|
|
37745
|
-
renameSync as
|
|
37905
|
+
renameSync as renameSync8,
|
|
37746
37906
|
rmSync as rmSync6,
|
|
37747
37907
|
statSync as statSync9,
|
|
37748
37908
|
unlinkSync as unlinkSync6,
|
|
37749
37909
|
writeFileSync as writeFileSync8
|
|
37750
37910
|
} from "node:fs";
|
|
37751
|
-
import { join as
|
|
37911
|
+
import { join as join18 } from "node:path";
|
|
37752
37912
|
function aftCacheBase() {
|
|
37753
37913
|
return getAftCacheRoot();
|
|
37754
37914
|
}
|
|
@@ -37756,18 +37916,18 @@ function lspCacheRoot() {
|
|
|
37756
37916
|
return getAftLspPackagesDir();
|
|
37757
37917
|
}
|
|
37758
37918
|
function lspPackageDir(npmPackage) {
|
|
37759
|
-
return
|
|
37919
|
+
return join18(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
37760
37920
|
}
|
|
37761
37921
|
function lspBinaryPath(npmPackage, binary) {
|
|
37762
|
-
return
|
|
37922
|
+
return join18(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
37763
37923
|
}
|
|
37764
37924
|
function lspBinDir(npmPackage) {
|
|
37765
|
-
return
|
|
37925
|
+
return join18(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
37766
37926
|
}
|
|
37767
37927
|
function isInstalled(npmPackage, binary) {
|
|
37768
37928
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
37769
37929
|
try {
|
|
37770
|
-
if (statSync9(
|
|
37930
|
+
if (statSync9(join18(lspBinDir(npmPackage), candidate)).isFile())
|
|
37771
37931
|
return true;
|
|
37772
37932
|
} catch {}
|
|
37773
37933
|
}
|
|
@@ -37787,13 +37947,13 @@ function writeInstalledMetaIn(installDir, version, sha256) {
|
|
|
37787
37947
|
installedAt: new Date().toISOString(),
|
|
37788
37948
|
...sha256 ? { sha256 } : {}
|
|
37789
37949
|
};
|
|
37790
|
-
writeFileSync8(
|
|
37950
|
+
writeFileSync8(join18(installDir, INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
37791
37951
|
} catch (err) {
|
|
37792
37952
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
37793
37953
|
}
|
|
37794
37954
|
}
|
|
37795
37955
|
function readInstalledMetaIn(installDir) {
|
|
37796
|
-
const path =
|
|
37956
|
+
const path = join18(installDir, INSTALLED_META_FILE);
|
|
37797
37957
|
try {
|
|
37798
37958
|
if (!statSync9(path).isFile())
|
|
37799
37959
|
return null;
|
|
@@ -37817,7 +37977,7 @@ function readInstalledMeta(packageKey) {
|
|
|
37817
37977
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
37818
37978
|
}
|
|
37819
37979
|
function lockPath(npmPackage) {
|
|
37820
|
-
return
|
|
37980
|
+
return join18(lspPackageDir(npmPackage), ".aft-installing");
|
|
37821
37981
|
}
|
|
37822
37982
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
37823
37983
|
function acquireInstallLock(lockKey) {
|
|
@@ -37948,7 +38108,7 @@ var AUTO_INSTALL_STAMP_FILE = "last-lsp-autoinstall.json";
|
|
|
37948
38108
|
var AUTO_INSTALL_WINDOW_MS = 60 * 1000;
|
|
37949
38109
|
var AUTO_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000;
|
|
37950
38110
|
function autoInstallStampPath() {
|
|
37951
|
-
return
|
|
38111
|
+
return join18(aftCacheBase(), AUTO_INSTALL_STAMP_FILE);
|
|
37952
38112
|
}
|
|
37953
38113
|
function hasRecentAutoInstallStamp(path) {
|
|
37954
38114
|
try {
|
|
@@ -38034,7 +38194,7 @@ function claimLspAutoInstallPass() {
|
|
|
38034
38194
|
encoding: "utf8",
|
|
38035
38195
|
mode: 384
|
|
38036
38196
|
});
|
|
38037
|
-
|
|
38197
|
+
renameSync8(tempPath, stampPath);
|
|
38038
38198
|
return { release };
|
|
38039
38199
|
} catch (err) {
|
|
38040
38200
|
if (claimed) {
|
|
@@ -38049,7 +38209,7 @@ function claimLspAutoInstallPass() {
|
|
|
38049
38209
|
}
|
|
38050
38210
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
38051
38211
|
function readVersionCheck(npmPackage) {
|
|
38052
|
-
const file =
|
|
38212
|
+
const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
38053
38213
|
try {
|
|
38054
38214
|
const raw = readFileSync12(file, "utf8");
|
|
38055
38215
|
const parsed = JSON.parse(raw);
|
|
@@ -38066,7 +38226,7 @@ function readVersionCheck(npmPackage) {
|
|
|
38066
38226
|
}
|
|
38067
38227
|
function writeVersionCheck(npmPackage, latest) {
|
|
38068
38228
|
mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
|
|
38069
|
-
const file =
|
|
38229
|
+
const file = join18(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
38070
38230
|
const record = {
|
|
38071
38231
|
last_checked: new Date().toISOString(),
|
|
38072
38232
|
latest_eligible: latest
|
|
@@ -38228,8 +38388,8 @@ var NPM_LSP_TABLE = [
|
|
|
38228
38388
|
];
|
|
38229
38389
|
|
|
38230
38390
|
// src/lsp-project-relevance.ts
|
|
38231
|
-
import { existsSync as
|
|
38232
|
-
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";
|
|
38233
38393
|
var MAX_WALK_DIRS = 200;
|
|
38234
38394
|
var MAX_WALK_DEPTH = 4;
|
|
38235
38395
|
var NOISE_DIRS = new Set([
|
|
@@ -38246,7 +38406,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
38246
38406
|
if (!rootMarkers)
|
|
38247
38407
|
return false;
|
|
38248
38408
|
for (const marker of rootMarkers) {
|
|
38249
|
-
if (
|
|
38409
|
+
if (existsSync17(join19(projectRoot, marker)))
|
|
38250
38410
|
return true;
|
|
38251
38411
|
}
|
|
38252
38412
|
return false;
|
|
@@ -38270,7 +38430,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
|
|
|
38270
38430
|
}
|
|
38271
38431
|
function readPackageJson(projectRoot) {
|
|
38272
38432
|
try {
|
|
38273
|
-
const raw = readFileSync13(
|
|
38433
|
+
const raw = readFileSync13(join19(projectRoot, "package.json"), "utf8");
|
|
38274
38434
|
const parsed = JSON.parse(raw);
|
|
38275
38435
|
if (typeof parsed !== "object" || parsed === null)
|
|
38276
38436
|
return null;
|
|
@@ -38300,7 +38460,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
38300
38460
|
for (const entry of entries) {
|
|
38301
38461
|
if (entry.isDirectory()) {
|
|
38302
38462
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
38303
|
-
queue.push({ dir:
|
|
38463
|
+
queue.push({ dir: join19(current.dir, entry.name), depth: current.depth + 1 });
|
|
38304
38464
|
}
|
|
38305
38465
|
continue;
|
|
38306
38466
|
}
|
|
@@ -38428,8 +38588,8 @@ async function resolveTargetVersion(spec, config, fetchImpl = fetch) {
|
|
|
38428
38588
|
}
|
|
38429
38589
|
function ensureInstallAnchor(cwd) {
|
|
38430
38590
|
try {
|
|
38431
|
-
const stub =
|
|
38432
|
-
if (!
|
|
38591
|
+
const stub = join20(cwd, "package.json");
|
|
38592
|
+
if (!existsSync18(stub)) {
|
|
38433
38593
|
writeFileSync9(stub, `${JSON.stringify({ name: "aft-lsp-cache", version: "0.0.0", private: true })}
|
|
38434
38594
|
`);
|
|
38435
38595
|
}
|
|
@@ -38655,12 +38815,12 @@ function sha256OfFileSync(path) {
|
|
|
38655
38815
|
}
|
|
38656
38816
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
38657
38817
|
const packageDir = lspPackageDir(spec.npm);
|
|
38658
|
-
const dest =
|
|
38818
|
+
const dest = join20(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
38659
38819
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
38660
38820
|
try {
|
|
38661
|
-
mkdirSync8(
|
|
38821
|
+
mkdirSync8(join20(dest, ".."), { recursive: true });
|
|
38662
38822
|
rmSync7(dest, { recursive: true, force: true });
|
|
38663
|
-
|
|
38823
|
+
renameSync9(packageDir, dest);
|
|
38664
38824
|
} catch (err) {
|
|
38665
38825
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: failed to quarantine cache entry: ${err}`);
|
|
38666
38826
|
}
|
|
@@ -38741,26 +38901,26 @@ async function pushLspPathsAfterAutoInstall(pool, projectRoot, cachedBinDirs) {
|
|
|
38741
38901
|
}
|
|
38742
38902
|
|
|
38743
38903
|
// src/lsp-github-install.ts
|
|
38744
|
-
import { execFileSync as
|
|
38904
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
38745
38905
|
import { createHash as createHash7, randomBytes as randomBytes3 } from "node:crypto";
|
|
38746
38906
|
import {
|
|
38747
38907
|
copyFileSync as copyFileSync4,
|
|
38748
38908
|
createReadStream as createReadStream2,
|
|
38749
38909
|
createWriteStream as createWriteStream3,
|
|
38750
|
-
existsSync as
|
|
38910
|
+
existsSync as existsSync19,
|
|
38751
38911
|
lstatSync as lstatSync2,
|
|
38752
38912
|
mkdirSync as mkdirSync9,
|
|
38753
38913
|
readdirSync as readdirSync5,
|
|
38754
38914
|
readFileSync as readFileSync15,
|
|
38755
38915
|
readlinkSync as readlinkSync2,
|
|
38756
38916
|
realpathSync as realpathSync3,
|
|
38757
|
-
renameSync as
|
|
38917
|
+
renameSync as renameSync10,
|
|
38758
38918
|
rmSync as rmSync8,
|
|
38759
38919
|
statSync as statSync11,
|
|
38760
38920
|
unlinkSync as unlinkSync7,
|
|
38761
38921
|
writeFileSync as writeFileSync10
|
|
38762
38922
|
} from "node:fs";
|
|
38763
|
-
import { dirname as dirname9, join as
|
|
38923
|
+
import { dirname as dirname9, join as join21, relative as relative3, resolve as resolve10 } from "node:path";
|
|
38764
38924
|
import { Readable as Readable3 } from "node:stream";
|
|
38765
38925
|
import { pipeline as pipeline3 } from "node:stream/promises";
|
|
38766
38926
|
|
|
@@ -38853,19 +39013,19 @@ function ghCacheRoot() {
|
|
|
38853
39013
|
return getAftLspBinariesDir();
|
|
38854
39014
|
}
|
|
38855
39015
|
function ghPackageDir(spec) {
|
|
38856
|
-
return
|
|
39016
|
+
return join21(ghCacheRoot(), spec.id);
|
|
38857
39017
|
}
|
|
38858
39018
|
function ghBinDir(spec) {
|
|
38859
|
-
return
|
|
39019
|
+
return join21(ghPackageDir(spec), "bin");
|
|
38860
39020
|
}
|
|
38861
39021
|
function ghExtractDir(spec) {
|
|
38862
|
-
return
|
|
39022
|
+
return join21(ghPackageDir(spec), "extracted");
|
|
38863
39023
|
}
|
|
38864
39024
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
38865
39025
|
var INSTALL_FAILED_FILE = ".aft-install-failed.json";
|
|
38866
39026
|
var INSTALL_FAILURE_BACKOFF_MS = 6 * 60 * 60 * 1000;
|
|
38867
39027
|
function installFailureMarkerPath(spec) {
|
|
38868
|
-
return
|
|
39028
|
+
return join21(ghPackageDir(spec), INSTALL_FAILED_FILE);
|
|
38869
39029
|
}
|
|
38870
39030
|
function readInstallFailureMarker(spec) {
|
|
38871
39031
|
try {
|
|
@@ -38886,7 +39046,7 @@ function writeInstallFailureMarker(spec, release, sha256, installError) {
|
|
|
38886
39046
|
mkdirSync9(dirname9(path), { recursive: true });
|
|
38887
39047
|
writeFileSync10(tempPath, `${JSON.stringify({ release, sha256, error: markerError, at: new Date().toISOString() })}
|
|
38888
39048
|
`, { encoding: "utf8", mode: 384 });
|
|
38889
|
-
|
|
39049
|
+
renameSync10(tempPath, path);
|
|
38890
39050
|
} catch (err) {
|
|
38891
39051
|
try {
|
|
38892
39052
|
rmSync8(tempPath, { force: true });
|
|
@@ -38907,12 +39067,12 @@ function isFreshInstallFailure(marker) {
|
|
|
38907
39067
|
}
|
|
38908
39068
|
function ghBinaryPath(spec, platform) {
|
|
38909
39069
|
const ext = platform === "win32" ? ".exe" : "";
|
|
38910
|
-
return
|
|
39070
|
+
return join21(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
38911
39071
|
}
|
|
38912
39072
|
function isGithubInstalled(spec, platform) {
|
|
38913
39073
|
for (const candidate of ghBinaryCandidates(spec, platform)) {
|
|
38914
39074
|
try {
|
|
38915
|
-
if (statSync11(
|
|
39075
|
+
if (statSync11(join21(ghBinDir(spec), candidate)).isFile())
|
|
38916
39076
|
return true;
|
|
38917
39077
|
} catch {}
|
|
38918
39078
|
}
|
|
@@ -38925,7 +39085,7 @@ function ghBinaryCandidates(spec, platform) {
|
|
|
38925
39085
|
}
|
|
38926
39086
|
function readGithubInstalledMetaIn(installDir) {
|
|
38927
39087
|
try {
|
|
38928
|
-
const path =
|
|
39088
|
+
const path = join21(installDir, INSTALLED_META_FILE2);
|
|
38929
39089
|
if (!statSync11(path).isFile())
|
|
38930
39090
|
return null;
|
|
38931
39091
|
const parsed = JSON.parse(readFileSync15(path, "utf8"));
|
|
@@ -38952,7 +39112,7 @@ function writeGithubInstalledMetaIn(installDir, version, binarySha256, archiveSh
|
|
|
38952
39112
|
binarySha256,
|
|
38953
39113
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
38954
39114
|
};
|
|
38955
|
-
writeFileSync10(
|
|
39115
|
+
writeFileSync10(join21(installDir, INSTALLED_META_FILE2), JSON.stringify(meta), "utf8");
|
|
38956
39116
|
} catch (err) {
|
|
38957
39117
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
38958
39118
|
}
|
|
@@ -39201,7 +39361,7 @@ function validateExtraction(stagingRoot) {
|
|
|
39201
39361
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
39202
39362
|
}
|
|
39203
39363
|
for (const entry of entries) {
|
|
39204
|
-
const full =
|
|
39364
|
+
const full = join21(dir, entry);
|
|
39205
39365
|
let lst;
|
|
39206
39366
|
try {
|
|
39207
39367
|
lst = lstatSync2(full);
|
|
@@ -39247,7 +39407,7 @@ function assertArchiveEntryPath(entry) {
|
|
|
39247
39407
|
}
|
|
39248
39408
|
function precheckWithTar(archivePath, command) {
|
|
39249
39409
|
let totalBytes = 0;
|
|
39250
|
-
const verbose =
|
|
39410
|
+
const verbose = execFileSync3(command, ["-tvf", archivePath], { encoding: "utf8" });
|
|
39251
39411
|
for (const line of verbose.split(`
|
|
39252
39412
|
`)) {
|
|
39253
39413
|
if (line.startsWith("h")) {
|
|
@@ -39260,7 +39420,7 @@ function precheckWithTar(archivePath, command) {
|
|
|
39260
39420
|
totalBytes += Math.max(...numeric);
|
|
39261
39421
|
}
|
|
39262
39422
|
}
|
|
39263
|
-
const names =
|
|
39423
|
+
const names = execFileSync3(command, ["-tf", archivePath], { encoding: "utf8" });
|
|
39264
39424
|
for (const entry of names.split(`
|
|
39265
39425
|
`)) {
|
|
39266
39426
|
if (entry.length > 0)
|
|
@@ -39271,19 +39431,18 @@ function precheckWithTar(archivePath, command) {
|
|
|
39271
39431
|
function precheckArchiveContents(archivePath, archiveType, zipListingMode = "platform") {
|
|
39272
39432
|
let totalBytes = 0;
|
|
39273
39433
|
if (archiveType === "zip" && zipListingMode === "platform" && process.platform !== "win32") {
|
|
39274
|
-
const out =
|
|
39434
|
+
const out = execFileSync3("unzip", ["-l", archivePath], { encoding: "utf8" });
|
|
39275
39435
|
const match = out.match(/^\s*(\d+)\s+\d+\s+files?\s*$/m);
|
|
39276
39436
|
if (match)
|
|
39277
39437
|
totalBytes = Number.parseInt(match[1] ?? "0", 10);
|
|
39278
|
-
const names =
|
|
39438
|
+
const names = execFileSync3("unzip", ["-Z1", archivePath], { encoding: "utf8" });
|
|
39279
39439
|
for (const entry of names.split(`
|
|
39280
39440
|
`)) {
|
|
39281
39441
|
if (entry.length > 0)
|
|
39282
39442
|
assertArchiveEntryPath(entry);
|
|
39283
39443
|
}
|
|
39284
39444
|
} else {
|
|
39285
|
-
|
|
39286
|
-
totalBytes = precheckWithTar(archivePath, command);
|
|
39445
|
+
totalBytes = precheckWithTar(archivePath, windowsTarExecutable());
|
|
39287
39446
|
}
|
|
39288
39447
|
if (totalBytes > MAX_EXTRACT_BYTES2) {
|
|
39289
39448
|
throw new Error(`archive uncompressed size ${totalBytes} exceeds ${MAX_EXTRACT_BYTES2}`);
|
|
@@ -39303,7 +39462,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
39303
39462
|
try {
|
|
39304
39463
|
rmSync8(destDir, { recursive: true, force: true });
|
|
39305
39464
|
} catch {}
|
|
39306
|
-
|
|
39465
|
+
renameSync10(stagingDir, destDir);
|
|
39307
39466
|
} catch (err) {
|
|
39308
39467
|
try {
|
|
39309
39468
|
rmSync8(stagingDir, { recursive: true, force: true });
|
|
@@ -39313,12 +39472,12 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
39313
39472
|
}
|
|
39314
39473
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
39315
39474
|
const packageDir = ghPackageDir(spec);
|
|
39316
|
-
const dest =
|
|
39475
|
+
const dest = join21(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
39317
39476
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
39318
39477
|
try {
|
|
39319
39478
|
mkdirSync9(dirname9(dest), { recursive: true });
|
|
39320
39479
|
rmSync8(dest, { recursive: true, force: true });
|
|
39321
|
-
|
|
39480
|
+
renameSync10(packageDir, dest);
|
|
39322
39481
|
} catch (err) {
|
|
39323
39482
|
warn2(`[lsp] tofu_mismatch ${spec.id}: failed to quarantine cache entry: ${err}`);
|
|
39324
39483
|
}
|
|
@@ -39326,7 +39485,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
39326
39485
|
function validateCachedGithubInstall(spec, platform) {
|
|
39327
39486
|
const packageDir = ghPackageDir(spec);
|
|
39328
39487
|
const meta = readGithubInstalledMetaIn(packageDir);
|
|
39329
|
-
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) =>
|
|
39488
|
+
const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join21(ghBinDir(spec), candidate)).find((candidate) => {
|
|
39330
39489
|
try {
|
|
39331
39490
|
return statSync11(candidate).isFile();
|
|
39332
39491
|
} catch {
|
|
@@ -39362,30 +39521,21 @@ function validateCachedGithubInstall(spec, platform) {
|
|
|
39362
39521
|
function runPlatformExtractor(archivePath, destDir, archiveType) {
|
|
39363
39522
|
if (archiveType === "zip") {
|
|
39364
39523
|
if (process.platform === "win32") {
|
|
39365
|
-
|
|
39366
|
-
stdio: "pipe",
|
|
39367
|
-
timeout: 180000
|
|
39368
|
-
});
|
|
39524
|
+
execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
|
|
39369
39525
|
return;
|
|
39370
39526
|
}
|
|
39371
|
-
|
|
39527
|
+
execFileSync3("unzip", ["-q", "-o", archivePath, "-d", destDir], {
|
|
39372
39528
|
stdio: "pipe",
|
|
39373
39529
|
timeout: 180000
|
|
39374
39530
|
});
|
|
39375
39531
|
return;
|
|
39376
39532
|
}
|
|
39377
39533
|
if (archiveType === "tar.gz") {
|
|
39378
|
-
|
|
39379
|
-
stdio: "pipe",
|
|
39380
|
-
timeout: 180000
|
|
39381
|
-
});
|
|
39534
|
+
execTarExtractionSync(["-xzf", archivePath, "-C", destDir], 180000);
|
|
39382
39535
|
return;
|
|
39383
39536
|
}
|
|
39384
39537
|
if (archiveType === "tar.xz") {
|
|
39385
|
-
|
|
39386
|
-
stdio: "pipe",
|
|
39387
|
-
timeout: 180000
|
|
39388
|
-
});
|
|
39538
|
+
execTarExtractionSync(["-xf", archivePath, "-C", destDir], 180000);
|
|
39389
39539
|
return;
|
|
39390
39540
|
}
|
|
39391
39541
|
throw new Error(`unsupported archive type: ${archiveType}`);
|
|
@@ -39406,7 +39556,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
39406
39556
|
}
|
|
39407
39557
|
const pkgDir = ghPackageDir(spec);
|
|
39408
39558
|
const extractDir = ghExtractDir(spec);
|
|
39409
|
-
const archivePath =
|
|
39559
|
+
const archivePath = join21(pkgDir, expected.name);
|
|
39410
39560
|
log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
|
|
39411
39561
|
try {
|
|
39412
39562
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
|
|
@@ -39448,8 +39598,8 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl,
|
|
|
39448
39598
|
unlinkSync7(archivePath);
|
|
39449
39599
|
} catch {}
|
|
39450
39600
|
}
|
|
39451
|
-
const innerBinaryPath =
|
|
39452
|
-
if (!
|
|
39601
|
+
const innerBinaryPath = join21(extractDir, spec.binaryPathInArchive(platform, arch, version));
|
|
39602
|
+
if (!existsSync19(innerBinaryPath)) {
|
|
39453
39603
|
const message = `extracted binary not found at ${innerBinaryPath}`;
|
|
39454
39604
|
error2(`[lsp] ${spec.id}: ${message}`);
|
|
39455
39605
|
return { ok: false, sha256: archiveSha256, error: message };
|
|
@@ -39554,7 +39704,7 @@ function runGithubAutoInstall(relevantServers, config, fetchImpl = fetch) {
|
|
|
39554
39704
|
if (!host) {
|
|
39555
39705
|
for (const spec of GITHUB_LSP_TABLE) {
|
|
39556
39706
|
try {
|
|
39557
|
-
if (
|
|
39707
|
+
if (existsSync19(ghBinDir(spec))) {
|
|
39558
39708
|
cachedBinDirs.push(ghBinDir(spec));
|
|
39559
39709
|
}
|
|
39560
39710
|
} catch {}
|
|
@@ -39871,25 +40021,25 @@ function isTuiConnected(sessionId) {
|
|
|
39871
40021
|
// src/shared/rpc-server.ts
|
|
39872
40022
|
import { randomBytes as randomBytes4, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
39873
40023
|
import {
|
|
39874
|
-
existsSync as
|
|
40024
|
+
existsSync as existsSync20,
|
|
39875
40025
|
mkdirSync as mkdirSync10,
|
|
39876
40026
|
readdirSync as readdirSync6,
|
|
39877
40027
|
readFileSync as readFileSync16,
|
|
39878
|
-
renameSync as
|
|
40028
|
+
renameSync as renameSync11,
|
|
39879
40029
|
unlinkSync as unlinkSync8,
|
|
39880
40030
|
writeFileSync as writeFileSync11
|
|
39881
40031
|
} from "node:fs";
|
|
39882
40032
|
import { createServer } from "node:http";
|
|
39883
|
-
import { dirname as dirname10, join as
|
|
40033
|
+
import { dirname as dirname10, join as join23 } from "node:path";
|
|
39884
40034
|
|
|
39885
40035
|
// src/shared/rpc-utils.ts
|
|
39886
|
-
import { join as
|
|
40036
|
+
import { join as join22 } from "node:path";
|
|
39887
40037
|
function projectHash(directory) {
|
|
39888
40038
|
return projectRootKeyHash(directory);
|
|
39889
40039
|
}
|
|
39890
40040
|
function rpcPortFileDir(storageDir, directory) {
|
|
39891
40041
|
const hash = projectHash(directory);
|
|
39892
|
-
return
|
|
40042
|
+
return join22(storageDir, "rpc", hash, "ports");
|
|
39893
40043
|
}
|
|
39894
40044
|
function isPidAlive(pid) {
|
|
39895
40045
|
if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
|
|
@@ -39963,7 +40113,7 @@ class AftRpcServer {
|
|
|
39963
40113
|
constructor(storageDir, directory) {
|
|
39964
40114
|
this.portsDir = rpcPortFileDir(storageDir, directory);
|
|
39965
40115
|
this.instanceId = randomBytes4(8).toString("hex");
|
|
39966
|
-
this.portFilePath =
|
|
40116
|
+
this.portFilePath = join23(this.portsDir, `${this.instanceId}.json`);
|
|
39967
40117
|
}
|
|
39968
40118
|
handle(method, handler) {
|
|
39969
40119
|
this.handlers.set(method, handler);
|
|
@@ -39993,6 +40143,7 @@ class AftRpcServer {
|
|
|
39993
40143
|
});
|
|
39994
40144
|
this.bunServer = server;
|
|
39995
40145
|
this.port = server.port ?? 0;
|
|
40146
|
+
server.unref?.();
|
|
39996
40147
|
this.afterServerStarted();
|
|
39997
40148
|
return this.port;
|
|
39998
40149
|
}
|
|
@@ -40038,7 +40189,7 @@ class AftRpcServer {
|
|
|
40038
40189
|
pid: process.pid,
|
|
40039
40190
|
started_at: Date.now()
|
|
40040
40191
|
}), { encoding: "utf-8", mode: 384 });
|
|
40041
|
-
|
|
40192
|
+
renameSync11(tmpPath, this.portFilePath);
|
|
40042
40193
|
}
|
|
40043
40194
|
sweepDeadPortFiles() {
|
|
40044
40195
|
let entries;
|
|
@@ -40050,7 +40201,7 @@ class AftRpcServer {
|
|
|
40050
40201
|
for (const entry of entries) {
|
|
40051
40202
|
if (!entry.endsWith(".json"))
|
|
40052
40203
|
continue;
|
|
40053
|
-
const filePath =
|
|
40204
|
+
const filePath = join23(this.portsDir, entry);
|
|
40054
40205
|
if (filePath === this.portFilePath)
|
|
40055
40206
|
continue;
|
|
40056
40207
|
try {
|
|
@@ -40069,7 +40220,7 @@ class AftRpcServer {
|
|
|
40069
40220
|
if (!this.nodeServer && !this.bunServer || this.port <= 0)
|
|
40070
40221
|
return;
|
|
40071
40222
|
try {
|
|
40072
|
-
if (
|
|
40223
|
+
if (existsSync20(this.portFilePath))
|
|
40073
40224
|
return;
|
|
40074
40225
|
this.writePortFile();
|
|
40075
40226
|
log2(`RPC port file was missing; rewrote ${this.portFilePath}`);
|
|
@@ -40336,12 +40487,6 @@ function formatCacheRoleLabel(role) {
|
|
|
40336
40487
|
}
|
|
40337
40488
|
return role;
|
|
40338
40489
|
}
|
|
40339
|
-
function formatSemanticIndexStatus(status, stage) {
|
|
40340
|
-
if ((status === "loading" || status === "building") && stage === "fingerprint_change") {
|
|
40341
|
-
return "Rebuilding (model changed)";
|
|
40342
|
-
}
|
|
40343
|
-
return status;
|
|
40344
|
-
}
|
|
40345
40490
|
function formatSemanticRefreshing(refreshingCount) {
|
|
40346
40491
|
if (!Number.isFinite(refreshingCount) || refreshingCount <= 0)
|
|
40347
40492
|
return null;
|
|
@@ -40453,7 +40598,7 @@ function formatStatusMarkdown(status) {
|
|
|
40453
40598
|
`- **Cache role:** \`${formatCacheRoleLabel(status.cache_role)}\``
|
|
40454
40599
|
];
|
|
40455
40600
|
appendDegradedStatus(lines, status, true);
|
|
40456
|
-
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)}\``);
|
|
40457
40602
|
const refreshing = formatSemanticRefreshing(status.semantic_index.refreshing_count);
|
|
40458
40603
|
if (refreshing) {
|
|
40459
40604
|
lines.push(`- **Refresh:** ${refreshing}`);
|
|
@@ -40622,7 +40767,7 @@ function isSyncWatchAborted(sessionID) {
|
|
|
40622
40767
|
}
|
|
40623
40768
|
|
|
40624
40769
|
// src/tools/permissions.ts
|
|
40625
|
-
import { execFileSync as
|
|
40770
|
+
import { execFileSync as execFileSync4 } from "node:child_process";
|
|
40626
40771
|
import * as fs4 from "node:fs";
|
|
40627
40772
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
40628
40773
|
import * as path3 from "node:path";
|
|
@@ -40877,7 +41022,7 @@ function gitRootForNearestExistingParent(resolved) {
|
|
|
40877
41022
|
cwd = path3.dirname(nearest);
|
|
40878
41023
|
} catch {}
|
|
40879
41024
|
try {
|
|
40880
|
-
const out =
|
|
41025
|
+
const out = execFileSync4("git", ["rev-parse", "--show-toplevel"], {
|
|
40881
41026
|
cwd,
|
|
40882
41027
|
encoding: "utf8",
|
|
40883
41028
|
stdio: ["ignore", "pipe", "ignore"]
|
|
@@ -41190,6 +41335,26 @@ function failure(error) {
|
|
|
41190
41335
|
})();
|
|
41191
41336
|
return new Error(`V2 tool execution rejected with a non-Error value: ${detail}`);
|
|
41192
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
|
+
}
|
|
41193
41358
|
function resultContent(result) {
|
|
41194
41359
|
if (typeof result === "string")
|
|
41195
41360
|
return { content: result };
|
|
@@ -41200,15 +41365,39 @@ function resultContent(result) {
|
|
|
41200
41365
|
...attachment.filename ? { name: attachment.filename } : {}
|
|
41201
41366
|
}));
|
|
41202
41367
|
const content = attachments.length ? [{ type: "text", text: result.output }, ...attachments] : result.output;
|
|
41203
|
-
const metadata = {
|
|
41368
|
+
const metadata = jsonSafeMetadata({
|
|
41204
41369
|
...result.metadata ?? {},
|
|
41205
41370
|
...result.title ? { title: result.title } : {}
|
|
41206
|
-
};
|
|
41371
|
+
});
|
|
41207
41372
|
return {
|
|
41208
41373
|
content,
|
|
41209
41374
|
...Object.keys(metadata).length ? { metadata } : {}
|
|
41210
41375
|
};
|
|
41211
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
|
+
}
|
|
41212
41401
|
function bareToolName3(name) {
|
|
41213
41402
|
return name.startsWith("aft_") ? name.slice(4) : name;
|
|
41214
41403
|
}
|
|
@@ -41271,15 +41460,15 @@ function runtimeFor(location, context, signal, consumers) {
|
|
|
41271
41460
|
abort: signal,
|
|
41272
41461
|
effectAbort: signal,
|
|
41273
41462
|
metadata: (update) => {
|
|
41274
|
-
Effect.runPromise(context.progress({
|
|
41463
|
+
Effect.runPromise(context.progress(jsonSafeMetadata({
|
|
41275
41464
|
...update.metadata ?? {},
|
|
41276
41465
|
...update.title ? { title: update.title } : {}
|
|
41277
|
-
}));
|
|
41466
|
+
})));
|
|
41278
41467
|
},
|
|
41279
41468
|
ask: (request) => {
|
|
41280
41469
|
if (consumers.requestPermission)
|
|
41281
41470
|
return consumers.requestPermission(request, context);
|
|
41282
|
-
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.`));
|
|
41283
41472
|
},
|
|
41284
41473
|
progress: context.progress
|
|
41285
41474
|
};
|
|
@@ -41308,6 +41497,9 @@ function projectV2Tool(name, definition, location, consumers = {}) {
|
|
|
41308
41497
|
context: runtime,
|
|
41309
41498
|
definition
|
|
41310
41499
|
}) : await definition.execute(input, runtime);
|
|
41500
|
+
const refusal = failureEnvelopeMessage(result);
|
|
41501
|
+
if (refusal)
|
|
41502
|
+
throw new Error(refusal);
|
|
41311
41503
|
return resultContent(result);
|
|
41312
41504
|
},
|
|
41313
41505
|
catch: failure
|
|
@@ -42402,7 +42594,7 @@ function createReadTool(ctx) {
|
|
|
42402
42594
|
try {
|
|
42403
42595
|
await runAsk(context.ask({
|
|
42404
42596
|
permission: "read",
|
|
42405
|
-
patterns: [filePath],
|
|
42597
|
+
patterns: [permissionPath(context, filePath)],
|
|
42406
42598
|
always: ["*"],
|
|
42407
42599
|
metadata: {}
|
|
42408
42600
|
}));
|
|
@@ -42563,7 +42755,7 @@ function getEditDescription(ctx, writeToolName) {
|
|
|
42563
42755
|
|
|
42564
42756
|
**Modes** (determined by which parameters you provide):
|
|
42565
42757
|
|
|
42566
|
-
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.
|
|
42567
42759
|
|
|
42568
42760
|
1. **Append** — pass \`path\` + \`appendContent\`
|
|
42569
42761
|
Appends text to the end of a file, creating it if it does not exist.
|
|
@@ -42664,8 +42856,8 @@ function createEditTool(ctx, writeToolName = "write") {
|
|
|
42664
42856
|
description: getEditDescription(ctx, writeToolName),
|
|
42665
42857
|
args: {
|
|
42666
42858
|
filePath: z7.string().describe("Path to the file to edit (absolute or relative to project root)"),
|
|
42667
|
-
symbol: z7.string().optional().describe("Named symbol to replace
|
|
42668
|
-
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."),
|
|
42669
42861
|
appendContent: z7.string().optional().describe("Text to append to the end of path; creates the file if needed"),
|
|
42670
42862
|
edits: z7.array(z7.object({
|
|
42671
42863
|
oldString: z7.string().optional().describe("Text to find for a batch find/replace edit"),
|
|
@@ -42907,7 +43099,7 @@ function createDeleteTool(ctx) {
|
|
|
42907
43099
|
}
|
|
42908
43100
|
await runAsk(context.ask({
|
|
42909
43101
|
permission: "edit",
|
|
42910
|
-
patterns: absolutePaths,
|
|
43102
|
+
patterns: resolveRelativePatterns(context, absolutePaths),
|
|
42911
43103
|
always: ["*"],
|
|
42912
43104
|
metadata: { action: "delete", count: absolutePaths.length }
|
|
42913
43105
|
}));
|
|
@@ -42960,7 +43152,7 @@ function createMoveTool(ctx) {
|
|
|
42960
43152
|
}
|
|
42961
43153
|
await runAsk(context.ask({
|
|
42962
43154
|
permission: "edit",
|
|
42963
|
-
patterns: [filePath, destPath],
|
|
43155
|
+
patterns: resolveRelativePatterns(context, [filePath, destPath]),
|
|
42964
43156
|
always: ["*"],
|
|
42965
43157
|
metadata: { action: "move" }
|
|
42966
43158
|
}));
|
|
@@ -43290,7 +43482,7 @@ function inspectTools(ctx) {
|
|
|
43290
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.",
|
|
43291
43483
|
args: {
|
|
43292
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.")),
|
|
43293
|
-
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.")),
|
|
43294
43486
|
topK: arg(z9.number().int().positive().max(100).optional().describe("Max drill-down items per category. Default 20, max 100."))
|
|
43295
43487
|
},
|
|
43296
43488
|
execute: async (args, context) => {
|
|
@@ -43683,7 +43875,7 @@ function safetyTools(ctx) {
|
|
|
43683
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.
|
|
43684
43876
|
` + `- 'history': List all edit snapshots for a file. Requires 'path'.
|
|
43685
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'.
|
|
43686
|
-
` + `- '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'.
|
|
43687
43879
|
` + `- 'list': List all available named checkpoints. No extra params needed.
|
|
43688
43880
|
|
|
43689
43881
|
` + `Each op requires specific parameters — see parameter descriptions for requirements.
|
|
@@ -43691,9 +43883,9 @@ function safetyTools(ctx) {
|
|
|
43691
43883
|
` + "Use checkpoint before risky multi-file changes. Use undo for quick single-file rollback.",
|
|
43692
43884
|
args: {
|
|
43693
43885
|
op: z12.enum(["undo", "history", "checkpoint", "restore", "list"]).describe("Safety operation"),
|
|
43694
|
-
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"),
|
|
43695
43887
|
name: z12.string().optional().describe("Checkpoint name (required for checkpoint, restore)"),
|
|
43696
|
-
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)")
|
|
43697
43889
|
},
|
|
43698
43890
|
execute: async (args, context) => {
|
|
43699
43891
|
const op = args.op;
|
|
@@ -44030,7 +44222,7 @@ function semanticTools(ctx) {
|
|
|
44030
44222
|
const rawArgs = { query };
|
|
44031
44223
|
const topK = coerceOptionalInt(args.topK, "topK", 1, 50);
|
|
44032
44224
|
const offset = coerceOptionalInt(args.offset, "offset", 0, 1e5);
|
|
44033
|
-
const includeTests =
|
|
44225
|
+
const includeTests = !isEmptyParam(args.includeTests) ? coerceBoolean(args.includeTests) : undefined;
|
|
44034
44226
|
if (topK !== undefined)
|
|
44035
44227
|
rawArgs.topK = topK;
|
|
44036
44228
|
if (offset !== undefined)
|
|
@@ -44270,11 +44462,11 @@ function throwSentinel(command) {
|
|
|
44270
44462
|
throw sentinel;
|
|
44271
44463
|
}
|
|
44272
44464
|
var PLUGIN_VERSION = resolvePluginVersion(import.meta.url);
|
|
44273
|
-
var ANNOUNCEMENT_VERSION = "0.
|
|
44465
|
+
var ANNOUNCEMENT_VERSION = "0.57.0";
|
|
44274
44466
|
var ANNOUNCEMENT_FEATURES = [
|
|
44275
|
-
"
|
|
44276
|
-
"
|
|
44277
|
-
"
|
|
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."
|
|
44278
44470
|
];
|
|
44279
44471
|
var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
|
|
44280
44472
|
var plugin = async (input) => initializePluginForDirectory(input);
|