@cortexkit/aft-pi 0.30.1 → 0.30.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
@@ -12399,7 +12399,7 @@ var require_snapshot_utils = __commonJS((exports, module) => {
12399
12399
  // ../../node_modules/.bun/undici@7.25.0/node_modules/undici/lib/mock/snapshot-recorder.js
12400
12400
  var require_snapshot_recorder = __commonJS((exports, module) => {
12401
12401
  var { writeFile, readFile, mkdir } = __require("node:fs/promises");
12402
- var { dirname: dirname3, resolve: resolve2 } = __require("node:path");
12402
+ var { dirname: dirname4, resolve: resolve2 } = __require("node:path");
12403
12403
  var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("node:timers");
12404
12404
  var { InvalidArgumentError, UndiciError } = require_errors();
12405
12405
  var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
@@ -12594,7 +12594,7 @@ var require_snapshot_recorder = __commonJS((exports, module) => {
12594
12594
  throw new InvalidArgumentError("Snapshot path is required");
12595
12595
  }
12596
12596
  const resolvedPath = resolve2(path);
12597
- await mkdir(dirname3(resolvedPath), { recursive: true });
12597
+ await mkdir(dirname4(resolvedPath), { recursive: true });
12598
12598
  const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
12599
12599
  hash,
12600
12600
  snapshot
@@ -29886,10 +29886,10 @@ var require_stringify = __commonJS((exports, module) => {
29886
29886
  replacer = null;
29887
29887
  indent = EMPTY;
29888
29888
  };
29889
- 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) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
29889
+ 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) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two)), gap) : EMPTY;
29890
29890
  var join_content = (inside, value, gap) => {
29891
29891
  const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
29892
- return join8(comment, inside, gap);
29892
+ return join9(comment, inside, gap);
29893
29893
  };
29894
29894
  var stringify_string = (holder, key, value) => {
29895
29895
  const raw = get_raw_string_literal(holder, key);
@@ -29911,13 +29911,13 @@ var require_stringify = __commonJS((exports, module) => {
29911
29911
  if (i !== 0) {
29912
29912
  inside += COMMA;
29913
29913
  }
29914
- const before = join8(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
29914
+ const before = join9(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
29915
29915
  inside += before || LF + deeper_gap;
29916
29916
  inside += stringify(i, value, deeper_gap) || STR_NULL;
29917
29917
  inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
29918
29918
  after_comma = process_comments(value, AFTER(i), deeper_gap);
29919
29919
  }
29920
- inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
29920
+ inside += join9(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
29921
29921
  return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
29922
29922
  };
29923
29923
  var object_stringify = (value, gap) => {
@@ -29938,13 +29938,13 @@ var require_stringify = __commonJS((exports, module) => {
29938
29938
  inside += COMMA;
29939
29939
  }
29940
29940
  first = false;
29941
- const before = join8(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
29941
+ const before = join9(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
29942
29942
  inside += before || LF + deeper_gap;
29943
29943
  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);
29944
29944
  after_comma = process_comments(value, AFTER(key), deeper_gap);
29945
29945
  };
29946
29946
  keys.forEach(iteratee);
29947
- inside += join8(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
29947
+ inside += join9(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
29948
29948
  return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
29949
29949
  };
29950
29950
  function stringify(key, holder, gap) {
@@ -34061,6 +34061,11 @@ class BinaryBridge {
34061
34061
  if (requestSessionId && options?.configureWarningClient !== undefined) {
34062
34062
  this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
34063
34063
  }
34064
+ const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
34065
+ const implicitTransportOptions = {
34066
+ ...options?.transportTimeoutMs !== undefined || options?.timeoutMs !== undefined ? { transportTimeoutMs: effectiveTimeoutMs } : {},
34067
+ markConfiguredOnSuccess: false
34068
+ };
34064
34069
  if (!this.configured) {
34065
34070
  if (command !== "configure" && command !== "version") {
34066
34071
  if (!this._configurePromise) {
@@ -34071,12 +34076,12 @@ class BinaryBridge {
34071
34076
  project_root: this.cwd,
34072
34077
  ...this.configOverrides,
34073
34078
  ...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
34074
- });
34079
+ }, implicitTransportOptions);
34075
34080
  if (configResult.success === false) {
34076
34081
  throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
34077
34082
  }
34078
34083
  await this.deliverConfigureWarnings(configResult, params, options);
34079
- await this.checkVersion();
34084
+ await this.checkVersion(implicitTransportOptions);
34080
34085
  if (!this.isAlive()) {
34081
34086
  throw new Error(`${this.errorPrefix} Bridge died during version check. Check logs: ${this.getLogFilePathVia()}`);
34082
34087
  }
@@ -34106,9 +34111,8 @@ class BinaryBridge {
34106
34111
  }
34107
34112
  const line = `${JSON.stringify(request)}
34108
34113
  `;
34109
- const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
34110
34114
  const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
34111
- return new Promise((resolve, reject) => {
34115
+ const response = await new Promise((resolve, reject) => {
34112
34116
  const timer = setTimeout(() => {
34113
34117
  this.pending.delete(id);
34114
34118
  const restartSuffix = keepBridgeOnTimeout ? "" : " — restarting bridge";
@@ -34141,6 +34145,10 @@ class BinaryBridge {
34141
34145
  }
34142
34146
  });
34143
34147
  });
34148
+ if (command === "configure" && response.success === true && options?.markConfiguredOnSuccess !== false) {
34149
+ this.configured = true;
34150
+ }
34151
+ return response;
34144
34152
  } catch (err) {
34145
34153
  if (err instanceof BridgeReplacedDuringVersionCheck && canRetryAfterVersionSwap && command !== "configure" && command !== "version") {
34146
34154
  this.logVia(`Retrying request "${command}" once after coordinated binary replacement: ${err.newBinaryPath}`);
@@ -34231,11 +34239,11 @@ class BinaryBridge {
34231
34239
  });
34232
34240
  }
34233
34241
  }
34234
- async checkVersion() {
34242
+ async checkVersion(options) {
34235
34243
  if (!this.minVersion)
34236
34244
  return;
34237
34245
  try {
34238
- const resp = await this.send("version");
34246
+ const resp = await this.send("version", {}, options);
34239
34247
  if (resp.success === false) {
34240
34248
  throw new Error(`Binary version check failed: ${String(resp.code ?? "unknown")} — likely too old`);
34241
34249
  }
@@ -34310,10 +34318,14 @@ class BinaryBridge {
34310
34318
  ...process.env,
34311
34319
  ...envPath ? { PATH: envPath } : {}
34312
34320
  };
34321
+ this.logVia(`bridge.spawnProcess: useFastembedBackend=${useFastembedBackend}, ` + `parentORT=${process.env.ORT_DYLIB_PATH ?? "(unset)"}, ` + `ortLibraryPath=${ortLibraryPath ?? "(none)"}`);
34313
34322
  if (useFastembedBackend) {
34314
34323
  env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ? join(this.configOverrides.storage_dir, "semantic", "models") : join(homedir() || "", ".cache", "fastembed"));
34315
- if (ortLibraryPath) {
34324
+ if (process.env.ORT_DYLIB_PATH) {
34325
+ this.logVia(`ORT_DYLIB_PATH inherited from parent env: ${process.env.ORT_DYLIB_PATH}`);
34326
+ } else if (ortLibraryPath) {
34316
34327
  env.ORT_DYLIB_PATH = ortLibraryPath;
34328
+ this.logVia(`ORT_DYLIB_PATH set from managed ONNX Runtime: ${ortLibraryPath}`);
34317
34329
  }
34318
34330
  }
34319
34331
  const child = spawn(this.binaryPath, [], {
@@ -34559,8 +34571,9 @@ class BinaryBridge {
34559
34571
  }
34560
34572
  }
34561
34573
  // ../aft-bridge/dist/downloader.js
34562
- import { createHash } from "node:crypto";
34563
- import { chmodSync, closeSync, createWriteStream, existsSync, mkdirSync, openSync, renameSync, rmSync, statSync, unlinkSync } from "node:fs";
34574
+ import { spawnSync } from "node:child_process";
34575
+ import { createHash, randomUUID } from "node:crypto";
34576
+ import { chmodSync, closeSync, createWriteStream, existsSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
34564
34577
  import { homedir as homedir2 } from "node:os";
34565
34578
  import { join as join2 } from "node:path";
34566
34579
  import { Readable } from "node:stream";
@@ -34588,6 +34601,34 @@ var LATEST_TAG_TIMEOUT_MS = 30000;
34588
34601
  var MAX_DOWNLOAD_BYTES = 200 * 1024 * 1024;
34589
34602
  var DOWNLOAD_LOCK_TIMEOUT_MS = 120000;
34590
34603
  var DOWNLOAD_LOCK_STALE_MS = 10 * 60000;
34604
+ function readBinaryVersion(binaryPath) {
34605
+ try {
34606
+ const result = spawnSync(binaryPath, ["--version"], {
34607
+ encoding: "utf-8",
34608
+ stdio: ["pipe", "pipe", "pipe"],
34609
+ timeout: 5000
34610
+ });
34611
+ const stdoutVersion = result.stdout?.trim();
34612
+ const stderrVersion = result.stderr?.trim();
34613
+ const rawVersion = stdoutVersion || stderrVersion;
34614
+ if (!rawVersion)
34615
+ return null;
34616
+ return rawVersion.replace(/^aft\s+/, "");
34617
+ } catch {
34618
+ return null;
34619
+ }
34620
+ }
34621
+ function expectedVersionFromTag(tag) {
34622
+ return tag.startsWith("v") ? tag.slice(1) : tag;
34623
+ }
34624
+ function isExpectedCachedBinary(binaryPath, tag) {
34625
+ const expected = expectedVersionFromTag(tag);
34626
+ const actual = readBinaryVersion(binaryPath);
34627
+ if (actual === expected)
34628
+ return true;
34629
+ warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; refreshing cache entry`);
34630
+ return false;
34631
+ }
34591
34632
  function getCacheDir() {
34592
34633
  if (process.platform === "win32") {
34593
34634
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
@@ -34623,7 +34664,7 @@ async function downloadBinary(version) {
34623
34664
  const versionedCacheDir = join2(getCacheDir(), tag);
34624
34665
  const binaryName = getBinaryName();
34625
34666
  const binaryPath = join2(versionedCacheDir, binaryName);
34626
- if (existsSync(binaryPath)) {
34667
+ if (existsSync(binaryPath) && isExpectedCachedBinary(binaryPath, tag)) {
34627
34668
  return binaryPath;
34628
34669
  }
34629
34670
  const downloadUrl = `https://github.com/${REPO}/releases/download/${tag}/${assetName}`;
@@ -34641,7 +34682,7 @@ async function downloadBinary(version) {
34641
34682
  mkdirSync(versionedCacheDir, { recursive: true });
34642
34683
  }
34643
34684
  releaseLock = await acquireDownloadLock(lockPath);
34644
- if (existsSync(binaryPath)) {
34685
+ if (existsSync(binaryPath) && isExpectedCachedBinary(binaryPath, tag)) {
34645
34686
  return binaryPath;
34646
34687
  }
34647
34688
  binaryController = new AbortController;
@@ -34730,7 +34771,7 @@ async function ensureBinary(version) {
34730
34771
  if (version) {
34731
34772
  const tag = version.startsWith("v") ? version : `v${version}`;
34732
34773
  const versionCached = getCachedBinaryPath(tag);
34733
- if (versionCached) {
34774
+ if (versionCached && isExpectedCachedBinary(versionCached, tag)) {
34734
34775
  log(`Found cached binary for ${tag}: ${versionCached}`);
34735
34776
  return versionCached;
34736
34777
  }
@@ -34744,13 +34785,17 @@ async function acquireDownloadLock(lockPath) {
34744
34785
  const startedAt = Date.now();
34745
34786
  while (true) {
34746
34787
  try {
34788
+ const owner = `${process.pid}:${Date.now()}:${randomUUID()}`;
34747
34789
  const fd = openSync(lockPath, "wx");
34790
+ writeSync(fd, owner);
34748
34791
  return () => {
34749
34792
  try {
34750
34793
  closeSync(fd);
34751
34794
  } catch {}
34752
34795
  try {
34753
- rmSync(lockPath, { force: true });
34796
+ if (readFileSync(lockPath, "utf-8") === owner) {
34797
+ rmSync(lockPath, { force: true });
34798
+ }
34754
34799
  } catch {}
34755
34800
  };
34756
34801
  } catch (err) {
@@ -34813,34 +34858,35 @@ function compressionSavingsPercent(original, compressed) {
34813
34858
  }
34814
34859
  // ../aft-bridge/dist/migration.js
34815
34860
  import { spawnSync as spawnSync2 } from "node:child_process";
34816
- import { existsSync as existsSync3, mkdirSync as mkdirSync3 } from "node:fs";
34861
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4 } from "node:fs";
34817
34862
  import { homedir as homedir4, tmpdir } from "node:os";
34818
- import { dirname, join as join4 } from "node:path";
34863
+ import { dirname as dirname2, join as join5 } from "node:path";
34864
+
34865
+ // ../aft-bridge/dist/paths.js
34866
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync as renameSync2 } from "node:fs";
34867
+ import { dirname, join as join3 } from "node:path";
34868
+ function resolveHarnessStoragePath(storageRoot, harness, ...segments) {
34869
+ return join3(storageRoot, harness, ...segments);
34870
+ }
34871
+ function repairRootScopedStorageFile(storageRoot, harness, fileName) {
34872
+ const harnessPath = resolveHarnessStoragePath(storageRoot, harness, fileName);
34873
+ const rootPath = join3(storageRoot, fileName);
34874
+ if (existsSync2(harnessPath) || !existsSync2(rootPath))
34875
+ return harnessPath;
34876
+ try {
34877
+ mkdirSync2(dirname(harnessPath), { recursive: true });
34878
+ renameSync2(rootPath, harnessPath);
34879
+ } catch {}
34880
+ return harnessPath;
34881
+ }
34819
34882
 
34820
34883
  // ../aft-bridge/dist/resolver.js
34821
- import { execSync, spawnSync } from "node:child_process";
34822
- import { chmodSync as chmodSync2, copyFileSync, existsSync as existsSync2, mkdirSync as mkdirSync2, renameSync as renameSync2 } from "node:fs";
34884
+ import { execSync } from "node:child_process";
34885
+ import { chmodSync as chmodSync2, copyFileSync, existsSync as existsSync3, mkdirSync as mkdirSync3, renameSync as renameSync3 } from "node:fs";
34823
34886
  import { createRequire as createRequire2 } from "node:module";
34824
34887
  import { homedir as homedir3 } from "node:os";
34825
- import { join as join3 } from "node:path";
34888
+ import { join as join4 } from "node:path";
34826
34889
  var ensureBinaryForResolver = ensureBinary;
34827
- function readBinaryVersion(binaryPath) {
34828
- try {
34829
- const result = spawnSync(binaryPath, ["--version"], {
34830
- encoding: "utf-8",
34831
- stdio: ["pipe", "pipe", "pipe"],
34832
- timeout: 5000
34833
- });
34834
- const stdoutVersion = result.stdout?.trim();
34835
- const stderrVersion = result.stderr?.trim();
34836
- const rawVersion = stdoutVersion || stderrVersion;
34837
- if (!rawVersion)
34838
- return null;
34839
- return rawVersion.replace(/^aft\s+/, "");
34840
- } catch {
34841
- return null;
34842
- }
34843
- }
34844
34890
  function copyToVersionedCache(npmBinaryPath, knownVersion) {
34845
34891
  try {
34846
34892
  const version = knownVersion ?? readBinaryVersion(npmBinaryPath);
@@ -34848,22 +34894,22 @@ function copyToVersionedCache(npmBinaryPath, knownVersion) {
34848
34894
  return null;
34849
34895
  const tag = version.startsWith("v") ? version : `v${version}`;
34850
34896
  const cacheDir = getCacheDir();
34851
- const versionedDir = join3(cacheDir, tag);
34897
+ const versionedDir = join4(cacheDir, tag);
34852
34898
  const ext = process.platform === "win32" ? ".exe" : "";
34853
- const cachedPath = join3(versionedDir, `aft${ext}`);
34854
- if (existsSync2(cachedPath)) {
34899
+ const cachedPath = join4(versionedDir, `aft${ext}`);
34900
+ if (existsSync3(cachedPath)) {
34855
34901
  const cachedVersion = readBinaryVersion(cachedPath);
34856
34902
  if (cachedVersion === version)
34857
34903
  return cachedPath;
34858
34904
  warn(`Cached binary at ${cachedPath} reports ${cachedVersion ?? "no version"}, expected ${version}; refreshing from npm package`);
34859
34905
  }
34860
- mkdirSync2(versionedDir, { recursive: true });
34906
+ mkdirSync3(versionedDir, { recursive: true });
34861
34907
  const tmpPath = `${cachedPath}.${process.pid}.${Date.now()}.tmp`;
34862
34908
  copyFileSync(npmBinaryPath, tmpPath);
34863
34909
  if (process.platform !== "win32") {
34864
34910
  chmodSync2(tmpPath, 493);
34865
34911
  }
34866
- renameSync2(tmpPath, cachedPath);
34912
+ renameSync3(tmpPath, cachedPath);
34867
34913
  log(`Copied npm binary to versioned cache: ${cachedPath}`);
34868
34914
  return cachedPath;
34869
34915
  } catch (err) {
@@ -34879,17 +34925,17 @@ function homeDirFromEnv(env) {
34879
34925
  }
34880
34926
  function cacheDirFromEnv(env) {
34881
34927
  if (process.platform === "win32") {
34882
- const base2 = env.LOCALAPPDATA || env.APPDATA || join3(homeDirFromEnv(env), "AppData", "Local");
34883
- return join3(base2, "aft", "bin");
34928
+ const base2 = env.LOCALAPPDATA || env.APPDATA || join4(homeDirFromEnv(env), "AppData", "Local");
34929
+ return join4(base2, "aft", "bin");
34884
34930
  }
34885
- const base = env.XDG_CACHE_HOME || join3(homeDirFromEnv(env), ".cache");
34886
- return join3(base, "aft", "bin");
34931
+ const base = env.XDG_CACHE_HOME || join4(homeDirFromEnv(env), ".cache");
34932
+ return join4(base, "aft", "bin");
34887
34933
  }
34888
34934
  function cachedBinaryPathFromEnv(version, env, ext) {
34889
- const binaryPath = join3(cacheDirFromEnv(env), version, `aft${ext}`);
34890
- return existsSync2(binaryPath) ? binaryPath : null;
34935
+ const binaryPath = join4(cacheDirFromEnv(env), version, `aft${ext}`);
34936
+ return existsSync3(binaryPath) ? binaryPath : null;
34891
34937
  }
34892
- function isExpectedCachedBinary(binaryPath, expectedVersion) {
34938
+ function isExpectedCachedBinary2(binaryPath, expectedVersion) {
34893
34939
  const expected = normalizeBareVersion(expectedVersion);
34894
34940
  const actual = readBinaryVersion(binaryPath);
34895
34941
  if (actual === expected)
@@ -34897,6 +34943,21 @@ function isExpectedCachedBinary(binaryPath, expectedVersion) {
34897
34943
  warn(`Cached binary at ${binaryPath} reports ${actual ?? "no version"}, expected ${expected}; skipping cache candidate`);
34898
34944
  return false;
34899
34945
  }
34946
+ function probeBinaryCandidate(binaryPath, source, expectedVersion) {
34947
+ const actual = readBinaryVersion(binaryPath);
34948
+ if (actual === null) {
34949
+ warn(`${source} binary at ${binaryPath} did not report a version; skipping`);
34950
+ return null;
34951
+ }
34952
+ if (expectedVersion && actual !== normalizeBareVersion(expectedVersion)) {
34953
+ warn(`${source} binary at ${binaryPath} reports ${actual}, expected ${normalizeBareVersion(expectedVersion)}; skipping`);
34954
+ return null;
34955
+ }
34956
+ return binaryPath;
34957
+ }
34958
+ function parsePathLookupOutput(output) {
34959
+ return output.split(/\r?\n/).map((candidate) => candidate.trim()).filter(Boolean);
34960
+ }
34900
34961
  function platformKey(platform = process.platform, arch = process.arch) {
34901
34962
  const archMap = PLATFORM_ARCH_MAP[platform];
34902
34963
  if (!archMap) {
@@ -34922,7 +34983,7 @@ function findBinarySync(expectedVersion) {
34922
34983
  if (pluginVersion) {
34923
34984
  const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
34924
34985
  const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
34925
- if (versionCached && isExpectedCachedBinary(versionCached, pluginVersion))
34986
+ if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion))
34926
34987
  return versionCached;
34927
34988
  }
34928
34989
  try {
@@ -34930,7 +34991,7 @@ function findBinarySync(expectedVersion) {
34930
34991
  const packageBin = `@cortexkit/aft-${key}/bin/aft${ext}`;
34931
34992
  const req = createRequire2(import.meta.url);
34932
34993
  const resolved = req.resolve(packageBin);
34933
- if (existsSync2(resolved)) {
34994
+ if (existsSync3(resolved)) {
34934
34995
  const npmVersion = readBinaryVersion(resolved);
34935
34996
  if (npmVersion === null) {
34936
34997
  warn(`npm platform package binary at ${resolved} did not report a version; skipping (continuing to PATH lookup)`);
@@ -34949,12 +35010,18 @@ function findBinarySync(expectedVersion) {
34949
35010
  env,
34950
35011
  stdio: ["pipe", "pipe", "pipe"]
34951
35012
  }).trim();
34952
- if (result)
34953
- return result;
35013
+ for (const candidate of parsePathLookupOutput(result)) {
35014
+ const usable = probeBinaryCandidate(candidate, "PATH", expectedVersion);
35015
+ if (usable)
35016
+ return usable;
35017
+ }
34954
35018
  } catch {}
34955
- const cargoPath = join3(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
34956
- if (existsSync2(cargoPath))
34957
- return cargoPath;
35019
+ const cargoPath = join4(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
35020
+ if (existsSync3(cargoPath)) {
35021
+ const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
35022
+ if (usable)
35023
+ return usable;
35024
+ }
34958
35025
  return null;
34959
35026
  }
34960
35027
  async function findBinary(expectedVersion) {
@@ -34995,9 +35062,9 @@ function dataHome() {
34995
35062
  if (process.env.XDG_DATA_HOME)
34996
35063
  return process.env.XDG_DATA_HOME;
34997
35064
  if (process.platform === "win32") {
34998
- return process.env.LOCALAPPDATA || process.env.APPDATA || join4(homeDir(), "AppData", "Local");
35065
+ return process.env.LOCALAPPDATA || process.env.APPDATA || join5(homeDir(), "AppData", "Local");
34999
35066
  }
35000
- return join4(homeDir(), ".local", "share");
35067
+ return join5(homeDir(), ".local", "share");
35001
35068
  }
35002
35069
  function homeDir() {
35003
35070
  if (process.platform === "win32")
@@ -35006,11 +35073,11 @@ function homeDir() {
35006
35073
  }
35007
35074
  function resolveLegacyStorageRoot(harness) {
35008
35075
  if (harness === "pi")
35009
- return join4(homeDir(), ".pi", "agent", "aft");
35010
- return join4(dataHome(), "opencode", "storage", "plugin", "aft");
35076
+ return join5(homeDir(), ".pi", "agent", "aft");
35077
+ return join5(dataHome(), "opencode", "storage", "plugin", "aft");
35011
35078
  }
35012
35079
  function resolveCortexKitStorageRoot() {
35013
- return join4(dataHome(), "cortexkit", "aft");
35080
+ return join5(dataHome(), "cortexkit", "aft");
35014
35081
  }
35015
35082
  function tail(value) {
35016
35083
  if (!value)
@@ -35024,26 +35091,26 @@ function spawnErrorLabel(error2) {
35024
35091
  return [code, error2.message].filter(Boolean).join(": ");
35025
35092
  }
35026
35093
  function migrationLogPath(newRoot, harness, logger) {
35027
- const desired = join4(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
35094
+ const desired = join5(newRoot, "logs", "migration", `${harness}-${Date.now()}.jsonl`);
35028
35095
  try {
35029
- mkdirSync3(dirname(desired), { recursive: true });
35096
+ mkdirSync4(dirname2(desired), { recursive: true });
35030
35097
  return desired;
35031
35098
  } catch (err) {
35032
- const fallback = join4(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
35033
- logger?.warn?.(`Failed to create AFT migration log directory ${dirname(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
35099
+ const fallback = join5(tmpdir(), `aft-migration-${harness}-${Date.now()}.jsonl`);
35100
+ logger?.warn?.(`Failed to create AFT migration log directory ${dirname2(desired)}: ${err instanceof Error ? err.message : String(err)}. ` + `Using fallback log path ${fallback}.`);
35034
35101
  return fallback;
35035
35102
  }
35036
35103
  }
35037
35104
  async function ensureStorageMigrated(opts) {
35038
35105
  const legacyRoot = resolveLegacyStorageRoot(opts.harness);
35039
35106
  const newRoot = resolveCortexKitStorageRoot();
35040
- const targetMarker = join4(newRoot, opts.harness, TARGET_MARKER);
35107
+ const targetMarker = resolveHarnessStoragePath(newRoot, opts.harness, TARGET_MARKER);
35041
35108
  const info = opts.logger?.info ?? opts.logger?.log;
35042
- if (existsSync3(targetMarker)) {
35109
+ if (existsSync4(targetMarker)) {
35043
35110
  info?.(`AFT storage already migrated for ${opts.harness}; using ${newRoot}`);
35044
35111
  return;
35045
35112
  }
35046
- if (!existsSync3(legacyRoot)) {
35113
+ if (!existsSync4(legacyRoot)) {
35047
35114
  info?.(`AFT storage migration skipped for ${opts.harness}: no legacy data at ${legacyRoot}; ` + `using ${newRoot} for fresh install`);
35048
35115
  return;
35049
35116
  }
@@ -35093,8 +35160,8 @@ async function ensureStorageMigrated(opts) {
35093
35160
  // ../aft-bridge/dist/onnx-runtime.js
35094
35161
  import { execFileSync } from "node:child_process";
35095
35162
  import { createHash as createHash2 } from "node:crypto";
35096
- 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 "node:fs";
35097
- import { dirname as dirname2, join as join5, relative, resolve } from "node:path";
35163
+ import { chmodSync as chmodSync3, closeSync as closeSync2, copyFileSync as copyFileSync2, createWriteStream as createWriteStream2, existsSync as existsSync5, lstatSync, mkdirSync as mkdirSync5, openSync as openSync2, readdirSync, readFileSync as readFileSync2, readlinkSync, realpathSync, rmSync as rmSync2, statSync as statSync2, symlinkSync, unlinkSync as unlinkSync2, writeFileSync } from "node:fs";
35164
+ import { basename, dirname as dirname3, join as join6, relative, resolve } from "node:path";
35098
35165
  import { Readable as Readable2 } from "node:stream";
35099
35166
  import { pipeline as pipeline2 } from "node:stream/promises";
35100
35167
  var ORT_VERSION = "1.24.4";
@@ -35157,9 +35224,9 @@ function getManualInstallHint() {
35157
35224
  }
35158
35225
  async function ensureOnnxRuntime(storageDir) {
35159
35226
  const info = getPlatformInfo();
35160
- const ortDir = join5(storageDir, "onnxruntime", ORT_VERSION);
35161
- const libPath = join5(ortDir, info?.libName ?? "libonnxruntime.dylib");
35162
- if (existsSync4(libPath)) {
35227
+ const ortDir = join6(storageDir, "onnxruntime", ORT_VERSION);
35228
+ const libPath = join6(ortDir, info?.libName ?? "libonnxruntime.dylib");
35229
+ if (existsSync5(libPath)) {
35163
35230
  const meta = readOnnxInstalledMeta(ortDir);
35164
35231
  if (meta?.sha256) {
35165
35232
  try {
@@ -35188,9 +35255,9 @@ async function ensureOnnxRuntime(storageDir) {
35188
35255
  warn(`ONNX Runtime auto-download not available for ${process.platform}/${process.arch}. Install manually: ${getManualInstallHint()}`);
35189
35256
  return null;
35190
35257
  }
35191
- const onnxBaseDir = join5(storageDir, "onnxruntime");
35192
- mkdirSync4(onnxBaseDir, { recursive: true });
35193
- const lockPath = join5(onnxBaseDir, ONNX_LOCK_FILE);
35258
+ const onnxBaseDir = join6(storageDir, "onnxruntime");
35259
+ mkdirSync5(onnxBaseDir, { recursive: true });
35260
+ const lockPath = join6(onnxBaseDir, ONNX_LOCK_FILE);
35194
35261
  cleanupAbandonedStagingDirs(onnxBaseDir);
35195
35262
  if (!acquireLock(lockPath)) {
35196
35263
  warn(`ONNX Runtime install already in progress in another process (lock: ${lockPath}). Skipping.`);
@@ -35209,7 +35276,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
35209
35276
  for (const entry of entries) {
35210
35277
  if (!entry.startsWith(`${ORT_VERSION}.tmp.`))
35211
35278
  continue;
35212
- const stagingDir = join5(onnxBaseDir, entry);
35279
+ const stagingDir = join6(onnxBaseDir, entry);
35213
35280
  const parts = entry.split(".");
35214
35281
  const pidStr = parts[parts.length - 2];
35215
35282
  const pid = pidStr ? Number.parseInt(pidStr, 10) : NaN;
@@ -35241,7 +35308,7 @@ function cleanupAbandonedStagingDirs(onnxBaseDir) {
35241
35308
  }
35242
35309
  function cleanupIncompleteTargetIfUnowned(ortDir) {
35243
35310
  try {
35244
- if (existsSync4(ortDir) && !existsSync4(join5(ortDir, ONNX_INSTALLED_META_FILE))) {
35311
+ if (existsSync5(ortDir) && !existsSync5(join6(ortDir, ONNX_INSTALLED_META_FILE))) {
35245
35312
  log(`[onnx] removing half-populated install dir ${ortDir} (no meta file)`);
35246
35313
  rmSync2(ortDir, { recursive: true, force: true });
35247
35314
  }
@@ -35251,6 +35318,14 @@ function cleanupIncompleteTargetIfUnowned(ortDir) {
35251
35318
  }
35252
35319
  var REQUIRED_ORT_MAJOR = 1;
35253
35320
  var REQUIRED_ORT_MIN_MINOR = 20;
35321
+ var INVALID_ORT_VERSION = "<invalid>";
35322
+ function parseOnnxVersionFromPath(value) {
35323
+ const name = basename(value);
35324
+ const semverish = name.match(/\.(\d+\.\d+\.\d+(?:[-+][A-Za-z0-9.-]+)?)(?:\.dylib)?$/);
35325
+ if (semverish)
35326
+ return semverish[1].split(/[-+]/, 1)[0];
35327
+ return /\d+\.\d+\.\d+/.test(name) ? INVALID_ORT_VERSION : null;
35328
+ }
35254
35329
  function detectOnnxVersion(libDir, libName) {
35255
35330
  try {
35256
35331
  const entries = readdirSync(libDir);
@@ -35258,23 +35333,23 @@ function detectOnnxVersion(libDir, libName) {
35258
35333
  for (const entry of entries) {
35259
35334
  if (!entry.startsWith(barePrefix))
35260
35335
  continue;
35261
- const match = entry.match(/\.(\d+\.\d+\.\d+)(?:\.dylib)?$/);
35262
- if (match)
35263
- return match[1];
35336
+ const version = parseOnnxVersionFromPath(entry);
35337
+ if (version)
35338
+ return version;
35264
35339
  }
35265
- const base = join5(libDir, libName);
35266
- if (existsSync4(base)) {
35340
+ const base = join6(libDir, libName);
35341
+ if (existsSync5(base)) {
35267
35342
  try {
35268
35343
  const real = realpathSync(base);
35269
- const m = real.match(/\.(\d+\.\d+\.\d+)(?:\.dylib)?$/);
35270
- if (m)
35271
- return m[1];
35344
+ const version = parseOnnxVersionFromPath(real);
35345
+ if (version)
35346
+ return version;
35272
35347
  } catch {}
35273
35348
  try {
35274
35349
  const target = readlinkSync(base);
35275
- const m = target.match(/\.(\d+\.\d+\.\d+)(?:\.dylib)?$/);
35276
- if (m)
35277
- return m[1];
35350
+ const version = parseOnnxVersionFromPath(target);
35351
+ if (version)
35352
+ return version;
35278
35353
  } catch {}
35279
35354
  }
35280
35355
  } catch {}
@@ -35299,7 +35374,7 @@ function findSystemOnnxRuntime(libName) {
35299
35374
  searchPaths.push("/usr/lib", "/usr/lib/x86_64-linux-gnu", "/usr/lib/aarch64-linux-gnu", "/usr/local/lib");
35300
35375
  }
35301
35376
  for (const dir of searchPaths) {
35302
- if (!existsSync4(join5(dir, libName)))
35377
+ if (!existsSync5(join6(dir, libName)))
35303
35378
  continue;
35304
35379
  const version = detectOnnxVersion(dir, libName);
35305
35380
  if (version && !isOnnxVersionCompatible(version)) {
@@ -35326,7 +35401,7 @@ async function downloadFileWithCap(url, destPath) {
35326
35401
  if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES2) {
35327
35402
  throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES2}`);
35328
35403
  }
35329
- mkdirSync4(dirname2(destPath), { recursive: true });
35404
+ mkdirSync5(dirname3(destPath), { recursive: true });
35330
35405
  let bytesWritten = 0;
35331
35406
  const guard = new TransformStream({
35332
35407
  transform(chunk, transformController) {
@@ -35356,11 +35431,11 @@ function validateExtractedTree(stagingRoot) {
35356
35431
  const walk = (dir) => {
35357
35432
  const entries = readdirSync(dir);
35358
35433
  for (const entry of entries) {
35359
- const fullPath = join5(dir, entry);
35434
+ const fullPath = join6(dir, entry);
35360
35435
  const lst = lstatSync(fullPath);
35361
35436
  if (lst.isSymbolicLink()) {
35362
35437
  const linkTarget = readlinkSync(fullPath);
35363
- const resolvedTarget = resolve(dirname2(fullPath), linkTarget);
35438
+ const resolvedTarget = resolve(dirname3(fullPath), linkTarget);
35364
35439
  const rel2 = relative(realRoot, resolvedTarget);
35365
35440
  if (rel2.startsWith("..") || process.platform !== "win32" && rel2.startsWith("/")) {
35366
35441
  throw new Error(`extracted symlink ${fullPath} points outside staging root: ${linkTarget}`);
@@ -35390,8 +35465,8 @@ async function downloadOnnxRuntime(info, targetDir) {
35390
35465
  log(`Downloading ONNX Runtime v${ORT_VERSION} for ${process.platform}/${process.arch}...`);
35391
35466
  const tmpDir = `${targetDir}.tmp.${process.pid}.${Date.now().toString(36)}`;
35392
35467
  try {
35393
- mkdirSync4(tmpDir, { recursive: true });
35394
- const archivePath = join5(tmpDir, `onnxruntime.${info.archiveType}`);
35468
+ mkdirSync5(tmpDir, { recursive: true });
35469
+ const archivePath = join6(tmpDir, `onnxruntime.${info.archiveType}`);
35395
35470
  await downloadFileWithCap(url, archivePath);
35396
35471
  const archiveSha256 = sha256File(archivePath);
35397
35472
  log(`ONNX Runtime archive sha256=${archiveSha256}`);
@@ -35407,16 +35482,16 @@ async function downloadOnnxRuntime(info, targetDir) {
35407
35482
  unlinkSync2(archivePath);
35408
35483
  } catch {}
35409
35484
  validateExtractedTree(tmpDir);
35410
- const extractedDir = join5(tmpDir, info.assetName, "lib");
35411
- if (!existsSync4(extractedDir)) {
35485
+ const extractedDir = join6(tmpDir, info.assetName, "lib");
35486
+ if (!existsSync5(extractedDir)) {
35412
35487
  throw new Error(`Expected directory not found: ${extractedDir}`);
35413
35488
  }
35414
- mkdirSync4(targetDir, { recursive: true });
35489
+ mkdirSync5(targetDir, { recursive: true });
35415
35490
  const libFiles = readdirSync(extractedDir).filter((f) => f.startsWith("libonnxruntime") || f.startsWith("onnxruntime"));
35416
35491
  const realFiles = [];
35417
35492
  const symlinks = [];
35418
35493
  for (const libFile of libFiles) {
35419
- const src = join5(extractedDir, libFile);
35494
+ const src = join6(extractedDir, libFile);
35420
35495
  try {
35421
35496
  const stat = lstatSync(src);
35422
35497
  log(`ORT extract: ${libFile} — isSymlink=${stat.isSymbolicLink()}, isFile=${stat.isFile()}, size=${stat.size}`);
@@ -35431,7 +35506,7 @@ async function downloadOnnxRuntime(info, targetDir) {
35431
35506
  }
35432
35507
  }
35433
35508
  copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks);
35434
- const libPath = join5(targetDir, info.libName);
35509
+ const libPath = join6(targetDir, info.libName);
35435
35510
  let libHash = null;
35436
35511
  try {
35437
35512
  libHash = sha256File(libPath);
@@ -35456,8 +35531,8 @@ async function downloadOnnxRuntime(info, targetDir) {
35456
35531
  function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, copyFile = copyFileSync2) {
35457
35532
  const requiredLibs = new Set([info.libName]);
35458
35533
  for (const libFile of realFiles) {
35459
- const src = join5(extractedDir, libFile);
35460
- const dst = join5(targetDir, libFile);
35534
+ const src = join6(extractedDir, libFile);
35535
+ const dst = join6(targetDir, libFile);
35461
35536
  try {
35462
35537
  copyFile(src, dst);
35463
35538
  if (process.platform !== "win32") {
@@ -35472,7 +35547,7 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
35472
35547
  }
35473
35548
  }
35474
35549
  for (const link of symlinks) {
35475
- const dst = join5(targetDir, link.name);
35550
+ const dst = join6(targetDir, link.name);
35476
35551
  try {
35477
35552
  unlinkSync2(dst);
35478
35553
  } catch {}
@@ -35486,8 +35561,8 @@ function copyOnnxLibraries(info, extractedDir, targetDir, realFiles, symlinks, c
35486
35561
  log(`ORT extract: failed to symlink optional ${link.name}: ${symlinkErr}`);
35487
35562
  }
35488
35563
  }
35489
- const requiredPath = join5(targetDir, info.libName);
35490
- if (!existsSync4(requiredPath)) {
35564
+ const requiredPath = join6(targetDir, info.libName);
35565
+ if (!existsSync5(requiredPath)) {
35491
35566
  rmSync2(targetDir, { recursive: true, force: true });
35492
35567
  throw new Error(`Required ONNX Runtime library missing after install: ${requiredPath}`);
35493
35568
  }
@@ -35513,17 +35588,17 @@ function writeOnnxInstalledMeta(installDir, version, sha256, archiveSha256) {
35513
35588
  ...sha256 ? { sha256 } : {},
35514
35589
  archiveSha256
35515
35590
  };
35516
- writeFileSync(join5(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
35591
+ writeFileSync(join6(installDir, ONNX_INSTALLED_META_FILE), JSON.stringify(meta), "utf8");
35517
35592
  } catch (err) {
35518
35593
  log(`[onnx] failed to write installed-meta in ${installDir}: ${err}`);
35519
35594
  }
35520
35595
  }
35521
35596
  function readOnnxInstalledMeta(installDir) {
35522
- const path = join5(installDir, ONNX_INSTALLED_META_FILE);
35597
+ const path = join6(installDir, ONNX_INSTALLED_META_FILE);
35523
35598
  try {
35524
35599
  if (!statSync2(path).isFile())
35525
35600
  return null;
35526
- const raw = readFileSync(path, "utf8");
35601
+ const raw = readFileSync2(path, "utf8");
35527
35602
  const parsed = JSON.parse(raw);
35528
35603
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
35529
35604
  return null;
@@ -35539,7 +35614,7 @@ function readOnnxInstalledMeta(installDir) {
35539
35614
  }
35540
35615
  function sha256File(path) {
35541
35616
  const hash = createHash2("sha256");
35542
- hash.update(readFileSync(path));
35617
+ hash.update(readFileSync2(path));
35543
35618
  return hash.digest("hex");
35544
35619
  }
35545
35620
  function acquireLock(lockPath) {
@@ -35567,7 +35642,7 @@ ${new Date().toISOString()}
35567
35642
  let owningPid = null;
35568
35643
  let lockMtimeMs = 0;
35569
35644
  try {
35570
- const raw = readFileSync(lockPath, "utf8");
35645
+ const raw = readFileSync2(lockPath, "utf8");
35571
35646
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
35572
35647
  const parsed = Number.parseInt(firstLine, 10);
35573
35648
  if (Number.isFinite(parsed) && parsed > 0)
@@ -35593,7 +35668,7 @@ function releaseLock(lockPath) {
35593
35668
  try {
35594
35669
  let owningPid = null;
35595
35670
  try {
35596
- const raw = readFileSync(lockPath, "utf8");
35671
+ const raw = readFileSync2(lockPath, "utf8");
35597
35672
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
35598
35673
  const parsed = Number.parseInt(firstLine, 10);
35599
35674
  if (Number.isFinite(parsed) && parsed > 0)
@@ -35661,6 +35736,7 @@ function isHomeDirectoryRoot(normalizedKey) {
35661
35736
 
35662
35737
  class BridgePool {
35663
35738
  bridges = new Map;
35739
+ staleBridges = new Set;
35664
35740
  binaryPath;
35665
35741
  maxPoolSize;
35666
35742
  idleTimeoutMs;
@@ -35683,6 +35759,7 @@ class BridgePool {
35683
35759
  onConfigureWarnings: options.onConfigureWarnings,
35684
35760
  onBashCompletion: options.onBashCompletion,
35685
35761
  onBashLongRunning: options.onBashLongRunning,
35762
+ onBashPatternMatch: options.onBashPatternMatch,
35686
35763
  errorPrefix: options.errorPrefix,
35687
35764
  logger: options.logger
35688
35765
  };
@@ -35734,6 +35811,12 @@ class BridgePool {
35734
35811
  this.bridges.delete(dir);
35735
35812
  }
35736
35813
  }
35814
+ for (const bridge of this.staleBridges) {
35815
+ if (bridge.hasPendingRequests())
35816
+ continue;
35817
+ bridge.shutdown().catch((err) => this.error("stale cleanup shutdown failed:", err));
35818
+ this.staleBridges.delete(bridge);
35819
+ }
35737
35820
  }
35738
35821
  evictLRU() {
35739
35822
  let oldestDir = null;
@@ -35757,14 +35840,21 @@ class BridgePool {
35757
35840
  clearInterval(this.cleanupTimer);
35758
35841
  this.cleanupTimer = null;
35759
35842
  }
35760
- const shutdowns = Array.from(this.bridges.values()).map((e) => e.bridge.shutdown());
35843
+ const shutdowns = [
35844
+ ...Array.from(this.bridges.values(), (e) => e.bridge.shutdown()),
35845
+ ...Array.from(this.staleBridges.values(), (bridge) => bridge.shutdown())
35846
+ ];
35761
35847
  this.bridges.clear();
35848
+ this.staleBridges.clear();
35762
35849
  await Promise.allSettled(shutdowns);
35763
35850
  }
35764
35851
  async replaceBinary(newPath) {
35765
35852
  this.binaryPath = newPath;
35853
+ for (const entry of this.bridges.values()) {
35854
+ this.staleBridges.add(entry.bridge);
35855
+ }
35766
35856
  this.bridges.clear();
35767
- this.log(`Binary path updated to ${newPath}. All bridges cleared — next calls will use the new binary.`);
35857
+ this.log(`Binary path updated to ${newPath}. Active bridges marked stale — next calls will use the new binary.`);
35768
35858
  return newPath;
35769
35859
  }
35770
35860
  log(message, meta) {
@@ -35814,11 +35904,11 @@ function normalizeKey(projectRoot) {
35814
35904
  }
35815
35905
  }
35816
35906
  // ../aft-bridge/dist/url-fetch.js
35817
- import { createHash as createHash3 } from "node:crypto";
35907
+ import { createHash as createHash3, randomBytes } from "node:crypto";
35818
35908
  import { lookup } from "node:dns/promises";
35819
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readdirSync as readdirSync2, readFileSync as readFileSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
35909
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readdirSync as readdirSync2, readFileSync as readFileSync3, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
35820
35910
  import { isIP } from "node:net";
35821
- import { join as join6 } from "node:path";
35911
+ import { join as join7 } from "node:path";
35822
35912
 
35823
35913
  // ../../node_modules/.bun/undici@7.25.0/node_modules/undici/index.js
35824
35914
  var __filename = "/home/runner/work/aft/aft/node_modules/.bun/undici@7.25.0/node_modules/undici/index.js";
@@ -35968,16 +36058,16 @@ var FETCH_TIMEOUT_MS = 30000;
35968
36058
  var BODY_CHUNK_TIMEOUT_MS = 15000;
35969
36059
  var MAX_REDIRECTS = 5;
35970
36060
  function cacheDir(storageDir) {
35971
- return join6(storageDir, "url_cache");
36061
+ return join7(storageDir, "url_cache");
35972
36062
  }
35973
36063
  function hashUrl(url) {
35974
36064
  return createHash3("sha256").update(url).digest("hex").slice(0, 16);
35975
36065
  }
35976
36066
  function metaPath(storageDir, hash) {
35977
- return join6(cacheDir(storageDir), `${hash}.meta.json`);
36067
+ return join7(cacheDir(storageDir), `${hash}.meta.json`);
35978
36068
  }
35979
36069
  function contentPath(storageDir, hash, extension) {
35980
- return join6(cacheDir(storageDir), `${hash}${extension}`);
36070
+ return join7(cacheDir(storageDir), `${hash}${extension}`);
35981
36071
  }
35982
36072
  function _isPrivateIpv4(address) {
35983
36073
  const parts = address.split(".").map((part) => Number.parseInt(part, 10));
@@ -36102,13 +36192,21 @@ function resolveRedirectUrl(currentUrl, location) {
36102
36192
  }
36103
36193
  return new URL(location, currentUrl);
36104
36194
  }
36195
+ var isBunRuntime = typeof globalThis.Bun !== "undefined";
36105
36196
  async function fetchWithRedirects(startUrl, allowPrivate, deps = {}) {
36106
36197
  let currentUrl = startUrl;
36107
- const fetchImpl2 = deps.fetchImpl ?? $fetch;
36198
+ const fetchImpl2 = deps.fetchImpl ?? (isBunRuntime ? globalThis.fetch : $fetch);
36108
36199
  const dnsLookup = deps.lookup ?? lookup;
36109
36200
  for (let redirectCount = 0;redirectCount <= MAX_REDIRECTS; redirectCount++) {
36110
36201
  const validatedIp = await assertPublicUrl(currentUrl, allowPrivate, dnsLookup);
36111
- const dispatcher = validatedIp ? (deps.dispatcherFactory ?? createPinnedDispatcher)(validatedIp) : undefined;
36202
+ let dispatcher;
36203
+ if (validatedIp) {
36204
+ if (deps.dispatcherFactory) {
36205
+ dispatcher = deps.dispatcherFactory(validatedIp);
36206
+ } else if (!isBunRuntime) {
36207
+ dispatcher = createPinnedDispatcher(validatedIp);
36208
+ }
36209
+ }
36112
36210
  const controller = new AbortController;
36113
36211
  const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
36114
36212
  let response;
@@ -36119,7 +36217,7 @@ async function fetchWithRedirects(startUrl, allowPrivate, deps = {}) {
36119
36217
  dispatcher,
36120
36218
  headers: {
36121
36219
  "user-agent": "aft-opencode-plugin",
36122
- accept: "application/vnd.github.raw, text/markdown, text/x-markdown, text/html;q=0.9, text/plain;q=0.5"
36220
+ accept: "application/vnd.github.raw, text/markdown, text/x-markdown, text/html;q=0.9, application/json;q=0.8, text/plain;q=0.5"
36123
36221
  }
36124
36222
  });
36125
36223
  } catch (err) {
@@ -36160,6 +36258,9 @@ function resolveExtension(contentType) {
36160
36258
  if (lower === "text/plain") {
36161
36259
  return ".md";
36162
36260
  }
36261
+ if (lower === "application/json" || lower === "application/ld+json" || lower.endsWith("+json")) {
36262
+ return ".json";
36263
+ }
36163
36264
  return null;
36164
36265
  }
36165
36266
  async function fetchUrlToTempFile(url, storageDir, options = {}) {
@@ -36175,15 +36276,15 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
36175
36276
  const allowPrivate = options.allowPrivate === true;
36176
36277
  await assertPublicUrl(parsed, allowPrivate, options.lookup);
36177
36278
  const dir = cacheDir(storageDir);
36178
- mkdirSync5(dir, { recursive: true });
36279
+ mkdirSync6(dir, { recursive: true });
36179
36280
  const hash = hashUrl(url);
36180
36281
  const metaFile = metaPath(storageDir, hash);
36181
- if (existsSync5(metaFile)) {
36282
+ if (existsSync6(metaFile)) {
36182
36283
  try {
36183
- const meta2 = JSON.parse(readFileSync2(metaFile, "utf8"));
36284
+ const meta2 = JSON.parse(readFileSync3(metaFile, "utf8"));
36184
36285
  const age = Date.now() - meta2.fetchedAt;
36185
36286
  const cached = contentPath(storageDir, hash, meta2.extension);
36186
- if (age < CACHE_TTL_MS && existsSync5(cached)) {
36287
+ if (age < CACHE_TTL_MS && existsSync6(cached)) {
36187
36288
  log(`URL cache hit: ${url} (${Math.round(age / 1000)}s old)`);
36188
36289
  return cached;
36189
36290
  }
@@ -36249,19 +36350,20 @@ async function fetchUrlToTempFile(url, storageDir, options = {}) {
36249
36350
  }
36250
36351
  const body = Buffer.concat(chunks);
36251
36352
  const contentFile = contentPath(storageDir, hash, extension);
36252
- const tmpContent = `${contentFile}.tmp-${process.pid}`;
36353
+ const nonce = randomBytes(8).toString("hex");
36354
+ const tmpContent = `${contentFile}.tmp-${process.pid}-${nonce}`;
36253
36355
  writeFileSync2(tmpContent, body);
36254
- const { renameSync: renameSync3 } = await import("node:fs");
36255
- renameSync3(tmpContent, contentFile);
36356
+ const { renameSync: renameSync4 } = await import("node:fs");
36357
+ renameSync4(tmpContent, contentFile);
36256
36358
  const meta = {
36257
36359
  url,
36258
36360
  contentType,
36259
36361
  extension,
36260
36362
  fetchedAt: Date.now()
36261
36363
  };
36262
- const tmpMeta = `${metaFile}.tmp-${process.pid}`;
36364
+ const tmpMeta = `${metaFile}.tmp-${process.pid}-${nonce}`;
36263
36365
  writeFileSync2(tmpMeta, JSON.stringify(meta));
36264
- renameSync3(tmpMeta, metaFile);
36366
+ renameSync4(tmpMeta, metaFile);
36265
36367
  log(`URL cached (${total} bytes): ${url}`);
36266
36368
  return contentFile;
36267
36369
  }
@@ -36499,7 +36601,7 @@ function markExplicitControl(sessionID, taskId, trackOutstanding = true) {
36499
36601
  if (idx >= 0) {
36500
36602
  const completion = state.pendingCompletions[idx];
36501
36603
  state.pendingCompletions.splice(idx, 1);
36502
- queuePendingPatternMatch(state, completionToExitPattern(completion));
36604
+ queuePendingPatternMatch(state, completionToExitPattern(completion, true));
36503
36605
  state.wakeDeferredTaskIds.delete(taskId);
36504
36606
  }
36505
36607
  }
@@ -36527,13 +36629,18 @@ function routeExplicitControlCompletions(state) {
36527
36629
  state.outstandingTaskIds.delete(completion.task_id);
36528
36630
  state.explicitControlTasks.delete(completion.task_id);
36529
36631
  state.wakeDeferredTaskIds.delete(completion.task_id);
36530
- queuePendingPatternMatch(state, completionToExitPattern(completion));
36632
+ queuePendingPatternMatch(state, completionToExitPattern(completion, true));
36531
36633
  } else {
36532
36634
  remaining.push(completion);
36533
36635
  }
36534
36636
  }
36535
36637
  state.pendingCompletions = remaining;
36536
36638
  }
36639
+ async function handlePushedPatternMatch(drainContext, frame) {
36640
+ const state = stateFor(drainContext.sessionID);
36641
+ queuePendingPatternMatch(state, frame);
36642
+ await triggerWakeIfPending(drainContext, true);
36643
+ }
36537
36644
  function ingestBgCompletions(sessionID, completions) {
36538
36645
  if (!Array.isArray(completions) || completions.length === 0)
36539
36646
  return [];
@@ -36549,7 +36656,7 @@ function ingestBgCompletions(sessionID, completions) {
36549
36656
  if (state.explicitControlTasks.has(completion.task_id)) {
36550
36657
  state.outstandingTaskIds.delete(completion.task_id);
36551
36658
  state.explicitControlTasks.delete(completion.task_id);
36552
- queuePendingPatternMatch(state, completionToExitPattern(completion));
36659
+ queuePendingPatternMatch(state, completionToExitPattern(completion, true));
36553
36660
  continue;
36554
36661
  }
36555
36662
  if (!state.outstandingTaskIds.has(completion.task_id)) {
@@ -36585,6 +36692,8 @@ async function appendToolResultBgCompletions(drainContext, content) {
36585
36692
  if (state.pendingCompletions.length === 0 && state.pendingLongRunning.length === 0 && state.pendingPatternMatches.length === 0)
36586
36693
  return;
36587
36694
  const deliveredCompletions = [...state.pendingCompletions];
36695
+ const deliveredPatternMatches = [...state.pendingPatternMatches];
36696
+ const completionAcks = completionAcksForDelivery(deliveredCompletions, deliveredPatternMatches);
36588
36697
  const reminder = formatCombinedSystemReminder(state.pendingCompletions, state.pendingLongRunning, state.pendingPatternMatches);
36589
36698
  state.pendingCompletions = [];
36590
36699
  for (const completion of deliveredCompletions) {
@@ -36594,7 +36703,7 @@ async function appendToolResultBgCompletions(drainContext, content) {
36594
36703
  state.pendingPatternMatches = [];
36595
36704
  state.wakeRetryAttempts = 0;
36596
36705
  state.wakeHardStopped = false;
36597
- await ackCompletions(drainContext, deliveredCompletions);
36706
+ await ackCompletions(drainContext, completionAcks);
36598
36707
  if (state.debounceTimer) {
36599
36708
  clearTimeout(state.debounceTimer);
36600
36709
  state.debounceTimer = null;
@@ -36757,7 +36866,8 @@ function scheduleWake(state, sendWake, onSendFailure, includeDeferredCompletions
36757
36866
  state.wakeDeferredTaskIds.delete(taskId);
36758
36867
  state.pendingLongRunning = [];
36759
36868
  state.pendingPatternMatches = [];
36760
- sendWake(reminder, pending).then(() => {
36869
+ const completionAcks = completionAcksForDelivery(pending, pendingPatternMatches);
36870
+ sendWake(reminder, completionAcks).then(() => {
36761
36871
  state.retryDelayMs = null;
36762
36872
  state.wakeRetryAttempts = 0;
36763
36873
  state.wakeHardStopped = false;
@@ -36822,7 +36932,7 @@ function ingestDrainedBgCompletions(sessionID, completions) {
36822
36932
  state.outstandingTaskIds.delete(completion.task_id);
36823
36933
  if (state.explicitControlTasks.has(completion.task_id)) {
36824
36934
  state.explicitControlTasks.delete(completion.task_id);
36825
- queuePendingPatternMatch(state, completionToExitPattern(completion));
36935
+ queuePendingPatternMatch(state, completionToExitPattern(completion, true));
36826
36936
  continue;
36827
36937
  }
36828
36938
  if (state.consumedTaskIds.has(completion.task_id))
@@ -36858,10 +36968,10 @@ function bufferUnknownCompletion(state, completion) {
36858
36968
  function pruneUnknownCompletions(state, now) {
36859
36969
  state.unknownCompletions = state.unknownCompletions.filter((entry) => now - entry.receivedAt <= UNKNOWN_COMPLETION_TTL_MS);
36860
36970
  }
36861
- function completionToExitPattern(completion) {
36971
+ function completionToExitPattern(completion, ackCompletionOnDelivery = false) {
36862
36972
  const status = formatStatus(completion);
36863
36973
  const preview = formatOutputPreview(completion).replace(/^ {4}/gm, "").slice(-300);
36864
- return {
36974
+ const entry = {
36865
36975
  task_id: completion.task_id,
36866
36976
  session_id: "",
36867
36977
  watch_id: "exit",
@@ -36872,6 +36982,20 @@ ${preview}` : `task ${completion.task_id} exited (${status})`,
36872
36982
  once: true,
36873
36983
  reason: "task_exit"
36874
36984
  };
36985
+ if (ackCompletionOnDelivery)
36986
+ entry.ackCompletionOnDelivery = true;
36987
+ return entry;
36988
+ }
36989
+ function completionAcksForDelivery(completions, patternMatches) {
36990
+ const acks = [...completions];
36991
+ const ackedTaskIds = new Set(acks.map((completion) => completion.task_id));
36992
+ for (const match of patternMatches) {
36993
+ if (!match.ackCompletionOnDelivery || ackedTaskIds.has(match.task_id))
36994
+ continue;
36995
+ acks.push({ task_id: match.task_id, status: "unknown", exit_code: null, command: "" });
36996
+ ackedTaskIds.add(match.task_id);
36997
+ }
36998
+ return acks;
36875
36999
  }
36876
37000
  function isBgCompletion(value) {
36877
37001
  if (!value || typeof value !== "object" || Array.isArray(value))
@@ -36941,7 +37065,7 @@ import {
36941
37065
  // package.json
36942
37066
  var package_default = {
36943
37067
  name: "@cortexkit/aft-pi",
36944
- version: "0.30.1",
37068
+ version: "0.30.2",
36945
37069
  type: "module",
36946
37070
  description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
36947
37071
  main: "dist/index.js",
@@ -36963,7 +37087,7 @@ var package_default = {
36963
37087
  prepublishOnly: "bun run build"
36964
37088
  },
36965
37089
  dependencies: {
36966
- "@cortexkit/aft-bridge": "0.30.1",
37090
+ "@cortexkit/aft-bridge": "0.30.2",
36967
37091
  "@xterm/headless": "^5.5.0",
36968
37092
  "comment-json": "^5.0.0",
36969
37093
  diff: "^8.0.4",
@@ -36971,12 +37095,12 @@ var package_default = {
36971
37095
  zod: "^4.1.8"
36972
37096
  },
36973
37097
  optionalDependencies: {
36974
- "@cortexkit/aft-darwin-arm64": "0.30.1",
36975
- "@cortexkit/aft-darwin-x64": "0.30.1",
36976
- "@cortexkit/aft-linux-arm64": "0.30.1",
36977
- "@cortexkit/aft-linux-x64": "0.30.1",
36978
- "@cortexkit/aft-win32-arm64": "0.30.1",
36979
- "@cortexkit/aft-win32-x64": "0.30.1"
37098
+ "@cortexkit/aft-darwin-arm64": "0.30.2",
37099
+ "@cortexkit/aft-darwin-x64": "0.30.2",
37100
+ "@cortexkit/aft-linux-arm64": "0.30.2",
37101
+ "@cortexkit/aft-linux-x64": "0.30.2",
37102
+ "@cortexkit/aft-win32-arm64": "0.30.2",
37103
+ "@cortexkit/aft-win32-x64": "0.30.2"
36980
37104
  },
36981
37105
  devDependencies: {
36982
37106
  "@earendil-works/pi-coding-agent": "*",
@@ -37268,9 +37392,13 @@ class AftStatusDialogComponent {
37268
37392
  async fetchOnce() {
37269
37393
  try {
37270
37394
  const bridge = bridgeFor(this.props.pluginCtx, this.props.extCtx.cwd);
37395
+ const sessionId = resolveSessionId(this.props.extCtx);
37271
37396
  const cached = bridge.getCachedStatus();
37272
- const response = cached ? { success: true, ...cached } : await callBridge(bridge, "status", {}, this.props.extCtx);
37273
- if (!cached) {
37397
+ const cachedSession = cached?.session;
37398
+ const cachedSessionId = cachedSession?.id;
37399
+ const cacheUsable = cached !== null && cachedSessionId !== undefined && cachedSessionId === sessionId;
37400
+ const response = cacheUsable ? { success: true, ...cached } : await callBridge(bridge, "status", {}, this.props.extCtx);
37401
+ if (!cacheUsable) {
37274
37402
  bridge.cacheStatusSnapshot(response);
37275
37403
  }
37276
37404
  if (this.closed)
@@ -37499,9 +37627,13 @@ function registerStatusCommand(pi, ctx) {
37499
37627
  return;
37500
37628
  }
37501
37629
  const bridge = bridgeFor(ctx, extCtx.cwd);
37630
+ const sessionId = resolveSessionId(extCtx);
37502
37631
  const cached = bridge.getCachedStatus();
37503
- const response = cached ? { success: true, ...cached } : await callBridge(bridge, "status", {}, extCtx);
37504
- if (!cached) {
37632
+ const cachedSession = cached?.session;
37633
+ const cachedSessionId = cachedSession?.id;
37634
+ const cacheUsable = cached !== null && cachedSessionId !== undefined && cachedSessionId === sessionId;
37635
+ const response = cacheUsable ? { success: true, ...cached } : await callBridge(bridge, "status", {}, extCtx);
37636
+ if (!cacheUsable) {
37505
37637
  bridge.cacheStatusSnapshot(response);
37506
37638
  }
37507
37639
  const snapshot = coerceAftStatus(response);
@@ -37521,9 +37653,9 @@ function registerStatusCommand(pi, ctx) {
37521
37653
 
37522
37654
  // src/config.ts
37523
37655
  var import_comment_json = __toESM(require_src2(), 1);
37524
- import { existsSync as existsSync6, readFileSync as readFileSync3, renameSync as renameSync3, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
37656
+ import { existsSync as existsSync7, readFileSync as readFileSync4, renameSync as renameSync4, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
37525
37657
  import { homedir as homedir6 } from "node:os";
37526
- import { join as join8 } from "node:path";
37658
+ import { join as join9 } from "node:path";
37527
37659
 
37528
37660
  // ../../node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
37529
37661
  var exports_external = {};
@@ -51367,13 +51499,13 @@ function migrateExperimentalBashBlock(rawConfig, configPath, logger) {
51367
51499
  return movedKeys;
51368
51500
  }
51369
51501
  function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
51370
- if (!existsSync6(configPath)) {
51502
+ if (!existsSync7(configPath)) {
51371
51503
  return { migrated: false, oldKeys: [] };
51372
51504
  }
51373
51505
  let tmpPath = null;
51374
51506
  let oldKeys = [];
51375
51507
  try {
51376
- const content = readFileSync3(configPath, "utf-8");
51508
+ const content = readFileSync4(configPath, "utf-8");
51377
51509
  const rawConfig = import_comment_json.parse(content);
51378
51510
  if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
51379
51511
  return { migrated: false, oldKeys: [] };
@@ -51390,7 +51522,7 @@ function migrateAftConfigFile(configPath, logger = { log: log2, warn: warn2 }) {
51390
51522
  ${serialized}` : serialized;
51391
51523
  tmpPath = `${configPath}.tmp.${process.pid}`;
51392
51524
  writeFileSync3(tmpPath, nextContent, "utf-8");
51393
- renameSync3(tmpPath, configPath);
51525
+ renameSync4(tmpPath, configPath);
51394
51526
  logger.log(`Migrated config at ${configPath}: removed ${oldKeys.join(", ")}`);
51395
51527
  return { migrated: true, oldKeys };
51396
51528
  } catch (err) {
@@ -51410,17 +51542,17 @@ ${serialized}` : serialized;
51410
51542
  function detectConfigFile(basePath) {
51411
51543
  const jsoncPath = `${basePath}.jsonc`;
51412
51544
  const jsonPath = `${basePath}.json`;
51413
- if (existsSync6(jsoncPath))
51545
+ if (existsSync7(jsoncPath))
51414
51546
  return { format: "jsonc", path: jsoncPath };
51415
- if (existsSync6(jsonPath))
51547
+ if (existsSync7(jsonPath))
51416
51548
  return { format: "json", path: jsonPath };
51417
51549
  return { format: "none", path: jsonPath };
51418
51550
  }
51419
51551
  function loadConfigFromPath(configPath) {
51420
51552
  try {
51421
- if (!existsSync6(configPath))
51553
+ if (!existsSync7(configPath))
51422
51554
  return null;
51423
- const content = readFileSync3(configPath, "utf-8");
51555
+ const content = readFileSync4(configPath, "utf-8");
51424
51556
  const rawConfig = import_comment_json.parse(content);
51425
51557
  if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
51426
51558
  warn2(`Config validation error in ${configPath}: root must be an object`);
@@ -51591,15 +51723,15 @@ function mergeConfigs(base, override) {
51591
51723
  };
51592
51724
  }
51593
51725
  function getGlobalPiDir() {
51594
- return join8(homedir6(), ".pi", "agent");
51726
+ return join9(homedir6(), ".pi", "agent");
51595
51727
  }
51596
51728
  function loadAftConfig(projectDirectory) {
51597
- const userBasePath = join8(getGlobalPiDir(), "aft");
51729
+ const userBasePath = join9(getGlobalPiDir(), "aft");
51598
51730
  migrateAftConfigFile(`${userBasePath}.jsonc`);
51599
51731
  migrateAftConfigFile(`${userBasePath}.json`);
51600
51732
  const userDetected = detectConfigFile(userBasePath);
51601
51733
  const userConfigPath = userDetected.format !== "none" ? userDetected.path : `${userBasePath}.json`;
51602
- const projectBasePath = join8(projectDirectory, ".pi", "aft");
51734
+ const projectBasePath = join9(projectDirectory, ".pi", "aft");
51603
51735
  migrateAftConfigFile(`${projectBasePath}.jsonc`);
51604
51736
  migrateAftConfigFile(`${projectBasePath}.json`);
51605
51737
  const projectDetected = detectConfigFile(projectBasePath);
@@ -51626,49 +51758,49 @@ function loadAftConfig(projectDirectory) {
51626
51758
  // src/lsp-auto-install.ts
51627
51759
  import { spawn as spawn2 } from "node:child_process";
51628
51760
  import { createHash as createHash4 } from "node:crypto";
51629
- import { createReadStream, mkdirSync as mkdirSync7, readFileSync as readFileSync6, renameSync as renameSync4, rmSync as rmSync3, statSync as statSync4 } from "node:fs";
51630
- import { join as join11 } from "node:path";
51761
+ import { createReadStream, mkdirSync as mkdirSync8, readFileSync as readFileSync7, renameSync as renameSync5, rmSync as rmSync3, statSync as statSync4 } from "node:fs";
51762
+ import { join as join12 } from "node:path";
51631
51763
 
51632
51764
  // src/lsp-cache.ts
51633
51765
  import {
51634
51766
  closeSync as closeSync3,
51635
- mkdirSync as mkdirSync6,
51767
+ mkdirSync as mkdirSync7,
51636
51768
  openSync as openSync3,
51637
- readFileSync as readFileSync4,
51769
+ readFileSync as readFileSync5,
51638
51770
  statSync as statSync3,
51639
51771
  unlinkSync as unlinkSync5,
51640
51772
  writeFileSync as writeFileSync4
51641
51773
  } from "node:fs";
51642
51774
  import { homedir as homedir7 } from "node:os";
51643
- import { join as join9 } from "node:path";
51775
+ import { join as join10 } from "node:path";
51644
51776
  function aftCacheBase() {
51645
51777
  const override = process.env.AFT_CACHE_DIR;
51646
51778
  if (override && override.length > 0)
51647
51779
  return override;
51648
51780
  if (process.platform === "win32") {
51649
51781
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
51650
- const base2 = localAppData || join9(homedir7(), "AppData", "Local");
51651
- return join9(base2, "aft");
51782
+ const base2 = localAppData || join10(homedir7(), "AppData", "Local");
51783
+ return join10(base2, "aft");
51652
51784
  }
51653
- const base = process.env.XDG_CACHE_HOME || join9(homedir7(), ".cache");
51654
- return join9(base, "aft");
51785
+ const base = process.env.XDG_CACHE_HOME || join10(homedir7(), ".cache");
51786
+ return join10(base, "aft");
51655
51787
  }
51656
51788
  function lspCacheRoot() {
51657
- return join9(aftCacheBase(), "lsp-packages");
51789
+ return join10(aftCacheBase(), "lsp-packages");
51658
51790
  }
51659
51791
  function lspPackageDir(npmPackage) {
51660
- return join9(lspCacheRoot(), encodeURIComponent(npmPackage));
51792
+ return join10(lspCacheRoot(), encodeURIComponent(npmPackage));
51661
51793
  }
51662
51794
  function lspBinaryPath(npmPackage, binary) {
51663
- return join9(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
51795
+ return join10(lspPackageDir(npmPackage), "node_modules", ".bin", binary);
51664
51796
  }
51665
51797
  function lspBinDir(npmPackage) {
51666
- return join9(lspPackageDir(npmPackage), "node_modules", ".bin");
51798
+ return join10(lspPackageDir(npmPackage), "node_modules", ".bin");
51667
51799
  }
51668
51800
  function isInstalled(npmPackage, binary) {
51669
51801
  for (const candidate of lspBinaryCandidates(binary)) {
51670
51802
  try {
51671
- if (statSync3(join9(lspBinDir(npmPackage), candidate)).isFile())
51803
+ if (statSync3(join10(lspBinDir(npmPackage), candidate)).isFile())
51672
51804
  return true;
51673
51805
  } catch {}
51674
51806
  }
@@ -51682,23 +51814,23 @@ function lspBinaryCandidates(binary) {
51682
51814
  var INSTALLED_META_FILE = ".aft-installed";
51683
51815
  function writeInstalledMetaIn(installDir, version2, sha256) {
51684
51816
  try {
51685
- mkdirSync6(installDir, { recursive: true });
51817
+ mkdirSync7(installDir, { recursive: true });
51686
51818
  const meta3 = {
51687
51819
  version: version2,
51688
51820
  installedAt: new Date().toISOString(),
51689
51821
  ...sha256 ? { sha256 } : {}
51690
51822
  };
51691
- writeFileSync4(join9(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
51823
+ writeFileSync4(join10(installDir, INSTALLED_META_FILE), JSON.stringify(meta3), "utf8");
51692
51824
  } catch (err) {
51693
51825
  log2(`[lsp-cache] failed to write installed-meta in ${installDir}: ${err}`);
51694
51826
  }
51695
51827
  }
51696
51828
  function readInstalledMetaIn(installDir) {
51697
- const path2 = join9(installDir, INSTALLED_META_FILE);
51829
+ const path2 = join10(installDir, INSTALLED_META_FILE);
51698
51830
  try {
51699
51831
  if (!statSync3(path2).isFile())
51700
51832
  return null;
51701
- const raw = readFileSync4(path2, "utf8");
51833
+ const raw = readFileSync5(path2, "utf8");
51702
51834
  const parsed = JSON.parse(raw);
51703
51835
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
51704
51836
  return null;
@@ -51718,11 +51850,11 @@ function readInstalledMeta(packageKey) {
51718
51850
  return readInstalledMetaIn(lspPackageDir(packageKey));
51719
51851
  }
51720
51852
  function lockPath(npmPackage) {
51721
- return join9(lspPackageDir(npmPackage), ".aft-installing");
51853
+ return join10(lspPackageDir(npmPackage), ".aft-installing");
51722
51854
  }
51723
51855
  var STALE_LOCK_MS2 = 30 * 60 * 1000;
51724
51856
  function acquireInstallLock(lockKey) {
51725
- mkdirSync6(lspPackageDir(lockKey), { recursive: true });
51857
+ mkdirSync7(lspPackageDir(lockKey), { recursive: true });
51726
51858
  const lock = lockPath(lockKey);
51727
51859
  const tryClaim = () => {
51728
51860
  try {
@@ -51748,7 +51880,7 @@ ${new Date().toISOString()}
51748
51880
  let owningPid = null;
51749
51881
  let lockMtimeMs = 0;
51750
51882
  try {
51751
- const raw = readFileSync4(lock, "utf8");
51883
+ const raw = readFileSync5(lock, "utf8");
51752
51884
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
51753
51885
  const parsed = Number.parseInt(firstLine, 10);
51754
51886
  if (Number.isFinite(parsed) && parsed > 0)
@@ -51786,7 +51918,7 @@ function releaseInstallLock(lockKey) {
51786
51918
  try {
51787
51919
  let owningPid = null;
51788
51920
  try {
51789
- const raw = readFileSync4(lock, "utf8");
51921
+ const raw = readFileSync5(lock, "utf8");
51790
51922
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
51791
51923
  const parsed = Number.parseInt(firstLine, 10);
51792
51924
  if (Number.isFinite(parsed) && parsed > 0)
@@ -51825,9 +51957,9 @@ async function withInstallLock(lockKey, task) {
51825
51957
  }
51826
51958
  var VERSION_CHECK_FILE = ".aft-version-check";
51827
51959
  function readVersionCheck(npmPackage) {
51828
- const file2 = join9(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
51960
+ const file2 = join10(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
51829
51961
  try {
51830
- const raw = readFileSync4(file2, "utf8");
51962
+ const raw = readFileSync5(file2, "utf8");
51831
51963
  const parsed = JSON.parse(raw);
51832
51964
  if (typeof parsed.last_checked === "string") {
51833
51965
  return {
@@ -51841,8 +51973,8 @@ function readVersionCheck(npmPackage) {
51841
51973
  }
51842
51974
  }
51843
51975
  function writeVersionCheck(npmPackage, latest) {
51844
- mkdirSync6(lspPackageDir(npmPackage), { recursive: true });
51845
- const file2 = join9(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
51976
+ mkdirSync7(lspPackageDir(npmPackage), { recursive: true });
51977
+ const file2 = join10(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
51846
51978
  const record2 = {
51847
51979
  last_checked: new Date().toISOString(),
51848
51980
  latest_eligible: latest
@@ -52004,8 +52136,8 @@ var NPM_LSP_TABLE = [
52004
52136
  ];
52005
52137
 
52006
52138
  // src/lsp-project-relevance.ts
52007
- import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync5 } from "node:fs";
52008
- import { join as join10 } from "node:path";
52139
+ import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync6 } from "node:fs";
52140
+ import { join as join11 } from "node:path";
52009
52141
  var MAX_WALK_DIRS = 200;
52010
52142
  var MAX_WALK_DEPTH = 4;
52011
52143
  var NOISE_DIRS = new Set([
@@ -52022,7 +52154,7 @@ function hasRootMarker(projectRoot, rootMarkers) {
52022
52154
  if (!rootMarkers)
52023
52155
  return false;
52024
52156
  for (const marker of rootMarkers) {
52025
- if (existsSync7(join10(projectRoot, marker)))
52157
+ if (existsSync8(join11(projectRoot, marker)))
52026
52158
  return true;
52027
52159
  }
52028
52160
  return false;
@@ -52046,7 +52178,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
52046
52178
  }
52047
52179
  function readPackageJson(projectRoot) {
52048
52180
  try {
52049
- const raw = readFileSync5(join10(projectRoot, "package.json"), "utf8");
52181
+ const raw = readFileSync6(join11(projectRoot, "package.json"), "utf8");
52050
52182
  const parsed = JSON.parse(raw);
52051
52183
  if (typeof parsed !== "object" || parsed === null)
52052
52184
  return null;
@@ -52076,7 +52208,7 @@ function relevantExtensionsInProject(projectRoot, extToServer) {
52076
52208
  for (const entry of entries) {
52077
52209
  if (entry.isDirectory()) {
52078
52210
  if (current.depth < MAX_WALK_DEPTH && !NOISE_DIRS.has(entry.name.toLowerCase())) {
52079
- queue.push({ dir: join10(current.dir, entry.name), depth: current.depth + 1 });
52211
+ queue.push({ dir: join11(current.dir, entry.name), depth: current.depth + 1 });
52080
52212
  }
52081
52213
  continue;
52082
52214
  }
@@ -52373,16 +52505,16 @@ function installedBinaryPath(spec) {
52373
52505
  return null;
52374
52506
  }
52375
52507
  function sha256OfFileSync(path2) {
52376
- return createHash4("sha256").update(readFileSync6(path2)).digest("hex");
52508
+ return createHash4("sha256").update(readFileSync7(path2)).digest("hex");
52377
52509
  }
52378
52510
  function quarantineCachedNpmInstall(spec, reason) {
52379
52511
  const packageDir = lspPackageDir(spec.npm);
52380
- const dest = join11(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
52512
+ const dest = join12(packageDir, "..", ".quarantine", encodeURIComponent(spec.npm), `${Date.now()}`);
52381
52513
  warn2(`[lsp] tofu_mismatch ${spec.npm}: ${reason}; quarantining ${packageDir} -> ${dest}`);
52382
52514
  try {
52383
- mkdirSync7(join11(dest, ".."), { recursive: true });
52515
+ mkdirSync8(join12(dest, ".."), { recursive: true });
52384
52516
  rmSync3(dest, { recursive: true, force: true });
52385
- renameSync4(packageDir, dest);
52517
+ renameSync5(packageDir, dest);
52386
52518
  } catch (err) {
52387
52519
  warn2(`[lsp] tofu_mismatch ${spec.npm}: failed to quarantine cache entry: ${err}`);
52388
52520
  }
@@ -52429,7 +52561,6 @@ function runAutoInstall(projectRoot, config2, fetchImpl2 = fetch) {
52429
52561
  continue;
52430
52562
  }
52431
52563
  installsStarted += 1;
52432
- installingBinaries.push(spec.binary);
52433
52564
  const controller = new AbortController;
52434
52565
  const promise2 = ensureServerInstalled(spec, config2, fetchImpl2, controller.signal).then((outcome) => {
52435
52566
  if (!outcome.started)
@@ -52458,25 +52589,25 @@ function runAutoInstall(projectRoot, config2, fetchImpl2 = fetch) {
52458
52589
 
52459
52590
  // src/lsp-github-install.ts
52460
52591
  import { execFileSync as execFileSync2 } from "node:child_process";
52461
- import { createHash as createHash5, randomBytes } from "node:crypto";
52592
+ import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
52462
52593
  import {
52463
52594
  copyFileSync as copyFileSync3,
52464
52595
  createReadStream as createReadStream2,
52465
52596
  createWriteStream as createWriteStream3,
52466
- existsSync as existsSync8,
52597
+ existsSync as existsSync9,
52467
52598
  lstatSync as lstatSync2,
52468
- mkdirSync as mkdirSync8,
52599
+ mkdirSync as mkdirSync9,
52469
52600
  readdirSync as readdirSync4,
52470
- readFileSync as readFileSync7,
52601
+ readFileSync as readFileSync8,
52471
52602
  readlinkSync as readlinkSync2,
52472
52603
  realpathSync as realpathSync3,
52473
- renameSync as renameSync5,
52604
+ renameSync as renameSync6,
52474
52605
  rmSync as rmSync4,
52475
52606
  statSync as statSync5,
52476
52607
  unlinkSync as unlinkSync6,
52477
52608
  writeFileSync as writeFileSync5
52478
52609
  } from "node:fs";
52479
- import { dirname as dirname3, join as join12, relative as relative2, resolve as resolve2 } from "node:path";
52610
+ import { dirname as dirname4, join as join13, relative as relative2, resolve as resolve2 } from "node:path";
52480
52611
  import { Readable as Readable3 } from "node:stream";
52481
52612
  import { pipeline as pipeline3 } from "node:stream/promises";
52482
52613
 
@@ -52566,26 +52697,26 @@ function detectHostPlatform() {
52566
52697
 
52567
52698
  // src/lsp-github-install.ts
52568
52699
  function ghCacheRoot() {
52569
- return join12(aftCacheBase(), "lsp-binaries");
52700
+ return join13(aftCacheBase(), "lsp-binaries");
52570
52701
  }
52571
52702
  function ghPackageDir(spec) {
52572
- return join12(ghCacheRoot(), spec.id);
52703
+ return join13(ghCacheRoot(), spec.id);
52573
52704
  }
52574
52705
  function ghBinDir(spec) {
52575
- return join12(ghPackageDir(spec), "bin");
52706
+ return join13(ghPackageDir(spec), "bin");
52576
52707
  }
52577
52708
  function ghExtractDir(spec) {
52578
- return join12(ghPackageDir(spec), "extracted");
52709
+ return join13(ghPackageDir(spec), "extracted");
52579
52710
  }
52580
52711
  var INSTALLED_META_FILE2 = ".aft-installed";
52581
52712
  function ghBinaryPath(spec, platform) {
52582
52713
  const ext = platform === "win32" ? ".exe" : "";
52583
- return join12(ghBinDir(spec), `${spec.binary}${ext}`);
52714
+ return join13(ghBinDir(spec), `${spec.binary}${ext}`);
52584
52715
  }
52585
52716
  function isGithubInstalled(spec, platform) {
52586
52717
  for (const candidate of ghBinaryCandidates(spec, platform)) {
52587
52718
  try {
52588
- if (statSync5(join12(ghBinDir(spec), candidate)).isFile())
52719
+ if (statSync5(join13(ghBinDir(spec), candidate)).isFile())
52589
52720
  return true;
52590
52721
  } catch {}
52591
52722
  }
@@ -52598,10 +52729,10 @@ function ghBinaryCandidates(spec, platform) {
52598
52729
  }
52599
52730
  function readGithubInstalledMetaIn(installDir) {
52600
52731
  try {
52601
- const path2 = join12(installDir, INSTALLED_META_FILE2);
52732
+ const path2 = join13(installDir, INSTALLED_META_FILE2);
52602
52733
  if (!statSync5(path2).isFile())
52603
52734
  return null;
52604
- const parsed = JSON.parse(readFileSync7(path2, "utf8"));
52735
+ const parsed = JSON.parse(readFileSync8(path2, "utf8"));
52605
52736
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
52606
52737
  return null;
52607
52738
  return {
@@ -52617,7 +52748,7 @@ function readGithubInstalledMetaIn(installDir) {
52617
52748
  }
52618
52749
  function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveSha256) {
52619
52750
  try {
52620
- mkdirSync8(installDir, { recursive: true });
52751
+ mkdirSync9(installDir, { recursive: true });
52621
52752
  const meta3 = {
52622
52753
  version: version2,
52623
52754
  installedAt: new Date().toISOString(),
@@ -52625,7 +52756,7 @@ function writeGithubInstalledMetaIn(installDir, version2, binarySha256, archiveS
52625
52756
  binarySha256,
52626
52757
  ...archiveSha256 ? { archiveSha256 } : {}
52627
52758
  };
52628
- writeFileSync5(join12(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
52759
+ writeFileSync5(join13(installDir, INSTALLED_META_FILE2), JSON.stringify(meta3), "utf8");
52629
52760
  } catch (err) {
52630
52761
  warn2(`[lsp] failed to write github installed metadata in ${installDir}: ${err}`);
52631
52762
  }
@@ -52642,7 +52773,7 @@ function sha256OfFile(path2) {
52642
52773
  });
52643
52774
  }
52644
52775
  function sha256OfFileSync2(path2) {
52645
- return createHash5("sha256").update(readFileSync7(path2)).digest("hex");
52776
+ return createHash5("sha256").update(readFileSync8(path2)).digest("hex");
52646
52777
  }
52647
52778
  async function fetchReleaseByTag(githubRepo, tag, fetchImpl2, signal) {
52648
52779
  const candidates = [];
@@ -52818,7 +52949,7 @@ async function downloadFile(url2, destPath, fetchImpl2, assetSize, signal) {
52818
52949
  if (Number.isFinite(advertised) && advertised > MAX_DOWNLOAD_BYTES3) {
52819
52950
  throw new Error(`Content-Length ${advertised} exceeds max ${MAX_DOWNLOAD_BYTES3}`);
52820
52951
  }
52821
- mkdirSync8(dirname3(destPath), { recursive: true });
52952
+ mkdirSync9(dirname4(destPath), { recursive: true });
52822
52953
  let bytesWritten = 0;
52823
52954
  const guard = new TransformStream({
52824
52955
  transform(chunk, controller) {
@@ -52874,7 +53005,7 @@ function validateExtraction(stagingRoot) {
52874
53005
  throw new Error(`failed to read staging dir ${dir}: ${err}`);
52875
53006
  }
52876
53007
  for (const entry of entries) {
52877
- const full = join12(dir, entry);
53008
+ const full = join13(dir, entry);
52878
53009
  let lst;
52879
53010
  try {
52880
53011
  lst = lstatSync2(full);
@@ -52939,12 +53070,12 @@ function precheckArchiveContents(archivePath, archiveType) {
52939
53070
  }
52940
53071
  }
52941
53072
  function extractArchiveSafely(archivePath, destDir, archiveType) {
52942
- const suffix = randomBytes(8).toString("hex");
53073
+ const suffix = randomBytes2(8).toString("hex");
52943
53074
  const stagingDir = `${destDir}.staging-${suffix}`;
52944
53075
  try {
52945
53076
  rmSync4(stagingDir, { recursive: true, force: true });
52946
53077
  } catch {}
52947
- mkdirSync8(stagingDir, { recursive: true });
53078
+ mkdirSync9(stagingDir, { recursive: true });
52948
53079
  try {
52949
53080
  precheckArchiveContents(archivePath, archiveType);
52950
53081
  runPlatformExtractor(archivePath, stagingDir, archiveType);
@@ -52952,7 +53083,7 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
52952
53083
  try {
52953
53084
  rmSync4(destDir, { recursive: true, force: true });
52954
53085
  } catch {}
52955
- renameSync5(stagingDir, destDir);
53086
+ renameSync6(stagingDir, destDir);
52956
53087
  } catch (err) {
52957
53088
  try {
52958
53089
  rmSync4(stagingDir, { recursive: true, force: true });
@@ -52962,12 +53093,12 @@ function extractArchiveSafely(archivePath, destDir, archiveType) {
52962
53093
  }
52963
53094
  function quarantineCachedGithubInstall(spec, reason) {
52964
53095
  const packageDir = ghPackageDir(spec);
52965
- const dest = join12(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
53096
+ const dest = join13(ghCacheRoot(), ".quarantine", encodeURIComponent(spec.id), `${Date.now()}`);
52966
53097
  warn2(`[lsp] tofu_mismatch ${spec.id}: ${reason}; quarantining ${packageDir} -> ${dest}`);
52967
53098
  try {
52968
- mkdirSync8(dirname3(dest), { recursive: true });
53099
+ mkdirSync9(dirname4(dest), { recursive: true });
52969
53100
  rmSync4(dest, { recursive: true, force: true });
52970
- renameSync5(packageDir, dest);
53101
+ renameSync6(packageDir, dest);
52971
53102
  } catch (err) {
52972
53103
  warn2(`[lsp] tofu_mismatch ${spec.id}: failed to quarantine cache entry: ${err}`);
52973
53104
  }
@@ -52975,7 +53106,7 @@ function quarantineCachedGithubInstall(spec, reason) {
52975
53106
  function validateCachedGithubInstall(spec, platform) {
52976
53107
  const packageDir = ghPackageDir(spec);
52977
53108
  const meta3 = readGithubInstalledMetaIn(packageDir);
52978
- const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join12(ghBinDir(spec), candidate)).find((candidate) => {
53109
+ const binaryPath = ghBinaryCandidates(spec, platform).map((candidate) => join13(ghBinDir(spec), candidate)).find((candidate) => {
52979
53110
  try {
52980
53111
  return statSync5(candidate).isFile();
52981
53112
  } catch {
@@ -53053,7 +53184,7 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl2,
53053
53184
  }
53054
53185
  const pkgDir = ghPackageDir(spec);
53055
53186
  const extractDir = ghExtractDir(spec);
53056
- const archivePath = join12(pkgDir, expected.name);
53187
+ const archivePath = join13(pkgDir, expected.name);
53057
53188
  log2(`[lsp] downloading ${spec.id} ${tag} → ${matchingAsset.url}`);
53058
53189
  try {
53059
53190
  await downloadFile(matchingAsset.url, archivePath, fetchImpl2, matchingAsset.size, signal);
@@ -53093,13 +53224,13 @@ async function downloadAndInstall(spec, tag, assets, platform, arch, fetchImpl2,
53093
53224
  unlinkSync6(archivePath);
53094
53225
  } catch {}
53095
53226
  }
53096
- const innerBinaryPath = join12(extractDir, spec.binaryPathInArchive(platform, arch, version2));
53097
- if (!existsSync8(innerBinaryPath)) {
53227
+ const innerBinaryPath = join13(extractDir, spec.binaryPathInArchive(platform, arch, version2));
53228
+ if (!existsSync9(innerBinaryPath)) {
53098
53229
  error2(`[lsp] ${spec.id}: extracted binary not found at ${innerBinaryPath}`);
53099
53230
  return null;
53100
53231
  }
53101
53232
  const targetBinary = ghBinaryPath(spec, platform);
53102
- mkdirSync8(dirname3(targetBinary), { recursive: true });
53233
+ mkdirSync9(dirname4(targetBinary), { recursive: true });
53103
53234
  try {
53104
53235
  copyFileSync3(innerBinaryPath, targetBinary);
53105
53236
  if (platform !== "win32") {
@@ -53178,7 +53309,7 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl2 = fetch) {
53178
53309
  if (!host) {
53179
53310
  for (const spec of GITHUB_LSP_TABLE) {
53180
53311
  try {
53181
- if (existsSync8(ghBinDir(spec))) {
53312
+ if (existsSync9(ghBinDir(spec))) {
53182
53313
  cachedBinDirs.push(ghBinDir(spec));
53183
53314
  }
53184
53315
  } catch {}
@@ -53208,7 +53339,6 @@ function runGithubAutoInstall(relevantServers, config2, fetchImpl2 = fetch) {
53208
53339
  continue;
53209
53340
  }
53210
53341
  installsStarted += 1;
53211
- installingBinaries.push(spec.binary);
53212
53342
  const controller = new AbortController;
53213
53343
  const promise2 = ensureGithubInstalled(spec, config2, fetchImpl2, host.platform, host.arch, controller.signal).then((outcome) => {
53214
53344
  if (!outcome.started)
@@ -53276,8 +53406,8 @@ function discoverRelevantGithubServers(projectRoot) {
53276
53406
  }
53277
53407
 
53278
53408
  // src/notifications.ts
53279
- import { existsSync as existsSync9, mkdirSync as mkdirSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "node:fs";
53280
- import { join as join13 } from "node:path";
53409
+ import { existsSync as existsSync10, mkdirSync as mkdirSync10, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "node:fs";
53410
+ import { dirname as dirname5 } from "node:path";
53281
53411
  var WARNING_MARKER = "\uD83D\uDD27 AFT: ⚠️";
53282
53412
  var FEATURE_MARKER = "\uD83D\uDD27 AFT: ✨";
53283
53413
  function sendIgnoredMessage(client, sessionId, text) {
@@ -53370,10 +53500,10 @@ async function deliverConfigureWarnings(opts, warnings) {
53370
53500
  }
53371
53501
  }
53372
53502
  function sendFeatureAnnouncement(version2, features, footer, storageDir) {
53373
- const versionFile = join13(storageDir, "last_announced_version");
53503
+ const versionFile = repairRootScopedStorageFile(storageDir, "pi", "last_announced_version");
53374
53504
  try {
53375
- if (existsSync9(versionFile)) {
53376
- const lastVersion = readFileSync8(versionFile, "utf-8").trim();
53505
+ if (existsSync10(versionFile)) {
53506
+ const lastVersion = readFileSync9(versionFile, "utf-8").trim();
53377
53507
  if (lastVersion === version2)
53378
53508
  return;
53379
53509
  }
@@ -53388,7 +53518,7 @@ function sendFeatureAnnouncement(version2, features, footer, storageDir) {
53388
53518
  log2(sections.join(`
53389
53519
  `));
53390
53520
  try {
53391
- mkdirSync9(storageDir, { recursive: true });
53521
+ mkdirSync10(dirname5(versionFile), { recursive: true });
53392
53522
  writeFileSync6(versionFile, version2);
53393
53523
  } catch {}
53394
53524
  }
@@ -54304,7 +54434,7 @@ async function bashStatusSnapshot(bridge, extCtx, taskId, outputMode, options) {
54304
54434
  async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFor, waitForExit, effectiveWaitMs) {
54305
54435
  const startedAt = Date.now();
54306
54436
  const deadline = startedAt + effectiveWaitMs;
54307
- let spillCursor = 0;
54437
+ let spillCursor = { output: 0, stderr: 0, combined: 0 };
54308
54438
  let scanText = "";
54309
54439
  let scanBaseOffset = 0;
54310
54440
  const bridgeOptions = {
@@ -54318,12 +54448,7 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
54318
54448
  try {
54319
54449
  while (true) {
54320
54450
  const data = await bashStatusSnapshot(bridge, extCtx, taskId, outputMode, bridgeOptions);
54321
- if (waitForExit && isTerminalStatus(data.status)) {
54322
- sawTerminal = true;
54323
- consumeBgCompletion(sessionId, taskId);
54324
- await markBgCompletionDelivered({ ctx, directory: extCtx.cwd, sessionID: sessionId }, taskId);
54325
- return withWaited(data, { reason: "exited", elapsed_ms: Date.now() - startedAt });
54326
- }
54451
+ const terminal = isTerminalStatus(data.status);
54327
54452
  if (waitFor) {
54328
54453
  const scan = await readNewTaskOutput(extCtx, taskId, data, spillCursor);
54329
54454
  if (scan) {
@@ -54333,6 +54458,11 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
54333
54458
  scanText += scan.text;
54334
54459
  const match = findWaitMatch(scanText, waitFor);
54335
54460
  if (match) {
54461
+ if (waitForExit && terminal) {
54462
+ sawTerminal = true;
54463
+ consumeBgCompletion(sessionId, taskId);
54464
+ await markBgCompletionDelivered({ ctx, directory: extCtx.cwd, sessionID: sessionId }, taskId);
54465
+ }
54336
54466
  return withWaited(data, {
54337
54467
  reason: "matched",
54338
54468
  elapsed_ms: Date.now() - startedAt,
@@ -54341,9 +54471,14 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
54341
54471
  });
54342
54472
  }
54343
54473
  }
54344
- if (isTerminalStatus(data.status)) {
54345
- return withWaited(data, { reason: "exited", elapsed_ms: Date.now() - startedAt });
54474
+ }
54475
+ if (terminal) {
54476
+ if (waitForExit) {
54477
+ sawTerminal = true;
54478
+ consumeBgCompletion(sessionId, taskId);
54479
+ await markBgCompletionDelivered({ ctx, directory: extCtx.cwd, sessionID: sessionId }, taskId);
54346
54480
  }
54481
+ return withWaited(data, { reason: "exited", elapsed_ms: Date.now() - startedAt });
54347
54482
  }
54348
54483
  if (Date.now() >= deadline) {
54349
54484
  return withWaited(data, { reason: "timeout", elapsed_ms: Date.now() - startedAt });
@@ -54353,21 +54488,45 @@ async function waitForBashStatus(ctx, bridge, extCtx, taskId, outputMode, waitFo
54353
54488
  } finally {
54354
54489
  if (waitForExit && !sawTerminal)
54355
54490
  unmarkTaskWaiting(sessionId, taskId);
54491
+ if (waitFor) {
54492
+ await disposePtyTerminal(watchPtyCacheKey(extCtx, taskId));
54493
+ }
54356
54494
  }
54357
54495
  }
54358
54496
  async function readNewTaskOutput(extCtx, taskId, data, cursor) {
54359
54497
  const outputPath = data.output_path;
54360
- if (!outputPath)
54361
- return;
54362
54498
  if (data.mode === "pty") {
54499
+ if (!outputPath)
54500
+ return;
54363
54501
  const { rows, cols } = ptyDimensions(data);
54364
- const state = await getOrCreatePtyTerminal(ptyCacheKey(extCtx, taskId), outputPath, rows, cols);
54502
+ const state = await getOrCreatePtyTerminal(watchPtyCacheKey(extCtx, taskId), outputPath, rows, cols);
54365
54503
  const baseOffset = state.offset;
54366
- const bytes2 = await readPtyBytes(state);
54367
- return { text: bytes2.toString("utf8"), baseOffset, nextCursor: state.offset };
54504
+ const bytes = await readPtyBytes(state);
54505
+ if (bytes.length === 0)
54506
+ return;
54507
+ return {
54508
+ text: bytes.toString("utf8"),
54509
+ baseOffset,
54510
+ nextCursor: { output: state.offset, stderr: 0, combined: state.offset }
54511
+ };
54368
54512
  }
54369
- const bytes = await readFileBytesFrom(outputPath, cursor);
54370
- return { text: bytes.toString("utf8"), baseOffset: cursor, nextCursor: cursor + bytes.length };
54513
+ const stderrPath = data.stderr_path;
54514
+ if (!outputPath && !stderrPath)
54515
+ return;
54516
+ const stdoutBytes = outputPath ? await readFileBytesFrom(outputPath, cursor.output) : Buffer.alloc(0);
54517
+ const stderrBytes = stderrPath ? await readFileBytesFrom(stderrPath, cursor.stderr) : Buffer.alloc(0);
54518
+ const bytesRead = stdoutBytes.length + stderrBytes.length;
54519
+ if (bytesRead === 0)
54520
+ return;
54521
+ return {
54522
+ text: Buffer.concat([stdoutBytes, stderrBytes]).toString("utf8"),
54523
+ baseOffset: cursor.combined,
54524
+ nextCursor: {
54525
+ output: cursor.output + stdoutBytes.length,
54526
+ stderr: cursor.stderr + stderrBytes.length,
54527
+ combined: cursor.combined + bytesRead
54528
+ }
54529
+ };
54371
54530
  }
54372
54531
  async function readFileBytesFrom(outputPath, cursor) {
54373
54532
  const handle = await fs3.open(outputPath, "r");
@@ -54479,6 +54638,9 @@ function ptyDimensions(data) {
54479
54638
  function ptyCacheKey(extCtx, taskId) {
54480
54639
  return `${extCtx.cwd}::${resolveSessionId(extCtx) ?? "__default__"}::${taskId}`;
54481
54640
  }
54641
+ function watchPtyCacheKey(extCtx, taskId) {
54642
+ return `${ptyCacheKey(extCtx, taskId)}::watch`;
54643
+ }
54482
54644
  function isTerminalStatus(status) {
54483
54645
  return status === "completed" || status === "failed" || status === "killed" || status === "timed_out";
54484
54646
  }
@@ -55434,6 +55596,14 @@ function renderCallTreeNode(node, depth, lines) {
55434
55596
  renderCallTreeNode(child, depth + 1, lines);
55435
55597
  });
55436
55598
  }
55599
+ function depthWarning(response, theme, depthField = "depth_limited", truncatedField = "truncated") {
55600
+ const limited = asBoolean(response[depthField]);
55601
+ const truncated = asNumber(response[truncatedField]) ?? 0;
55602
+ if (!limited && truncated === 0)
55603
+ return "";
55604
+ const detail = truncated > 0 ? `, ${truncated} truncated` : "";
55605
+ return theme.fg("warning", `(depth limited${detail})`);
55606
+ }
55437
55607
  function renderTracePath(path2, index, lines) {
55438
55608
  lines.push(`Path ${index + 1}`);
55439
55609
  asRecords(path2.hops).forEach((hop, hopIndex) => {
@@ -55451,12 +55621,16 @@ function buildNavigateSections(args, payload, theme) {
55451
55621
  if (args.op === "call_tree") {
55452
55622
  const lines = [];
55453
55623
  renderCallTreeNode(response, 0, lines);
55624
+ const warning = depthWarning(response, theme);
55625
+ if (warning)
55626
+ lines.push(warning);
55454
55627
  return lines.length > 0 ? lines : [theme.fg("muted", "No call tree available.")];
55455
55628
  }
55456
55629
  if (args.op === "callers") {
55457
55630
  const groups = asRecords(response.callers);
55631
+ const warning = depthWarning(response, theme);
55458
55632
  const sections2 = [
55459
- `${theme.fg("success", `${asNumber(response.total_callers) ?? 0} caller${(asNumber(response.total_callers) ?? 0) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${groups.length} file group${groups.length === 1 ? "" : "s"}`)}`
55633
+ `${theme.fg("success", `${asNumber(response.total_callers) ?? 0} caller${(asNumber(response.total_callers) ?? 0) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${groups.length} file group${groups.length === 1 ? "" : "s"}`)} ${warning}`.trim()
55460
55634
  ];
55461
55635
  groups.forEach((group) => {
55462
55636
  const file2 = shortenPath(asString(group.file) ?? "(unknown file)");
@@ -55471,8 +55645,9 @@ function buildNavigateSections(args, payload, theme) {
55471
55645
  }
55472
55646
  if (args.op === "trace_to") {
55473
55647
  const paths = asRecords(response.paths);
55648
+ const warning = depthWarning(response, theme, "max_depth_reached", "truncated_paths");
55474
55649
  const sections2 = [
55475
- `${theme.fg("success", `${asNumber(response.total_paths) ?? paths.length} path${(asNumber(response.total_paths) ?? paths.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.entry_points_found) ?? 0} entry point${(asNumber(response.entry_points_found) ?? 0) === 1 ? "" : "s"}`)}`
55650
+ `${theme.fg("success", `${asNumber(response.total_paths) ?? paths.length} path${(asNumber(response.total_paths) ?? paths.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.entry_points_found) ?? 0} entry point${(asNumber(response.entry_points_found) ?? 0) === 1 ? "" : "s"}`)} ${warning}`.trim()
55476
55651
  ];
55477
55652
  if (paths.length === 0)
55478
55653
  sections2.push(theme.fg("muted", "No entry paths found."));
@@ -55486,8 +55661,9 @@ function buildNavigateSections(args, payload, theme) {
55486
55661
  }
55487
55662
  if (args.op === "impact") {
55488
55663
  const callers = asRecords(response.callers);
55664
+ const warning = depthWarning(response, theme);
55489
55665
  const sections2 = [
55490
- `${theme.fg("warning", `${asNumber(response.total_affected) ?? callers.length} affected call site${(asNumber(response.total_affected) ?? callers.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.affected_files) ?? 0} file${(asNumber(response.affected_files) ?? 0) === 1 ? "" : "s"}`)}`
55666
+ `${theme.fg("warning", `${asNumber(response.total_affected) ?? callers.length} affected call site${(asNumber(response.total_affected) ?? callers.length) === 1 ? "" : "s"}`)} ${theme.fg("muted", `${asNumber(response.affected_files) ?? 0} file${(asNumber(response.affected_files) ?? 0) === 1 ? "" : "s"}`)} ${warning}`.trim()
55491
55667
  ];
55492
55668
  if (callers.length === 0)
55493
55669
  sections2.push(theme.fg("muted", "No impacted callers found."));
@@ -56459,6 +56635,10 @@ function shouldPrepareOnnxRuntime(config2) {
56459
56635
  const isFastembedSemanticBackend = (config2.semantic?.backend ?? "fastembed") === "fastembed";
56460
56636
  return config2.semantic_search === true && isFastembedSemanticBackend;
56461
56637
  }
56638
+ function bridgeDirectoryFromCallback(bridge, fallback) {
56639
+ const cwd = bridge?.cwd;
56640
+ return typeof cwd === "string" && cwd.length > 0 ? cwd : fallback;
56641
+ }
56462
56642
  async function handleConfigureWarningsForSession(context) {
56463
56643
  const validWarnings = coerceConfigureWarnings(context.warnings);
56464
56644
  if (!context.sessionId) {
@@ -56675,21 +56855,32 @@ ${lines}
56675
56855
  });
56676
56856
  }, 0);
56677
56857
  },
56678
- onBashCompletion: (completion) => {
56858
+ onBashCompletion: (completion, bridge) => {
56859
+ const directory = bridgeDirectoryFromCallback(bridge, process.cwd());
56679
56860
  handlePushedBgCompletion({
56680
56861
  ctx,
56681
- directory: process.cwd(),
56862
+ directory,
56682
56863
  sessionID: completion.session_id,
56683
56864
  runtime: pi
56684
56865
  }, completion);
56685
56866
  },
56686
- onBashLongRunning: (reminder) => {
56867
+ onBashLongRunning: (reminder, bridge) => {
56868
+ const directory = bridgeDirectoryFromCallback(bridge, process.cwd());
56687
56869
  handlePushedBgLongRunning({
56688
56870
  ctx,
56689
- directory: process.cwd(),
56871
+ directory,
56690
56872
  sessionID: reminder.session_id,
56691
56873
  runtime: pi
56692
56874
  }, reminder);
56875
+ },
56876
+ onBashPatternMatch: (frame, bridge) => {
56877
+ const directory = bridgeDirectoryFromCallback(bridge, process.cwd());
56878
+ handlePushedPatternMatch({
56879
+ ctx,
56880
+ directory,
56881
+ sessionID: frame.session_id,
56882
+ runtime: pi
56883
+ }, frame);
56693
56884
  }
56694
56885
  };
56695
56886
  pool = new BridgePool(binaryPath, poolOptions, configOverrides);
@@ -56786,28 +56977,31 @@ ${lines}
56786
56977
  runtime: pi
56787
56978
  });
56788
56979
  });
56789
- pi.on("session_shutdown", async () => {
56980
+ const unregisterShutdownCleanup = registerShutdownCleanup(async () => {
56790
56981
  try {
56791
56982
  await Promise.allSettled([abortInFlightAutoInstalls(), abortInFlightGithubInstalls()]);
56792
56983
  await disposeAllPtyTerminals();
56793
56984
  await pool.shutdown();
56794
- log2("Bridge pool shut down");
56795
56985
  } catch (err) {
56796
- warn2(`Error during bridge shutdown: ${err instanceof Error ? err.message : String(err)}`);
56986
+ warn2(`Error during process shutdown: ${err instanceof Error ? err.message : String(err)}`);
56797
56987
  }
56798
56988
  });
56799
- registerShutdownCleanup(async () => {
56989
+ pi.on("session_shutdown", async () => {
56800
56990
  try {
56801
56991
  await Promise.allSettled([abortInFlightAutoInstalls(), abortInFlightGithubInstalls()]);
56802
56992
  await disposeAllPtyTerminals();
56803
56993
  await pool.shutdown();
56994
+ log2("Bridge pool shut down");
56804
56995
  } catch (err) {
56805
- warn2(`Error during process shutdown: ${err instanceof Error ? err.message : String(err)}`);
56996
+ warn2(`Error during bridge shutdown: ${err instanceof Error ? err.message : String(err)}`);
56997
+ } finally {
56998
+ unregisterShutdownCleanup();
56806
56999
  }
56807
57000
  });
56808
57001
  log2(`AFT extension ready (surface=${config2.tool_surface ?? "recommended"})`);
56809
57002
  }
56810
57003
  var __test__2 = {
57004
+ bridgeDirectoryFromCallback,
56811
57005
  resolveToolSurface,
56812
57006
  handleConfigureWarningsForSession,
56813
57007
  shouldPrepareOnnxRuntime,