@cortexkit/aft-opencode 0.26.4 → 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/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, tail) {
1610
+ function TemplateElement2(value, tail2) {
1611
1611
  this.type = syntax_1.Syntax.TemplateElement;
1612
1612
  this.value = value;
1613
- this.tail = 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 tail = false;
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
- tail = true;
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 join7 = (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;
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 join7(comment, inside, gap);
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 = join7(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
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 += join7(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
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 = join7(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
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 += join7(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
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 existsSync14, mkdirSync as mkdirSync12, readFileSync as readFileSync12, writeFileSync as writeFileSync12 } from "fs";
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 { homedir as homedir10 } from "os";
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 chmodSync2, closeSync as closeSync2, copyFileSync, createWriteStream as createWriteStream2, existsSync as existsSync2, lstatSync, mkdirSync as mkdirSync2, openSync as openSync2, readdirSync, readFileSync, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync2, writeFileSync } from "fs";
8838
- import { dirname, join as join3, relative, resolve } from "path";
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 platformKey = archMap[process.arch];
8887
- const ortArch = platformKey ? platformKey.split("-")[1] : process.arch;
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 = join3(storageDir, "onnxruntime", ORT_VERSION);
8905
- const libPath = join3(ortDir, info?.libName ?? "libonnxruntime.dylib");
8906
- if (existsSync2(libPath)) {
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 = join3(storageDir, "onnxruntime");
8936
- mkdirSync2(onnxBaseDir, { recursive: true });
8937
- const lockPath = join3(onnxBaseDir, ONNX_LOCK_FILE);
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 = join3(onnxBaseDir, entry);
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 (existsSync2(ortDir) && !existsSync2(join3(ortDir, ONNX_INSTALLED_META_FILE))) {
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 = join3(libDir, libName);
9010
- if (existsSync2(base)) {
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 (!existsSync2(join3(dir, libName)))
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
- mkdirSync2(dirname(destPath), { recursive: true });
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 = join3(dir, entry);
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(dirname(fullPath), linkTarget);
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
- mkdirSync2(tmpDir, { recursive: true });
9138
- const archivePath = join3(tmpDir, `onnxruntime.${info.archiveType}`);
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 = join3(tmpDir, info.assetName, "lib");
9155
- if (!existsSync2(extractedDir)) {
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
- mkdirSync2(targetDir, { recursive: true });
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 = join3(extractedDir, libFile);
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 = join3(targetDir, info.libName);
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 = copyFileSync) {
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 = join3(extractedDir, libFile);
9204
- const dst = join3(targetDir, libFile);
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
- chmodSync2(dst, 493);
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 = join3(targetDir, link.name);
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 = join3(targetDir, info.libName);
9234
- if (!existsSync2(requiredPath)) {
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(join3(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
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 = join3(installDir, ONNX_INSTALLED_META_FILE);
9542
+ const path = join5(installDir, ONNX_INSTALLED_META_FILE);
9267
9543
  try {
9268
9544
  if (!statSync2(path).isFile())
9269
9545
  return null;
@@ -9523,196 +9799,28 @@ function normalizeKey(projectRoot) {
9523
9799
  return stripped;
9524
9800
  }
9525
9801
  }
9526
- // ../aft-bridge/dist/resolver.js
9527
- import { execSync, spawnSync } from "child_process";
9528
- import { chmodSync as chmodSync3, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync2 } from "fs";
9529
- import { createRequire } from "module";
9530
- import { homedir as homedir3 } from "os";
9531
- import { join as join4 } from "path";
9532
- function readBinaryVersion(binaryPath) {
9533
- try {
9534
- const result = spawnSync(binaryPath, ["--version"], {
9535
- encoding: "utf-8",
9536
- stdio: ["pipe", "pipe", "pipe"],
9537
- timeout: 5000
9538
- });
9539
- const stdoutVersion = result.stdout?.trim();
9540
- const stderrVersion = result.stderr?.trim();
9541
- const rawVersion = stdoutVersion || stderrVersion;
9542
- if (!rawVersion)
9543
- return null;
9544
- return rawVersion.replace(/^aft\s+/, "");
9545
- } catch {
9546
- return null;
9547
- }
9548
- }
9549
- function copyToVersionedCache(npmBinaryPath, knownVersion) {
9550
- try {
9551
- const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
9552
- if (!version)
9553
- return null;
9554
- const tag = version.startsWith("v") ? version : `v${version}`;
9555
- const cacheDir = getCacheDir();
9556
- const versionedDir = join4(cacheDir, tag);
9557
- const ext = process.platform === "win32" ? ".exe" : "";
9558
- const cachedPath = join4(versionedDir, `aft${ext}`);
9559
- if (existsSync3(cachedPath)) {
9560
- const cachedVersion = readBinaryVersion(cachedPath);
9561
- if (cachedVersion === version)
9562
- return cachedPath;
9563
- warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
9564
- }
9565
- mkdirSync3(versionedDir, { recursive: true });
9566
- const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
9567
- copyFileSync2(npmBinaryPath, tmpPath);
9568
- if (process.platform !== "win32") {
9569
- chmodSync3(tmpPath, 493);
9570
- }
9571
- renameSync2(tmpPath, cachedPath);
9572
- log(`Copied npm binary to versioned cache: ${cachedPath}`);
9573
- return cachedPath;
9574
- } catch (err) {
9575
- warn(`Failed to copy binary to cache: ${err instanceof Error ? err.message : String(err)}`);
9576
- return null;
9577
- }
9578
- }
9579
- function normalizeBareVersion(version) {
9580
- return version.startsWith("v") ? version.slice(1) : version;
9581
- }
9582
- function homeDirFromEnv(env) {
9583
- return (process.platform === "win32" ? env.USERPROFILE || env.HOME : env.HOME) || homedir3();
9584
- }
9585
- function cacheDirFromEnv(env) {
9586
- if (process.platform === "win32") {
9587
- const base2 = env.LOCALAPPDATA || env.APPDATA || join4(homeDirFromEnv(env), "AppData", "Local");
9588
- return join4(base2, "aft", "bin");
9589
- }
9590
- const base = env.XDG_CACHE_HOME || join4(homeDirFromEnv(env), ".cache");
9591
- return join4(base, "aft", "bin");
9592
- }
9593
- function cachedBinaryPathFromEnv(version, env, ext) {
9594
- const binaryPath = join4(cacheDirFromEnv(env), version, `aft${ext}`);
9595
- return existsSync3(binaryPath) ? binaryPath : null;
9596
- }
9597
- function isExpectedCachedBinary(binaryPath, expectedVersion) {
9598
- const expected = normalizeBareVersion(expectedVersion);
9599
- const actual = readBinaryVersion(binaryPath);
9600
- if (actual === expected)
9601
- return true;
9602
- warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
9603
- return false;
9604
- }
9605
- function platformKey(platform = process.platform, arch = process.arch) {
9606
- const archMap = PLATFORM_ARCH_MAP[platform];
9607
- if (!archMap) {
9608
- throw new Error(`Unsupported platform: ${platform} (arch: ${arch}). ` + `Supported platforms: ${Object.keys(PLATFORM_ARCH_MAP).join(", ")}`);
9609
- }
9610
- const key = archMap[arch];
9611
- if (!key) {
9612
- throw new Error(`Unsupported architecture: ${arch} on platform ${platform}. ` + `Supported architectures for ${platform}: ${Object.keys(archMap).join(", ")}`);
9613
- }
9614
- return key;
9615
- }
9616
- function findBinarySync(expectedVersion) {
9617
- const ext = process.platform === "win32" ? ".exe" : "";
9618
- const env = { ...process.env };
9619
- const pluginVersion = expectedVersion ?? (() => {
9620
- try {
9621
- const req = createRequire(import.meta.url);
9622
- return req("../package.json").version;
9623
- } catch {
9624
- return null;
9625
- }
9626
- })();
9627
- if (pluginVersion) {
9628
- const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
9629
- const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
9630
- if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
9631
- return versionCached;
9632
- }
9633
- try {
9634
- const key = platformKey();
9635
- const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
9636
- const req = createRequire(import.meta.url);
9637
- const resolved = req.resolve(packageBin);
9638
- if (existsSync3(resolved)) {
9639
- const npmVersion = readBinaryVersion(resolved);
9640
- if (npmVersion === null) {
9641
- warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
9642
- } else if (pluginVersion && npmVersion !== normalizeBareVersion(pluginVersion)) {
9643
- warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
9644
- } else {
9645
- const copied = copyToVersionedCache(resolved, npmVersion);
9646
- return copied ?? resolved;
9647
- }
9648
- }
9649
- } catch {}
9650
- try {
9651
- const whichCmd = process.platform === "win32" ? "where aft" : "which aft";
9652
- const result = execSync(whichCmd, {
9653
- encoding: "utf-8",
9654
- env,
9655
- stdio: ["pipe", "pipe", "pipe"]
9656
- }).trim();
9657
- if (result)
9658
- return result;
9659
- } catch {}
9660
- const cargoPath = join4(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
9661
- if (existsSync3(cargoPath))
9662
- return cargoPath;
9663
- return null;
9664
- }
9665
- async function findBinary(expectedVersion) {
9666
- const syncResult = findBinarySync(expectedVersion);
9667
- if (syncResult) {
9668
- log(`Resolved binary: ${syncResult}`);
9669
- return syncResult;
9670
- }
9671
- log("Binary not found locally, attempting auto-download...");
9672
- const downloaded = await ensureBinary(expectedVersion);
9673
- if (downloaded)
9674
- return downloaded;
9675
- throw new Error([
9676
- "Could not find the `aft` binary.",
9677
- "",
9678
- "Attempted sources:",
9679
- " - Cache directory (~/.cache/aft/bin/)",
9680
- " - npm platform package (@cortexkit/aft-<platform>)",
9681
- " - PATH lookup (which aft)",
9682
- " - ~/.cargo/bin/aft",
9683
- " - Auto-download from GitHub releases (failed)",
9684
- "",
9685
- "Install it using one of these methods:",
9686
- " npm install @cortexkit/aft-opencode # installs platform-specific binary via npm",
9687
- " cargo install agent-file-tools # from crates.io",
9688
- " cargo build --release # from source (binary at target/release/aft)",
9689
- "",
9690
- "Or add the aft directory to your PATH."
9691
- ].join(`
9692
- `));
9693
- }
9694
9802
  // ../aft-bridge/dist/url-fetch.js
9695
9803
  import { createHash as createHash3 } from "crypto";
9696
9804
  import { lookup } from "dns/promises";
9697
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readdirSync as readdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "fs";
9805
+ import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "fs";
9698
9806
  import { isIP } from "net";
9699
- import { join as join5 } from "path";
9807
+ import { join as join6 } from "path";
9700
9808
  import { Agent, fetch as undiciFetch } from "undici";
9701
9809
  var MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
9702
9810
  var CACHE_TTL_MS = 24 * 60 * 60 * 1000;
9703
9811
  var FETCH_TIMEOUT_MS = 30000;
9704
9812
  var MAX_REDIRECTS = 5;
9705
9813
  function cacheDir(storageDir) {
9706
- return join5(storageDir, "url_cache");
9814
+ return join6(storageDir, "url_cache");
9707
9815
  }
9708
9816
  function hashUrl(url) {
9709
9817
  return createHash3("sha256").update(url).digest("hex").slice(0, 16);
9710
9818
  }
9711
9819
  function metaPath(storageDir, hash) {
9712
- return join5(cacheDir(storageDir), `${hash}.meta.json`);
9820
+ return join6(cacheDir(storageDir), `${hash}.meta.json`);
9713
9821
  }
9714
9822
  function contentPath(storageDir, hash, extension) {
9715
- return join5(cacheDir(storageDir), `${hash}${extension}`);
9823
+ return join6(cacheDir(storageDir), `${hash}${extension}`);
9716
9824
  }
9717
9825
  function _isPrivateIpv4(address) {
9718
9826
  const parts = address.split(".").map((part) => Number.parseInt(part, 10));
@@ -9730,9 +9838,9 @@ function expandIpv6(addr) {
9730
9838
  let normalized = addr;
9731
9839
  const lastColon = normalized.lastIndexOf(":");
9732
9840
  if (lastColon !== -1) {
9733
- const tail = normalized.slice(lastColon + 1);
9734
- if (tail.includes(".")) {
9735
- const octets = tail.split(".").map((p) => Number.parseInt(p, 10));
9841
+ const tail2 = normalized.slice(lastColon + 1);
9842
+ if (tail2.includes(".")) {
9843
+ const octets = tail2.split(".").map((p) => Number.parseInt(p, 10));
9736
9844
  if (octets.length !== 4 || octets.some((o) => Number.isNaN(o) || o < 0 || o > 255)) {
9737
9845
  return null;
9738
9846
  }
@@ -9910,15 +10018,15 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
9910
10018
  const allowPrivate = options.allowPrivate === true;
9911
10019
  await assertPublicUrl(parsed, allowPrivate, options.lookup);
9912
10020
  const dir = cacheDir(storageDir);
9913
- mkdirSync4(dir, { recursive: true });
10021
+ mkdirSync5(dir, { recursive: true });
9914
10022
  const hash = hashUrl(url);
9915
10023
  const metaFile = metaPath(storageDir, hash);
9916
- if (existsSync4(metaFile)) {
10024
+ if (existsSync5(metaFile)) {
9917
10025
  try {
9918
10026
  const meta2 = JSON.parse(readFileSync2(metaFile, "utf8"));
9919
10027
  const age = Date.now() - meta2.fetchedAt;
9920
10028
  const cached = contentPath(storageDir, hash, meta2.extension);
9921
- if (age < CACHE_TTL_MS && existsSync4(cached)) {
10029
+ if (age < CACHE_TTL_MS && existsSync5(cached)) {
9922
10030
  log(`URL cache hit: ${url} (${Math.round(age / 1000)}s old)`);
9923
10031
  return cached;
9924
10032
  }
@@ -9980,21 +10088,21 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
9980
10088
  }
9981
10089
  function cleanupUrlCache(storageDir) {
9982
10090
  const dir = cacheDir(storageDir);
9983
- if (!existsSync4(dir))
10091
+ if (!existsSync5(dir))
9984
10092
  return;
9985
10093
  let removed = 0;
9986
10094
  try {
9987
10095
  for (const entry of readdirSync2(dir)) {
9988
10096
  if (!entry.endsWith(".meta.json"))
9989
10097
  continue;
9990
- const metaFile = join5(dir, entry);
10098
+ const metaFile = join6(dir, entry);
9991
10099
  try {
9992
10100
  const meta = JSON.parse(readFileSync2(metaFile, "utf8"));
9993
10101
  const age = Date.now() - meta.fetchedAt;
9994
10102
  if (age > CACHE_TTL_MS) {
9995
10103
  const hash = entry.slice(0, -".meta.json".length);
9996
10104
  const content = contentPath(storageDir, hash, meta.extension);
9997
- if (existsSync4(content))
10105
+ if (existsSync5(content))
9998
10106
  unlinkSync3(content);
9999
10107
  unlinkSync3(metaFile);
10000
10108
  removed++;
@@ -10366,12 +10474,12 @@ function formatSystemReminder(completions) {
10366
10474
  const bullets = completions.map((completion) => formatCompletion(completion)).join(`
10367
10475
  `);
10368
10476
  const anyTruncated = completions.some((c) => c.output_truncated === true);
10369
- const tail = anyTruncated ? `
10477
+ const tail2 = anyTruncated ? `
10370
10478
 
10371
10479
  For truncated tasks, use bash_status({ taskId: "..." }) to retrieve full output.` : "";
10372
10480
  return `<system-reminder>
10373
10481
  [BACKGROUND BASH COMPLETED]
10374
- ${bullets}${tail}
10482
+ ${bullets}${tail2}
10375
10483
  </system-reminder>`;
10376
10484
  }
10377
10485
  function formatLongRunningReminder(reminders) {
@@ -10626,9 +10734,9 @@ function formatDuration(completion) {
10626
10734
 
10627
10735
  // src/config.ts
10628
10736
  var import_comment_json = __toESM(require_src2(), 1);
10629
- import { existsSync as existsSync5, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "fs";
10630
- import { homedir as homedir4 } from "os";
10631
- import { join as join7 } from "path";
10737
+ import { existsSync as existsSync6, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "fs";
10738
+ import { homedir as homedir5 } from "os";
10739
+ import { join as join8 } from "path";
10632
10740
 
10633
10741
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
10634
10742
  var exports_external = {};
@@ -24381,7 +24489,7 @@ function migrateRawConfig(rawConfig, configPath, logger) {
24381
24489
  return oldKeys;
24382
24490
  }
24383
24491
  function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
24384
- if (!existsSync5(configPath)) {
24492
+ if (!existsSync6(configPath)) {
24385
24493
  return { migrated: false, oldKeys: [] };
24386
24494
  }
24387
24495
  let tmpPath = null;
@@ -24425,10 +24533,10 @@ ${serialized}` : serialized;
24425
24533
  function detectConfigFile(basePath) {
24426
24534
  const jsoncPath = `${basePath}.jsonc`;
24427
24535
  const jsonPath = `${basePath}.json`;
24428
- if (existsSync5(jsoncPath)) {
24536
+ if (existsSync6(jsoncPath)) {
24429
24537
  return { format: "jsonc", path: jsoncPath };
24430
24538
  }
24431
- if (existsSync5(jsonPath)) {
24539
+ if (existsSync6(jsonPath)) {
24432
24540
  return { format: "json", path: jsonPath };
24433
24541
  }
24434
24542
  return { format: "none", path: jsonPath };
@@ -24461,7 +24569,7 @@ function parseConfigPartially(rawConfig) {
24461
24569
  }
24462
24570
  function loadConfigFromPath(configPath) {
24463
24571
  try {
24464
- if (!existsSync5(configPath)) {
24572
+ if (!existsSync6(configPath)) {
24465
24573
  return null;
24466
24574
  }
24467
24575
  const content = readFileSync3(configPath, "utf-8");
@@ -24605,17 +24713,17 @@ function getOpenCodeConfigDir() {
24605
24713
  if (envDir) {
24606
24714
  return envDir;
24607
24715
  }
24608
- const xdgConfig = process.env.XDG_CONFIG_HOME || join7(homedir4(), ".config");
24609
- return join7(xdgConfig, "opencode");
24716
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join8(homedir5(), ".config");
24717
+ return join8(xdgConfig, "opencode");
24610
24718
  }
24611
24719
  function loadAftConfig(projectDirectory) {
24612
24720
  const configDir = getOpenCodeConfigDir();
24613
- const userBasePath = join7(configDir, "aft");
24721
+ const userBasePath = join8(configDir, "aft");
24614
24722
  migrateAftConfigFile(`${userBasePath}.jsonc`);
24615
24723
  migrateAftConfigFile(`${userBasePath}.json`);
24616
24724
  const userDetected = detectConfigFile(userBasePath);
24617
24725
  const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
24618
- const projectBasePath = join7(projectDirectory, ".opencode", "aft");
24726
+ const projectBasePath = join8(projectDirectory, ".opencode", "aft");
24619
24727
  migrateAftConfigFile(`${projectBasePath}.jsonc`);
24620
24728
  migrateAftConfigFile(`${projectBasePath}.json`);
24621
24729
  const projectDetected = detectConfigFile(projectBasePath);
@@ -24640,44 +24748,44 @@ function loadAftConfig(projectDirectory) {
24640
24748
  }
24641
24749
 
24642
24750
  // src/hooks/auto-update-checker/index.ts
24643
- import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync6, renameSync as renameSync4, writeFileSync as writeFileSync6 } from "fs";
24644
- import { dirname as dirname4, join as join11 } from "path";
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";
24645
24753
 
24646
24754
  // src/hooks/auto-update-checker/cache.ts
24647
24755
  var import_comment_json3 = __toESM(require_src2(), 1);
24648
24756
  import { spawn as spawn2 } from "child_process";
24649
- import { cpSync, existsSync as existsSync7, mkdtempSync, readFileSync as readFileSync5, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "fs";
24650
- import { tmpdir as tmpdir2 } from "os";
24651
- import { basename, dirname as dirname3, join as join10 } from "path";
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";
24652
24760
 
24653
24761
  // src/hooks/auto-update-checker/checker.ts
24654
24762
  var import_comment_json2 = __toESM(require_src2(), 1);
24655
- import { existsSync as existsSync6, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
24656
- import { homedir as homedir6 } from "os";
24657
- import { dirname as dirname2, isAbsolute, join as join9, resolve as resolve2 } from "path";
24763
+ import { existsSync as existsSync7, readFileSync as readFileSync4, statSync as statSync3, writeFileSync as writeFileSync4 } from "fs";
24764
+ import { homedir as homedir7 } from "os";
24765
+ import { dirname as dirname3, isAbsolute, join as join10, resolve as resolve2 } from "path";
24658
24766
  import { fileURLToPath } from "url";
24659
24767
 
24660
24768
  // src/hooks/auto-update-checker/constants.ts
24661
- import { homedir as homedir5, platform } from "os";
24662
- import { join as join8 } from "path";
24769
+ import { homedir as homedir6, platform } from "os";
24770
+ import { join as join9 } from "path";
24663
24771
  var PACKAGE_NAME = "@cortexkit/aft-opencode";
24664
24772
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
24665
24773
  var NPM_FETCH_TIMEOUT = 1e4;
24666
24774
  function getOpenCodeCacheRoot() {
24667
24775
  if (platform() === "win32") {
24668
- return join8(process.env.LOCALAPPDATA ?? homedir5(), "opencode");
24776
+ return join9(process.env.LOCALAPPDATA ?? homedir6(), "opencode");
24669
24777
  }
24670
- return join8(homedir5(), ".cache", "opencode");
24778
+ return join9(homedir6(), ".cache", "opencode");
24671
24779
  }
24672
24780
  function getOpenCodeConfigRoot() {
24673
24781
  if (platform() === "win32") {
24674
- return join8(process.env.APPDATA ?? join8(homedir5(), "AppData", "Roaming"), "opencode");
24782
+ return join9(process.env.APPDATA ?? join9(homedir6(), "AppData", "Roaming"), "opencode");
24675
24783
  }
24676
- return join8(process.env.XDG_CONFIG_HOME ?? join8(homedir5(), ".config"), "opencode");
24784
+ return join9(process.env.XDG_CONFIG_HOME ?? join9(homedir6(), ".config"), "opencode");
24677
24785
  }
24678
- var CACHE_DIR = join8(getOpenCodeCacheRoot(), "packages");
24679
- var USER_OPENCODE_CONFIG = join8(getOpenCodeConfigRoot(), "opencode.json");
24680
- var USER_OPENCODE_CONFIG_JSONC = join8(getOpenCodeConfigRoot(), "opencode.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");
24681
24789
 
24682
24790
  // src/hooks/auto-update-checker/types.ts
24683
24791
  var NpmPackageEnvelopeSchema = exports_external.object({
@@ -24735,8 +24843,8 @@ function extractChannel(version2) {
24735
24843
  }
24736
24844
  function getConfigPaths(directory) {
24737
24845
  return [
24738
- join9(directory, ".opencode", "opencode.json"),
24739
- join9(directory, ".opencode", "opencode.jsonc"),
24846
+ join10(directory, ".opencode", "opencode.json"),
24847
+ join10(directory, ".opencode", "opencode.jsonc"),
24740
24848
  USER_OPENCODE_CONFIG,
24741
24849
  USER_OPENCODE_CONFIG_JSONC
24742
24850
  ];
@@ -24751,12 +24859,12 @@ function resolvePathPluginSpec(spec, configPath) {
24751
24859
  }
24752
24860
  if (isAbsolute(spec) || /^[A-Za-z]:[\\/]/.test(spec))
24753
24861
  return spec;
24754
- return resolve2(dirname2(configPath), spec);
24862
+ return resolve2(dirname3(configPath), spec);
24755
24863
  }
24756
24864
  function getLocalDevPath(directory) {
24757
24865
  for (const configPath of getConfigPaths(directory)) {
24758
24866
  try {
24759
- if (!existsSync6(configPath))
24867
+ if (!existsSync7(configPath))
24760
24868
  continue;
24761
24869
  const rawConfig = parseJsonConfig(readFileSync4(configPath, "utf-8"));
24762
24870
  const plugins = getPluginEntries(rawConfig);
@@ -24780,17 +24888,17 @@ function getLocalDevPath(directory) {
24780
24888
  function findPackageJsonUp(startPath) {
24781
24889
  try {
24782
24890
  const stat = statSync3(startPath);
24783
- let dir = stat.isDirectory() ? startPath : dirname2(startPath);
24891
+ let dir = stat.isDirectory() ? startPath : dirname3(startPath);
24784
24892
  for (let i = 0;i < 10; i++) {
24785
- const pkgPath = join9(dir, "package.json");
24786
- if (existsSync6(pkgPath)) {
24893
+ const pkgPath = join10(dir, "package.json");
24894
+ if (existsSync7(pkgPath)) {
24787
24895
  try {
24788
24896
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(pkgPath, "utf-8")));
24789
24897
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
24790
24898
  return pkgPath;
24791
24899
  } catch {}
24792
24900
  }
24793
- const parent = dirname2(dir);
24901
+ const parent = dirname3(dir);
24794
24902
  if (parent === dir)
24795
24903
  break;
24796
24904
  dir = parent;
@@ -24814,7 +24922,7 @@ function getLocalDevVersion(directory) {
24814
24922
  }
24815
24923
  function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
24816
24924
  try {
24817
- return findPackageJsonUp(dirname2(fileURLToPath(currentModuleUrl)));
24925
+ return findPackageJsonUp(dirname3(fileURLToPath(currentModuleUrl)));
24818
24926
  } catch (err) {
24819
24927
  warn2(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
24820
24928
  return null;
@@ -24823,7 +24931,7 @@ function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
24823
24931
  function findPluginEntry(directory) {
24824
24932
  for (const configPath of getConfigPaths(directory)) {
24825
24933
  try {
24826
- if (!existsSync6(configPath))
24934
+ if (!existsSync7(configPath))
24827
24935
  continue;
24828
24936
  const rawConfig = parseJsonConfig(readFileSync4(configPath, "utf-8"));
24829
24937
  const plugins = getPluginEntries(rawConfig);
@@ -24843,7 +24951,7 @@ function findPluginEntry(directory) {
24843
24951
  }
24844
24952
  var cachedPackageVersion = null;
24845
24953
  function getSpecCachePackageJsonPath(spec) {
24846
- return join9(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
24954
+ return join10(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
24847
24955
  }
24848
24956
  function getCachedVersion(spec) {
24849
24957
  if (!spec && cachedPackageVersion)
@@ -24852,11 +24960,11 @@ function getCachedVersion(spec) {
24852
24960
  getCurrentRuntimePackageJsonPath(),
24853
24961
  spec ? getSpecCachePackageJsonPath(spec) : null,
24854
24962
  getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
24855
- join9(homedir6(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
24963
+ join10(homedir7(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
24856
24964
  ].filter(isString);
24857
24965
  for (const packageJsonPath of candidates) {
24858
24966
  try {
24859
- if (!existsSync6(packageJsonPath))
24967
+ if (!existsSync7(packageJsonPath))
24860
24968
  continue;
24861
24969
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync4(packageJsonPath, "utf-8")));
24862
24970
  if (pkg.success && pkg.data.version) {
@@ -24900,17 +25008,17 @@ async function getLatestVersion(channel = "latest", options = {}) {
24900
25008
  // src/hooks/auto-update-checker/cache.ts
24901
25009
  var pendingSnapshots = new Map;
24902
25010
  function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
24903
- const packageDir = join10(installDir, "node_modules", packageName);
24904
- const lockfilePath = join10(installDir, "package-lock.json");
24905
- const tempDir = mkdtempSync(join10(tmpdir2(), "aft-auto-update-"));
24906
- const stagedPackageDir = existsSync7(packageDir) ? join10(tempDir, "package") : null;
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;
24907
25015
  if (stagedPackageDir)
24908
25016
  cpSync(packageDir, stagedPackageDir, { recursive: true });
24909
25017
  return {
24910
25018
  packageJsonPath,
24911
- packageJson: existsSync7(packageJsonPath) ? readFileSync5(packageJsonPath, "utf-8") : null,
25019
+ packageJson: existsSync8(packageJsonPath) ? readFileSync5(packageJsonPath, "utf-8") : null,
24912
25020
  lockfilePath,
24913
- lockfile: existsSync7(lockfilePath) ? readFileSync5(lockfilePath, "utf-8") : null,
25021
+ lockfile: existsSync8(lockfilePath) ? readFileSync5(lockfilePath, "utf-8") : null,
24914
25022
  packageDir,
24915
25023
  stagedPackageDir,
24916
25024
  tempDir
@@ -24939,13 +25047,13 @@ function stripPackageNameFromPath(pathValue, packageName) {
24939
25047
  for (const segment of [...packageName.split("/")].reverse()) {
24940
25048
  if (basename(current) !== segment)
24941
25049
  return null;
24942
- current = dirname3(current);
25050
+ current = dirname4(current);
24943
25051
  }
24944
25052
  return current;
24945
25053
  }
24946
25054
  function removeFromPackageLock(installDir, packageName) {
24947
- const lockPath = join10(installDir, "package-lock.json");
24948
- if (!existsSync7(lockPath))
25055
+ const lockPath = join11(installDir, "package-lock.json");
25056
+ if (!existsSync8(lockPath))
24949
25057
  return false;
24950
25058
  try {
24951
25059
  const lock = import_comment_json3.parse(readFileSync5(lockPath, "utf-8"));
@@ -24971,7 +25079,7 @@ function removeFromPackageLock(installDir, packageName) {
24971
25079
  }
24972
25080
  }
24973
25081
  function ensureDependencyVersion(packageJsonPath, packageName, version2) {
24974
- if (!existsSync7(packageJsonPath))
25082
+ if (!existsSync8(packageJsonPath))
24975
25083
  return false;
24976
25084
  try {
24977
25085
  const raw = import_comment_json3.parse(readFileSync5(packageJsonPath, "utf-8"));
@@ -24993,8 +25101,8 @@ function ensureDependencyVersion(packageJsonPath, packageName, version2) {
24993
25101
  }
24994
25102
  }
24995
25103
  function removeInstalledPackage(installDir, packageName) {
24996
- const packageDir = join10(installDir, "node_modules", packageName);
24997
- if (!existsSync7(packageDir))
25104
+ const packageDir = join11(installDir, "node_modules", packageName);
25105
+ if (!existsSync8(packageDir))
24998
25106
  return false;
24999
25107
  rmSync3(packageDir, { recursive: true, force: true });
25000
25108
  log2(`[auto-update-checker] Package removed: ${packageDir}`);
@@ -25002,19 +25110,19 @@ function removeInstalledPackage(installDir, packageName) {
25002
25110
  }
25003
25111
  function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackageJsonPath()) {
25004
25112
  if (runtimePackageJsonPath) {
25005
- const packageDir = dirname3(runtimePackageJsonPath);
25113
+ const packageDir = dirname4(runtimePackageJsonPath);
25006
25114
  const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
25007
25115
  if (nodeModulesDir && basename(nodeModulesDir) === "node_modules") {
25008
- const installDir = dirname3(nodeModulesDir);
25009
- const packageJsonPath = join10(installDir, "package.json");
25010
- if (existsSync7(packageJsonPath))
25116
+ const installDir = dirname4(nodeModulesDir);
25117
+ const packageJsonPath = join11(installDir, "package.json");
25118
+ if (existsSync8(packageJsonPath))
25011
25119
  return { installDir, packageJsonPath };
25012
25120
  }
25013
25121
  return null;
25014
25122
  }
25015
- const legacyPackageJsonPath = join10(dirname3(CACHE_DIR), "package.json");
25016
- if (existsSync7(legacyPackageJsonPath)) {
25017
- return { installDir: dirname3(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
25123
+ const legacyPackageJsonPath = join11(dirname4(CACHE_DIR), "package.json");
25124
+ if (existsSync8(legacyPackageJsonPath)) {
25125
+ return { installDir: dirname4(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
25018
25126
  }
25019
25127
  return null;
25020
25128
  }
@@ -25152,8 +25260,8 @@ function claimCheckSlot(storageDir, intervalMs) {
25152
25260
  if (!storageDir)
25153
25261
  return true;
25154
25262
  try {
25155
- const file2 = join11(storageDir, TIMESTAMP_FILENAME);
25156
- if (existsSync8(file2)) {
25263
+ const file2 = join12(storageDir, TIMESTAMP_FILENAME);
25264
+ if (existsSync9(file2)) {
25157
25265
  try {
25158
25266
  const raw = JSON.parse(readFileSync6(file2, "utf-8"));
25159
25267
  const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
@@ -25162,7 +25270,7 @@ function claimCheckSlot(storageDir, intervalMs) {
25162
25270
  }
25163
25271
  } catch {}
25164
25272
  }
25165
- mkdirSync5(dirname4(file2), { recursive: true });
25273
+ mkdirSync6(dirname5(file2), { recursive: true });
25166
25274
  const tmp = `${file2}.tmp.${process.pid}`;
25167
25275
  writeFileSync6(tmp, JSON.stringify({ lastCheckedMs: Date.now() }), "utf-8");
25168
25276
  renameSync4(tmp, file2);
@@ -25253,49 +25361,49 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
25253
25361
  // src/lsp-auto-install.ts
25254
25362
  import { spawn as spawn3 } from "child_process";
25255
25363
  import { createHash as createHash4 } from "crypto";
25256
- import { createReadStream, mkdirSync as mkdirSync7, readFileSync as readFileSync8, renameSync as renameSync5, rmSync as rmSync4, statSync as statSync5 } from "fs";
25257
- import { join as join14 } from "path";
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";
25258
25366
 
25259
25367
  // src/lsp-cache.ts
25260
25368
  import {
25261
25369
  closeSync as closeSync3,
25262
- mkdirSync as mkdirSync6,
25370
+ mkdirSync as mkdirSync7,
25263
25371
  openSync as openSync3,
25264
25372
  readFileSync as readFileSync7,
25265
25373
  statSync as statSync4,
25266
25374
  unlinkSync as unlinkSync5,
25267
25375
  writeFileSync as writeFileSync7
25268
25376
  } from "fs";
25269
- import { homedir as homedir7 } from "os";
25270
- import { join as join12 } from "path";
25377
+ import { homedir as homedir8 } from "os";
25378
+ import { join as join13 } from "path";
25271
25379
  function aftCacheBase() {
25272
25380
  const override = process.env.AFT_CACHE_DIR;
25273
25381
  if (override && override.length > 0)
25274
25382
  return override;
25275
25383
  if (process.platform === "win32") {
25276
25384
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
25277
- const base2 = localAppData || join12(homedir7(), "AppData", "Local");
25278
- return join12(base2, "aft");
25385
+ const base2 = localAppData || join13(homedir8(), "AppData", "Local");
25386
+ return join13(base2, "aft");
25279
25387
  }
25280
- const base = process.env.XDG_CACHE_HOME || join12(homedir7(), ".cache");
25281
- return join12(base, "aft");
25388
+ const base = process.env.XDG_CACHE_HOME || join13(homedir8(), ".cache");
25389
+ return join13(base, "aft");
25282
25390
  }
25283
25391
  function lspCacheRoot() {
25284
- return join12(aftCacheBase(), "lsp-packages");
25392
+ return join13(aftCacheBase(), "lsp-packages");
25285
25393
  }
25286
25394
  function lspPackageDir(npmPackage) {
25287
- return join12(lspCacheRoot(), encodeURIComponent(npmPackage));
25395
+ return join13(lspCacheRoot(), encodeURIComponent(npmPackage));
25288
25396
  }
25289
25397
  function lspBinaryPath(npmPackage, binary) {
25290
- return join12(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
25398
+ return join13(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
25291
25399
  }
25292
25400
  function lspBinDir(npmPackage) {
25293
- return join12(lspPackageDir(npmPackage), "node_modules", ".bin");
25401
+ return join13(lspPackageDir(npmPackage), "node_modules", ".bin");
25294
25402
  }
25295
25403
  function isInstalled(npmPackage, binary) {
25296
25404
  for (const candidate of lspBinaryCandidates(binary)) {
25297
25405
  try {
25298
- if (statSync4(join12(lspBinDir(npmPackage), candidate)).isFile())
25406
+ if (statSync4(join13(lspBinDir(npmPackage), candidate)).isFile())
25299
25407
  return true;
25300
25408
  } catch {}
25301
25409
  }
@@ -25309,19 +25417,19 @@ function lspBinaryCandidates(binary) {
25309
25417
  var INSTALLED_META_FILE = ".aft-installed";
25310
25418
  function writeInstalledMetaIn(installDir, version2, sha256) {
25311
25419
  try {
25312
- mkdirSync6(installDir, { recursive: true });
25420
+ mkdirSync7(installDir, { recursive: true });
25313
25421
  const meta3 = {
25314
25422
  version: version2,
25315
25423
  installedAt: new Date().toISOString(),
25316
25424
  ...sha256 ? { sha256 } : {}
25317
25425
  };
25318
- writeFileSync7(join12(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
25426
+ writeFileSync7(join13(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
25319
25427
  } catch (err) {
25320
25428
  log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
25321
25429
  }
25322
25430
  }
25323
25431
  function readInstalledMetaIn(installDir) {
25324
- const path2 = join12(installDir, INSTALLED_META_FILE);
25432
+ const path2 = join13(installDir, INSTALLED_META_FILE);
25325
25433
  try {
25326
25434
  if (!statSync4(path2).isFile())
25327
25435
  return null;
@@ -25345,11 +25453,11 @@ function readInstalledMeta(packageKey) {
25345
25453
  return readInstalledMetaIn(lspPackageDir(packageKey));
25346
25454
  }
25347
25455
  function lockPath(npmPackage) {
25348
- return join12(lspPackageDir(npmPackage), ".aft-installing");
25456
+ return join13(lspPackageDir(npmPackage), ".aft-installing");
25349
25457
  }
25350
25458
  var STALE_LOCK_MS2 = 30 * 60 * 1000;
25351
25459
  function acquireInstallLock(lockKey) {
25352
- mkdirSync6(lspPackageDir(lockKey), { recursive: true });
25460
+ mkdirSync7(lspPackageDir(lockKey), { recursive: true });
25353
25461
  const lock = lockPath(lockKey);
25354
25462
  const tryClaim = () => {
25355
25463
  try {
@@ -25452,7 +25560,7 @@ async function withInstallLock(lockKey, task) {
25452
25560
  }
25453
25561
  var VERSION_CHECK_FILE = ".aft-version-check";
25454
25562
  function readVersionCheck(npmPackage) {
25455
- const file2 = join12(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
25563
+ const file2 = join13(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
25456
25564
  try {
25457
25565
  const raw = readFileSync7(file2, "utf8");
25458
25566
  const parsed = JSON.parse(raw);
@@ -25468,8 +25576,8 @@ function readVersionCheck(npmPackage) {
25468
25576
  }
25469
25577
  }
25470
25578
  function writeVersionCheck(npmPackage, latest) {
25471
- mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
25472
- const file2 = join12(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
25579
+ mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
25580
+ const file2 = join13(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
25473
25581
  const record2 = {
25474
25582
  last_checked: new Date().toISOString(),
25475
25583
  latest_eligible: latest
@@ -25617,8 +25725,8 @@ var NPM_LSP_TABLE = [
25617
25725
  ];
25618
25726
 
25619
25727
  // src/lsp-project-relevance.ts
25620
- import { existsSync as existsSync9, readdirSync as readdirSync3 } from "fs";
25621
- import { join as join13 } from "path";
25728
+ import { existsSync as existsSync10, readdirSync as readdirSync3 } from "fs";
25729
+ import { join as join14 } from "path";
25622
25730
  var MAX_WALK_DIRS = 200;
25623
25731
  var MAX_WALK_DEPTH = 4;
25624
25732
  var NOISE_DIRS = new Set([
@@ -25635,7 +25743,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
25635
25743
  if (!rootMarkers)
25636
25744
  return false;
25637
25745
  for (const marker of rootMarkers) {
25638
- if (existsSync9(join13(projectRoot, marker)))
25746
+ if (existsSync10(join14(projectRoot, marker)))
25639
25747
  return true;
25640
25748
  }
25641
25749
  return false;
@@ -25661,7 +25769,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
25661
25769
  for (const entry of entries) {
25662
25770
  if (entry.isDirectory()) {
25663
25771
  if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
25664
- queue.push({ dir: join13(current.dir, entry.name), depth: current.depth + 1 });
25772
+ queue.push({ dir: join14(current.dir, entry.name), depth: current.depth + 1 });
25665
25773
  }
25666
25774
  continue;
25667
25775
  }
@@ -25958,10 +26066,10 @@ function sha256OfFileSync(path2) {
25958
26066
  }
25959
26067
  function quarantineCachedNpmInstall(spec, reason) {
25960
26068
  const packageDir = lspPackageDir(spec.npm);
25961
- const dest = join14(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
26069
+ const dest = join15(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
25962
26070
  warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
25963
26071
  try {
25964
- mkdirSync7(join14(dest, ".."), { recursive: true });
26072
+ mkdirSync8(join15(dest, ".."), { recursive: true });
25965
26073
  rmSync4(dest, { recursive: true, force: true });
25966
26074
  renameSync5(packageDir, dest);
25967
26075
  } catch (err) {
@@ -26044,9 +26152,9 @@ import {
26044
26152
  copyFileSync as copyFileSync3,
26045
26153
  createReadStream as createReadStream2,
26046
26154
  createWriteStream as createWriteStream3,
26047
- existsSync as existsSync10,
26155
+ existsSync as existsSync11,
26048
26156
  lstatSync as lstatSync2,
26049
- mkdirSync as mkdirSync8,
26157
+ mkdirSync as mkdirSync9,
26050
26158
  readdirSync as readdirSync4,
26051
26159
  readFileSync as readFileSync9,
26052
26160
  readlinkSync as readlinkSync2,
@@ -26057,7 +26165,7 @@ import {
26057
26165
  unlinkSync as unlinkSync6,
26058
26166
  writeFileSync as writeFileSync8
26059
26167
  } from "fs";
26060
- import { dirname as dirname5, join as join15, relative as relative2, resolve as resolve3 } from "path";
26168
+ import { dirname as dirname6, join as join16, relative as relative2, resolve as resolve3 } from "path";
26061
26169
  import { Readable as Readable3 } from "stream";
26062
26170
  import { pipeline as pipeline3 } from "stream/promises";
26063
26171
 
@@ -26147,26 +26255,26 @@ function detectHostPlatform() {
26147
26255
 
26148
26256
  // src/lsp-github-install.ts
26149
26257
  function ghCacheRoot() {
26150
- return join15(aftCacheBase(), "lsp-binaries");
26258
+ return join16(aftCacheBase(), "lsp-binaries");
26151
26259
  }
26152
26260
  function ghPackageDir(spec) {
26153
- return join15(ghCacheRoot(), spec.id);
26261
+ return join16(ghCacheRoot(), spec.id);
26154
26262
  }
26155
26263
  function ghBinDir(spec) {
26156
- return join15(ghPackageDir(spec), "bin");
26264
+ return join16(ghPackageDir(spec), "bin");
26157
26265
  }
26158
26266
  function ghExtractDir(spec) {
26159
- return join15(ghPackageDir(spec), "extracted");
26267
+ return join16(ghPackageDir(spec), "extracted");
26160
26268
  }
26161
26269
  var INSTALLED_META_FILE2 = ".aft-installed";
26162
26270
  function ghBinaryPath(spec, platform2) {
26163
26271
  const ext = platform2 === "win32" ? ".exe" : "";
26164
- return join15(ghBinDir(spec), `${spec.binary}${ext}`);
26272
+ return join16(ghBinDir(spec), `${spec.binary}${ext}`);
26165
26273
  }
26166
26274
  function isGithubInstalled(spec, platform2) {
26167
26275
  for (const candidate of ghBinaryCandidates(spec, platform2)) {
26168
26276
  try {
26169
- if (statSync6(join15(ghBinDir(spec), candidate)).isFile())
26277
+ if (statSync6(join16(ghBinDir(spec), candidate)).isFile())
26170
26278
  return true;
26171
26279
  } catch {}
26172
26280
  }
@@ -26179,7 +26287,7 @@ function ghBinaryCandidates(spec, platform2) {
26179
26287
  }
26180
26288
  function readGithubInstalledMetaIn(installDir) {
26181
26289
  try {
26182
- const path2 = join15(installDir, INSTALLED_META_FILE2);
26290
+ const path2 = join16(installDir, INSTALLED_META_FILE2);
26183
26291
  if (!statSync6(path2).isFile())
26184
26292
  return null;
26185
26293
  const parsed = JSON.parse(readFileSync9(path2, "utf8"));
@@ -26198,7 +26306,7 @@ function readGithubInstalledMetaIn(installDir) {
26198
26306
  }
26199
26307
  function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveSha256) {
26200
26308
  try {
26201
- mkdirSync8(installDir, { recursive: true });
26309
+ mkdirSync9(installDir, { recursive: true });
26202
26310
  const meta3 = {
26203
26311
  version: version2,
26204
26312
  installedAt: new Date().toISOString(),
@@ -26206,7 +26314,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
26206
26314
  binarySha256,
26207
26315
  ...archiveSha256 ? { archiveSha256 } : {}
26208
26316
  };
26209
- writeFileSync8(join15(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
26317
+ writeFileSync8(join16(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
26210
26318
  } catch (err) {
26211
26319
  warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
26212
26320
  }
@@ -26399,7 +26507,7 @@ async function downloadFile(url2, destPath, fetchImpl, assetSize, signal) {
26399
26507
  if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
26400
26508
  throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
26401
26509
  }
26402
- mkdirSync8(dirname5(destPath), { recursive: true });
26510
+ mkdirSync9(dirname6(destPath), { recursive: true });
26403
26511
  let bytesWritten = 0;
26404
26512
  const guard = new TransformStream({
26405
26513
  transform(chunk, controller) {
@@ -26455,7 +26563,7 @@ function validateExtraction(stagingRoot) {
26455
26563
  throw new Error(`failed to read staging dir ${dir}: ${err}`);
26456
26564
  }
26457
26565
  for (const entry of entries) {
26458
- const full = join15(dir, entry);
26566
+ const full = join16(dir, entry);
26459
26567
  let lst;
26460
26568
  try {
26461
26569
  lst = lstatSync2(full);
@@ -26525,7 +26633,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
26525
26633
  try {
26526
26634
  rmSync5(stagingDir, { recursive: true, force: true });
26527
26635
  } catch {}
26528
- mkdirSync8(stagingDir, { recursive: true });
26636
+ mkdirSync9(stagingDir, { recursive: true });
26529
26637
  try {
26530
26638
  precheckArchiveContents(archivePath, archiveType);
26531
26639
  runPlatformExtractor(archivePath, stagingDir, archiveType);
@@ -26543,10 +26651,10 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
26543
26651
  }
26544
26652
  function quarantineCachedGithubInstall(spec, reason) {
26545
26653
  const packageDir = ghPackageDir(spec);
26546
- const dest = join15(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
26654
+ const dest = join16(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
26547
26655
  warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
26548
26656
  try {
26549
- mkdirSync8(dirname5(dest), { recursive: true });
26657
+ mkdirSync9(dirname6(dest), { recursive: true });
26550
26658
  rmSync5(dest, { recursive: true, force: true });
26551
26659
  renameSync6(packageDir, dest);
26552
26660
  } catch (err) {
@@ -26556,7 +26664,7 @@ function quarantineCachedGithubInstall(spec, reason) {
26556
26664
  function validateCachedGithubInstall(spec, platform2) {
26557
26665
  const packageDir = ghPackageDir(spec);
26558
26666
  const meta3 = readGithubInstalledMetaIn(packageDir);
26559
- const binaryPath = ghBinaryCandidates(spec, platform2).map((candidate) => join15(ghBinDir(spec), candidate)).find((candidate) => {
26667
+ const binaryPath = ghBinaryCandidates(spec, platform2).map((candidate) => join16(ghBinDir(spec), candidate)).find((candidate) => {
26560
26668
  try {
26561
26669
  return statSync6(candidate).isFile();
26562
26670
  } catch {
@@ -26634,7 +26742,7 @@ async function downloadAndInstall(spec, tag, assets, platform2, arch, fetchImpl,
26634
26742
  }
26635
26743
  const pkgDir = ghPackageDir(spec);
26636
26744
  const extractDir = ghExtractDir(spec);
26637
- const archivePath = join15(pkgDir, expected.name);
26745
+ const archivePath = join16(pkgDir, expected.name);
26638
26746
  log2(`[lsp] downloading ${spec.id} ${tag} \u2192 ${matchingAsset.url}`);
26639
26747
  try {
26640
26748
  await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
@@ -26674,13 +26782,13 @@ async function downloadAndInstall(spec, tag, assets, platform2, arch, fetchImpl,
26674
26782
  unlinkSync6(archivePath);
26675
26783
  } catch {}
26676
26784
  }
26677
- const innerBinaryPath = join15(extractDir, spec.binaryPathInArchive(platform2, arch, version2));
26678
- if (!existsSync10(innerBinaryPath)) {
26785
+ const innerBinaryPath = join16(extractDir, spec.binaryPathInArchive(platform2, arch, version2));
26786
+ if (!existsSync11(innerBinaryPath)) {
26679
26787
  error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
26680
26788
  return null;
26681
26789
  }
26682
26790
  const targetBinary = ghBinaryPath(spec, platform2);
26683
- mkdirSync8(dirname5(targetBinary), { recursive: true });
26791
+ mkdirSync9(dirname6(targetBinary), { recursive: true });
26684
26792
  try {
26685
26793
  copyFileSync3(innerBinaryPath, targetBinary);
26686
26794
  if (platform2 !== "win32") {
@@ -26759,7 +26867,7 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl = fetch) {
26759
26867
  if (!host) {
26760
26868
  for (const spec of GITHUB_LSP_TABLE) {
26761
26869
  try {
26762
- if (existsSync10(ghBinDir(spec))) {
26870
+ if (existsSync11(ghBinDir(spec))) {
26763
26871
  cachedBinDirs.push(ghBinDir(spec));
26764
26872
  }
26765
26873
  } catch {}
@@ -26922,9 +27030,9 @@ function normalizeToolMap(tools) {
26922
27030
  }
26923
27031
 
26924
27032
  // src/notifications.ts
26925
- import { existsSync as existsSync11, mkdirSync as mkdirSync9, readFileSync as readFileSync10, renameSync as renameSync7, rmSync as rmSync6, writeFileSync as writeFileSync9 } from "fs";
26926
- import { homedir as homedir8, platform as platform2 } from "os";
26927
- import { join as join16 } from "path";
27033
+ import { existsSync as existsSync12, mkdirSync as mkdirSync10, readFileSync as readFileSync10, writeFileSync as writeFileSync9 } from "fs";
27034
+ import { homedir as homedir9, platform as platform2 } from "os";
27035
+ import { join as join17 } from "path";
26928
27036
  function isTuiMode() {
26929
27037
  return process.env.OPENCODE_CLIENT === "cli";
26930
27038
  }
@@ -26943,26 +27051,25 @@ var AFT_MARKER = "\uD83D\uDD27 AFT:";
26943
27051
  var FEATURE_MARKER = `${AFT_MARKER} New in`;
26944
27052
  var WARNING_MARKER = `${AFT_MARKER} \u26A0\uFE0F`;
26945
27053
  var STATUS_MARKER = `${AFT_MARKER} \u2705`;
26946
- var WARNED_TOOLS_FILE = "warned_tools.json";
26947
27054
  function getDesktopStatePath() {
26948
27055
  const os2 = platform2();
26949
- const home = homedir8();
27056
+ const home = homedir9();
26950
27057
  if (os2 === "darwin") {
26951
- return join16(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
27058
+ return join17(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
26952
27059
  }
26953
27060
  if (os2 === "linux") {
26954
- const xdgConfig = process.env.XDG_CONFIG_HOME || join16(home, ".config");
26955
- return join16(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
27061
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join17(home, ".config");
27062
+ return join17(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
26956
27063
  }
26957
27064
  if (os2 === "win32") {
26958
- const appData = process.env.APPDATA || join16(home, "AppData", "Roaming");
26959
- return join16(appData, "ai.opencode.desktop", "opencode.global.dat");
27065
+ const appData = process.env.APPDATA || join17(home, "AppData", "Roaming");
27066
+ return join17(appData, "ai.opencode.desktop", "opencode.global.dat");
26960
27067
  }
26961
27068
  return null;
26962
27069
  }
26963
27070
  function readDesktopState(directory) {
26964
27071
  const statePath = getDesktopStatePath();
26965
- if (!statePath || !existsSync11(statePath)) {
27072
+ if (!statePath || !existsSync12(statePath)) {
26966
27073
  return { sessionId: null, serverUrl: null };
26967
27074
  }
26968
27075
  try {
@@ -27064,9 +27171,9 @@ async function sendWarning(opts, message) {
27064
27171
  }
27065
27172
  async function sendFeatureAnnouncement(opts, version2, features, storageDir) {
27066
27173
  if (storageDir) {
27067
- const versionFile = join16(storageDir, "last_announced_version");
27174
+ const versionFile = join17(storageDir, "last_announced_version");
27068
27175
  try {
27069
- if (existsSync11(versionFile)) {
27176
+ if (existsSync12(versionFile)) {
27070
27177
  const lastVersion = readFileSync10(versionFile, "utf-8").trim();
27071
27178
  if (lastVersion === version2)
27072
27179
  return;
@@ -27087,60 +27194,41 @@ async function sendFeatureAnnouncement(opts, version2, features, storageDir) {
27087
27194
  }
27088
27195
  if (storageDir) {
27089
27196
  try {
27090
- mkdirSync9(storageDir, { recursive: true });
27091
- writeFileSync9(join16(storageDir, "last_announced_version"), version2);
27197
+ mkdirSync10(storageDir, { recursive: true });
27198
+ writeFileSync9(join17(storageDir, "last_announced_version"), version2);
27092
27199
  } catch {}
27093
27200
  }
27094
27201
  }
27095
- function readWarnedTools(storageDir) {
27202
+ async function readWarnedTools(bridge) {
27096
27203
  try {
27097
- const warnedToolsPath = join16(storageDir, WARNED_TOOLS_FILE);
27098
- if (!existsSync11(warnedToolsPath))
27204
+ const resp = await bridge.send("db_get_state", { key: "warned_tools" });
27205
+ if (resp.success === false)
27099
27206
  return {};
27100
- const parsed = JSON.parse(readFileSync10(warnedToolsPath, "utf-8"));
27207
+ const value = resp.data?.value;
27208
+ if (typeof value !== "string")
27209
+ return {};
27210
+ const parsed = JSON.parse(value);
27101
27211
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
27102
27212
  return {};
27103
- const warned = {};
27104
- for (const [key, version2] of Object.entries(parsed)) {
27105
- if (typeof version2 === "string") {
27106
- warned[key] = version2;
27107
- }
27108
- }
27109
- return warned;
27213
+ return parsed;
27110
27214
  } catch {
27111
27215
  return {};
27112
27216
  }
27113
27217
  }
27114
- function writeWarnedTools(storageDir, warned) {
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;
27115
27225
  try {
27116
- mkdirSync9(storageDir, { recursive: true });
27117
- const warnedToolsPath = join16(storageDir, WARNED_TOOLS_FILE);
27118
- const tmpPath = join16(storageDir, `${WARNED_TOOLS_FILE}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`);
27119
- writeFileSync9(tmpPath, `${JSON.stringify(warned, null, 2)}
27120
- `);
27121
- renameSync7(tmpPath, warnedToolsPath);
27226
+ await bridge.send("db_set_state", {
27227
+ key: "warned_tools",
27228
+ value: JSON.stringify(warned)
27229
+ });
27122
27230
  } catch {}
27123
27231
  }
27124
- async function withWarnedToolsLock(storageDir, fn) {
27125
- const lockDir = join16(storageDir, "warned_tools.lock");
27126
- for (let attempt = 0;attempt < 5; attempt++) {
27127
- try {
27128
- mkdirSync9(storageDir, { recursive: true });
27129
- mkdirSync9(lockDir, { mode: 448 });
27130
- try {
27131
- return await fn();
27132
- } finally {
27133
- rmSync6(lockDir, { recursive: true, force: true });
27134
- }
27135
- } catch (err) {
27136
- const code = err.code;
27137
- if (code !== "EEXIST")
27138
- return null;
27139
- await new Promise((resolve4) => setTimeout(resolve4, 10 * (attempt + 1)));
27140
- }
27141
- }
27142
- return null;
27143
- }
27144
27232
  function warningKey(warning, projectRoot) {
27145
27233
  const scope = warning.kind === "lsp_binary_missing" ? "_" : projectRoot ?? "_";
27146
27234
  return [
@@ -27179,29 +27267,14 @@ ${warning.hint}`;
27179
27267
  async function deliverConfigureWarnings(opts, warnings) {
27180
27268
  if (warnings.length === 0)
27181
27269
  return;
27182
- const deliveredWithLock = await withWarnedToolsLock(opts.storageDir, async () => {
27183
- const warned = readWarnedTools(opts.storageDir);
27184
- let changed = false;
27185
- for (const warning of warnings) {
27186
- const key = warningKey(warning, opts.projectRoot);
27187
- if (Object.hasOwn(warned, key))
27188
- continue;
27189
- const delivered = await sendIgnoredMessage(opts.client, opts.sessionId, formatConfigureWarning(warning));
27190
- if (!delivered)
27191
- continue;
27192
- warned[key] = opts.pluginVersion;
27193
- changed = true;
27194
- }
27195
- if (changed) {
27196
- const merged = { ...readWarnedTools(opts.storageDir), ...warned };
27197
- writeWarnedTools(opts.storageDir, merged);
27198
- }
27199
- return true;
27200
- });
27201
- if (deliveredWithLock)
27202
- return;
27203
27270
  for (const warning of warnings) {
27204
- await sendIgnoredMessage(opts.client, opts.sessionId, formatConfigureWarning(warning));
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);
27205
27278
  }
27206
27279
  }
27207
27280
  async function cleanupWarnings(opts) {
@@ -27239,20 +27312,20 @@ async function cleanupWarnings(opts) {
27239
27312
 
27240
27313
  // src/shared/rpc-server.ts
27241
27314
  import { randomBytes as randomBytes2 } from "crypto";
27242
- import { mkdirSync as mkdirSync10, renameSync as renameSync8, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "fs";
27315
+ import { mkdirSync as mkdirSync11, renameSync as renameSync7, unlinkSync as unlinkSync7, writeFileSync as writeFileSync10 } from "fs";
27243
27316
  import { createServer } from "http";
27244
- import { dirname as dirname6 } from "path";
27317
+ import { dirname as dirname7 } from "path";
27245
27318
 
27246
27319
  // src/shared/rpc-utils.ts
27247
27320
  import { createHash as createHash6 } from "crypto";
27248
- import { join as join17 } from "path";
27321
+ import { join as join18 } from "path";
27249
27322
  function projectHash(directory) {
27250
27323
  const normalized = directory.replace(/\/+$/, "");
27251
27324
  return createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
27252
27325
  }
27253
27326
  function rpcPortFilePath(storageDir, directory) {
27254
27327
  const hash2 = projectHash(directory);
27255
- return join17(storageDir, "rpc", hash2, "port");
27328
+ return join18(storageDir, "rpc", hash2, "port");
27256
27329
  }
27257
27330
 
27258
27331
  // src/shared/rpc-server.ts
@@ -27285,14 +27358,14 @@ class AftRpcServer {
27285
27358
  this.token = randomBytes2(32).toString("hex");
27286
27359
  this.server = server;
27287
27360
  try {
27288
- const dir = dirname6(this.portFilePath);
27289
- mkdirSync10(dir, { recursive: true, mode: 448 });
27361
+ const dir = dirname7(this.portFilePath);
27362
+ mkdirSync11(dir, { recursive: true, mode: 448 });
27290
27363
  const tmpPath = `${this.portFilePath}.tmp`;
27291
27364
  writeFileSync10(tmpPath, JSON.stringify({ port: this.port, token: this.token }), {
27292
27365
  encoding: "utf-8",
27293
27366
  mode: 384
27294
27367
  });
27295
- renameSync8(tmpPath, this.portFilePath);
27368
+ renameSync7(tmpPath, this.portFilePath);
27296
27369
  log2(`RPC server listening on 127.0.0.1:${this.port}`);
27297
27370
  } catch (err) {
27298
27371
  warn2(`Failed to write RPC port file: ${err}`);
@@ -27446,6 +27519,24 @@ function readNumber(value, fallback = 0) {
27446
27519
  function readOptionalNumber(value) {
27447
27520
  return typeof value === "number" && Number.isFinite(value) ? value : null;
27448
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
+ }
27449
27540
  function formatFlag(enabled) {
27450
27541
  return enabled ? "enabled" : "disabled";
27451
27542
  }
@@ -27524,6 +27615,7 @@ function coerceAftStatus(response) {
27524
27615
  tracked_files: readNumber(session.tracked_files),
27525
27616
  checkpoints: readNumber(session.checkpoints)
27526
27617
  },
27618
+ compression: readCompression(response.compression),
27527
27619
  message: readString(response.message, "")
27528
27620
  };
27529
27621
  }
@@ -27582,21 +27674,21 @@ function formatStatusMarkdown(status) {
27582
27674
 
27583
27675
  // src/shared/tui-config.ts
27584
27676
  var import_comment_json4 = __toESM(require_src2(), 1);
27585
- import { existsSync as existsSync12, mkdirSync as mkdirSync11, readFileSync as readFileSync11, writeFileSync as writeFileSync11 } from "fs";
27586
- import { dirname as dirname7, join as join19 } from "path";
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";
27587
27679
 
27588
27680
  // src/shared/opencode-config-dir.ts
27589
- import { homedir as homedir9 } from "os";
27590
- import { join as join18, resolve as resolve4 } from "path";
27681
+ import { homedir as homedir10 } from "os";
27682
+ import { join as join19, resolve as resolve4 } from "path";
27591
27683
  function getCliConfigDir() {
27592
27684
  const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
27593
27685
  if (envConfigDir) {
27594
27686
  return resolve4(envConfigDir);
27595
27687
  }
27596
27688
  if (process.platform === "win32") {
27597
- return join18(homedir9(), ".config", "opencode");
27689
+ return join19(homedir10(), ".config", "opencode");
27598
27690
  }
27599
- return join18(process.env.XDG_CONFIG_HOME || join18(homedir9(), ".config"), "opencode");
27691
+ return join19(process.env.XDG_CONFIG_HOME || join19(homedir10(), ".config"), "opencode");
27600
27692
  }
27601
27693
  function getOpenCodeConfigDir2(_options) {
27602
27694
  return getCliConfigDir();
@@ -27605,10 +27697,10 @@ function getOpenCodeConfigPaths(options) {
27605
27697
  const configDir = getOpenCodeConfigDir2(options);
27606
27698
  return {
27607
27699
  configDir,
27608
- configJson: join18(configDir, "opencode.json"),
27609
- configJsonc: join18(configDir, "opencode.jsonc"),
27610
- packageJson: join18(configDir, "package.json"),
27611
- omoConfig: join18(configDir, "magic-context.jsonc")
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")
27612
27704
  };
27613
27705
  }
27614
27706
 
@@ -27617,11 +27709,11 @@ var PLUGIN_NAME = "@cortexkit/aft-opencode";
27617
27709
  var PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
27618
27710
  function resolveTuiConfigPath() {
27619
27711
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
27620
- const jsoncPath = join19(configDir, "tui.jsonc");
27621
- const jsonPath = join19(configDir, "tui.json");
27622
- if (existsSync12(jsoncPath))
27712
+ const jsoncPath = join20(configDir, "tui.jsonc");
27713
+ const jsonPath = join20(configDir, "tui.json");
27714
+ if (existsSync13(jsoncPath))
27623
27715
  return jsoncPath;
27624
- if (existsSync12(jsonPath))
27716
+ if (existsSync13(jsonPath))
27625
27717
  return jsonPath;
27626
27718
  return jsonPath;
27627
27719
  }
@@ -27629,7 +27721,7 @@ function ensureTuiPluginEntry() {
27629
27721
  try {
27630
27722
  const configPath = resolveTuiConfigPath();
27631
27723
  let config2 = {};
27632
- if (existsSync12(configPath)) {
27724
+ if (existsSync13(configPath)) {
27633
27725
  config2 = import_comment_json4.parse(readFileSync11(configPath, "utf-8")) ?? {};
27634
27726
  }
27635
27727
  const plugins = Array.isArray(config2.plugin) ? config2.plugin.filter((value) => typeof value === "string") : [];
@@ -27638,7 +27730,7 @@ function ensureTuiPluginEntry() {
27638
27730
  }
27639
27731
  plugins.push(PLUGIN_ENTRY);
27640
27732
  config2.plugin = plugins;
27641
- mkdirSync11(dirname7(configPath), { recursive: true });
27733
+ mkdirSync12(dirname8(configPath), { recursive: true });
27642
27734
  writeFileSync11(configPath, `${import_comment_json4.stringify(config2, null, 2)}
27643
27735
  `);
27644
27736
  log2(`[aft-plugin] added TUI plugin entry to ${configPath}`);
@@ -30662,9 +30754,9 @@ function splitIncludeArg(raw) {
30662
30754
  }
30663
30755
  buf += ch;
30664
30756
  }
30665
- const tail = buf.trim();
30666
- if (tail.length > 0)
30667
- out.push(tail);
30757
+ const tail2 = buf.trim();
30758
+ if (tail2.length > 0)
30759
+ out.push(tail2);
30668
30760
  return out;
30669
30761
  }
30670
30762
  function searchTools(ctx) {
@@ -31024,6 +31116,7 @@ async function handleConfigureWarningsForSession(context) {
31024
31116
  await deliverConfigureWarnings({
31025
31117
  client: context.client ?? context.fallbackClient,
31026
31118
  sessionId: context.sessionId,
31119
+ bridge: context.bridge,
31027
31120
  storageDir: context.storageDir,
31028
31121
  pluginVersion: context.pluginVersion,
31029
31122
  projectRoot: context.projectRoot
@@ -31078,6 +31171,7 @@ var ANNOUNCEMENT_FEATURES = [
31078
31171
  var plugin = async (input) => initializePluginForDirectory(input);
31079
31172
  async function initializePluginForDirectory(input) {
31080
31173
  const binaryPath = await findBinary(PLUGIN_VERSION);
31174
+ await ensureStorageMigrated({ harness: "opencode", binaryPath, logger: bridgeLogger });
31081
31175
  const aftConfig = loadAftConfig(input.directory);
31082
31176
  const autoUpdateAbort = new AbortController;
31083
31177
  const configOverrides = {};
@@ -31104,8 +31198,7 @@ async function initializePluginForDirectory(input) {
31104
31198
  if (aftConfig.max_callgraph_files !== undefined)
31105
31199
  configOverrides.max_callgraph_files = aftConfig.max_callgraph_files;
31106
31200
  const isFastembedSemanticBackend = (aftConfig.semantic?.backend ?? "fastembed") === "fastembed";
31107
- const dataHome = process.env.XDG_DATA_HOME || join21(homedir10(), ".local", "share");
31108
- configOverrides.storage_dir = join21(dataHome, "opencode", "storage", "plugin", "aft");
31201
+ configOverrides.storage_dir = resolveCortexKitStorageRoot();
31109
31202
  let onnxRuntimePromise = null;
31110
31203
  if (aftConfig.semantic_search && isFastembedSemanticBackend) {
31111
31204
  const storageDir2 = configOverrides.storage_dir;
@@ -31212,17 +31305,23 @@ ${lines}
31212
31305
  versionUpgradePromises.set(minVersion, upgradePromise);
31213
31306
  return upgradePromise;
31214
31307
  },
31215
- onConfigureWarnings: async ({ projectRoot, sessionId, client, warnings }) => {
31308
+ onConfigureWarnings: ({ projectRoot, sessionId, client, warnings }) => {
31309
+ const bridge = pool.getActiveBridgeForRoot(projectRoot);
31310
+ if (!bridge)
31311
+ return;
31216
31312
  const pendingWarnings = sessionId ? drainPendingEagerWarnings(projectRoot) : [];
31217
- await handleConfigureWarningsForSession({
31218
- projectRoot,
31219
- sessionId,
31220
- client,
31221
- warnings: [...pendingWarnings, ...warnings],
31222
- fallbackClient: input.client,
31223
- storageDir: configOverrides.storage_dir,
31224
- pluginVersion: PLUGIN_VERSION
31225
- });
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);
31226
31325
  },
31227
31326
  onBashCompletion: (completion) => {
31228
31327
  const sessionDir = getSessionDirectoryCached(completion.session_id) ?? input.directory;
@@ -31244,6 +31343,7 @@ ${lines}
31244
31343
  }
31245
31344
  };
31246
31345
  const pool = new BridgePool(binaryPath, poolOptions, configOverrides);
31346
+ pool.setConfigureOverride("harness", "opencode");
31247
31347
  const ctx = {
31248
31348
  pool,
31249
31349
  client: input.client,
@@ -31293,7 +31393,9 @@ ${lines}
31293
31393
  };
31294
31394
  }
31295
31395
  const cached2 = bridge.getCachedStatus();
31296
- if (cached2 !== null) {
31396
+ const cachedSessionId = cached2?.session;
31397
+ const cachedId = cachedSessionId?.id;
31398
+ if (cached2 !== null && cachedId === sessionID) {
31297
31399
  return { success: true, ...cached2 };
31298
31400
  }
31299
31401
  const response = await bridge.send("status", { session_id: sessionID });
@@ -31308,9 +31410,9 @@ ${lines}
31308
31410
  return { show: false };
31309
31411
  }
31310
31412
  if (storageDir) {
31311
- const versionFile = join21(storageDir, "last_announced_version");
31413
+ const versionFile = join22(storageDir, "last_announced_version");
31312
31414
  try {
31313
- if (existsSync14(versionFile)) {
31415
+ if (existsSync15(versionFile)) {
31314
31416
  const lastVersion = readFileSync12(versionFile, "utf-8").trim();
31315
31417
  if (lastVersion === ANNOUNCEMENT_VERSION)
31316
31418
  return { show: false };
@@ -31322,8 +31424,8 @@ ${lines}
31322
31424
  rpcServer.handle("mark-announced", async () => {
31323
31425
  if (storageDir && ANNOUNCEMENT_VERSION) {
31324
31426
  try {
31325
- mkdirSync12(storageDir, { recursive: true });
31326
- writeFileSync12(join21(storageDir, "last_announced_version"), ANNOUNCEMENT_VERSION);
31427
+ mkdirSync13(storageDir, { recursive: true });
31428
+ writeFileSync12(join22(storageDir, "last_announced_version"), ANNOUNCEMENT_VERSION);
31327
31429
  } catch {}
31328
31430
  }
31329
31431
  return { success: true };
@@ -31464,8 +31566,11 @@ Install: ${getManualInstallHint()}`).catch(() => {});
31464
31566
  const sessionDir = await getSessionDirectory(input.client, commandInput.sessionID, input.directory) ?? input.directory;
31465
31567
  const bridge = ctx.pool.getActiveBridgeForRoot(sessionDir) ?? ctx.pool.getBridge(sessionDir);
31466
31568
  const cached2 = bridge.getCachedStatus();
31467
- const response = cached2 ? { success: true, ...cached2 } : await bridge.send("status", { session_id: commandInput.sessionID });
31468
- if (!cached2 && response.success !== false) {
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) {
31469
31574
  bridge.cacheStatusSnapshot(response);
31470
31575
  }
31471
31576
  if (response.success === false) {