@cortexkit/aft-opencode 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.
package/dist/index.js CHANGED
@@ -12087,6 +12087,8 @@ var AFT_MODULE_ID = "aft";
12087
12087
  var MAX_CONSECUTIVE_TRANSPORT_FAILURES = 3;
12088
12088
  var RECONNECT_RETRY_FLOOR_MS = 100;
12089
12089
  var RECONNECT_RETRY_CAP_MS = 2000;
12090
+ var ROUTE_OPEN_RELOAD_WAIT_CAP_MS = 15000;
12091
+ var ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX = " The AFT daemon module did not return within the 15s reload window.";
12090
12092
  var BG_STABLE_MS = 5000;
12091
12093
  function reconnectBackoffMs(attempt) {
12092
12094
  return Math.min(RECONNECT_RETRY_FLOOR_MS * 2 ** Math.min(attempt, 6), RECONNECT_RETRY_CAP_MS);
@@ -12395,6 +12397,15 @@ function isAbsentRootRouteError(err) {
12395
12397
  function absentRootError(root) {
12396
12398
  return new SubcError(`invalid route project root: project root does not exist: ${root}`, "config_divergence");
12397
12399
  }
12400
+ function reloadWindowExhaustedError(error2) {
12401
+ if (error2 instanceof Error) {
12402
+ try {
12403
+ error2.message += ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX;
12404
+ return error2;
12405
+ } catch {}
12406
+ }
12407
+ return new Error(`${String(error2)}${ROUTE_OPEN_RELOAD_WAIT_EXHAUSTED_SUFFIX}`);
12408
+ }
12398
12409
  function safeCloseRoute(client, route) {
12399
12410
  try {
12400
12411
  client.closeRouteChannel(route).catch(() => {
@@ -12519,6 +12530,7 @@ class SubcTransportPool {
12519
12530
  connecting = null;
12520
12531
  routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
12521
12532
  routeReopenRetry = null;
12533
+ routeReopenRetryMs = null;
12522
12534
  sessions = new Map;
12523
12535
  rootIndex = new Map;
12524
12536
  dormantRoots = new Map;
@@ -12992,6 +13004,23 @@ class SubcTransportPool {
12992
13004
  throw error2;
12993
13005
  }
12994
13006
  };
13007
+ const openRouteAfterReloadWindow = async () => {
13008
+ let reloadWaitedMs = 0;
13009
+ while (true) {
13010
+ try {
13011
+ return await openRoute();
13012
+ } catch (error2) {
13013
+ if (!isRouteOpenReloadWindowError(error2))
13014
+ throw error2;
13015
+ const { delayMs, wait } = this.waitForRouteReopenBackoff();
13016
+ if (reloadWaitedMs + delayMs > ROUTE_OPEN_RELOAD_WAIT_CAP_MS) {
13017
+ throw reloadWindowExhaustedError(error2);
13018
+ }
13019
+ reloadWaitedMs += delayMs;
13020
+ await wait;
13021
+ }
13022
+ }
13023
+ };
12995
13024
  const clearRouteEntry = (entry) => {
12996
13025
  if (record.routeEntry !== entry)
12997
13026
  return;
@@ -13028,7 +13057,7 @@ class SubcTransportPool {
13028
13057
  this.ensureBgSubscription(identity, record);
13029
13058
  return reply;
13030
13059
  };
13031
- let routeAndEntry = await openRoute();
13060
+ let routeAndEntry = await openRouteAfterReloadWindow();
13032
13061
  try {
13033
13062
  return await requestOnRoute(routeAndEntry.route);
13034
13063
  } catch (error2) {
@@ -13036,8 +13065,8 @@ class SubcTransportPool {
13036
13065
  throw this.annotateReapError(error2, record);
13037
13066
  if (isRouteProvenAbsentError(error2) && this.isCurrentSession(key, record) && this.client === client) {
13038
13067
  clearRouteEntry(routeAndEntry.entry);
13039
- await this.waitForRouteReopenBackoff();
13040
- routeAndEntry = await openRoute();
13068
+ await this.waitForRouteReopenBackoff().wait;
13069
+ routeAndEntry = await openRouteAfterReloadWindow();
13041
13070
  try {
13042
13071
  const reply = await requestOnRoute(routeAndEntry.route);
13043
13072
  this.resetRouteReopenBackoff();
@@ -13063,17 +13092,21 @@ class SubcTransportPool {
13063
13092
  }
13064
13093
  waitForRouteReopenBackoff() {
13065
13094
  const pending = this.routeReopenRetry;
13066
- if (pending)
13067
- return pending;
13068
- const delay = this.routeReopenRetryDelayMs;
13069
- this.routeReopenRetryDelayMs = Math.min(delay * 2, RECONNECT_RETRY_CAP_MS);
13095
+ const pendingDelay = this.routeReopenRetryMs;
13096
+ if (pending && pendingDelay !== null)
13097
+ return { delayMs: pendingDelay, wait: pending };
13098
+ const delayMs = this.routeReopenRetryDelayMs;
13099
+ this.routeReopenRetryDelayMs = Math.min(delayMs * 2, RECONNECT_RETRY_CAP_MS);
13070
13100
  let retry;
13071
- retry = Promise.resolve().then(() => this.routeRetrySleep(delay)).finally(() => {
13072
- if (this.routeReopenRetry === retry)
13101
+ retry = Promise.resolve().then(() => this.routeRetrySleep(delayMs)).finally(() => {
13102
+ if (this.routeReopenRetry === retry) {
13073
13103
  this.routeReopenRetry = null;
13104
+ this.routeReopenRetryMs = null;
13105
+ }
13074
13106
  });
13075
13107
  this.routeReopenRetry = retry;
13076
- return retry;
13108
+ this.routeReopenRetryMs = delayMs;
13109
+ return { delayMs, wait: retry };
13077
13110
  }
13078
13111
  resetRouteReopenBackoff() {
13079
13112
  this.routeReopenRetryDelayMs = RECONNECT_RETRY_FLOOR_MS;
@@ -13360,6 +13393,12 @@ function isRouteGoodbyeError(error2) {
13360
13393
  }
13361
13394
  return error2.code === "route_closed" && error2.message.includes("route closed by subc");
13362
13395
  }
13396
+ function isRouteOpenReloadWindowError(error2) {
13397
+ if (error2 === null || typeof error2 !== "object")
13398
+ return false;
13399
+ const code = error2.code;
13400
+ return code === "module_reloading" || code === "module_warming" || code === "target_unavailable";
13401
+ }
13363
13402
  function hasEngineResponse(error2) {
13364
13403
  const response = error2.response;
13365
13404
  if (response !== null && typeof response === "object")
@@ -13684,7 +13723,16 @@ function platformKey(platform = process.platform, arch = process.arch) {
13684
13723
  }
13685
13724
  return key;
13686
13725
  }
13726
+ function logBinaryResolution(resolution) {
13727
+ log(`Resolved binary from ${resolution.source}: ${resolution.path}`);
13728
+ }
13687
13729
  function findBinarySync(expectedVersion) {
13730
+ const resolution = findBinarySyncInner(expectedVersion);
13731
+ if (resolution)
13732
+ logBinaryResolution(resolution);
13733
+ return resolution?.path ?? null;
13734
+ }
13735
+ function findBinarySyncInner(expectedVersion) {
13688
13736
  const ext = process.platform === "win32" ? ".exe" : "";
13689
13737
  const env = { ...process.env };
13690
13738
  const pluginVersion = expectedVersion ?? (() => {
@@ -13698,8 +13746,9 @@ function findBinarySync(expectedVersion) {
13698
13746
  if (pluginVersion) {
13699
13747
  const tag = pluginVersion.startsWith("v") ? pluginVersion : `v${pluginVersion}`;
13700
13748
  const versionCached = cachedBinaryPathFromEnv(tag, env, ext);
13701
- if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion))
13702
- return versionCached;
13749
+ if (versionCached && isExpectedCachedBinary2(versionCached, pluginVersion)) {
13750
+ return { path: versionCached, source: "versioned cache" };
13751
+ }
13703
13752
  }
13704
13753
  try {
13705
13754
  const key = platformKey();
@@ -13714,7 +13763,7 @@ function findBinarySync(expectedVersion) {
13714
13763
  warn(`npm platform package binary v${npmVersion} does not match plugin v${pluginVersion}; skipping (continuing to PATH lookup)`);
13715
13764
  } else {
13716
13765
  const copied = copyToVersionedCache(resolved, npmVersion);
13717
- return copied ?? resolved;
13766
+ return { path: copied ?? resolved, source: "npm platform package" };
13718
13767
  }
13719
13768
  }
13720
13769
  } catch {}
@@ -13732,27 +13781,28 @@ function findBinarySync(expectedVersion) {
13732
13781
  }
13733
13782
  const usable = probeBinaryCandidate(candidate, "PATH", expectedVersion);
13734
13783
  if (usable)
13735
- return usable;
13784
+ return { path: usable, source: "PATH" };
13736
13785
  }
13737
13786
  } catch {}
13738
13787
  const cargoPath = join7(homeDirFromEnv(env), ".cargo", "bin", `aft${ext}`);
13739
13788
  if (existsSync5(cargoPath)) {
13740
13789
  const usable = probeBinaryCandidate(cargoPath, "cargo", expectedVersion);
13741
13790
  if (usable)
13742
- return usable;
13791
+ return { path: usable, source: "cargo" };
13743
13792
  }
13744
13793
  return null;
13745
13794
  }
13746
13795
  async function findBinary(expectedVersion) {
13747
13796
  const syncResult = findBinarySync(expectedVersion);
13748
13797
  if (syncResult) {
13749
- log(`Resolved binary: ${syncResult}`);
13750
13798
  return syncResult;
13751
13799
  }
13752
13800
  log("Binary not found locally, attempting auto-download...");
13753
13801
  const downloaded = await ensureBinaryForResolver(expectedVersion);
13754
- if (downloaded)
13802
+ if (downloaded) {
13803
+ logBinaryResolution({ path: downloaded, source: "auto-download" });
13755
13804
  return downloaded;
13805
+ }
13756
13806
  throw new Error([
13757
13807
  "Could not find the `aft` binary.",
13758
13808
  "",
@@ -37984,6 +38034,7 @@ var HASHLINE_EDIT_DESCRIPTION = [
37984
38034
  "",
37985
38035
  "Quick reference:",
37986
38036
  "- Header: `[path#TAG]`; TAG is exactly four hexadecimal digits from a current tagged read. Read every addressed row and gap boundary; REM and MV require a whole-file tagged read. Re-read after an edit before chaining: an edit-response tag can retain only changed context.",
38037
+ "- Same canonical path: multiple sections compose in patch order against pre-request coordinates.",
37987
38038
  "- Addresses: `0` (BOF), `N` (one line), `N.=M` (range; `N..=M`/`N..M` also work), `<N`/`>N` (gap before/after), `N*`/`<N*`/`>N*` (block), and `$`/`$-K` (EOF-relative). A plain `N` PUT replaces; use `<N` or `>N` to insert.",
37988
38039
  "- PUT text: `PUT <address>:` followed by one or more `+` body rows (`+` alone is blank). A final patch newline is allowed. PUT without `:` copies `@name` (or the anonymous register) and takes no body; names use `@` plus ASCII letters, digits, `_`, or `-`.",
37989
38040
  "- CUT: `CUT <address> [@name]`. REM: bare `REM` only, removing the whole file. MV: `MV <destination>` (one whitespace-free path, optional matching quotes), once and after any line operations. `*** Begin Patch`/`*** End Patch` is an optional envelope."
@@ -39658,7 +39709,7 @@ var PLUGIN_VERSION = (() => {
39658
39709
  return "0.0.0";
39659
39710
  }
39660
39711
  })();
39661
- var ANNOUNCEMENT_VERSION = "0.52.0";
39712
+ var ANNOUNCEMENT_VERSION = "0.52.1";
39662
39713
  var ANNOUNCEMENT_FEATURES = [
39663
39714
  "Callgraph stays consistent under load: edits arriving mid-rebuild can no longer be silently lost from navigation results.",
39664
39715
  "aft_zoom handles real-world .jsonc: files with comment banners above the opening brace now resolve, and not-found errors point at the segment that actually failed (thanks @iceteaSA).",
@@ -1 +1 @@
1
- {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,qBAAqB,CAAC;AAInF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiDjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AA+OtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAoIjE;AAkrBD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4BnF"}
1
+ {"version":3,"file":"hoisted.d.ts","sourceRoot":"","sources":["../../src/tools/hoisted.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAe,cAAc,EAAc,MAAM,qBAAqB,CAAC;AAInF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAiDjD,wEAAwE;AACxE,eAAO,MAAM,wBAAwB,GAAI,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,OAAO,MAAM,KAAG,MAChD,CAAC;AA+OtC;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CAoIjE;AAmrBD;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA0B/E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CA4BnF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.52.0",
3
+ "version": "0.52.1",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for Agent File Tools (AFT) — tree-sitter and lsp powered code analysis",
6
6
  "main": "dist/index.js",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@clack/prompts": "^1.6.0",
37
- "@cortexkit/aft-bridge": "0.52.0",
37
+ "@cortexkit/aft-bridge": "0.52.1",
38
38
  "@opentui/core": "0.4.3",
39
39
  "@opentui/solid": "0.4.3",
40
40
  "comment-json": "^4.6.2",
@@ -43,12 +43,12 @@
43
43
  "zod": "^4.4.3"
44
44
  },
45
45
  "optionalDependencies": {
46
- "@cortexkit/aft-darwin-arm64": "0.52.0",
47
- "@cortexkit/aft-darwin-x64": "0.52.0",
48
- "@cortexkit/aft-linux-arm64": "0.52.0",
49
- "@cortexkit/aft-linux-x64": "0.52.0",
50
- "@cortexkit/aft-win32-arm64": "0.52.0",
51
- "@cortexkit/aft-win32-x64": "0.52.0"
46
+ "@cortexkit/aft-darwin-arm64": "0.52.1",
47
+ "@cortexkit/aft-darwin-x64": "0.52.1",
48
+ "@cortexkit/aft-linux-arm64": "0.52.1",
49
+ "@cortexkit/aft-linux-x64": "0.52.1",
50
+ "@cortexkit/aft-win32-arm64": "0.52.1",
51
+ "@cortexkit/aft-win32-x64": "0.52.1"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@opencode-ai/plugin": "^1.17.11",