@cortexkit/aft 0.39.1 → 0.39.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAG3D,OAAO,EAEL,KAAK,gBAAgB,EAKtB,MAAM,uBAAuB,CAAC;AAe/B,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,qBAAqB,CAAC;AAOvE,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,WAAW,GAAG,cAAc,CAAC;AAE9E,eAAO,MAAM,2BAA2B,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,EAapF,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,iBAAiB,EAAqB,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,WAAW,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAkHvE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAOnE;AA4BD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAgD5B;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,IAAI,sBAAsB,CAsDzD;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC5E,OAAO,EAAE,MAAM,CAAC;CACjB;AA0ID,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,cAAc,EAAE,EAC1B,MAAM,EAAE,gBAAgB,GACvB,iBAAiB,EAAE,CAsErB;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAIvE;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAK9F;AAwKD,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAK1F;AAsGD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AA4DD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D"}
1
+ {"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAI3D,OAAO,EAEL,KAAK,gBAAgB,EAKtB,MAAM,uBAAuB,CAAC;AAe/B,OAAO,EAAE,KAAK,WAAW,EAAkB,MAAM,qBAAqB,CAAC;AAOvE,MAAM,MAAM,iBAAiB,GAAG,cAAc,GAAG,WAAW,GAAG,cAAc,CAAC;AAE9E,eAAO,MAAM,2BAA2B,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,EAapF,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,iBAAiB,EAAqB,CAAC;AAEhF,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,WAAW,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH;AAED,MAAM,WAAW,iBAAiB;IAChC,cAAc,CAAC,EAAE,MAAM,WAAW,CAAC;IACnC,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAkHvE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAOnE;AA4BD,wBAAsB,iBAAiB,CACrC,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,EAAE,SAAS,iBAAiB,EAAE,EACrC,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,iBAAiB,CAAC,CAgD5B;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,gBAAgB,IAAI,sBAAsB,CAsDzD;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,QAAQ,GAAG,eAAe,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC5E,OAAO,EAAE,MAAM,CAAC;CACjB;AA0ID,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,cAAc,EAAE,EAC1B,MAAM,EAAE,gBAAgB,GACvB,iBAAiB,EAAE,CAsErB;AAED,wBAAgB,+BAA+B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAIvE;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAK9F;AAwKD,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,GAAG,MAAM,CAK1F;AAsGD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AA4DD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG7D"}
package/dist/index.js CHANGED
@@ -107,7 +107,10 @@ var init_active_logger = __esm(() => {
107
107
  // ../aft-bridge/dist/bash-hints.js
108
108
  var init_bash_hints = () => {};
109
109
  // ../aft-bridge/dist/command-timeouts.js
110
- var LONG_RUNNING_COMMAND_TIMEOUT_MS;
110
+ function isPassiveCommand(command) {
111
+ return PASSIVE_COMMANDS.has(command);
112
+ }
113
+ var LONG_RUNNING_COMMAND_TIMEOUT_MS, PASSIVE_COMMANDS, PASSIVE_COMMAND_TIMEOUT_MS = 5000;
111
114
  var init_command_timeouts = __esm(() => {
112
115
  LONG_RUNNING_COMMAND_TIMEOUT_MS = {
113
116
  callers: 60000,
@@ -119,6 +122,7 @@ var init_command_timeouts = __esm(() => {
119
122
  glob: 60000,
120
123
  semantic_search: 60000
121
124
  };
125
+ PASSIVE_COMMANDS = new Set(["status"]);
122
126
  });
123
127
 
124
128
  // ../aft-bridge/dist/status-bar.js
@@ -161,6 +165,10 @@ function bashTaskIdFrom(response) {
161
165
  function tagStderrLine(line) {
162
166
  return /^\[aft(-\w+)?\] /.test(line) ? line : `[aft] ${line}`;
163
167
  }
168
+ function shouldSurfaceStderrLine(line) {
169
+ const normalized = line.trim();
170
+ return !(normalized === `Error in cpuinfo: ${BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE}` || normalized === BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE);
171
+ }
164
172
  function compareSemver(a, b) {
165
173
  const [aMain, aPre] = a.split("-", 2);
166
174
  const [bMain, bPre] = b.split("-", 2);
@@ -226,7 +234,7 @@ function clampSemanticTimeout(configOverrides, bridgeTimeoutMs) {
226
234
  }
227
235
  };
228
236
  }
229
- var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, SEMANTIC_TIMEOUT_SAFETY_MARGIN_MS = 5000, MAX_STDOUT_BUFFER, STDOUT_BUFFER_COMPACT_THRESHOLD, TERMINAL_BASH_STATUSES, BridgeReplacedDuringVersionCheck, BinaryBridge;
237
+ var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, SEMANTIC_TIMEOUT_SAFETY_MARGIN_MS = 5000, MAX_STDOUT_BUFFER, STDOUT_BUFFER_COMPACT_THRESHOLD, TERMINAL_BASH_STATUSES, BENIGN_CPUINFO_PROC_CPUINFO_PARSE_FAILURE = "failed to parse processor information from /proc/cpuinfo", BridgeReplacedDuringVersionCheck, BinaryBridge;
230
238
  var init_bridge = __esm(() => {
231
239
  init_active_logger();
232
240
  init_command_timeouts();
@@ -264,6 +272,7 @@ var init_bridge = __esm(() => {
264
272
  _restartCount = 0;
265
273
  _shuttingDown = false;
266
274
  timeoutMs;
275
+ hangThreshold;
267
276
  maxRestarts;
268
277
  configured = false;
269
278
  _configurePromise = null;
@@ -288,6 +297,7 @@ var init_bridge = __esm(() => {
288
297
  this.binaryPath = binaryPath;
289
298
  this.cwd = cwd;
290
299
  this.timeoutMs = options?.timeoutMs ?? DEFAULT_BRIDGE_TIMEOUT_MS;
300
+ this.hangThreshold = options?.hangThreshold ?? BRIDGE_HANG_TIMEOUT_THRESHOLD;
291
301
  this.maxRestarts = options?.maxRestarts ?? 3;
292
302
  this.configOverrides = clampSemanticTimeout(configOverrides ?? {}, this.timeoutMs);
293
303
  this.minVersion = options?.minVersion;
@@ -405,7 +415,9 @@ var init_bridge = __esm(() => {
405
415
  if (requestSessionId && options?.configureWarningClient !== undefined) {
406
416
  this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
407
417
  }
408
- const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
418
+ const passive = isPassiveCommand(command);
419
+ const resolvedTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
420
+ const effectiveTimeoutMs = passive ? Math.min(resolvedTimeoutMs, PASSIVE_COMMAND_TIMEOUT_MS) : resolvedTimeoutMs;
409
421
  const implicitTransportOptions = {
410
422
  ...options?.transportTimeoutMs !== undefined || options?.timeoutMs !== undefined ? { transportTimeoutMs: effectiveTimeoutMs } : {},
411
423
  markConfiguredOnSuccess: false
@@ -455,7 +467,7 @@ var init_bridge = __esm(() => {
455
467
  }
456
468
  const line = `${JSON.stringify(request)}
457
469
  `;
458
- const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
470
+ const keepBridgeOnTimeout = passive || options?.keepBridgeOnTimeout === true;
459
471
  let requestSentAt = Date.now();
460
472
  const response = await new Promise((resolve, reject) => {
461
473
  const timer = setTimeout(() => {
@@ -477,7 +489,7 @@ var init_bridge = __esm(() => {
477
489
  const childActiveSinceRequest = this.lastChildActivityAt > requestSentAt;
478
490
  const consecutiveTimeouts = this.consecutiveRequestTimeouts + 1;
479
491
  this.consecutiveRequestTimeouts = consecutiveTimeouts;
480
- const keepWarm = childActiveSinceRequest || consecutiveTimeouts < BRIDGE_HANG_TIMEOUT_THRESHOLD;
492
+ const keepWarm = childActiveSinceRequest || consecutiveTimeouts < this.hangThreshold;
481
493
  const restartSuffix = keepWarm ? " — bridge kept warm" : " — restarting bridge";
482
494
  const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
483
495
  if (requestSessionId) {
@@ -772,7 +784,7 @@ var init_bridge = __esm(() => {
772
784
  `)) !== -1) {
773
785
  const line = this.stderrBuffer.slice(0, newlineIdx).replace(/\r$/, "");
774
786
  this.stderrBuffer = this.stderrBuffer.slice(newlineIdx + 1);
775
- if (!line)
787
+ if (!line || !shouldSurfaceStderrLine(line))
776
788
  continue;
777
789
  const tagged = tagStderrLine(line);
778
790
  this.logVia(tagged);
@@ -782,7 +794,7 @@ var init_bridge = __esm(() => {
782
794
  flushStderrBuffer() {
783
795
  const line = this.stderrBuffer.replace(/\r$/, "");
784
796
  this.stderrBuffer = "";
785
- if (!line)
797
+ if (!line || !shouldSurfaceStderrLine(line))
786
798
  return;
787
799
  const tagged = tagStderrLine(line);
788
800
  this.logVia(tagged);
@@ -1008,6 +1020,9 @@ var init_bridge = __esm(() => {
1008
1020
  }
1009
1021
  };
1010
1022
  });
1023
+
1024
+ // ../aft-bridge/dist/callgraph-format.js
1025
+ var init_callgraph_format = () => {};
1011
1026
  // ../aft-bridge/dist/platform.js
1012
1027
  var init_platform = () => {};
1013
1028
 
@@ -1304,6 +1319,7 @@ class BridgePool {
1304
1319
  this.projectConfigLoader = options.projectConfigLoader;
1305
1320
  this.bridgeOptions = {
1306
1321
  timeoutMs: options.timeoutMs,
1322
+ hangThreshold: options.hangThreshold,
1307
1323
  maxRestarts: options.maxRestarts,
1308
1324
  minVersion: options.minVersion,
1309
1325
  onVersionMismatch: options.onVersionMismatch,
@@ -1470,6 +1486,7 @@ var init_dist = __esm(() => {
1470
1486
  init_active_logger();
1471
1487
  init_bash_hints();
1472
1488
  init_bridge();
1489
+ init_callgraph_format();
1473
1490
  init_command_timeouts();
1474
1491
  init_downloader();
1475
1492
  init_migration();
@@ -12375,11 +12392,232 @@ var init_binary_cache = __esm(() => {
12375
12392
  init_paths2();
12376
12393
  });
12377
12394
 
12378
- // src/lib/lsp-cache.ts
12379
- import { existsSync as existsSync10, readdirSync as readdirSync5, rmSync as rmSync2, statSync as statSync6 } from "node:fs";
12395
+ // src/lib/sanitize.ts
12396
+ import { realpathSync as realpathSync2 } from "node:fs";
12397
+ import { homedir as homedir8, userInfo } from "node:os";
12398
+ function escapeRegex(value) {
12399
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12400
+ }
12401
+ function safeRealpath(p2) {
12402
+ try {
12403
+ return realpathSync2(p2);
12404
+ } catch {
12405
+ return null;
12406
+ }
12407
+ }
12408
+ function isSensitiveKeyName(keyName) {
12409
+ return SENSITIVE_KEY_WORD.test(keyName) || SEGMENTED_KEY_WORD.test(keyName) || CAMEL_CASE_KEY_WORD.test(keyName);
12410
+ }
12411
+ function redactSecrets(content) {
12412
+ let sanitized = content;
12413
+ sanitized = sanitized.replace(/\b((?:Proxy-)?Authorization[^\S\r\n]*:[^\S\r\n]*(?:Bearer|Basic)[^\S\r\n]+)[A-Za-z0-9._~+/-]+=*/gi, `$1${SECRET_PLACEHOLDER}`);
12414
+ sanitized = sanitized.replace(/\bgithub_pat_[A-Za-z0-9_]+\b/g, SECRET_PLACEHOLDER);
12415
+ sanitized = sanitized.replace(/\bgh(?:p|o|s)_[A-Za-z0-9_]{16,}\b/g, SECRET_PLACEHOLDER);
12416
+ sanitized = sanitized.replace(/\bsk-(?:live-)?[A-Za-z0-9][A-Za-z0-9_-]{7,}\b/g, SECRET_PLACEHOLDER);
12417
+ sanitized = sanitized.replace(JWT_PATTERN, SECRET_PLACEHOLDER);
12418
+ sanitized = sanitized.replace(AWS_ACCESS_KEY_ID_PATTERN, SECRET_PLACEHOLDER);
12419
+ sanitized = sanitized.replace(quotedSensitiveKeyValuePattern, (match, prefix, _keyQuote, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
12420
+ sanitized = sanitized.replace(unquotedSensitiveKeyValuePattern, (match, prefix, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
12421
+ sanitized = sanitized.replace(bareSensitiveKeyValuePattern, (match, prefix, keyName) => isSensitiveKeyName(keyName) ? `${prefix}${SECRET_PLACEHOLDER}` : match);
12422
+ sanitized = sanitized.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^@\s/?#]+@/gi, `$1${URL_CREDENTIAL_PLACEHOLDER}@`);
12423
+ sanitized = sanitized.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, "<EMAIL>");
12424
+ return sanitized;
12425
+ }
12426
+ function sanitizeContent(content) {
12427
+ const username = userInfo().username;
12428
+ const home = homedir8();
12429
+ let sanitized = redactSecrets(content);
12430
+ const cwd = process.cwd();
12431
+ for (const candidate of new Set([cwd, safeRealpath(cwd)])) {
12432
+ if (candidate && candidate !== "/" && candidate !== home) {
12433
+ sanitized = sanitized.replace(new RegExp(escapeRegex(candidate), "g"), "<PROJECT>");
12434
+ }
12435
+ }
12436
+ if (home) {
12437
+ sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
12438
+ }
12439
+ sanitized = sanitized.replace(/\/Users\/[^/\s"']+/g, "/Users/<USER>");
12440
+ sanitized = sanitized.replace(/\/home\/[^/\s"']+/g, "/home/<USER>");
12441
+ sanitized = sanitized.replace(/([A-Za-z]:\\\\Users\\\\)[^\\\\"'\s]+/g, "$1<USER>");
12442
+ sanitized = sanitized.replace(/([A-Za-z]:\\Users\\)[^\\"'\s]+/g, "$1<USER>");
12443
+ sanitized = sanitized.replace(/([A-Za-z]:\/Users\/)[^/\s"']+/g, "$1<USER>");
12444
+ if (username) {
12445
+ sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
12446
+ }
12447
+ return sanitized;
12448
+ }
12449
+ function sanitizeValue(value) {
12450
+ if (typeof value === "string") {
12451
+ return sanitizeContent(value);
12452
+ }
12453
+ if (Array.isArray(value)) {
12454
+ return value.map((entry) => sanitizeValue(entry));
12455
+ }
12456
+ if (value && typeof value === "object") {
12457
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeValue(entry)]));
12458
+ }
12459
+ return value;
12460
+ }
12461
+ var SECRET_PLACEHOLDER = "<REDACTED_SECRET>", URL_CREDENTIAL_PLACEHOLDER = "***", KEY_NAME = "[A-Za-z_][A-Za-z0-9_.-]*", SENSITIVE_KEY_WORD, SEGMENTED_KEY_WORD, CAMEL_CASE_KEY_WORD, JWT_PATTERN, AWS_ACCESS_KEY_ID_PATTERN, quotedSensitiveKeyValuePattern, unquotedSensitiveKeyValuePattern, bareSensitiveKeyValuePattern;
12462
+ var init_sanitize = __esm(() => {
12463
+ SENSITIVE_KEY_WORD = /(?:token|password|secret|api[_-]?key|passwd|pwd|credential)/i;
12464
+ SEGMENTED_KEY_WORD = /(?:^|[_.-])key(?:$|[_.-])/i;
12465
+ CAMEL_CASE_KEY_WORD = /[a-z0-9]Key(?:$|[A-Z_.-])/;
12466
+ JWT_PATTERN = /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
12467
+ AWS_ACCESS_KEY_ID_PATTERN = /\b(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}\b/g;
12468
+ quotedSensitiveKeyValuePattern = new RegExp(String.raw`((['"])(${KEY_NAME})\2[^\S\r\n]*:[^\S\r\n]*)(['"])([^'"\r\n]+)\4`, "gi");
12469
+ unquotedSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)(['"])([^'"\r\n]+)\3`, "gi");
12470
+ bareSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)([^\s,;&'"]+)`, "gi");
12471
+ });
12472
+
12473
+ // src/lib/bridge-tool-failures.ts
12474
+ import { closeSync as closeSync2, existsSync as existsSync10, openSync as openSync2, readSync as readSync2, statSync as statSync6 } from "node:fs";
12475
+ import { tmpdir as tmpdir2 } from "node:os";
12380
12476
  import { join as join10 } from "node:path";
12477
+ function resolveBridgePluginLogPath() {
12478
+ const isTestEnv = process.env.BUN_TEST === "1" || false;
12479
+ return join10(tmpdir2(), isTestEnv ? "aft-plugin-test.log" : "aft-plugin.log");
12480
+ }
12481
+ function tailLogFileBytes(path, maxBytes) {
12482
+ if (!existsSync10(path) || maxBytes <= 0)
12483
+ return "";
12484
+ let fd = null;
12485
+ try {
12486
+ const size = statSync6(path).size;
12487
+ if (size === 0)
12488
+ return "";
12489
+ const readLength = Math.min(size, maxBytes);
12490
+ const position = size - readLength;
12491
+ fd = openSync2(path, "r");
12492
+ const buffer = Buffer.allocUnsafe(readLength);
12493
+ const bytesRead = readSync2(fd, buffer, 0, readLength, position);
12494
+ return buffer.subarray(0, bytesRead).toString("utf-8").trim();
12495
+ } catch {
12496
+ return "";
12497
+ } finally {
12498
+ if (fd !== null) {
12499
+ try {
12500
+ closeSync2(fd);
12501
+ } catch {}
12502
+ }
12503
+ }
12504
+ }
12505
+ function stripSessionTags(line) {
12506
+ return line.replace(SESSION_TAG_PATTERN, "").replace(/\s+/g, " ").trim();
12507
+ }
12508
+ function stripPathLikeTokens(label) {
12509
+ let out = label;
12510
+ out = out.replace(/\/(?:Users|home|var|tmp|private|Volumes)\/[^\s"'`,;)]+/gi, "<path>");
12511
+ out = out.replace(/[A-Za-z]:\\(?:Users|Program Files)[^\\s"'`,;)]+/gi, "<path>");
12512
+ out = out.replace(/file:\/\/[^\s"'`,;)]+/gi, "<path>");
12513
+ out = out.replace(/\(id=[^)]+\)/gi, "");
12514
+ return out.replace(/\s+/g, " ").trim();
12515
+ }
12516
+ function classifyBridgeLogLine(line) {
12517
+ const timeoutMatch = line.match(/Request "([^"]+)"[\s\S]*?timed out after (\d+)ms/i);
12518
+ if (timeoutMatch) {
12519
+ return `${timeoutMatch[1]}: timed out after ${timeoutMatch[2]}ms`;
12520
+ }
12521
+ const lowerTimeout = line.match(/request "([^"]+)" timed out after (\d+)ms/i);
12522
+ if (lowerTimeout) {
12523
+ return `${lowerTimeout[1]}: timed out after ${lowerTimeout[2]}ms`;
12524
+ }
12525
+ if (/Bridge killed after timeout/i.test(line)) {
12526
+ return "bridge killed after timeout";
12527
+ }
12528
+ if (/bridge killed during sibling timeout/i.test(line)) {
12529
+ return "bridge killed during sibling timeout";
12530
+ }
12531
+ if (/restarting bridge/i.test(line)) {
12532
+ return "restarting bridge";
12533
+ }
12534
+ const rpcMatch = line.match(/RPC error:\s*([^\s=]+)/i);
12535
+ if (rpcMatch) {
12536
+ return `rpc: RPC error (${rpcMatch[1]})`;
12537
+ }
12538
+ if (/spawn error/i.test(line)) {
12539
+ return "spawn: spawn error";
12540
+ }
12541
+ if (/failed to spawn/i.test(line)) {
12542
+ return "spawn: failed to spawn";
12543
+ }
12544
+ if (/\bonnx/i.test(line) && /\b(?:error|failed|missing|incompatible)\b/i.test(line)) {
12545
+ return "onnx: onnx runtime error";
12546
+ }
12547
+ if (/\bORT_/i.test(line) && /\b(?:error|failed)\b/i.test(line)) {
12548
+ return "onnx: ORT error";
12549
+ }
12550
+ const codeMatch = line.match(STRUCTURED_CODE_PATTERN);
12551
+ if (codeMatch && /\bERROR\b/.test(line)) {
12552
+ return `code: ${codeMatch[1]}`;
12553
+ }
12554
+ if (/\bERROR\b/.test(line) && /\[aft-plugin\]|\[aft-bridge\]|\[aft-lsp\]|\[aft\]/i.test(line)) {
12555
+ return "error: ERROR log line";
12556
+ }
12557
+ return null;
12558
+ }
12559
+ function aggregateBridgeToolFailures(logText) {
12560
+ const counts = new Map;
12561
+ if (!logText.trim())
12562
+ return counts;
12563
+ for (const rawLine of logText.split(/\r?\n/)) {
12564
+ if (!stripSessionTags(rawLine))
12565
+ continue;
12566
+ const key = classifyBridgeLogLine(rawLine);
12567
+ if (!key)
12568
+ continue;
12569
+ const sanitizedKey = stripPathLikeTokens(sanitizeContent(key));
12570
+ if (!sanitizedKey)
12571
+ continue;
12572
+ counts.set(sanitizedKey, (counts.get(sanitizedKey) ?? 0) + 1);
12573
+ }
12574
+ return counts;
12575
+ }
12576
+ function sortFailureKeys(a, b, counts) {
12577
+ const countDiff = (counts.get(b) ?? 0) - (counts.get(a) ?? 0);
12578
+ if (countDiff !== 0)
12579
+ return countDiff;
12580
+ return a.localeCompare(b);
12581
+ }
12582
+ function formatRecentAftToolFailuresSection(counts, options) {
12583
+ const maxClasses = options?.maxClasses ?? MAX_TOOL_FAILURE_CLASSES;
12584
+ const heading = "### Recent AFT tool failures";
12585
+ if (counts.size === 0) {
12586
+ return `${heading}
12587
+ No recent AFT tool failures recorded.`;
12588
+ }
12589
+ const sorted = [...counts.keys()].sort((a, b) => sortFailureKeys(a, b, counts));
12590
+ const shown = sorted.slice(0, maxClasses);
12591
+ const hidden = sorted.length - shown.length;
12592
+ const bullets = shown.map((key) => {
12593
+ const count = counts.get(key) ?? 0;
12594
+ return `- ${key} ×${count}`;
12595
+ });
12596
+ if (hidden > 0) {
12597
+ bullets.push(`- +${hidden} more failure class(es) omitted`);
12598
+ }
12599
+ return [heading, ...bullets].join(`
12600
+ `);
12601
+ }
12602
+ function buildRecentAftToolFailuresSectionFromLog(logPath = resolveBridgePluginLogPath(), options) {
12603
+ const tailBytes = options?.tailBytes ?? BRIDGE_LOG_TAIL_BYTES;
12604
+ const tail = tailLogFileBytes(logPath, tailBytes);
12605
+ const counts = aggregateBridgeToolFailures(tail);
12606
+ return formatRecentAftToolFailuresSection(counts, options);
12607
+ }
12608
+ var BRIDGE_LOG_TAIL_BYTES, MAX_TOOL_FAILURE_CLASSES = 30, SESSION_TAG_PATTERN, STRUCTURED_CODE_PATTERN;
12609
+ var init_bridge_tool_failures = __esm(() => {
12610
+ init_sanitize();
12611
+ BRIDGE_LOG_TAIL_BYTES = 2 * 1024 * 1024;
12612
+ SESSION_TAG_PATTERN = /\[ses_[^\]\s]+\]|\[[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\]/g;
12613
+ STRUCTURED_CODE_PATTERN = /"code"\s*:\s*"([^"]+)"/;
12614
+ });
12615
+
12616
+ // src/lib/lsp-cache.ts
12617
+ import { existsSync as existsSync11, readdirSync as readdirSync5, rmSync as rmSync2, statSync as statSync7 } from "node:fs";
12618
+ import { join as join11 } from "node:path";
12381
12619
  function inspectDir(path) {
12382
- if (!existsSync10(path)) {
12620
+ if (!existsSync11(path)) {
12383
12621
  return { entries: [], totalSize: 0 };
12384
12622
  }
12385
12623
  const entries = [];
@@ -12391,9 +12629,9 @@ function inspectDir(path) {
12391
12629
  return { entries: [], totalSize: 0 };
12392
12630
  }
12393
12631
  for (const name of names) {
12394
- const full = join10(path, name);
12632
+ const full = join11(path, name);
12395
12633
  try {
12396
- if (!statSync6(full).isDirectory())
12634
+ if (!statSync7(full).isDirectory())
12397
12635
  continue;
12398
12636
  const size = dirSize(full);
12399
12637
  entries.push({
@@ -12449,8 +12687,8 @@ var init_lsp_cache = __esm(() => {
12449
12687
  });
12450
12688
 
12451
12689
  // src/lib/onnx.ts
12452
- import { existsSync as existsSync11, readdirSync as readdirSync6, readlinkSync, realpathSync as realpathSync2, statSync as statSync7 } from "node:fs";
12453
- import { basename, isAbsolute as isAbsolute2, join as join11, resolve as resolve4, win32 } from "node:path";
12690
+ import { existsSync as existsSync12, readdirSync as readdirSync6, readlinkSync, realpathSync as realpathSync3, statSync as statSync8 } from "node:fs";
12691
+ import { basename, isAbsolute as isAbsolute2, join as join12, resolve as resolve4, win32 } from "node:path";
12454
12692
  function getOnnxLibraryName() {
12455
12693
  if (process.platform === "darwin")
12456
12694
  return "libonnxruntime.dylib";
@@ -12513,13 +12751,13 @@ function findSystemOnnxRuntime() {
12513
12751
  searchPaths.push(...pathEntriesForPlatform());
12514
12752
  const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
12515
12753
  const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
12516
- searchPaths.push(join11(programFiles, "onnxruntime", "lib"), join11(programFiles, "Microsoft ONNX Runtime", "lib"), join11(programFiles, "Microsoft Machine Learning", "lib"), join11(programFilesX86, "onnxruntime", "lib"), ...(() => {
12754
+ searchPaths.push(join12(programFiles, "onnxruntime", "lib"), join12(programFiles, "Microsoft ONNX Runtime", "lib"), join12(programFiles, "Microsoft Machine Learning", "lib"), join12(programFilesX86, "onnxruntime", "lib"), ...(() => {
12517
12755
  const nugetPaths = [];
12518
12756
  const userProfile = process.env.USERPROFILE ?? "";
12519
12757
  if (!userProfile)
12520
12758
  return nugetPaths;
12521
- const nugetPackageDir = join11(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
12522
- if (!existsSync11(nugetPackageDir))
12759
+ const nugetPackageDir = join12(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
12760
+ if (!existsSync12(nugetPackageDir))
12523
12761
  return nugetPaths;
12524
12762
  try {
12525
12763
  for (const entry of readdirSync6(nugetPackageDir, { withFileTypes: true })) {
@@ -12527,7 +12765,7 @@ function findSystemOnnxRuntime() {
12527
12765
  continue;
12528
12766
  if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
12529
12767
  continue;
12530
- nugetPaths.push(join11(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join11(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
12768
+ nugetPaths.push(join12(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join12(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
12531
12769
  }
12532
12770
  } catch {}
12533
12771
  return nugetPaths;
@@ -12557,12 +12795,12 @@ function findSystemOnnxRuntime() {
12557
12795
  return unknownVersionPaths[0] ?? null;
12558
12796
  }
12559
12797
  function findCachedOnnxRuntime(storageDir) {
12560
- const ortDir = join11(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
12798
+ const ortDir = join12(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
12561
12799
  const libName = getOnnxLibraryName();
12562
- if (existsSync11(join11(ortDir, libName)))
12800
+ if (existsSync12(join12(ortDir, libName)))
12563
12801
  return ortDir;
12564
- const libSubdir = join11(ortDir, "lib");
12565
- if (existsSync11(join11(libSubdir, libName)))
12802
+ const libSubdir = join12(ortDir, "lib");
12803
+ if (existsSync12(join12(libSubdir, libName)))
12566
12804
  return libSubdir;
12567
12805
  return null;
12568
12806
  }
@@ -12583,7 +12821,7 @@ function parseOrtVersionFromDirectoryPath(value) {
12583
12821
  return null;
12584
12822
  }
12585
12823
  function detectOrtVersion(libDir) {
12586
- if (!existsSync11(libDir))
12824
+ if (!existsSync12(libDir))
12587
12825
  return null;
12588
12826
  const libName = getOnnxLibraryName();
12589
12827
  try {
@@ -12598,10 +12836,10 @@ function detectOrtVersion(libDir) {
12598
12836
  if (version)
12599
12837
  return version;
12600
12838
  }
12601
- const base = join11(libDir, libName);
12602
- if (existsSync11(base)) {
12839
+ const base = join12(libDir, libName);
12840
+ if (existsSync12(base)) {
12603
12841
  try {
12604
- const real = realpathSync2(base);
12842
+ const real = realpathSync3(base);
12605
12843
  const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
12606
12844
  if (version)
12607
12845
  return version;
@@ -12629,93 +12867,15 @@ function isOrtVersionCompatible(version) {
12629
12867
  var ONNX_RUNTIME_VERSION = "1.24.4", INVALID_ORT_VERSION = "<invalid>", REQUIRED_ORT_MAJOR = 1, REQUIRED_ORT_MIN_MINOR = 20;
12630
12868
  var init_onnx = () => {};
12631
12869
 
12632
- // src/lib/sanitize.ts
12633
- import { realpathSync as realpathSync3 } from "node:fs";
12634
- import { homedir as homedir8, userInfo } from "node:os";
12635
- function escapeRegex(value) {
12636
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
12637
- }
12638
- function safeRealpath(p2) {
12639
- try {
12640
- return realpathSync3(p2);
12641
- } catch {
12642
- return null;
12643
- }
12644
- }
12645
- function isSensitiveKeyName(keyName) {
12646
- return SENSITIVE_KEY_WORD.test(keyName) || SEGMENTED_KEY_WORD.test(keyName) || CAMEL_CASE_KEY_WORD.test(keyName);
12647
- }
12648
- function redactSecrets(content) {
12649
- let sanitized = content;
12650
- sanitized = sanitized.replace(/\b((?:Proxy-)?Authorization[^\S\r\n]*:[^\S\r\n]*(?:Bearer|Basic)[^\S\r\n]+)[A-Za-z0-9._~+/-]+=*/gi, `$1${SECRET_PLACEHOLDER}`);
12651
- sanitized = sanitized.replace(/\bgithub_pat_[A-Za-z0-9_]+\b/g, SECRET_PLACEHOLDER);
12652
- sanitized = sanitized.replace(/\bgh(?:p|o|s)_[A-Za-z0-9_]{16,}\b/g, SECRET_PLACEHOLDER);
12653
- sanitized = sanitized.replace(/\bsk-(?:live-)?[A-Za-z0-9][A-Za-z0-9_-]{7,}\b/g, SECRET_PLACEHOLDER);
12654
- sanitized = sanitized.replace(JWT_PATTERN, SECRET_PLACEHOLDER);
12655
- sanitized = sanitized.replace(AWS_ACCESS_KEY_ID_PATTERN, SECRET_PLACEHOLDER);
12656
- sanitized = sanitized.replace(quotedSensitiveKeyValuePattern, (match, prefix, _keyQuote, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
12657
- sanitized = sanitized.replace(unquotedSensitiveKeyValuePattern, (match, prefix, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
12658
- sanitized = sanitized.replace(bareSensitiveKeyValuePattern, (match, prefix, keyName) => isSensitiveKeyName(keyName) ? `${prefix}${SECRET_PLACEHOLDER}` : match);
12659
- sanitized = sanitized.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^@\s/?#]+@/gi, `$1${URL_CREDENTIAL_PLACEHOLDER}@`);
12660
- sanitized = sanitized.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, "<EMAIL>");
12661
- return sanitized;
12662
- }
12663
- function sanitizeContent(content) {
12664
- const username = userInfo().username;
12665
- const home = homedir8();
12666
- let sanitized = redactSecrets(content);
12667
- const cwd = process.cwd();
12668
- for (const candidate of new Set([cwd, safeRealpath(cwd)])) {
12669
- if (candidate && candidate !== "/" && candidate !== home) {
12670
- sanitized = sanitized.replace(new RegExp(escapeRegex(candidate), "g"), "<PROJECT>");
12671
- }
12672
- }
12673
- if (home) {
12674
- sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
12675
- }
12676
- sanitized = sanitized.replace(/\/Users\/[^/\s"']+/g, "/Users/<USER>");
12677
- sanitized = sanitized.replace(/\/home\/[^/\s"']+/g, "/home/<USER>");
12678
- sanitized = sanitized.replace(/([A-Za-z]:\\\\Users\\\\)[^\\\\"'\s]+/g, "$1<USER>");
12679
- sanitized = sanitized.replace(/([A-Za-z]:\\Users\\)[^\\"'\s]+/g, "$1<USER>");
12680
- sanitized = sanitized.replace(/([A-Za-z]:\/Users\/)[^/\s"']+/g, "$1<USER>");
12681
- if (username) {
12682
- sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
12683
- }
12684
- return sanitized;
12685
- }
12686
- function sanitizeValue(value) {
12687
- if (typeof value === "string") {
12688
- return sanitizeContent(value);
12689
- }
12690
- if (Array.isArray(value)) {
12691
- return value.map((entry) => sanitizeValue(entry));
12692
- }
12693
- if (value && typeof value === "object") {
12694
- return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeValue(entry)]));
12695
- }
12696
- return value;
12697
- }
12698
- var SECRET_PLACEHOLDER = "<REDACTED_SECRET>", URL_CREDENTIAL_PLACEHOLDER = "***", KEY_NAME = "[A-Za-z_][A-Za-z0-9_.-]*", SENSITIVE_KEY_WORD, SEGMENTED_KEY_WORD, CAMEL_CASE_KEY_WORD, JWT_PATTERN, AWS_ACCESS_KEY_ID_PATTERN, quotedSensitiveKeyValuePattern, unquotedSensitiveKeyValuePattern, bareSensitiveKeyValuePattern;
12699
- var init_sanitize = __esm(() => {
12700
- SENSITIVE_KEY_WORD = /(?:token|password|secret|api[_-]?key|passwd|pwd|credential)/i;
12701
- SEGMENTED_KEY_WORD = /(?:^|[_.-])key(?:$|[_.-])/i;
12702
- CAMEL_CASE_KEY_WORD = /[a-z0-9]Key(?:$|[A-Z_.-])/;
12703
- JWT_PATTERN = /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
12704
- AWS_ACCESS_KEY_ID_PATTERN = /\b(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}\b/g;
12705
- quotedSensitiveKeyValuePattern = new RegExp(String.raw`((['"])(${KEY_NAME})\2[^\S\r\n]*:[^\S\r\n]*)(['"])([^'"\r\n]+)\4`, "gi");
12706
- unquotedSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)(['"])([^'"\r\n]+)\3`, "gi");
12707
- bareSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)([^\s,;&'"]+)`, "gi");
12708
- });
12709
-
12710
12870
  // src/lib/diagnostics.ts
12711
12871
  import {
12712
12872
  accessSync,
12713
- closeSync as closeSync2,
12873
+ closeSync as closeSync3,
12714
12874
  constants,
12715
- existsSync as existsSync12,
12716
- openSync as openSync2,
12717
- readSync as readSync2,
12718
- statSync as statSync8
12875
+ existsSync as existsSync13,
12876
+ openSync as openSync3,
12877
+ readSync as readSync3,
12878
+ statSync as statSync9
12719
12879
  } from "node:fs";
12720
12880
  async function collectDiagnostics(adapters) {
12721
12881
  const cliVersion = getSelfVersion();
@@ -12744,7 +12904,7 @@ async function diagnoseHarness(adapter) {
12744
12904
  const logPath = adapter.getLogFile();
12745
12905
  const pluginCache = adapter.getPluginCacheInfo();
12746
12906
  const storageAccessible = (() => {
12747
- if (!existsSync12(storage))
12907
+ if (!existsSync13(storage))
12748
12908
  return false;
12749
12909
  try {
12750
12910
  accessSync(storage, constants.R_OK | constants.W_OK);
@@ -12767,14 +12927,14 @@ async function diagnoseHarness(adapter) {
12767
12927
  pluginRegistered: adapter.hasPluginEntry(),
12768
12928
  configPaths,
12769
12929
  aftConfig: {
12770
- exists: existsSync12(configPaths.aftConfig),
12930
+ exists: existsSync13(configPaths.aftConfig),
12771
12931
  ...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
12772
12932
  flags: aftFlags
12773
12933
  },
12774
12934
  pluginCache,
12775
12935
  storageDir: {
12776
12936
  path: storage,
12777
- exists: existsSync12(storage),
12937
+ exists: existsSync13(storage),
12778
12938
  accessible: storageAccessible,
12779
12939
  sizesByKey: describeStorage
12780
12940
  },
@@ -12792,8 +12952,8 @@ async function diagnoseHarness(adapter) {
12792
12952
  },
12793
12953
  logFile: {
12794
12954
  path: logPath,
12795
- exists: existsSync12(logPath),
12796
- sizeKb: existsSync12(logPath) ? Math.round(statSync8(logPath).size / 1024) : 0
12955
+ exists: existsSync13(logPath),
12956
+ sizeKb: existsSync13(logPath) ? Math.round(statSync9(logPath).size / 1024) : 0
12797
12957
  }
12798
12958
  };
12799
12959
  }
@@ -12987,15 +13147,15 @@ function formatDiagnosticIssuesSection(report) {
12987
13147
  return lines;
12988
13148
  }
12989
13149
  function tailLogFile(path, lines) {
12990
- if (!existsSync12(path))
13150
+ if (!existsSync13(path))
12991
13151
  return "";
12992
13152
  if (lines <= 0)
12993
13153
  return "";
12994
13154
  const chunkSize = 64 * 1024;
12995
13155
  let fd = null;
12996
13156
  try {
12997
- const size = statSync8(path).size;
12998
- fd = openSync2(path, "r");
13157
+ const size = statSync9(path).size;
13158
+ fd = openSync3(path, "r");
12999
13159
  const chunks = [];
13000
13160
  let position = size;
13001
13161
  let newlineCount = 0;
@@ -13003,7 +13163,7 @@ function tailLogFile(path, lines) {
13003
13163
  const readLength = Math.min(chunkSize, position);
13004
13164
  position -= readLength;
13005
13165
  const buffer = Buffer.allocUnsafe(readLength);
13006
- const bytesRead = readSync2(fd, buffer, 0, readLength, position);
13166
+ const bytesRead = readSync3(fd, buffer, 0, readLength, position);
13007
13167
  const chunk = bytesRead === readLength ? buffer : buffer.subarray(0, bytesRead);
13008
13168
  chunks.unshift(chunk);
13009
13169
  for (let i = chunk.length - 1;i >= 0; i -= 1) {
@@ -13018,7 +13178,7 @@ function tailLogFile(path, lines) {
13018
13178
  } finally {
13019
13179
  if (fd !== null) {
13020
13180
  try {
13021
- closeSync2(fd);
13181
+ closeSync3(fd);
13022
13182
  } catch {}
13023
13183
  }
13024
13184
  }
@@ -13077,7 +13237,7 @@ var init_github = () => {};
13077
13237
  function filterLogToSession(logText, sessionId) {
13078
13238
  const bareId = sessionId.replace(/^ses_/, "");
13079
13239
  const keepTokens = [`[ses_${bareId}]`, `[${bareId}]`];
13080
- return logText.split(/\r?\n/).filter((line) => !SESSION_TAG_PATTERN.test(line) || keepTokens.some((token) => line.includes(token))).join(`
13240
+ return logText.split(/\r?\n/).filter((line) => !SESSION_TAG_PATTERN2.test(line) || keepTokens.some((token) => line.includes(token))).join(`
13081
13241
  `);
13082
13242
  }
13083
13243
  function isErrorLogLine(line) {
@@ -13157,9 +13317,9 @@ function truncateToByteBudget(input, maxBytes) {
13157
13317
  }
13158
13318
  return buf.subarray(0, end).toString("utf8");
13159
13319
  }
13160
- var MAX_GITHUB_BODY_BYTES = 60000, SESSION_TAG_PATTERN, ERROR_LOG_PATTERNS;
13320
+ var MAX_GITHUB_BODY_BYTES = 60000, SESSION_TAG_PATTERN2, ERROR_LOG_PATTERNS;
13161
13321
  var init_issue_body = __esm(() => {
13162
- SESSION_TAG_PATTERN = /\[ses_[^\]\s]+\]|\[[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\]/;
13322
+ SESSION_TAG_PATTERN2 = /\[ses_[^\]\s]+\]|\[[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\]/;
13163
13323
  ERROR_LOG_PATTERNS = [
13164
13324
  /\bcrashed:/i,
13165
13325
  /\bfailed:/i,
@@ -13173,8 +13333,8 @@ var init_issue_body = __esm(() => {
13173
13333
  });
13174
13334
 
13175
13335
  // src/lib/onnx-fix.ts
13176
- import { existsSync as existsSync13, rmSync as rmSync3 } from "node:fs";
13177
- import { join as join12 } from "node:path";
13336
+ import { existsSync as existsSync14, rmSync as rmSync3 } from "node:fs";
13337
+ import { join as join13 } from "node:path";
13178
13338
  function findOnnxFixCandidates(report) {
13179
13339
  const candidates = [];
13180
13340
  for (const harness of report.harnesses) {
@@ -13182,7 +13342,7 @@ function findOnnxFixCandidates(report) {
13182
13342
  continue;
13183
13343
  if (!harness.storageDir.exists)
13184
13344
  continue;
13185
- const storageOnnxDir = join12(harness.storageDir.path, "onnxruntime");
13345
+ const storageOnnxDir = join13(harness.storageDir.path, "onnxruntime");
13186
13346
  const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
13187
13347
  const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
13188
13348
  const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
@@ -13191,7 +13351,7 @@ function findOnnxFixCandidates(report) {
13191
13351
  harness,
13192
13352
  reason: `cached ONNX Runtime at ${harness.onnxRuntime.cachedPath} is v${harness.onnxRuntime.cachedVersion}, but AFT requires ${harness.onnxRuntime.requirement}. Clearing forces a fresh download on next start.`,
13193
13353
  storageOnnxDir,
13194
- storageOnnxBytes: existsSync13(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
13354
+ storageOnnxBytes: existsSync14(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
13195
13355
  });
13196
13356
  continue;
13197
13357
  }
@@ -13200,7 +13360,7 @@ function findOnnxFixCandidates(report) {
13200
13360
  harness,
13201
13361
  reason: `system ONNX Runtime at ${harness.onnxRuntime.systemPath} is v${harness.onnxRuntime.systemVersion}, but AFT requires ${harness.onnxRuntime.requirement}, and no AFT-managed install is present. AFT v0.19.5+ skips incompatible system installs and auto-downloads v1.24 on next start; clearing any stale state here ensures a clean slate.`,
13202
13362
  storageOnnxDir,
13203
- storageOnnxBytes: existsSync13(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
13363
+ storageOnnxBytes: existsSync14(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
13204
13364
  });
13205
13365
  }
13206
13366
  }
@@ -13230,7 +13390,7 @@ async function runOnnxFix(adapters, report, options = {}) {
13230
13390
  const result = { cleared: 0, bytesReclaimed: 0, errors: [] };
13231
13391
  const rmFn = options.rmFn ?? rmSync3;
13232
13392
  for (const c2 of candidates) {
13233
- if (!existsSync13(c2.storageOnnxDir)) {
13393
+ if (!existsSync14(c2.storageOnnxDir)) {
13234
13394
  O2.success(`${c2.harness.displayName}: no cached state to clear; restart your harness to trigger a fresh ONNX download`);
13235
13395
  continue;
13236
13396
  }
@@ -13256,10 +13416,10 @@ var init_onnx_fix = __esm(() => {
13256
13416
  });
13257
13417
 
13258
13418
  // src/lib/sessions.ts
13259
- import { existsSync as existsSync14, readdirSync as readdirSync7, readFileSync as readFileSync4, statSync as statSync9 } from "node:fs";
13419
+ import { existsSync as existsSync15, readdirSync as readdirSync7, readFileSync as readFileSync4, statSync as statSync10 } from "node:fs";
13260
13420
  import { createRequire as createRequire3 } from "node:module";
13261
13421
  import { homedir as homedir9 } from "node:os";
13262
- import { basename as basename2, join as join13 } from "node:path";
13422
+ import { basename as basename2, join as join14 } from "node:path";
13263
13423
  function listRecentSessions(adapter) {
13264
13424
  try {
13265
13425
  if (adapter.kind === "opencode")
@@ -13288,8 +13448,8 @@ function mapOpenCodeSessionRows(rows) {
13288
13448
  }).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
13289
13449
  }
13290
13450
  function listRecentOpenCodeSessions() {
13291
- const dbPath = join13(getXdgDataHome(), "opencode", "opencode.db");
13292
- if (!existsSync14(dbPath))
13451
+ const dbPath = join14(getXdgDataHome(), "opencode", "opencode.db");
13452
+ if (!existsSync15(dbPath))
13293
13453
  return [];
13294
13454
  let db = null;
13295
13455
  try {
@@ -13308,10 +13468,10 @@ function listRecentOpenCodeSessions() {
13308
13468
  }
13309
13469
  function getXdgDataHome() {
13310
13470
  const xdgDataHome = process.env.XDG_DATA_HOME;
13311
- return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join13(homedir9(), ".local", "share");
13471
+ return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join14(homedir9(), ".local", "share");
13312
13472
  }
13313
13473
  function listRecentPiSessions() {
13314
- return listPiSessionsFromDir(join13(getHomeDir(), ".pi", "agent", "sessions"));
13474
+ return listPiSessionsFromDir(join14(getHomeDir(), ".pi", "agent", "sessions"));
13315
13475
  }
13316
13476
  function getHomeDir() {
13317
13477
  const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
@@ -13319,11 +13479,11 @@ function getHomeDir() {
13319
13479
  }
13320
13480
  function listPiSessionsFromDir(sessionsDir) {
13321
13481
  try {
13322
- if (!existsSync14(sessionsDir))
13482
+ if (!existsSync15(sessionsDir))
13323
13483
  return [];
13324
13484
  const files = collectJsonlFiles(sessionsDir).map((filePath) => {
13325
13485
  try {
13326
- const stats = statSync9(filePath);
13486
+ const stats = statSync10(filePath);
13327
13487
  return { filePath, mtimeMs: stats.mtimeMs };
13328
13488
  } catch {
13329
13489
  return null;
@@ -13357,7 +13517,7 @@ function collectJsonlFiles(root) {
13357
13517
  continue;
13358
13518
  }
13359
13519
  for (const entry of entries) {
13360
- const path = join13(dir, entry.name);
13520
+ const path = join14(dir, entry.name);
13361
13521
  if (entry.isDirectory()) {
13362
13522
  stack.push(path);
13363
13523
  } else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
@@ -13457,17 +13617,17 @@ __export(exports_doctor, {
13457
13617
  import { execFileSync } from "node:child_process";
13458
13618
  import {
13459
13619
  chmodSync as chmodSync2,
13460
- existsSync as existsSync15,
13620
+ existsSync as existsSync16,
13461
13621
  mkdirSync as mkdirSync3,
13462
13622
  mkdtempSync,
13463
13623
  readFileSync as readFileSync5,
13464
13624
  realpathSync as realpathSync4,
13465
13625
  rmSync as rmSync4,
13466
- statSync as statSync10,
13626
+ statSync as statSync11,
13467
13627
  writeFileSync as writeFileSync2
13468
13628
  } from "node:fs";
13469
- import { tmpdir as tmpdir2 } from "node:os";
13470
- import { join as join14 } from "node:path";
13629
+ import { tmpdir as tmpdir3 } from "node:os";
13630
+ import { join as join15 } from "node:path";
13471
13631
  async function runDoctor(options) {
13472
13632
  if (options.issue) {
13473
13633
  return runIssueFlow(options.argv);
@@ -13621,7 +13781,7 @@ function clearOldBinaries() {
13621
13781
  errors: [],
13622
13782
  keptVersion: keepTag
13623
13783
  };
13624
- if (!existsSync15(info.path)) {
13784
+ if (!existsSync16(info.path)) {
13625
13785
  O2.info(`Binary cache: nothing to clear at ${info.path}`);
13626
13786
  return result;
13627
13787
  }
@@ -13631,10 +13791,10 @@ function clearOldBinaries() {
13631
13791
  return result;
13632
13792
  }
13633
13793
  for (const version of stale) {
13634
- const dir = join14(info.path, version);
13794
+ const dir = join15(info.path, version);
13635
13795
  let bytes = 0;
13636
13796
  try {
13637
- bytes = statSync10(dir).isDirectory() ? dirSize(dir) : 0;
13797
+ bytes = statSync11(dir).isDirectory() ? dirSize(dir) : 0;
13638
13798
  } catch {
13639
13799
  bytes = 0;
13640
13800
  }
@@ -13956,7 +14116,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
13956
14116
  if (!adapter.isInstalled() || !adapter.hasPluginEntry())
13957
14117
  continue;
13958
14118
  const storageDir = adapter.getStorageDir();
13959
- if (existsSync15(storageDir))
14119
+ if (existsSync16(storageDir))
13960
14120
  continue;
13961
14121
  mkdirSync3(storageDir, { recursive: true });
13962
14122
  summary.created += 1;
@@ -14059,11 +14219,11 @@ function deriveIssueTitleFromBody(body) {
14059
14219
  function writeIssueReviewFile(body) {
14060
14220
  let reviewDir = null;
14061
14221
  try {
14062
- reviewDir = mkdtempSync(join14(tmpdir2(), "aft-issue-"));
14222
+ reviewDir = mkdtempSync(join15(tmpdir3(), "aft-issue-"));
14063
14223
  if (process.platform !== "win32") {
14064
14224
  chmodSync2(reviewDir, 448);
14065
14225
  }
14066
- const outPath = join14(reviewDir, "issue.md");
14226
+ const outPath = join15(reviewDir, "issue.md");
14067
14227
  writeFileSync2(outPath, `${body}
14068
14228
  `, { encoding: "utf8", mode: 384, flag: "wx" });
14069
14229
  return { path: outPath, realPath: realpathSync4(outPath) };
@@ -14152,6 +14312,7 @@ ${scopedTail || "<no log output>"}
14152
14312
  const recentErrorsSection = recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
14153
14313
  `), "```"].join(`
14154
14314
  `);
14315
+ const toolFailuresSection = buildRecentAftToolFailuresSectionFromLog();
14155
14316
  const rawBody = [
14156
14317
  "## Description",
14157
14318
  description,
@@ -14169,6 +14330,8 @@ ${scopedTail || "<no log output>"}
14169
14330
  "## Recent errors (last 20, sanitized)",
14170
14331
  recentErrorsSection,
14171
14332
  "",
14333
+ toolFailuresSection,
14334
+ "",
14172
14335
  "## Logs (last 200 lines per harness)",
14173
14336
  logSections,
14174
14337
  "_Usernames and home paths have been stripped from this report._"
@@ -14223,6 +14386,7 @@ var DOCTOR_CLEAR_TARGET_OPTIONS, DOCTOR_FORCE_CLEAR_TARGETS;
14223
14386
  var init_doctor = __esm(async () => {
14224
14387
  init_dist();
14225
14388
  init_binary_cache();
14389
+ init_bridge_tool_failures();
14226
14390
  init_fs_util();
14227
14391
  init_github();
14228
14392
  init_harness_select();
@@ -0,0 +1,26 @@
1
+ /** Newest window: tail of the bridge log by bytes (not full file). */
2
+ export declare const BRIDGE_LOG_TAIL_BYTES: number;
3
+ export declare const MAX_TOOL_FAILURE_CLASSES = 30;
4
+ export declare function resolveBridgePluginLogPath(): string;
5
+ /** Read up to `maxBytes` from the end of a log file (UTF-8). */
6
+ export declare function tailLogFileBytes(path: string, maxBytes: number): string;
7
+ export type ToolFailureKey = string;
8
+ /**
9
+ * Aggregate failure-shaped lines from bridge plugin log text into counts.
10
+ * Input should be a recent tail only; keys are tool/command + error class.
11
+ */
12
+ export declare function aggregateBridgeToolFailures(logText: string): Map<ToolFailureKey, number>;
13
+ /**
14
+ * Render the `### Recent AFT tool failures` markdown section from aggregated counts.
15
+ */
16
+ export declare function formatRecentAftToolFailuresSection(counts: Map<ToolFailureKey, number>, options?: {
17
+ maxClasses?: number;
18
+ }): string;
19
+ /**
20
+ * Build the tool-failures section from the bridge log path (newest tail window).
21
+ */
22
+ export declare function buildRecentAftToolFailuresSectionFromLog(logPath?: string, options?: {
23
+ tailBytes?: number;
24
+ maxClasses?: number;
25
+ }): string;
26
+ //# sourceMappingURL=bridge-tool-failures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge-tool-failures.d.ts","sourceRoot":"","sources":["../../src/lib/bridge-tool-failures.ts"],"names":[],"mappings":"AAKA,sEAAsE;AACtE,eAAO,MAAM,qBAAqB,QAAkB,CAAC;AAErD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAO3C,wBAAgB,0BAA0B,IAAI,MAAM,CAGnD;AAED,gEAAgE;AAChE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuBvE;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC;AAmEpC;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,CAcxF;AAQD;;GAEG;AACH,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,GAAG,CAAC,cAAc,EAAE,MAAM,CAAC,EACnC,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAChC,MAAM,CAqBR;AAED;;GAEG;AACH,wBAAgB,wCAAwC,CACtD,OAAO,GAAE,MAAqC,EAC9C,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,MAAM,CAKR"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cortexkit/aft",
3
- "version": "0.39.1",
3
+ "version": "0.39.3",
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.2.0",
27
- "@cortexkit/aft-bridge": "0.39.1",
27
+ "@cortexkit/aft-bridge": "0.39.3",
28
28
  "comment-json": "^4.6.2"
29
29
  },
30
30
  "devDependencies": {