@cortexkit/aft-opencode 0.51.0 → 0.51.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +81 -17
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -8532,6 +8532,13 @@ class BridgeTransportUnavailableError extends Error {
8532
8532
  this.name = "BridgeTransportUnavailableError";
8533
8533
  }
8534
8534
  }
8535
+
8536
+ class BridgeTransportUnknownOutcomeError extends BridgeTransportUnavailableError {
8537
+ constructor(message, options) {
8538
+ super(message, options);
8539
+ this.name = "BridgeTransportUnknownOutcomeError";
8540
+ }
8541
+ }
8535
8542
  function isBridgeTransportTimeout(err) {
8536
8543
  return err instanceof Error && err.code === "transport_timeout";
8537
8544
  }
@@ -8673,6 +8680,20 @@ class BinaryBridge {
8673
8680
  isAlive() {
8674
8681
  return this.process !== null && this.process.exitCode === null && !this.process.killed;
8675
8682
  }
8683
+ invalidateTransportProcess(error2) {
8684
+ const proc = this.process;
8685
+ if (!proc)
8686
+ return;
8687
+ this.process = null;
8688
+ this.spawnedBinaryFingerprint = null;
8689
+ if (proc.exitCode === null && !proc.killed) {
8690
+ proc.kill("SIGKILL");
8691
+ }
8692
+ this.clearRestartResetTimer();
8693
+ this.configured = false;
8694
+ this.outstandingBackgroundTaskIds.clear();
8695
+ this.rejectAllPending(error2 instanceof BridgeTransportUnknownOutcomeError ? error2 : new BridgeTransportUnknownOutcomeError(error2.message, { cause: error2 }));
8696
+ }
8676
8697
  hasPendingRequests() {
8677
8698
  return this.pending.size > 0;
8678
8699
  }
@@ -8794,6 +8815,12 @@ class BinaryBridge {
8794
8815
  if (!this.configured) {
8795
8816
  if (command !== "configure" && command !== "version") {
8796
8817
  if (!this._configurePromise) {
8818
+ const configuringChild = this.process;
8819
+ const requireConfiguringChild = () => {
8820
+ if (this.process !== configuringChild) {
8821
+ throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge process changed during configure; retry on replacement`);
8822
+ }
8823
+ };
8797
8824
  const sessionIdForConfigure = typeof params.session_id === "string" ? params.session_id : undefined;
8798
8825
  this._configurePromise = (async () => {
8799
8826
  try {
@@ -8802,11 +8829,14 @@ class BinaryBridge {
8802
8829
  ...this.configOverrides,
8803
8830
  ...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
8804
8831
  }, implicitTransportOptions);
8832
+ requireConfiguringChild();
8805
8833
  if (configResult.success === false) {
8806
8834
  throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
8807
8835
  }
8808
8836
  await this.deliverConfigureWarnings(configResult, params, options);
8837
+ requireConfiguringChild();
8809
8838
  await this.checkVersion(implicitTransportOptions);
8839
+ requireConfiguringChild();
8810
8840
  if (!this.isAlive()) {
8811
8841
  throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge died during version check. Check logs: ${this.getLogFilePathVia()}`);
8812
8842
  }
@@ -8838,6 +8868,7 @@ class BinaryBridge {
8838
8868
  `;
8839
8869
  const keepBridgeOnTimeout = passive || options?.keepBridgeOnTimeout === true;
8840
8870
  let requestSentAt = Date.now();
8871
+ const child = this.process;
8841
8872
  const response = await new Promise((resolve2, reject) => {
8842
8873
  const timer = setTimeout(() => {
8843
8874
  const entry = this.pending.get(id);
@@ -8874,23 +8905,36 @@ class BinaryBridge {
8874
8905
  this.handleTimeout(requestSessionId);
8875
8906
  }, effectiveTimeoutMs);
8876
8907
  this.pending.set(id, { resolve: resolve2, reject, timer, onProgress: options?.onProgress, command });
8877
- if (!this.process?.stdin?.writable) {
8908
+ if (!child?.stdin?.writable) {
8878
8909
  this.pending.delete(id);
8879
8910
  clearTimeout(timer);
8880
- reject(new BridgeTransportUnavailableError(`${this.errorPrefix} stdin not writable for command "${command}"`));
8911
+ const error2 = new BridgeTransportUnavailableError(`${this.errorPrefix} stdin not writable for command "${command}"`);
8912
+ reject(error2);
8913
+ if (this.process === child)
8914
+ this.invalidateTransportProcess(error2);
8881
8915
  return;
8882
8916
  }
8883
8917
  requestSentAt = Date.now();
8884
- this.process.stdin.write(line, (err) => {
8885
- if (err) {
8886
- const entry = this.pending.get(id);
8887
- if (entry) {
8888
- this.pending.delete(id);
8889
- clearTimeout(entry.timer);
8890
- entry.reject(new BridgeTransportUnavailableError(`${this.errorPrefix} Failed to write to stdin: ${err.message}`, { cause: err }));
8891
- }
8918
+ const handleWriteFailure = (cause) => {
8919
+ const writeError = cause instanceof Error ? cause : new Error(String(cause));
8920
+ const error2 = new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Failed to write to stdin: ${writeError.message}`, { cause: writeError });
8921
+ const entry = this.pending.get(id);
8922
+ if (entry) {
8923
+ this.pending.delete(id);
8924
+ clearTimeout(entry.timer);
8925
+ entry.reject(error2);
8892
8926
  }
8893
- });
8927
+ if (this.process === child)
8928
+ this.invalidateTransportProcess(error2);
8929
+ };
8930
+ try {
8931
+ child.stdin.write(line, (err) => {
8932
+ if (err)
8933
+ handleWriteFailure(err);
8934
+ });
8935
+ } catch (err) {
8936
+ handleWriteFailure(err);
8937
+ }
8894
8938
  });
