@cortexkit/aft-opencode 0.26.3 → 0.27.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 +3 -0
- package/dist/bg-notifications.d.ts.map +1 -1
- package/dist/configure-warnings.d.ts +2 -0
- package/dist/configure-warnings.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +577 -506
- package/dist/notifications.d.ts +21 -0
- package/dist/notifications.d.ts.map +1 -1
- package/dist/shared/last-assistant-model.d.ts +0 -9
- package/dist/shared/last-assistant-model.d.ts.map +1 -1
- package/dist/shared/status.d.ts +20 -0
- package/dist/shared/status.d.ts.map +1 -1
- package/dist/tui.js +113 -12
- package/package.json +7 -7
- package/src/shared/last-assistant-model.ts +23 -2
- package/src/shared/status.ts +43 -0
- package/src/tui/index.tsx +49 -3
- package/src/tui/sidebar.tsx +81 -2
package/dist/index.js
CHANGED
|
@@ -1607,10 +1607,10 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
1607
1607
|
}();
|
|
1608
1608
|
exports2.TaggedTemplateExpression = TaggedTemplateExpression;
|
|
1609
1609
|
var TemplateElement = function() {
|
|
1610
|
-
function TemplateElement2(value,
|
|
1610
|
+
function TemplateElement2(value, tail2) {
|
|
1611
1611
|
this.type = syntax_1.Syntax.TemplateElement;
|
|
1612
1612
|
this.value = value;
|
|
1613
|
-
this.tail =
|
|
1613
|
+
this.tail = tail2;
|
|
1614
1614
|
}
|
|
1615
1615
|
return TemplateElement2;
|
|
1616
1616
|
}();
|
|
@@ -5450,14 +5450,14 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
5450
5450
|
var terminated = false;
|
|
5451
5451
|
var start = this.index;
|
|
5452
5452
|
var head = this.source[start] === "`";
|
|
5453
|
-
var
|
|
5453
|
+
var tail2 = false;
|
|
5454
5454
|
var rawOffset = 2;
|
|
5455
5455
|
++this.index;
|
|
5456
5456
|
while (!this.eof()) {
|
|
5457
5457
|
var ch = this.source[this.index++];
|
|
5458
5458
|
if (ch === "`") {
|
|
5459
5459
|
rawOffset = 1;
|
|
5460
|
-
|
|
5460
|
+
tail2 = true;
|
|
5461
5461
|
terminated = true;
|
|
5462
5462
|
break;
|
|
5463
5463
|
} else if (ch === "$") {
|
|
@@ -5558,7 +5558,7 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
5558
5558
|
value: this.source.slice(start + 1, this.index - rawOffset),
|
|
5559
5559
|
cooked,
|
|
5560
5560
|
head,
|
|
5561
|
-
tail,
|
|
5561
|
+
tail: tail2,
|
|
5562
5562
|
lineNumber: this.lineNumber,
|
|
5563
5563
|
lineStart: this.lineStart,
|
|
5564
5564
|
start,
|
|
@@ -7652,10 +7652,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7652
7652
|
replacer = null;
|
|
7653
7653
|
indent = EMPTY;
|
|
7654
7654
|
};
|
|
7655
|
-
var
|
|
7655
|
+
var join8 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
7656
7656
|
var join_content = (inside, value, gap) => {
|
|
7657
7657
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
7658
|
-
return
|
|
7658
|
+
return join8(comment, inside, gap);
|
|
7659
7659
|
};
|
|
7660
7660
|
var stringify_string = (holder, key, value) => {
|
|
7661
7661
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -7677,13 +7677,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7677
7677
|
if (i !== 0) {
|
|
7678
7678
|
inside += COMMA;
|
|
7679
7679
|
}
|
|
7680
|
-
const before =
|
|
7680
|
+
const before = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
7681
7681
|
inside += before || LF + deeper_gap;
|
|
7682
7682
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
7683
7683
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
7684
7684
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
7685
7685
|
}
|
|
7686
|
-
inside +=
|
|
7686
|
+
inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7687
7687
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
7688
7688
|
};
|
|
7689
7689
|
var object_stringify = (value, gap) => {
|
|
@@ -7704,13 +7704,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7704
7704
|
inside += COMMA;
|
|
7705
7705
|
}
|
|
7706
7706
|
first = false;
|
|
7707
|
-
const before =
|
|
7707
|
+
const before = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
7708
7708
|
inside += before || LF + deeper_gap;
|
|
7709
7709
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
7710
7710
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
7711
7711
|
};
|
|
7712
7712
|
keys.forEach(iteratee);
|
|
7713
|
-
inside +=
|
|
7713
|
+
inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7714
7714
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
7715
7715
|
};
|
|
7716
7716
|
function stringify(key, holder, gap) {
|
|
@@ -7803,10 +7803,9 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
7803
7803
|
});
|
|
7804
7804
|
|
|
7805
7805
|
// src/index.ts
|
|
7806
|
-
import { existsSync as
|
|
7806
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync13, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
|
|
7807
7807
|
import { createRequire as createRequire2 } from "module";
|
|
7808
|
-
import {
|
|
7809
|
-
import { join as join21 } from "path";
|
|
7808
|
+
import { join as join22 } from "path";
|
|
7810
7809
|
|
|
7811
7810
|
// ../aft-bridge/dist/active-logger.js
|
|
7812
7811
|
var ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
|
|
@@ -8831,11 +8830,288 @@ async function fetchLatestTag() {
|
|
|
8831
8830
|
clearTimeout(timeout);
|
|
8832
8831
|
}
|
|
8833
8832
|
}
|
|
8833
|
+
// ../aft-bridge/dist/migration.js
|
|
8834
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
8835
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync3 } from "fs";
|
|
8836
|
+
import { homedir as homedir4, tmpdir } from "os";
|
|
8837
|
+
import { dirname, join as join4 } from "path";
|
|
8838
|
+
|
|
8839
|
+
// ../aft-bridge/dist/resolver.js
|
|
8840
|
+
import { execSync, spawnSync } from "child_process";
|
|
8841
|
+
import { chmodSync as chmodSync2, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync as renameSync2 } from "fs";
|
|
8842
|
+
import { createRequire } from "module";
|
|
8843
|
+
import { homedir as homedir3 } from "os";
|
|
8844
|
+
import { join as join3 } from "path";
|
|
8845
|
+
function readBinaryVersion(binaryPath) {
|
|
8846
|
+
try {
|
|
8847
|
+
const result = spawnSync(binaryPath, ["--version"], {
|
|
8848
|
+
encoding: "utf-8",
|
|
8849
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
8850
|
+
timeout: 5000
|
|
8851
|
+
});
|
|
8852
|
+
const stdoutVersion = result.stdout?.trim();
|
|
8853
|
+
const stderrVersion = result.stderr?.trim();
|
|
8854
|
+
const rawVersion = stdoutVersion || stderrVersion;
|
|
8855
|
+
if (!rawVersion)
|
|
8856
|
+
return null;
|
|
8857
|
+
return rawVersion.replace(/^aft\s+/, "");
|
|
8858
|
+
} catch {
|
|
8859
|
+
return null;
|
|
8860
|
+
}
|
|
8861
|
+
}
|
|
8862
|
+
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
8863
|
+
try {
|
|
8864
|
+
const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
|
|
8865
|
+
if (!version)
|
|
8866
|
+
return null;
|
|
8867
|
+
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
8868
|
+
const cacheDir = getCacheDir();
|
|
8869
|
+
const versionedDir = join3(cacheDir, tag);
|
|
8870
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
8871
|
+
const cachedPath = join3(versionedDir, `aft${ext}`);
|
|
8872
|
+
if (existsSync2(cachedPath)) {
|
|
8873
|
+
const cachedVersion = readBinaryVersion(cachedPath);
|
|
8874
|
+
if (cachedVersion === version)
|
|
8875
|
+
return cachedPath;
|
|
8876
|
+
warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
|
|
8877
|
+
}
|
|
8878
|
+
mkdirSync2(versionedDir, { recursive: true });
|
|
8879
|
+
const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
|
|
8880
|
+
copyFileSync(npmBinaryPath, tmpPath);
|
|
8881
|
+
if (process.platform !== "win32") {
|
|
8882
|
+
chmodSync2(tmpPath, 493);
|
|
8883
|
+
}
|
|
8884
|
+
renameSync2(tmpPath, cachedPath);
|
|
8885
|
+
log(`Copied npm binary to versioned cache: ${cachedPath}`);
|
|
8886
|
+
return cachedPath;
|
|
8887
|
+
} catch (err) {
|
|
8888
|
+
warn(`Failed to copy binary to cache: ${err instanceof Error ? err.message : String(err)}`);
|
|
8889
|
+
return null;
|
|
8890
|
+
}
|
|
8891
|
+
}
|
|
8892
|
+
function normalizeBareVersion(version) {
|
|
8893
|
+
return version.startsWith("v") ? version.slice(1) : version;
|
|
8894
|
+
}
|
|
8895
|
+
function homeDirFromEnv(env) {
|
|
8896
|
+
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir3();
|
|
8897
|
+
}
|
|
8898
|
+
function cacheDirFromEnv(env) {
|
|
8899
|
+
if (process.platform === "win32") {
|
|
8900
|
+
const base2 = env.LOCALAPPDATA || env.APPDATA || join3(homeDirFromEnv(env), "AppData", "Local");
|
|
8901
|
+
return join3(base2, "aft", "bin");
|
|
8902
|
+
}
|
|
8903
|
+
const base = env.XDG_CACHE_HOME || join3(homeDirFromEnv(env), ".cache");
|
|
8904
|
+
return join3(base, "aft", "bin");
|
|
8905
|
+
}
|
|
8906
|
+
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
8907
|
+
const binaryPath = join3(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
8908
|
+
return existsSync2(binaryPath) ? binaryPath : null;
|
|
8909
|
+
}
|
|
8910
|
+
function isExpectedCachedBinary(binaryPath, expectedVersion) {
|
|
8911
|
+
const expected = normalizeBareVersion(expectedVersion);
|
|
8912
|
+
const actual = readBinaryVersion(binaryPath);
|
|
8913
|
+
if (actual === expected)
|
|
8914
|
+
return true;
|
|
8915
|
+
warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
|
|
8916
|
+
return false;
|
|
8917
|
+
}
|
|
8918
|
+
function platformKey(platform = process.platform, arch = process.arch) {
|
|
8919
|
+
const archMap = PLATFORM_ARCH_MAP[platform];
|
|
8920
|
+
if (!archMap) {
|
|
8921
|
+
throw new Error(`Unsupported platform: ${platform} (arch: ${arch}). ` + `Supported platforms: ${Object.keys(PLATFORM_ARCH_MAP).join(", ")}`);
|
|
8922
|
+
}
|
|
8923
|
+
const key = archMap[arch];
|
|
8924
|
+
if (!key) {
|
|
8925
|
+
throw new Error(`Unsupported architecture: ${arch} on platform ${platform}. ` + `Supported architectures for ${platform}: ${Object.keys(archMap).join(", ")}`);
|
|
8926
|
+
}
|
|
8927
|
+
return key;
|
|
8928
|
+
}
|
|
8929
|
+
function findBinarySync(expectedVersion) {
|
|
8930
|
+
const ext = process.platform === "win32" ? ".exe" : "";
|
|
8931
|
+
const env = { ...process.env };
|
|
8932
|
+
const pluginVersion = expectedVersion ?? (() => {
|
|
8933
|
+
try {
|
|
8934
|
+
const req = createRequire(import.meta.url);
|
|
8935
|
+
return req("../package.json").version;
|
|
8936
|
+
} catch {
|
|
8937
|
+
return null;
|
|
8938
|
+
}
|
|
8939
|
+
})();
|
|
8940
|
+
if (pluginVersion) {
|
|
8941
|
+
const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
|
|
8942
|
+
const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
|
|
8943
|
+
if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
|
|
8944
|
+
return versionCached;
|
|
8945
|
+
}
|
|
8946
|
+
try {
|
|
8947
|
+
const key = platformKey();
|
|
8948
|
+
const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
|
|
8949
|
+
const req = createRequire(import.meta.url);
|
|
8950
|
+
const resolved = req.resolve(packageBin);
|
|
8951
|
+
if (existsSync2(resolved)) {
|
|
8952
|
+
const npmVersion = readBinaryVersion(resolved);
|
|
8953
|
+
if (npmVersion === null) {
|
|
8954
|
+
warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
|
|
8955
|
+
} else if (pluginVersion && npmVersion !== normalizeBareVersion(pluginVersion)) {
|
|
8956
|
+
warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
|
|
8957
|
+
} else {
|
|
8958
|
+
const copied = copyToVersionedCache(resolved, npmVersion);
|
|
8959
|
+
return copied ?? resolved;
|
|
8960
|
+
}
|
|
8961
|
+
}
|
|
8962
|
+
} catch {}
|
|
8963
|
+
try {
|
|
8964
|
+
const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
|
|
8965
|
+
const result = execSync(whichCmd, {
|
|
8966
|
+
encoding: "utf-8",
|
|
8967
|
+
env,
|
|
8968
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
8969
|
+
}).trim();
|
|
8970
|
+
if (result)
|
|
8971
|
+
return result;
|
|
8972
|
+
} catch {}
|
|
8973
|
+
const cargoPath = join3(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
8974
|
+
if (existsSync2(cargoPath))
|
|
8975
|
+
return cargoPath;
|
|
8976
|
+
return null;
|
|
8977
|
+
}
|
|
8978
|
+
async function findBinary(expectedVersion) {
|
|
8979
|
+
const syncResult = findBinarySync(expectedVersion);
|
|
8980
|
+
if (syncResult) {
|
|
8981
|
+
log(`Resolved binary: ${syncResult}`);
|
|
8982
|
+
return syncResult;
|
|
8983
|
+
}
|
|
8984
|
+
log("Binary not found locally, attempting auto-download...");
|
|
8985
|
+
const downloaded = await ensureBinary(expectedVersion);
|
|
8986
|
+
if (downloaded)
|
|
8987
|
+
return downloaded;
|
|
8988
|
+
throw new Error([
|
|
8989
|
+
"Could not find the `aft` binary.",
|
|
8990
|
+
"",
|
|
8991
|
+
"Attempted sources:",
|
|
8992
|
+
" - Cache directory (~/.cache/aft/bin/)",
|
|
8993
|
+
" - npm platform package (@cortexkit/aft-<platform>)",
|
|
8994
|
+
" - PATH lookup (which aft)",
|
|
8995
|
+
" - ~/.cargo/bin/aft",
|
|
8996
|
+
" - Auto-download from GitHub releases (failed)",
|
|
8997
|
+
"",
|
|
8998
|
+
"Install it using one of these methods:",
|
|
8999
|
+
" npm install @cortexkit/aft-opencode # installs platform-specific binary via npm",
|
|
9000
|
+
" cargo install agent-file-tools # from crates.io",
|
|
9001
|
+
" cargo build --release # from source (binary at target/release/aft)",
|
|
9002
|
+
"",
|
|
9003
|
+
"Or add the aft directory to your PATH."
|
|
9004
|
+
].join(`
|
|
9005
|
+
`));
|
|
9006
|
+
}
|
|
9007
|
+
|
|
9008
|
+
// ../aft-bridge/dist/migration.js
|
|
9009
|
+
var TARGET_MARKER = ".migrated_from_legacy";
|
|
9010
|
+
var DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
9011
|
+
function dataHome() {
|
|
9012
|
+
if (process.env.XDG_DATA_HOME)
|
|
9013
|
+
return process.env.XDG_DATA_HOME;
|
|
9014
|
+
if (process.platform === "win32") {
|
|
9015
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join4(homeDir(), "AppData", "Local");
|
|
9016
|
+
}
|
|
9017
|
+
return join4(homeDir(), ".local", "share");
|
|
9018
|
+
}
|
|
9019
|
+
function homeDir() {
|
|
9020
|
+
if (process.platform === "win32")
|
|
9021
|
+
return process.env.USERPROFILE || process.env.HOME || homedir4();
|
|
9022
|
+
return process.env.HOME || homedir4();
|
|
9023
|
+
}
|
|
9024
|
+
function resolveLegacyStorageRoot(harness) {
|
|
9025
|
+
if (harness === "pi")
|
|
9026
|
+
return join4(homeDir(), ".pi", "agent", "aft");
|
|
9027
|
+
return join4(dataHome(), "opencode", "storage", "plugin", "aft");
|
|
9028
|
+
}
|
|
9029
|
+
function resolveCortexKitStorageRoot() {
|
|
9030
|
+
return join4(dataHome(), "cortexkit", "aft");
|
|
9031
|
+
}
|
|
9032
|
+
function tail(value) {
|
|
9033
|
+
if (!value)
|
|
9034
|
+
return "";
|
|
9035
|
+
return value.split(`
|
|
9036
|
+
`).slice(-20).join(`
|
|
9037
|
+
`).trim();
|
|
9038
|
+
}
|
|
9039
|
+
function spawnErrorLabel(error2) {
|
|
9040
|
+
const code = "code" in error2 ? String(error2.code ?? "") : "";
|
|
9041
|
+
return [code, error2.message].filter(Boolean).join(": ");
|
|
9042
|
+
}
|
|
9043
|
+
function migrationLogPath(newRoot, harness, logger) {
|
|
9044
|
+
const desired = join4(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
|
|
9045
|
+
try {
|
|
9046
|
+
mkdirSync3(dirname(desired), { recursive: true });
|
|
9047
|
+
return desired;
|
|
9048
|
+
} catch (err) {
|
|
9049
|
+
const fallback = join4(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
|
|
9050
|
+
logger?.warn?.(`Failed to create AFT migration log directory ${dirname(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
|
|
9051
|
+
return fallback;
|
|
9052
|
+
}
|
|
9053
|
+
}
|
|
9054
|
+
async function ensureStorageMigrated(opts) {
|
|
9055
|
+
const legacyRoot = resolveLegacyStorageRoot(opts.harness);
|
|
9056
|
+
const newRoot = resolveCortexKitStorageRoot();
|
|
9057
|
+
const targetMarker = join4(newRoot, opts.harness, TARGET_MARKER);
|
|
9058
|
+
const info = opts.logger?.info ?? opts.logger?.log;
|
|
9059
|
+
if (existsSync3(targetMarker)) {
|
|
9060
|
+
info?.(`AFT storage already migrated for ${opts.harness}; using ${newRoot}`);
|
|
9061
|
+
return;
|
|
9062
|
+
}
|
|
9063
|
+
if (!existsSync3(legacyRoot)) {
|
|
9064
|
+
info?.(`AFT storage migration skipped for ${opts.harness}: no legacy data at ${legacyRoot}; ` + `using ${newRoot} for fresh install`);
|
|
9065
|
+
return;
|
|
9066
|
+
}
|
|
9067
|
+
const logPath = migrationLogPath(newRoot, opts.harness, opts.logger);
|
|
9068
|
+
const binaryPath = opts.binaryPath ?? await findBinary();
|
|
9069
|
+
const startMs = Date.now();
|
|
9070
|
+
info?.(`AFT storage migration starting for ${opts.harness}: ${legacyRoot} -> ${newRoot} ` + `(binary=${binaryPath}, log=${logPath})`);
|
|
9071
|
+
try {
|
|
9072
|
+
process.stderr.write(`
|
|
9073
|
+
[AFT] Migrating ${opts.harness} storage to ${newRoot}.
|
|
9074
|
+
` + `[AFT] This may take several minutes for large indexes \u2014 please do not close ${opts.harness === "pi" ? "Pi" : "OpenCode"}.
|
|
9075
|
+
` + `[AFT] Source: ${legacyRoot}
|
|
9076
|
+
` + `[AFT] Log: ${logPath}
|
|
9077
|
+
|
|
9078
|
+
`);
|
|
9079
|
+
} catch {}
|
|
9080
|
+
const result = spawnSync2(binaryPath, [
|
|
9081
|
+
"migrate-storage",
|
|
9082
|
+
"--from",
|
|
9083
|
+
legacyRoot,
|
|
9084
|
+
"--to",
|
|
9085
|
+
newRoot,
|
|
9086
|
+
"--harness",
|
|
9087
|
+
opts.harness,
|
|
9088
|
+
"--log",
|
|
9089
|
+
logPath
|
|
9090
|
+
], {
|
|
9091
|
+
encoding: "utf8",
|
|
9092
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
9093
|
+
timeout: opts.timeoutMs ?? DEFAULT_TIMEOUT_MS
|
|
9094
|
+
});
|
|
9095
|
+
if (!result.error && result.status === 0) {
|
|
9096
|
+
const elapsedMs = Date.now() - startMs;
|
|
9097
|
+
info?.(`AFT storage migration completed for ${opts.harness} in ${elapsedMs}ms (log=${logPath})`);
|
|
9098
|
+
try {
|
|
9099
|
+
process.stderr.write(`[AFT] Migration complete (${(elapsedMs / 1000).toFixed(1)}s).
|
|
9100
|
+
|
|
9101
|
+
`);
|
|
9102
|
+
} catch {}
|
|
9103
|
+
return;
|
|
9104
|
+
}
|
|
9105
|
+
const detail = result.error ? `spawn error ${spawnErrorLabel(result.error)}` : result.status === null ? `terminated by signal ${result.signal ?? "unknown"}` : `exit ${result.status}`;
|
|
9106
|
+
const stderrTail = tail(result.stderr);
|
|
9107
|
+
const stdoutTail = tail(result.stdout);
|
|
9108
|
+
throw new Error(`AFT storage migration failed (${detail}). ` + `Harness: ${opts.harness}. Legacy: ${legacyRoot}. Target: ${newRoot}. ` + `See log: ${logPath}. ` + `Plugin load aborted to prevent legacy/new state divergence.` + (stderrTail ? ` Stderr tail: ${stderrTail}` : "") + (stdoutTail ? ` Stdout tail: ${stdoutTail}` : ""));
|
|
9109
|
+
}
|
|
8834
9110
|
// ../aft-bridge/dist/onnx-runtime.js
|
|
8835
9111
|
import { execFileSync } from "child_process";
|
|
8836
9112
|
import { createHash as createHash2 } from "crypto";
|
|
8837
|
-
import { chmodSync as
|
|
8838
|
-
import { dirname, join as
|
|
9113
|
+
import { chmodSync as chmodSync3, closeSync as closeSync2, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync4, lstatSync, mkdirSync as mkdirSync4, openSync as openSync2, readdirSync, readFileSync, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync2, writeFileSync } from "fs";
|
|
9114
|
+
import { dirname as dirname2, join as join5, relative, resolve } from "path";
|
|
8839
9115
|
import { Readable as Readable2 } from "stream";
|
|
8840
9116
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
8841
9117
|
var ORT_VERSION = "1.24.4";
|
|
@@ -8883,8 +9159,8 @@ function getPlatformInfo() {
|
|
|
8883
9159
|
if (!platformMap)
|
|
8884
9160
|
return null;
|
|
8885
9161
|
const archMap = PLATFORM_ARCH_MAP[process.platform] ?? {};
|
|
8886
|
-
const
|
|
8887
|
-
const ortArch =
|
|
9162
|
+
const platformKey2 = archMap[process.arch];
|
|
9163
|
+
const ortArch = platformKey2 ? platformKey2.split("-")[1] : process.arch;
|
|
8888
9164
|
return platformMap[ortArch] || null;
|
|
8889
9165
|
}
|
|
8890
9166
|
function isOrtAutoDownloadSupported() {
|
|
@@ -8901,9 +9177,9 @@ function getManualInstallHint() {
|
|
|
8901
9177
|
}
|
|
8902
9178
|
async function ensureOnnxRuntime(storageDir) {
|
|
8903
9179
|
const info = getPlatformInfo();
|
|
8904
|
-
const ortDir =
|
|
8905
|
-
const libPath =
|
|
8906
|
-
if (
|
|
9180
|
+
const ortDir = join5(storageDir, "onnxruntime", ORT_VERSION);
|
|
9181
|
+
const libPath = join5(ortDir, info?.libName ?? "libonnxruntime.dylib");
|
|
9182
|
+
if (existsSync4(libPath)) {
|
|
8907
9183
|
const meta = readOnnxInstalledMeta(ortDir);
|
|
8908
9184
|
if (meta?.sha256) {
|
|
8909
9185
|
try {
|
|
@@ -8932,9 +9208,9 @@ async function ensureOnnxRuntime(storageDir) {
|
|
|
8932
9208
|
warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
|
|
8933
9209
|
return null;
|
|
8934
9210
|
}
|
|
8935
|
-
const onnxBaseDir =
|
|
8936
|
-
|
|
8937
|
-
const lockPath =
|
|
9211
|
+
const onnxBaseDir = join5(storageDir, "onnxruntime");
|
|
9212
|
+
mkdirSync4(onnxBaseDir, { recursive: true });
|
|
9213
|
+
const lockPath = join5(onnxBaseDir, ONNX_LOCK_FILE);
|
|
8938
9214
|
cleanupAbandonedStagingDirs(onnxBaseDir);
|
|
8939
9215
|
if (!acquireLock(lockPath)) {
|
|
8940
9216
|
warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
|
|
@@ -8953,7 +9229,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
8953
9229
|
for (const entry of entries) {
|
|
8954
9230
|
if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
|
|
8955
9231
|
continue;
|
|
8956
|
-
const stagingDir =
|
|
9232
|
+
const stagingDir = join5(onnxBaseDir, entry);
|
|
8957
9233
|
const parts = entry.split(".");
|
|
8958
9234
|
const pidStr = parts[parts.length - 2];
|
|
8959
9235
|
const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
|
|
@@ -8985,7 +9261,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
|
|
|
8985
9261
|
}
|
|
8986
9262
|
function cleanupIncompleteTargetIfUnowned(ortDir) {
|
|
8987
9263
|
try {
|
|
8988
|
-
if (
|
|
9264
|
+
if (existsSync4(ortDir) && !existsSync4(join5(ortDir, ONNX_INSTALLED_META_FILE))) {
|
|
8989
9265
|
log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
|
|
8990
9266
|
rmSync2(ortDir, { recursive: true, force: true });
|
|
8991
9267
|
}
|
|
@@ -9006,8 +9282,8 @@ function detectOnnxVersion(libDir, libName) {
|
|
|
9006
9282
|
if (match)
|
|
9007
9283
|
return match[1];
|
|
9008
9284
|
}
|
|
9009
|
-
const base =
|
|
9010
|
-
if (
|
|
9285
|
+
const base = join5(libDir, libName);
|
|
9286
|
+
if (existsSync4(base)) {
|
|
9011
9287
|
try {
|
|
9012
9288
|
const real = realpathSync(base);
|
|
9013
9289
|
const m = real.match(/\.(\d+\.\d+\.\d+)(?:\.dylib)?$/);
|
|
@@ -9043,7 +9319,7 @@ function findSystemOnnxRuntime(libName) {
|
|
|
9043
9319
|
searchPaths.push("/usr/lib", "/usr/lib/x86_64-linux-gnu", "/usr/lib/aarch64-linux-gnu", "/usr/local/lib");
|
|
9044
9320
|
}
|
|
9045
9321
|
for (const dir of searchPaths) {
|
|
9046
|
-
if (!
|
|
9322
|
+
if (!existsSync4(join5(dir, libName)))
|
|
9047
9323
|
continue;
|
|
9048
9324
|
const version = detectOnnxVersion(dir, libName);
|
|
9049
9325
|
if (version && !isOnnxVersionCompatible(version)) {
|
|
@@ -9070,7 +9346,7 @@ async function downloadFileWithCap(url, destPath) {
|
|
|
9070
9346
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
|
|
9071
9347
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
|
|
9072
9348
|
}
|
|
9073
|
-
|
|
9349
|
+
mkdirSync4(dirname2(destPath), { recursive: true });
|
|
9074
9350
|
let bytesWritten = 0;
|
|
9075
9351
|
const guard = new TransformStream({
|
|
9076
9352
|
transform(chunk, transformController) {
|
|
@@ -9100,11 +9376,11 @@ function validateExtractedTree(stagingRoot) {
|
|
|
9100
9376
|
const walk = (dir) => {
|
|
9101
9377
|
const entries = readdirSync(dir);
|
|
9102
9378
|
for (const entry of entries) {
|
|
9103
|
-
const fullPath =
|
|
9379
|
+
const fullPath = join5(dir, entry);
|
|
9104
9380
|
const lst = lstatSync(fullPath);
|
|
9105
9381
|
if (lst.isSymbolicLink()) {
|
|
9106
9382
|
const linkTarget = readlinkSync(fullPath);
|
|
9107
|
-
const resolvedTarget = resolve(
|
|
9383
|
+
const resolvedTarget = resolve(dirname2(fullPath), linkTarget);
|
|
9108
9384
|
const rel2 = relative(realRoot, resolvedTarget);
|
|
9109
9385
|
if (rel2.startsWith("..") || process.platform !== "win32" && rel2.startsWith("/")) {
|
|
9110
9386
|
throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
|
|
@@ -9134,8 +9410,8 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
9134
9410
|
log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
|
|
9135
9411
|
const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
|
|
9136
9412
|
try {
|
|
9137
|
-
|
|
9138
|
-
const archivePath =
|
|
9413
|
+
mkdirSync4(tmpDir, { recursive: true });
|
|
9414
|
+
const archivePath = join5(tmpDir, `onnxruntime.${info.archiveType}`);
|
|
9139
9415
|
await downloadFileWithCap(url, archivePath);
|
|
9140
9416
|
const archiveSha256 = sha256File(archivePath);
|
|
9141
9417
|
log(`ONNX Runtime archive sha256=${archiveSha256}`);
|
|
@@ -9151,16 +9427,16 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
9151
9427
|
unlinkSync2(archivePath);
|
|
9152
9428
|
} catch {}
|
|
9153
9429
|
validateExtractedTree(tmpDir);
|
|
9154
|
-
const extractedDir =
|
|
9155
|
-
if (!
|
|
9430
|
+
const extractedDir = join5(tmpDir, info.assetName, "lib");
|
|
9431
|
+
if (!existsSync4(extractedDir)) {
|
|
9156
9432
|
throw new Error(`Expected directory not found: ${extractedDir}`);
|
|
9157
9433
|
}
|
|
9158
|
-
|
|
9434
|
+
mkdirSync4(targetDir, { recursive: true });
|
|
9159
9435
|
const libFiles = readdirSync(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
|
|
9160
9436
|
const realFiles = [];
|
|
9161
9437
|
const symlinks = [];
|
|
9162
9438
|
for (const libFile of libFiles) {
|
|
9163
|
-
const src =
|
|
9439
|
+
const src = join5(extractedDir, libFile);
|
|
9164
9440
|
try {
|
|
9165
9441
|
const stat = lstatSync(src);
|
|
9166
9442
|
log(`ORT extract: ${libFile} \u2014 isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
|
|
@@ -9175,7 +9451,7 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
9175
9451
|
}
|
|
9176
9452
|
}
|
|
9177
9453
|
copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
|
|
9178
|
-
const libPath =
|
|
9454
|
+
const libPath = join5(targetDir, info.libName);
|
|
9179
9455
|
let libHash = null;
|
|
9180
9456
|
try {
|
|
9181
9457
|
libHash = sha256File(libPath);
|
|
@@ -9197,15 +9473,15 @@ async function downloadOnnxRuntime(info, targetDir) {
|
|
|
9197
9473
|
return null;
|
|
9198
9474
|
}
|
|
9199
9475
|
}
|
|
9200
|
-
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile =
|
|
9476
|
+
function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync2) {
|
|
9201
9477
|
const requiredLibs = new Set([info.libName]);
|
|
9202
9478
|
for (const libFile of realFiles) {
|
|
9203
|
-
const src =
|
|
9204
|
-
const dst =
|
|
9479
|
+
const src = join5(extractedDir, libFile);
|
|
9480
|
+
const dst = join5(targetDir, libFile);
|
|
9205
9481
|
try {
|
|
9206
9482
|
copyFile(src, dst);
|
|
9207
9483
|
if (process.platform !== "win32") {
|
|
9208
|
-
|
|
9484
|
+
chmodSync3(dst, 493);
|
|
9209
9485
|
}
|
|
9210
9486
|
} catch (copyErr) {
|
|
9211
9487
|
if (requiredLibs.has(libFile)) {
|
|
@@ -9216,7 +9492,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
9216
9492
|
}
|
|
9217
9493
|
}
|
|
9218
9494
|
for (const link of symlinks) {
|
|
9219
|
-
const dst =
|
|
9495
|
+
const dst = join5(targetDir, link.name);
|
|
9220
9496
|
try {
|
|
9221
9497
|
unlinkSync2(dst);
|
|
9222
9498
|
} catch {}
|
|
@@ -9230,8 +9506,8 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
|
|
|
9230
9506
|
log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
|
|
9231
9507
|
}
|
|
9232
9508
|
}
|
|
9233
|
-
const requiredPath =
|
|
9234
|
-
if (!
|
|
9509
|
+
const requiredPath = join5(targetDir, info.libName);
|
|
9510
|
+
if (!existsSync4(requiredPath)) {
|
|
9235
9511
|
rmSync2(targetDir, { recursive: true, force: true });
|
|
9236
9512
|
throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
|
|
9237
9513
|
}
|
|
@@ -9257,13 +9533,13 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
|
|
|
9257
9533
|
...sha256 ? { sha256 } : {},
|
|
9258
9534
|
archiveSha256
|
|
9259
9535
|
};
|
|
9260
|
-
writeFileSync(
|
|
9536
|
+
writeFileSync(join5(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
|
|
9261
9537
|
} catch (err) {
|
|
9262
9538
|
log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
|
|
9263
9539
|
}
|
|
9264
9540
|
}
|
|
9265
9541
|
function readOnnxInstalledMeta(installDir) {
|
|
9266
|
-
const path =
|
|
9542
|
+
const path = join5(installDir, ONNX_INSTALLED_META_FILE);
|
|
9267
9543
|
try {
|
|
9268
9544
|
if (!statSync2(path).isFile())
|
|
9269
9545
|
return null;
|
|
@@ -9378,31 +9654,9 @@ function isProcessAlive(pid) {
|
|
|
9378
9654
|
}
|
|
9379
9655
|
// ../aft-bridge/dist/pool.js
|
|
9380
9656
|
import { realpathSync as realpathSync2 } from "fs";
|
|
9381
|
-
import { homedir as homedir3 } from "os";
|
|
9382
9657
|
var DEFAULT_IDLE_TIMEOUT_MS = Infinity;
|
|
9383
9658
|
var DEFAULT_MAX_POOL_SIZE = 8;
|
|
9384
9659
|
var CLEANUP_INTERVAL_MS = 60 * 1000;
|
|
9385
|
-
function canonicalHomeDir() {
|
|
9386
|
-
try {
|
|
9387
|
-
const home = homedir3();
|
|
9388
|
-
if (!home)
|
|
9389
|
-
return null;
|
|
9390
|
-
try {
|
|
9391
|
-
return realpathSync2(home);
|
|
9392
|
-
} catch {
|
|
9393
|
-
return home.replace(/[/\\]+$/, "");
|
|
9394
|
-
}
|
|
9395
|
-
} catch {
|
|
9396
|
-
return null;
|
|
9397
|
-
}
|
|
9398
|
-
}
|
|
9399
|
-
function isHomeDirectoryRoot(normalizedKey) {
|
|
9400
|
-
const home = canonicalHomeDir();
|
|
9401
|
-
if (!home)
|
|
9402
|
-
return false;
|
|
9403
|
-
return normalizedKey === home;
|
|
9404
|
-
}
|
|
9405
|
-
|
|
9406
9660
|
class BridgePool {
|
|
9407
9661
|
bridges = new Map;
|
|
9408
9662
|
binaryPath;
|
|
@@ -9545,196 +9799,28 @@ function normalizeKey(projectRoot) {
|
|
|
9545
9799
|
return stripped;
|
|
9546
9800
|
}
|
|
9547
9801
|
}
|
|
9548
|
-
// ../aft-bridge/dist/resolver.js
|
|
9549
|
-
import { execSync, spawnSync } from "child_process";
|
|
9550
|
-
import { chmodSync as chmodSync3, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync2 } from "fs";
|
|
9551
|
-
import { createRequire } from "module";
|
|
9552
|
-
import { homedir as homedir4 } from "os";
|
|
9553
|
-
import { join as join4 } from "path";
|
|
9554
|
-
function readBinaryVersion(binaryPath) {
|
|
9555
|
-
try {
|
|
9556
|
-
const result = spawnSync(binaryPath, ["--version"], {
|
|
9557
|
-
encoding: "utf-8",
|
|
9558
|
-
stdio: ["pipe", "pipe", "pipe"],
|
|
9559
|
-
timeout: 5000
|
|
9560
|
-
});
|
|
9561
|
-
const stdoutVersion = result.stdout?.trim();
|
|
9562
|
-
const stderrVersion = result.stderr?.trim();
|
|
9563
|
-
const rawVersion = stdoutVersion || stderrVersion;
|
|
9564
|
-
if (!rawVersion)
|
|
9565
|
-
return null;
|
|
9566
|
-
return rawVersion.replace(/^aft\s+/, "");
|
|
9567
|
-
} catch {
|
|
9568
|
-
return null;
|
|
9569
|
-
}
|
|
9570
|
-
}
|
|
9571
|
-
function copyToVersionedCache(npmBinaryPath, knownVersion) {
|
|
9572
|
-
try {
|
|
9573
|
-
const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
|
|
9574
|
-
if (!version)
|
|
9575
|
-
return null;
|
|
9576
|
-
const tag = version.startsWith("v") ? version : `v${version}`;
|
|
9577
|
-
const cacheDir = getCacheDir();
|
|
9578
|
-
const versionedDir = join4(cacheDir, tag);
|
|
9579
|
-
const ext = process.platform === "win32" ? ".exe" : "";
|
|
9580
|
-
const cachedPath = join4(versionedDir, `aft${ext}`);
|
|
9581
|
-
if (existsSync3(cachedPath)) {
|
|
9582
|
-
const cachedVersion = readBinaryVersion(cachedPath);
|
|
9583
|
-
if (cachedVersion === version)
|
|
9584
|
-
return cachedPath;
|
|
9585
|
-
warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
|
|
9586
|
-
}
|
|
9587
|
-
mkdirSync3(versionedDir, { recursive: true });
|
|
9588
|
-
const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
|
|
9589
|
-
copyFileSync2(npmBinaryPath, tmpPath);
|
|
9590
|
-
if (process.platform !== "win32") {
|
|
9591
|
-
chmodSync3(tmpPath, 493);
|
|
9592
|
-
}
|
|
9593
|
-
renameSync2(tmpPath, cachedPath);
|
|
9594
|
-
log(`Copied npm binary to versioned cache: ${cachedPath}`);
|
|
9595
|
-
return cachedPath;
|
|
9596
|
-
} catch (err) {
|
|
9597
|
-
warn(`Failed to copy binary to cache: ${err instanceof Error ? err.message : String(err)}`);
|
|
9598
|
-
return null;
|
|
9599
|
-
}
|
|
9600
|
-
}
|
|
9601
|
-
function normalizeBareVersion(version) {
|
|
9602
|
-
return version.startsWith("v") ? version.slice(1) : version;
|
|
9603
|
-
}
|
|
9604
|
-
function homeDirFromEnv(env) {
|
|
9605
|
-
return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir4();
|
|
9606
|
-
}
|
|
9607
|
-
function cacheDirFromEnv(env) {
|
|
9608
|
-
if (process.platform === "win32") {
|
|
9609
|
-
const base2 = env.LOCALAPPDATA || env.APPDATA || join4(homeDirFromEnv(env), "AppData", "Local");
|
|
9610
|
-
return join4(base2, "aft", "bin");
|
|
9611
|
-
}
|
|
9612
|
-
const base = env.XDG_CACHE_HOME || join4(homeDirFromEnv(env), ".cache");
|
|
9613
|
-
return join4(base, "aft", "bin");
|
|
9614
|
-
}
|
|
9615
|
-
function cachedBinaryPathFromEnv(version, env, ext) {
|
|
9616
|
-
const binaryPath = join4(cacheDirFromEnv(env), version, `aft${ext}`);
|
|
9617
|
-
return existsSync3(binaryPath) ? binaryPath : null;
|
|
9618
|
-
}
|
|
9619
|
-
function isExpectedCachedBinary(binaryPath, expectedVersion) {
|
|
9620
|
-
const expected = normalizeBareVersion(expectedVersion);
|
|
9621
|
-
const actual = readBinaryVersion(binaryPath);
|
|
9622
|
-
if (actual === expected)
|
|
9623
|
-
return true;
|
|
9624
|
-
warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
|
|
9625
|
-
return false;
|
|
9626
|
-
}
|
|
9627
|
-
function platformKey(platform = process.platform, arch = process.arch) {
|
|
9628
|
-
const archMap = PLATFORM_ARCH_MAP[platform];
|
|
9629
|
-
if (!archMap) {
|
|
9630
|
-
throw new Error(`Unsupported platform: ${platform} (arch: ${arch}). ` + `Supported platforms: ${Object.keys(PLATFORM_ARCH_MAP).join(", ")}`);
|
|
9631
|
-
}
|
|
9632
|
-
const key = archMap[arch];
|
|
9633
|
-
if (!key) {
|
|
9634
|
-
throw new Error(`Unsupported architecture: ${arch} on platform ${platform}. ` + `Supported architectures for ${platform}: ${Object.keys(archMap).join(", ")}`);
|
|
9635
|
-
}
|
|
9636
|
-
return key;
|
|
9637
|
-
}
|
|
9638
|
-
function findBinarySync(expectedVersion) {
|
|
9639
|
-
const ext = process.platform === "win32" ? ".exe" : "";
|
|
9640
|
-
const env = { ...process.env };
|
|
9641
|
-
const pluginVersion = expectedVersion ?? (() => {
|
|
9642
|
-
try {
|
|
9643
|
-
const req = createRequire(import.meta.url);
|
|
9644
|
-
return req("../package.json").version;
|
|
9645
|
-
} catch {
|
|
9646
|
-
return null;
|
|
9647
|
-
}
|
|
9648
|
-
})();
|
|
9649
|
-
if (pluginVersion) {
|
|
9650
|
-
const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
|
|
9651
|
-
const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
|
|
9652
|
-
if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
|
|
9653
|
-
return versionCached;
|
|
9654
|
-
}
|
|
9655
|
-
try {
|
|
9656
|
-
const key = platformKey();
|
|
9657
|
-
const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
|
|
9658
|
-
const req = createRequire(import.meta.url);
|
|
9659
|
-
const resolved = req.resolve(packageBin);
|
|
9660
|
-
if (existsSync3(resolved)) {
|
|
9661
|
-
const npmVersion = readBinaryVersion(resolved);
|
|
9662
|
-
if (npmVersion === null) {
|
|
9663
|
-
warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
|
|
9664
|
-
} else if (pluginVersion && npmVersion !== normalizeBareVersion(pluginVersion)) {
|
|
9665
|
-
warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
|
|
9666
|
-
} else {
|
|
9667
|
-
const copied = copyToVersionedCache(resolved, npmVersion);
|
|
9668
|
-
return copied ?? resolved;
|
|
9669
|
-
}
|
|
9670
|
-
}
|
|
9671
|
-
} catch {}
|
|
9672
|
-
try {
|
|
9673
|
-
const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
|
|
9674
|
-
const result = execSync(whichCmd, {
|
|
9675
|
-
encoding: "utf-8",
|
|
9676
|
-
env,
|
|
9677
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
9678
|
-
}).trim();
|
|
9679
|
-
if (result)
|
|
9680
|
-
return result;
|
|
9681
|
-
} catch {}
|
|
9682
|
-
const cargoPath = join4(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
|
|
9683
|
-
if (existsSync3(cargoPath))
|
|
9684
|
-
return cargoPath;
|
|
9685
|
-
return null;
|
|
9686
|
-
}
|
|
9687
|
-
async function findBinary(expectedVersion) {
|
|
9688
|
-
const syncResult = findBinarySync(expectedVersion);
|
|
9689
|
-
if (syncResult) {
|
|
9690
|
-
log(`Resolved binary: ${syncResult}`);
|
|
9691
|
-
return syncResult;
|
|
9692
|
-
}
|
|
9693
|
-
log("Binary not found locally, attempting auto-download...");
|
|
9694
|
-
const downloaded = await ensureBinary(expectedVersion);
|
|
9695
|
-
if (downloaded)
|
|
9696
|
-
return downloaded;
|
|
9697
|
-
throw new Error([
|
|
9698
|
-
"Could not find the `aft` binary.",
|
|
9699
|
-
"",
|
|
9700
|
-
"Attempted sources:",
|
|
9701
|
-
" - Cache directory (~/.cache/aft/bin/)",
|
|
9702
|
-
" - npm platform package (@cortexkit/aft-<platform>)",
|
|
9703
|
-
" - PATH lookup (which aft)",
|
|
9704
|
-
" - ~/.cargo/bin/aft",
|
|
9705
|
-
" - Auto-download from GitHub releases (failed)",
|
|
9706
|
-
"",
|
|
9707
|
-
"Install it using one of these methods:",
|
|
9708
|
-
" npm install @cortexkit/aft-opencode # installs platform-specific binary via npm",
|
|
9709
|
-
" cargo install agent-file-tools # from crates.io",
|
|
9710
|
-
" cargo build --release # from source (binary at target/release/aft)",
|
|
9711
|
-
"",
|
|
9712
|
-
"Or add the aft directory to your PATH."
|
|
9713
|
-
].join(`
|
|
9714
|
-
`));
|
|
9715
|
-
}
|
|
9716
9802
|
// ../aft-bridge/dist/url-fetch.js
|
|
9717
9803
|
import { createHash as createHash3 } from "crypto";
|
|
9718
9804
|
import { lookup } from "dns/promises";
|
|
9719
|
-
import { existsSync as
|
|
9805
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
9720
9806
|
import { isIP } from "net";
|
|
9721
|
-
import { join as
|
|
9807
|
+
import { join as join6 } from "path";
|
|
9722
9808
|
import { Agent, fetch as undiciFetch } from "undici";
|
|
9723
9809
|
var MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
|
|
9724
9810
|
var CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
9725
9811
|
var FETCH_TIMEOUT_MS = 30000;
|
|
9726
9812
|
var MAX_REDIRECTS = 5;
|
|
9727
9813
|
function cacheDir(storageDir) {
|
|
9728
|
-
return
|
|
9814
|
+
return join6(storageDir, "url_cache");
|
|
9729
9815
|
}
|
|
9730
9816
|
function hashUrl(url) {
|
|
9731
9817
|
return createHash3("sha256").update(url).digest("hex").slice(0, 16);
|
|
9732
9818
|
}
|
|
9733
9819
|
function metaPath(storageDir, hash) {
|
|
9734
|
-
return
|
|
9820
|
+
return join6(cacheDir(storageDir), `${hash}.meta.json`);
|
|
9735
9821
|
}
|
|
9736
9822
|
function contentPath(storageDir, hash, extension) {
|
|
9737
|
-
return
|
|
9823
|
+
return join6(cacheDir(storageDir), `${hash}${extension}`);
|
|
9738
9824
|
}
|
|
9739
9825
|
function _isPrivateIpv4(address) {
|
|
9740
9826
|
const parts = address.split(".").map((part) => Number.parseInt(part, 10));
|
|
@@ -9752,9 +9838,9 @@ function expandIpv6(addr) {
|
|
|
9752
9838
|
let normalized = addr;
|
|
9753
9839
|
const lastColon = normalized.lastIndexOf(":");
|
|
9754
9840
|
if (lastColon !== -1) {
|
|
9755
|
-
const
|
|
9756
|
-
if (
|
|
9757
|
-
const octets =
|
|
9841
|
+
const tail2 = normalized.slice(lastColon + 1);
|
|
9842
|
+
if (tail2.includes(".")) {
|
|
9843
|
+
const octets = tail2.split(".").map((p) => Number.parseInt(p, 10));
|
|
9758
9844
|
if (octets.length !== 4 || octets.some((o) => Number.isNaN(o) || o < 0 || o > 255)) {
|
|
9759
9845
|
return null;
|
|
9760
9846
|
}
|
|
@@ -9932,15 +10018,15 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
|
|
|
9932
10018
|
const allowPrivate = options.allowPrivate === true;
|
|
9933
10019
|
await assertPublicUrl(parsed, allowPrivate, options.lookup);
|
|
9934
10020
|
const dir = cacheDir(storageDir);
|
|
9935
|
-
|
|
10021
|
+
mkdirSync5(dir, { recursive: true });
|
|
9936
10022
|
const hash = hashUrl(url);
|
|
9937
10023
|
const metaFile = metaPath(storageDir, hash);
|
|
9938
|
-
if (
|
|
10024
|
+
if (existsSync5(metaFile)) {
|
|
9939
10025
|
try {
|
|
9940
10026
|
const meta2 = JSON.parse(readFileSync2(metaFile, "utf8"));
|
|
9941
10027
|
const age = Date.now() - meta2.fetchedAt;
|
|
9942
10028
|
const cached = contentPath(storageDir, hash, meta2.extension);
|
|
9943
|
-
if (age < CACHE_TTL_MS &&
|
|
10029
|
+
if (age < CACHE_TTL_MS && existsSync5(cached)) {
|
|
9944
10030
|
log(`URL cache hit: ${url} (${Math.round(age / 1000)}s old)`);
|
|
9945
10031
|
return cached;
|
|
9946
10032
|
}
|
|
@@ -10002,21 +10088,21 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
|
|
|
10002
10088
|
}
|
|
10003
10089
|
function cleanupUrlCache(storageDir) {
|
|
10004
10090
|
const dir = cacheDir(storageDir);
|
|
10005
|
-
if (!
|
|
10091
|
+
if (!existsSync5(dir))
|
|
10006
10092
|
return;
|
|
10007
10093
|
let removed = 0;
|
|
10008
10094
|
try {
|
|
10009
10095
|
for (const entry of readdirSync2(dir)) {
|
|
10010
10096
|
if (!entry.endsWith(".meta.json"))
|
|
10011
10097
|
continue;
|
|
10012
|
-
const metaFile =
|
|
10098
|
+
const metaFile = join6(dir, entry);
|
|
10013
10099
|
try {
|
|
10014
10100
|
const meta = JSON.parse(readFileSync2(metaFile, "utf8"));
|
|
10015
10101
|
const age = Date.now() - meta.fetchedAt;
|
|
10016
10102
|
if (age > CACHE_TTL_MS) {
|
|
10017
10103
|
const hash = entry.slice(0, -".meta.json".length);
|
|
10018
10104
|
const content = contentPath(storageDir, hash, meta.extension);
|
|
10019
|
-
if (
|
|
10105
|
+
if (existsSync5(content))
|
|
10020
10106
|
unlinkSync3(content);
|
|
10021
10107
|
unlinkSync3(metaFile);
|
|
10022
10108
|
removed++;
|
|
@@ -10218,6 +10304,7 @@ function mergeContexts(base, patch) {
|
|
|
10218
10304
|
function isComplete(ctx) {
|
|
10219
10305
|
return Boolean(ctx.agent && ctx.model && ctx.variant);
|
|
10220
10306
|
}
|
|
10307
|
+
var PROMPT_CONTEXT_MESSAGE_LIMIT = 50;
|
|
10221
10308
|
async function resolvePromptContext(client, sessionId) {
|
|
10222
10309
|
if (!client || !sessionId)
|
|
10223
10310
|
return null;
|
|
@@ -10226,7 +10313,10 @@ async function resolvePromptContext(client, sessionId) {
|
|
|
10226
10313
|
return null;
|
|
10227
10314
|
let messages = [];
|
|
10228
10315
|
try {
|
|
10229
|
-
const response = await c.session.messages({
|
|
10316
|
+
const response = await c.session.messages({
|
|
10317
|
+
path: { id: sessionId },
|
|
10318
|
+
query: { limit: PROMPT_CONTEXT_MESSAGE_LIMIT }
|
|
10319
|
+
});
|
|
10230
10320
|
messages = extractMessages(response);
|
|
10231
10321
|
} catch {
|
|
10232
10322
|
return null;
|
|
@@ -10384,12 +10474,12 @@ function formatSystemReminder(completions) {
|
|
|
10384
10474
|
const bullets = completions.map((completion) => formatCompletion(completion)).join(`
|
|
10385
10475
|
`);
|
|
10386
10476
|
const anyTruncated = completions.some((c) => c.output_truncated === true);
|
|
10387
|
-
const
|
|
10477
|
+
const tail2 = anyTruncated ? `
|
|
10388
10478
|
|
|
10389
10479
|
For truncated tasks, use bash_status({ taskId: "..." }) to retrieve full output.` : "";
|
|
10390
10480
|
return `<system-reminder>
|
|
10391
10481
|
[BACKGROUND BASH COMPLETED]
|
|
10392
|
-
${bullets}${
|
|
10482
|
+
${bullets}${tail2}
|
|
10393
10483
|
</system-reminder>`;
|
|
10394
10484
|
}
|
|
10395
10485
|
function formatLongRunningReminder(reminders) {
|
|
@@ -10644,9 +10734,9 @@ function formatDuration(completion) {
|
|
|
10644
10734
|
|
|
10645
10735
|
// src/config.ts
|
|
10646
10736
|
var import_comment_json = __toESM(require_src2(), 1);
|
|
10647
|
-
import { existsSync as
|
|
10737
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
10648
10738
|
import { homedir as homedir5 } from "os";
|
|
10649
|
-
import { join as
|
|
10739
|
+
import { join as join8 } from "path";
|
|
10650
10740
|
|
|
10651
10741
|
// ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
|
|
10652
10742
|
var exports_external = {};
|
|
@@ -24399,7 +24489,7 @@ function migrateRawConfig(rawConfig, configPath, logger) {
|
|
|
24399
24489
|
return oldKeys;
|
|
24400
24490
|
}
|
|
24401
24491
|
function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
|
|
24402
|
-
if (!
|
|
24492
|
+
if (!existsSync6(configPath)) {
|
|
24403
24493
|
return { migrated: false, oldKeys: [] };
|
|
24404
24494
|
}
|
|
24405
24495
|
let tmpPath = null;
|
|
@@ -24443,10 +24533,10 @@ ${serialized}` : serialized;
|
|
|
24443
24533
|
function detectConfigFile(basePath) {
|
|
24444
24534
|
const jsoncPath = `${basePath}.jsonc`;
|
|
24445
24535
|
const jsonPath = `${basePath}.json`;
|
|
24446
|
-
if (
|
|
24536
|
+
if (existsSync6(jsoncPath)) {
|
|
24447
24537
|
return { format: "jsonc", path: jsoncPath };
|
|
24448
24538
|
}
|
|
24449
|
-
if (
|
|
24539
|
+
if (existsSync6(jsonPath)) {
|
|
24450
24540
|
return { format: "json", path: jsonPath };
|
|
24451
24541
|
}
|
|
24452
24542
|
return { format: "none", path: jsonPath };
|
|
@@ -24479,7 +24569,7 @@ function parseConfigPartially(rawConfig) {
|
|
|
24479
24569
|
}
|
|
24480
24570
|
function loadConfigFromPath(configPath) {
|
|
24481
24571
|
try {
|
|
24482
|
-
if (!
|
|
24572
|
+
if (!existsSync6(configPath)) {
|
|
24483
24573
|
return null;
|
|
24484
24574
|
}
|
|
24485
24575
|
const content = readFileSync3(configPath, "utf-8");
|
|
@@ -24623,17 +24713,17 @@ function getOpenCodeConfigDir() {
|
|
|
24623
24713
|
if (envDir) {
|
|
24624
24714
|
return envDir;
|
|
24625
24715
|
}
|
|
24626
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
24627
|
-
return
|
|
24716
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join8(homedir5(), ".config");
|
|
24717
|
+
return join8(xdgConfig, "opencode");
|
|
24628
24718
|
}
|
|
24629
24719
|
function loadAftConfig(projectDirectory) {
|
|
24630
24720
|
const configDir = getOpenCodeConfigDir();
|
|
24631
|
-
const userBasePath =
|
|
24721
|
+
const userBasePath = join8(configDir, "aft");
|
|
24632
24722
|
migrateAftConfigFile(`${userBasePath}.jsonc`);
|
|
24633
24723
|
migrateAftConfigFile(`${userBasePath}.json`);
|
|
24634
24724
|
const userDetected = detectConfigFile(userBasePath);
|
|
24635
24725
|
const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
|
|
24636
|
-
const projectBasePath =
|
|
24726
|
+
const projectBasePath = join8(projectDirectory, ".opencode", "aft");
|
|
24637
24727
|
migrateAftConfigFile(`${projectBasePath}.jsonc`);
|
|
24638
24728
|
migrateAftConfigFile(`${projectBasePath}.json`);
|
|
24639
24729
|
const projectDetected = detectConfigFile(projectBasePath);
|
|
@@ -24658,44 +24748,44 @@ function loadAftConfig(projectDirectory) {
|
|
|
24658
24748
|
}
|
|
24659
24749
|
|
|
24660
24750
|
// src/hooks/auto-update-checker/index.ts
|
|
24661
|
-
import { existsSync as
|
|
24662
|
-
import { dirname as
|
|
24751
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync6, readFileSync as readFileSync6, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "fs";
|
|
24752
|
+
import { dirname as dirname5, join as join12 } from "path";
|
|
24663
24753
|
|
|
24664
24754
|
// src/hooks/auto-update-checker/cache.ts
|
|
24665
24755
|
var import_comment_json3 = __toESM(require_src2(), 1);
|
|
24666
24756
|
import { spawn as spawn2 } from "child_process";
|
|
24667
|
-
import { cpSync, existsSync as
|
|
24668
|
-
import { tmpdir as
|
|
24669
|
-
import { basename, dirname as
|
|
24757
|
+
import { cpSync, existsSync as existsSync8, mkdtempSync, readFileSync as readFileSync5, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
24758
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
24759
|
+
import { basename, dirname as dirname4, join as join11 } from "path";
|
|
24670
24760
|
|
|
24671
24761
|
// src/hooks/auto-update-checker/checker.ts
|
|
24672
24762
|
var import_comment_json2 = __toESM(require_src2(), 1);
|
|
24673
|
-
import { existsSync as
|
|
24763
|
+
import { existsSync as existsSync7, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
24674
24764
|
import { homedir as homedir7 } from "os";
|
|
24675
|
-
import { dirname as
|
|
24765
|
+
import { dirname as dirname3, isAbsolute, join as join10, resolve as resolve2 } from "path";
|
|
24676
24766
|
import { fileURLToPath } from "url";
|
|
24677
24767
|
|
|
24678
24768
|
// src/hooks/auto-update-checker/constants.ts
|
|
24679
24769
|
import { homedir as homedir6, platform } from "os";
|
|
24680
|
-
import { join as
|
|
24770
|
+
import { join as join9 } from "path";
|
|
24681
24771
|
var PACKAGE_NAME = "@cortexkit/aft-opencode";
|
|
24682
24772
|
var NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
24683
24773
|
var NPM_FETCH_TIMEOUT = 1e4;
|
|
24684
24774
|
function getOpenCodeCacheRoot() {
|
|
24685
24775
|
if (platform() === "win32") {
|
|
24686
|
-
return
|
|
24776
|
+
return join9(process.env.LOCALAPPDATA ?? homedir6(), "opencode");
|
|
24687
24777
|
}
|
|
24688
|
-
return
|
|
24778
|
+
return join9(homedir6(), ".cache", "opencode");
|
|
24689
24779
|
}
|
|
24690
24780
|
function getOpenCodeConfigRoot() {
|
|
24691
24781
|
if (platform() === "win32") {
|
|
24692
|
-
return
|
|
24782
|
+
return join9(process.env.APPDATA ?? join9(homedir6(), "AppData", "Roaming"), "opencode");
|
|
24693
24783
|
}
|
|
24694
|
-
return
|
|
24784
|
+
return join9(process.env.XDG_CONFIG_HOME ?? join9(homedir6(), ".config"), "opencode");
|
|
24695
24785
|
}
|
|
24696
|
-
var CACHE_DIR =
|
|
24697
|
-
var USER_OPENCODE_CONFIG =
|
|
24698
|
-
var USER_OPENCODE_CONFIG_JSONC =
|
|
24786
|
+
var CACHE_DIR = join9(getOpenCodeCacheRoot(), "packages");
|
|
24787
|
+
var USER_OPENCODE_CONFIG = join9(getOpenCodeConfigRoot(), "opencode.json");
|
|
24788
|
+
var USER_OPENCODE_CONFIG_JSONC = join9(getOpenCodeConfigRoot(), "opencode.jsonc");
|
|
24699
24789
|
|
|
24700
24790
|
// src/hooks/auto-update-checker/types.ts
|
|
24701
24791
|
var NpmPackageEnvelopeSchema = exports_external.object({
|
|
@@ -24753,8 +24843,8 @@ function extractChannel(version2) {
|
|
|
24753
24843
|
}
|
|
24754
24844
|
function getConfigPaths(directory) {
|
|
24755
24845
|
return [
|
|
24756
|
-
|
|
24757
|
-
|
|
24846
|
+
join10(directory, ".opencode", "opencode.json"),
|
|
24847
|
+
join10(directory, ".opencode", "opencode.jsonc"),
|
|
24758
24848
|
USER_OPENCODE_CONFIG,
|
|
24759
24849
|
USER_OPENCODE_CONFIG_JSONC
|
|
24760
24850
|
];
|
|
@@ -24769,12 +24859,12 @@ function resolvePathPluginSpec(spec, configPath) {
|
|
|
24769
24859
|
}
|
|
24770
24860
|
if (isAbsolute(spec) || /^[A-Za-z]:[\\/]/.test(spec))
|
|
24771
24861
|
return spec;
|
|
24772
|
-
return resolve2(
|
|
24862
|
+
return resolve2(dirname3(configPath), spec);
|
|
24773
24863
|
}
|
|
24774
24864
|
function getLocalDevPath(directory) {
|
|
24775
24865
|
for (const configPath of getConfigPaths(directory)) {
|
|
24776
24866
|
try {
|
|
24777
|
-
if (!
|
|
24867
|
+
if (!existsSync7(configPath))
|
|
24778
24868
|
continue;
|
|
24779
24869
|
const rawConfig = parseJsonConfig(readFileSync4(configPath, "utf-8"));
|
|
24780
24870
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -24798,17 +24888,17 @@ function getLocalDevPath(directory) {
|
|
|
24798
24888
|
function findPackageJsonUp(startPath) {
|
|
24799
24889
|
try {
|
|
24800
24890
|
const stat = statSync3(startPath);
|
|
24801
|
-
let dir = stat.isDirectory() ? startPath :
|
|
24891
|
+
let dir = stat.isDirectory() ? startPath : dirname3(startPath);
|
|
24802
24892
|
for (let i = 0;i < 10; i++) {
|
|
24803
|
-
const pkgPath =
|
|
24804
|
-
if (
|
|
24893
|
+
const pkgPath = join10(dir, "package.json");
|
|
24894
|
+
if (existsSync7(pkgPath)) {
|
|
24805
24895
|
try {
|
|
24806
24896
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
|
|
24807
24897
|
if (pkg.success && pkg.data.name === PACKAGE_NAME)
|
|
24808
24898
|
return pkgPath;
|
|
24809
24899
|
} catch {}
|
|
24810
24900
|
}
|
|
24811
|
-
const parent =
|
|
24901
|
+
const parent = dirname3(dir);
|
|
24812
24902
|
if (parent === dir)
|
|
24813
24903
|
break;
|
|
24814
24904
|
dir = parent;
|
|
@@ -24832,7 +24922,7 @@ function getLocalDevVersion(directory) {
|
|
|
24832
24922
|
}
|
|
24833
24923
|
function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
24834
24924
|
try {
|
|
24835
|
-
return findPackageJsonUp(
|
|
24925
|
+
return findPackageJsonUp(dirname3(fileURLToPath(currentModuleUrl)));
|
|
24836
24926
|
} catch (err) {
|
|
24837
24927
|
warn2(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
|
|
24838
24928
|
return null;
|
|
@@ -24841,7 +24931,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
|
|
|
24841
24931
|
function findPluginEntry(directory) {
|
|
24842
24932
|
for (const configPath of getConfigPaths(directory)) {
|
|
24843
24933
|
try {
|
|
24844
|
-
if (!
|
|
24934
|
+
if (!existsSync7(configPath))
|
|
24845
24935
|
continue;
|
|
24846
24936
|
const rawConfig = parseJsonConfig(readFileSync4(configPath, "utf-8"));
|
|
24847
24937
|
const plugins = getPluginEntries(rawConfig);
|
|
@@ -24861,7 +24951,7 @@ function findPluginEntry(directory) {
|
|
|
24861
24951
|
}
|
|
24862
24952
|
var cachedPackageVersion = null;
|
|
24863
24953
|
function getSpecCachePackageJsonPath(spec) {
|
|
24864
|
-
return
|
|
24954
|
+
return join10(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
|
|
24865
24955
|
}
|
|
24866
24956
|
function getCachedVersion(spec) {
|
|
24867
24957
|
if (!spec && cachedPackageVersion)
|
|
@@ -24870,11 +24960,11 @@ function getCachedVersion(spec) {
|
|
|
24870
24960
|
getCurrentRuntimePackageJsonPath(),
|
|
24871
24961
|
spec ? getSpecCachePackageJsonPath(spec) : null,
|
|
24872
24962
|
getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
|
|
24873
|
-
|
|
24963
|
+
join10(homedir7(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
|
|
24874
24964
|
].filter(isString);
|
|
24875
24965
|
for (const packageJsonPath of candidates) {
|
|
24876
24966
|
try {
|
|
24877
|
-
if (!
|
|
24967
|
+
if (!existsSync7(packageJsonPath))
|
|
24878
24968
|
continue;
|
|
24879
24969
|
const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(packageJsonPath, "utf-8")));
|
|
24880
24970
|
if (pkg.success && pkg.data.version) {
|
|
@@ -24918,17 +25008,17 @@ async function getLatestVersion(channel = "latest", options = {}) {
|
|
|
24918
25008
|
// src/hooks/auto-update-checker/cache.ts
|
|
24919
25009
|
var pendingSnapshots = new Map;
|
|
24920
25010
|
function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
|
|
24921
|
-
const packageDir =
|
|
24922
|
-
const lockfilePath =
|
|
24923
|
-
const tempDir = mkdtempSync(
|
|
24924
|
-
const stagedPackageDir =
|
|
25011
|
+
const packageDir = join11(installDir, "node_modules", packageName);
|
|
25012
|
+
const lockfilePath = join11(installDir, "package-lock.json");
|
|
25013
|
+
const tempDir = mkdtempSync(join11(tmpdir3(), "aft-auto-update-"));
|
|
25014
|
+
const stagedPackageDir = existsSync8(packageDir) ? join11(tempDir, "package") : null;
|
|
24925
25015
|
if (stagedPackageDir)
|
|
24926
25016
|
cpSync(packageDir, stagedPackageDir, { recursive: true });
|
|
24927
25017
|
return {
|
|
24928
25018
|
packageJsonPath,
|
|
24929
|
-
packageJson:
|
|
25019
|
+
packageJson: existsSync8(packageJsonPath) ? readFileSync5(packageJsonPath, "utf-8") : null,
|
|
24930
25020
|
lockfilePath,
|
|
24931
|
-
lockfile:
|
|
25021
|
+
lockfile: existsSync8(lockfilePath) ? readFileSync5(lockfilePath, "utf-8") : null,
|
|
24932
25022
|
packageDir,
|
|
24933
25023
|
stagedPackageDir,
|
|
24934
25024
|
tempDir
|
|
@@ -24957,13 +25047,13 @@ function stripPackageNameFromPath(pathValue, packageName) {
|
|
|
24957
25047
|
for (const segment of [...packageName.split("/")].reverse()) {
|
|
24958
25048
|
if (basename(current) !== segment)
|
|
24959
25049
|
return null;
|
|
24960
|
-
current =
|
|
25050
|
+
current = dirname4(current);
|
|
24961
25051
|
}
|
|
24962
25052
|
return current;
|
|
24963
25053
|
}
|
|
24964
25054
|
function removeFromPackageLock(installDir, packageName) {
|
|
24965
|
-
const lockPath =
|
|
24966
|
-
if (!
|
|
25055
|
+
const lockPath = join11(installDir, "package-lock.json");
|
|
25056
|
+
if (!existsSync8(lockPath))
|
|
24967
25057
|
return false;
|
|
24968
25058
|
try {
|
|
24969
25059
|
const lock = import_comment_json3.parse(readFileSync5(lockPath, "utf-8"));
|
|
@@ -24989,7 +25079,7 @@ function removeFromPackageLock(installDir, packageName) {
|
|
|
24989
25079
|
}
|
|
24990
25080
|
}
|
|
24991
25081
|
function ensureDependencyVersion(packageJsonPath, packageName, version2) {
|
|
24992
|
-
if (!
|
|
25082
|
+
if (!existsSync8(packageJsonPath))
|
|
24993
25083
|
return false;
|
|
24994
25084
|
try {
|
|
24995
25085
|
const raw = import_comment_json3.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
@@ -25011,8 +25101,8 @@ function ensureDependencyVersion(packageJsonPath, packageName, version2) {
|
|
|
25011
25101
|
}
|
|
25012
25102
|
}
|
|
25013
25103
|
function removeInstalledPackage(installDir, packageName) {
|
|
25014
|
-
const packageDir =
|
|
25015
|
-
if (!
|
|
25104
|
+
const packageDir = join11(installDir, "node_modules", packageName);
|
|
25105
|
+
if (!existsSync8(packageDir))
|
|
25016
25106
|
return false;
|
|
25017
25107
|
rmSync3(packageDir, { recursive: true, force: true });
|
|
25018
25108
|
log2(`[auto-update-checker] Package removed: ${packageDir}`);
|
|
@@ -25020,19 +25110,19 @@ function removeInstalledPackage(installDir, packageName) {
|
|
|
25020
25110
|
}
|
|
25021
25111
|
function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackageJsonPath()) {
|
|
25022
25112
|
if (runtimePackageJsonPath) {
|
|
25023
|
-
const packageDir =
|
|
25113
|
+
const packageDir = dirname4(runtimePackageJsonPath);
|
|
25024
25114
|
const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
|
|
25025
25115
|
if (nodeModulesDir && basename(nodeModulesDir) === "node_modules") {
|
|
25026
|
-
const installDir =
|
|
25027
|
-
const packageJsonPath =
|
|
25028
|
-
if (
|
|
25116
|
+
const installDir = dirname4(nodeModulesDir);
|
|
25117
|
+
const packageJsonPath = join11(installDir, "package.json");
|
|
25118
|
+
if (existsSync8(packageJsonPath))
|
|
25029
25119
|
return { installDir, packageJsonPath };
|
|
25030
25120
|
}
|
|
25031
25121
|
return null;
|
|
25032
25122
|
}
|
|
25033
|
-
const legacyPackageJsonPath =
|
|
25034
|
-
if (
|
|
25035
|
-
return { installDir:
|
|
25123
|
+
const legacyPackageJsonPath = join11(dirname4(CACHE_DIR), "package.json");
|
|
25124
|
+
if (existsSync8(legacyPackageJsonPath)) {
|
|
25125
|
+
return { installDir: dirname4(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
|
|
25036
25126
|
}
|
|
25037
25127
|
return null;
|
|
25038
25128
|
}
|
|
@@ -25170,8 +25260,8 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
25170
25260
|
if (!storageDir)
|
|
25171
25261
|
return true;
|
|
25172
25262
|
try {
|
|
25173
|
-
const file2 =
|
|
25174
|
-
if (
|
|
25263
|
+
const file2 = join12(storageDir, TIMESTAMP_FILENAME);
|
|
25264
|
+
if (existsSync9(file2)) {
|
|
25175
25265
|
try {
|
|
25176
25266
|
const raw = JSON.parse(readFileSync6(file2, "utf-8"));
|
|
25177
25267
|
const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
|
|
@@ -25180,7 +25270,7 @@ function claimCheckSlot(storageDir, intervalMs) {
|
|
|
25180
25270
|
}
|
|
25181
25271
|
} catch {}
|
|
25182
25272
|
}
|
|
25183
|
-
|
|
25273
|
+
mkdirSync6(dirname5(file2), { recursive: true });
|
|
25184
25274
|
const tmp = `${file2}.tmp.${process.pid}`;
|
|
25185
25275
|
writeFileSync6(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
|
|
25186
25276
|
renameSync4(tmp, file2);
|
|
@@ -25271,13 +25361,13 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
|
|
|
25271
25361
|
// src/lsp-auto-install.ts
|
|
25272
25362
|
import { spawn as spawn3 } from "child_process";
|
|
25273
25363
|
import { createHash as createHash4 } from "crypto";
|
|
25274
|
-
import { createReadStream, mkdirSync as
|
|
25275
|
-
import { join as
|
|
25364
|
+
import { createReadStream, mkdirSync as mkdirSync8, readFileSync as readFileSync8, renameSync as renameSync5, rmSync as rmSync4, statSync as statSync5 } from "fs";
|
|
25365
|
+
import { join as join15 } from "path";
|
|
25276
25366
|
|
|
25277
25367
|
// src/lsp-cache.ts
|
|
25278
25368
|
import {
|
|
25279
25369
|
closeSync as closeSync3,
|
|
25280
|
-
mkdirSync as
|
|
25370
|
+
mkdirSync as mkdirSync7,
|
|
25281
25371
|
openSync as openSync3,
|
|
25282
25372
|
readFileSync as readFileSync7,
|
|
25283
25373
|
statSync as statSync4,
|
|
@@ -25285,35 +25375,35 @@ import {
|
|
|
25285
25375
|
writeFileSync as writeFileSync7
|
|
25286
25376
|
} from "fs";
|
|
25287
25377
|
import { homedir as homedir8 } from "os";
|
|
25288
|
-
import { join as
|
|
25378
|
+
import { join as join13 } from "path";
|
|
25289
25379
|
function aftCacheBase() {
|
|
25290
25380
|
const override = process.env.AFT_CACHE_DIR;
|
|
25291
25381
|
if (override && override.length > 0)
|
|
25292
25382
|
return override;
|
|
25293
25383
|
if (process.platform === "win32") {
|
|
25294
25384
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
25295
|
-
const base2 = localAppData ||
|
|
25296
|
-
return
|
|
25385
|
+
const base2 = localAppData || join13(homedir8(), "AppData", "Local");
|
|
25386
|
+
return join13(base2, "aft");
|
|
25297
25387
|
}
|
|
25298
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
25299
|
-
return
|
|
25388
|
+
const base = process.env.XDG_CACHE_HOME || join13(homedir8(), ".cache");
|
|
25389
|
+
return join13(base, "aft");
|
|
25300
25390
|
}
|
|
25301
25391
|
function lspCacheRoot() {
|
|
25302
|
-
return
|
|
25392
|
+
return join13(aftCacheBase(), "lsp-packages");
|
|
25303
25393
|
}
|
|
25304
25394
|
function lspPackageDir(npmPackage) {
|
|
25305
|
-
return
|
|
25395
|
+
return join13(lspCacheRoot(), encodeURIComponent(npmPackage));
|
|
25306
25396
|
}
|
|
25307
25397
|
function lspBinaryPath(npmPackage, binary) {
|
|
25308
|
-
return
|
|
25398
|
+
return join13(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
|
|
25309
25399
|
}
|
|
25310
25400
|
function lspBinDir(npmPackage) {
|
|
25311
|
-
return
|
|
25401
|
+
return join13(lspPackageDir(npmPackage), "node_modules", ".bin");
|
|
25312
25402
|
}
|
|
25313
25403
|
function isInstalled(npmPackage, binary) {
|
|
25314
25404
|
for (const candidate of lspBinaryCandidates(binary)) {
|
|
25315
25405
|
try {
|
|
25316
|
-
if (statSync4(
|
|
25406
|
+
if (statSync4(join13(lspBinDir(npmPackage), candidate)).isFile())
|
|
25317
25407
|
return true;
|
|
25318
25408
|
} catch {}
|
|
25319
25409
|
}
|
|
@@ -25327,19 +25417,19 @@ function lspBinaryCandidates(binary) {
|
|
|
25327
25417
|
var INSTALLED_META_FILE = ".aft-installed";
|
|
25328
25418
|
function writeInstalledMetaIn(installDir, version2, sha256) {
|
|
25329
25419
|
try {
|
|
25330
|
-
|
|
25420
|
+
mkdirSync7(installDir, { recursive: true });
|
|
25331
25421
|
const meta3 = {
|
|
25332
25422
|
version: version2,
|
|
25333
25423
|
installedAt: new Date().toISOString(),
|
|
25334
25424
|
...sha256 ? { sha256 } : {}
|
|
25335
25425
|
};
|
|
25336
|
-
writeFileSync7(
|
|
25426
|
+
writeFileSync7(join13(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
|
|
25337
25427
|
} catch (err) {
|
|
25338
25428
|
log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
|
|
25339
25429
|
}
|
|
25340
25430
|
}
|
|
25341
25431
|
function readInstalledMetaIn(installDir) {
|
|
25342
|
-
const path2 =
|
|
25432
|
+
const path2 = join13(installDir, INSTALLED_META_FILE);
|
|
25343
25433
|
try {
|
|
25344
25434
|
if (!statSync4(path2).isFile())
|
|
25345
25435
|
return null;
|
|
@@ -25363,11 +25453,11 @@ function readInstalledMeta(packageKey) {
|
|
|
25363
25453
|
return readInstalledMetaIn(lspPackageDir(packageKey));
|
|
25364
25454
|
}
|
|
25365
25455
|
function lockPath(npmPackage) {
|
|
25366
|
-
return
|
|
25456
|
+
return join13(lspPackageDir(npmPackage), ".aft-installing");
|
|
25367
25457
|
}
|
|
25368
25458
|
var STALE_LOCK_MS2 = 30 * 60 * 1000;
|
|
25369
25459
|
function acquireInstallLock(lockKey) {
|
|
25370
|
-
|
|
25460
|
+
mkdirSync7(lspPackageDir(lockKey), { recursive: true });
|
|
25371
25461
|
const lock = lockPath(lockKey);
|
|
25372
25462
|
const tryClaim = () => {
|
|
25373
25463
|
try {
|
|
@@ -25470,7 +25560,7 @@ async function withInstallLock(lockKey, task) {
|
|
|
25470
25560
|
}
|
|
25471
25561
|
var VERSION_CHECK_FILE = ".aft-version-check";
|
|
25472
25562
|
function readVersionCheck(npmPackage) {
|
|
25473
|
-
const file2 =
|
|
25563
|
+
const file2 = join13(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
25474
25564
|
try {
|
|
25475
25565
|
const raw = readFileSync7(file2, "utf8");
|
|
25476
25566
|
const parsed = JSON.parse(raw);
|
|
@@ -25486,8 +25576,8 @@ function readVersionCheck(npmPackage) {
|
|
|
25486
25576
|
}
|
|
25487
25577
|
}
|
|
25488
25578
|
function writeVersionCheck(npmPackage, latest) {
|
|
25489
|
-
|
|
25490
|
-
const file2 =
|
|
25579
|
+
mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
|
|
25580
|
+
const file2 = join13(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
|
|
25491
25581
|
const record2 = {
|
|
25492
25582
|
last_checked: new Date().toISOString(),
|
|
25493
25583
|
latest_eligible: latest
|
|
@@ -25635,8 +25725,8 @@ var NPM_LSP_TABLE = [
|
|
|
25635
25725
|
];
|
|
25636
25726
|
|
|
25637
25727
|
// src/lsp-project-relevance.ts
|
|
25638
|
-
import { existsSync as
|
|
25639
|
-
import { join as
|
|
25728
|
+
import { existsSync as existsSync10, readdirSync as readdirSync3 } from "fs";
|
|
25729
|
+
import { join as join14 } from "path";
|
|
25640
25730
|
var MAX_WALK_DIRS = 200;
|
|
25641
25731
|
var MAX_WALK_DEPTH = 4;
|
|
25642
25732
|
var NOISE_DIRS = new Set([
|
|
@@ -25653,7 +25743,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
|
|
|
25653
25743
|
if (!rootMarkers)
|
|
25654
25744
|
return false;
|
|
25655
25745
|
for (const marker of rootMarkers) {
|
|
25656
|
-
if (
|
|
25746
|
+
if (existsSync10(join14(projectRoot, marker)))
|
|
25657
25747
|
return true;
|
|
25658
25748
|
}
|
|
25659
25749
|
return false;
|
|
@@ -25679,7 +25769,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
|
|
|
25679
25769
|
for (const entry of entries) {
|
|
25680
25770
|
if (entry.isDirectory()) {
|
|
25681
25771
|
if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
|
|
25682
|
-
queue.push({ dir:
|
|
25772
|
+
queue.push({ dir: join14(current.dir, entry.name), depth: current.depth + 1 });
|
|
25683
25773
|
}
|
|
25684
25774
|
continue;
|
|
25685
25775
|
}
|
|
@@ -25976,10 +26066,10 @@ function sha256OfFileSync(path2) {
|
|
|
25976
26066
|
}
|
|
25977
26067
|
function quarantineCachedNpmInstall(spec, reason) {
|
|
25978
26068
|
const packageDir = lspPackageDir(spec.npm);
|
|
25979
|
-
const dest =
|
|
26069
|
+
const dest = join15(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
|
|
25980
26070
|
warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
25981
26071
|
try {
|
|
25982
|
-
|
|
26072
|
+
mkdirSync8(join15(dest, ".."), { recursive: true });
|
|
25983
26073
|
rmSync4(dest, { recursive: true, force: true });
|
|
25984
26074
|
renameSync5(packageDir, dest);
|
|
25985
26075
|
} catch (err) {
|
|
@@ -26062,9 +26152,9 @@ import {
|
|
|
26062
26152
|
copyFileSync as copyFileSync3,
|
|
26063
26153
|
createReadStream as createReadStream2,
|
|
26064
26154
|
createWriteStream as createWriteStream3,
|
|
26065
|
-
existsSync as
|
|
26155
|
+
existsSync as existsSync11,
|
|
26066
26156
|
lstatSync as lstatSync2,
|
|
26067
|
-
mkdirSync as
|
|
26157
|
+
mkdirSync as mkdirSync9,
|
|
26068
26158
|
readdirSync as readdirSync4,
|
|
26069
26159
|
readFileSync as readFileSync9,
|
|
26070
26160
|
readlinkSync as readlinkSync2,
|
|
@@ -26075,7 +26165,7 @@ import {
|
|
|
26075
26165
|
unlinkSync as unlinkSync6,
|
|
26076
26166
|
writeFileSync as writeFileSync8
|
|
26077
26167
|
} from "fs";
|
|
26078
|
-
import { dirname as
|
|
26168
|
+
import { dirname as dirname6, join as join16, relative as relative2, resolve as resolve3 } from "path";
|
|
26079
26169
|
import { Readable as Readable3 } from "stream";
|
|
26080
26170
|
import { pipeline as pipeline3 } from "stream/promises";
|
|
26081
26171
|
|
|
@@ -26165,26 +26255,26 @@ function detectHostPlatform() {
|
|
|
26165
26255
|
|
|
26166
26256
|
// src/lsp-github-install.ts
|
|
26167
26257
|
function ghCacheRoot() {
|
|
26168
|
-
return
|
|
26258
|
+
return join16(aftCacheBase(), "lsp-binaries");
|
|
26169
26259
|
}
|
|
26170
26260
|
function ghPackageDir(spec) {
|
|
26171
|
-
return
|
|
26261
|
+
return join16(ghCacheRoot(), spec.id);
|
|
26172
26262
|
}
|
|
26173
26263
|
function ghBinDir(spec) {
|
|
26174
|
-
return
|
|
26264
|
+
return join16(ghPackageDir(spec), "bin");
|
|
26175
26265
|
}
|
|
26176
26266
|
function ghExtractDir(spec) {
|
|
26177
|
-
return
|
|
26267
|
+
return join16(ghPackageDir(spec), "extracted");
|
|
26178
26268
|
}
|
|
26179
26269
|
var INSTALLED_META_FILE2 = ".aft-installed";
|
|
26180
26270
|
function ghBinaryPath(spec, platform2) {
|
|
26181
26271
|
const ext = platform2 === "win32" ? ".exe" : "";
|
|
26182
|
-
return
|
|
26272
|
+
return join16(ghBinDir(spec), `${spec.binary}${ext}`);
|
|
26183
26273
|
}
|
|
26184
26274
|
function isGithubInstalled(spec, platform2) {
|
|
26185
26275
|
for (const candidate of ghBinaryCandidates(spec, platform2)) {
|
|
26186
26276
|
try {
|
|
26187
|
-
if (statSync6(
|
|
26277
|
+
if (statSync6(join16(ghBinDir(spec), candidate)).isFile())
|
|
26188
26278
|
return true;
|
|
26189
26279
|
} catch {}
|
|
26190
26280
|
}
|
|
@@ -26197,7 +26287,7 @@ function ghBinaryCandidates(spec, platform2) {
|
|
|
26197
26287
|
}
|
|
26198
26288
|
function readGithubInstalledMetaIn(installDir) {
|
|
26199
26289
|
try {
|
|
26200
|
-
const path2 =
|
|
26290
|
+
const path2 = join16(installDir, INSTALLED_META_FILE2);
|
|
26201
26291
|
if (!statSync6(path2).isFile())
|
|
26202
26292
|
return null;
|
|
26203
26293
|
const parsed = JSON.parse(readFileSync9(path2, "utf8"));
|
|
@@ -26216,7 +26306,7 @@ function readGithubInstalledMetaIn(installDir) {
|
|
|
26216
26306
|
}
|
|
26217
26307
|
function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveSha256) {
|
|
26218
26308
|
try {
|
|
26219
|
-
|
|
26309
|
+
mkdirSync9(installDir, { recursive: true });
|
|
26220
26310
|
const meta3 = {
|
|
26221
26311
|
version: version2,
|
|
26222
26312
|
installedAt: new Date().toISOString(),
|
|
@@ -26224,7 +26314,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
|
|
|
26224
26314
|
binarySha256,
|
|
26225
26315
|
...archiveSha256 ? { archiveSha256 } : {}
|
|
26226
26316
|
};
|
|
26227
|
-
writeFileSync8(
|
|
26317
|
+
writeFileSync8(join16(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
|
|
26228
26318
|
} catch (err) {
|
|
26229
26319
|
warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
|
|
26230
26320
|
}
|
|
@@ -26417,7 +26507,7 @@ async function downloadFile(url2, destPath, fetchImpl, assetSize, signal) {
|
|
|
26417
26507
|
if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
|
|
26418
26508
|
throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
|
|
26419
26509
|
}
|
|
26420
|
-
|
|
26510
|
+
mkdirSync9(dirname6(destPath), { recursive: true });
|
|
26421
26511
|
let bytesWritten = 0;
|
|
26422
26512
|
const guard = new TransformStream({
|
|
26423
26513
|
transform(chunk, controller) {
|
|
@@ -26473,7 +26563,7 @@ function validateExtraction(stagingRoot) {
|
|
|
26473
26563
|
throw new Error(`failed to read staging dir ${dir}: ${err}`);
|
|
26474
26564
|
}
|
|
26475
26565
|
for (const entry of entries) {
|
|
26476
|
-
const full =
|
|
26566
|
+
const full = join16(dir, entry);
|
|
26477
26567
|
let lst;
|
|
26478
26568
|
try {
|
|
26479
26569
|
lst = lstatSync2(full);
|
|
@@ -26543,7 +26633,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
26543
26633
|
try {
|
|
26544
26634
|
rmSync5(stagingDir, { recursive: true, force: true });
|
|
26545
26635
|
} catch {}
|
|
26546
|
-
|
|
26636
|
+
mkdirSync9(stagingDir, { recursive: true });
|
|
26547
26637
|
try {
|
|
26548
26638
|
precheckArchiveContents(archivePath, archiveType);
|
|
26549
26639
|
runPlatformExtractor(archivePath, stagingDir, archiveType);
|
|
@@ -26561,10 +26651,10 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
|
|
|
26561
26651
|
}
|
|
26562
26652
|
function quarantineCachedGithubInstall(spec, reason) {
|
|
26563
26653
|
const packageDir = ghPackageDir(spec);
|
|
26564
|
-
const dest =
|
|
26654
|
+
const dest = join16(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
|
|
26565
26655
|
warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
|
|
26566
26656
|
try {
|
|
26567
|
-
|
|
26657
|
+
mkdirSync9(dirname6(dest), { recursive: true });
|
|
26568
26658
|
rmSync5(dest, { recursive: true, force: true });
|
|
26569
26659
|
renameSync6(packageDir, dest);
|
|
26570
26660
|
} catch (err) {
|
|
@@ -26574,7 +26664,7 @@ function quarantineCachedGithubInstall(spec, reason) {
|
|
|
26574
26664
|
function validateCachedGithubInstall(spec, platform2) {
|
|
26575
26665
|
const packageDir = ghPackageDir(spec);
|
|
26576
26666
|
const meta3 = readGithubInstalledMetaIn(packageDir);
|
|
26577
|
-
const binaryPath = ghBinaryCandidates(spec, platform2).map((candidate) =>
|
|
26667
|
+
const binaryPath = ghBinaryCandidates(spec, platform2).map((candidate) => join16(ghBinDir(spec), candidate)).find((candidate) => {
|
|
26578
26668
|
try {
|
|
26579
26669
|
return statSync6(candidate).isFile();
|
|
26580
26670
|
} catch {
|
|
@@ -26652,7 +26742,7 @@ async function downloadAndInstall(spec, tag, assets, platform2, arch, fetchImpl,
|
|
|
26652
26742
|
}
|
|
26653
26743
|
const pkgDir = ghPackageDir(spec);
|
|
26654
26744
|
const extractDir = ghExtractDir(spec);
|
|
26655
|
-
const archivePath =
|
|
26745
|
+
const archivePath = join16(pkgDir, expected.name);
|
|
26656
26746
|
log2(`[lsp] downloading ${spec.id} ${tag} \u2192 ${matchingAsset.url}`);
|
|
26657
26747
|
try {
|
|
26658
26748
|
await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
|
|
@@ -26692,13 +26782,13 @@ async function downloadAndInstall(spec, tag, assets, platform2, arch, fetchImpl,
|
|
|
26692
26782
|
unlinkSync6(archivePath);
|
|
26693
26783
|
} catch {}
|
|
26694
26784
|
}
|
|
26695
|
-
const innerBinaryPath =
|
|
26696
|
-
if (!
|
|
26785
|
+
const innerBinaryPath = join16(extractDir, spec.binaryPathInArchive(platform2, arch, version2));
|
|
26786
|
+
if (!existsSync11(innerBinaryPath)) {
|
|
26697
26787
|
error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
|
|
26698
26788
|
return null;
|
|
26699
26789
|
}
|
|
26700
26790
|
const targetBinary = ghBinaryPath(spec, platform2);
|
|
26701
|
-
|
|
26791
|
+
mkdirSync9(dirname6(targetBinary), { recursive: true });
|
|
26702
26792
|
try {
|
|
26703
26793
|
copyFileSync3(innerBinaryPath, targetBinary);
|
|
26704
26794
|
if (platform2 !== "win32") {
|
|
@@ -26777,7 +26867,7 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl = fetch) {
|
|
|
26777
26867
|
if (!host) {
|
|
26778
26868
|
for (const spec of GITHUB_LSP_TABLE) {
|
|
26779
26869
|
try {
|
|
26780
|
-
if (
|
|
26870
|
+
if (existsSync11(ghBinDir(spec))) {
|
|
26781
26871
|
cachedBinDirs.push(ghBinDir(spec));
|
|
26782
26872
|
}
|
|
26783
26873
|
} catch {}
|
|
@@ -26940,9 +27030,9 @@ function normalizeToolMap(tools) {
|
|
|
26940
27030
|
}
|
|
26941
27031
|
|
|
26942
27032
|
// src/notifications.ts
|
|
26943
|
-
import { existsSync as
|
|
27033
|
+
import { existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
|
|
26944
27034
|
import { homedir as homedir9, platform as platform2 } from "os";
|
|
26945
|
-
import { join as
|
|
27035
|
+
import { join as join17 } from "path";
|
|
26946
27036
|
function isTuiMode() {
|
|
26947
27037
|
return process.env.OPENCODE_CLIENT === "cli";
|
|
26948
27038
|
}
|
|
@@ -26961,26 +27051,25 @@ var AFT_MARKER = "\uD83D\uDD27 AFT:";
|
|
|
26961
27051
|
var FEATURE_MARKER = `${AFT_MARKER} New in`;
|
|
26962
27052
|
var WARNING_MARKER = `${AFT_MARKER} \u26A0\uFE0F`;
|
|
26963
27053
|
var STATUS_MARKER = `${AFT_MARKER} \u2705`;
|
|
26964
|
-
var WARNED_TOOLS_FILE = "warned_tools.json";
|
|
26965
27054
|
function getDesktopStatePath() {
|
|
26966
27055
|
const os2 = platform2();
|
|
26967
27056
|
const home = homedir9();
|
|
26968
27057
|
if (os2 === "darwin") {
|
|
26969
|
-
return
|
|
27058
|
+
return join17(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
|
|
26970
27059
|
}
|
|
26971
27060
|
if (os2 === "linux") {
|
|
26972
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ||
|
|
26973
|
-
return
|
|
27061
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME || join17(home, ".config");
|
|
27062
|
+
return join17(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
|
|
26974
27063
|
}
|
|
26975
27064
|
if (os2 === "win32") {
|
|
26976
|
-
const appData = process.env.APPDATA ||
|
|
26977
|
-
return
|
|
27065
|
+
const appData = process.env.APPDATA || join17(home, "AppData", "Roaming");
|
|
27066
|
+
return join17(appData, "ai.opencode.desktop", "opencode.global.dat");
|
|
26978
27067
|
}
|
|
26979
27068
|
return null;
|
|
26980
27069
|
}
|
|
26981
27070
|
function readDesktopState(directory) {
|
|
26982
27071
|
const statePath = getDesktopStatePath();
|
|
26983
|
-
if (!statePath || !
|
|
27072
|
+
if (!statePath || !existsSync12(statePath)) {
|
|
26984
27073
|
return { sessionId: null, serverUrl: null };
|
|
26985
27074
|
}
|
|
26986
27075
|
try {
|
|
@@ -27018,11 +27107,15 @@ function getServerAuth() {
|
|
|
27018
27107
|
const username = process.env.OPENCODE_SERVER_USERNAME ?? "opencode";
|
|
27019
27108
|
return `Basic ${Buffer.from(`${username}:${password}`, "utf8").toString("base64")}`;
|
|
27020
27109
|
}
|
|
27110
|
+
var SESSION_MESSAGES_LIMIT = 50;
|
|
27021
27111
|
async function getSessionMessages(client, sessionId) {
|
|
27022
27112
|
try {
|
|
27023
27113
|
const c = client;
|
|
27024
27114
|
if (typeof c.session?.messages === "function") {
|
|
27025
|
-
const result = await c.session.messages({
|
|
27115
|
+
const result = await c.session.messages({
|
|
27116
|
+
path: { id: sessionId },
|
|
27117
|
+
query: { limit: SESSION_MESSAGES_LIMIT }
|
|
27118
|
+
});
|
|
27026
27119
|
return result?.data ?? [];
|
|
27027
27120
|
}
|
|
27028
27121
|
} catch {}
|
|
@@ -27078,9 +27171,9 @@ async function sendWarning(opts, message) {
|
|
|
27078
27171
|
}
|
|
27079
27172
|
async function sendFeatureAnnouncement(opts, version2, features, storageDir) {
|
|
27080
27173
|
if (storageDir) {
|
|
27081
|
-
const versionFile =
|
|
27174
|
+
const versionFile = join17(storageDir, "last_announced_version");
|
|
27082
27175
|
try {
|
|
27083
|
-
if (
|
|
27176
|
+
if (existsSync12(versionFile)) {
|
|
27084
27177
|
const lastVersion = readFileSync10(versionFile, "utf-8").trim();
|
|
27085
27178
|
if (lastVersion === version2)
|
|
27086
27179
|
return;
|
|
@@ -27101,60 +27194,41 @@ async function sendFeatureAnnouncement(opts, version2, features, storageDir) {
|
|
|
27101
27194
|
}
|
|
27102
27195
|
if (storageDir) {
|
|
27103
27196
|
try {
|
|
27104
|
-
|
|
27105
|
-
writeFileSync9(
|
|
27197
|
+
mkdirSync10(storageDir, { recursive: true });
|
|
27198
|
+
writeFileSync9(join17(storageDir, "last_announced_version"), version2);
|
|
27106
27199
|
} catch {}
|
|
27107
27200
|
}
|
|
27108
27201
|
}
|
|
27109
|
-
function readWarnedTools(
|
|
27202
|
+
async function readWarnedTools(bridge) {
|
|
27110
27203
|
try {
|
|
27111
|
-
const
|
|
27112
|
-
if (
|
|
27204
|
+
const resp = await bridge.send("db_get_state", { key: "warned_tools" });
|
|
27205
|
+
if (resp.success === false)
|
|
27206
|
+
return {};
|
|
27207
|
+
const value = resp.data?.value;
|
|
27208
|
+
if (typeof value !== "string")
|
|
27113
27209
|
return {};
|
|
27114
|
-
const parsed = JSON.parse(
|
|
27210
|
+
const parsed = JSON.parse(value);
|
|
27115
27211
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
27116
27212
|
return {};
|
|
27117
|
-
|
|
27118
|
-
for (const [key, version2] of Object.entries(parsed)) {
|
|
27119
|
-
if (typeof version2 === "string") {
|
|
27120
|
-
warned[key] = version2;
|
|
27121
|
-
}
|
|
27122
|
-
}
|
|
27123
|
-
return warned;
|
|
27213
|
+
return parsed;
|
|
27124
27214
|
} catch {
|
|
27125
27215
|
return {};
|
|
27126
27216
|
}
|
|
27127
27217
|
}
|
|
27128
|
-
function
|
|
27218
|
+
async function hasWarnedFor(bridge, key) {
|
|
27219
|
+
const warned = await readWarnedTools(bridge);
|
|
27220
|
+
return warned[key] === true || typeof warned[key] === "string";
|
|
27221
|
+
}
|
|
27222
|
+
async function recordWarning(bridge, key) {
|
|
27223
|
+
const warned = await readWarnedTools(bridge);
|
|
27224
|
+
warned[key] = true;
|
|
27129
27225
|
try {
|
|
27130
|
-
|
|
27131
|
-
|
|
27132
|
-
|
|
27133
|
-
|
|
27134
|
-
`);
|
|
27135
|
-
renameSync7(tmpPath, warnedToolsPath);
|
|
27226
|
+
await bridge.send("db_set_state", {
|
|
27227
|
+
key: "warned_tools",
|
|
27228
|
+
value: JSON.stringify(warned)
|
|
27229
|
+
});
|
|
27136
27230
|
} catch {}
|
|
27137
27231
|
}
|
|
27138
|
-
async function withWarnedToolsLock(storageDir, fn) {
|
|
27139
|
-
const lockDir = join16(storageDir, "warned_tools.lock");
|
|
27140
|
-
for (let attempt = 0;attempt < 5; attempt++) {
|
|
27141
|
-
try {
|
|
27142
|
-
mkdirSync9(storageDir, { recursive: true });
|
|
27143
|
-
mkdirSync9(lockDir, { mode: 448 });
|
|
27144
|
-
try {
|
|
27145
|
-
return await fn();
|
|
27146
|
-
} finally {
|
|
27147
|
-
rmSync6(lockDir, { recursive: true, force: true });
|
|
27148
|
-
}
|
|
27149
|
-
} catch (err) {
|
|
27150
|
-
const code = err.code;
|
|
27151
|
-
if (code !== "EEXIST")
|
|
27152
|
-
return null;
|
|
27153
|
-
await new Promise((resolve4) => setTimeout(resolve4, 10 * (attempt + 1)));
|
|
27154
|
-
}
|
|
27155
|
-
}
|
|
27156
|
-
return null;
|
|
27157
|
-
}
|
|
27158
27232
|
function warningKey(warning, projectRoot) {
|
|
27159
27233
|
const scope = warning.kind === "lsp_binary_missing" ? "_" : projectRoot ?? "_";
|
|
27160
27234
|
return [
|
|
@@ -27193,29 +27267,14 @@ ${warning.hint}`;
|
|
|
27193
27267
|
async function deliverConfigureWarnings(opts, warnings) {
|
|
27194
27268
|
if (warnings.length === 0)
|
|
27195
27269
|
return;
|
|
27196
|
-
const deliveredWithLock = await withWarnedToolsLock(opts.storageDir, async () => {
|
|
27197
|
-
const warned = readWarnedTools(opts.storageDir);
|
|
27198
|
-
let changed = false;
|
|
27199
|
-
for (const warning of warnings) {
|
|
27200
|
-
const key = warningKey(warning, opts.projectRoot);
|
|
27201
|
-
if (Object.hasOwn(warned, key))
|
|
27202
|
-
continue;
|
|
27203
|
-
const delivered = await sendIgnoredMessage(opts.client, opts.sessionId, formatConfigureWarning(warning));
|
|
27204
|
-
if (!delivered)
|
|
27205
|
-
continue;
|
|
27206
|
-
warned[key] = opts.pluginVersion;
|
|
27207
|
-
changed = true;
|
|
27208
|
-
}
|
|
27209
|
-
if (changed) {
|
|
27210
|
-
const merged = { ...readWarnedTools(opts.storageDir), ...warned };
|
|
27211
|
-
writeWarnedTools(opts.storageDir, merged);
|
|
27212
|
-
}
|
|
27213
|
-
return true;
|
|
27214
|
-
});
|
|
27215
|
-
if (deliveredWithLock)
|
|
27216
|
-
return;
|
|
27217
27270
|
for (const warning of warnings) {
|
|
27218
|
-
|
|
27271
|
+
const key = warningKey(warning, opts.projectRoot);
|
|
27272
|
+
if (await hasWarnedFor(opts.bridge, key))
|
|
27273
|
+
continue;
|
|
27274
|
+
const delivered = await sendIgnoredMessage(opts.client, opts.sessionId, formatConfigureWarning(warning));
|
|
27275
|
+
if (!delivered)
|
|
27276
|
+
continue;
|
|
27277
|
+
await recordWarning(opts.bridge, key);
|
|
27219
27278
|
}
|
|
27220
27279
|
}
|
|
27221
27280
|
async function cleanupWarnings(opts) {
|
|
@@ -27253,20 +27312,20 @@ async function cleanupWarnings(opts) {
|
|
|
27253
27312
|
|
|
27254
27313
|
// src/shared/rpc-server.ts
|
|
27255
27314
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
27256
|
-
import { mkdirSync as
|
|
27315
|
+
import { mkdirSync as mkdirSync11, renameSync as renameSync7, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "fs";
|
|
27257
27316
|
import { createServer } from "http";
|
|
27258
|
-
import { dirname as
|
|
27317
|
+
import { dirname as dirname7 } from "path";
|
|
27259
27318
|
|
|
27260
27319
|
// src/shared/rpc-utils.ts
|
|
27261
27320
|
import { createHash as createHash6 } from "crypto";
|
|
27262
|
-
import { join as
|
|
27321
|
+
import { join as join18 } from "path";
|
|
27263
27322
|
function projectHash(directory) {
|
|
27264
27323
|
const normalized = directory.replace(/\/+$/, "");
|
|
27265
27324
|
return createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
|
|
27266
27325
|
}
|
|
27267
27326
|
function rpcPortFilePath(storageDir, directory) {
|
|
27268
27327
|
const hash2 = projectHash(directory);
|
|
27269
|
-
return
|
|
27328
|
+
return join18(storageDir, "rpc", hash2, "port");
|
|
27270
27329
|
}
|
|
27271
27330
|
|
|
27272
27331
|
// src/shared/rpc-server.ts
|
|
@@ -27299,14 +27358,14 @@ class AftRpcServer {
|
|
|
27299
27358
|
this.token = randomBytes2(32).toString("hex");
|
|
27300
27359
|
this.server = server;
|
|
27301
27360
|
try {
|
|
27302
|
-
const dir =
|
|
27303
|
-
|
|
27361
|
+
const dir = dirname7(this.portFilePath);
|
|
27362
|
+
mkdirSync11(dir, { recursive: true, mode: 448 });
|
|
27304
27363
|
const tmpPath = `${this.portFilePath}.tmp`;
|
|
27305
27364
|
writeFileSync10(tmpPath, JSON.stringify({ port: this.port, token: this.token }), {
|
|
27306
27365
|
encoding: "utf-8",
|
|
27307
27366
|
mode: 384
|
|
27308
27367
|
});
|
|
27309
|
-
|
|
27368
|
+
renameSync7(tmpPath, this.portFilePath);
|
|
27310
27369
|
log2(`RPC server listening on 127.0.0.1:${this.port}`);
|
|
27311
27370
|
} catch (err) {
|
|
27312
27371
|
warn2(`Failed to write RPC port file: ${err}`);
|
|
@@ -27460,6 +27519,24 @@ function readNumber(value, fallback = 0) {
|
|
|
27460
27519
|
function readOptionalNumber(value) {
|
|
27461
27520
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
27462
27521
|
}
|
|
27522
|
+
function readCompressionAggregate(value) {
|
|
27523
|
+
const aggregate = asRecord(value);
|
|
27524
|
+
return {
|
|
27525
|
+
events: readNumber(aggregate.events),
|
|
27526
|
+
original_tokens: readNumber(aggregate.original_tokens),
|
|
27527
|
+
compressed_tokens: readNumber(aggregate.compressed_tokens),
|
|
27528
|
+
savings_tokens: readNumber(aggregate.savings_tokens)
|
|
27529
|
+
};
|
|
27530
|
+
}
|
|
27531
|
+
function readCompression(value) {
|
|
27532
|
+
if (typeof value !== "object" || value === null)
|
|
27533
|
+
return;
|
|
27534
|
+
const compression = asRecord(value);
|
|
27535
|
+
return {
|
|
27536
|
+
project: readCompressionAggregate(compression.project),
|
|
27537
|
+
session: readCompressionAggregate(compression.session)
|
|
27538
|
+
};
|
|
27539
|
+
}
|
|
27463
27540
|
function formatFlag(enabled) {
|
|
27464
27541
|
return enabled ? "enabled" : "disabled";
|
|
27465
27542
|
}
|
|
@@ -27537,7 +27614,9 @@ function coerceAftStatus(response) {
|
|
|
27537
27614
|
id: readString(session.id, "__default__"),
|
|
27538
27615
|
tracked_files: readNumber(session.tracked_files),
|
|
27539
27616
|
checkpoints: readNumber(session.checkpoints)
|
|
27540
|
-
}
|
|
27617
|
+
},
|
|
27618
|
+
compression: readCompression(response.compression),
|
|
27619
|
+
message: readString(response.message, "")
|
|
27541
27620
|
};
|
|
27542
27621
|
}
|
|
27543
27622
|
function formatStatusMarkdown(status) {
|
|
@@ -27595,21 +27674,21 @@ function formatStatusMarkdown(status) {
|
|
|
27595
27674
|
|
|
27596
27675
|
// src/shared/tui-config.ts
|
|
27597
27676
|
var import_comment_json4 = __toESM(require_src2(), 1);
|
|
27598
|
-
import { existsSync as
|
|
27599
|
-
import { dirname as
|
|
27677
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
|
|
27678
|
+
import { dirname as dirname8, join as join20 } from "path";
|
|
27600
27679
|
|
|
27601
27680
|
// src/shared/opencode-config-dir.ts
|
|
27602
27681
|
import { homedir as homedir10 } from "os";
|
|
27603
|
-
import { join as
|
|
27682
|
+
import { join as join19, resolve as resolve4 } from "path";
|
|
27604
27683
|
function getCliConfigDir() {
|
|
27605
27684
|
const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
27606
27685
|
if (envConfigDir) {
|
|
27607
27686
|
return resolve4(envConfigDir);
|
|
27608
27687
|
}
|
|
27609
27688
|
if (process.platform === "win32") {
|
|
27610
|
-
return
|
|
27689
|
+
return join19(homedir10(), ".config", "opencode");
|
|
27611
27690
|
}
|
|
27612
|
-
return
|
|
27691
|
+
return join19(process.env.XDG_CONFIG_HOME || join19(homedir10(), ".config"), "opencode");
|
|
27613
27692
|
}
|
|
27614
27693
|
function getOpenCodeConfigDir2(_options) {
|
|
27615
27694
|
return getCliConfigDir();
|
|
@@ -27618,10 +27697,10 @@ function getOpenCodeConfigPaths(options) {
|
|
|
27618
27697
|
const configDir = getOpenCodeConfigDir2(options);
|
|
27619
27698
|
return {
|
|
27620
27699
|
configDir,
|
|
27621
|
-
configJson:
|
|
27622
|
-
configJsonc:
|
|
27623
|
-
packageJson:
|
|
27624
|
-
omoConfig:
|
|
27700
|
+
configJson: join19(configDir, "opencode.json"),
|
|
27701
|
+
configJsonc: join19(configDir, "opencode.jsonc"),
|
|
27702
|
+
packageJson: join19(configDir, "package.json"),
|
|
27703
|
+
omoConfig: join19(configDir, "magic-context.jsonc")
|
|
27625
27704
|
};
|
|
27626
27705
|
}
|
|
27627
27706
|
|
|
@@ -27630,11 +27709,11 @@ var PLUGIN_NAME = "@cortexkit/aft-opencode";
|
|
|
27630
27709
|
var PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
|
|
27631
27710
|
function resolveTuiConfigPath() {
|
|
27632
27711
|
const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
|
|
27633
|
-
const jsoncPath =
|
|
27634
|
-
const jsonPath =
|
|
27635
|
-
if (
|
|
27712
|
+
const jsoncPath = join20(configDir, "tui.jsonc");
|
|
27713
|
+
const jsonPath = join20(configDir, "tui.json");
|
|
27714
|
+
if (existsSync13(jsoncPath))
|
|
27636
27715
|
return jsoncPath;
|
|
27637
|
-
if (
|
|
27716
|
+
if (existsSync13(jsonPath))
|
|
27638
27717
|
return jsonPath;
|
|
27639
27718
|
return jsonPath;
|
|
27640
27719
|
}
|
|
@@ -27642,7 +27721,7 @@ function ensureTuiPluginEntry() {
|
|
|
27642
27721
|
try {
|
|
27643
27722
|
const configPath = resolveTuiConfigPath();
|
|
27644
27723
|
let config2 = {};
|
|
27645
|
-
if (
|
|
27724
|
+
if (existsSync13(configPath)) {
|
|
27646
27725
|
config2 = import_comment_json4.parse(readFileSync11(configPath, "utf-8")) ?? {};
|
|
27647
27726
|
}
|
|
27648
27727
|
const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((value) => typeof value === "string") : [];
|
|
@@ -27651,7 +27730,7 @@ function ensureTuiPluginEntry() {
|
|
|
27651
27730
|
}
|
|
27652
27731
|
plugins.push(PLUGIN_ENTRY);
|
|
27653
27732
|
config2.plugin = plugins;
|
|
27654
|
-
|
|
27733
|
+
mkdirSync12(dirname8(configPath), { recursive: true });
|
|
27655
27734
|
writeFileSync11(configPath, `${import_comment_json4.stringify(config2, null, 2)}
|
|
27656
27735
|
`);
|
|
27657
27736
|
log2(`[aft-plugin] added TUI plugin entry to ${configPath}`);
|
|
@@ -30675,9 +30754,9 @@ function splitIncludeArg(raw) {
|
|
|
30675
30754
|
}
|
|
30676
30755
|
buf += ch;
|
|
30677
30756
|
}
|
|
30678
|
-
const
|
|
30679
|
-
if (
|
|
30680
|
-
out.push(
|
|
30757
|
+
const tail2 = buf.trim();
|
|
30758
|
+
if (tail2.length > 0)
|
|
30759
|
+
out.push(tail2);
|
|
30681
30760
|
return out;
|
|
30682
30761
|
}
|
|
30683
30762
|
function searchTools(ctx) {
|
|
@@ -31037,6 +31116,7 @@ async function handleConfigureWarningsForSession(context) {
|
|
|
31037
31116
|
await deliverConfigureWarnings({
|
|
31038
31117
|
client: context.client ?? context.fallbackClient,
|
|
31039
31118
|
sessionId: context.sessionId,
|
|
31119
|
+
bridge: context.bridge,
|
|
31040
31120
|
storageDir: context.storageDir,
|
|
31041
31121
|
pluginVersion: context.pluginVersion,
|
|
31042
31122
|
projectRoot: context.projectRoot
|
|
@@ -31091,6 +31171,7 @@ var ANNOUNCEMENT_FEATURES = [
|
|
|
31091
31171
|
var plugin = async (input) => initializePluginForDirectory(input);
|
|
31092
31172
|
async function initializePluginForDirectory(input) {
|
|
31093
31173
|
const binaryPath = await findBinary(PLUGIN_VERSION);
|
|
31174
|
+
await ensureStorageMigrated({ harness: "opencode", binaryPath, logger: bridgeLogger });
|
|
31094
31175
|
const aftConfig = loadAftConfig(input.directory);
|
|
31095
31176
|
const autoUpdateAbort = new AbortController;
|
|
31096
31177
|
const configOverrides = {};
|
|
@@ -31117,8 +31198,7 @@ async function initializePluginForDirectory(input) {
|
|
|
31117
31198
|
if (aftConfig.max_callgraph_files !== undefined)
|
|
31118
31199
|
configOverrides.max_callgraph_files = aftConfig.max_callgraph_files;
|
|
31119
31200
|
const isFastembedSemanticBackend = (aftConfig.semantic?.backend ?? "fastembed") === "fastembed";
|
|
31120
|
-
|
|
31121
|
-
configOverrides.storage_dir = join21(dataHome, "opencode", "storage", "plugin", "aft");
|
|
31201
|
+
configOverrides.storage_dir = resolveCortexKitStorageRoot();
|
|
31122
31202
|
let onnxRuntimePromise = null;
|
|
31123
31203
|
if (aftConfig.semantic_search && isFastembedSemanticBackend) {
|
|
31124
31204
|
const storageDir2 = configOverrides.storage_dir;
|
|
@@ -31225,17 +31305,23 @@ ${lines}
|
|
|
31225
31305
|
versionUpgradePromises.set(minVersion, upgradePromise);
|
|
31226
31306
|
return upgradePromise;
|
|
31227
31307
|
},
|
|
31228
|
-
onConfigureWarnings:
|
|
31308
|
+
onConfigureWarnings: ({ projectRoot, sessionId, client, warnings }) => {
|
|
31309
|
+
const bridge = pool.getActiveBridgeForRoot(projectRoot);
|
|
31310
|
+
if (!bridge)
|
|
31311
|
+
return;
|
|
31229
31312
|
const pendingWarnings = sessionId ? drainPendingEagerWarnings(projectRoot) : [];
|
|
31230
|
-
|
|
31231
|
-
|
|
31232
|
-
|
|
31233
|
-
|
|
31234
|
-
|
|
31235
|
-
|
|
31236
|
-
|
|
31237
|
-
|
|
31238
|
-
|
|
31313
|
+
setTimeout(() => {
|
|
31314
|
+
handleConfigureWarningsForSession({
|
|
31315
|
+
projectRoot,
|
|
31316
|
+
sessionId,
|
|
31317
|
+
client,
|
|
31318
|
+
bridge,
|
|
31319
|
+
warnings: [...pendingWarnings, ...warnings],
|
|
31320
|
+
fallbackClient: input.client,
|
|
31321
|
+
storageDir: configOverrides.storage_dir,
|
|
31322
|
+
pluginVersion: PLUGIN_VERSION
|
|
31323
|
+
});
|
|
31324
|
+
}, 0);
|
|
31239
31325
|
},
|
|
31240
31326
|
onBashCompletion: (completion) => {
|
|
31241
31327
|
const sessionDir = getSessionDirectoryCached(completion.session_id) ?? input.directory;
|
|
@@ -31257,6 +31343,7 @@ ${lines}
|
|
|
31257
31343
|
}
|
|
31258
31344
|
};
|
|
31259
31345
|
const pool = new BridgePool(binaryPath, poolOptions, configOverrides);
|
|
31346
|
+
pool.setConfigureOverride("harness", "opencode");
|
|
31260
31347
|
const ctx = {
|
|
31261
31348
|
pool,
|
|
31262
31349
|
client: input.client,
|
|
@@ -31276,27 +31363,6 @@ ${lines}
|
|
|
31276
31363
|
warn2(`ONNX Runtime resolution rejected unexpectedly: ${err}`);
|
|
31277
31364
|
});
|
|
31278
31365
|
}
|
|
31279
|
-
(async () => {
|
|
31280
|
-
try {
|
|
31281
|
-
if (isHomeDirectoryRoot(input.directory)) {
|
|
31282
|
-
log2(`Eager configure skipped: input.directory=${input.directory} is the user home directory. ` + `The first real tool call from a session will warm the correct project bridge.`);
|
|
31283
|
-
return;
|
|
31284
|
-
}
|
|
31285
|
-
if (onnxRuntimePromise) {
|
|
31286
|
-
await Promise.race([
|
|
31287
|
-
onnxRuntimePromise,
|
|
31288
|
-
new Promise((resolve11) => setTimeout(() => resolve11(null), 60000))
|
|
31289
|
-
]);
|
|
31290
|
-
}
|
|
31291
|
-
const bridge = pool.getBridge(input.directory);
|
|
31292
|
-
const response = await bridge.send("status", {}, { configureWarningClient: input.client });
|
|
31293
|
-
if (response.success !== false) {
|
|
31294
|
-
bridge.cacheStatusSnapshot(response);
|
|
31295
|
-
}
|
|
31296
|
-
} catch (err) {
|
|
31297
|
-
log2(`eager configure failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
31298
|
-
}
|
|
31299
|
-
})();
|
|
31300
31366
|
const rpcServer = new AftRpcServer(configOverrides.storage_dir, input.directory);
|
|
31301
31367
|
const unregisterShutdown = registerShutdownCleanup(async () => {
|
|
31302
31368
|
await Promise.allSettled([abortInFlightAutoInstalls(), abortInFlightGithubInstalls()]);
|
|
@@ -31323,11 +31389,13 @@ ${lines}
|
|
|
31323
31389
|
return {
|
|
31324
31390
|
success: true,
|
|
31325
31391
|
status: "not_initialized",
|
|
31326
|
-
message: "
|
|
31392
|
+
message: "Waiting for first tool call to populate"
|
|
31327
31393
|
};
|
|
31328
31394
|
}
|
|
31329
31395
|
const cached2 = bridge.getCachedStatus();
|
|
31330
|
-
|
|
31396
|
+
const cachedSessionId = cached2?.session;
|
|
31397
|
+
const cachedId = cachedSessionId?.id;
|
|
31398
|
+
if (cached2 !== null && cachedId === sessionID) {
|
|
31331
31399
|
return { success: true, ...cached2 };
|
|
31332
31400
|
}
|
|
31333
31401
|
const response = await bridge.send("status", { session_id: sessionID });
|
|
@@ -31342,9 +31410,9 @@ ${lines}
|
|
|
31342
31410
|
return { show: false };
|
|
31343
31411
|
}
|
|
31344
31412
|
if (storageDir) {
|
|
31345
|
-
const versionFile =
|
|
31413
|
+
const versionFile = join22(storageDir, "last_announced_version");
|
|
31346
31414
|
try {
|
|
31347
|
-
if (
|
|
31415
|
+
if (existsSync15(versionFile)) {
|
|
31348
31416
|
const lastVersion = readFileSync12(versionFile, "utf-8").trim();
|
|
31349
31417
|
if (lastVersion === ANNOUNCEMENT_VERSION)
|
|
31350
31418
|
return { show: false };
|
|
@@ -31356,8 +31424,8 @@ ${lines}
|
|
|
31356
31424
|
rpcServer.handle("mark-announced", async () => {
|
|
31357
31425
|
if (storageDir && ANNOUNCEMENT_VERSION) {
|
|
31358
31426
|
try {
|
|
31359
|
-
|
|
31360
|
-
writeFileSync12(
|
|
31427
|
+
mkdirSync13(storageDir, { recursive: true });
|
|
31428
|
+
writeFileSync12(join22(storageDir, "last_announced_version"), ANNOUNCEMENT_VERSION);
|
|
31361
31429
|
} catch {}
|
|
31362
31430
|
}
|
|
31363
31431
|
return { success: true };
|
|
@@ -31498,8 +31566,11 @@ Install: ${getManualInstallHint()}`).catch(() => {});
|
|
|
31498
31566
|
const sessionDir = await getSessionDirectory(input.client, commandInput.sessionID, input.directory) ?? input.directory;
|
|
31499
31567
|
const bridge = ctx.pool.getActiveBridgeForRoot(sessionDir) ?? ctx.pool.getBridge(sessionDir);
|
|
31500
31568
|
const cached2 = bridge.getCachedStatus();
|
|
31501
|
-
const
|
|
31502
|
-
|
|
31569
|
+
const cachedSessionId = cached2?.session;
|
|
31570
|
+
const cachedId = cachedSessionId?.id;
|
|
31571
|
+
const cacheUsable = cached2 !== null && cachedId === commandInput.sessionID;
|
|
31572
|
+
const response = cacheUsable ? { success: true, ...cached2 } : await bridge.send("status", { session_id: commandInput.sessionID });
|
|
31573
|
+
if (!cacheUsable && response.success !== false) {
|
|
31503
31574
|
bridge.cacheStatusSnapshot(response);
|
|
31504
31575
|
}
|
|
31505
31576
|
if (response.success === false) {
|