@cortexkit/aft-opencode 0.35.0 → 0.35.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -7637,9 +7637,9 @@ var require_stringify = __commonJS((exports, module) => {
7637
7637
  if (line_breaks_before === null) {
7638
7638
  line_breaks_before = inline ? 0 : 1;
7639
7639
  }
7640
- const delimiter = line_breaks_before > 0 ? repeat_line_breaks(line_breaks_before, deeper_gap) : inline ? SPACE : i === 0 ? EMPTY : LF + deeper_gap;
7640
+ const delimiter2 = line_breaks_before > 0 ? repeat_line_breaks(line_breaks_before, deeper_gap) : inline ? SPACE : i === 0 ? EMPTY : LF + deeper_gap;
7641
7641
  const is_line_comment = type === "LineComment";
7642
- str += delimiter + comment_stringify(value, is_line_comment);
7642
+ str += delimiter2 + comment_stringify(value, is_line_comment);
7643
7643
  last_comment = comment;
7644
7644
  });
7645
7645
  const default_line_breaks_after = display_block || last_comment.type === "LineComment" ? 1 : 0;
@@ -7652,10 +7652,10 @@ var require_stringify = __commonJS((exports, module) => {
7652
7652
  replacer = null;
7653
7653
  indent = EMPTY;
7654
7654
  };
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;
7655
+ var join9 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), 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 join8(comment, inside, gap);
7658
+ return join9(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 = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
7680
+ const before = join9(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 += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7686
+ inside += join9(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 = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
7707
+ const before = join9(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 += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
7713
+ inside += join9(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) {
@@ -12740,6 +12740,49 @@ async function fetchLatestTag() {
12740
12740
  clearTimeout(timeout);
12741
12741
  }
12742
12742
  }
12743
+ // ../aft-bridge/dist/edit-summary.js
12744
+ function formatEditSummary(data) {
12745
+ if (data.rolled_back === true) {
12746
+ return "Edit rolled back: the change produced invalid syntax, so the file was left unchanged.";
12747
+ }
12748
+ if (typeof data.files_modified === "number") {
12749
+ const n = data.files_modified;
12750
+ return `Applied edits to ${n} file${n === 1 ? "" : "s"}.`;
12751
+ }
12752
+ const additions = data.diff?.additions ?? 0;
12753
+ const deletions = data.diff?.deletions ?? 0;
12754
+ const counts = `+${additions}/-${deletions}`;
12755
+ if (data.created === true) {
12756
+ let s2 = `Created file (${counts}).`;
12757
+ if (data.formatted)
12758
+ s2 += " Auto-formatted.";
12759
+ return s2;
12760
+ }
12761
+ let detail = counts;
12762
+ if (typeof data.edits_applied === "number" && data.edits_applied > 1) {
12763
+ detail = `${counts}, ${data.edits_applied} edits`;
12764
+ } else if (typeof data.replacements === "number" && data.replacements > 1) {
12765
+ detail = `${counts}, ${data.replacements} replacements`;
12766
+ }
12767
+ let s = `Edited (${detail}).`;
12768
+ if (data.formatted)
12769
+ s += " Auto-formatted.";
12770
+ return s;
12771
+ }
12772
+ // ../aft-bridge/dist/jsonc.js
12773
+ function stripJsoncSymbols(value) {
12774
+ if (Array.isArray(value)) {
12775
+ return value.map((item) => stripJsoncSymbols(item));
12776
+ }
12777
+ if (value !== null && typeof value === "object") {
12778
+ const out = {};
12779
+ for (const [key, val] of Object.entries(value)) {
12780
+ out[key] = stripJsoncSymbols(val);
12781
+ }
12782
+ return out;
12783
+ }
12784
+ return value;
12785
+ }
12743
12786
  // ../aft-bridge/dist/migration.js
12744
12787
  import { spawnSync as spawnSync2 } from "node:child_process";
12745
12788
  import { existsSync as existsSync4, mkdirSync as mkdirSync4 } from "node:fs";
@@ -12798,7 +12841,7 @@ function markAnnouncementSeen(storageRoot, harness, currentVersion) {
12798
12841
 
12799
12842
  // ../aft-bridge/dist/resolver.js
12800
12843
  import { execSync } from "node:child_process";
12801
- import { chmodSync as chmodSync2, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync3, unlinkSync as unlinkSync2 } from "node:fs";
12844
+ import { chmodSync as chmodSync2, closeSync as closeSync2, copyFileSync as copyFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, openSync as openSync2, readSync, renameSync as renameSync3, unlinkSync as unlinkSync2 } from "node:fs";
12802
12845
  import { createRequire as createRequire2 } from "node:module";
12803
12846
  import { homedir as homedir3 } from "node:os";
12804
12847
  import { join as join4 } from "node:path";
@@ -12879,6 +12922,37 @@ function probeBinaryCandidate(binaryPath, source, expectedVersion) {
12879
12922
  function parsePathLookupOutput(output) {
12880
12923
  return output.split(/\r?\n/).map((candidate) => candidate.trim()).filter(Boolean);
12881
12924
  }
12925
+ function isNativeExecutable(binaryPath) {
12926
+ let fd = null;
12927
+ try {
12928
+ fd = openSync2(binaryPath, "r");
12929
+ const buf = Buffer.alloc(4);
12930
+ const read = readSync(fd, buf, 0, 4, 0);
12931
+ if (read < 2)
12932
+ return false;
12933
+ const b0 = buf[0];
12934
+ const b1 = buf[1];
12935
+ if (b0 === 35 && b1 === 33)
12936
+ return false;
12937
+ const m32 = buf.readUInt32BE(0);
12938
+ const machO = new Set([4277009102, 4277009103, 3472551422, 3489328638, 3405691582]);
12939
+ if (read >= 4 && machO.has(m32))
12940
+ return true;
12941
+ if (read >= 4 && m32 === 2135247942)
12942
+ return true;
12943
+ if (b0 === 77 && b1 === 90)
12944
+ return true;
12945
+ return false;
12946
+ } catch {
12947
+ return false;
12948
+ } finally {
12949
+ if (fd !== null) {
12950
+ try {
12951
+ closeSync2(fd);
12952
+ } catch {}
12953
+ }
12954
+ }
12955
+ }
12882
12956
  function platformKey(platform = process.platform, arch = process.arch) {
12883
12957
  const archMap = PLATFORM_ARCH_MAP[platform];
12884
12958
  if (!archMap) {
@@ -12932,6 +13006,10 @@ function findBinarySync(expectedVersion) {
12932
13006
  stdio: ["pipe", "pipe", "pipe"]
12933
13007
  }).trim();
12934
13008
  for (const candidate of parsePathLookupOutput(result)) {
13009
+ if (!isNativeExecutable(candidate)) {
13010
+ warn(`PATH binary at ${candidate} is not a native executable (script shim?); skipping`);
13011
+ continue;
13012
+ }
12935
13013
  const usable = probeBinaryCandidate(candidate, "PATH", expectedVersion);
12936
13014
  if (usable)
12937
13015
  return usable;
@@ -13078,11 +13156,128 @@ async function ensureStorageMigrated(opts) {
13078
13156
  const stdoutTail = tail(result.stdout);
13079
13157
  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}` : ""));
13080
13158
  }
13159
+ // ../aft-bridge/dist/npm-resolver.js
13160
+ import { readdirSync, statSync as statSync2 } from "node:fs";
13161
+ import { homedir as homedir5 } from "node:os";
13162
+ import { delimiter, dirname as dirname3, isAbsolute, join as join6 } from "node:path";
13163
+ function defaultDeps() {
13164
+ return {
13165
+ platform: process.platform,
13166
+ env: process.env,
13167
+ home: homedir5(),
13168
+ execPath: process.execPath
13169
+ };
13170
+ }
13171
+ function npmBinaryName(platform) {
13172
+ return platform === "win32" ? "npm.cmd" : "npm";
13173
+ }
13174
+ function isFile(p) {
13175
+ try {
13176
+ return statSync2(p).isFile();
13177
+ } catch {
13178
+ return false;
13179
+ }
13180
+ }
13181
+ function npmFromPath(deps) {
13182
+ const name = npmBinaryName(deps.platform);
13183
+ const raw = deps.env.PATH ?? deps.env.Path ?? "";
13184
+ for (const entry of raw.split(delimiter)) {
13185
+ const dir = entry.trim().replace(/^"|"$/g, "");
13186
+ if (!dir || !isAbsolute(dir))
13187
+ continue;
13188
+ if (isFile(join6(dir, name)))
13189
+ return dir;
13190
+ }
13191
+ return null;
13192
+ }
13193
+ function npmAdjacentToNode(deps) {
13194
+ const dir = dirname3(deps.execPath);
13195
+ return isFile(join6(dir, npmBinaryName(deps.platform))) ? dir : null;
13196
+ }
13197
+ function highestVersionedNodeBin(installsDir, name) {
13198
+ let entries;
13199
+ try {
13200
+ entries = readdirSync(installsDir);
13201
+ } catch {
13202
+ return null;
13203
+ }
13204
+ const candidates = entries.filter((v) => isFile(join6(installsDir, v, "bin", name))).sort((a, b) => compareVersionsDesc(a, b));
13205
+ return candidates.length > 0 ? join6(installsDir, candidates[0], "bin") : null;
13206
+ }
13207
+ function compareVersionsDesc(a, b) {
13208
+ const pa = a.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
13209
+ const pb = b.replace(/^v/, "").split(".").map((n) => Number.parseInt(n, 10));
13210
+ for (let i = 0;i < Math.max(pa.length, pb.length); i++) {
13211
+ const na = Number.isFinite(pa[i]) ? pa[i] : -1;
13212
+ const nb = Number.isFinite(pb[i]) ? pb[i] : -1;
13213
+ if (na !== nb)
13214
+ return nb - na;
13215
+ }
13216
+ return b.localeCompare(a);
13217
+ }
13218
+ function wellKnownNpmDirs(deps) {
13219
+ const { platform, env, home } = deps;
13220
+ const name = npmBinaryName(platform);
13221
+ const dirs = [];
13222
+ const push = (dir) => {
13223
+ if (dir && !dirs.includes(dir))
13224
+ dirs.push(dir);
13225
+ };
13226
+ if (platform === "win32") {
13227
+ const programFiles = env.ProgramFiles || "C:\\Program Files";
13228
+ const appData = env.APPDATA;
13229
+ const localAppData = env.LOCALAPPDATA;
13230
+ push(join6(programFiles, "nodejs"));
13231
+ if (appData)
13232
+ push(join6(appData, "npm"));
13233
+ if (localAppData)
13234
+ push(join6(localAppData, "Volta", "bin"));
13235
+ if (env.NVM_SYMLINK)
13236
+ push(env.NVM_SYMLINK);
13237
+ } else {
13238
+ if (env.NVM_BIN)
13239
+ push(env.NVM_BIN);
13240
+ push(highestVersionedNodeBin(join6(home, ".nvm", "versions", "node"), name));
13241
+ push(highestVersionedNodeBin(join6(home, ".local", "share", "mise", "installs", "node"), name));
13242
+ push(highestVersionedNodeBin(join6(home, ".asdf", "installs", "nodejs"), name));
13243
+ push(join6(home, ".volta", "bin"));
13244
+ push(join6(home, ".asdf", "shims"));
13245
+ const systemDirs = deps.systemNpmDirs ?? (platform === "darwin" ? ["/opt/homebrew/bin", "/usr/local/bin"] : ["/usr/local/bin", "/usr/bin", join6(home, ".local", "bin")]);
13246
+ for (const dir of systemDirs)
13247
+ push(dir);
13248
+ }
13249
+ return dirs;
13250
+ }
13251
+ function resolveNpm(deps = defaultDeps()) {
13252
+ const name = npmBinaryName(deps.platform);
13253
+ const onPath = npmFromPath(deps);
13254
+ if (onPath)
13255
+ return { command: join6(onPath, name), binDir: onPath };
13256
+ const adjacent = npmAdjacentToNode(deps);
13257
+ if (adjacent)
13258
+ return { command: join6(adjacent, name), binDir: adjacent };
13259
+ for (const dir of wellKnownNpmDirs(deps)) {
13260
+ const candidate = join6(dir, name);
13261
+ if (isFile(candidate))
13262
+ return { command: candidate, binDir: dir };
13263
+ }
13264
+ return null;
13265
+ }
13266
+ function npmSpawnEnv(resolved, baseEnv = process.env) {
13267
+ if (!resolved.binDir)
13268
+ return { ...baseEnv };
13269
+ const existing = baseEnv.PATH ?? baseEnv.Path ?? "";
13270
+ const next = existing ? `${resolved.binDir}${delimiter}${existing}` : resolved.binDir;
13271
+ return { ...baseEnv, PATH: next };
13272
+ }
13273
+ function isNpmAvailable(deps = defaultDeps()) {
13274
+ return resolveNpm(deps) !== null;
13275
+ }
13081
13276
  // ../aft-bridge/dist/onnx-runtime.js
13082
13277
  import { execFileSync } from "node:child_process";
13083
13278
  import { createHash as createHash2 } from "node:crypto";
13084
- import { chmodSync as chmodSync3, closeSync as closeSync2, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, openSync as openSync2, readdirSync, readFileSync as readFileSync3, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
13085
- import { basename, dirname as dirname3, isAbsolute, join as join6, relative, resolve, win32 } from "node:path";
13279
+ import { chmodSync as chmodSync3, closeSync as closeSync3, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, openSync as openSync3, readdirSync as readdirSync2, readFileSync as readFileSync3, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync3, symlinkSync, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
13280
+ import { basename, dirname as dirname4, isAbsolute as isAbsolute2, join as join7, relative, resolve, win32 } from "node:path";
13086
13281
  import { Readable as Readable2 } from "node:stream";
13087
13282
  import { pipeline as pipeline2 } from "node:stream/promises";
13088
13283
  var ORT_VERSION = "1.24.4";
@@ -13148,10 +13343,10 @@ function getManualInstallHint() {
13148
13343
  }
13149
13344
  async function ensureOnnxRuntime(storageDir) {
13150
13345
  const info = getPlatformInfo();
13151
- const ortVersionDir = join6(storageDir, "onnxruntime", ORT_VERSION);
13346
+ const ortVersionDir = join7(storageDir, "onnxruntime", ORT_VERSION);
13152
13347
  const libName = info?.libName ?? "libonnxruntime.dylib";
13153
13348
  const resolvedOrtDir = resolveCachedOnnxRuntimeDir(ortVersionDir, libName);
13154
- const libPath = join6(resolvedOrtDir, libName);
13349
+ const libPath = join7(resolvedOrtDir, libName);
13155
13350
  if (existsSync5(libPath)) {
13156
13351
  const meta = readOnnxInstalledMeta(ortVersionDir);
13157
13352
  if (meta?.sha256) {
@@ -13181,9 +13376,9 @@ async function ensureOnnxRuntime(storageDir) {
13181
13376
  warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
13182
13377
  return null;
13183
13378
  }
13184
- const onnxBaseDir = join6(storageDir, "onnxruntime");
13379
+ const onnxBaseDir = join7(storageDir, "onnxruntime");
13185
13380
  mkdirSync5(onnxBaseDir, { recursive: true });
13186
- const lockPath = join6(onnxBaseDir, ONNX_LOCK_FILE);
13381
+ const lockPath = join7(onnxBaseDir, ONNX_LOCK_FILE);
13187
13382
  cleanupAbandonedStagingDirs(onnxBaseDir);
13188
13383
  if (!acquireLock(lockPath)) {
13189
13384
  warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
@@ -13198,11 +13393,11 @@ async function ensureOnnxRuntime(storageDir) {
13198
13393
  }
13199
13394
  function cleanupAbandonedStagingDirs(onnxBaseDir) {
13200
13395
  try {
13201
- const entries = readdirSync(onnxBaseDir);
13396
+ const entries = readdirSync2(onnxBaseDir);
13202
13397
  for (const entry of entries) {
13203
13398
  if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
13204
13399
  continue;
13205
- const stagingDir = join6(onnxBaseDir, entry);
13400
+ const stagingDir = join7(onnxBaseDir, entry);
13206
13401
  const parts = entry.split(".");
13207
13402
  const pidStr = parts[parts.length - 2];
13208
13403
  const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
@@ -13214,7 +13409,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
13214
13409
  abandoned = true;
13215
13410
  } else {
13216
13411
  try {
13217
- const ageMs = Date.now() - statSync2(stagingDir).mtimeMs;
13412
+ const ageMs = Date.now() - statSync3(stagingDir).mtimeMs;
13218
13413
  abandoned = ageMs > STALE_LOCK_MS;
13219
13414
  } catch {
13220
13415
  abandoned = true;
@@ -13239,7 +13434,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
13239
13434
  }
13240
13435
  function cleanupIncompleteTargetIfUnowned(ortDir) {
13241
13436
  try {
13242
- if (existsSync5(ortDir) && !existsSync5(join6(ortDir, ONNX_INSTALLED_META_FILE))) {
13437
+ if (existsSync5(ortDir) && !existsSync5(join7(ortDir, ONNX_INSTALLED_META_FILE))) {
13243
13438
  log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
13244
13439
  rmSync2(ortDir, { recursive: true, force: true });
13245
13440
  }
@@ -13268,11 +13463,11 @@ function parseOnnxVersionFromDirectoryPath(value) {
13268
13463
  }
13269
13464
  function isPathInsideRoot(root, candidate) {
13270
13465
  const rel = relative(root, candidate);
13271
- return rel === "" || !rel.startsWith("../") && !rel.startsWith("..\\") && rel !== ".." && !isAbsolute(rel) && !win32.isAbsolute(rel);
13466
+ return rel === "" || !rel.startsWith("../") && !rel.startsWith("..\\") && rel !== ".." && !isAbsolute2(rel) && !win32.isAbsolute(rel);
13272
13467
  }
13273
13468
  function detectOnnxVersion(libDir, libName) {
13274
13469
  try {
13275
- const entries = readdirSync(libDir);
13470
+ const entries = readdirSync2(libDir);
13276
13471
  const barePrefix = libName.replace(/\.(so|dylib|dll)$/, "");
13277
13472
  const expectedPrefix = process.platform === "win32" ? barePrefix.toLowerCase() : barePrefix;
13278
13473
  for (const entry of entries) {
@@ -13283,7 +13478,7 @@ function detectOnnxVersion(libDir, libName) {
13283
13478
  if (version)
13284
13479
  return version;
13285
13480
  }
13286
- const base = join6(libDir, libName);
13481
+ const base = join7(libDir, libName);
13287
13482
  if (existsSync5(base)) {
13288
13483
  try {
13289
13484
  const real = realpathSync(base);
@@ -13315,16 +13510,16 @@ function pathEnvValue() {
13315
13510
  return process.env.PATH ?? process.env.Path ?? process.env.path ?? "";
13316
13511
  }
13317
13512
  function pathEntriesForPlatform() {
13318
- const delimiter = process.platform === "win32" ? ";" : ":";
13319
- return pathEnvValue().split(delimiter).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter((entry) => {
13513
+ const delimiter2 = process.platform === "win32" ? ";" : ":";
13514
+ return pathEnvValue().split(delimiter2).map((entry) => entry.trim().replace(/^"|"$/g, "")).filter((entry) => {
13320
13515
  if (!entry || entry === "." || entry.includes("\x00"))
13321
13516
  return false;
13322
- return isAbsolute(entry) || win32.isAbsolute(entry);
13517
+ return isAbsolute2(entry) || win32.isAbsolute(entry);
13323
13518
  });
13324
13519
  }
13325
13520
  function directoryContainsLibrary(dir, libName) {
13326
13521
  try {
13327
- const entries = readdirSync(dir);
13522
+ const entries = readdirSync2(dir);
13328
13523
  if (process.platform === "win32") {
13329
13524
  const expected = libName.toLowerCase();
13330
13525
  return entries.some((entry) => entry.toLowerCase() === expected);
@@ -13335,10 +13530,10 @@ function directoryContainsLibrary(dir, libName) {
13335
13530
  }
13336
13531
  }
13337
13532
  function resolveCachedOnnxRuntimeDir(ortVersionDir, libName) {
13338
- if (existsSync5(join6(ortVersionDir, libName)))
13533
+ if (existsSync5(join7(ortVersionDir, libName)))
13339
13534
  return ortVersionDir;
13340
- const libSubdir = join6(ortVersionDir, "lib");
13341
- if (existsSync5(join6(libSubdir, libName)))
13535
+ const libSubdir = join7(ortVersionDir, "lib");
13536
+ if (existsSync5(join7(libSubdir, libName)))
13342
13537
  return libSubdir;
13343
13538
  return ortVersionDir;
13344
13539
  }
@@ -13353,21 +13548,21 @@ function findSystemOnnxRuntime(libName) {
13353
13548
  } else if (process.platform === "win32") {
13354
13549
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
13355
13550
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
13356
- searchPaths.push(join6(programFiles, "onnxruntime", "lib"), join6(programFiles, "Microsoft ONNX Runtime", "lib"), join6(programFiles, "Microsoft Machine Learning", "lib"), join6(programFilesX86, "onnxruntime", "lib"), ...(() => {
13551
+ searchPaths.push(join7(programFiles, "onnxruntime", "lib"), join7(programFiles, "Microsoft ONNX Runtime", "lib"), join7(programFiles, "Microsoft Machine Learning", "lib"), join7(programFilesX86, "onnxruntime", "lib"), ...(() => {
13357
13552
  const nugetPaths = [];
13358
13553
  const userProfile = process.env.USERPROFILE ?? "";
13359
13554
  if (!userProfile)
13360
13555
  return nugetPaths;
13361
- const nugetPackageDir = join6(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
13556
+ const nugetPackageDir = join7(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
13362
13557
  if (!existsSync5(nugetPackageDir))
13363
13558
  return nugetPaths;
13364
13559
  try {
13365
- for (const entry of readdirSync(nugetPackageDir, { withFileTypes: true })) {
13560
+ for (const entry of readdirSync2(nugetPackageDir, { withFileTypes: true })) {
13366
13561
  if (!entry.isDirectory())
13367
13562
  continue;
13368
13563
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
13369
13564
  continue;
13370
- nugetPaths.push(join6(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join6(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
13565
+ nugetPaths.push(join7(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join7(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
13371
13566
  }
13372
13567
  } catch (err) {
13373
13568
  warn(`Failed to scan NuGet ONNX Runtime cache ${nugetPackageDir}: ${err instanceof Error ? err.message : String(err)}`);
@@ -13389,7 +13584,7 @@ function findSystemOnnxRuntime(libName) {
13389
13584
  });
13390
13585
  const unknownVersionPaths = [];
13391
13586
  for (const dir of uniquePaths) {
13392
- const libPath = join6(dir, libName);
13587
+ const libPath = join7(dir, libName);
13393
13588
  if (process.platform === "win32") {
13394
13589
  if (!directoryContainsLibrary(dir, libName))
13395
13590
  continue;
@@ -13425,7 +13620,7 @@ async function downloadFileWithCap(url, destPath) {
13425
13620
  if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
13426
13621
  throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
13427
13622
  }
13428
- mkdirSync5(dirname3(destPath), { recursive: true });
13623
+ mkdirSync5(dirname4(destPath), { recursive: true });
13429
13624
  let bytesWritten = 0;
13430
13625
  const guard = new TransformStream({
13431
13626
  transform(chunk, transformController) {
@@ -13453,21 +13648,21 @@ function validateExtractedTree(stagingRoot) {
13453
13648
  const realRoot = realpathSync(stagingRoot);
13454
13649
  let totalBytes = 0;
13455
13650
  const walk = (dir) => {
13456
- const entries = readdirSync(dir);
13651
+ const entries = readdirSync2(dir);
13457
13652
  for (const entry of entries) {
13458
- const fullPath = join6(dir, entry);
13653
+ const fullPath = join7(dir, entry);
13459
13654
  const lst = lstatSync(fullPath);
13460
13655
  if (lst.isSymbolicLink()) {
13461
13656
  const linkTarget = readlinkSync(fullPath);
13462
- const resolvedTarget = resolve(dirname3(fullPath), linkTarget);
13657
+ const resolvedTarget = resolve(dirname4(fullPath), linkTarget);
13463
13658
  const rel2 = relative(realRoot, resolvedTarget);
13464
- if (rel2.startsWith("..") || isAbsolute(rel2) || win32.isAbsolute(rel2)) {
13659
+ if (rel2.startsWith("..") || isAbsolute2(rel2) || win32.isAbsolute(rel2)) {
13465
13660
  throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
13466
13661
  }
13467
13662
  continue;
13468
13663
  }
13469
13664
  const rel = relative(realRoot, fullPath);
13470
- if (rel.startsWith("..") || isAbsolute(rel) || win32.isAbsolute(rel)) {
13665
+ if (rel.startsWith("..") || isAbsolute2(rel) || win32.isAbsolute(rel)) {
13471
13666
  throw new Error(`extracted entry ${fullPath} escapes staging root`);
13472
13667
  }
13473
13668
  if (lst.isDirectory()) {
@@ -13490,7 +13685,7 @@ async function downloadOnnxRuntime(info, targetDir) {
13490
13685
  const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
13491
13686
  try {
13492
13687
  mkdirSync5(tmpDir, { recursive: true });
13493
- const archivePath = join6(tmpDir, `onnxruntime.${info.archiveType}`);
13688
+ const archivePath = join7(tmpDir, `onnxruntime.${info.archiveType}`);
13494
13689
  await downloadFileWithCap(url, archivePath);
13495
13690
  const archiveSha256 = sha256File(archivePath);
13496
13691
  log(`ONNX Runtime archive sha256=${archiveSha256}`);
@@ -13506,16 +13701,16 @@ async function downloadOnnxRuntime(info, targetDir) {
13506
13701
  unlinkSync3(archivePath);
13507
13702
  } catch {}
13508
13703
  validateExtractedTree(tmpDir);
13509
- const extractedDir = join6(tmpDir, info.assetName, "lib");
13704
+ const extractedDir = join7(tmpDir, info.assetName, "lib");
13510
13705
  if (!existsSync5(extractedDir)) {
13511
13706
  throw new Error(`Expected directory not found: ${extractedDir}`);
13512
13707
  }
13513
13708
  mkdirSync5(targetDir, { recursive: true });
13514
- const libFiles = readdirSync(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
13709
+ const libFiles = readdirSync2(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
13515
13710
  const realFiles = [];
13516
13711
  const symlinks = [];
13517
13712
  for (const libFile of libFiles) {
13518
- const src = join6(extractedDir, libFile);
13713
+ const src = join7(extractedDir, libFile);
13519
13714
  try {
13520
13715
  const stat = lstatSync(src);
13521
13716
  log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
@@ -13530,7 +13725,7 @@ async function downloadOnnxRuntime(info, targetDir) {
13530
13725
  }
13531
13726
  }
13532
13727
  copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
13533
- const libPath = join6(targetDir, info.libName);
13728
+ const libPath = join7(targetDir, info.libName);
13534
13729
  let libHash = null;
13535
13730
  try {
13536
13731
  libHash = sha256File(libPath);
@@ -13555,8 +13750,8 @@ async function downloadOnnxRuntime(info, targetDir) {
13555
13750
  function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync3) {
13556
13751
  const requiredLibs = new Set([info.libName]);
13557
13752
  for (const libFile of realFiles) {
13558
- const src = join6(extractedDir, libFile);
13559
- const dst = join6(targetDir, libFile);
13753
+ const src = join7(extractedDir, libFile);
13754
+ const dst = join7(targetDir, libFile);
13560
13755
  try {
13561
13756
  copyFile(src, dst);
13562
13757
  if (process.platform !== "win32") {
@@ -13572,12 +13767,12 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
13572
13767
  }
13573
13768
  const targetRoot = realpathSync(targetDir);
13574
13769
  for (const link of symlinks) {
13575
- const dst = join6(targetDir, link.name);
13770
+ const dst = join7(targetDir, link.name);
13576
13771
  try {
13577
13772
  unlinkSync3(dst);
13578
13773
  } catch {}
13579
- const dstForContainment = join6(targetRoot, link.name);
13580
- const resolvedTarget = resolve(dirname3(dstForContainment), link.target);
13774
+ const dstForContainment = join7(targetRoot, link.name);
13775
+ const resolvedTarget = resolve(dirname4(dstForContainment), link.target);
13581
13776
  if (!isPathInsideRoot(targetRoot, resolvedTarget)) {
13582
13777
  const message = `ONNX Runtime symlink ${link.name} points outside install dir: ${link.target}`;
13583
13778
  if (requiredLibs.has(link.name)) {
@@ -13597,7 +13792,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
13597
13792
  log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
13598
13793
  }
13599
13794
  }
13600
- const requiredPath = join6(targetDir, info.libName);
13795
+ const requiredPath = join7(targetDir, info.libName);
13601
13796
  if (!existsSync5(requiredPath)) {
13602
13797
  rmSync2(targetDir, { recursive: true, force: true });
13603
13798
  throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
@@ -13624,15 +13819,15 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
13624
13819
  ...sha256 ? { sha256 } : {},
13625
13820
  archiveSha256
13626
13821
  };
13627
- writeFileSync2(join6(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
13822
+ writeFileSync2(join7(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
13628
13823
  } catch (err) {
13629
13824
  log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
13630
13825
  }
13631
13826
  }
13632
13827
  function readOnnxInstalledMeta(installDir) {
13633
- const path = join6(installDir, ONNX_INSTALLED_META_FILE);
13828
+ const path = join7(installDir, ONNX_INSTALLED_META_FILE);
13634
13829
  try {
13635
- if (!statSync2(path).isFile())
13830
+ if (!statSync3(path).isFile())
13636
13831
  return null;
13637
13832
  const raw = readFileSync3(path, "utf8");
13638
13833
  const parsed = JSON.parse(raw);
@@ -13656,13 +13851,13 @@ function sha256File(path) {
13656
13851
  function acquireLock(lockPath) {
13657
13852
  const tryClaim = () => {
13658
13853
  try {
13659
- const fd = openSync2(lockPath, "wx");
13854
+ const fd = openSync3(lockPath, "wx");
13660
13855
  try {
13661
13856
  writeFileSync2(fd, `${process.pid}
13662
13857
  ${new Date().toISOString()}
13663
13858
  `);
13664
13859
  } finally {
13665
- closeSync2(fd);
13860
+ closeSync3(fd);
13666
13861
  }
13667
13862
  return true;
13668
13863
  } catch (err) {
@@ -13683,7 +13878,7 @@ ${new Date().toISOString()}
13683
13878
  const parsed = Number.parseInt(firstLine, 10);
13684
13879
  if (Number.isFinite(parsed) && parsed > 0)
13685
13880
  owningPid = parsed;
13686
- lockMtimeMs = statSync2(lockPath).mtimeMs;
13881
+ lockMtimeMs = statSync3(lockPath).mtimeMs;
13687
13882
  } catch {
13688
13883
  return tryClaim();
13689
13884
  }
@@ -14982,10 +15177,10 @@ function formatDuration(completion) {
14982
15177
  }
14983
15178
 
14984
15179
  // src/config.ts
14985
- var import_comment_json = __toESM(require_src2(), 1);
14986
15180
  import { existsSync as existsSync6, readFileSync as readFileSync4, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
14987
- import { homedir as homedir5 } from "node:os";
14988
- import { join as join8 } from "node:path";
15181
+ import { homedir as homedir6 } from "node:os";
15182
+ import { join as join9 } from "node:path";
15183
+ var import_comment_json = __toESM(require_src2(), 1);
14989
15184
 
14990
15185
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
14991
15186
  var exports_external = {};
@@ -16571,8 +16766,8 @@ function emoji() {
16571
16766
  }
16572
16767
  var ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
16573
16768
  var ipv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/;
16574
- var mac = (delimiter) => {
16575
- const escapedDelim = escapeRegex(delimiter ?? ":");
16769
+ var mac = (delimiter2) => {
16770
+ const escapedDelim = escapeRegex(delimiter2 ?? ":");
16576
16771
  return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
16577
16772
  };
16578
16773
  var cidrv4 = /^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/;
@@ -28989,14 +29184,15 @@ function loadConfigFromPath(configPath) {
28989
29184
  const content = readFileSync4(configPath, "utf-8");
28990
29185
  const rawConfig = import_comment_json.parse(content);
28991
29186
  migrateRawConfig(rawConfig, configPath, { log: log2, warn: warn2 });
28992
- const result = AftConfigSchema.safeParse(rawConfig);
29187
+ const cleanConfig = stripJsoncSymbols(rawConfig);
29188
+ const result = AftConfigSchema.safeParse(cleanConfig);
28993
29189
  if (result.success) {
28994
29190
  log2(`Config loaded from ${configPath}`);
28995
29191
  return result.data;
28996
29192
  }
28997
29193
  const errorMsg = result.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ");
28998
29194
  warn2(`Config validation error in ${configPath}: ${errorMsg}`);
28999
- return parseConfigPartially(rawConfig);
29195
+ return parseConfigPartially(cleanConfig);
29000
29196
  } catch (err) {
29001
29197
  const errorMsg = err instanceof Error ? err.message : String(err);
29002
29198
  error2(`Error loading config from ${configPath}: ${errorMsg}`);
@@ -29178,17 +29374,17 @@ function getOpenCodeConfigDir() {
29178
29374
  if (envDir) {
29179
29375
  return envDir;
29180
29376
  }
29181
- const xdgConfig = process.env.XDG_CONFIG_HOME || join8(homedir5(), ".config");
29182
- return join8(xdgConfig, "opencode");
29377
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join9(homedir6(), ".config");
29378
+ return join9(xdgConfig, "opencode");
29183
29379
  }
29184
29380
  function loadAftConfig(projectDirectory) {
29185
29381
  const configDir = getOpenCodeConfigDir();
29186
- const userBasePath = join8(configDir, "aft");
29382
+ const userBasePath = join9(configDir, "aft");
29187
29383
  migrateAftConfigFile(`${userBasePath}.jsonc`);
29188
29384
  migrateAftConfigFile(`${userBasePath}.json`);
29189
29385
  const userDetected = detectConfigFile(userBasePath);
29190
29386
  const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
29191
- const projectBasePath = join8(projectDirectory, ".opencode", "aft");
29387
+ const projectBasePath = join9(projectDirectory, ".opencode", "aft");
29192
29388
  migrateAftConfigFile(`${projectBasePath}.jsonc`);
29193
29389
  migrateAftConfigFile(`${projectBasePath}.json`);
29194
29390
  const projectDetected = detectConfigFile(projectBasePath);
@@ -29214,8 +29410,8 @@ function loadAftConfig(projectDirectory) {
29214
29410
 
29215
29411
  // src/notifications.ts
29216
29412
  import { existsSync as existsSync7, readFileSync as readFileSync5 } from "node:fs";
29217
- import { homedir as homedir6, platform } from "node:os";
29218
- import { join as join9 } from "node:path";
29413
+ import { homedir as homedir7, platform } from "node:os";
29414
+ import { join as join10 } from "node:path";
29219
29415
  function isTuiMode() {
29220
29416
  return process.env.OPENCODE_CLIENT === "cli";
29221
29417
  }
@@ -29236,17 +29432,17 @@ var WARNING_MARKER = `${AFT_MARKER} ⚠️`;
29236
29432
  var STATUS_MARKER = `${AFT_MARKER} ✅`;
29237
29433
  function getDesktopStatePath() {
29238
29434
  const os2 = platform();
29239
- const home = homedir6();
29435
+ const home = homedir7();
29240
29436
  if (os2 === "darwin") {
29241
- return join9(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
29437
+ return join10(home, "Library", "Application Support", "ai.opencode.desktop", "opencode.global.dat");
29242
29438
  }
29243
29439
  if (os2 === "linux") {
29244
- const xdgConfig = process.env.XDG_CONFIG_HOME || join9(home, ".config");
29245
- return join9(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
29440
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join10(home, ".config");
29441
+ return join10(xdgConfig, "ai.opencode.desktop", "opencode.global.dat");
29246
29442
  }
29247
29443
  if (os2 === "win32") {
29248
- const appData = process.env.APPDATA || join9(home, "AppData", "Roaming");
29249
- return join9(appData, "ai.opencode.desktop", "opencode.global.dat");
29444
+ const appData = process.env.APPDATA || join10(home, "AppData", "Roaming");
29445
+ return join10(appData, "ai.opencode.desktop", "opencode.global.dat");
29250
29446
  }
29251
29447
  return null;
29252
29448
  }
@@ -29701,52 +29897,52 @@ async function flushConfigureWarningsOnIdle(sessionId) {
29701
29897
 
29702
29898
  // src/hooks/auto-update-checker/index.ts
29703
29899
  import {
29704
- closeSync as closeSync3,
29900
+ closeSync as closeSync4,
29705
29901
  existsSync as existsSync10,
29706
29902
  mkdirSync as mkdirSync6,
29707
- openSync as openSync3,
29903
+ openSync as openSync4,
29708
29904
  readFileSync as readFileSync8,
29709
29905
  renameSync as renameSync5,
29710
29906
  rmSync as rmSync4,
29711
29907
  writeFileSync as writeFileSync6
29712
29908
  } from "node:fs";
29713
- import { dirname as dirname6 } from "node:path";
29909
+ import { dirname as dirname7 } from "node:path";
29714
29910
 
29715
29911
  // src/hooks/auto-update-checker/cache.ts
29716
- var import_comment_json3 = __toESM(require_src2(), 1);
29717
29912
  import { spawn as spawn2 } from "node:child_process";
29718
29913
  import { cpSync, existsSync as existsSync9, mkdtempSync, readFileSync as readFileSync7, rmSync as rmSync3, writeFileSync as writeFileSync5 } from "node:fs";
29719
29914
  import { tmpdir as tmpdir3 } from "node:os";
29720
- import { basename as basename2, dirname as dirname5, join as join12 } from "node:path";
29915
+ import { basename as basename2, dirname as dirname6, join as join13 } from "node:path";
29916
+ var import_comment_json3 = __toESM(require_src2(), 1);
29721
29917
 
29722
29918
  // src/hooks/auto-update-checker/checker.ts
29723
29919
  var import_comment_json2 = __toESM(require_src2(), 1);
29724
- import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync3, writeFileSync as writeFileSync4 } from "node:fs";
29725
- import { homedir as homedir8 } from "node:os";
29726
- import { dirname as dirname4, isAbsolute as isAbsolute2, join as join11, resolve as resolve2 } from "node:path";
29920
+ import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync4, writeFileSync as writeFileSync4 } from "node:fs";
29921
+ import { homedir as homedir9 } from "node:os";
29922
+ import { dirname as dirname5, isAbsolute as isAbsolute3, join as join12, resolve as resolve2 } from "node:path";
29727
29923
  import { fileURLToPath } from "node:url";
29728
29924
 
29729
29925
  // src/hooks/auto-update-checker/constants.ts
29730
- import { homedir as homedir7, platform as platform2 } from "node:os";
29731
- import { join as join10 } from "node:path";
29926
+ import { homedir as homedir8, platform as platform2 } from "node:os";
29927
+ import { join as join11 } from "node:path";
29732
29928
  var PACKAGE_NAME = "@cortexkit/aft-opencode";
29733
29929
  var NPM_REGISTRY_URL = "https://registry.npmjs.org";
29734
29930
  var NPM_FETCH_TIMEOUT = 1e4;
29735
29931
  function getOpenCodeCacheRoot() {
29736
29932
  if (platform2() === "win32") {
29737
- return join10(process.env.LOCALAPPDATA ?? homedir7(), "opencode");
29933
+ return join11(process.env.LOCALAPPDATA ?? homedir8(), "opencode");
29738
29934
  }
29739
- return join10(homedir7(), ".cache", "opencode");
29935
+ return join11(homedir8(), ".cache", "opencode");
29740
29936
  }
29741
29937
  function getOpenCodeConfigRoot() {
29742
29938
  if (platform2() === "win32") {
29743
- return join10(process.env.APPDATA ?? join10(homedir7(), "AppData", "Roaming"), "opencode");
29939
+ return join11(process.env.APPDATA ?? join11(homedir8(), "AppData", "Roaming"), "opencode");
29744
29940
  }
29745
- return join10(process.env.XDG_CONFIG_HOME ?? join10(homedir7(), ".config"), "opencode");
29941
+ return join11(process.env.XDG_CONFIG_HOME ?? join11(homedir8(), ".config"), "opencode");
29746
29942
  }
29747
- var CACHE_DIR = join10(getOpenCodeCacheRoot(), "packages");
29748
- var USER_OPENCODE_CONFIG = join10(getOpenCodeConfigRoot(), "opencode.json");
29749
- var USER_OPENCODE_CONFIG_JSONC = join10(getOpenCodeConfigRoot(), "opencode.jsonc");
29943
+ var CACHE_DIR = join11(getOpenCodeCacheRoot(), "packages");
29944
+ var USER_OPENCODE_CONFIG = join11(getOpenCodeConfigRoot(), "opencode.json");
29945
+ var USER_OPENCODE_CONFIG_JSONC = join11(getOpenCodeConfigRoot(), "opencode.jsonc");
29750
29946
 
29751
29947
  // src/hooks/auto-update-checker/types.ts
29752
29948
  var NpmPackageEnvelopeSchema = exports_external.object({
@@ -29804,8 +30000,8 @@ function extractChannel(version2) {
29804
30000
  }
29805
30001
  function getConfigPaths(directory) {
29806
30002
  return [
29807
- join11(directory, ".opencode", "opencode.json"),
29808
- join11(directory, ".opencode", "opencode.jsonc"),
30003
+ join12(directory, ".opencode", "opencode.json"),
30004
+ join12(directory, ".opencode", "opencode.jsonc"),
29809
30005
  USER_OPENCODE_CONFIG,
29810
30006
  USER_OPENCODE_CONFIG_JSONC
29811
30007
  ];
@@ -29818,9 +30014,9 @@ function resolvePathPluginSpec(spec, configPath) {
29818
30014
  return spec.replace(/^file:\/\//, "");
29819
30015
  }
29820
30016
  }
29821
- if (isAbsolute2(spec) || /^[A-Za-z]:[\\/]/.test(spec))
30017
+ if (isAbsolute3(spec) || /^[A-Za-z]:[\\/]/.test(spec))
29822
30018
  return spec;
29823
- return resolve2(dirname4(configPath), spec);
30019
+ return resolve2(dirname5(configPath), spec);
29824
30020
  }
29825
30021
  function getLocalDevPath(directory) {
29826
30022
  for (const configPath of getConfigPaths(directory)) {
@@ -29832,7 +30028,7 @@ function getLocalDevPath(directory) {
29832
30028
  for (const entry of plugins) {
29833
30029
  if (entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))
29834
30030
  continue;
29835
- if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute2(entry)) {
30031
+ if (entry.startsWith("file://") || entry.startsWith(".") || isAbsolute3(entry)) {
29836
30032
  const localPath = resolvePathPluginSpec(entry, configPath);
29837
30033
  const pkgPath = findPackageJsonUp(localPath);
29838
30034
  if (!pkgPath)
@@ -29848,10 +30044,10 @@ function getLocalDevPath(directory) {
29848
30044
  }
29849
30045
  function findPackageJsonUp(startPath) {
29850
30046
  try {
29851
- const stat = statSync3(startPath);
29852
- let dir = stat.isDirectory() ? startPath : dirname4(startPath);
30047
+ const stat = statSync4(startPath);
30048
+ let dir = stat.isDirectory() ? startPath : dirname5(startPath);
29853
30049
  for (let i = 0;i < 10; i++) {
29854
- const pkgPath = join11(dir, "package.json");
30050
+ const pkgPath = join12(dir, "package.json");
29855
30051
  if (existsSync8(pkgPath)) {
29856
30052
  try {
29857
30053
  const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync6(pkgPath, "utf-8")));
@@ -29859,7 +30055,7 @@ function findPackageJsonUp(startPath) {
29859
30055
  return pkgPath;
29860
30056
  } catch {}
29861
30057
  }
29862
- const parent = dirname4(dir);
30058
+ const parent = dirname5(dir);
29863
30059
  if (parent === dir)
29864
30060
  break;
29865
30061
  dir = parent;
@@ -29883,7 +30079,7 @@ function getLocalDevVersion(directory) {
29883
30079
  }
29884
30080
  function getCurrentRuntimePackageJsonPath(currentModuleUrl = import.meta.url) {
29885
30081
  try {
29886
- return findPackageJsonUp(dirname4(fileURLToPath(currentModuleUrl)));
30082
+ return findPackageJsonUp(dirname5(fileURLToPath(currentModuleUrl)));
29887
30083
  } catch (err) {
29888
30084
  warn2(`[auto-update-checker] Failed to resolve runtime package path: ${String(err)}`);
29889
30085
  return null;
@@ -29912,7 +30108,7 @@ function findPluginEntry(directory) {
29912
30108
  }
29913
30109
  var cachedPackageVersion = null;
29914
30110
  function getSpecCachePackageJsonPath(spec) {
29915
- return join11(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
30111
+ return join12(CACHE_DIR, spec, "node_modules", PACKAGE_NAME, "package.json");
29916
30112
  }
29917
30113
  function getCachedVersion(spec) {
29918
30114
  if (!spec && cachedPackageVersion)
@@ -29921,7 +30117,7 @@ function getCachedVersion(spec) {
29921
30117
  getCurrentRuntimePackageJsonPath(),
29922
30118
  spec ? getSpecCachePackageJsonPath(spec) : null,
29923
30119
  getSpecCachePackageJsonPath(`${PACKAGE_NAME}@latest`),
29924
- join11(homedir8(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
30120
+ join12(homedir9(), ".cache", "opencode", "node_modules", PACKAGE_NAME, "package.json")
29925
30121
  ].filter(isString);
29926
30122
  for (const packageJsonPath of candidates) {
29927
30123
  try {
@@ -29969,10 +30165,10 @@ async function getLatestVersion(channel = "latest", options = {}) {
29969
30165
  // src/hooks/auto-update-checker/cache.ts
29970
30166
  var pendingSnapshots = new Map;
29971
30167
  function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
29972
- const packageDir = join12(installDir, "node_modules", packageName);
29973
- const lockfilePath = join12(installDir, "package-lock.json");
29974
- const tempDir = mkdtempSync(join12(tmpdir3(), "aft-auto-update-"));
29975
- const stagedPackageDir = existsSync9(packageDir) ? join12(tempDir, "package") : null;
30168
+ const packageDir = join13(installDir, "node_modules", packageName);
30169
+ const lockfilePath = join13(installDir, "package-lock.json");
30170
+ const tempDir = mkdtempSync(join13(tmpdir3(), "aft-auto-update-"));
30171
+ const stagedPackageDir = existsSync9(packageDir) ? join13(tempDir, "package") : null;
29976
30172
  if (stagedPackageDir)
29977
30173
  cpSync(packageDir, stagedPackageDir, { recursive: true });
29978
30174
  return {
@@ -30008,12 +30204,12 @@ function stripPackageNameFromPath(pathValue, packageName) {
30008
30204
  for (const segment of [...packageName.split("/")].reverse()) {
30009
30205
  if (basename2(current) !== segment)
30010
30206
  return null;
30011
- current = dirname5(current);
30207
+ current = dirname6(current);
30012
30208
  }
30013
30209
  return current;
30014
30210
  }
30015
30211
  function removeFromPackageLock(installDir, packageName) {
30016
- const lockPath = join12(installDir, "package-lock.json");
30212
+ const lockPath = join13(installDir, "package-lock.json");
30017
30213
  if (!existsSync9(lockPath))
30018
30214
  return false;
30019
30215
  try {
@@ -30062,7 +30258,7 @@ function ensureDependencyVersion(packageJsonPath, packageName, version2) {
30062
30258
  }
30063
30259
  }
30064
30260
  function removeInstalledPackage(installDir, packageName) {
30065
- const packageDir = join12(installDir, "node_modules", packageName);
30261
+ const packageDir = join13(installDir, "node_modules", packageName);
30066
30262
  if (!existsSync9(packageDir))
30067
30263
  return false;
30068
30264
  rmSync3(packageDir, { recursive: true, force: true });
@@ -30071,19 +30267,19 @@ function removeInstalledPackage(installDir, packageName) {
30071
30267
  }
30072
30268
  function resolveInstallContext(runtimePackageJsonPath = getCurrentRuntimePackageJsonPath()) {
30073
30269
  if (runtimePackageJsonPath) {
30074
- const packageDir = dirname5(runtimePackageJsonPath);
30270
+ const packageDir = dirname6(runtimePackageJsonPath);
30075
30271
  const nodeModulesDir = stripPackageNameFromPath(packageDir, PACKAGE_NAME);
30076
30272
  if (nodeModulesDir && basename2(nodeModulesDir) === "node_modules") {
30077
- const installDir = dirname5(nodeModulesDir);
30078
- const packageJsonPath = join12(installDir, "package.json");
30273
+ const installDir = dirname6(nodeModulesDir);
30274
+ const packageJsonPath = join13(installDir, "package.json");
30079
30275
  if (existsSync9(packageJsonPath))
30080
30276
  return { installDir, packageJsonPath };
30081
30277
  }
30082
30278
  return null;
30083
30279
  }
30084
- const legacyPackageJsonPath = join12(dirname5(CACHE_DIR), "package.json");
30280
+ const legacyPackageJsonPath = join13(dirname6(CACHE_DIR), "package.json");
30085
30281
  if (existsSync9(legacyPackageJsonPath)) {
30086
- return { installDir: dirname5(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
30282
+ return { installDir: dirname6(CACHE_DIR), packageJsonPath: legacyPackageJsonPath };
30087
30283
  }
30088
30284
  return null;
30089
30285
  }
@@ -30119,10 +30315,16 @@ async function runNpmInstallSafe(installDir, options = {}) {
30119
30315
  try {
30120
30316
  if (options.signal?.aborted)
30121
30317
  return { ok: false, reason: "aborted" };
30122
- const npmBin = process.platform === "win32" ? "npm.cmd" : "npm";
30123
- const proc = spawn2(npmBin, ["install", "--no-audit", "--no-fund", "--no-progress", "--ignore-scripts"], {
30318
+ const npm = resolveNpm();
30319
+ if (!npm) {
30320
+ const reason = "npm not found on PATH or in known version-manager locations";
30321
+ warnNpmInstallFailure(reason, stderrTail);
30322
+ return { ok: false, reason };
30323
+ }
30324
+ const proc = spawn2(npm.command, ["install", "--no-audit", "--no-fund", "--no-progress", "--ignore-scripts"], {
30124
30325
  cwd: installDir,
30125
- stdio: ["ignore", "pipe", "pipe"]
30326
+ stdio: ["ignore", "pipe", "pipe"],
30327
+ env: npmSpawnEnv(npm)
30126
30328
  });
30127
30329
  proc.stderr?.on("data", (chunk) => {
30128
30330
  stderrTail += chunk.toString("utf8");
@@ -30251,11 +30453,11 @@ function claimCheckSlot(storageDir, intervalMs) {
30251
30453
  try {
30252
30454
  if (hasRecentCheckTimestamp(file2, intervalMs))
30253
30455
  return null;
30254
- mkdirSync6(dirname6(file2), { recursive: true });
30456
+ mkdirSync6(dirname7(file2), { recursive: true });
30255
30457
  const lockPath = `${file2}.lock`;
30256
30458
  let lockFd;
30257
30459
  try {
30258
- lockFd = openSync3(lockPath, "wx");
30460
+ lockFd = openSync4(lockPath, "wx");
30259
30461
  writeFileSync6(lockFd, JSON.stringify({ pid: process.pid, startedMs: Date.now() }));
30260
30462
  } catch (err) {
30261
30463
  if (err.code !== "EEXIST") {
@@ -30266,7 +30468,7 @@ function claimCheckSlot(storageDir, intervalMs) {
30266
30468
  const lock = {
30267
30469
  release: () => {
30268
30470
  try {
30269
- closeSync3(lockFd);
30471
+ closeSync4(lockFd);
30270
30472
  } catch {}
30271
30473
  rmSync4(lockPath, { force: true });
30272
30474
  }
@@ -30361,6 +30563,11 @@ async function runBackgroundUpdateCheck(ctx, options) {
30361
30563
  log2("[auto-update-checker] Auto-update disabled, notification only");
30362
30564
  return;
30363
30565
  }
30566
+ if (!isNpmAvailable()) {
30567
+ showToast(ctx, `AFT ${latestVersion} available`, `v${latestVersion} is ready, but npm was not found so it can't auto-install. Run \`npx @cortexkit/aft doctor --fix\` from a terminal, or launch OpenCode from a shell where npm is on PATH.`, "warning", 1e4);
30568
+ warn2("[auto-update-checker] npm not found on PATH or known version-manager locations; skipping destructive auto-update steps");
30569
+ return;
30570
+ }
30364
30571
  const installDir = preparePackageUpdate(latestVersion, PACKAGE_NAME);
30365
30572
  if (!installDir) {
30366
30573
  showToast(ctx, `AFT ${latestVersion}`, `v${latestVersion} available. Auto-update could not prepare the active install.`, "warning", 8000);
@@ -30391,49 +30598,49 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
30391
30598
  // src/lsp-auto-install.ts
30392
30599
  import { spawn as spawn3 } from "node:child_process";
30393
30600
  import { createHash as createHash4 } from "node:crypto";
30394
- import { createReadStream, mkdirSync as mkdirSync8, readFileSync as readFileSync11, renameSync as renameSync6, rmSync as rmSync5, statSync as statSync5 } from "node:fs";
30395
- import { join as join15 } from "node:path";
30601
+ import { createReadStream, mkdirSync as mkdirSync8, readFileSync as readFileSync11, renameSync as renameSync6, rmSync as rmSync5, statSync as statSync6 } from "node:fs";
30602
+ import { join as join16 } from "node:path";
30396
30603
 
30397
30604
  // src/lsp-cache.ts
30398
30605
  import {
30399
- closeSync as closeSync4,
30606
+ closeSync as closeSync5,
30400
30607
  mkdirSync as mkdirSync7,
30401
- openSync as openSync4,
30608
+ openSync as openSync5,
30402
30609
  readFileSync as readFileSync9,
30403
- statSync as statSync4,
30610
+ statSync as statSync5,
30404
30611
  unlinkSync as unlinkSync5,
30405
30612
  writeFileSync as writeFileSync7
30406
30613
  } from "node:fs";
30407
- import { homedir as homedir9 } from "node:os";
30408
- import { join as join13 } from "node:path";
30614
+ import { homedir as homedir10 } from "node:os";
30615
+ import { join as join14 } from "node:path";
30409
30616
  function aftCacheBase() {
30410
30617
  const override = process.env.AFT_CACHE_DIR;
30411
30618
  if (override && override.length > 0)
30412
30619
  return override;
30413
30620
  if (process.platform === "win32") {
30414
30621
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
30415
- const base2 = localAppData || join13(homedir9(), "AppData", "Local");
30416
- return join13(base2, "aft");
30622
+ const base2 = localAppData || join14(homedir10(), "AppData", "Local");
30623
+ return join14(base2, "aft");
30417
30624
  }
30418
- const base = process.env.XDG_CACHE_HOME || join13(homedir9(), ".cache");
30419
- return join13(base, "aft");
30625
+ const base = process.env.XDG_CACHE_HOME || join14(homedir10(), ".cache");
30626
+ return join14(base, "aft");
30420
30627
  }
30421
30628
  function lspCacheRoot() {
30422
- return join13(aftCacheBase(), "lsp-packages");
30629
+ return join14(aftCacheBase(), "lsp-packages");
30423
30630
  }
30424
30631
  function lspPackageDir(npmPackage) {
30425
- return join13(lspCacheRoot(), encodeURIComponent(npmPackage));
30632
+ return join14(lspCacheRoot(), encodeURIComponent(npmPackage));
30426
30633
  }
30427
30634
  function lspBinaryPath(npmPackage, binary) {
30428
- return join13(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
30635
+ return join14(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
30429
30636
  }
30430
30637
  function lspBinDir(npmPackage) {
30431
- return join13(lspPackageDir(npmPackage), "node_modules", ".bin");
30638
+ return join14(lspPackageDir(npmPackage), "node_modules", ".bin");
30432
30639
  }
30433
30640
  function isInstalled(npmPackage, binary) {
30434
30641
  for (const candidate of lspBinaryCandidates(binary)) {
30435
30642
  try {
30436
- if (statSync4(join13(lspBinDir(npmPackage), candidate)).isFile())
30643
+ if (statSync5(join14(lspBinDir(npmPackage), candidate)).isFile())
30437
30644
  return true;
30438
30645
  } catch {}
30439
30646
  }
@@ -30453,15 +30660,15 @@ function writeInstalledMetaIn(installDir, version2, sha256) {
30453
30660
  installedAt: new Date().toISOString(),
30454
30661
  ...sha256 ? { sha256 } : {}
30455
30662
  };
30456
- writeFileSync7(join13(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
30663
+ writeFileSync7(join14(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
30457
30664
  } catch (err) {
30458
30665
  log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
30459
30666
  }
30460
30667
  }
30461
30668
  function readInstalledMetaIn(installDir) {
30462
- const path2 = join13(installDir, INSTALLED_META_FILE);
30669
+ const path2 = join14(installDir, INSTALLED_META_FILE);
30463
30670
  try {
30464
- if (!statSync4(path2).isFile())
30671
+ if (!statSync5(path2).isFile())
30465
30672
  return null;
30466
30673
  const raw = readFileSync9(path2, "utf8");
30467
30674
  const parsed = JSON.parse(raw);
@@ -30483,7 +30690,7 @@ function readInstalledMeta(packageKey) {
30483
30690
  return readInstalledMetaIn(lspPackageDir(packageKey));
30484
30691
  }
30485
30692
  function lockPath(npmPackage) {
30486
- return join13(lspPackageDir(npmPackage), ".aft-installing");
30693
+ return join14(lspPackageDir(npmPackage), ".aft-installing");
30487
30694
  }
30488
30695
  var STALE_LOCK_MS2 = 30 * 60 * 1000;
30489
30696
  function acquireInstallLock(lockKey) {
@@ -30491,13 +30698,13 @@ function acquireInstallLock(lockKey) {
30491
30698
  const lock = lockPath(lockKey);
30492
30699
  const tryClaim = () => {
30493
30700
  try {
30494
- const fd = openSync4(lock, "wx");
30701
+ const fd = openSync5(lock, "wx");
30495
30702
  try {
30496
30703
  writeFileSync7(fd, `${process.pid}
30497
30704
  ${new Date().toISOString()}
30498
30705
  `);
30499
30706
  } finally {
30500
- closeSync4(fd);
30707
+ closeSync5(fd);
30501
30708
  }
30502
30709
  return true;
30503
30710
  } catch (err) {
@@ -30518,7 +30725,7 @@ ${new Date().toISOString()}
30518
30725
  const parsed = Number.parseInt(firstLine, 10);
30519
30726
  if (Number.isFinite(parsed) && parsed > 0)
30520
30727
  owningPid = parsed;
30521
- lockMtimeMs = statSync4(lock).mtimeMs;
30728
+ lockMtimeMs = statSync5(lock).mtimeMs;
30522
30729
  } catch {
30523
30730
  return tryClaim();
30524
30731
  }
@@ -30590,7 +30797,7 @@ async function withInstallLock(lockKey, task) {
30590
30797
  }
30591
30798
  var VERSION_CHECK_FILE = ".aft-version-check";
30592
30799
  function readVersionCheck(npmPackage) {
30593
- const file2 = join13(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
30800
+ const file2 = join14(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
30594
30801
  try {
30595
30802
  const raw = readFileSync9(file2, "utf8");
30596
30803
  const parsed = JSON.parse(raw);
@@ -30607,7 +30814,7 @@ function readVersionCheck(npmPackage) {
30607
30814
  }
30608
30815
  function writeVersionCheck(npmPackage, latest) {
30609
30816
  mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
30610
- const file2 = join13(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
30817
+ const file2 = join14(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
30611
30818
  const record2 = {
30612
30819
  last_checked: new Date().toISOString(),
30613
30820
  latest_eligible: latest
@@ -30769,8 +30976,8 @@ var NPM_LSP_TABLE = [
30769
30976
  ];
30770
30977
 
30771
30978
  // src/lsp-project-relevance.ts
30772
- import { existsSync as existsSync11, readdirSync as readdirSync2, readFileSync as readFileSync10 } from "node:fs";
30773
- import { join as join14 } from "node:path";
30979
+ import { existsSync as existsSync11, readdirSync as readdirSync3, readFileSync as readFileSync10 } from "node:fs";
30980
+ import { join as join15 } from "node:path";
30774
30981
  var MAX_WALK_DIRS = 200;
30775
30982
  var MAX_WALK_DEPTH = 4;
30776
30983
  var NOISE_DIRS = new Set([
@@ -30787,7 +30994,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
30787
30994
  if (!rootMarkers)
30788
30995
  return false;
30789
30996
  for (const marker of rootMarkers) {
30790
- if (existsSync11(join14(projectRoot, marker)))
30997
+ if (existsSync11(join15(projectRoot, marker)))
30791
30998
  return true;
30792
30999
  }
30793
31000
  return false;
@@ -30811,7 +31018,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
30811
31018
  }
30812
31019
  function readPackageJson(projectRoot) {
30813
31020
  try {
30814
- const raw = readFileSync10(join14(projectRoot, "package.json"), "utf8");
31021
+ const raw = readFileSync10(join15(projectRoot, "package.json"), "utf8");
30815
31022
  const parsed = JSON.parse(raw);
30816
31023
  if (typeof parsed !== "object" || parsed === null)
30817
31024
  return null;
@@ -30834,14 +31041,14 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
30834
31041
  visitedDirs += 1;
30835
31042
  let entries;
30836
31043
  try {
30837
- entries = readdirSync2(current.dir, { withFileTypes: true });
31044
+ entries = readdirSync3(current.dir, { withFileTypes: true });
30838
31045
  } catch {
30839
31046
  continue;
30840
31047
  }
30841
31048
  for (const entry of entries) {
30842
31049
  if (entry.isDirectory()) {
30843
31050
  if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
30844
- queue.push({ dir: join14(current.dir, entry.name), depth: current.depth + 1 });
31051
+ queue.push({ dir: join15(current.dir, entry.name), depth: current.depth + 1 });
30845
31052
  }
30846
31053
  continue;
30847
31054
  }
@@ -30975,10 +31182,16 @@ function runInstall(spec, version2, cwd, signal) {
30975
31182
  resolve3(false);
30976
31183
  return;
30977
31184
  }
30978
- const npmBin = process.platform === "win32" ? "npm.cmd" : "npm";
30979
- const child = spawn3(npmBin, ["install", "--no-save", "--ignore-scripts", "--silent", target], {
31185
+ const npm = resolveNpm();
31186
+ if (!npm) {
31187
+ warn2(`[lsp] npm not found on PATH or known locations; cannot install ${target}`);
31188
+ resolve3(false);
31189
+ return;
31190
+ }
31191
+ const child = spawn3(npm.command, ["install", "--no-save", "--ignore-scripts", "--silent", target], {
30980
31192
  stdio: ["ignore", "pipe", "pipe"],
30981
- cwd
31193
+ cwd,
31194
+ env: npmSpawnEnv(npm)
30982
31195
  });
30983
31196
  child.unref();
30984
31197
  let stderrBuf = "";
@@ -31105,7 +31318,7 @@ function hashInstalledBinary(spec) {
31105
31318
  let pathToHash = null;
31106
31319
  for (const p of candidates) {
31107
31320
  try {
31108
- if (statSync5(p).isFile()) {
31321
+ if (statSync6(p).isFile()) {
31109
31322
  pathToHash = p;
31110
31323
  break;
31111
31324
  }
@@ -31131,7 +31344,7 @@ function installedBinaryPath(spec) {
31131
31344
  ] : [lspBinaryPath(spec.npm, spec.binary)];
31132
31345
  for (const candidate of candidates) {
31133
31346
  try {
31134
- if (statSync5(candidate).isFile())
31347
+ if (statSync6(candidate).isFile())
31135
31348
  return candidate;
31136
31349
  } catch {}
31137
31350
  }
@@ -31142,10 +31355,10 @@ function sha256OfFileSync(path2) {
31142
31355
  }
31143
31356
  function quarantineCachedNpmInstall(spec, reason) {
31144
31357
  const packageDir = lspPackageDir(spec.npm);
31145
- const dest = join15(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
31358
+ const dest = join16(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
31146
31359
  warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
31147
31360
  try {
31148
- mkdirSync8(join15(dest, ".."), { recursive: true });
31361
+ mkdirSync8(join16(dest, ".."), { recursive: true });
31149
31362
  rmSync5(dest, { recursive: true, force: true });
31150
31363
  renameSync6(packageDir, dest);
31151
31364
  } catch (err) {
@@ -31231,17 +31444,17 @@ import {
31231
31444
  existsSync as existsSync12,
31232
31445
  lstatSync as lstatSync2,
31233
31446
  mkdirSync as mkdirSync9,
31234
- readdirSync as readdirSync3,
31447
+ readdirSync as readdirSync4,
31235
31448
  readFileSync as readFileSync12,
31236
31449
  readlinkSync as readlinkSync2,
31237
31450
  realpathSync as realpathSync3,
31238
31451
  renameSync as renameSync7,
31239
31452
  rmSync as rmSync6,
31240
- statSync as statSync6,
31453
+ statSync as statSync7,
31241
31454
  unlinkSync as unlinkSync6,
31242
31455
  writeFileSync as writeFileSync8
31243
31456
  } from "node:fs";
31244
- import { dirname as dirname7, join as join16, relative as relative2, resolve as resolve3 } from "node:path";
31457
+ import { dirname as dirname8, join as join17, relative as relative2, resolve as resolve3 } from "node:path";
31245
31458
  import { Readable as Readable3 } from "node:stream";
31246
31459
  import { pipeline as pipeline3 } from "node:stream/promises";
31247
31460
 
@@ -31331,26 +31544,26 @@ function detectHostPlatform() {
31331
31544
 
31332
31545
  // src/lsp-github-install.ts
31333
31546
  function ghCacheRoot() {
31334
- return join16(aftCacheBase(), "lsp-binaries");
31547
+ return join17(aftCacheBase(), "lsp-binaries");
31335
31548
  }
31336
31549
  function ghPackageDir(spec) {
31337
- return join16(ghCacheRoot(), spec.id);
31550
+ return join17(ghCacheRoot(), spec.id);
31338
31551
  }
31339
31552
  function ghBinDir(spec) {
31340
- return join16(ghPackageDir(spec), "bin");
31553
+ return join17(ghPackageDir(spec), "bin");
31341
31554
  }
31342
31555
  function ghExtractDir(spec) {
31343
- return join16(ghPackageDir(spec), "extracted");
31556
+ return join17(ghPackageDir(spec), "extracted");
31344
31557
  }
31345
31558
  var INSTALLED_META_FILE2 = ".aft-installed";
31346
31559
  function ghBinaryPath(spec, platform3) {
31347
31560
  const ext = platform3 === "win32" ? ".exe" : "";
31348
- return join16(ghBinDir(spec), `${spec.binary}${ext}`);
31561
+ return join17(ghBinDir(spec), `${spec.binary}${ext}`);
31349
31562
  }
31350
31563
  function isGithubInstalled(spec, platform3) {
31351
31564
  for (const candidate of ghBinaryCandidates(spec, platform3)) {
31352
31565
  try {
31353
- if (statSync6(join16(ghBinDir(spec), candidate)).isFile())
31566
+ if (statSync7(join17(ghBinDir(spec), candidate)).isFile())
31354
31567
  return true;
31355
31568
  } catch {}
31356
31569
  }
@@ -31363,8 +31576,8 @@ function ghBinaryCandidates(spec, platform3) {
31363
31576
  }
31364
31577
  function readGithubInstalledMetaIn(installDir) {
31365
31578
  try {
31366
- const path2 = join16(installDir, INSTALLED_META_FILE2);
31367
- if (!statSync6(path2).isFile())
31579
+ const path2 = join17(installDir, INSTALLED_META_FILE2);
31580
+ if (!statSync7(path2).isFile())
31368
31581
  return null;
31369
31582
  const parsed = JSON.parse(readFileSync12(path2, "utf8"));
31370
31583
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
@@ -31390,7 +31603,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
31390
31603
  binarySha256,
31391
31604
  ...archiveSha256 ? { archiveSha256 } : {}
31392
31605
  };
31393
- writeFileSync8(join16(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
31606
+ writeFileSync8(join17(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
31394
31607
  } catch (err) {
31395
31608
  warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
31396
31609
  }
@@ -31583,7 +31796,7 @@ async function downloadFile(url2, destPath, fetchImpl, assetSize, signal) {
31583
31796
  if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
31584
31797
  throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
31585
31798
  }
31586
- mkdirSync9(dirname7(destPath), { recursive: true });
31799
+ mkdirSync9(dirname8(destPath), { recursive: true });
31587
31800
  let bytesWritten = 0;
31588
31801
  const guard = new TransformStream({
31589
31802
  transform(chunk, controller) {
@@ -31634,12 +31847,12 @@ function validateExtraction(stagingRoot) {
31634
31847
  const walk = (dir) => {
31635
31848
  let entries;
31636
31849
  try {
31637
- entries = readdirSync3(dir);
31850
+ entries = readdirSync4(dir);
31638
31851
  } catch (err) {
31639
31852
  throw new Error(`failed to read staging dir ${dir}: ${err}`);
31640
31853
  }
31641
31854
  for (const entry of entries) {
31642
- const full = join16(dir, entry);
31855
+ const full = join17(dir, entry);
31643
31856
  let lst;
31644
31857
  try {
31645
31858
  lst = lstatSync2(full);
@@ -31727,10 +31940,10 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
31727
31940
  }
31728
31941
  function quarantineCachedGithubInstall(spec, reason) {
31729
31942
  const packageDir = ghPackageDir(spec);
31730
- const dest = join16(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
31943
+ const dest = join17(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
31731
31944
  warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
31732
31945
  try {
31733
- mkdirSync9(dirname7(dest), { recursive: true });
31946
+ mkdirSync9(dirname8(dest), { recursive: true });
31734
31947
  rmSync6(dest, { recursive: true, force: true });
31735
31948
  renameSync7(packageDir, dest);
31736
31949
  } catch (err) {
@@ -31740,9 +31953,9 @@ function quarantineCachedGithubInstall(spec, reason) {
31740
31953
  function validateCachedGithubInstall(spec, platform3) {
31741
31954
  const packageDir = ghPackageDir(spec);
31742
31955
  const meta3 = readGithubInstalledMetaIn(packageDir);
31743
- const binaryPath = ghBinaryCandidates(spec, platform3).map((candidate) => join16(ghBinDir(spec), candidate)).find((candidate) => {
31956
+ const binaryPath = ghBinaryCandidates(spec, platform3).map((candidate) => join17(ghBinDir(spec), candidate)).find((candidate) => {
31744
31957
  try {
31745
- return statSync6(candidate).isFile();
31958
+ return statSync7(candidate).isFile();
31746
31959
  } catch {
31747
31960
  return false;
31748
31961
  }
@@ -31818,7 +32031,7 @@ async function downloadAndInstall(spec, tag, assets, platform3, arch, fetchImpl,
31818
32031
  }
31819
32032
  const pkgDir = ghPackageDir(spec);
31820
32033
  const extractDir = ghExtractDir(spec);
31821
- const archivePath = join16(pkgDir, expected.name);
32034
+ const archivePath = join17(pkgDir, expected.name);
31822
32035
  log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
31823
32036
  try {
31824
32037
  await downloadFile(matchingAsset.url, archivePath, fetchImpl, matchingAsset.size, signal);
@@ -31858,13 +32071,13 @@ async function downloadAndInstall(spec, tag, assets, platform3, arch, fetchImpl,
31858
32071
  unlinkSync6(archivePath);
31859
32072
  } catch {}
31860
32073
  }
31861
- const innerBinaryPath = join16(extractDir, spec.binaryPathInArchive(platform3, arch, version2));
32074
+ const innerBinaryPath = join17(extractDir, spec.binaryPathInArchive(platform3, arch, version2));
31862
32075
  if (!existsSync12(innerBinaryPath)) {
31863
32076
  error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
31864
32077
  return null;
31865
32078
  }
31866
32079
  const targetBinary = ghBinaryPath(spec, platform3);
31867
- mkdirSync9(dirname7(targetBinary), { recursive: true });
32080
+ mkdirSync9(dirname8(targetBinary), { recursive: true });
31868
32081
  try {
31869
32082
  copyFileSync4(innerBinaryPath, targetBinary);
31870
32083
  if (platform3 !== "win32") {
@@ -32192,18 +32405,18 @@ function writeTerminal(terminal, data) {
32192
32405
  import { randomBytes as randomBytes2 } from "node:crypto";
32193
32406
  import { mkdirSync as mkdirSync10, renameSync as renameSync8, unlinkSync as unlinkSync7, writeFileSync as writeFileSync9 } from "node:fs";
32194
32407
  import { createServer } from "node:http";
32195
- import { dirname as dirname8, join as join18 } from "node:path";
32408
+ import { dirname as dirname9, join as join19 } from "node:path";
32196
32409
 
32197
32410
  // src/shared/rpc-utils.ts
32198
32411
  import { createHash as createHash6 } from "node:crypto";
32199
- import { join as join17 } from "node:path";
32412
+ import { join as join18 } from "node:path";
32200
32413
  function projectHash(directory) {
32201
32414
  const normalized = directory.replace(/\/+$/, "");
32202
32415
  return createHash6("sha256").update(normalized).digest("hex").slice(0, 16);
32203
32416
  }
32204
32417
  function rpcPortFileDir(storageDir, directory) {
32205
32418
  const hash2 = projectHash(directory);
32206
- return join17(storageDir, "rpc", hash2, "ports");
32419
+ return join18(storageDir, "rpc", hash2, "ports");
32207
32420
  }
32208
32421
 
32209
32422
  // src/shared/rpc-server.ts
@@ -32218,7 +32431,7 @@ class AftRpcServer {
32218
32431
  constructor(storageDir, directory) {
32219
32432
  this.portsDir = rpcPortFileDir(storageDir, directory);
32220
32433
  this.instanceId = randomBytes2(8).toString("hex");
32221
- this.portFilePath = join18(this.portsDir, `${this.instanceId}.json`);
32434
+ this.portFilePath = join19(this.portsDir, `${this.instanceId}.json`);
32222
32435
  }
32223
32436
  handle(method, handler) {
32224
32437
  this.handlers.set(method, handler);
@@ -32240,7 +32453,7 @@ class AftRpcServer {
32240
32453
  this.token = randomBytes2(32).toString("hex");
32241
32454
  this.server = server;
32242
32455
  try {
32243
- const dir = dirname8(this.portFilePath);
32456
+ const dir = dirname9(this.portFilePath);
32244
32457
  mkdirSync10(dir, { recursive: true, mode: 448 });
32245
32458
  const tmpPath = `${this.portFilePath}.tmp`;
32246
32459
  writeFileSync9(tmpPath, JSON.stringify({ port: this.port, token: this.token }), {
@@ -32575,20 +32788,20 @@ function formatStatusMarkdown(status) {
32575
32788
  // src/shared/tui-config.ts
32576
32789
  var import_comment_json4 = __toESM(require_src2(), 1);
32577
32790
  import { existsSync as existsSync13, mkdirSync as mkdirSync11, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
32578
- import { dirname as dirname9, join as join20 } from "node:path";
32791
+ import { dirname as dirname10, join as join21 } from "node:path";
32579
32792
 
32580
32793
  // src/shared/opencode-config-dir.ts
32581
- import { homedir as homedir10 } from "node:os";
32582
- import { join as join19, resolve as resolve4 } from "node:path";
32794
+ import { homedir as homedir11 } from "node:os";
32795
+ import { join as join20, resolve as resolve4 } from "node:path";
32583
32796
  function getCliConfigDir() {
32584
32797
  const envConfigDir = process.env.OPENCODE_CONFIG_DIR?.trim();
32585
32798
  if (envConfigDir) {
32586
32799
  return resolve4(envConfigDir);
32587
32800
  }
32588
32801
  if (process.platform === "win32") {
32589
- return join19(homedir10(), ".config", "opencode");
32802
+ return join20(homedir11(), ".config", "opencode");
32590
32803
  }
32591
- return join19(process.env.XDG_CONFIG_HOME || join19(homedir10(), ".config"), "opencode");
32804
+ return join20(process.env.XDG_CONFIG_HOME || join20(homedir11(), ".config"), "opencode");
32592
32805
  }
32593
32806
  function getOpenCodeConfigDir2(_options) {
32594
32807
  return getCliConfigDir();
@@ -32597,10 +32810,10 @@ function getOpenCodeConfigPaths(options) {
32597
32810
  const configDir = getOpenCodeConfigDir2(options);
32598
32811
  return {
32599
32812
  configDir,
32600
- configJson: join19(configDir, "opencode.json"),
32601
- configJsonc: join19(configDir, "opencode.jsonc"),
32602
- packageJson: join19(configDir, "package.json"),
32603
- omoConfig: join19(configDir, "magic-context.jsonc")
32813
+ configJson: join20(configDir, "opencode.json"),
32814
+ configJsonc: join20(configDir, "opencode.jsonc"),
32815
+ packageJson: join20(configDir, "package.json"),
32816
+ omoConfig: join20(configDir, "magic-context.jsonc")
32604
32817
  };
32605
32818
  }
32606
32819
 
@@ -32609,8 +32822,8 @@ var PLUGIN_NAME = "@cortexkit/aft-opencode";
32609
32822
  var PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
32610
32823
  function resolveTuiConfigPath() {
32611
32824
  const configDir = getOpenCodeConfigPaths({ binary: "opencode" }).configDir;
32612
- const jsoncPath = join20(configDir, "tui.jsonc");
32613
- const jsonPath = join20(configDir, "tui.json");
32825
+ const jsoncPath = join21(configDir, "tui.jsonc");
32826
+ const jsonPath = join21(configDir, "tui.json");
32614
32827
  if (existsSync13(jsoncPath))
32615
32828
  return jsoncPath;
32616
32829
  if (existsSync13(jsonPath))
@@ -32630,7 +32843,7 @@ function ensureTuiPluginEntry() {
32630
32843
  }
32631
32844
  plugins.push(PLUGIN_ENTRY);
32632
32845
  config2.plugin = plugins;
32633
- mkdirSync11(dirname9(configPath), { recursive: true });
32846
+ mkdirSync11(dirname10(configPath), { recursive: true });
32634
32847
  writeFileSync10(configPath, `${import_comment_json4.stringify(config2, null, 2)}
32635
32848
  `);
32636
32849
  log2(`[aft-plugin] added TUI plugin entry to ${configPath}`);
@@ -32718,6 +32931,7 @@ import { tool as tool3 } from "@opencode-ai/plugin";
32718
32931
 
32719
32932
  // src/tools/_shared.ts
32720
32933
  import * as fs3 from "node:fs";
32934
+ import * as os2 from "node:os";
32721
32935
  import * as path2 from "node:path";
32722
32936
  import { tool as tool2 } from "@opencode-ai/plugin";
32723
32937
  var z2 = tool2.schema;
@@ -32830,8 +33044,19 @@ async function resolveProjectRoot(ctx, runtime) {
32830
33044
  }
32831
33045
  return projectRootFor(runtime);
32832
33046
  }
33047
+ function expandTilde(input) {
33048
+ if (!input || !input.startsWith("~"))
33049
+ return input;
33050
+ if (input === "~")
33051
+ return os2.homedir();
33052
+ if (input.startsWith("~/") || input.startsWith(`~${path2.sep}`)) {
33053
+ return path2.resolve(os2.homedir(), input.slice(2));
33054
+ }
33055
+ return input;
33056
+ }
32833
33057
  function resolvePathFromProjectRoot(projectRoot, target) {
32834
- return path2.isAbsolute(target) ? target : path2.resolve(projectRoot, target);
33058
+ const expanded = expandTilde(target);
33059
+ return path2.isAbsolute(expanded) ? expanded : path2.resolve(projectRoot, expanded);
32835
33060
  }
32836
33061
  async function resolvePathArg(ctx, runtime, target) {
32837
33062
  return resolvePathFromProjectRoot(await resolveProjectRoot(ctx, runtime), target);
@@ -34912,7 +35137,7 @@ function createEditTool(ctx, writeToolName = "write") {
34912
35137
  if (response.success === false) {
34913
35138
  throw new Error(response.message ?? "transaction failed");
34914
35139
  }
34915
- return JSON.stringify(response);
35140
+ return formatEditSummary(response);
34916
35141
  }
34917
35142
  const file2 = args.filePath;
34918
35143
  if (!file2)
@@ -34999,12 +35224,7 @@ function createEditTool(ctx, writeToolName = "write") {
34999
35224
  });
35000
35225
  }
35001
35226
  }
35002
- const agentData = { ...data };
35003
- if (agentData.diff && typeof agentData.diff === "object") {
35004
- const d = agentData.diff;
35005
- agentData.diff = { additions: d.additions ?? 0, deletions: d.deletions ?? 0 };
35006
- }
35007
- let result = JSON.stringify(agentData);
35227
+ let result = formatEditSummary(data);
35008
35228
  const globSkipNote = formatGlobSkipReasonsNote(data.format_skip_reasons);
35009
35229
  if (globSkipNote)
35010
35230
  result += `
@@ -36547,18 +36767,7 @@ function safetyTools(ctx) {
36547
36767
 
36548
36768
  // src/tools/search.ts
36549
36769
  import * as fs7 from "node:fs";
36550
- import * as os2 from "node:os";
36551
36770
  import * as path6 from "node:path";
36552
- function expandTilde(input) {
36553
- if (!input || !input.startsWith("~"))
36554
- return input;
36555
- if (input === "~")
36556
- return os2.homedir();
36557
- if (input.startsWith("~/") || input.startsWith(`~${path6.sep}`)) {
36558
- return path6.resolve(os2.homedir(), input.slice(2));
36559
- }
36560
- return input;
36561
- }
36562
36771
  function arg2(schema) {
36563
36772
  return schema;
36564
36773
  }
@@ -36772,6 +36981,14 @@ function semanticHonestyNote(response) {
36772
36981
  notes.push("partial/incomplete");
36773
36982
  return notes.length > 0 ? `Search status: ${notes.join("; ")}.` : undefined;
36774
36983
  }
36984
+ function extraHonestyNote(response) {
36985
+ const notes = [];
36986
+ if (response.fully_degraded === true)
36987
+ notes.push("fully degraded");
36988
+ if (response.complete === false)
36989
+ notes.push("partial/incomplete");
36990
+ return notes.length > 0 ? `Search status: ${notes.join("; ")}.` : undefined;
36991
+ }
36775
36992
  function arg3(schema) {
36776
36993
  return schema;
36777
36994
  }
@@ -36823,24 +37040,12 @@ function semanticTools(ctx) {
36823
37040
  const code = typeof response.code === "string" && response.code.length > 0 ? response.code : undefined;
36824
37041
  throw new Error(code ? `semantic_search: ${code} — ${message}` : message);
36825
37042
  }
36826
- const honestyNote = semanticHonestyNote(response);
36827
- if (typeof response.text === "string" && response.status === "disabled" && Array.isArray(response.results) && response.results.length === 0) {
36828
- return honestyNote ? `${response.text}
36829
- ${honestyNote}` : response.text;
36830
- }
36831
- const structured = JSON.stringify(response, null, 2);
36832
37043
  if (typeof response.text === "string" && response.text.length > 0) {
36833
- const display = honestyNote ? `${response.text}
36834
- ${honestyNote}` : response.text;
36835
- return `${display}
36836
-
36837
- Structured response:
36838
- ${structured}`;
37044
+ const note = extraHonestyNote(response);
37045
+ return note ? `${response.text}
37046
+ ${note}` : response.text;
36839
37047
  }
36840
- return honestyNote ? `${honestyNote}
36841
-
36842
- Structured response:
36843
- ${structured}` : structured;
37048
+ return semanticHonestyNote(response) ?? "No results.";
36844
37049
  }
36845
37050
  };
36846
37051
  return {