@cortexkit/aft-pi 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 +89 -25
  2. package/package.json +8 -8
package/dist/index.js CHANGED
@@ -8613,6 +8613,13 @@ class BridgeTransportUnavailableError extends Error {
8613
8613
  this.name = "BridgeTransportUnavailableError";
8614
8614
  }
8615
8615
  }
8616
+
8617
+ class BridgeTransportUnknownOutcomeError extends BridgeTransportUnavailableError {
8618
+ constructor(message, options) {
8619
+ super(message, options);
8620
+ this.name = "BridgeTransportUnknownOutcomeError";
8621
+ }
8622
+ }
8616
8623
  function isBridgeTransportTimeout(err) {
8617
8624
  return err instanceof Error && err.code === "transport_timeout";
8618
8625
  }
@@ -8754,6 +8761,20 @@ class BinaryBridge {
8754
8761
  isAlive() {
8755
8762
  return this.process !== null && this.process.exitCode === null && !this.process.killed;
8756
8763
  }
8764
+ invalidateTransportProcess(error2) {
8765
+ const proc = this.process;
8766
+ if (!proc)
8767
+ return;
8768
+ this.process = null;
8769
+ this.spawnedBinaryFingerprint = null;
8770
+ if (proc.exitCode === null && !proc.killed) {
8771
+ proc.kill("SIGKILL");
8772
+ }
8773
+ this.clearRestartResetTimer();
8774
+ this.configured = false;
8775
+ this.outstandingBackgroundTaskIds.clear();
8776
+ this.rejectAllPending(error2 instanceof BridgeTransportUnknownOutcomeError ? error2 : new BridgeTransportUnknownOutcomeError(error2.message, { cause: error2 }));
8777
+ }
8757
8778
  hasPendingRequests() {
8758
8779
  return this.pending.size > 0;
8759
8780
  }
@@ -8875,6 +8896,12 @@ class BinaryBridge {
8875
8896
  if (!this.configured) {
8876
8897
  if (command !== "configure" && command !== "version") {
8877
8898
  if (!this._configurePromise) {
8899
+ const configuringChild = this.process;
8900
+ const requireConfiguringChild = () => {
8901
+ if (this.process !== configuringChild) {
8902
+ throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge process changed during configure; retry on replacement`);
8903
+ }
8904
+ };
8878
8905
  const sessionIdForConfigure = typeof params.session_id === "string" ? params.session_id : undefined;
8879
8906
  this._configurePromise = (async () => {
8880
8907
  try {
@@ -8883,11 +8910,14 @@ class BinaryBridge {
8883
8910
  ...this.configOverrides,
8884
8911
  ...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
8885
8912
  }, implicitTransportOptions);
8913
+ requireConfiguringChild();
8886
8914
  if (configResult.success === false) {
8887
8915
  throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
8888
8916
  }
8889
8917
  await this.deliverConfigureWarnings(configResult, params, options);
8918
+ requireConfiguringChild();
8890
8919
  await this.checkVersion(implicitTransportOptions);
8920
+ requireConfiguringChild();
8891
8921
  if (!this.isAlive()) {
8892
8922
  throw new BridgeTransportUnavailableError(`${this.errorPrefix} Bridge died during version check. Check logs: ${this.getLogFilePathVia()}`);
8893
8923
  }
@@ -8919,6 +8949,7 @@ class BinaryBridge {
8919
8949
  `;
8920
8950
  const keepBridgeOnTimeout = passive || options?.keepBridgeOnTimeout === true;
8921
8951
  let requestSentAt = Date.now();
8952
+ const child = this.process;
8922
8953
  const response = await new Promise((resolve2, reject) => {
8923
8954
  const timer = setTimeout(() => {
8924
8955
  const entry = this.pending.get(id);
@@ -8955,23 +8986,36 @@ class BinaryBridge {
8955
8986
  this.handleTimeout(requestSessionId);
8956
8987
  }, effectiveTimeoutMs);
8957
8988
  this.pending.set(id, { resolve: resolve2, reject, timer, onProgress: options?.onProgress, command });
8958
- if (!this.process?.stdin?.writable) {
8989
+ if (!child?.stdin?.writable) {
8959
8990
  this.pending.delete(id);
8960
8991
  clearTimeout(timer);
8961
- reject(new BridgeTransportUnavailableError(`${this.errorPrefix} stdin not writable for command "${command}"`));
8992
+ const error2 = new BridgeTransportUnavailableError(`${this.errorPrefix} stdin not writable for command "${command}"`);
8993
+ reject(error2);
8994
+ if (this.process === child)
8995
+ this.invalidateTransportProcess(error2);
8962
8996
  return;
8963
8997
  }
8964
8998
  requestSentAt = Date.now();
8965
- this.process.stdin.write(line, (err) => {
8966
- if (err) {
8967
- const entry = this.pending.get(id);
8968
- if (entry) {
8969
- this.pending.delete(id);
8970
- clearTimeout(entry.timer);
8971
- entry.reject(new BridgeTransportUnavailableError(`${this.errorPrefix} Failed to write to stdin: ${err.message}`, { cause: err }));
8972
- }
8999
+ const handleWriteFailure = (cause) => {
9000
+ const writeError = cause instanceof Error ? cause : new Error(String(cause));
9001
+ const error2 = new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Failed to write to stdin: ${writeError.message}`, { cause: writeError });
9002
+ const entry = this.pending.get(id);
9003
+ if (entry) {
9004
+ this.pending.delete(id);
9005
+ clearTimeout(entry.timer);
9006
+ entry.reject(error2);
8973
9007
  }
8974
- });
9008
+ if (this.process === child)
9009
+ this.invalidateTransportProcess(error2);
9010
+ };
9011
+ try {
9012
+ child.stdin.write(line, (err) => {
9013
+ if (err)
9014
+ handleWriteFailure(err);
9015
+ });
9016
+ } catch (err) {
9017
+ handleWriteFailure(err);
9018
+ }
8975
9019
  });
8976
9020
  if (command === "configure" && response.success === true && options?.markConfiguredOnSuccess !== false) {
8977
9021
  this.configured = true;
@@ -9129,8 +9173,11 @@ class BinaryBridge {
9129
9173
  });
9130
9174
  }
9131
9175
  ensureSpawned(triggeringSessionId) {
9132
- if (this.isAlive())
9176
+ if (this.isAlive() && this.process?.stdin?.writable)
9133
9177
  return;
9178
+ if (this.process !== null) {
9179
+ this.invalidateTransportProcess(new BridgeTransportUnavailableError(`${this.errorPrefix} Child stdin is not writable`));
9180
+ }
9134
9181
  this.spawnProcess(triggeringSessionId);
9135
9182
  }
9136
9183
  spawnProcess(triggeringSessionId) {
@@ -9183,9 +9230,13 @@ class BinaryBridge {
9183
9230
  const currentChild = child;
9184
9231
  const stdoutDecoder = new StringDecoder("utf8");
9185
9232
  child.stdout?.on("data", (chunk) => {
9233
+ if (this.process !== currentChild)
9234
+ return;
9186
9235
  this.onStdoutData(stdoutDecoder.write(chunk));
9187
9236
  });
9188
9237
  child.stdout?.on("end", () => {
9238
+ if (this.process !== currentChild)
9239
+ return;
9189
9240
  const remaining = stdoutDecoder.end();
9190
9241
  if (remaining)
9191
9242
  this.onStdoutData(remaining);
@@ -9193,9 +9244,13 @@ class BinaryBridge {
9193
9244
  });
9194
9245
  const stderrDecoder = new StringDecoder("utf8");
9195
9246
  child.stderr?.on("data", (chunk) => {
9247
+ if (this.process !== currentChild)
9248
+ return;
9196
9249
  this.onStderrData(stderrDecoder.write(chunk));
9197
9250
  });
9198
9251
  child.stderr?.on("end", () => {
9252
+ if (this.process !== currentChild)
9253
+ return;
9199
9254
  const remaining = stderrDecoder.end();
9200
9255
  if (remaining)
9201
9256
  this.onStderrData(remaining);
@@ -9218,7 +9273,7 @@ class BinaryBridge {
9218
9273
  this.process = null;
9219
9274
  this.configured = false;
9220
9275
  this.clearRestartResetTimer();
9221
- this.rejectAllPending(new BridgeTransportUnavailableError(`${this.errorPrefix} Binary killed by ${signal}`));
9276
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Binary killed by ${signal}`));
9222
9277
  return;
9223
9278
  }
9224
9279
  this.handleCrash();
@@ -9396,7 +9451,7 @@ class BinaryBridge {
9396
9451
  handleTimeout(triggeringSessionId) {
9397
9452
  this.consecutiveRequestTimeouts = 0;
9398
9453
  this.spawnedBinaryFingerprint = null;
9399
- this.rejectAllPending(new Error(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
9454
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
9400
9455
  this.outstandingBackgroundTaskIds.clear();
9401
9456
  if (this.process) {
9402
9457
  this.process.kill("SIGKILL");
@@ -9433,7 +9488,7 @@ class BinaryBridge {
9433
9488
  if (tail) {
9434
9489
  this.errorVia(`Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""}.${tail}`);
9435
9490
  }
9436
- this.rejectAllPending(new BridgeTransportUnavailableError(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`, { cause }));
9491
+ this.rejectAllPending(new BridgeTransportUnknownOutcomeError(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`, { cause }));
9437
9492
  if (this._retiringDueToBinaryChange) {
9438
9493
  this.logVia("Binary exited while retiring after an on-disk update; skipping auto-restart");
9439
9494
  return;
@@ -14340,6 +14395,7 @@ function toolErrorFromResponse(command, response) {
14340
14395
  }
14341
14396
  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.";
14342
14397
  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.";
14398
+ 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.";
14343
14399
  function isRouteGoodbyeError(error2) {
14344
14400
  if (!(error2 instanceof SubcError))
14345
14401
  return false;
@@ -14362,6 +14418,8 @@ function isBashTransportDeadError(error2) {
14362
14418
  if (!(error2 instanceof Error) || hasEngineResponse(error2) || isRouteGoodbyeError(error2)) {
14363
14419
  return false;
14364
14420
  }
14421
+ if (error2 instanceof BridgeTransportUnknownOutcomeError)
14422
+ return false;
14365
14423
  return error2 instanceof BridgeTransportUnavailableError || error2 instanceof SubcTransportShuttingDownError || isConsumerReconnectTransient(error2) || error2 instanceof StaleRouteHandleError || error2 instanceof SubcRootGenerationExpiredError || error2 instanceof SubcRootReapedError;
14366
14424
  }
14367
14425
  function isTransportClassError(error2) {
@@ -14370,6 +14428,12 @@ function isTransportClassError(error2) {
14370
14428
  function adaptToolError(command, error2) {
14371
14429
  if (!(error2 instanceof Error))
14372
14430
  return error2;
14431
+ if (error2 instanceof BridgeTransportUnknownOutcomeError) {
14432
+ if (error2.message.includes(BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION))
14433
+ return error2;
14434
+ error2.message = error2.message ? `${error2.message} ${BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION}` : BRIDGE_TRANSPORT_UNKNOWN_OUTCOME_DISPOSITION;
14435
+ return error2;
14436
+ }
14373
14437
  if (isRouteGoodbyeError(error2)) {
14374
14438
  if (error2.message.includes(SUBC_MODULE_RESTART_DISPOSITION))
14375
14439
  return error2;
@@ -17953,7 +18017,7 @@ import {
17953
18017
  // package.json
17954
18018
  var package_default = {
17955
18019
  name: "@cortexkit/aft-pi",
17956
- version: "0.51.0",
18020
+ version: "0.51.2",
17957
18021
  type: "module",
17958
18022
  description: "Pi coding agent extension for Agent File Tools (AFT) — tree-sitter and LSP-powered code analysis",
17959
18023
  main: "dist/index.js",
@@ -17976,19 +18040,19 @@ var package_default = {
17976
18040
  "test:unit": "bun test src/__tests__ --path-ignore-patterns 'src/__tests__/e2e/**'"
17977
18041
  },
17978
18042
  dependencies: {
17979
- "@cortexkit/aft-bridge": "0.51.0",
18043
+ "@cortexkit/aft-bridge": "0.51.2",
17980
18044
  "comment-json": "^5.0.0",
17981
18045
  diff: "^8.0.4",
17982
18046
  typebox: "1.1.38",
17983
18047
  zod: "^4.4.3"
17984
18048
  },
17985
18049
  optionalDependencies: {
17986
- "@cortexkit/aft-darwin-arm64": "0.51.0",
17987
- "@cortexkit/aft-darwin-x64": "0.51.0",
17988
- "@cortexkit/aft-linux-arm64": "0.51.0",
17989
- "@cortexkit/aft-linux-x64": "0.51.0",
17990
- "@cortexkit/aft-win32-arm64": "0.51.0",
17991
- "@cortexkit/aft-win32-x64": "0.51.0"
18050
+ "@cortexkit/aft-darwin-arm64": "0.51.2",
18051
+ "@cortexkit/aft-darwin-x64": "0.51.2",
18052
+ "@cortexkit/aft-linux-arm64": "0.51.2",
18053
+ "@cortexkit/aft-linux-x64": "0.51.2",
18054
+ "@cortexkit/aft-win32-arm64": "0.51.2",
18055
+ "@cortexkit/aft-win32-x64": "0.51.2"
17992
18056
  },
17993
18057
  devDependencies: {
17994
18058
  "@earendil-works/pi-coding-agent": "^0.80.2",
@@ -38880,7 +38944,7 @@ var SearchParams2 = Type13.Object({
38880
38944
  description: "Include test files (*.test.*, *_test.rs, __tests__/, …) plus test-support, fixture, mock, snapshot, and corpus files. Defaults to false."
38881
38945
  })),
38882
38946
  path: Type13.Optional(Type13.String({
38883
- description: "Search a different project root (absolute or ~ path). Requires that project to have been indexed by AFT."
38947
+ description: "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."
38884
38948
  }))
38885
38949
  });
38886
38950
  function buildSemanticSections(args, payload, theme) {
@@ -39251,7 +39315,7 @@ var PLUGIN_VERSION = (() => {
39251
39315
  return "0.0.0";
39252
39316
  }
39253
39317
  })();
39254
- var ANNOUNCEMENT_VERSION = "0.51.0";
39318
+ var ANNOUNCEMENT_VERSION = "0.51.2";
39255
39319
  var ANNOUNCEMENT_FEATURES = [
39256
39320
  "Callgraph stays consistent under load: edits arriving mid-rebuild can no longer be silently lost from navigation results.",
39257
39321
  "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-pi",
3
- "version": "0.51.0",
3
+ "version": "0.51.2",
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.51.0",
26
+ "@cortexkit/aft-bridge": "0.51.2",
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.51.0",
34
- "@cortexkit/aft-darwin-x64": "0.51.0",
35
- "@cortexkit/aft-linux-arm64": "0.51.0",
36
- "@cortexkit/aft-linux-x64": "0.51.0",
37
- "@cortexkit/aft-win32-arm64": "0.51.0",
38
- "@cortexkit/aft-win32-x64": "0.51.0"
33
+ "@cortexkit/aft-darwin-arm64": "0.51.2",
34
+ "@cortexkit/aft-darwin-x64": "0.51.2",
35
+ "@cortexkit/aft-linux-arm64": "0.51.2",
36
+ "@cortexkit/aft-linux-x64": "0.51.2",
37
+ "@cortexkit/aft-win32-arm64": "0.51.2",
38
+ "@cortexkit/aft-win32-x64": "0.51.2"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@earendil-works/pi-coding-agent": "^0.80.2",