@cortexkit/aft-pi 0.44.0 → 0.45.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +188 -68
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -8314,6 +8314,8 @@ function resolveBashKillTimeout(modelTimeout, foregroundWaitMs) {
8314
8314
  }
8315
8315
  // ../aft-bridge/dist/bridge.js
8316
8316
  import { spawn } from "node:child_process";
8317
+ import { createHash } from "node:crypto";
8318
+ import { readFileSync } from "node:fs";
8317
8319
  import { homedir as homedir2 } from "node:os";
8318
8320
  import { join as join2 } from "node:path";
8319
8321
  import { StringDecoder } from "node:string_decoder";
@@ -8408,6 +8410,22 @@ function bashTaskIdFrom(response) {
8408
8410
  return camelCase;
8409
8411
  return;
8410
8412
  }
8413
+ function hashBinaryOnDisk(binaryPath) {
8414
+ try {
8415
+ return createHash("sha256").update(readFileSync(binaryPath)).digest("hex");
8416
+ } catch {
8417
+ return null;
8418
+ }
8419
+ }
8420
+ var binaryFingerprintReader = hashBinaryOnDisk;
8421
+ function readBinaryFingerprint(binaryPath) {
8422
+ try {
8423
+ const fingerprint = binaryFingerprintReader(binaryPath);
8424
+ return typeof fingerprint === "string" && fingerprint.length > 0 ? fingerprint : null;
8425
+ } catch {
8426
+ return null;
8427
+ }
8428
+ }
8411
8429
  function tagStderrLine(line) {
8412
8430
  return /^\[aft(-\w+)?\] /.test(line) ? line : `[aft] ${line}`;
8413
8431
  }
