@cortexkit/aft 0.39.1 → 0.39.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.
|
@@ -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;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
|
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
|
-
|
|
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
|
|
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 <
|
|
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);
|
|
@@ -1304,6 +1316,7 @@ class BridgePool {
|
|
|
1304
1316
|
this.projectConfigLoader = options.projectConfigLoader;
|
|
1305
1317
|
this.bridgeOptions = {
|
|
1306
1318
|
timeoutMs: options.timeoutMs,
|
|
1319
|
+
hangThreshold: options.hangThreshold,
|
|
1307
1320
|
maxRestarts: options.maxRestarts,
|
|
1308
1321
|
minVersion: options.minVersion,
|
|
1309
1322
|
onVersionMismatch: options.onVersionMismatch,
|
|
@@ -12375,11 +12388,232 @@ var init_binary_cache = __esm(() => {
|
|
|
12375
12388
|
init_paths2();
|
|
12376
12389
|
});
|
|
12377
12390
|
|
|
12378
|
-
// src/lib/
|
|
12379
|
-
import {
|
|
12391
|
+
// src/lib/sanitize.ts
|
|
12392
|
+
import { realpathSync as realpathSync2 } from "node:fs";
|
|
12393
|
+
import { homedir as homedir8, userInfo } from "node:os";
|
|
12394
|
+
function escapeRegex(value) {
|
|
12395
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12396
|
+
}
|
|
12397
|
+
function safeRealpath(p2) {
|
|
12398
|
+
try {
|
|
12399
|
+
return realpathSync2(p2);
|
|
12400
|
+
} catch {
|
|
12401
|
+
return null;
|
|
12402
|
+
}
|
|
12403
|
+
}
|
|
12404
|
+
function isSensitiveKeyName(keyName) {
|
|
12405
|
+
return SENSITIVE_KEY_WORD.test(keyName) || SEGMENTED_KEY_WORD.test(keyName) || CAMEL_CASE_KEY_WORD.test(keyName);
|
|
12406
|
+
}
|
|
12407
|
+
function redactSecrets(content) {
|
|
12408
|
+
let sanitized = content;
|
|
12409
|
+
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}`);
|
|
12410
|
+
sanitized = sanitized.replace(/\bgithub_pat_[A-Za-z0-9_]+\b/g, SECRET_PLACEHOLDER);
|
|
12411
|
+
sanitized = sanitized.replace(/\bgh(?:p|o|s)_[A-Za-z0-9_]{16,}\b/g, SECRET_PLACEHOLDER);
|
|
12412
|
+
sanitized = sanitized.replace(/\bsk-(?:live-)?[A-Za-z0-9][A-Za-z0-9_-]{7,}\b/g, SECRET_PLACEHOLDER);
|
|
12413
|
+
sanitized = sanitized.replace(JWT_PATTERN, SECRET_PLACEHOLDER);
|
|
12414
|
+
sanitized = sanitized.replace(AWS_ACCESS_KEY_ID_PATTERN, SECRET_PLACEHOLDER);
|
|
12415
|
+
sanitized = sanitized.replace(quotedSensitiveKeyValuePattern, (match, prefix, _keyQuote, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
|
|
12416
|
+
sanitized = sanitized.replace(unquotedSensitiveKeyValuePattern, (match, prefix, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
|
|
12417
|
+
sanitized = sanitized.replace(bareSensitiveKeyValuePattern, (match, prefix, keyName) => isSensitiveKeyName(keyName) ? `${prefix}${SECRET_PLACEHOLDER}` : match);
|
|
12418
|
+
sanitized = sanitized.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^@\s/?#]+@/gi, `$1${URL_CREDENTIAL_PLACEHOLDER}@`);
|
|
12419
|
+
sanitized = sanitized.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, "<EMAIL>");
|
|
12420
|
+
return sanitized;
|
|
12421
|
+
}
|
|
12422
|
+
function sanitizeContent(content) {
|
|
12423
|
+
const username = userInfo().username;
|
|
12424
|
+
const home = homedir8();
|
|
12425
|
+
let sanitized = redactSecrets(content);
|
|
12426
|
+
const cwd = process.cwd();
|
|
12427
|
+
for (const candidate of new Set([cwd, safeRealpath(cwd)])) {
|
|
12428
|
+
if (candidate && candidate !== "/" && candidate !== home) {
|
|
12429
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex(candidate), "g"), "<PROJECT>");
|
|
12430
|
+
}
|
|
12431
|
+
}
|
|
12432
|
+
if (home) {
|
|
12433
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
|
|
12434
|
+
}
|
|
12435
|
+
sanitized = sanitized.replace(/\/Users\/[^/\s"']+/g, "/Users/<USER>");
|
|
12436
|
+
sanitized = sanitized.replace(/\/home\/[^/\s"']+/g, "/home/<USER>");
|
|
12437
|
+
sanitized = sanitized.replace(/([A-Za-z]:\\\\Users\\\\)[^\\\\"'\s]+/g, "$1<USER>");
|
|
12438
|
+
sanitized = sanitized.replace(/([A-Za-z]:\\Users\\)[^\\"'\s]+/g, "$1<USER>");
|
|
12439
|
+
sanitized = sanitized.replace(/([A-Za-z]:\/Users\/)[^/\s"']+/g, "$1<USER>");
|
|
12440
|
+
if (username) {
|
|
12441
|
+
sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
|
|
12442
|
+
}
|
|
12443
|
+
return sanitized;
|
|
12444
|
+
}
|
|
12445
|
+
function sanitizeValue(value) {
|
|
12446
|
+
if (typeof value === "string") {
|
|
12447
|
+
return sanitizeContent(value);
|
|
12448
|
+
}
|
|
12449
|
+
if (Array.isArray(value)) {
|
|
12450
|
+
return value.map((entry) => sanitizeValue(entry));
|
|
12451
|
+
}
|
|
12452
|
+
if (value && typeof value === "object") {
|
|
12453
|
+
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeValue(entry)]));
|
|
12454
|
+
}
|
|
12455
|
+
return value;
|
|
12456
|
+
}
|
|
12457
|
+
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;
|
|
12458
|
+
var init_sanitize = __esm(() => {
|
|
12459
|
+
SENSITIVE_KEY_WORD = /(?:token|password|secret|api[_-]?key|passwd|pwd|credential)/i;
|
|
12460
|
+
SEGMENTED_KEY_WORD = /(?:^|[_.-])key(?:$|[_.-])/i;
|
|
12461
|
+
CAMEL_CASE_KEY_WORD = /[a-z0-9]Key(?:$|[A-Z_.-])/;
|
|
12462
|
+
JWT_PATTERN = /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
|
|
12463
|
+
AWS_ACCESS_KEY_ID_PATTERN = /\b(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}\b/g;
|
|
12464
|
+
quotedSensitiveKeyValuePattern = new RegExp(String.raw`((['"])(${KEY_NAME})\2[^\S\r\n]*:[^\S\r\n]*)(['"])([^'"\r\n]+)\4`, "gi");
|
|
12465
|
+
unquotedSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)(['"])([^'"\r\n]+)\3`, "gi");
|
|
12466
|
+
bareSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)([^\s,;&'"]+)`, "gi");
|
|
12467
|
+
});
|
|
12468
|
+
|
|
12469
|
+
// src/lib/bridge-tool-failures.ts
|
|
12470
|
+
import { closeSync as closeSync2, existsSync as existsSync10, openSync as openSync2, readSync as readSync2, statSync as statSync6 } from "node:fs";
|
|
12471
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
12380
12472
|
import { join as join10 } from "node:path";
|
|
12473
|
+
function resolveBridgePluginLogPath() {
|
|
12474
|
+
const isTestEnv = process.env.BUN_TEST === "1" || false;
|
|
12475
|
+
return join10(tmpdir2(), isTestEnv ? "aft-plugin-test.log" : "aft-plugin.log");
|
|
12476
|
+
}
|
|
12477
|
+
function tailLogFileBytes(path, maxBytes) {
|
|
12478
|
+
if (!existsSync10(path) || maxBytes <= 0)
|
|
12479
|
+
return "";
|
|
12480
|
+
let fd = null;
|
|
12481
|
+
try {
|
|
12482
|
+
const size = statSync6(path).size;
|
|
12483
|
+
if (size === 0)
|
|
12484
|
+
return "";
|
|
12485
|
+
const readLength = Math.min(size, maxBytes);
|
|
12486
|
+
const position = size - readLength;
|
|
12487
|
+
fd = openSync2(path, "r");
|
|
12488
|
+
const buffer = Buffer.allocUnsafe(readLength);
|
|
12489
|
+
const bytesRead = readSync2(fd, buffer, 0, readLength, position);
|
|
12490
|
+
return buffer.subarray(0, bytesRead).toString("utf-8").trim();
|
|
12491
|
+
} catch {
|
|
12492
|
+
return "";
|
|
12493
|
+
} finally {
|
|
12494
|
+
if (fd !== null) {
|
|
12495
|
+
try {
|
|
12496
|
+
closeSync2(fd);
|
|
12497
|
+
} catch {}
|
|
12498
|
+
}
|
|
12499
|
+
}
|
|
12500
|
+
}
|
|
12501
|
+
function stripSessionTags(line) {
|
|
12502
|
+
return line.replace(SESSION_TAG_PATTERN, "").replace(/\s+/g, " ").trim();
|
|
12503
|
+
}
|
|
12504
|
+
function stripPathLikeTokens(label) {
|
|
12505
|
+
let out = label;
|
|
12506
|
+
out = out.replace(/\/(?:Users|home|var|tmp|private|Volumes)\/[^\s"'`,;)]+/gi, "<path>");
|
|
12507
|
+
out = out.replace(/[A-Za-z]:\\(?:Users|Program Files)[^\\s"'`,;)]+/gi, "<path>");
|
|
12508
|
+
out = out.replace(/file:\/\/[^\s"'`,;)]+/gi, "<path>");
|
|
12509
|
+
out = out.replace(/\(id=[^)]+\)/gi, "");
|
|
12510
|
+
return out.replace(/\s+/g, " ").trim();
|
|
12511
|
+
}
|
|
12512
|
+
function classifyBridgeLogLine(line) {
|
|
12513
|
+
const timeoutMatch = line.match(/Request "([^"]+)"[\s\S]*?timed out after (\d+)ms/i);
|
|
12514
|
+
if (timeoutMatch) {
|
|
12515
|
+
return `${timeoutMatch[1]}: timed out after ${timeoutMatch[2]}ms`;
|
|
12516
|
+
}
|
|
12517
|
+
const lowerTimeout = line.match(/request "([^"]+)" timed out after (\d+)ms/i);
|
|
12518
|
+
if (lowerTimeout) {
|
|
12519
|
+
return `${lowerTimeout[1]}: timed out after ${lowerTimeout[2]}ms`;
|
|
12520
|
+
}
|
|
12521
|
+
if (/Bridge killed after timeout/i.test(line)) {
|
|
12522
|
+
return "bridge killed after timeout";
|
|
12523
|
+
}
|
|
12524
|
+
if (/bridge killed during sibling timeout/i.test(line)) {
|
|
12525
|
+
return "bridge killed during sibling timeout";
|
|
12526
|
+
}
|
|
12527
|
+
if (/restarting bridge/i.test(line)) {
|
|
12528
|
+
return "restarting bridge";
|
|
12529
|
+
}
|
|
12530
|
+
const rpcMatch = line.match(/RPC error:\s*([^\s=]+)/i);
|
|
12531
|
+
if (rpcMatch) {
|
|
12532
|
+
return `rpc: RPC error (${rpcMatch[1]})`;
|
|
12533
|
+
}
|
|
12534
|
+
if (/spawn error/i.test(line)) {
|
|
12535
|
+
return "spawn: spawn error";
|
|
12536
|
+
}
|
|
12537
|
+
if (/failed to spawn/i.test(line)) {
|
|
12538
|
+
return "spawn: failed to spawn";
|
|
12539
|
+
}
|
|
12540
|
+
if (/\bonnx/i.test(line) && /\b(?:error|failed|missing|incompatible)\b/i.test(line)) {
|
|
12541
|
+
return "onnx: onnx runtime error";
|
|
12542
|
+
}
|
|
12543
|
+
if (/\bORT_/i.test(line) && /\b(?:error|failed)\b/i.test(line)) {
|
|
12544
|
+
return "onnx: ORT error";
|
|
12545
|
+
}
|
|
12546
|
+
const codeMatch = line.match(STRUCTURED_CODE_PATTERN);
|
|
12547
|
+
if (codeMatch && /\bERROR\b/.test(line)) {
|
|
12548
|
+
return `code: ${codeMatch[1]}`;
|
|
12549
|
+
}
|
|
12550
|
+
if (/\bERROR\b/.test(line) && /\[aft-plugin\]|\[aft-bridge\]|\[aft-lsp\]|\[aft\]/i.test(line)) {
|
|
12551
|
+
return "error: ERROR log line";
|
|
12552
|
+
}
|
|
12553
|
+
return null;
|
|
12554
|
+
}
|
|
12555
|
+
function aggregateBridgeToolFailures(logText) {
|
|
12556
|
+
const counts = new Map;
|
|
12557
|
+
if (!logText.trim())
|
|
12558
|
+
return counts;
|
|
12559
|
+
for (const rawLine of logText.split(/\r?\n/)) {
|
|
12560
|
+
if (!stripSessionTags(rawLine))
|
|
12561
|
+
continue;
|
|
12562
|
+
const key = classifyBridgeLogLine(rawLine);
|
|
12563
|
+
if (!key)
|
|
12564
|
+
continue;
|
|
12565
|
+
const sanitizedKey = stripPathLikeTokens(sanitizeContent(key));
|
|
12566
|
+
if (!sanitizedKey)
|
|
12567
|
+
continue;
|
|
12568
|
+
counts.set(sanitizedKey, (counts.get(sanitizedKey) ?? 0) + 1);
|
|
12569
|
+
}
|
|
12570
|
+
return counts;
|
|
12571
|
+
}
|
|
12572
|
+
function sortFailureKeys(a, b, counts) {
|
|
12573
|
+
const countDiff = (counts.get(b) ?? 0) - (counts.get(a) ?? 0);
|
|
12574
|
+
if (countDiff !== 0)
|
|
12575
|
+
return countDiff;
|
|
12576
|
+
return a.localeCompare(b);
|
|
12577
|
+
}
|
|
12578
|
+
function formatRecentAftToolFailuresSection(counts, options) {
|
|
12579
|
+
const maxClasses = options?.maxClasses ?? MAX_TOOL_FAILURE_CLASSES;
|
|
12580
|
+
const heading = "### Recent AFT tool failures";
|
|
12581
|
+
if (counts.size === 0) {
|
|
12582
|
+
return `${heading}
|
|
12583
|
+
No recent AFT tool failures recorded.`;
|
|
12584
|
+
}
|
|
12585
|
+
const sorted = [...counts.keys()].sort((a, b) => sortFailureKeys(a, b, counts));
|
|
12586
|
+
const shown = sorted.slice(0, maxClasses);
|
|
12587
|
+
const hidden = sorted.length - shown.length;
|
|
12588
|
+
const bullets = shown.map((key) => {
|
|
12589
|
+
const count = counts.get(key) ?? 0;
|
|
12590
|
+
return `- ${key} ×${count}`;
|
|
12591
|
+
});
|
|
12592
|
+
if (hidden > 0) {
|
|
12593
|
+
bullets.push(`- +${hidden} more failure class(es) omitted`);
|
|
12594
|
+
}
|
|
12595
|
+
return [heading, ...bullets].join(`
|
|
12596
|
+
`);
|
|
12597
|
+
}
|
|
12598
|
+
function buildRecentAftToolFailuresSectionFromLog(logPath = resolveBridgePluginLogPath(), options) {
|
|
12599
|
+
const tailBytes = options?.tailBytes ?? BRIDGE_LOG_TAIL_BYTES;
|
|
12600
|
+
const tail = tailLogFileBytes(logPath, tailBytes);
|
|
12601
|
+
const counts = aggregateBridgeToolFailures(tail);
|
|
12602
|
+
return formatRecentAftToolFailuresSection(counts, options);
|
|
12603
|
+
}
|
|
12604
|
+
var BRIDGE_LOG_TAIL_BYTES, MAX_TOOL_FAILURE_CLASSES = 30, SESSION_TAG_PATTERN, STRUCTURED_CODE_PATTERN;
|
|
12605
|
+
var init_bridge_tool_failures = __esm(() => {
|
|
12606
|
+
init_sanitize();
|
|
12607
|
+
BRIDGE_LOG_TAIL_BYTES = 2 * 1024 * 1024;
|
|
12608
|
+
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;
|
|
12609
|
+
STRUCTURED_CODE_PATTERN = /"code"\s*:\s*"([^"]+)"/;
|
|
12610
|
+
});
|
|
12611
|
+
|
|
12612
|
+
// src/lib/lsp-cache.ts
|
|
12613
|
+
import { existsSync as existsSync11, readdirSync as readdirSync5, rmSync as rmSync2, statSync as statSync7 } from "node:fs";
|
|
12614
|
+
import { join as join11 } from "node:path";
|
|
12381
12615
|
function inspectDir(path) {
|
|
12382
|
-
if (!
|
|
12616
|
+
if (!existsSync11(path)) {
|
|
12383
12617
|
return { entries: [], totalSize: 0 };
|
|
12384
12618
|
}
|
|
12385
12619
|
const entries = [];
|
|
@@ -12391,9 +12625,9 @@ function inspectDir(path) {
|
|
|
12391
12625
|
return { entries: [], totalSize: 0 };
|
|
12392
12626
|
}
|
|
12393
12627
|
for (const name of names) {
|
|
12394
|
-
const full =
|
|
12628
|
+
const full = join11(path, name);
|
|
12395
12629
|
try {
|
|
12396
|
-
if (!
|
|
12630
|
+
if (!statSync7(full).isDirectory())
|
|
12397
12631
|
continue;
|
|
12398
12632
|
const size = dirSize(full);
|
|
12399
12633
|
entries.push({
|
|
@@ -12449,8 +12683,8 @@ var init_lsp_cache = __esm(() => {
|
|
|
12449
12683
|
});
|
|
12450
12684
|
|
|
12451
12685
|
// src/lib/onnx.ts
|
|
12452
|
-
import { existsSync as
|
|
12453
|
-
import { basename, isAbsolute as isAbsolute2, join as
|
|
12686
|
+
import { existsSync as existsSync12, readdirSync as readdirSync6, readlinkSync, realpathSync as realpathSync3, statSync as statSync8 } from "node:fs";
|
|
12687
|
+
import { basename, isAbsolute as isAbsolute2, join as join12, resolve as resolve4, win32 } from "node:path";
|
|
12454
12688
|
function getOnnxLibraryName() {
|
|
12455
12689
|
if (process.platform === "darwin")
|
|
12456
12690
|
return "libonnxruntime.dylib";
|
|
@@ -12513,13 +12747,13 @@ function findSystemOnnxRuntime() {
|
|
|
12513
12747
|
searchPaths.push(...pathEntriesForPlatform());
|
|
12514
12748
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
12515
12749
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
12516
|
-
searchPaths.push(
|
|
12750
|
+
searchPaths.push(join12(programFiles, "onnxruntime", "lib"), join12(programFiles, "Microsoft ONNX Runtime", "lib"), join12(programFiles, "Microsoft Machine Learning", "lib"), join12(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
12517
12751
|
const nugetPaths = [];
|
|
12518
12752
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
12519
12753
|
if (!userProfile)
|
|
12520
12754
|
return nugetPaths;
|
|
12521
|
-
const nugetPackageDir =
|
|
12522
|
-
if (!
|
|
12755
|
+
const nugetPackageDir = join12(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
12756
|
+
if (!existsSync12(nugetPackageDir))
|
|
12523
12757
|
return nugetPaths;
|
|
12524
12758
|
try {
|
|
12525
12759
|
for (const entry of readdirSync6(nugetPackageDir, { withFileTypes: true })) {
|
|
@@ -12527,7 +12761,7 @@ function findSystemOnnxRuntime() {
|
|
|
12527
12761
|
continue;
|
|
12528
12762
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
12529
12763
|
continue;
|
|
12530
|
-
nugetPaths.push(
|
|
12764
|
+
nugetPaths.push(join12(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join12(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
12531
12765
|
}
|
|
12532
12766
|
} catch {}
|
|
12533
12767
|
return nugetPaths;
|
|
@@ -12557,12 +12791,12 @@ function findSystemOnnxRuntime() {
|
|
|
12557
12791
|
return unknownVersionPaths[0] ?? null;
|
|
12558
12792
|
}
|
|
12559
12793
|
function findCachedOnnxRuntime(storageDir) {
|
|
12560
|
-
const ortDir =
|
|
12794
|
+
const ortDir = join12(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
|
|
12561
12795
|
const libName = getOnnxLibraryName();
|
|
12562
|
-
if (
|
|
12796
|
+
if (existsSync12(join12(ortDir, libName)))
|
|
12563
12797
|
return ortDir;
|
|
12564
|
-
const libSubdir =
|
|
12565
|
-
if (
|
|
12798
|
+
const libSubdir = join12(ortDir, "lib");
|
|
12799
|
+
if (existsSync12(join12(libSubdir, libName)))
|
|
12566
12800
|
return libSubdir;
|
|
12567
12801
|
return null;
|
|
12568
12802
|
}
|
|
@@ -12583,7 +12817,7 @@ function parseOrtVersionFromDirectoryPath(value) {
|
|
|
12583
12817
|
return null;
|
|
12584
12818
|
}
|
|
12585
12819
|
function detectOrtVersion(libDir) {
|
|
12586
|
-
if (!
|
|
12820
|
+
if (!existsSync12(libDir))
|
|
12587
12821
|
return null;
|
|
12588
12822
|
const libName = getOnnxLibraryName();
|
|
12589
12823
|
try {
|
|
@@ -12598,10 +12832,10 @@ function detectOrtVersion(libDir) {
|
|
|
12598
12832
|
if (version)
|
|
12599
12833
|
return version;
|
|
12600
12834
|
}
|
|
12601
|
-
const base =
|
|
12602
|
-
if (
|
|
12835
|
+
const base = join12(libDir, libName);
|
|
12836
|
+
if (existsSync12(base)) {
|
|
12603
12837
|
try {
|
|
12604
|
-
const real =
|
|
12838
|
+
const real = realpathSync3(base);
|
|
12605
12839
|
const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
|
|
12606
12840
|
if (version)
|
|
12607
12841
|
return version;
|
|
@@ -12629,93 +12863,15 @@ function isOrtVersionCompatible(version) {
|
|
|
12629
12863
|
var ONNX_RUNTIME_VERSION = "1.24.4", INVALID_ORT_VERSION = "<invalid>", REQUIRED_ORT_MAJOR = 1, REQUIRED_ORT_MIN_MINOR = 20;
|
|
12630
12864
|
var init_onnx = () => {};
|
|
12631
12865
|
|
|
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
12866
|
// src/lib/diagnostics.ts
|
|
12711
12867
|
import {
|
|
12712
12868
|
accessSync,
|
|
12713
|
-
closeSync as
|
|
12869
|
+
closeSync as closeSync3,
|
|
12714
12870
|
constants,
|
|
12715
|
-
existsSync as
|
|
12716
|
-
openSync as
|
|
12717
|
-
readSync as
|
|
12718
|
-
statSync as
|
|
12871
|
+
existsSync as existsSync13,
|
|
12872
|
+
openSync as openSync3,
|
|
12873
|
+
readSync as readSync3,
|
|
12874
|
+
statSync as statSync9
|
|
12719
12875
|
} from "node:fs";
|
|
12720
12876
|
async function collectDiagnostics(adapters) {
|
|
12721
12877
|
const cliVersion = getSelfVersion();
|
|
@@ -12744,7 +12900,7 @@ async function diagnoseHarness(adapter) {
|
|
|
12744
12900
|
const logPath = adapter.getLogFile();
|
|
12745
12901
|
const pluginCache = adapter.getPluginCacheInfo();
|
|
12746
12902
|
const storageAccessible = (() => {
|
|
12747
|
-
if (!
|
|
12903
|
+
if (!existsSync13(storage))
|
|
12748
12904
|
return false;
|
|
12749
12905
|
try {
|
|
12750
12906
|
accessSync(storage, constants.R_OK | constants.W_OK);
|
|
@@ -12767,14 +12923,14 @@ async function diagnoseHarness(adapter) {
|
|
|
12767
12923
|
pluginRegistered: adapter.hasPluginEntry(),
|
|
12768
12924
|
configPaths,
|
|
12769
12925
|
aftConfig: {
|
|
12770
|
-
exists:
|
|
12926
|
+
exists: existsSync13(configPaths.aftConfig),
|
|
12771
12927
|
...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
|
|
12772
12928
|
flags: aftFlags
|
|
12773
12929
|
},
|
|
12774
12930
|
pluginCache,
|
|
12775
12931
|
storageDir: {
|
|
12776
12932
|
path: storage,
|
|
12777
|
-
exists:
|
|
12933
|
+
exists: existsSync13(storage),
|
|
12778
12934
|
accessible: storageAccessible,
|
|
12779
12935
|
sizesByKey: describeStorage
|
|
12780
12936
|
},
|
|
@@ -12792,8 +12948,8 @@ async function diagnoseHarness(adapter) {
|
|
|
12792
12948
|
},
|
|
12793
12949
|
logFile: {
|
|
12794
12950
|
path: logPath,
|
|
12795
|
-
exists:
|
|
12796
|
-
sizeKb:
|
|
12951
|
+
exists: existsSync13(logPath),
|
|
12952
|
+
sizeKb: existsSync13(logPath) ? Math.round(statSync9(logPath).size / 1024) : 0
|
|
12797
12953
|
}
|
|
12798
12954
|
};
|
|
12799
12955
|
}
|
|
@@ -12987,15 +13143,15 @@ function formatDiagnosticIssuesSection(report) {
|
|
|
12987
13143
|
return lines;
|
|
12988
13144
|
}
|
|
12989
13145
|
function tailLogFile(path, lines) {
|
|
12990
|
-
if (!
|
|
13146
|
+
if (!existsSync13(path))
|
|
12991
13147
|
return "";
|
|
12992
13148
|
if (lines <= 0)
|
|
12993
13149
|
return "";
|
|
12994
13150
|
const chunkSize = 64 * 1024;
|
|
12995
13151
|
let fd = null;
|
|
12996
13152
|
try {
|
|
12997
|
-
const size =
|
|
12998
|
-
fd =
|
|
13153
|
+
const size = statSync9(path).size;
|
|
13154
|
+
fd = openSync3(path, "r");
|
|
12999
13155
|
const chunks = [];
|
|
13000
13156
|
let position = size;
|
|
13001
13157
|
let newlineCount = 0;
|
|
@@ -13003,7 +13159,7 @@ function tailLogFile(path, lines) {
|
|
|
13003
13159
|
const readLength = Math.min(chunkSize, position);
|
|
13004
13160
|
position -= readLength;
|
|
13005
13161
|
const buffer = Buffer.allocUnsafe(readLength);
|
|
13006
|
-
const bytesRead =
|
|
13162
|
+
const bytesRead = readSync3(fd, buffer, 0, readLength, position);
|
|
13007
13163
|
const chunk = bytesRead === readLength ? buffer : buffer.subarray(0, bytesRead);
|
|
13008
13164
|
chunks.unshift(chunk);
|
|
13009
13165
|
for (let i = chunk.length - 1;i >= 0; i -= 1) {
|
|
@@ -13018,7 +13174,7 @@ function tailLogFile(path, lines) {
|
|
|
13018
13174
|
} finally {
|
|
13019
13175
|
if (fd !== null) {
|
|
13020
13176
|
try {
|
|
13021
|
-
|
|
13177
|
+
closeSync3(fd);
|
|
13022
13178
|
} catch {}
|
|
13023
13179
|
}
|
|
13024
13180
|
}
|
|
@@ -13077,7 +13233,7 @@ var init_github = () => {};
|
|
|
13077
13233
|
function filterLogToSession(logText, sessionId) {
|
|
13078
13234
|
const bareId = sessionId.replace(/^ses_/, "");
|
|
13079
13235
|
const keepTokens = [`[ses_${bareId}]`, `[${bareId}]`];
|
|
13080
|
-
return logText.split(/\r?\n/).filter((line) => !
|
|
13236
|
+
return logText.split(/\r?\n/).filter((line) => !SESSION_TAG_PATTERN2.test(line) || keepTokens.some((token) => line.includes(token))).join(`
|
|
13081
13237
|
`);
|
|
13082
13238
|
}
|
|
13083
13239
|
function isErrorLogLine(line) {
|
|
@@ -13157,9 +13313,9 @@ function truncateToByteBudget(input, maxBytes) {
|
|
|
13157
13313
|
}
|
|
13158
13314
|
return buf.subarray(0, end).toString("utf8");
|
|
13159
13315
|
}
|
|
13160
|
-
var MAX_GITHUB_BODY_BYTES = 60000,
|
|
13316
|
+
var MAX_GITHUB_BODY_BYTES = 60000, SESSION_TAG_PATTERN2, ERROR_LOG_PATTERNS;
|
|
13161
13317
|
var init_issue_body = __esm(() => {
|
|
13162
|
-
|
|
13318
|
+
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
13319
|
ERROR_LOG_PATTERNS = [
|
|
13164
13320
|
/\bcrashed:/i,
|
|
13165
13321
|
/\bfailed:/i,
|
|
@@ -13173,8 +13329,8 @@ var init_issue_body = __esm(() => {
|
|
|
13173
13329
|
});
|
|
13174
13330
|
|
|
13175
13331
|
// src/lib/onnx-fix.ts
|
|
13176
|
-
import { existsSync as
|
|
13177
|
-
import { join as
|
|
13332
|
+
import { existsSync as existsSync14, rmSync as rmSync3 } from "node:fs";
|
|
13333
|
+
import { join as join13 } from "node:path";
|
|
13178
13334
|
function findOnnxFixCandidates(report) {
|
|
13179
13335
|
const candidates = [];
|
|
13180
13336
|
for (const harness of report.harnesses) {
|
|
@@ -13182,7 +13338,7 @@ function findOnnxFixCandidates(report) {
|
|
|
13182
13338
|
continue;
|
|
13183
13339
|
if (!harness.storageDir.exists)
|
|
13184
13340
|
continue;
|
|
13185
|
-
const storageOnnxDir =
|
|
13341
|
+
const storageOnnxDir = join13(harness.storageDir.path, "onnxruntime");
|
|
13186
13342
|
const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
|
|
13187
13343
|
const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
|
|
13188
13344
|
const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
|
|
@@ -13191,7 +13347,7 @@ function findOnnxFixCandidates(report) {
|
|
|
13191
13347
|
harness,
|
|
13192
13348
|
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
13349
|
storageOnnxDir,
|
|
13194
|
-
storageOnnxBytes:
|
|
13350
|
+
storageOnnxBytes: existsSync14(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
13195
13351
|
});
|
|
13196
13352
|
continue;
|
|
13197
13353
|
}
|
|
@@ -13200,7 +13356,7 @@ function findOnnxFixCandidates(report) {
|
|
|
13200
13356
|
harness,
|
|
13201
13357
|
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
13358
|
storageOnnxDir,
|
|
13203
|
-
storageOnnxBytes:
|
|
13359
|
+
storageOnnxBytes: existsSync14(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
13204
13360
|
});
|
|
13205
13361
|
}
|
|
13206
13362
|
}
|
|
@@ -13230,7 +13386,7 @@ async function runOnnxFix(adapters, report, options = {}) {
|
|
|
13230
13386
|
const result = { cleared: 0, bytesReclaimed: 0, errors: [] };
|
|
13231
13387
|
const rmFn = options.rmFn ?? rmSync3;
|
|
13232
13388
|
for (const c2 of candidates) {
|
|
13233
|
-
if (!
|
|
13389
|
+
if (!existsSync14(c2.storageOnnxDir)) {
|
|
13234
13390
|
O2.success(`${c2.harness.displayName}: no cached state to clear; restart your harness to trigger a fresh ONNX download`);
|
|
13235
13391
|
continue;
|
|
13236
13392
|
}
|
|
@@ -13256,10 +13412,10 @@ var init_onnx_fix = __esm(() => {
|
|
|
13256
13412
|
});
|
|
13257
13413
|
|
|
13258
13414
|
// src/lib/sessions.ts
|
|
13259
|
-
import { existsSync as
|
|
13415
|
+
import { existsSync as existsSync15, readdirSync as readdirSync7, readFileSync as readFileSync4, statSync as statSync10 } from "node:fs";
|
|
13260
13416
|
import { createRequire as createRequire3 } from "node:module";
|
|
13261
13417
|
import { homedir as homedir9 } from "node:os";
|
|
13262
|
-
import { basename as basename2, join as
|
|
13418
|
+
import { basename as basename2, join as join14 } from "node:path";
|
|
13263
13419
|
function listRecentSessions(adapter) {
|
|
13264
13420
|
try {
|
|
13265
13421
|
if (adapter.kind === "opencode")
|
|
@@ -13288,8 +13444,8 @@ function mapOpenCodeSessionRows(rows) {
|
|
|
13288
13444
|
}).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
|
|
13289
13445
|
}
|
|
13290
13446
|
function listRecentOpenCodeSessions() {
|
|
13291
|
-
const dbPath =
|
|
13292
|
-
if (!
|
|
13447
|
+
const dbPath = join14(getXdgDataHome(), "opencode", "opencode.db");
|
|
13448
|
+
if (!existsSync15(dbPath))
|
|
13293
13449
|
return [];
|
|
13294
13450
|
let db = null;
|
|
13295
13451
|
try {
|
|
@@ -13308,10 +13464,10 @@ function listRecentOpenCodeSessions() {
|
|
|
13308
13464
|
}
|
|
13309
13465
|
function getXdgDataHome() {
|
|
13310
13466
|
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
13311
|
-
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome :
|
|
13467
|
+
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join14(homedir9(), ".local", "share");
|
|
13312
13468
|
}
|
|
13313
13469
|
function listRecentPiSessions() {
|
|
13314
|
-
return listPiSessionsFromDir(
|
|
13470
|
+
return listPiSessionsFromDir(join14(getHomeDir(), ".pi", "agent", "sessions"));
|
|
13315
13471
|
}
|
|
13316
13472
|
function getHomeDir() {
|
|
13317
13473
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
@@ -13319,11 +13475,11 @@ function getHomeDir() {
|
|
|
13319
13475
|
}
|
|
13320
13476
|
function listPiSessionsFromDir(sessionsDir) {
|
|
13321
13477
|
try {
|
|
13322
|
-
if (!
|
|
13478
|
+
if (!existsSync15(sessionsDir))
|
|
13323
13479
|
return [];
|
|
13324
13480
|
const files = collectJsonlFiles(sessionsDir).map((filePath) => {
|
|
13325
13481
|
try {
|
|
13326
|
-
const stats =
|
|
13482
|
+
const stats = statSync10(filePath);
|
|
13327
13483
|
return { filePath, mtimeMs: stats.mtimeMs };
|
|
13328
13484
|
} catch {
|
|
13329
13485
|
return null;
|
|
@@ -13357,7 +13513,7 @@ function collectJsonlFiles(root) {
|
|
|
13357
13513
|
continue;
|
|
13358
13514
|
}
|
|
13359
13515
|
for (const entry of entries) {
|
|
13360
|
-
const path =
|
|
13516
|
+
const path = join14(dir, entry.name);
|
|
13361
13517
|
if (entry.isDirectory()) {
|
|
13362
13518
|
stack.push(path);
|
|
13363
13519
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
@@ -13457,17 +13613,17 @@ __export(exports_doctor, {
|
|
|
13457
13613
|
import { execFileSync } from "node:child_process";
|
|
13458
13614
|
import {
|
|
13459
13615
|
chmodSync as chmodSync2,
|
|
13460
|
-
existsSync as
|
|
13616
|
+
existsSync as existsSync16,
|
|
13461
13617
|
mkdirSync as mkdirSync3,
|
|
13462
13618
|
mkdtempSync,
|
|
13463
13619
|
readFileSync as readFileSync5,
|
|
13464
13620
|
realpathSync as realpathSync4,
|
|
13465
13621
|
rmSync as rmSync4,
|
|
13466
|
-
statSync as
|
|
13622
|
+
statSync as statSync11,
|
|
13467
13623
|
writeFileSync as writeFileSync2
|
|
13468
13624
|
} from "node:fs";
|
|
13469
|
-
import { tmpdir as
|
|
13470
|
-
import { join as
|
|
13625
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
13626
|
+
import { join as join15 } from "node:path";
|
|
13471
13627
|
async function runDoctor(options) {
|
|
13472
13628
|
if (options.issue) {
|
|
13473
13629
|
return runIssueFlow(options.argv);
|
|
@@ -13621,7 +13777,7 @@ function clearOldBinaries() {
|
|
|
13621
13777
|
errors: [],
|
|
13622
13778
|
keptVersion: keepTag
|
|
13623
13779
|
};
|
|
13624
|
-
if (!
|
|
13780
|
+
if (!existsSync16(info.path)) {
|
|
13625
13781
|
O2.info(`Binary cache: nothing to clear at ${info.path}`);
|
|
13626
13782
|
return result;
|
|
13627
13783
|
}
|
|
@@ -13631,10 +13787,10 @@ function clearOldBinaries() {
|
|
|
13631
13787
|
return result;
|
|
13632
13788
|
}
|
|
13633
13789
|
for (const version of stale) {
|
|
13634
|
-
const dir =
|
|
13790
|
+
const dir = join15(info.path, version);
|
|
13635
13791
|
let bytes = 0;
|
|
13636
13792
|
try {
|
|
13637
|
-
bytes =
|
|
13793
|
+
bytes = statSync11(dir).isDirectory() ? dirSize(dir) : 0;
|
|
13638
13794
|
} catch {
|
|
13639
13795
|
bytes = 0;
|
|
13640
13796
|
}
|
|
@@ -13956,7 +14112,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
|
|
|
13956
14112
|
if (!adapter.isInstalled() || !adapter.hasPluginEntry())
|
|
13957
14113
|
continue;
|
|
13958
14114
|
const storageDir = adapter.getStorageDir();
|
|
13959
|
-
if (
|
|
14115
|
+
if (existsSync16(storageDir))
|
|
13960
14116
|
continue;
|
|
13961
14117
|
mkdirSync3(storageDir, { recursive: true });
|
|
13962
14118
|
summary.created += 1;
|
|
@@ -14059,11 +14215,11 @@ function deriveIssueTitleFromBody(body) {
|
|
|
14059
14215
|
function writeIssueReviewFile(body) {
|
|
14060
14216
|
let reviewDir = null;
|
|
14061
14217
|
try {
|
|
14062
|
-
reviewDir = mkdtempSync(
|
|
14218
|
+
reviewDir = mkdtempSync(join15(tmpdir3(), "aft-issue-"));
|
|
14063
14219
|
if (process.platform !== "win32") {
|
|
14064
14220
|
chmodSync2(reviewDir, 448);
|
|
14065
14221
|
}
|
|
14066
|
-
const outPath =
|
|
14222
|
+
const outPath = join15(reviewDir, "issue.md");
|
|
14067
14223
|
writeFileSync2(outPath, `${body}
|
|
14068
14224
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
14069
14225
|
return { path: outPath, realPath: realpathSync4(outPath) };
|
|
@@ -14152,6 +14308,7 @@ ${scopedTail || "<no log output>"}
|
|
|
14152
14308
|
const recentErrorsSection = recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
|
|
14153
14309
|
`), "```"].join(`
|
|
14154
14310
|
`);
|
|
14311
|
+
const toolFailuresSection = buildRecentAftToolFailuresSectionFromLog();
|
|
14155
14312
|
const rawBody = [
|
|
14156
14313
|
"## Description",
|
|
14157
14314
|
description,
|
|
@@ -14169,6 +14326,8 @@ ${scopedTail || "<no log output>"}
|
|
|
14169
14326
|
"## Recent errors (last 20, sanitized)",
|
|
14170
14327
|
recentErrorsSection,
|
|
14171
14328
|
"",
|
|
14329
|
+
toolFailuresSection,
|
|
14330
|
+
"",
|
|
14172
14331
|
"## Logs (last 200 lines per harness)",
|
|
14173
14332
|
logSections,
|
|
14174
14333
|
"_Usernames and home paths have been stripped from this report._"
|
|
@@ -14223,6 +14382,7 @@ var DOCTOR_CLEAR_TARGET_OPTIONS, DOCTOR_FORCE_CLEAR_TARGETS;
|
|
|
14223
14382
|
var init_doctor = __esm(async () => {
|
|
14224
14383
|
init_dist();
|
|
14225
14384
|
init_binary_cache();
|
|
14385
|
+
init_bridge_tool_failures();
|
|
14226
14386
|
init_fs_util();
|
|
14227
14387
|
init_github();
|
|
14228
14388
|
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.
|
|
3
|
+
"version": "0.39.2",
|
|
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.
|
|
27
|
+
"@cortexkit/aft-bridge": "0.39.2",
|
|
28
28
|
"comment-json": "^4.6.2"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|