@cortexkit/aft-opencode 0.44.0 → 0.45.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -8233,6 +8233,8 @@ function resolveBashKillTimeout(modelTimeout, foregroundWaitMs) {
8233
8233
  }
8234
8234
  // ../aft-bridge/dist/bridge.js
8235
8235
  import { spawn } from "node:child_process";
8236
+ import { createHash } from "node:crypto";
8237
+ import { readFileSync } from "node:fs";
8236
8238
  import { homedir as homedir2 } from "node:os";
8237
8239
  import { join as join2 } from "node:path";
8238
8240
  import { StringDecoder } from "node:string_decoder";
@@ -8332,6 +8334,22 @@ function bashTaskIdFrom(response) {
8332
8334
  return camelCase;
8333
8335
  return;
8334
8336
  }
8337
+ function hashBinaryOnDisk(binaryPath) {
8338
+ try {
8339
+ return createHash("sha256").update(readFileSync(binaryPath)).digest("hex");
8340
+ } catch {
8341
+ return null;
8342
+ }
8343
+ }
8344
+ var binaryFingerprintReader = hashBinaryOnDisk;
8345
+ function readBinaryFingerprint(binaryPath) {
8346
+ try {
8347
+ const fingerprint = binaryFingerprintReader(binaryPath);
8348
+ return typeof fingerprint === "string" && fingerprint.length > 0 ? fingerprint : null;
8349
+ } catch {
8350
+ return null;
8351
+ }
8352
+ }
8335
8353
  function tagStderrLine(line) {
8336
8354
  return /^\[aft(-\w+)?\] /.test(line) ? line : `[aft] ${line}`;
8337
8355
  }