@@ -8503,6 +8521,9 @@ class BinaryBridge {
8503
8521
  binaryPath;
8504
8522
  cwd;
8505
8523
  process = null;
8524
+ spawnedBinaryFingerprint = null;
8525
+ lastBinaryFingerprintCheckAt = 0;
8526
+ _retiringDueToBinaryChange = false;
8506
8527
  pending = new Map;
8507
8528
  outstandingBackgroundTaskIds = new Set;
8508
8529
  nextId = 1;
@@ -8622,6 +8643,24 @@ class BinaryBridge {
8622
8643
  hasOutstandingBackgroundTasks() {
8623
8644
  return this.outstandingBackgroundTaskIds.size > 0;
8624
8645
  }
8646
+ maybeScheduleRespawnForUpdatedBinary(checkIntervalMs, now = Date.now()) {
8647
+ if (this._shuttingDown || this._retiringDueToBinaryChange || !this.isAlive())
8648
+ return false;
8649
+ if (this.pending.size > 0 || this.outstandingBackgroundTaskIds.size > 0)
8650
+ return false;
8651
+ if (now - this.lastBinaryFingerprintCheckAt < checkIntervalMs)
8652
+ return false;
8653
+ this.lastBinaryFingerprintCheckAt = now;
8654
+ const spawnedFingerprint = this.spawnedBinaryFingerprint;
8655
+ if (!spawnedFingerprint)
8656
+ return false;
8657
+ const currentFingerprint = readBinaryFingerprint(this.binaryPath);
8658
+ if (!currentFingerprint || currentFingerprint === spawnedFingerprint)
8659
+ return false;
8660
+ this._retiringDueToBinaryChange = true;
8661
+ this.logVia(`Binary contents changed on disk for ${this.binaryPath}; retiring this bridge so the next tool call respawns onto the updated binary.`);
8662
+ return true;
8663
+ }
8625
8664
  getCwd() {
8626
8665
  return this.cwd;
8627
8666
  }
@@ -8654,6 +8693,9 @@ class BinaryBridge {
8654
8693
  }
8655
8694
  async sendWithVersionMismatchRetry(command, params, options, canRetryAfterVersionSwap) {
8656
8695
  try {
8696
+ if (this._retiringDueToBinaryChange) {
8697
+ throw new Error(`${this.errorPrefix} Bridge is retiring after the on-disk binary changed; retry to respawn on the updated binary`);
8698
+ }
8657
8699
  if (this._shuttingDown) {
8658
8700
  throw new Error(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
8659
8701
  }
@@ -8852,6 +8894,7 @@ class BinaryBridge {
8852
8894
  }
8853
8895
  async shutdown() {
8854
8896
  this._shuttingDown = true;
8897
+ this.spawnedBinaryFingerprint = null;
8855
8898
  this.clearRestartResetTimer();
8856
8899
  this.configureWarningClients.clear();
8857
8900
  this.rejectAllPending(new Error(`${this.errorPrefix} Bridge shutting down`));
@@ -8905,6 +8948,9 @@ class BinaryBridge {
8905
8948
  async replaceCurrentBinary(newBinaryPath) {
8906
8949
  this.binaryPath = newBinaryPath;
8907
8950
  this.configured = false;
8951
+ this.spawnedBinaryFingerprint = null;
8952
+ this.lastBinaryFingerprintCheckAt = 0;
8953
+ this._retiringDueToBinaryChange = false;
8908
8954
  this.clearRestartResetTimer();
8909
8955
  this.rejectAllPending(new Error(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
8910
8956
  if (!this.process)
@@ -8930,6 +8976,7 @@ class BinaryBridge {
8930
8976
  this.spawnProcess(triggeringSessionId);
8931
8977
  }
8932
8978
  spawnProcess(triggeringSessionId) {
8979
+ this._retiringDueToBinaryChange = false;
8933
8980
  this.lastStatusBar = undefined;
8934
8981
  if (triggeringSessionId) {
8935
8982
  this.sessionLogVia(triggeringSessionId, `Spawning binary: ${this.binaryPath} (cwd: ${this.cwd})`);
@@ -9020,6 +9067,8 @@ class BinaryBridge {
9020
9067
  this.handleCrash();
9021
9068
  });
9022
9069
  this.process = child;
9070
+ this.spawnedBinaryFingerprint = readBinaryFingerprint(this.binaryPath);
9071
+ this.lastBinaryFingerprintCheckAt = Date.now();
9023
9072
  this.stdoutBuffer = "";
9024
9073
  this.stdoutReadOffset = 0;
9025
9074
  this.stderrBuffer = "";
@@ -9198,6 +9247,7 @@ class BinaryBridge {
9198
9247
  }
9199
9248
  handleTimeout(triggeringSessionId) {
9200
9249
  this.consecutiveRequestTimeouts = 0;
9250
+ this.spawnedBinaryFingerprint = null;
9201
9251
  this.rejectAllPending(new Error(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
9202
9252
  this.outstandingBackgroundTaskIds.clear();
9203
9253
  if (this.process) {
@@ -9224,6 +9274,7 @@ class BinaryBridge {
9224
9274
  handleCrash(cause) {
9225
9275
  const proc = this.process;
9226
9276
  this.process = null;
9277
+ this.spawnedBinaryFingerprint = null;
9227
9278
  if (proc && proc.exitCode === null && !proc.killed) {
9228
9279
  proc.kill("SIGKILL");
9229
9280
  }
@@ -9235,6 +9286,10 @@ class BinaryBridge {
9235
9286
  this.errorVia(`Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""}.${tail}`);
9236
9287
  }
9237
9288
  this.rejectAllPending(new Error(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`));
9289
+ if (this._retiringDueToBinaryChange) {
9290
+ this.logVia("Binary exited while retiring after an on-disk update; skipping auto-restart");
9291
+ return;
9292
+ }
9238
9293
  if (this._restartCount < this.maxRestarts) {
9239
9294
  const delay = 100 * 2 ** this._restartCount;
9240
9295
  this._restartCount++;
@@ -9643,13 +9698,13 @@ function isEmptyParam(value) {
9643
9698
  return false;
9644
9699
  }
9645
9700
  // ../aft-bridge/dist/config-tiers.js
9646
- import { existsSync, readFileSync } from "node:fs";
9701
+ import { existsSync, readFileSync as readFileSync2 } from "node:fs";
9647
9702
  import { resolve as resolve2 } from "node:path";
9648
9703
  function readConfigTiers(opts) {
9649
9704
  const tiers = [];
9650
9705
  try {
9651
9706
  if (existsSync(opts.userConfigPath)) {
9652
- const doc = readFileSync(opts.userConfigPath, "utf-8");
9707
+ const doc = readFileSync2(opts.userConfigPath, "utf-8");
9653
9708
  tiers.push({
9654
9709
  tier: "user",
9655
9710
  source: resolve2(opts.userConfigPath),
@@ -9659,7 +9714,7 @@ function readConfigTiers(opts) {
9659
9714
  } catch {}
9660
9715
  try {
9661
9716
  if (existsSync(opts.projectConfigPath)) {
9662
- const doc = readFileSync(opts.projectConfigPath, "utf-8");
9717
+ const doc = readFileSync2(opts.projectConfigPath, "utf-8");
9663
9718
  tiers.push({
9664
9719
  tier: "project",
9665
9720
  source: resolve2(opts.projectConfigPath),
@@ -9677,8 +9732,8 @@ function formatDroppedKeyWarnings(dropped) {
9677
9732
  }
9678
9733
  // ../aft-bridge/dist/downloader.js
9679
9734
  import { spawnSync } from "node:child_process";
9680
- import { createHash, randomUUID } from "node:crypto";
9681
- import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync2, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
9735
+ import { createHash as createHash2, randomUUID } from "node:crypto";
9736
+ import { chmodSync, closeSync, copyFileSync, createWriteStream, existsSync as existsSync2, mkdirSync, openSync, readFileSync as readFileSync3, renameSync, rmSync, statSync, unlinkSync, writeSync } from "node:fs";
9682
9737
  import { homedir as homedir4 } from "node:os";
9683
9738
  import { join as join3 } from "node:path";
9684
9739
  import { Readable } from "node:stream";
@@ -9822,7 +9877,7 @@ async function downloadBinary(version) {
9822
9877
  warn(`Checksum verification failed: checksums.sha256 found but no entry for ${assetName}. ` + "Binary download aborted for security reasons.");
9823
9878
  return null;
9824
9879
  }
9825
- const hash = createHash("sha256");
9880
+ const hash = createHash2("sha256");
9826
9881
  let bytesWritten = 0;
9827
9882
  const guard = new TransformStream({
9828
9883
  transform(chunk, controller) {
@@ -9906,7 +9961,7 @@ async function acquireDownloadLock(lockPath) {
9906
9961
  closeSync(fd);
9907
9962
  } catch {}
9908
9963
  try {
9909
- if (readFileSync2(lockPath, "utf-8") === owner) {
9964
+ if (readFileSync3(lockPath, "utf-8") === owner) {
9910
9965
  rmSync(lockPath, { force: true });
9911
9966
  }
9912
9967
  } catch {}
@@ -10031,12 +10086,12 @@ function stripJsoncSymbols(value) {
10031
10086
  }
10032
10087
  // ../aft-bridge/dist/migration.js
10033
10088
  import { spawnSync as spawnSync2 } from "node:child_process";
10034
- 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";
10089
+ 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";
10035
10090
  import { homedir as homedir7, tmpdir } from "node:os";
10036
10091
  import { basename, dirname as dirname2, join as join6, resolve as resolve4 } from "node:path";
10037
10092
 
10038
10093
  // ../aft-bridge/dist/paths.js
10039
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, renameSync as renameSync2, writeFileSync } from "node:fs";
10094
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync4, renameSync as renameSync2, writeFileSync } from "node:fs";
10040
10095
  import { homedir as homedir5 } from "node:os";
10041
10096
  import { dirname, isAbsolute as isAbsolute2, join as join4, resolve as resolve3 } from "node:path";
10042
10097
  function homeDir() {
@@ -10110,7 +10165,7 @@ function shouldShowAnnouncement(storageRoot, harness, currentVersion) {
10110
10165
  let lastVersion = "";
10111
10166
  try {
10112
10167
  if (existsSync3(versionFile)) {
10113
- lastVersion = readFileSync3(versionFile, "utf-8").trim();
10168
+ lastVersion = readFileSync4(versionFile, "utf-8").trim();
10114
10169
  }
10115
10170
  } catch {
10116
10171
  return false;
@@ -10507,7 +10562,7 @@ function atomicCopyConfigFile(sourcePath, targetPath) {
10507
10562
  let fd = null;
10508
10563
  try {
10509
10564
  fd = openSync3(tmpPath, "wx", 384);
10510
- writeFileSync2(fd, readFileSync4(sourcePath));
10565
+ writeFileSync2(fd, readFileSync5(sourcePath));
10511
10566
  closeSync3(fd);
10512
10567
  fd = null;
10513
10568
  renameSync4(tmpPath, targetPath);
@@ -10586,7 +10641,7 @@ function markLegacySourcesMovedAside(sources, targetPath, logger) {
10586
10641
  const desiredMarkerPath = `${source.path}${MOVED_MARKER_SUFFIX}`;
10587
10642
  const markerPath = nonClobberingSidecarPath(desiredMarkerPath);
10588
10643
  try {
10589
- const original = readFileSync4(source.path, "utf-8");
10644
+ const original = readFileSync5(source.path, "utf-8");
10590
10645
  if (markerPath !== desiredMarkerPath) {
10591
10646
  logger?.warn?.(`Preserving existing legacy AFT marker ${desiredMarkerPath}; writing new marker to ${markerPath}`);
10592
10647
  }
@@ -10655,10 +10710,10 @@ function migrateAftConfigFile(opts) {
10655
10710
  try {
10656
10711
  const sources = existingSources.map((source) => ({
10657
10712
  ...source,
10658
- content: readFileSync4(source.path, "utf-8")
10713
+ content: readFileSync5(source.path, "utf-8")
10659
10714
  }));
10660
10715
  if (existsSync5(opts.targetPath)) {
10661
- const targetContent = readFileSync4(opts.targetPath, "utf-8");
10716
+ const targetContent = readFileSync5(opts.targetPath, "utf-8");
10662
10717
  for (const source of sources) {
10663
10718
  if (fileSemanticsMatch(source.content, targetContent))
10664
10719
  continue;
@@ -10889,8 +10944,8 @@ function npmSpawnEnv(resolved, baseEnv = process.env) {
10889
10944
  }
10890
10945
  // ../aft-bridge/dist/onnx-runtime.js
10891
10946
  import { execFileSync } from "node:child_process";
10892
- import { createHash as createHash2 } from "node:crypto";
10893
- 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";
10947
+ import { createHash as createHash3 } from "node:crypto";
10948
+ 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";
10894
10949
  import { basename as basename2, dirname as dirname4, isAbsolute as isAbsolute4, join as join8, relative as relative2, resolve as resolve5, win32 } from "node:path";
10895
10950
  import { Readable as Readable2 } from "node:stream";
10896
10951
  import { pipeline as pipeline2 } from "node:stream/promises";
@@ -11440,7 +11495,7 @@ function readOnnxInstalledMeta(installDir) {
11440
11495
  try {
11441
11496
  if (!statSync4(path2).isFile())
11442
11497
  return null;
11443
- const raw = readFileSync5(path2, "utf8");
11498
+ const raw = readFileSync6(path2, "utf8");
11444
11499
  const parsed = JSON.parse(raw);
11445
11500
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
11446
11501
  return null;
@@ -11455,8 +11510,8 @@ function readOnnxInstalledMeta(installDir) {
11455
11510
  }
11456
11511
  }
11457
11512
  function sha256File(path2) {
11458
- const hash = createHash2("sha256");
11459
- hash.update(readFileSync5(path2));
11513
+ const hash = createHash3("sha256");
11514
+ hash.update(readFileSync6(path2));
11460
11515
  return hash.digest("hex");
11461
11516
  }
11462
11517
  function acquireLock(lockPath) {
@@ -11484,7 +11539,7 @@ ${new Date().toISOString()}
11484
11539
  let owningPid = null;
11485
11540
  let lockMtimeMs = 0;
11486
11541
  try {
11487
- const raw = readFileSync5(lockPath, "utf8");
11542
+ const raw = readFileSync6(lockPath, "utf8");
11488
11543
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
11489
11544
  const parsed = Number.parseInt(firstLine, 10);
11490
11545
  if (Number.isFinite(parsed) && parsed > 0)
@@ -11509,7 +11564,7 @@ function releaseLock(lockPath) {
11509
11564
  try {
11510
11565
  let owningPid = null;
11511
11566
  try {
11512
- const raw = readFileSync5(lockPath, "utf8");
11567
+ const raw = readFileSync6(lockPath, "utf8");
11513
11568
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
11514
11569
  const parsed = Number.parseInt(firstLine, 10);
11515
11570
  if (Number.isFinite(parsed) && parsed > 0)
@@ -11704,6 +11759,11 @@ class BridgePool {
11704
11759
  for (const [dir, entry] of this.bridges) {
11705
11760
  if (entry.bridge.hasPendingRequests() || entry.bridge.hasOutstandingBackgroundTasks())
11706
11761
  continue;
11762
+ if (entry.bridge.maybeScheduleRespawnForUpdatedBinary(CLEANUP_INTERVAL_MS, now)) {
11763
+ this.staleBridges.add(entry.bridge);
11764
+ this.bridges.delete(dir);
11765
+ continue;
11766
+ }
11707
11767
  if (now - entry.lastUsed > this.idleTimeoutMs) {
11708
11768
  entry.bridge.shutdown().catch((err) => this.error("cleanup shutdown failed:", err));
11709
11769
  this.bridges.delete(dir);
@@ -11800,10 +11860,11 @@ class BridgePool {
11800
11860
  function normalizeKey(projectRoot) {
11801
11861
  return canonicalizeProjectRoot(projectRoot);
11802
11862
  }
11803
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
11863
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/client.ts
11804
11864
  import { promises as fs2 } from "node:fs";
11865
+ import { debuglog } from "node:util";
11805
11866
 
11806
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/auth.ts
11867
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/auth.ts
11807
11868
  import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
11808
11869
  var NONCE_LEN = 32;
11809
11870
  var MAX_AUTH_MESSAGE_LEN = 4096;
@@ -11867,7 +11928,7 @@ async function authenticateClient(sock, conn, deadlineMs) {
11867
11928
  await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
11868
11929
  }
11869
11930
 
11870
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/connection-file.ts
11931
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/connection-file.ts
11871
11932
  import { promises as fs } from "node:fs";
11872
11933
  var SCHEMA_VERSION = 1;
11873
11934
  var MIN_KEY_LEN = 32;
@@ -11936,7 +11997,7 @@ async function readConnectionFile(path2) {
11936
11997
  return info;
11937
11998
  }
11938
11999
 
11939
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/envelope.ts
12000
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/envelope.ts
11940
12001
  var PROTOCOL_VERSION = 1;
11941
12002
  var HEADER_LEN = 17;
11942
12003
  var FROZEN_PREFIX_LEN = 5;
@@ -12043,7 +12104,7 @@ function encodeFrame(frame) {
12043
12104
  return out;
12044
12105
  }
12045
12106
 
12046
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/socket.ts
12107
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/socket.ts
12047
12108
  import net from "node:net";
12048
12109
 
12049
12110
  class SocketClosedError extends Error {
@@ -12074,6 +12135,9 @@ class SubcSocket {
12074
12135
  buffered = 0;
12075
12136
  waiter = null;
12076
12137
  closedErr = null;
12138
+ bufferedBytes() {
12139
+ return this.buffered;
12140
+ }
12077
12141
  constructor(sock) {
12078
12142
  this.sock = sock;
12079
12143
  sock.on("data", (chunk) => {
@@ -12232,9 +12296,14 @@ class SubcSocket {
12232
12296
  }
12233
12297
  }
12234
12298
 
12235
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/client.ts
12299
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/client.ts
12300
+ var debug = debuglog("subc-client");
12236
12301
  var DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4;
12237
12302
  var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
12303
+ var TIMEOUT_ARBITRATION_GRACE_MS = 50;
12304
+ var REQUEST_DEADLINE_MARKER = "request_deadline";
12305
+ var DEADLINE_NO_DROP_CODE = "deadline_exceeded_no_drop_observed";
12306
+ var ROUTE_OPEN_RETRY_DEADLINE_MS = 1e4;
12238
12307
  var BODY_READ_TIMEOUT_MS = 30000;
12239
12308
  var EMPTY_BODY = new Uint8Array(0);
12240
12309
  var DEFAULT_MANAGED_TARGET_KIND = "management_surface";
@@ -12278,6 +12347,7 @@ class SubcClient {
12278
12347
  closeStarted = false;
12279
12348
  reconnecting = null;
12280
12349
  generation = 1;
12350
+ readerActive = false;
12281
12351
  constructor(sock, currentConn, opts) {
12282
12352
  this.sock = sock;
12283
12353
  this.currentConn = currentConn;
@@ -12336,7 +12406,7 @@ class SubcClient {
12336
12406
  }
12337
12407
  continue;
12338
12408
  }
12339
- if (err.kind === "outcome_unknown") {
12409
+ if (err.kind === "outcome_unknown" && err.code !== DEADLINE_NO_DROP_CODE) {
12340
12410
  this.scheduleReconnectAfterDrop(err);
12341
12411
  }
12342
12412
  throw err;
@@ -12459,7 +12529,7 @@ class SubcClient {
12459
12529
  timer: null
12460
12530
  };
12461
12531
  pending.timer = setTimeout(() => {
12462
- this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
12532
+ this.arbitrateTimeout(key, pending, channel, corr, ms);
12463
12533
  }, ms);
12464
12534
  this.pending.set(key, pending);
12465
12535
  this.sock.write(encodeFrame(frame), Date.now() + ms).catch((err) => {
@@ -12469,6 +12539,23 @@ class SubcClient {
12469
12539
  });
12470
12540
  });
12471
12541
  }
12542
+ arbitrateTimeout(key, pending, channel, corr, ms) {
12543
+ const settleAsTimeout = () => {
12544
+ this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms), REQUEST_DEADLINE_MARKER));
12545
+ };
12546
+ const graceDeadline = Date.now() + this.opts.timeoutArbitrationGraceMs;
12547
+ const arbitrate = () => {
12548
+ if (this.pending.get(key) !== pending)
12549
+ return;
12550
+ const readerDraining = this.readerActive || this.sock.bufferedBytes() > 0;
12551
+ if (readerDraining && Date.now() < graceDeadline) {
12552
+ setImmediate(arbitrate);
12553
+ return;
12554
+ }
12555
+ settleAsTimeout();
12556
+ };
12557
+ setImmediate(arbitrate);
12558
+ }
12472
12559
  async managedRequest(routeChannel, body, opts) {
12473
12560
  const bytes = body instanceof Uint8Array ? body : this.encode(body);
12474
12561
  const priority = opts.priority ?? 1 /* Interactive */;
@@ -12493,6 +12580,9 @@ class SubcClient {
12493
12580
  if (!handedToSocket) {
12494
12581
  return this.notSentCallError("request bytes were not queued to the subc socket", err);
12495
12582
  }
12583
+ if (err instanceof SubcError && err.code === REQUEST_DEADLINE_MARKER) {
12584
+ 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);
12585
+ }
12496
12586
  return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", err);
12497
12587
  };
12498
12588
  return new Promise((resolve7, reject) => {
@@ -12506,7 +12596,7 @@ class SubcClient {
12506
12596
  classifyFailure
12507
12597
  };
12508
12598
  pending.timer = setTimeout(() => {
12509
- this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms)));
12599
+ this.arbitrateTimeout(key, pending, channel, corr, ms);
12510
12600
  }, ms);
12511
12601
  this.pending.set(key, pending);
12512
12602
  const write = this.sock.writeTracked(encodeFrame(frame), Date.now() + ms);
@@ -12551,6 +12641,9 @@ class SubcClient {
12551
12641
  return cached.opening;
12552
12642
  }
12553
12643
  async openCachedRoute(cached) {
12644
+ const routeRetryDeadline = Date.now() + ROUTE_OPEN_RETRY_DEADLINE_MS;
12645
+ let routeRetryDelay = this.opts.reconnectBackoff.baseMs;
12646
+ let routeRetryAttempt = 0;
12554
12647
  for (;; ) {
12555
12648
  if (cached.closed)
12556
12649
  throw this.routeClosedDuringOpen();
@@ -12584,6 +12677,15 @@ class SubcClient {
12584
12677
  }
12585
12678
  continue;
12586
12679
  }
12680
+ if (!this.closeStarted && err instanceof SubcError && isRetryableRouteOpenCode(err.code)) {
12681
+ routeRetryAttempt += 1;
12682
+ if (routeRetryAttempt < this.opts.reconnectBackoff.maxAttempts && Date.now() < routeRetryDeadline) {
12683
+ await this.opts.sleep(routeRetryDelay);
12684
+ routeRetryDelay = Math.min(routeRetryDelay * 2, this.opts.reconnectBackoff.capMs);
12685
+ continue;
12686
+ }
12687
+ throw this.notSentCallError(`route.open failed for module ${cached.moduleId}: ${err.code} (retry budget exhausted)`, err);
12688
+ }
12587
12689
  throw this.terminalCallError(`route.open failed for module ${cached.moduleId}`, err);
12588
12690
  }
12589
12691
  }
@@ -12677,9 +12779,16 @@ class SubcClient {
12677
12779
  try {
12678
12780
  for (;; ) {
12679
12781
  const headerBytes = await sock.readExact(HEADER_LEN, Number.POSITIVE_INFINITY);
12680
- const header = decodeHeader(headerBytes);
12681
- const body = header.len === 0 ? new Uint8Array(0) : await sock.readExact(header.len, Date.now() + BODY_READ_TIMEOUT_MS);
12682
- this.dispatch({ header, body });
12782
+ this.readerActive = true;
12783
+ try {
12784
+ const header = decodeHeader(headerBytes);
12785
+ const body = header.len === 0 ? new Uint8Array(0) : await sock.readExact(header.len, Date.now() + BODY_READ_TIMEOUT_MS);
12786
+ if (this.sock === sock && this.generation === generation) {
12787
+ this.dispatch({ header, body });
12788
+ }
12789
+ } finally {
12790
+ this.readerActive = false;
12791
+ }
12683
12792
  }
12684
12793
  } catch (err) {
12685
12794
  if (this.sock === sock && this.generation === generation) {
@@ -12711,13 +12820,20 @@ class SubcClient {
12711
12820
  this.failChannel(frame.header.channel, new SubcError("route closed by subc (GOODBYE)"));
12712
12821
  return;
12713
12822
  }
12823
+ if (frame.header.ty === 1 /* Response */ || frame.header.ty === 5 /* Error */ || frame.header.ty === 4 /* StreamEnd */) {
12824
+ 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() ?? "?");
12825
+ return;
12826
+ }
12714
12827
  }
12715
12828
  settle(key, pending, run) {
12829
+ if (this.pending.get(key) !== pending)
12830
+ return false;
12716
12831
  this.pending.delete(key);
12717
12832
  if (pending.timer)
12718
12833
  clearTimeout(pending.timer);
12719
12834
  run();
12720
12835
  pending.onSettle?.();
12836
+ return true;
12721
12837
  }
12722
12838
  rejectPending(key, pending, err) {
12723
12839
  this.settle(key, pending, () => pending.reject(pending.classifyFailure?.(err) ?? err));
@@ -12781,6 +12897,9 @@ function isConsumerReconnectTransient(err) {
12781
12897
  const code = errorCode(err);
12782
12898
  return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
12783
12899
  }
12900
+ function isRetryableRouteOpenCode(code) {
12901
+ return code === "unknown_module" || code === "module_reloading" || code === "target_unavailable" || code === "module_timeout";
12902
+ }
12784
12903
  async function connectionFileExists(path2) {
12785
12904
  try {
12786
12905
  await fs2.access(path2);
@@ -12796,7 +12915,8 @@ function normalizeConnectOptions(opts) {
12796
12915
  identity: opts.identity,
12797
12916
  targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
12798
12917
  reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
12799
- sleep: opts.sleep ?? ((ms) => new Promise((resolve7) => setTimeout(resolve7, ms)))
12918
+ sleep: opts.sleep ?? ((ms) => new Promise((resolve7) => setTimeout(resolve7, ms))),
12919
+ timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
12800
12920
  };
12801
12921
  }
12802
12922
  function routeCacheKey(target, identity, consumerIdentity) {
@@ -12825,7 +12945,7 @@ function causeMessage(cause) {
12825
12945
  return "";
12826
12946
  return `: ${cause instanceof Error ? cause.message : String(cause)}`;
12827
12947
  }
12828
- // ../../node_modules/.bun/@cortexkit+subc-client@0.2.1/node_modules/@cortexkit/subc-client/src/provider.ts
12948
+ // ../../node_modules/.bun/@cortexkit+subc-client@0.3.0/node_modules/@cortexkit/subc-client/src/provider.ts
12829
12949
  import { Buffer as Buffer2 } from "node:buffer";
12830
12950
  var DEFAULT_HANDSHAKE_TIMEOUT_MS2 = 1e4;
12831
12951
  var BODY_READ_TIMEOUT_MS2 = 30000;
@@ -14658,7 +14778,7 @@ import {
14658
14778
  // package.json
14659
14779
  var package_default = {
14660
14780
  name: "@cortexkit/aft-pi",
14661
- version: "0.44.0",
14781
+ version: "0.45.0",
14662
14782
  type: "module",
14663
14783
  description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
14664
14784
  main: "dist/index.js",
@@ -14681,19 +14801,19 @@ var package_default = {
14681
14801
  "test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
14682
14802
  },
14683
14803
  dependencies: {
14684
- "@cortexkit/aft-bridge": "0.44.0",
14804
+ "@cortexkit/aft-bridge": "0.45.0",
14685
14805
  "comment-json": "^5.0.0",
14686
14806
  diff: "^8.0.4",
14687
14807
  typebox: "1.1.38",
14688
14808
  zod: "^4.4.3"
14689
14809
  },
14690
14810
  optionalDependencies: {
14691
- "@cortexkit/aft-darwin-arm64": "0.44.0",
14692
- "@cortexkit/aft-darwin-x64": "0.44.0",
14693
- "@cortexkit/aft-linux-arm64": "0.44.0",
14694
- "@cortexkit/aft-linux-x64": "0.44.0",
14695
- "@cortexkit/aft-win32-arm64": "0.44.0",
14696
- "@cortexkit/aft-win32-x64": "0.44.0"
14811
+ "@cortexkit/aft-darwin-arm64": "0.45.0",
14812
+ "@cortexkit/aft-darwin-x64": "0.45.0",
14813
+ "@cortexkit/aft-linux-arm64": "0.45.0",
14814
+ "@cortexkit/aft-linux-x64": "0.45.0",
14815
+ "@cortexkit/aft-win32-arm64": "0.45.0",
14816
+ "@cortexkit/aft-win32-x64": "0.45.0"
14697
14817
  },
14698
14818
  devDependencies: {
14699
14819
  "@earendil-works/pi-coding-agent": "^0.80.2",
@@ -15282,7 +15402,7 @@ function registerStatusCommand(pi, ctx) {
15282
15402
  }
15283
15403
 
15284
15404
  // src/config.ts
15285
- import { existsSync as existsSync7, readFileSync as readFileSync6, renameSync as renameSync5, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
15405
+ import { existsSync as existsSync7, readFileSync as readFileSync7, renameSync as renameSync5, unlinkSync as unlinkSync5, writeFileSync as writeFileSync4 } from "node:fs";
15286
15406
  var import_comment_json = __toESM(require_src2(), 1);
15287
15407
 
15288
15408
  // ../../node_modules/.bun/zod@4.4.3/node_modules/zod/v4/classic/external.js
@@ -29860,7 +29980,7 @@ function migrateAftConfigFile2(configPath, logger = { log: log2, warn: warn2 })
29860
29980
  let tmpPath = null;
29861
29981
  let oldKeys = [];
29862
29982
  try {
29863
- const content = readFileSync6(configPath, "utf-8");
29983
+ const content = readFileSync7(configPath, "utf-8");
29864
29984
  const rawConfig = import_comment_json.parse(content);
29865
29985
  if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
29866
29986
  return { migrated: false, oldKeys: [] };
@@ -29909,7 +30029,7 @@ function loadConfigFromPath(configPath) {
29909
30029
  try {
29910
30030
  if (!existsSync7(configPath))
29911
30031
  return null;
29912
- const content = readFileSync6(configPath, "utf-8");
30032
+ const content = readFileSync7(configPath, "utf-8");
29913
30033
  const rawConfig = import_comment_json.parse(content);
29914
30034
  if (!rawConfig || typeof rawConfig !== "object" || Array.isArray(rawConfig)) {
29915
30035
  recordConfigParseFailure(configPath, "root must be an object");
@@ -30192,12 +30312,12 @@ function loadAftConfig(projectDirectory) {
30192
30312
 
30193
30313
  // src/lsp-auto-install.ts
30194
30314
  import { spawn as spawn2 } from "node:child_process";
30195
- import { createHash as createHash3 } from "node:crypto";
30315
+ import { createHash as createHash4 } from "node:crypto";
30196
30316
  import {
30197
30317
  createReadStream,
30198
30318
  existsSync as existsSync9,
30199
30319
  mkdirSync as mkdirSync7,
30200
- readFileSync as readFileSync9,
30320
+ readFileSync as readFileSync10,
30201
30321
  renameSync as renameSync6,
30202
30322
  rmSync as rmSync4,
30203
30323
  statSync as statSync6,
@@ -30210,7 +30330,7 @@ import {
30210
30330
  closeSync as closeSync5,
30211
30331
  mkdirSync as mkdirSync6,
30212
30332
  openSync as openSync5,
30213
- readFileSync as readFileSync7,
30333
+ readFileSync as readFileSync8,
30214
30334
  statSync as statSync5,
30215
30335
  unlinkSync as unlinkSync6,
30216
30336
  writeFileSync as writeFileSync5
@@ -30274,7 +30394,7 @@ function readInstalledMetaIn(installDir) {
30274
30394
  try {
30275
30395
  if (!statSync5(path3).isFile())
30276
30396
  return null;
30277
- const raw = readFileSync7(path3, "utf8");
30397
+ const raw = readFileSync8(path3, "utf8");
30278
30398
  const parsed = JSON.parse(raw);
30279
30399
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
30280
30400
  return null;
@@ -30324,7 +30444,7 @@ ${new Date().toISOString()}
30324
30444
  let owningPid = null;
30325
30445
  let lockMtimeMs = 0;
30326
30446
  try {
30327
- const raw = readFileSync7(lock, "utf8");
30447
+ const raw = readFileSync8(lock, "utf8");
30328
30448
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
30329
30449
  const parsed = Number.parseInt(firstLine, 10);
30330
30450
  if (Number.isFinite(parsed) && parsed > 0)
@@ -30362,7 +30482,7 @@ function releaseInstallLock(lockKey) {
30362
30482
  try {
30363
30483
  let owningPid = null;
30364
30484
  try {
30365
- const raw = readFileSync7(lock, "utf8");
30485
+ const raw = readFileSync8(lock, "utf8");
30366
30486
  const firstLine = raw.split(/\r?\n/, 1)[0]?.trim() ?? "";
30367
30487
  const parsed = Number.parseInt(firstLine, 10);
30368
30488
  if (Number.isFinite(parsed) && parsed > 0)
@@ -30403,7 +30523,7 @@ var VERSION_CHECK_FILE = ".aft-version-check";
30403
30523
  function readVersionCheck(npmPackage) {
30404
30524
  const file2 = join11(lspPackageDir(npmPackage), VERSION_CHECK_FILE);
30405
30525
  try {
30406
- const raw = readFileSync7(file2, "utf8");
30526
+ const raw = readFileSync8(file2, "utf8");
30407
30527
  const parsed = JSON.parse(raw);
30408
30528
  if (typeof parsed.last_checked === "string") {
30409
30529
  return {
@@ -30580,7 +30700,7 @@ var NPM_LSP_TABLE = [
30580
30700
  ];
30581
30701
 
30582
30702
  // src/lsp-project-relevance.ts
30583
- import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "node:fs";
30703
+ import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync9 } from "node:fs";
30584
30704
  import { join as join12 } from "node:path";
30585
30705
  var MAX_WALK_DIRS = 200;
30586
30706
  var MAX_WALK_DEPTH = 4;
@@ -30622,7 +30742,7 @@ function hasPackageJsonDep(projectRoot, depNames) {
30622
30742
  }
30623
30743
  function readPackageJson(projectRoot) {
30624
30744
  try {
30625
- const raw = readFileSync8(join12(projectRoot, "package.json"), "utf8");
30745
+ const raw = readFileSync9(join12(projectRoot, "package.json"), "utf8");
30626
30746
  const parsed = JSON.parse(raw);
30627
30747
  if (typeof parsed !== "object" || parsed === null)
30628
30748
  return null;
@@ -30944,7 +31064,7 @@ function hashInstalledBinary(spec) {
30944
31064
  reject(new Error(`installed binary not found at any of: ${candidates.join(", ")}`));
30945
31065
  return;
30946
31066
  }
30947
- const hash2 = createHash3("sha256");
31067
+ const hash2 = createHash4("sha256");
30948
31068
  const stream = createReadStream(pathToHash);
30949
31069
  stream.on("error", reject);
30950
31070
  stream.on("data", (chunk) => hash2.update(chunk));
@@ -30967,7 +31087,7 @@ function installedBinaryPath(spec) {
30967
31087
  return null;
30968
31088
  }
30969
31089
  function sha256OfFileSync(path3) {
30970
- return createHash3("sha256").update(readFileSync9(path3)).digest("hex");
31090
+ return createHash4("sha256").update(readFileSync10(path3)).digest("hex");
30971
31091
  }
30972
31092
  function quarantineCachedNpmInstall(spec, reason) {
30973
31093
  const packageDir = lspPackageDir(spec.npm);
@@ -31051,7 +31171,7 @@ function runAutoInstall(projectRoot, config2, fetchImpl = fetch) {
31051
31171
 
31052
31172
  // src/lsp-github-install.ts
31053
31173
  import { execFileSync as execFileSync2 } from "node:child_process";
31054
- import { createHash as createHash4, randomBytes as randomBytes2 } from "node:crypto";
31174
+ import { createHash as createHash5, randomBytes as randomBytes2 } from "node:crypto";
31055
31175
  import {
31056
31176
  copyFileSync as copyFileSync4,
31057
31177
  createReadStream as createReadStream2,
@@ -31060,7 +31180,7 @@ import {
31060
31180
  lstatSync as lstatSync2,
31061
31181
  mkdirSync as mkdirSync8,
31062
31182
  readdirSync as readdirSync4,
31063
- readFileSync as readFileSync10,
31183
+ readFileSync as readFileSync11,
31064
31184
  readlinkSync as readlinkSync2,
31065
31185
  realpathSync as realpathSync3,
31066
31186
  renameSync as renameSync7,
@@ -31194,7 +31314,7 @@ function readGithubInstalledMetaIn(installDir) {
31194
31314
  const path3 = join14(installDir, INSTALLED_META_FILE2);
31195
31315
  if (!statSync7(path3).isFile())
31196
31316
  return null;
31197
- const parsed = JSON.parse(readFileSync10(path3, "utf8"));
31317
+ const parsed = JSON.parse(readFileSync11(path3, "utf8"));
31198
31318
  if (typeof parsed.version !== "string" || parsed.version.length === 0)
31199
31319
  return null;
31200
31320
  return {
@@ -31227,7 +31347,7 @@ var MAX_DOWNLOAD_BYTES3 = 256 * 1024 * 1024;
31227
31347
  var MAX_EXTRACT_BYTES2 = 1024 * 1024 * 1024;
31228
31348
  function sha256OfFile(path3) {
31229
31349
  return new Promise((resolve8, reject) => {
31230
- const hash2 = createHash4("sha256");
31350
+ const hash2 = createHash5("sha256");
31231
31351
  const stream = createReadStream2(path3);
31232
31352
  stream.on("error", reject);
31233
31353
  stream.on("data", (chunk) => hash2.update(chunk));
@@ -31235,7 +31355,7 @@ function sha256OfFile(path3) {
31235
31355
  });
31236
31356
  }
31237
31357
  function sha256OfFileSync2(path3) {
31238
- return createHash4("sha256").update(readFileSync10(path3)).digest("hex");
31358
+ return createHash5("sha256").update(readFileSync11(path3)).digest("hex");
31239
31359
  }
31240
31360
  async function fetchReleaseByTag(githubRepo, tag, fetchImpl, signal) {
31241
31361
  const candidates = [];
@@ -35581,13 +35701,13 @@ var PLUGIN_VERSION = (() => {
35581
35701
  return "0.0.0";
35582
35702
  }
35583
35703
  })();
35584
- var ANNOUNCEMENT_VERSION = "0.44.0";
35704
+ var ANNOUNCEMENT_VERSION = "0.45.0";
35585
35705
  var ANNOUNCEMENT_FEATURES = [
35586
- "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.",
35587
- "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.",
35588
- "Stale diagnostics fixed: files edited outside AFT (scripts, git) no longer show outdated errors in aft_inspect or the status bar.",
35589
- "bash wait: true blocks until a long command finishes instead of promoting it to background.",
35590
- "Objective-C support (.m/.mm): outline, zoom, AST search, and semantic indexing."
35706
+ "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.",
35707
+ "Config files (playwright/eslint/tsup/vitest *.config.ts), Storybook stories, Mocha hooks, and SvelteKit hooks/$lib imports are no longer flagged as dead code.",
35708
+ "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.",
35709
+ "Fixed npx @cortexkit/aft doctor --fix and setup failing to download the binary on fresh installs.",
35710
+ "Bridges now detect an updated aft binary on disk and respawn onto it automatically."
35591
35711
  ];
35592
35712
  var ANNOUNCEMENT_FOOTER = "Join us on Discord: https://discord.gg/DSa65w8wuf";
35593
35713
  var ALL_ONLY_TOOLS = new Set(["aft_callgraph", "aft_delete", "aft_move", "aft_refactor"]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-pi",
3
- "version": "0.44.0",
3
+ "version": "0.45.0",
4
4
  "type": "module",
5
5
  "description": "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
6
6
  "main": "dist/index.js",
@@ -23,19 +23,19 @@
23
23
  "test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
24
24
  },
25
25
  "dependencies": {
26
- "@cortexkit/aft-bridge": "0.44.0",
26
+ "@cortexkit/aft-bridge": "0.45.0",
27
27
  "comment-json": "^5.0.0",
28
28
  "diff": "^8.0.4",
29
29
  "typebox": "1.1.38",
30
30
  "zod": "^4.4.3"
31
31
  },
32
32
  "optionalDependencies": {
33
- "@cortexkit/aft-darwin-arm64": "0.44.0",
34
- "@cortexkit/aft-darwin-x64": "0.44.0",
35
- "@cortexkit/aft-linux-arm64": "0.44.0",
36
- "@cortexkit/aft-linux-x64": "0.44.0",
37
- "@cortexkit/aft-win32-arm64": "0.44.0",
38
- "@cortexkit/aft-win32-x64": "0.44.0"
33
+ "@cortexkit/aft-darwin-arm64": "0.45.0",
34
+ "@cortexkit/aft-darwin-x64": "0.45.0",
35
+ "@cortexkit/aft-linux-arm64": "0.45.0",
36
+ "@cortexkit/aft-linux-x64": "0.45.0",
37
+ "@cortexkit/aft-win32-arm64": "0.45.0",
38
+ "@cortexkit/aft-win32-x64": "0.45.0"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@earendil-works/pi-coding-agent": "^0.80.2",