@cortexkit/aft 0.52.0 → 0.52.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.
Files changed (2) hide show
  1. package/dist/index.js +67 -18
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -4956,6 +4956,15 @@ function isAbsentRootRouteError(err) {
4956
4956
  function absentRootError(root) {
4957
4957
  return new SubcError(`invalid route project root: project root does not exist: ${root}`, "config_divergence");
4958
4958
  }
4959
+ function reloadWindowExhaustedError(error2) {
4960
+ if (error2 instanceof Error) {
4961
+ try {
4962
+ error2.message += ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX;
4963
+ return error2;
4964
+ } catch {}
4965
+ }
4966
+ return new Error(`${String(error2)}${ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX}`);
4967
+ }
4959
4968
  function safeCloseRoute(client, route) {
4960
4969
  try {
4961
4970
  client.closeRouteChannel(route).catch(() => {
@@ -5077,6 +5086,7 @@ class SubcTransportPool {
5077
5086
  connecting = null;
5078
5087
  routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
5079
5088
  routeReopenRetry = null;
5089
+ routeReopenRetryMs = null;
5080
5090
  sessions = new Map;
5081
5091
  rootIndex = new Map;
5082
5092
  dormantRoots = new Map;
@@ -5550,6 +5560,23 @@ class SubcTransportPool {
5550
5560
  throw error2;
5551
5561
  }
5552
5562
  };
5563
+ const openRouteAfterReloadWindow = async () => {
5564
+ let reloadWaitedMs = 0;
5565
+ while (true) {
5566
+ try {
5567
+ return await openRoute();
5568
+ } catch (error2) {
5569
+ if (!isRouteOpenReloadWindowError(error2))
5570
+ throw error2;
5571
+ const { delayMs, wait } = this.waitForRouteReopenBackoff();
5572
+ if (reloadWaitedMs + delayMs > ROUTE_OPEN_RELOAD_WAIT_CAP_MS) {
5573
+ throw reloadWindowExhaustedError(error2);
5574
+ }
5575
+ reloadWaitedMs += delayMs;
5576
+ await wait;
5577
+ }
5578
+ }
5579
+ };
5553
5580
  const clearRouteEntry = (entry) => {
5554
5581
  if (record.routeEntry !== entry)
5555
5582
  return;
@@ -5586,7 +5613,7 @@ class SubcTransportPool {
5586
5613
  this.ensureBgSubscription(identity, record);
5587
5614
  return reply;
5588
5615
  };
5589
- let routeAndEntry = await openRoute();
5616
+ let routeAndEntry = await openRouteAfterReloadWindow();
5590
5617
  try {
5591
5618
  return await requestOnRoute(routeAndEntry.route);
5592
5619
  } catch (error2) {
@@ -5594,8 +5621,8 @@ class SubcTransportPool {
5594
5621
  throw this.annotateReapError(error2, record);
5595
5622
  if (isRouteProvenAbsentError(error2) && this.isCurrentSession(key, record) && this.client === client) {
5596
5623
  clearRouteEntry(routeAndEntry.entry);
5597
- await this.waitForRouteReopenBackoff();
5598
- routeAndEntry = await openRoute();
5624
+ await this.waitForRouteReopenBackoff().wait;
5625
+ routeAndEntry = await openRouteAfterReloadWindow();
5599
5626
  try {
5600
5627
  const reply = await requestOnRoute(routeAndEntry.route);
5601
5628
  this.resetRouteReopenBackoff();
@@ -5621,17 +5648,21 @@ class SubcTransportPool {
5621
5648
  }
5622
5649
  waitForRouteReopenBackoff() {
5623
5650
  const pending = this.routeReopenRetry;
5624
- if (pending)
5625
- return pending;
5626
- const delay = this.routeReopenRetryDelayMs;
5627
- this.routeReopenRetryDelayMs = Math.min(delay * 2, RECONNECT_RETRY_CAP_MS);
5651
+ const pendingDelay = this.routeReopenRetryMs;
5652
+ if (pending && pendingDelay !== null)
5653
+ return { delayMs: pendingDelay, wait: pending };
5654
+ const delayMs = this.routeReopenRetryDelayMs;
5655
+ this.routeReopenRetryDelayMs = Math.min(delayMs * 2, RECONNECT_RETRY_CAP_MS);
5628
5656
  let retry;
5629
- retry = Promise.resolve().then(() => this.routeRetrySleep(delay)).finally(() => {
5630
- if (this.routeReopenRetry === retry)
5657
+ retry = Promise.resolve().then(() => this.routeRetrySleep(delayMs)).finally(() => {
5658
+ if (this.routeReopenRetry === retry) {
5631
5659
  this.routeReopenRetry = null;
5660
+ this.routeReopenRetryMs = null;
5661
+ }
5632
5662
  });
5633
5663
  this.routeReopenRetry = retry;
5634
- return retry;
5664
+ this.routeReopenRetryMs = delayMs;
5665
+ return { delayMs, wait: retry };
5635
5666
  }
5636
5667
  resetRouteReopenBackoff() {
5637
5668
  this.routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
@@ -5889,10 +5920,11 @@ function resolveBridgeForNudge(pool, ref) {
5889
5920
  currentConcretePoolId: candidate.getConcretePoolId?.()
5890
5921
  });
5891
5922
  }
5892
- var SubcTransportShuttingDownError, AFT_MODULE_ID = "aft", MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3, RECONNECT_RETRY_FLOOR_MS = 100, RECONNECT_RETRY_CAP_MS = 2000, BG_STABLE_MS = 5000, BG_LIFECYCLE_LOG_INTERVAL_MS = 60000, BG_DISPATCH_PROBE_INTERVAL_MS = 60000, DEFAULT_SESSION_ID = "__default__", LOCALLY_SATISFIED_COMMANDS, SubcRootReapedError, SubcRootGenerationExpiredError, SubcRootDemandRequiredError, RouteTornDownError;
5923
+ var SubcTransportShuttingDownError, AFT_MODULE_ID = "aft", MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3, RECONNECT_RETRY_FLOOR_MS = 100, RECONNECT_RETRY_CAP_MS = 2000, ROUTE_OPEN_RELOAD_WAIT_CAP_MS = 15000, ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX = " The AFT daemon module did not return within the 15s reload window.", BG_STABLE_MS = 5000, BG_LIFECYCLE_LOG_INTERVAL_MS = 60000, BG_DISPATCH_PROBE_INTERVAL_MS = 60000, DEFAULT_SESSION_ID = "__default__", LOCALLY_SATISFIED_COMMANDS, SubcRootReapedError, SubcRootGenerationExpiredError, SubcRootDemandRequiredError, RouteTornDownError;
5893
5924
  var init_subc_transport = __esm(() => {
5894
5925
  init_dist();
5895
5926
  init_active_logger();
5927
+ init_error_contract();
5896
5928
  init_lifecycle_registry();
5897
5929
  init_project_identity();
5898
5930
  SubcTransportShuttingDownError = class SubcTransportShuttingDownError extends SubcCallError {
@@ -5963,6 +5995,12 @@ function isRouteGoodbyeError(error2) {
5963
5995
  }
5964
5996
  return error2.code === "route_closed" && error2.message.includes("route closed by subc");
5965
5997
  }
5998
+ function isRouteOpenReloadWindowError(error2) {
5999
+ if (error2 === null || typeof error2 !== "object")
6000
+ return false;
6001
+ const code = error2.code;
6002
+ return code === "module_reloading" || code === "module_warming" || code === "target_unavailable";
6003
+ }
5966
6004
  function hasEngineResponse(error2) {
5967
6005
  const response = error2.response;
5968
6006
  if (response !== null && typeof response === "object")
@@ -6321,7 +6359,16 @@ function platformKey(platform = process.platform, arch = process.arch) {
6321
6359
  }
6322
6360
  return key;
6323
6361
  }
6362
+ function logBinaryResolution(resolution) {
6363
+ log(`Resolved binary from ${resolution.source}: ${resolution.path}`);
6364
+ }
6324
6365
  function findBinarySync(expectedVersion) {
6366
+ const resolution = findBinarySyncInner(expectedVersion);
6367
+ if (resolution)
6368
+ logBinaryResolution(resolution);
6369
+ return resolution?.path ?? null;
6370
+ }
6371
+ function findBinarySyncInner(expectedVersion) {
6325
6372
  const ext = process.platform === "win32" ? ".exe" : "";
6326
6373
  const env = { ...process.env };
6327
6374
  const pluginVersion = expectedVersion ?? (() => {
@@ -6335,8 +6382,9 @@ function findBinarySync(expectedVersion) {
6335
6382
  if (pluginVersion) {
6336
6383
  const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
6337
6384
  const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
6338
- if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion))
6339
- return versionCached;
6385
+ if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion)) {
6386
+ return { path: versionCached, source: "versioned cache" };
6387
+ }
6340
6388
  }
6341
6389
  try {
6342
6390
  const key = platformKey();
@@ -6351,7 +6399,7 @@ function findBinarySync(expectedVersion) {
6351
6399
  warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
6352
6400
  } else {
6353
6401
  const copied = copyToVersionedCache(resolved, npmVersion);
6354
- return copied ?? resolved;
6402
+ return { path: copied ?? resolved, source: "npm platform package" };
6355
6403
  }
6356
6404
  }
6357
6405
  } catch {}
@@ -6369,27 +6417,28 @@ function findBinarySync(expectedVersion) {
6369
6417
  }
6370
6418
  const usable = probeBinaryCandidate(candidate, "PATH", expectedVersion);
6371
6419
  if (usable)
6372
- return usable;
6420
+ return { path: usable, source: "PATH" };
6373
6421
  }
6374
6422
  } catch {}
6375
6423
  const cargoPath = join7(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
6376
6424
  if (existsSync5(cargoPath)) {
6377
6425
  const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
6378
6426
  if (usable)
6379
- return usable;
6427
+ return { path: usable, source: "cargo" };
6380
6428
  }
6381
6429
  return null;
6382
6430
  }
6383
6431
  async function findBinary(expectedVersion) {
6384
6432
  const syncResult = findBinarySync(expectedVersion);
6385
6433
  if (syncResult) {
6386
- log(`Resolved binary: ${syncResult}`);
6387
6434
  return syncResult;
6388
6435
  }
6389
6436
  log("Binary not found locally, attempting auto-download...");
6390
6437
  const downloaded = await ensureBinaryForResolver(expectedVersion);
6391
- if (downloaded)
6438
+ if (downloaded) {
6439
+ logBinaryResolution({ path: downloaded, source: "auto-download" });
6392
6440
  return downloaded;
6441
+ }
6393
6442
  throw new Error([
6394
6443
  "Could not find the `aft` binary.",
6395
6444
  "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft",
3
- "version": "0.52.0",
3
+ "version": "0.52.1",
4
4
  "type": "module",
5
5
  "description": "Unified CLI for Agent File Tools (AFT) — setup, doctor, and diagnostics across supported agent harnesses (OpenCode, Pi)",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "dependencies": {
26
26
  "@clack/prompts": "^1.6.0",
27
- "@cortexkit/aft-bridge": "0.52.0",
27
+ "@cortexkit/aft-bridge": "0.52.1",
28
28
  "comment-json": "^4.6.2"
29
29
  },
30
30
  "devDependencies": {