@@ -8427,6 +8445,9 @@ class BinaryBridge {
8427
8445
  binaryPath;
8428
8446
  cwd;
8429
8447
  process = null;
8448
+ spawnedBinaryFingerprint = null;
8449
+ lastBinaryFingerprintCheckAt = 0;
8450
+ _retiringDueToBinaryChange = false;
8430
8451
  pending = new Map;
8431
8452
  outstandingBackgroundTaskIds = new Set;
8432
8453
  nextId = 1;
@@ -8546,6 +8567,24 @@ class BinaryBridge {
8546
8567
  hasOutstandingBackgroundTasks() {
8547
8568
  return this.outstandingBackgroundTaskIds.size > 0;
8548
8569
  }
8570
+ maybeScheduleRespawnForUpdatedBinary(checkIntervalMs, now = Date.now()) {
8571
+ if (this._shuttingDown || this._retiringDueToBinaryChange || !this.isAlive())
8572
+ return false;
8573
+ if (this.pending.size > 0 || this.outstandingBackgroundTaskIds.size > 0)
8574
+ return false;
8575
+ if (now - this.lastBinaryFingerprintCheckAt < checkIntervalMs)
8576
+ return false;
8577
+ this.lastBinaryFingerprintCheckAt = now;
8578
+ const spawnedFingerprint = this.spawnedBinaryFingerprint;
8579
+ if (!spawnedFingerprint)
8580
+ return false;
8581
+ const currentFingerprint = readBinaryFingerprint(this.binaryPath);
8582
+ if (!currentFingerprint || currentFingerprint === spawnedFingerprint)
8583
+ return false;
8584
+ this._retiringDueToBinaryChange = true;
8585
+ this.logVia(`Binary contents changed on disk for ${this.binaryPath}; retiring this bridge so the next tool call respawns onto the updated binary.`);
8586
+ return true;
8587
+ }
8549
8588
  getCwd() {
8550
8589
  return this.cwd;
8551
8590
  }
@@ -8578,6 +8617,9 @@ class BinaryBridge {
8578
8617
  }
8579
8618
  async sendWithVersionMismatchRetry(command, params, options, canRetryAfterVersionSwap) {
8580
8619
  try {
8620
+ if (this._retiringDueToBinaryChange) {
8621
+ throw new Error(`${this.errorPrefix} Bridge is retiring after the on-disk binary changed; retry to respawn on the updated binary`);
8622
+ }
8581
8623
  if (this._shuttingDown) {
8582
8624
  throw new Error(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
8583
8625
  }
@@ -8776,6 +8818,7 @@ class BinaryBridge {
8776
8818
  }
8777
8819
  async shutdown() {
8778
8820
  this._shuttingDown = true;
8821
+ this.spawnedBinaryFingerprint = null;
8779
8822
  this.clearRestartResetTimer();
8780
8823
  this.configureWarningClients.clear();
8781
8824
  this.rejectAllPending(new Error(`${this.errorPrefix} Bridge shutting down`));
@@ -8829,6 +8872,9 @@ class BinaryBridge {
8829
8872
  async replaceCurrentBinary(newBinaryPath) {
8830
8873
  this.binaryPath = newBinaryPath;
8831
8874
  this.configured = false;
8875
+ this.spawnedBinaryFingerprint = null;
8876
+ this.lastBinaryFingerprintCheckAt = 0;
8877
+ this._retiringDueToBinaryChange = false;
8832
8878
  this.clearRestartResetTimer();
8833
8879
  this.rejectAllPending(new Error(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
8834
8880
  if (!this.process)
@@ -8854,6 +8900,7 @@ class BinaryBridge {
8854
8900
  this.spawnProcess(triggeringSessionId);
8855
8901
  }
8856
8902
  spawnProcess(triggeringSessionId) {
8903
+ this._retiringDueToBinaryChange = false;
8857
8904
  this.lastStatusBar = undefined;
8858
8905
  if (triggeringSessionId) {
8859
8906
  this.sessionLogVia(triggeringSessionId, `Spawning binary: ${this.binaryPath} (cwd: ${this.cwd})`);
@@ -8944,6 +8991,8 @@ class BinaryBridge {
8944
8991
  this.handleCrash();
8945
8992
  });
8946
8993
  this.process = child;
8994
+ this.spawnedBinaryFingerprint = readBinaryFingerprint(this.binaryPath);
8995
+ this.lastBinaryFingerprintCheckAt = Date.now();
8947
8996
  this.stdoutBuffer = "";
8948
8997
  this.stdoutReadOffset = 0;
8949
8998
  this.stderrBuffer = "";
@@ -9122,6 +9171,7 @@ class BinaryBridge {
9122
9171
  }
9123
9172
  handleTimeout(triggeringSessionId) {
9124
9173
  this.consecutiveRequestTimeouts = 0;
9174
+ this.spawnedBinaryFingerprint = null;
9125
9175
  this.rejectAllPending(new Error(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
9126
9176
  this.outstandingBackgroundTaskIds.clear();
9127
9177
  if (this.process) {
@@ -9148,6 +9198,7 @@ class BinaryBridge {
9148
9198
  handleCrash(cause) {
9149
9199
  const proc = this.process;
9150
9200
  this.process = null;
9201
+ this.spawnedBinaryFingerprint = null;
9151
9202
  if (proc && proc.exitCode === null && !proc.killed) {
9152
9203
  proc.kill("SIGKILL");
9153
9204
  }
@@ -9159,6 +9210,10 @@ class BinaryBridge {
9159
9210
  this.errorVia(`Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""}.${tail}`);
9160
9211
  }
9161
9212
  this.rejectAllPending(new Error(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`));
9213
+ if (this._retiringDueToBinaryChange) {
9214
+ this.logVia("Binary exited while retiring after an on-disk update; skipping auto-restart");
9215
+ return;
9216
+ }
9162
9217
  if (this._restartCount < this.maxRestarts) {
9163
9218
  const delay = 100 * 2 ** this._restartCount;
9164
9219
  this._restartCount++;
@@ -9288,13 +9343,13 @@ function isEmptyParam(value) {
9288
9343
  return false;
9289
9344
  }
9290
9345
  // ../aft-bridge/dist/config-tiers.js
9291
- import { existsSync, readFileSync } from "node:fs";
9346
+ import { existsSync, readFileSync as readFileSync2 } from "node:fs";
9292
9347
  import { resolve as resolve2 } from "node:path";
9293
9348
  function readConfigTiers(opts) {
9294
9349
  const tiers = [];
9295
9350
  try {
9296
9351
  if (existsSync(opts.userConfigPath)) {
9297
- const doc = readFileSync(opts.userConfigPath, "utf-8");
9352
+ const doc = readFileSync2(opts.userConfigPath, "utf-8");
9298
9353
  tiers.push({
9299
9354
  tier: "user",
9300
9355
  source: resolve2(opts.userConfigPath),
@@ -9304,7 +9359,7 @@ function readConfigTiers(opts) {
9304
9359
  } catch {}
9305
9360
  try {
9306
9361
  if (existsSync(opts.projectConfigPath)) {
9307
- const doc = readFileSync(opts.projectConfigPath, "utf-8");
9362
+ const doc = readFileSync2(opts.projectConfigPath, "utf-8");
9308
9363
  tiers.push({
9309
9364
  tier: "project",
9310
9365
  source: resolve2(opts.projectConfigPath),
@@ -9322,8 +9377,8 @@ function formatDroppedKeyWarnings(dropped) {
9322
9377
  }
9323
9378
  // ../aft-bridge/dist/downloader.js
9324
9379
  import { spawnSync } from "node:child_process";
9325
- import { createHash, randomUUID } from "node:crypto";
9326
- import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync2, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
9380
+ import { createHash as createHash2, randomUUID } from "node:crypto";
9381
+ import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync3, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
9327
9382
  import { homedir as homedir3 } from "node:os";
9328
9383
  import { join as join3 } from "node:path";
9329
9384
  import { Readable } from "node:stream";
@@ -9467,7 +9522,7 @@ async function downloadBinary(version) {
9467
9522
  warn(`Checksum verification failed: checksums.sha256 found but no entry for ${assetName}. ` + "Binary download aborted for security reasons.");
9468
9523
  return null;
9469
9524
  }
9470
- const hash = createHash("sha256");
9525
+ const hash = createHash2("sha256");
9471
9526
  let bytesWritten = 0;
9472
9527
  const guard = new TransformStream({
9473
9528
  transform(chunk, controller) {
@@ -9551,7 +9606,7 @@ async function acquireDownloadLock(lockPath) {
9551
9606
  closeSync(fd);
9552
9607
  } catch {}
9553
9608
  try {
9554
- if (readFileSync2(lockPath, "utf-8") === owner) {
9609
+ if (readFileSync3(lockPath, "utf-8") === owner) {
9555
9610
  rmSync(lockPath, { force: true });
9556
9611
  }
9557
9612
  } catch {}
@@ -9623,12 +9678,12 @@ function stripJsoncSymbols(value) {
9623
9678
  }
9624
9679
  // ../aft-bridge/dist/migration.js
9625
9680
  import { spawnSync as spawnSync2 } from "node:child_process";
9626
- import { closeSync as closeSync3, existsSync as existsSync5, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync4, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
9681
+ import { closeSync as closeSync3, existsSync as existsSync5, mkdirSync as mkdirSync4, openSync as openSync3, readFileSync as readFileSync5, renameSync as renameSync4, rmSync as rmSync2, statSync as statSync2, unlinkSync as unlinkSync3, writeFileSync as writeFileSync2 } from "node:fs";
9627
9682
  import { homedir as homedir6, tmpdir } from "node:os";
9628
9683
  import { basename, dirname as dirname2, join as join6, resolve as resolve4 } from "node:path";
9629
9684
 
9630
9685
  // ../aft-bridge/dist/paths.js
9631
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync } from "node:fs";
9686
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync } from "node:fs";
9632
9687
  import { homedir as homedir4 } from "node:os";
9633
9688
  import { dirname, isAbsolute as isAbsolute2, join as join4, resolve as resolve3 } from "node:path";
9634
9689
  function homeDir() {
@@ -9702,7 +9757,7 @@ function shouldShowAnnouncement(storageRoot, harness, currentVersion) {
9702
9757
  let lastVersion = "";
9703
9758
  try {
9704
9759
  if (existsSync3(versionFile)) {
9705
- lastVersion = readFileSync3(versionFile, "utf-8").trim();
9760
+ lastVersion = readFileSync4(versionFile, "utf-8").trim();
9706
9761
  }
9707
9762
  } catch {
9708
9763
  return false;
@@ -10099,7 +10154,7 @@ function atomicCopyConfigFile(sourcePath, targetPath) {
10099
10154
  let fd = null;
10100
10155
  try {
10101
10156
  fd = openSync3(tmpPath, "wx", 384);
10102
- writeFileSync2(fd, readFileSync4(sourcePath));
10157
+ writeFileSync2(fd, readFileSync5(sourcePath));
10103
10158
  closeSync3(fd);
10104
10159
  fd = null;
10105
10160
  renameSync4(tmpPath, targetPath);
@@ -10178,7 +10233,7 @@ function markLegacySourcesMovedAside(sources, targetPath, logger) {
10178
10233
  const desiredMarkerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
10179
10234
  const markerPath = nonClobberingSidecarPath(desiredMarkerPath);
10180
10235
  try {
10181
- const original = readFileSync4(source.path, "utf-8");
10236
+ const original = readFileSync5(source.path, "utf-8");
10182
10237
  if (markerPath !== desiredMarkerPath) {
10183
10238
  logger?.warn?.(`Preserving existing legacy AFT marker ${desiredMarkerPath}; writing new marker to ${markerPath}`);
10184
10239
  }
@@ -10247,10 +10302,10 @@ function migrateAftConfigFile(opts) {
10247
10302
  try {
10248
10303
  const sources = existingSources.map((source) => ({
10249
10304
  ...source,
10250
- content: readFileSync4(source.path, "utf-8")
10305
+ content: readFileSync5(source.path, "utf-8")
10251
10306
  }));
10252
10307
  if (existsSync5(opts.targetPath)) {
10253
- const targetContent = readFileSync4(opts.targetPath, "utf-8");
10308
+ const targetContent = readFileSync5(opts.targetPath, "utf-8");
10254
10309
  for (const source of sources) {
10255
10310
  if (fileSemanticsMatch(source.content, targetContent))
10256
10311
  continue;
@@ -10484,8 +10539,8 @@ function isNpmAvailable(deps = defaultDeps()) {
10484
10539
  }
10485
10540
  // ../aft-bridge/dist/onnx-runtime.js
10486
10541
  import { execFileSync } from "node:child_process";
10487
- import { createHash as createHash2 } from "node:crypto";
10488
- import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync5, openSync as openSync4, readdirSync as readdirSync2, readFileSync as readFileSync5, readlinkSync, realpathSync, rmSync as rmSync3, statSync as statSync4, symlinkSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
10542
+ import { createHash as createHash3 } from "node:crypto";
10543
+ import { chmodSync as chmodSync3, closeSync as closeSync4, copyFileSync as copyFileSync3, createWriteStream as createWriteStream2, existsSync as existsSync6, lstatSync, mkdirSync as mkdirSync5, openSync as openSync4, readdirSync as readdirSync2, readFileSync as readFileSync6, readlinkSync, realpathSync, rmSync as rmSync3, statSync as statSync4, symlinkSync, unlinkSync as unlinkSync4, writeFileSync as writeFileSync3 } from "node:fs";
10489
10544
  import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute4, join as join8, relative as relative2, resolve as resolve5, win32 } from "node:path";
10490
10545
  import { Readable as Readable2 } from "node:stream";
10491
10546
  import { pipeline as pipeline2 } from "node:stream/promises";
@@ -11038,7 +11093,7 @@ function readOnnxInstalledMeta(installDir) {
11038
11093
  try {
11039
11094
  if (!statSync4(path2).isFile())
11040
11095
  return null;
11041
- const raw = readFileSync5(path2, "utf8");
11096
+ const raw = readFileSync6(path2, "utf8");
11042
11097
  const parsed = JSON.parse(raw);
11043
11098
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
11044
11099
  return null;
@@ -11053,8 +11108,8 @@ function readOnnxInstalledMeta(installDir) {
11053
11108
  }
11054
11109
  }
11055
11110
  function sha256File(path2) {
11056
- const hash = createHash2("sha256");
11057
- hash.update(readFileSync5(path2));
11111
+ const hash = createHash3("sha256");
11112
+ hash.update(readFileSync6(path2));
11058
11113
  return hash.digest("hex");
11059
11114
  }
11060
11115
  function acquireLock(lockPath) {
@@ -11082,7 +11137,7 @@ ${new Date().toISOString()}
11082
11137
  let owningPid = null;
11083
11138
  let lockMtimeMs = 0;
11084
11139
  try {
11085
- const raw = readFileSync5(lockPath, "utf8");
11140
+ const raw = readFileSync6(lockPath, "utf8");
11086
11141
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
11087
11142
  const parsed = Number.parseInt(firstLine, 10);
11088
11143
  if (Number.isFinite(parsed) && parsed > 0)
@@ -11107,7 +11162,7 @@ function releaseLock(lockPath) {
11107
11162
  try {
11108
11163
  let owningPid = null;
11109
11164
  try {
11110
- const raw = readFileSync5(lockPath, "utf8");
11165
+ const raw = readFileSync6(lockPath, "utf8");
11111
11166
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
11112
11167
  const parsed = Number.parseInt(firstLine, 10);
11113
11168
  if (Number.isFinite(parsed) && parsed > 0)
@@ -11171,7 +11226,7 @@ function isProcessAlive(pid) {
11171
11226
  }
11172
11227
  }
11173
11228
  // ../aft-bridge/dist/project-identity.js
11174
- import { createHash as createHash3 } from "node:crypto";
11229
+ import { createHash as createHash4 } from "node:crypto";
11175
11230
  import { realpathSync as realpathSync2 } from "node:fs";
11176
11231
  import { resolve as resolve6 } from "node:path";
11177
11232
  function canonicalizeProjectRoot(dir) {
@@ -11202,7 +11257,7 @@ function normalizeWindowsRoot(p) {
11202
11257
  return s;
11203
11258
  }
11204
11259
  function projectRootKeyHash(dir) {
11205
- return createHash3("sha256").update(canonicalizeProjectRoot(dir)).digest("hex").slice(0, 16);
11260
+ return createHash4("sha256").update(canonicalizeProjectRoot(dir)).digest("hex").slice(0, 16);
11206
11261
  }
11207
11262
 
11208
11263
  // ../aft-bridge/dist/pool.js
@@ -11286,6 +11341,11 @@ class BridgePool {
11286
11341
  for (const [dir, entry] of this.bridges) {
11287
11342
  if (entry.bridge.hasPendingRequests() || entry.bridge.hasOutstandingBackgroundTasks())
11288
11343
  continue;
11344
+ if (entry.bridge.maybeScheduleRespawnForUpdatedBinary(CLEANUP_INTERVAL_MS, now)) {
11345
+ this.staleBridges.add(entry.bridge);
11346
+ this.bridges.delete(dir);
11347
+ continue;
11348
+ }
11289
11349
  if (now - entry.lastUsed > this.idleTimeoutMs) {
11290
11350
  entry.bridge.shutdown().catch((err) => this.error("cleanup shutdown failed:", err));
11291
11351
  this.bridges.delete(dir);
@@ -11382,10 +11442,11 @@ class BridgePool {
11382
11442
  function normalizeKey(projectRoot) {
11383
11443
  return canonicalizeProjectRoot(projectRoot);
11384
11444
  }
11385
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
11445
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/client.ts
11386
11446
  import { promises as fs2 } from "node:fs";
11447
+ import { debuglog } from "node:util";
11387
11448
 
11388
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/auth.ts
11449
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/auth.ts
11389
11450
  import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
11390
11451
  var NONCE_LEN = 32;
11391
11452
  var MAX_AUTH_MESSAGE_LEN = 4096;
@@ -11449,7 +11510,7 @@ async function authenticateClient(sock, conn, deadlineMs) {
11449
11510
  await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
11450
11511
  }
11451
11512
 
11452
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/connection-file.ts
11513
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/connection-file.ts
11453
11514
  import { promises as fs } from "node:fs";
11454
11515
  var SCHEMA_VERSION = 1;
11455
11516
  var MIN_KEY_LEN = 32;
@@ -11518,7 +11579,7 @@ async function readConnectionFile(path2) {
11518
11579
  return info;
11519
11580
  }
11520
11581
 
11521
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/envelope.ts
11582
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/envelope.ts
11522
11583
  var PROTOCOL_VERSION = 1;
11523
11584
  var HEADER_LEN = 17;
11524
11585
  var FROZEN_PREFIX_LEN = 5;
@@ -11625,7 +11686,7 @@ function encodeFrame(frame) {
11625
11686
  return out;
11626
11687
  }
11627
11688
 
11628
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/socket.ts
11689
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/socket.ts
11629
11690
  import net from "node:net";
11630
11691
 
11631
11692
  class SocketClosedError extends Error {
@@ -11656,6 +11717,9 @@ class SubcSocket {
11656
11717
  buffered = 0;
11657
11718
  waiter = null;
11658
11719
  closedErr = null;
11720
+ bufferedBytes() {
11721
+ return this.buffered;
11722
+ }
11659
11723
  constructor(sock) {
11660
11724
  this.sock = sock;
11661
11725
  sock.on("data", (chunk) => {
@@ -11814,9 +11878,14 @@ class SubcSocket {
11814
11878
  }
11815
11879
  }
11816
11880
 
11817
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
11881
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/client.ts
11882
+ var debug = debuglog("subc-client");
11818
11883
  var DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4;
11819
11884
  var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
11885
+ var TIMEOUT_ARBITRATION_GRACE_MS = 50;
11886
+ var REQUEST_DEADLINE_MARKER = "request_deadline";
11887
+ var DEADLINE_NO_DROP_CODE = "deadline_exceeded_no_drop_observed";
11888
+ var ROUTE_OPEN_RETRY_DEADLINE_MS = 1e4;
11820
11889
  var BODY_READ_TIMEOUT_MS = 30000;
11821
11890
  var EMPTY_BODY = new Uint8Array(0);
11822
11891
  var DEFAULT_MANAGED_TARGET_KIND = "management_surface";
@@ -11860,6 +11929,7 @@ class SubcClient {
11860
11929
  closeStarted = false;
11861
11930
  reconnecting = null;
11862
11931
  generation = 1;
11932
+ readerActive = false;
11863
11933
  constructor(sock, currentConn, opts) {
11864
11934
  this.sock = sock;
11865
11935
  this.currentConn = currentConn;
@@ -11918,7 +11988,7 @@ class SubcClient {
11918
11988
  }
11919
11989
  continue;
11920
11990
  }
11921
- if (err.kind === "outcome_unknown") {
11991
+ if (err.kind === "outcome_unknown" && err.code !== DEADLINE_NO_DROP_CODE) {
11922
11992
  this.scheduleReconnectAfterDrop(err);
11923
11993
  }
11924
11994
  throw err;
@@ -12041,7 +12111,7 @@ class SubcClient {
12041
12111
  timer: null
12042
12112
  };
12043
12113
  pending.timer = setTimeout(() => {
12044
- this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
12114
+ this.arbitrateTimeout(key, pending, channel, corr, ms);
12045
12115
  }, ms);
12046
12116
  this.pending.set(key, pending);
12047
12117
  this.sock.write(encodeFrame(frame), Date.now() + ms).catch((err) => {
@@ -12051,6 +12121,23 @@ class SubcClient {
12051
12121
  });
12052
12122
  });
12053
12123
  }
12124
+ arbitrateTimeout(key, pending, channel, corr, ms) {
12125
+ const settleAsTimeout = () => {
12126
+ this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms), REQUEST_DEADLINE_MARKER));
12127
+ };
12128
+ const graceDeadline = Date.now() + this.opts.timeoutArbitrationGraceMs;
12129
+ const arbitrate = () => {
12130
+ if (this.pending.get(key) !== pending)
12131
+ return;
12132
+ const readerDraining = this.readerActive || this.sock.bufferedBytes() > 0;
12133
+ if (readerDraining && Date.now() < graceDeadline) {
12134
+ setImmediate(arbitrate);
12135
+ return;
12136
+ }
12137
+ settleAsTimeout();
12138
+ };
12139
+ setImmediate(arbitrate);
12140
+ }
12054
12141
  async managedRequest(routeChannel, body, opts) {
12055
12142
  const bytes = body instanceof Uint8Array ? body : this.encode(body);
12056
12143
  const priority = opts.priority ?? 1 /* Interactive */;
@@ -12075,6 +12162,9 @@ class SubcClient {
12075
12162
  if (!handedToSocket) {
12076
12163
  return this.notSentCallError("request bytes were not queued to the subc socket", err);
12077
12164
  }
12165
+ if (err instanceof SubcError && err.code === REQUEST_DEADLINE_MARKER) {
12166
+ return new SubcCallError("outcome_unknown", `managed call deadline exceeded after request bytes were queued to the local socket; no terminal response was observed; outcome unknown${causeMessage(err)}`, DEADLINE_NO_DROP_CODE, err);
12167
+ }
12078
12168
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", err);
12079
12169
  };
12080
12170
  return new Promise((resolve7, reject) => {
@@ -12088,7 +12178,7 @@ class SubcClient {
12088
12178
  classifyFailure
12089
12179
  };
12090
12180
  pending.timer = setTimeout(() => {
12091
- this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
12181
+ this.arbitrateTimeout(key, pending, channel, corr, ms);
12092
12182
  }, ms);
12093
12183
  this.pending.set(key, pending);
12094
12184
  const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
@@ -12133,6 +12223,9 @@ class SubcClient {
12133
12223
  return cached.opening;
12134
12224
  }
12135
12225
  async openCachedRoute(cached) {
12226
+ const routeRetryDeadline = Date.now() + ROUTE_OPEN_RETRY_DEADLINE_MS;
12227
+ let routeRetryDelay = this.opts.reconnectBackoff.baseMs;
12228
+ let routeRetryAttempt = 0;
12136
12229
  for (;; ) {
12137
12230
  if (cached.closed)
12138
12231
  throw this.routeClosedDuringOpen();
@@ -12166,6 +12259,15 @@ class SubcClient {
12166
12259
  }
12167
12260
  continue;
12168
12261
  }
12262
+ if (!this.closeStarted && err instanceof SubcError && isRetryableRouteOpenCode(err.code)) {
12263
+ routeRetryAttempt += 1;
12264
+ if (routeRetryAttempt < this.opts.reconnectBackoff.maxAttempts && Date.now() < routeRetryDeadline) {
12265
+ await this.opts.sleep(routeRetryDelay);
12266
+ routeRetryDelay = Math.min(routeRetryDelay * 2, this.opts.reconnectBackoff.capMs);
12267
+ continue;
12268
+ }
12269
+ throw this.notSentCallError(`route.open failed for module ${cached.moduleId}: ${err.code} (retry budget exhausted)`, err);
12270
+ }
12169
12271
  throw this.terminalCallError(`route.open failed for module ${cached.moduleId}`, err);
12170
12272
  }
12171
12273
  }
@@ -12259,9 +12361,16 @@ class SubcClient {
12259
12361
  try {
12260
12362
  for (;; ) {
12261
12363
  const headerBytes = await sock.readExact(HEADER_LEN, Number.POSITIVE_INFINITY);
12262
- const header = decodeHeader(headerBytes);
12263
- const body = header.len === 0 ? new Uint8Array(0) : await sock.readExact(header.len, Date.now() + BODY_READ_TIMEOUT_MS);
12264
- this.dispatch({ header, body });
12364
+ this.readerActive = true;
12365
+ try {
12366
+ const header = decodeHeader(headerBytes);
12367
+ const body = header.len === 0 ? new Uint8Array(0) : await sock.readExact(header.len, Date.now() + BODY_READ_TIMEOUT_MS);
12368
+ if (this.sock === sock && this.generation === generation) {
12369
+ this.dispatch({ header, body });
12370
+ }
12371
+ } finally {
12372
+ this.readerActive = false;
12373
+ }
12265
12374
  }
12266
12375
  } catch (err) {
12267
12376
  if (this.sock === sock && this.generation === generation) {
@@ -12293,13 +12402,20 @@ class SubcClient {
12293
12402
  this.failChannel(frame.header.channel, new SubcError("route closed by subc (GOODBYE)"));
12294
12403
  return;
12295
12404
  }
12405
+ if (frame.header.ty === 1 /* Response */ || frame.header.ty === 5 /* Error */ || frame.header.ty === 4 /* StreamEnd */) {
12406
+ debug("dropped terminal frame with no waiter: type=%d channel=%d corr=%s port=%s", frame.header.ty, frame.header.channel, frame.header.corr, this.sock.localPort() ?? "?");
12407
+ return;
12408
+ }
12296
12409
  }
12297
12410
  settle(key, pending, run) {
12411
+ if (this.pending.get(key) !== pending)
12412
+ return false;
12298
12413
  this.pending.delete(key);
12299
12414
  if (pending.timer)
12300
12415
  clearTimeout(pending.timer);
12301
12416
  run();
12302
12417
  pending.onSettle?.();
12418
+ return true;
12303
12419
  }
12304
12420
  rejectPending(key, pending, err) {
12305
12421
  this.settle(key, pending, () => pending.reject(pending.classifyFailure?.(err) ?? err));
@@ -12363,6 +12479,9 @@ function isConsumerReconnectTransient(err) {
12363
12479
  const code = errorCode(err);
12364
12480
  return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
12365
12481
  }
12482
+ function isRetryableRouteOpenCode(code) {
12483
+ return code === "unknown_module" || code === "module_reloading" || code === "target_unavailable" || code === "module_timeout";
12484
+ }
12366
12485
  async function connectionFileExists(path2) {
12367
12486
  try {
12368
12487
  await fs2.access(path2);
@@ -12378,7 +12497,8 @@ function normalizeConnectOptions(opts) {
12378
12497
  identity: opts.identity,
12379
12498
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
12380
12499
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
12381
- sleep: opts.sleep ?? ((ms) => new Promise((resolve7) => setTimeout(resolve7, ms)))
12500
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve7) => setTimeout(resolve7, ms))),
12501
+ timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
12382
12502
  };
12383
12503
  }
12384
12504
  function routeCacheKey(target, identity, consumerIdentity) {
@@ -12407,7 +12527,7 @@ function causeMessage(cause) {
12407
12527
  return "";
12408
12528
  return `: ${cause instanceof Error ? cause.message : String(cause)}`;
12409
12529
  }
12410
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/provider.ts
12530
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/provider.ts
12411
12531
  import { Buffer as Buffer2 } from "node:buffer";
12412
12532
  var DEFAULT_HANDSHAKE_TIMEOUT_MS2 = 1e4;
12413
12533
  var BODY_READ_TIMEOUT_MS2 = 30000;
@@ -13436,7 +13556,7 @@ async function createAftTransportPool(opts) {
13436
13556
  return new BridgePool(opts.binaryPath, opts.poolOptions, opts.configOverrides);
13437
13557
  }
13438
13558
  // src/bg-notifications.ts
13439
- import { createHash as createHash4, randomUUID as randomUUID2 } from "node:crypto";
13559
+ import { createHash as createHash5, randomUUID as randomUUID2 } from "node:crypto";
13440
13560
 
13441
13561
  // src/logger.ts
13442
13562
  import * as fs3 from "node:fs";
@@ -13600,7 +13720,7 @@ async function resolvePromptContext(client, sessionId) {
13600
13720
 
13601
13721
  // src/bg-notifications.ts
13602
13722
  function hashReminder(text) {
13603
- return createHash4("sha256").update(text).digest("hex").slice(0, 16);
13723
+ return createHash5("sha256").update(text).digest("hex").slice(0, 16);
13604
13724
  }
13605
13725
  var CONSUMED_TASKIDS_CAP = 256;
13606
13726
  var DELIVERED_AWAITING_ACK_CAP = 4096;
@@ -14364,7 +14484,7 @@ function formatDuration(completion) {
14364
14484
  }
14365
14485
 
14366
14486
  // src/config.ts
14367
- import { existsSync as existsSync7, readFileSync as readFileSync6, renameSync as renameSync5, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
14487
+ import { existsSync as existsSync7, readFileSync as readFileSync7, renameSync as renameSync5, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
14368
14488
  var import_comment_json = __toESM(require_src2(), 1);
14369
14489
 
14370
14490
  // ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
@@ -28690,9 +28810,6 @@ var LspServerEntrySchema = exports_external.object({
28690
28810
  env: exports_external.record(exports_external.string().min(1), exports_external.string()).optional(),
28691
28811
  initialization_options: exports_external.unknown().optional()
28692
28812
  });
28693
- var LspServerSchema = LspServerEntrySchema.extend({
28694
- id: exports_external.string().trim().min(1)
28695
- });
28696
28813
  var LspConfigSchema = exports_external.object({
28697
28814
  servers: exports_external.record(exports_external.string().trim().min(1), LspServerEntrySchema).optional(),
28698
28815
  disabled: exports_external.array(exports_external.string().trim().min(1)).optional(),
@@ -28956,7 +29073,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
28956
29073
  let tmpPath = null;
28957
29074
  let oldKeys = [];
28958
29075
  try {
28959
- const content = readFileSync6(configPath, "utf-8");
29076
+ const content = readFileSync7(configPath, "utf-8");
28960
29077
  const rawConfig = import_comment_json.parse(content);
28961
29078
  if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
28962
29079
  return { migrated: false, oldKeys: [] };
@@ -29033,7 +29150,7 @@ function loadConfigFromPath(configPath) {
29033
29150
  if (!existsSync7(configPath)) {
29034
29151
  return null;
29035
29152
  }
29036
- const content = readFileSync6(configPath, "utf-8");
29153
+ const content = readFileSync7(configPath, "utf-8");
29037
29154
  const rawConfig = import_comment_json.parse(content);
29038
29155
  migrateRawConfig(rawConfig, configPath, { log: log2, warn: warn2 });
29039
29156
  const cleanConfig = stripJsoncSymbols(rawConfig);
@@ -29301,7 +29418,7 @@ function loadAftConfig(projectDirectory) {
29301
29418
  }
29302
29419
 
29303
29420
  // src/notifications.ts
29304
- import { existsSync as existsSync8, readFileSync as readFileSync7 } from "node:fs";
29421
+ import { existsSync as existsSync8, readFileSync as readFileSync8 } from "node:fs";
29305
29422
  import { homedir as homedir9, platform } from "node:os";
29306
29423
  import { join as join11 } from "node:path";
29307
29424
  function isTuiMode() {
@@ -29321,7 +29438,6 @@ async function showTuiToast(client, title, message, variant = "info", duration3
29321
29438
  var AFT_MARKER = "\uD83D\uDD27 AFT:";
29322
29439
  var FEATURE_MARKER = `${AFT_MARKER} New in`;
29323
29440
  var WARNING_MARKER = `${AFT_MARKER} ⚠️`;
29324
- var STATUS_MARKER = `${AFT_MARKER} ✅`;
29325
29441
  function getDesktopStatePath() {
29326
29442
  const os3 = platform();
29327
29443
  const home = homedir9();
@@ -29344,7 +29460,7 @@ function readDesktopState() {
29344
29460
  return { serverUrl: null };
29345
29461
  }
29346
29462
  try {
29347
- const raw = readFileSync7(statePath, "utf-8");
29463
+ const raw = readFileSync8(statePath, "utf-8");
29348
29464
  const state = JSON.parse(raw);
29349
29465
  let serverUrl = null;
29350
29466
  const serverStr = state.server;
@@ -29843,7 +29959,7 @@ import {
29843
29959
  existsSync as existsSync11,
29844
29960
  mkdirSync as mkdirSync6,
29845
29961
  openSync as openSync5,
29846
- readFileSync as readFileSync10,
29962
+ readFileSync as readFileSync11,
29847
29963
  renameSync as renameSync6,
29848
29964
  rmSync as rmSync5,
29849
29965
  writeFileSync as writeFileSync7
@@ -29852,14 +29968,14 @@ import { dirname as dirname7 } from "node:path";
29852
29968
 
29853
29969
  // src/hooks/auto-update-checker/cache.ts
29854
29970
  import { spawn as spawn2 } from "node:child_process";
29855
- import { cpSync, existsSync as existsSync10, mkdtempSync, readFileSync as readFileSync9, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
29971
+ import { cpSync, existsSync as existsSync10, mkdtempSync, readFileSync as readFileSync10, rmSync as rmSync4, writeFileSync as writeFileSync6 } from "node:fs";
29856
29972
  import { tmpdir as tmpdir3 } from "node:os";
29857
29973
  import { basename as basename3, dirname as dirname6, join as join14 } from "node:path";
29858
29974
  var import_comment_json3 = __toESM(require_src2(), 1);
29859
29975
 
29860
29976
  // src/hooks/auto-update-checker/checker.ts
29861
29977
  var import_comment_json2 = __toESM(require_src2(), 1);
29862
- import { existsSync as existsSync9, readFileSync as readFileSync8, statSync as statSync5, writeFileSync as writeFileSync5 } from "node:fs";
29978
+ import { existsSync as existsSync9, readFileSync as readFileSync9, statSync as statSync5, writeFileSync as writeFileSync5 } from "node:fs";
29863
29979
  import { homedir as homedir11 } from "node:os";
29864
29980
  import { dirname as dirname5, isAbsolute as isAbsolute6, join as join13, resolve as resolve7 } from "node:path";
29865
29981
  import { fileURLToPath } from "node:url";
@@ -29965,7 +30081,7 @@ function getLocalDevPath(directory) {
29965
30081
  try {
29966
30082
  if (!existsSync9(configPath))
29967
30083
  continue;
29968
- const rawConfig = parseJsonConfig(readFileSync8(configPath, "utf-8"));
30084
+ const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
29969
30085
  const plugins = getPluginEntries(rawConfig);
29970
30086
  for (const entry of plugins) {
29971
30087
  if (entry === PACKAGE_NAME || entry.startsWith(`${PACKAGE_NAME}@`))
@@ -29975,7 +30091,7 @@ function getLocalDevPath(directory) {
29975
30091
  const pkgPath = findPackageJsonUp(localPath);
29976
30092
  if (!pkgPath)
29977
30093
  continue;
29978
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync8(pkgPath, "utf-8")));
30094
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
29979
30095
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
29980
30096
  return localPath;
29981
30097
  }
@@ -29992,7 +30108,7 @@ function findPackageJsonUp(startPath) {
29992
30108
  const pkgPath = join13(dir, "package.json");
29993
30109
  if (existsSync9(pkgPath)) {
29994
30110
  try {
29995
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync8(pkgPath, "utf-8")));
30111
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
29996
30112
  if (pkg.success && pkg.data.name === PACKAGE_NAME)
29997
30113
  return pkgPath;
29998
30114
  } catch {}
@@ -30013,7 +30129,7 @@ function getLocalDevVersion(directory) {
30013
30129
  const pkgPath = findPackageJsonUp(localPath);
30014
30130
  if (!pkgPath)
30015
30131
  return null;
30016
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync8(pkgPath, "utf-8")));
30132
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(pkgPath, "utf-8")));
30017
30133
  return pkg.success ? pkg.data.version ?? null : null;
30018
30134
  } catch {
30019
30135
  return null;
@@ -30032,7 +30148,7 @@ function findPluginEntry(directory) {
30032
30148
  try {
30033
30149
  if (!existsSync9(configPath))
30034
30150
  continue;
30035
- const rawConfig = parseJsonConfig(readFileSync8(configPath, "utf-8"));
30151
+ const rawConfig = parseJsonConfig(readFileSync9(configPath, "utf-8"));
30036
30152
  const plugins = getPluginEntries(rawConfig);
30037
30153
  for (const entry of plugins) {
30038
30154
  if (entry === PACKAGE_NAME) {
@@ -30065,7 +30181,7 @@ function getCachedVersion(spec) {
30065
30181
  try {
30066
30182
  if (!existsSync9(packageJsonPath))
30067
30183
  continue;
30068
- const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync8(packageJsonPath, "utf-8")));
30184
+ const pkg = PackageJsonSchema.safeParse(JSON.parse(readFileSync9(packageJsonPath, "utf-8")));
30069
30185
  if (pkg.success && pkg.data.version) {
30070
30186
  if (!spec)
30071
30187
  cachedPackageVersion = pkg.data.version;
@@ -30115,9 +30231,9 @@ function createAutoUpdateSnapshot(installDir, packageJsonPath, packageName) {
30115
30231
  cpSync(packageDir, stagedPackageDir, { recursive: true });
30116
30232
  return {
30117
30233
  packageJsonPath,
30118
- packageJson: existsSync10(packageJsonPath) ? readFileSync9(packageJsonPath, "utf-8") : null,
30234
+ packageJson: existsSync10(packageJsonPath) ? readFileSync10(packageJsonPath, "utf-8") : null,
30119
30235
  lockfilePath,
30120
- lockfile: existsSync10(lockfilePath) ? readFileSync9(lockfilePath, "utf-8") : null,
30236
+ lockfile: existsSync10(lockfilePath) ? readFileSync10(lockfilePath, "utf-8") : null,
30121
30237
  packageDir,
30122
30238
  stagedPackageDir,
30123
30239
  tempDir
@@ -30155,7 +30271,7 @@ function removeFromPackageLock(installDir, packageName) {
30155
30271
  if (!existsSync10(lockPath))
30156
30272
  return false;
30157
30273
  try {
30158
- const lock = import_comment_json3.parse(readFileSync9(lockPath, "utf-8"));
30274
+ const lock = import_comment_json3.parse(readFileSync10(lockPath, "utf-8"));
30159
30275
  let modified = false;
30160
30276
  if (lock.packages) {
30161
30277
  const key = `node_modules/${packageName}`;
@@ -30181,7 +30297,7 @@ function ensureDependencyVersion(packageJsonPath, packageName, version2) {
30181
30297
  if (!existsSync10(packageJsonPath))
30182
30298
  return false;
30183
30299
  try {
30184
- const raw = import_comment_json3.parse(readFileSync9(packageJsonPath, "utf-8"));
30300
+ const raw = import_comment_json3.parse(readFileSync10(packageJsonPath, "utf-8"));
30185
30301
  const pkgJson = PackageJsonSchema.safeParse(raw);
30186
30302
  if (!pkgJson.success)
30187
30303
  return false;
@@ -30435,7 +30551,7 @@ function hasRecentCheckTimestamp(file2, intervalMs) {
30435
30551
  if (!existsSync11(file2))
30436
30552
  return false;
30437
30553
  try {
30438
- const raw = JSON.parse(readFileSync10(file2, "utf-8"));
30554
+ const raw = JSON.parse(readFileSync11(file2, "utf-8"));
30439
30555
  const last = typeof raw.lastCheckedMs === "number" ? raw.lastCheckedMs : 0;
30440
30556
  return Number.isFinite(last) && Date.now() - last < intervalMs;
30441
30557
  } catch {
@@ -30539,12 +30655,12 @@ function showToast(ctx, title, message, variant = "info", duration3 = 3000) {
30539
30655
 
30540
30656
  // src/lsp-auto-install.ts
30541
30657
  import { spawn as spawn3 } from "node:child_process";
30542
- import { createHash as createHash5 } from "node:crypto";
30658
+ import { createHash as createHash6 } from "node:crypto";
30543
30659
  import {
30544
30660
  createReadStream,
30545
30661
  existsSync as existsSync13,
30546
30662
  mkdirSync as mkdirSync8,
30547
- readFileSync as readFileSync13,
30663
+ readFileSync as readFileSync14,
30548
30664
  renameSync as renameSync7,
30549
30665
  rmSync as rmSync6,
30550
30666
  statSync as statSync7,
@@ -30557,7 +30673,7 @@ import {
30557
30673
  closeSync as closeSync6,
30558
30674
  mkdirSync as mkdirSync7,
30559
30675
  openSync as openSync6,
30560
- readFileSync as readFileSync11,
30676
+ readFileSync as readFileSync12,
30561
30677
  statSync as statSync6,
30562
30678
  unlinkSync as unlinkSync6,
30563
30679
  writeFileSync as writeFileSync8
@@ -30621,7 +30737,7 @@ function readInstalledMetaIn(installDir) {
30621
30737
  try {
30622
30738
  if (!statSync6(path3).isFile())
30623
30739
  return null;
30624
- const raw = readFileSync11(path3, "utf8");
30740
+ const raw = readFileSync12(path3, "utf8");
30625
30741
  const parsed = JSON.parse(raw);
30626
30742
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
30627
30743
  return null;
@@ -30671,7 +30787,7 @@ ${new Date().toISOString()}
30671
30787
  let owningPid = null;
30672
30788
  let lockMtimeMs = 0;
30673
30789
  try {
30674
- const raw = readFileSync11(lock, "utf8");
30790
+ const raw = readFileSync12(lock, "utf8");
30675
30791
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
30676
30792
  const parsed = Number.parseInt(firstLine, 10);
30677
30793
  if (Number.isFinite(parsed) && parsed > 0)
@@ -30709,7 +30825,7 @@ function releaseInstallLock(lockKey) {
30709
30825
  try {
30710
30826
  let owningPid = null;
30711
30827
  try {
30712
- const raw = readFileSync11(lock, "utf8");
30828
+ const raw = readFileSync12(lock, "utf8");
30713
30829
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
30714
30830
  const parsed = Number.parseInt(firstLine, 10);
30715
30831
  if (Number.isFinite(parsed) && parsed > 0)
@@ -30750,7 +30866,7 @@ var VERSION_CHECK_FILE = ".aft-version-check";
30750
30866
  function readVersionCheck(npmPackage) {
30751
30867
  const file2 = join15(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
30752
30868
  try {
30753
- const raw = readFileSync11(file2, "utf8");
30869
+ const raw = readFileSync12(file2, "utf8");
30754
30870
  const parsed = JSON.parse(raw);
30755
30871
  if (typeof parsed.last_checked === "string") {
30756
30872
  return {
@@ -30927,7 +31043,7 @@ var NPM_LSP_TABLE = [
30927
31043
  ];
30928
31044
 
30929
31045
  // src/lsp-project-relevance.ts
30930
- import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync12 } from "node:fs";
31046
+ import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync13 } from "node:fs";
30931
31047
  import { join as join16 } from "node:path";
30932
31048
  var MAX_WALK_DIRS = 200;
30933
31049
  var MAX_WALK_DEPTH = 4;
@@ -30969,7 +31085,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
30969
31085
  }
30970
31086
  function readPackageJson(projectRoot) {
30971
31087
  try {
30972
- const raw = readFileSync12(join16(projectRoot, "package.json"), "utf8");
31088
+ const raw = readFileSync13(join16(projectRoot, "package.json"), "utf8");
30973
31089
  const parsed = JSON.parse(raw);
30974
31090
  if (typeof parsed !== "object" || parsed === null)
30975
31091
  return null;
@@ -31291,7 +31407,7 @@ function hashInstalledBinary(spec) {
31291
31407
  reject(new Error(`installed binary not found at any of: ${candidates.join(", ")}`));
31292
31408
  return;
31293
31409
  }
31294
- const hash2 = createHash5("sha256");
31410
+ const hash2 = createHash6("sha256");
31295
31411
  const stream = createReadStream(pathToHash);
31296
31412
  stream.on("error", reject);
31297
31413
  stream.on("data", (chunk) => hash2.update(chunk));
@@ -31314,7 +31430,7 @@ function installedBinaryPath(spec) {
31314
31430
  return null;
31315
31431
  }
31316
31432
  function sha256OfFileSync(path3) {
31317
- return createHash5("sha256").update(readFileSync13(path3)).digest("hex");
31433
+ return createHash6("sha256").update(readFileSync14(path3)).digest("hex");
31318
31434
  }
31319
31435
  function quarantineCachedNpmInstall(spec, reason) {
31320
31436
  const packageDir = lspPackageDir(spec.npm);
@@ -31399,7 +31515,7 @@ function runAutoInstall(projectRoot, config2, fetchImpl = fetch) {
31399
31515
 
31400
31516
  // src/lsp-github-install.ts
31401
31517
  import { execFileSync as execFileSync2 } from "node:child_process";
31402
- import { createHash as createHash6, randomBytes as randomBytes2 } from "node:crypto";
31518
+ import { createHash as createHash7, randomBytes as randomBytes2 } from "node:crypto";
31403
31519
  import {
31404
31520
  copyFileSync as copyFileSync4,
31405
31521
  createReadStream as createReadStream2,
@@ -31408,7 +31524,7 @@ import {
31408
31524
  lstatSync as lstatSync2,
31409
31525
  mkdirSync as mkdirSync9,
31410
31526
  readdirSync as readdirSync4,
31411
- readFileSync as readFileSync14,
31527
+ readFileSync as readFileSync15,
31412
31528
  readlinkSync as readlinkSync2,
31413
31529
  realpathSync as realpathSync3,
31414
31530
  renameSync as renameSync8,
@@ -31542,7 +31658,7 @@ function readGithubInstalledMetaIn(installDir) {
31542
31658
  const path3 = join18(installDir, INSTALLED_META_FILE2);
31543
31659
  if (!statSync8(path3).isFile())
31544
31660
  return null;
31545
- const parsed = JSON.parse(readFileSync14(path3, "utf8"));
31661
+ const parsed = JSON.parse(readFileSync15(path3, "utf8"));
31546
31662
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
31547
31663
  return null;
31548
31664
  return {
@@ -31575,7 +31691,7 @@ var MAX_DOWNLOAD_BYTES3 = 256 * 1024 * 1024;
31575
31691
  var MAX_EXTRACT_BYTES2 = 1024 * 1024 * 1024;
31576
31692
  function sha256OfFile(path3) {
31577
31693
  return new Promise((resolve9, reject) => {
31578
- const hash2 = createHash6("sha256");
31694
+ const hash2 = createHash7("sha256");
31579
31695
  const stream = createReadStream2(path3);
31580
31696
  stream.on("error", reject);
31581
31697
  stream.on("data", (chunk) => hash2.update(chunk));
@@ -31583,7 +31699,7 @@ function sha256OfFile(path3) {
31583
31699
  });
31584
31700
  }
31585
31701
  function sha256OfFileSync2(path3) {
31586
- return createHash6("sha256").update(readFileSync14(path3)).digest("hex");
31702
+ return createHash7("sha256").update(readFileSync15(path3)).digest("hex");
31587
31703
  }
31588
31704
  async function fetchReleaseByTag(githubRepo, tag, fetchImpl, signal) {
31589
31705
  const candidates = [];
@@ -32362,7 +32478,7 @@ import {
32362
32478
  existsSync as existsSync15,
32363
32479
  mkdirSync as mkdirSync10,
32364
32480
  readdirSync as readdirSync5,
32365
- readFileSync as readFileSync15,
32481
+ readFileSync as readFileSync16,
32366
32482
  renameSync as renameSync9,
32367
32483
  unlinkSync as unlinkSync8,
32368
32484
  writeFileSync as writeFileSync11
@@ -32542,7 +32658,7 @@ class AftRpcServer {
32542
32658
  if (filePath === this.portFilePath)
32543
32659
  continue;
32544
32660
  try {
32545
- const record2 = parseRpcPortRecord(readFileSync15(filePath, "utf-8"));
32661
+ const record2 = parseRpcPortRecord(readFileSync16(filePath, "utf-8"));
32546
32662
  if (record2 === null) {
32547
32663
  unlinkSync8(filePath);
32548
32664
  continue;
@@ -36315,13 +36431,13 @@ var PLUGIN_VERSION = (() => {
36315
36431
  return "0.0.0";
36316
36432
  }
36317
36433
  })();
36318
- var ANNOUNCEMENT_VERSION = "0.44.0";
36434
+ var ANNOUNCEMENT_VERSION = "0.45.0";
36319
36435
  var ANNOUNCEMENT_FEATURES = [
36320
- "Code Health accuracy overhaul: framework entry points (Tauri commands, Next.js/Nuxt/SvelteKit/Remix/Astro routes, NestJS decorators) are no longer flagged dead, barrel re-exports collapse to their real definition, and test-only usage moves out of the headline counts into its own tier.",
36321
- "New: import cycle detection for TS/JS (aft_inspect sections: cycles), and expected_mirrors config to suppress intentional duplicate pairs like plugin/pi-plugin parity trees.",
36322
- "Stale diagnostics fixed: files edited outside AFT (scripts, git) no longer show outdated errors in aft_inspect or the status bar.",
36323
- "bash wait: true blocks until a long command finishes instead of promoting it to background.",
36324
- "Objective-C support (.m/.mm): outline, zoom, AST search, and semantic indexing."
36436
+ "Code Health verified against 12 real repositories: dead code is only reported for languages we can actually analyze (Java/Kotlin now say 'not analyzed' instead of guessing), and generated code (gen/ trees, *_pb.ts, DO NOT EDIT banners) moves out of the headline counts into its own bucket.",
36437
+ "Config files (playwright/eslint/tsup/vitest *.config.ts), Storybook stories, Mocha hooks, and SvelteKit hooks/$lib imports are no longer flagged as dead code.",
36438
+ "Rust module aliases, inline-module calls, and cross-crate pub use re-exports now resolve; Go interface methods (sort.Interface, Bubble Tea) are no longer flagged dead.",
36439
+ "Fixed npx @cortexkit/aft doctor --fix and setup failing to download the binary on fresh installs.",
36440
+ "Bridges now detect an updated aft binary on disk and respawn onto it automatically."
36325
36441
  ];
36326
36442
  var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
36327
36443
  var plugin = async (input) => initializePluginForDirectory(input);