8895
8939
  if (command === "configure" && response.success === true && options?.markConfiguredOnSuccess !== false) {
8896
8940
  this.configured = true;
@@ -9048,8 +9092,11 @@ class BinaryBridge {
9048
9092
  });
9049
9093
  }
9050
9094
  ensureSpawned(triggeringSessionId) {
9051
- if (this.isAlive())
9095
+ if (this.isAlive() && this.process?.stdin?.writable)
9052
9096
  return;
9097
+ if (this.process !== null) {
9098
+ this.invalidateTransportProcess(new BridgeTransportUnavailableError(`${this.errorPrefix} Child stdin is not writable`));
9099
+ }
9053
9100
  this.spawnProcess(triggeringSessionId);
9054
9101
  }
9055
9102
  spawnProcess(triggeringSessionId) {
@@ -9102,9 +9149,13 @@ class BinaryBridge {
9102
9149
  const currentChild = child;
9103
9150
  const stdoutDecoder = new StringDecoder("utf8");
9104
9151
  child.stdout?.on("data", (chunk) => {
9152
+ if (this.process !== currentChild)
9153
+ return;
9105
9154
  this.onStdoutData(stdoutDecoder.write(chunk));
9106
9155
  });
9107
9156
  child.stdout?.on("end", () => {
9157
+ if (this.process !== currentChild)
9158
+ return;
9108
9159
  const remaining = stdoutDecoder.end();
9109
9160
  if (remaining)
9110
9161
  this.onStdoutData(remaining);
@@ -9112,9 +9163,13 @@ class BinaryBridge {
9112
9163
  });
9113
9164
  const stderrDecoder = new StringDecoder("utf8");
9114
9165
  child.stderr?.on("data", (chunk) => {
9166
+ if (this.process !== currentChild)
9167
+ return;
9115
9168
  this.onStderrData(stderrDecoder.write(chunk));
9116
9169
  });
9117
9170
  child.stderr?.on("end", () => {
9171
+ if (this.process !== currentChild)
9172
+ return;
9118
9173
  const remaining = stderrDecoder.end();
9119
9174
  if (remaining)
9120
9175
  this.onStderrData(remaining);
@@ -9137,7 +9192,7 @@ class BinaryBridge {
9137
9192
  this.process = null;
9138
9193
  this.configured = false;
9139
9194
  this.clearRestartResetTimer();
9140
- this.rejectAllPending(new BridgeTransportUnavailableError(`${this.errorPrefix} Binary killed by ${signal}`));
9195
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Binary killed by ${signal}`));
9141
9196
  return;
9142
9197
  }
9143
9198
  this.handleCrash();
@@ -9315,7 +9370,7 @@ class BinaryBridge {
9315
9370
  handleTimeout(triggeringSessionId) {
9316
9371
  this.consecutiveRequestTimeouts = 0;
9317
9372
  this.spawnedBinaryFingerprint = null;
9318
- this.rejectAllPending(new Error(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
9373
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
9319
9374
  this.outstandingBackgroundTaskIds.clear();
9320
9375
  if (this.process) {
9321
9376
  this.process.kill("SIGKILL");
@@ -9352,7 +9407,7 @@ class BinaryBridge {
9352
9407
  if (tail) {
9353
9408
  this.errorVia(`Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""}.${tail}`);
9354
9409
  }
9355
- this.rejectAllPending(new BridgeTransportUnavailableError(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`, { cause }));
9410
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`, { cause }));
9356
9411
  if (this._retiringDueToBinaryChange) {
9357
9412
  this.logVia("Binary exited while retiring after an on-disk update; skipping auto-restart");
9358
9413
  return;
@@ -13945,6 +14000,7 @@ function toolErrorFromResponse(command, response) {
13945
14000
  }
13946
14001
  var BASH_TRANSPORT_DISPOSITION = "The transport to the AFT daemon was interrupted; no background task was created for this command and no task ID exists. Re-run the command. Do not poll bash_status for it.";
13947
14002
  var SUBC_MODULE_RESTART_DISPOSITION = "The AFT daemon module restarted while this call was in flight, so its outcome is UNKNOWN: it may or may not have executed. Verify actual state before re-running, and never blind-retry a mutation.";
14003
+ var BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION = "The standalone AFT transport failed after this call may have been sent, so its outcome is UNKNOWN: it may or may not have executed. Verify actual state before re-running, and never blind-retry a mutation.";
13948
14004
  function isRouteGoodbyeError(error2) {
13949
14005
  if (!(error2 instanceof SubcError))
13950
14006
  return false;
@@ -13967,6 +14023,8 @@ function isBashTransportDeadError(error2) {
13967
14023
  if (!(error2 instanceof Error) || hasEngineResponse(error2) || isRouteGoodbyeError(error2)) {
13968
14024
  return false;
13969
14025
  }
14026
+ if (error2 instanceof BridgeTransportUnknownOutcomeError)
14027
+ return false;
13970
14028
  return error2 instanceof BridgeTransportUnavailableError || error2 instanceof SubcTransportShuttingDownError || isConsumerReconnectTransient(error2) || error2 instanceof StaleRouteHandleError || error2 instanceof SubcRootGenerationExpiredError || error2 instanceof SubcRootReapedError;
13971
14029
  }
13972
14030
  function isTransportClassError(error2) {
@@ -13975,6 +14033,12 @@ function isTransportClassError(error2) {
13975
14033
  function adaptToolError(command, error2) {
13976
14034
  if (!(error2 instanceof Error))
13977
14035
  return error2;
14036
+ if (error2 instanceof BridgeTransportUnknownOutcomeError) {
14037
+ if (error2.message.includes(BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION))
14038
+ return error2;
14039
+ error2.message = error2.message ? `${error2.message} ${BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION}` : BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION;
14040
+ return error2;
14041
+ }
13978
14042
  if (isRouteGoodbyeError(error2)) {
13979
14043
  if (error2.message.includes(SUBC_MODULE_RESTART_DISPOSITION))
13980
14044
  return error2;
@@ -39979,7 +40043,7 @@ function semanticTools(ctx) {
39979
40043
  query: arg3(z15.string().describe("Concept, regex, literal text, filename, or capability to find. Examples: 'fuzzy match with whitespace tolerance', '^export', 'Cargo.lock'.")),
39980
40044
  topK: arg3(optionalInt(1, 100).describe("Number of results (default: 10, max: 100)")),
39981
40045
  includeTests: arg3(z15.boolean().optional().describe("Include test files (*.test.*, *_test.rs, __tests__/, …) plus test-support, fixture, mock, snapshot, and corpus files. Defaults to false.")),
39982
- path: arg3(z15.string().optional().describe("Search a different project root (absolute or ~ path). Requires that project to have been indexed by AFT."))
40046
+ path: arg3(z15.string().optional().describe("Only set this to search a different Git project (absolute or ~ path). Omit it for the current configured workspace, including non-Git workspace roots; this is not a subdirectory filter. Unindexed external projects use a bounded lexical fallback."))
39983
40047
  },
39984
40048
  execute: async (args, context) => {
39985
40049
  if (isEmptyParam(args.query) || typeof args.query !== "string" || args.query.trim().length === 0) {
@@ -40182,7 +40246,7 @@ var PLUGIN_VERSION = (() => {
40182
40246
  return "0.0.0";
40183
40247
  }
40184
40248
  })();
40185
- var ANNOUNCEMENT_VERSION = "0.51.0";
40249
+ var ANNOUNCEMENT_VERSION = "0.51.2";
40186
40250
  var ANNOUNCEMENT_FEATURES = [
40187
40251
  "Callgraph stays consistent under load: edits arriving mid-rebuild can no longer be silently lost from navigation results.",
40188
40252
  "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).",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft-opencode",
3
- "version": "0.51.0",
3
+ "version": "0.51.2",
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.51.0",
37
+ "@cortexkit/aft-bridge": "0.51.2",
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.51.0",
47
- "@cortexkit/aft-darwin-x64": "0.51.0",
48
- "@cortexkit/aft-linux-arm64": "0.51.0",
49
- "@cortexkit/aft-linux-x64": "0.51.0",
50
- "@cortexkit/aft-win32-arm64": "0.51.0",
51
- "@cortexkit/aft-win32-x64": "0.51.0"
46
+ "@cortexkit/aft-darwin-arm64": "0.51.2",
47
+ "@cortexkit/aft-darwin-x64": "0.51.2",
48
+ "@cortexkit/aft-linux-arm64": "0.51.2",
49
+ "@cortexkit/aft-linux-x64": "0.51.2",
50
+ "@cortexkit/aft-win32-arm64": "0.51.2",
51
+ "@cortexkit/aft-win32-x64": "0.51.2"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@opencode-ai/plugin": "^1.17.11",