@cortexkit/aft 0.39.0 → 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
|
@@ -104,8 +104,13 @@ var ACTIVE_LOGGER_SYMBOL;
|
|
|
104
104
|
var init_active_logger = __esm(() => {
|
|
105
105
|
ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
|
|
106
106
|
});
|
|
107
|
+
// ../aft-bridge/dist/bash-hints.js
|
|
108
|
+
var init_bash_hints = () => {};
|
|
107
109
|
// ../aft-bridge/dist/command-timeouts.js
|
|
108
|
-
|
|
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;
|
|
109
114
|
var init_command_timeouts = __esm(() => {
|
|
110
115
|
LONG_RUNNING_COMMAND_TIMEOUT_MS = {
|
|
111
116
|
callers: 60000,
|
|
@@ -117,6 +122,7 @@ var init_command_timeouts = __esm(() => {
|
|
|
117
122
|
glob: 60000,
|
|
118
123
|
semantic_search: 60000
|
|
119
124
|
};
|
|
125
|
+
PASSIVE_COMMANDS = new Set(["status"]);
|
|
120
126
|
});
|
|
121
127
|
|
|
122
128
|
// ../aft-bridge/dist/status-bar.js
|
|
@@ -159,6 +165,10 @@ function bashTaskIdFrom(response) {
|
|
|
159
165
|
function tagStderrLine(line) {
|
|
160
166
|
return /^\[aft(-\w+)?\] /.test(line) ? line : `[aft] ${line}`;
|
|
161
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
|
+
}
|
|
162
172
|
function compareSemver(a, b) {
|
|
163
173
|
const [aMain, aPre] = a.split("-", 2);
|
|
164
174
|
const [bMain, bPre] = b.split("-", 2);
|
|
@@ -224,7 +234,7 @@ function clampSemanticTimeout(configOverrides, bridgeTimeoutMs) {
|
|
|
224
234
|
}
|
|
225
235
|
};
|
|
226
236
|
}
|
|
227
|
-
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;
|
|
228
238
|
var init_bridge = __esm(() => {
|
|
229
239
|
init_active_logger();
|
|
230
240
|
init_command_timeouts();
|
|
@@ -262,6 +272,7 @@ var init_bridge = __esm(() => {
|
|
|
262
272
|
_restartCount = 0;
|
|
263
273
|
_shuttingDown = false;
|
|
264
274
|
timeoutMs;
|
|
275
|
+
hangThreshold;
|
|
265
276
|
maxRestarts;
|
|
266
277
|
configured = false;
|
|
267
278
|
_configurePromise = null;
|
|
@@ -286,6 +297,7 @@ var init_bridge = __esm(() => {
|
|
|
286
297
|
this.binaryPath = binaryPath;
|
|
287
298
|
this.cwd = cwd;
|
|
288
299
|
this.timeoutMs = options?.timeoutMs ?? DEFAULT_BRIDGE_TIMEOUT_MS;
|
|
300
|
+
this.hangThreshold = options?.hangThreshold ?? BRIDGE_HANG_TIMEOUT_THRESHOLD;
|
|
289
301
|
this.maxRestarts = options?.maxRestarts ?? 3;
|
|
290
302
|
this.configOverrides = clampSemanticTimeout(configOverrides ?? {}, this.timeoutMs);
|
|
291
303
|
this.minVersion = options?.minVersion;
|
|
@@ -403,7 +415,9 @@ var init_bridge = __esm(() => {
|
|
|
403
415
|
if (requestSessionId && options?.configureWarningClient !== undefined) {
|
|
404
416
|
this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
|
|
405
417
|
}
|
|
406
|
-
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;
|
|
407
421
|
const implicitTransportOptions = {
|
|
408
422
|
...options?.transportTimeoutMs !== undefined || options?.timeoutMs !== undefined ? { transportTimeoutMs: effectiveTimeoutMs } : {},
|
|
409
423
|
markConfiguredOnSuccess: false
|
|
@@ -453,7 +467,7 @@ var init_bridge = __esm(() => {
|
|
|
453
467
|
}
|
|
454
468
|
const line = `${JSON.stringify(request)}
|
|
455
469
|
`;
|
|
456
|
-
const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
|
|
470
|
+
const keepBridgeOnTimeout = passive || options?.keepBridgeOnTimeout === true;
|
|
457
471
|
let requestSentAt = Date.now();
|
|
458
472
|
const response = await new Promise((resolve, reject) => {
|
|
459
473
|
const timer = setTimeout(() => {
|
|
@@ -475,7 +489,7 @@ var init_bridge = __esm(() => {
|
|
|
475
489
|
const childActiveSinceRequest = this.lastChildActivityAt > requestSentAt;
|
|
476
490
|
const consecutiveTimeouts = this.consecutiveRequestTimeouts + 1;
|
|
477
491
|
this.consecutiveRequestTimeouts = consecutiveTimeouts;
|
|
478
|
-
const keepWarm = childActiveSinceRequest || consecutiveTimeouts <
|
|
492
|
+
const keepWarm = childActiveSinceRequest || consecutiveTimeouts < this.hangThreshold;
|
|
479
493
|
const restartSuffix = keepWarm ? " — bridge kept warm" : " — restarting bridge";
|
|
480
494
|
const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
|
|
481
495
|
if (requestSessionId) {
|
|
@@ -770,7 +784,7 @@ var init_bridge = __esm(() => {
|
|
|
770
784
|
`)) !== -1) {
|
|
771
785
|
const line = this.stderrBuffer.slice(0, newlineIdx).replace(/\r$/, "");
|
|
772
786
|
this.stderrBuffer = this.stderrBuffer.slice(newlineIdx + 1);
|
|
773
|
-
if (!line)
|
|
787
|
+
if (!line || !shouldSurfaceStderrLine(line))
|
|
774
788
|
continue;
|
|
775
789
|
const tagged = tagStderrLine(line);
|
|
776
790
|
this.logVia(tagged);
|
|
@@ -780,7 +794,7 @@ var init_bridge = __esm(() => {
|
|
|
780
794
|
flushStderrBuffer() {
|
|
781
795
|
const line = this.stderrBuffer.replace(/\r$/, "");
|
|
782
796
|
this.stderrBuffer = "";
|
|
783
|
-
if (!line)
|
|
797
|
+
if (!line || !shouldSurfaceStderrLine(line))
|
|
784
798
|
return;
|
|
785
799
|
const tagged = tagStderrLine(line);
|
|
786
800
|
this.logVia(tagged);
|
|
@@ -1302,6 +1316,7 @@ class BridgePool {
|
|
|
1302
1316
|
this.projectConfigLoader = options.projectConfigLoader;
|
|
1303
1317
|
this.bridgeOptions = {
|
|
1304
1318
|
timeoutMs: options.timeoutMs,
|
|
1319
|
+
hangThreshold: options.hangThreshold,
|
|
1305
1320
|
maxRestarts: options.maxRestarts,
|
|
1306
1321
|
minVersion: options.minVersion,
|
|
1307
1322
|
onVersionMismatch: options.onVersionMismatch,
|
|
@@ -1466,6 +1481,7 @@ var init_pool = __esm(() => {
|
|
|
1466
1481
|
// ../aft-bridge/dist/index.js
|
|
1467
1482
|
var init_dist = __esm(() => {
|
|
1468
1483
|
init_active_logger();
|
|
1484
|
+
init_bash_hints();
|
|
1469
1485
|
init_bridge();
|
|
1470
1486
|
init_command_timeouts();
|
|
1471
1487
|
init_downloader();
|
|
@@ -12372,11 +12388,232 @@ var init_binary_cache = __esm(() => {
|
|
|
12372
12388
|
init_paths2();
|
|
12373
12389
|
});
|
|
12374
12390
|
|
|
12375
|
-
// src/lib/
|
|
12376
|
-
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";
|
|
12377
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";
|
|
12378
12615
|
function inspectDir(path) {
|
|
12379
|
-
if (!
|
|
12616
|
+
if (!existsSync11(path)) {
|
|
12380
12617
|
return { entries: [], totalSize: 0 };
|
|
12381
12618
|
}
|
|
12382
12619
|
const entries = [];
|
|
@@ -12388,9 +12625,9 @@ function inspectDir(path) {
|
|
|
12388
12625
|
return { entries: [], totalSize: 0 };
|
|
12389
12626
|
}
|
|
12390
12627
|
for (const name of names) {
|
|
12391
|
-
const full =
|
|
12628
|
+
const full = join11(path, name);
|
|
12392
12629
|
try {
|
|
12393
|
-
if (!
|
|
12630
|
+
if (!statSync7(full).isDirectory())
|
|
12394
12631
|
continue;
|
|
12395
12632
|
const size = dirSize(full);
|
|
12396
12633
|
entries.push({
|
|
@@ -12446,8 +12683,8 @@ var init_lsp_cache = __esm(() => {
|
|
|
12446
12683
|
});
|
|
12447
12684
|
|
|
12448
12685
|
// src/lib/onnx.ts
|
|
12449
|
-
import { existsSync as
|
|
12450
|
-
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";
|
|
12451
12688
|
function getOnnxLibraryName() {
|
|
12452
12689
|
if (process.platform === "darwin")
|
|
12453
12690
|
return "libonnxruntime.dylib";
|
|
@@ -12510,13 +12747,13 @@ function findSystemOnnxRuntime() {
|
|
|
12510
12747
|
searchPaths.push(...pathEntriesForPlatform());
|
|
12511
12748
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
12512
12749
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
12513
|
-
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"), ...(() => {
|
|
12514
12751
|
const nugetPaths = [];
|
|
12515
12752
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
12516
12753
|
if (!userProfile)
|
|
12517
12754
|
return nugetPaths;
|
|
12518
|
-
const nugetPackageDir =
|
|
12519
|
-
if (!
|
|
12755
|
+
const nugetPackageDir = join12(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
12756
|
+
if (!existsSync12(nugetPackageDir))
|
|
12520
12757
|
return nugetPaths;
|
|
12521
12758
|
try {
|
|
12522
12759
|
for (const entry of readdirSync6(nugetPackageDir, { withFileTypes: true })) {
|
|
@@ -12524,7 +12761,7 @@ function findSystemOnnxRuntime() {
|
|
|
12524
12761
|
continue;
|
|
12525
12762
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
12526
12763
|
continue;
|
|
12527
|
-
nugetPaths.push(
|
|
12764
|
+
nugetPaths.push(join12(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join12(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
12528
12765
|
}
|
|
12529
12766
|
} catch {}
|
|
12530
12767
|
return nugetPaths;
|
|
@@ -12554,12 +12791,12 @@ function findSystemOnnxRuntime() {
|
|
|
12554
12791
|
return unknownVersionPaths[0] ?? null;
|
|
12555
12792
|
}
|
|
12556
12793
|
function findCachedOnnxRuntime(storageDir) {
|
|
12557
|
-
const ortDir =
|
|
12794
|
+
const ortDir = join12(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
|
|
12558
12795
|
const libName = getOnnxLibraryName();
|
|
12559
|
-
if (
|
|
12796
|
+
if (existsSync12(join12(ortDir, libName)))
|
|
12560
12797
|
return ortDir;
|
|
12561
|
-
const libSubdir =
|
|
12562
|
-
if (
|
|
12798
|
+
const libSubdir = join12(ortDir, "lib");
|
|
12799
|
+
if (existsSync12(join12(libSubdir, libName)))
|
|
12563
12800
|
return libSubdir;
|
|
12564
12801
|
return null;
|
|
12565
12802
|
}
|
|
@@ -12580,7 +12817,7 @@ function parseOrtVersionFromDirectoryPath(value) {
|
|
|
12580
12817
|
return null;
|
|
12581
12818
|
}
|
|
12582
12819
|
function detectOrtVersion(libDir) {
|
|
12583
|
-
if (!
|
|
12820
|
+
if (!existsSync12(libDir))
|
|
12584
12821
|
return null;
|
|
12585
12822
|
const libName = getOnnxLibraryName();
|
|
12586
12823
|
try {
|
|
@@ -12595,10 +12832,10 @@ function detectOrtVersion(libDir) {
|
|
|
12595
12832
|
if (version)
|
|
12596
12833
|
return version;
|
|
12597
12834
|
}
|
|
12598
|
-
const base =
|
|
12599
|
-
if (
|
|
12835
|
+
const base = join12(libDir, libName);
|
|
12836
|
+
if (existsSync12(base)) {
|
|
12600
12837
|
try {
|
|
12601
|
-
const real =
|
|
12838
|
+
const real = realpathSync3(base);
|
|
12602
12839
|
const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
|
|
12603
12840
|
if (version)
|
|
12604
12841
|
return version;
|
|
@@ -12626,93 +12863,15 @@ function isOrtVersionCompatible(version) {
|
|
|
12626
12863
|
var ONNX_RUNTIME_VERSION = "1.24.4", INVALID_ORT_VERSION = "<invalid>", REQUIRED_ORT_MAJOR = 1, REQUIRED_ORT_MIN_MINOR = 20;
|
|
12627
12864
|
var init_onnx = () => {};
|
|
12628
12865
|
|
|
12629
|
-
// src/lib/sanitize.ts
|
|
12630
|
-
import { realpathSync as realpathSync3 } from "node:fs";
|
|
12631
|
-
import { homedir as homedir8, userInfo } from "node:os";
|
|
12632
|
-
function escapeRegex(value) {
|
|
12633
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
12634
|
-
}
|
|
12635
|
-
function safeRealpath(p2) {
|
|
12636
|
-
try {
|
|
12637
|
-
return realpathSync3(p2);
|
|
12638
|
-
} catch {
|
|
12639
|
-
return null;
|
|
12640
|
-
}
|
|
12641
|
-
}
|
|
12642
|
-
function isSensitiveKeyName(keyName) {
|
|
12643
|
-
return SENSITIVE_KEY_WORD.test(keyName) || SEGMENTED_KEY_WORD.test(keyName) || CAMEL_CASE_KEY_WORD.test(keyName);
|
|
12644
|
-
}
|
|
12645
|
-
function redactSecrets(content) {
|
|
12646
|
-
let sanitized = content;
|
|
12647
|
-
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}`);
|
|
12648
|
-
sanitized = sanitized.replace(/\bgithub_pat_[A-Za-z0-9_]+\b/g, SECRET_PLACEHOLDER);
|
|
12649
|
-
sanitized = sanitized.replace(/\bgh(?:p|o|s)_[A-Za-z0-9_]{16,}\b/g, SECRET_PLACEHOLDER);
|
|
12650
|
-
sanitized = sanitized.replace(/\bsk-(?:live-)?[A-Za-z0-9][A-Za-z0-9_-]{7,}\b/g, SECRET_PLACEHOLDER);
|
|
12651
|
-
sanitized = sanitized.replace(JWT_PATTERN, SECRET_PLACEHOLDER);
|
|
12652
|
-
sanitized = sanitized.replace(AWS_ACCESS_KEY_ID_PATTERN, SECRET_PLACEHOLDER);
|
|
12653
|
-
sanitized = sanitized.replace(quotedSensitiveKeyValuePattern, (match, prefix, _keyQuote, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
|
|
12654
|
-
sanitized = sanitized.replace(unquotedSensitiveKeyValuePattern, (match, prefix, keyName, valueQuote) => isSensitiveKeyName(keyName) ? `${prefix}${valueQuote}${SECRET_PLACEHOLDER}${valueQuote}` : match);
|
|
12655
|
-
sanitized = sanitized.replace(bareSensitiveKeyValuePattern, (match, prefix, keyName) => isSensitiveKeyName(keyName) ? `${prefix}${SECRET_PLACEHOLDER}` : match);
|
|
12656
|
-
sanitized = sanitized.replace(/\b([a-z][a-z0-9+.-]*:\/\/)[^@\s/?#]+@/gi, `$1${URL_CREDENTIAL_PLACEHOLDER}@`);
|
|
12657
|
-
sanitized = sanitized.replace(/\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi, "<EMAIL>");
|
|
12658
|
-
return sanitized;
|
|
12659
|
-
}
|
|
12660
|
-
function sanitizeContent(content) {
|
|
12661
|
-
const username = userInfo().username;
|
|
12662
|
-
const home = homedir8();
|
|
12663
|
-
let sanitized = redactSecrets(content);
|
|
12664
|
-
const cwd = process.cwd();
|
|
12665
|
-
for (const candidate of new Set([cwd, safeRealpath(cwd)])) {
|
|
12666
|
-
if (candidate && candidate !== "/" && candidate !== home) {
|
|
12667
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex(candidate), "g"), "<PROJECT>");
|
|
12668
|
-
}
|
|
12669
|
-
}
|
|
12670
|
-
if (home) {
|
|
12671
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex(home), "g"), "~");
|
|
12672
|
-
}
|
|
12673
|
-
sanitized = sanitized.replace(/\/Users\/[^/\s"']+/g, "/Users/<USER>");
|
|
12674
|
-
sanitized = sanitized.replace(/\/home\/[^/\s"']+/g, "/home/<USER>");
|
|
12675
|
-
sanitized = sanitized.replace(/([A-Za-z]:\\\\Users\\\\)[^\\\\"'\s]+/g, "$1<USER>");
|
|
12676
|
-
sanitized = sanitized.replace(/([A-Za-z]:\\Users\\)[^\\"'\s]+/g, "$1<USER>");
|
|
12677
|
-
sanitized = sanitized.replace(/([A-Za-z]:\/Users\/)[^/\s"']+/g, "$1<USER>");
|
|
12678
|
-
if (username) {
|
|
12679
|
-
sanitized = sanitized.replace(new RegExp(escapeRegex(username), "g"), "<USER>");
|
|
12680
|
-
}
|
|
12681
|
-
return sanitized;
|
|
12682
|
-
}
|
|
12683
|
-
function sanitizeValue(value) {
|
|
12684
|
-
if (typeof value === "string") {
|
|
12685
|
-
return sanitizeContent(value);
|
|
12686
|
-
}
|
|
12687
|
-
if (Array.isArray(value)) {
|
|
12688
|
-
return value.map((entry) => sanitizeValue(entry));
|
|
12689
|
-
}
|
|
12690
|
-
if (value && typeof value === "object") {
|
|
12691
|
-
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, sanitizeValue(entry)]));
|
|
12692
|
-
}
|
|
12693
|
-
return value;
|
|
12694
|
-
}
|
|
12695
|
-
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;
|
|
12696
|
-
var init_sanitize = __esm(() => {
|
|
12697
|
-
SENSITIVE_KEY_WORD = /(?:token|password|secret|api[_-]?key|passwd|pwd|credential)/i;
|
|
12698
|
-
SEGMENTED_KEY_WORD = /(?:^|[_.-])key(?:$|[_.-])/i;
|
|
12699
|
-
CAMEL_CASE_KEY_WORD = /[a-z0-9]Key(?:$|[A-Z_.-])/;
|
|
12700
|
-
JWT_PATTERN = /\beyJ[A-Za-z0-9_-]+\.eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g;
|
|
12701
|
-
AWS_ACCESS_KEY_ID_PATTERN = /\b(?:AKIA|ASIA|AGPA|AIDA|AROA)[A-Z0-9]{16}\b/g;
|
|
12702
|
-
quotedSensitiveKeyValuePattern = new RegExp(String.raw`((['"])(${KEY_NAME})\2[^\S\r\n]*:[^\S\r\n]*)(['"])([^'"\r\n]+)\4`, "gi");
|
|
12703
|
-
unquotedSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)(['"])([^'"\r\n]+)\3`, "gi");
|
|
12704
|
-
bareSensitiveKeyValuePattern = new RegExp(String.raw`\b((${KEY_NAME})[^\S\r\n]*[=:][^\S\r\n]*)([^\s,;&'"]+)`, "gi");
|
|
12705
|
-
});
|
|
12706
|
-
|
|
12707
12866
|
// src/lib/diagnostics.ts
|
|
12708
12867
|
import {
|
|
12709
12868
|
accessSync,
|
|
12710
|
-
closeSync as
|
|
12869
|
+
closeSync as closeSync3,
|
|
12711
12870
|
constants,
|
|
12712
|
-
existsSync as
|
|
12713
|
-
openSync as
|
|
12714
|
-
readSync as
|
|
12715
|
-
statSync as
|
|
12871
|
+
existsSync as existsSync13,
|
|
12872
|
+
openSync as openSync3,
|
|
12873
|
+
readSync as readSync3,
|
|
12874
|
+
statSync as statSync9
|
|
12716
12875
|
} from "node:fs";
|
|
12717
12876
|
async function collectDiagnostics(adapters) {
|
|
12718
12877
|
const cliVersion = getSelfVersion();
|
|
@@ -12741,7 +12900,7 @@ async function diagnoseHarness(adapter) {
|
|
|
12741
12900
|
const logPath = adapter.getLogFile();
|
|
12742
12901
|
const pluginCache = adapter.getPluginCacheInfo();
|
|
12743
12902
|
const storageAccessible = (() => {
|
|
12744
|
-
if (!
|
|
12903
|
+
if (!existsSync13(storage))
|
|
12745
12904
|
return false;
|
|
12746
12905
|
try {
|
|
12747
12906
|
accessSync(storage, constants.R_OK | constants.W_OK);
|
|
@@ -12764,14 +12923,14 @@ async function diagnoseHarness(adapter) {
|
|
|
12764
12923
|
pluginRegistered: adapter.hasPluginEntry(),
|
|
12765
12924
|
configPaths,
|
|
12766
12925
|
aftConfig: {
|
|
12767
|
-
exists:
|
|
12926
|
+
exists: existsSync13(configPaths.aftConfig),
|
|
12768
12927
|
...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
|
|
12769
12928
|
flags: aftFlags
|
|
12770
12929
|
},
|
|
12771
12930
|
pluginCache,
|
|
12772
12931
|
storageDir: {
|
|
12773
12932
|
path: storage,
|
|
12774
|
-
exists:
|
|
12933
|
+
exists: existsSync13(storage),
|
|
12775
12934
|
accessible: storageAccessible,
|
|
12776
12935
|
sizesByKey: describeStorage
|
|
12777
12936
|
},
|
|
@@ -12789,8 +12948,8 @@ async function diagnoseHarness(adapter) {
|
|
|
12789
12948
|
},
|
|
12790
12949
|
logFile: {
|
|
12791
12950
|
path: logPath,
|
|
12792
|
-
exists:
|
|
12793
|
-
sizeKb:
|
|
12951
|
+
exists: existsSync13(logPath),
|
|
12952
|
+
sizeKb: existsSync13(logPath) ? Math.round(statSync9(logPath).size / 1024) : 0
|
|
12794
12953
|
}
|
|
12795
12954
|
};
|
|
12796
12955
|
}
|
|
@@ -12984,15 +13143,15 @@ function formatDiagnosticIssuesSection(report) {
|
|
|
12984
13143
|
return lines;
|
|
12985
13144
|
}
|
|
12986
13145
|
function tailLogFile(path, lines) {
|
|
12987
|
-
if (!
|
|
13146
|
+
if (!existsSync13(path))
|
|
12988
13147
|
return "";
|
|
12989
13148
|
if (lines <= 0)
|
|
12990
13149
|
return "";
|
|
12991
13150
|
const chunkSize = 64 * 1024;
|
|
12992
13151
|
let fd = null;
|
|
12993
13152
|
try {
|
|
12994
|
-
const size =
|
|
12995
|
-
fd =
|
|
13153
|
+
const size = statSync9(path).size;
|
|
13154
|
+
fd = openSync3(path, "r");
|
|
12996
13155
|
const chunks = [];
|
|
12997
13156
|
let position = size;
|
|
12998
13157
|
let newlineCount = 0;
|
|
@@ -13000,7 +13159,7 @@ function tailLogFile(path, lines) {
|
|
|
13000
13159
|
const readLength = Math.min(chunkSize, position);
|
|
13001
13160
|
position -= readLength;
|
|
13002
13161
|
const buffer = Buffer.allocUnsafe(readLength);
|
|
13003
|
-
const bytesRead =
|
|
13162
|
+
const bytesRead = readSync3(fd, buffer, 0, readLength, position);
|
|
13004
13163
|
const chunk = bytesRead === readLength ? buffer : buffer.subarray(0, bytesRead);
|
|
13005
13164
|
chunks.unshift(chunk);
|
|
13006
13165
|
for (let i = chunk.length - 1;i >= 0; i -= 1) {
|
|
@@ -13015,7 +13174,7 @@ function tailLogFile(path, lines) {
|
|
|
13015
13174
|
} finally {
|
|
13016
13175
|
if (fd !== null) {
|
|
13017
13176
|
try {
|
|
13018
|
-
|
|
13177
|
+
closeSync3(fd);
|
|
13019
13178
|
} catch {}
|
|
13020
13179
|
}
|
|
13021
13180
|
}
|
|
@@ -13074,7 +13233,7 @@ var init_github = () => {};
|
|
|
13074
13233
|
function filterLogToSession(logText, sessionId) {
|
|
13075
13234
|
const bareId = sessionId.replace(/^ses_/, "");
|
|
13076
13235
|
const keepTokens = [`[ses_${bareId}]`, `[${bareId}]`];
|
|
13077
|
-
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(`
|
|
13078
13237
|
`);
|
|
13079
13238
|
}
|
|
13080
13239
|
function isErrorLogLine(line) {
|
|
@@ -13154,9 +13313,9 @@ function truncateToByteBudget(input, maxBytes) {
|
|
|
13154
13313
|
}
|
|
13155
13314
|
return buf.subarray(0, end).toString("utf8");
|
|
13156
13315
|
}
|
|
13157
|
-
var MAX_GITHUB_BODY_BYTES = 60000,
|
|
13316
|
+
var MAX_GITHUB_BODY_BYTES = 60000, SESSION_TAG_PATTERN2, ERROR_LOG_PATTERNS;
|
|
13158
13317
|
var init_issue_body = __esm(() => {
|
|
13159
|
-
|
|
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}\]/;
|
|
13160
13319
|
ERROR_LOG_PATTERNS = [
|
|
13161
13320
|
/\bcrashed:/i,
|
|
13162
13321
|
/\bfailed:/i,
|
|
@@ -13170,8 +13329,8 @@ var init_issue_body = __esm(() => {
|
|
|
13170
13329
|
});
|
|
13171
13330
|
|
|
13172
13331
|
// src/lib/onnx-fix.ts
|
|
13173
|
-
import { existsSync as
|
|
13174
|
-
import { join as
|
|
13332
|
+
import { existsSync as existsSync14, rmSync as rmSync3 } from "node:fs";
|
|
13333
|
+
import { join as join13 } from "node:path";
|
|
13175
13334
|
function findOnnxFixCandidates(report) {
|
|
13176
13335
|
const candidates = [];
|
|
13177
13336
|
for (const harness of report.harnesses) {
|
|
@@ -13179,7 +13338,7 @@ function findOnnxFixCandidates(report) {
|
|
|
13179
13338
|
continue;
|
|
13180
13339
|
if (!harness.storageDir.exists)
|
|
13181
13340
|
continue;
|
|
13182
|
-
const storageOnnxDir =
|
|
13341
|
+
const storageOnnxDir = join13(harness.storageDir.path, "onnxruntime");
|
|
13183
13342
|
const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
|
|
13184
13343
|
const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
|
|
13185
13344
|
const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
|
|
@@ -13188,7 +13347,7 @@ function findOnnxFixCandidates(report) {
|
|
|
13188
13347
|
harness,
|
|
13189
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.`,
|
|
13190
13349
|
storageOnnxDir,
|
|
13191
|
-
storageOnnxBytes:
|
|
13350
|
+
storageOnnxBytes: existsSync14(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
13192
13351
|
});
|
|
13193
13352
|
continue;
|
|
13194
13353
|
}
|
|
@@ -13197,7 +13356,7 @@ function findOnnxFixCandidates(report) {
|
|
|
13197
13356
|
harness,
|
|
13198
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.`,
|
|
13199
13358
|
storageOnnxDir,
|
|
13200
|
-
storageOnnxBytes:
|
|
13359
|
+
storageOnnxBytes: existsSync14(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
13201
13360
|
});
|
|
13202
13361
|
}
|
|
13203
13362
|
}
|
|
@@ -13227,7 +13386,7 @@ async function runOnnxFix(adapters, report, options = {}) {
|
|
|
13227
13386
|
const result = { cleared: 0, bytesReclaimed: 0, errors: [] };
|
|
13228
13387
|
const rmFn = options.rmFn ?? rmSync3;
|
|
13229
13388
|
for (const c2 of candidates) {
|
|
13230
|
-
if (!
|
|
13389
|
+
if (!existsSync14(c2.storageOnnxDir)) {
|
|
13231
13390
|
O2.success(`${c2.harness.displayName}: no cached state to clear; restart your harness to trigger a fresh ONNX download`);
|
|
13232
13391
|
continue;
|
|
13233
13392
|
}
|
|
@@ -13253,10 +13412,10 @@ var init_onnx_fix = __esm(() => {
|
|
|
13253
13412
|
});
|
|
13254
13413
|
|
|
13255
13414
|
// src/lib/sessions.ts
|
|
13256
|
-
import { existsSync as
|
|
13415
|
+
import { existsSync as existsSync15, readdirSync as readdirSync7, readFileSync as readFileSync4, statSync as statSync10 } from "node:fs";
|
|
13257
13416
|
import { createRequire as createRequire3 } from "node:module";
|
|
13258
13417
|
import { homedir as homedir9 } from "node:os";
|
|
13259
|
-
import { basename as basename2, join as
|
|
13418
|
+
import { basename as basename2, join as join14 } from "node:path";
|
|
13260
13419
|
function listRecentSessions(adapter) {
|
|
13261
13420
|
try {
|
|
13262
13421
|
if (adapter.kind === "opencode")
|
|
@@ -13285,8 +13444,8 @@ function mapOpenCodeSessionRows(rows) {
|
|
|
13285
13444
|
}).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
|
|
13286
13445
|
}
|
|
13287
13446
|
function listRecentOpenCodeSessions() {
|
|
13288
|
-
const dbPath =
|
|
13289
|
-
if (!
|
|
13447
|
+
const dbPath = join14(getXdgDataHome(), "opencode", "opencode.db");
|
|
13448
|
+
if (!existsSync15(dbPath))
|
|
13290
13449
|
return [];
|
|
13291
13450
|
let db = null;
|
|
13292
13451
|
try {
|
|
@@ -13305,10 +13464,10 @@ function listRecentOpenCodeSessions() {
|
|
|
13305
13464
|
}
|
|
13306
13465
|
function getXdgDataHome() {
|
|
13307
13466
|
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
13308
|
-
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome :
|
|
13467
|
+
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join14(homedir9(), ".local", "share");
|
|
13309
13468
|
}
|
|
13310
13469
|
function listRecentPiSessions() {
|
|
13311
|
-
return listPiSessionsFromDir(
|
|
13470
|
+
return listPiSessionsFromDir(join14(getHomeDir(), ".pi", "agent", "sessions"));
|
|
13312
13471
|
}
|
|
13313
13472
|
function getHomeDir() {
|
|
13314
13473
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
@@ -13316,11 +13475,11 @@ function getHomeDir() {
|
|
|
13316
13475
|
}
|
|
13317
13476
|
function listPiSessionsFromDir(sessionsDir) {
|
|
13318
13477
|
try {
|
|
13319
|
-
if (!
|
|
13478
|
+
if (!existsSync15(sessionsDir))
|
|
13320
13479
|
return [];
|
|
13321
13480
|
const files = collectJsonlFiles(sessionsDir).map((filePath) => {
|
|
13322
13481
|
try {
|
|
13323
|
-
const stats =
|
|
13482
|
+
const stats = statSync10(filePath);
|
|
13324
13483
|
return { filePath, mtimeMs: stats.mtimeMs };
|
|
13325
13484
|
} catch {
|
|
13326
13485
|
return null;
|
|
@@ -13354,7 +13513,7 @@ function collectJsonlFiles(root) {
|
|
|
13354
13513
|
continue;
|
|
13355
13514
|
}
|
|
13356
13515
|
for (const entry of entries) {
|
|
13357
|
-
const path =
|
|
13516
|
+
const path = join14(dir, entry.name);
|
|
13358
13517
|
if (entry.isDirectory()) {
|
|
13359
13518
|
stack.push(path);
|
|
13360
13519
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
@@ -13454,17 +13613,17 @@ __export(exports_doctor, {
|
|
|
13454
13613
|
import { execFileSync } from "node:child_process";
|
|
13455
13614
|
import {
|
|
13456
13615
|
chmodSync as chmodSync2,
|
|
13457
|
-
existsSync as
|
|
13616
|
+
existsSync as existsSync16,
|
|
13458
13617
|
mkdirSync as mkdirSync3,
|
|
13459
13618
|
mkdtempSync,
|
|
13460
13619
|
readFileSync as readFileSync5,
|
|
13461
13620
|
realpathSync as realpathSync4,
|
|
13462
13621
|
rmSync as rmSync4,
|
|
13463
|
-
statSync as
|
|
13622
|
+
statSync as statSync11,
|
|
13464
13623
|
writeFileSync as writeFileSync2
|
|
13465
13624
|
} from "node:fs";
|
|
13466
|
-
import { tmpdir as
|
|
13467
|
-
import { join as
|
|
13625
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
13626
|
+
import { join as join15 } from "node:path";
|
|
13468
13627
|
async function runDoctor(options) {
|
|
13469
13628
|
if (options.issue) {
|
|
13470
13629
|
return runIssueFlow(options.argv);
|
|
@@ -13618,7 +13777,7 @@ function clearOldBinaries() {
|
|
|
13618
13777
|
errors: [],
|
|
13619
13778
|
keptVersion: keepTag
|
|
13620
13779
|
};
|
|
13621
|
-
if (!
|
|
13780
|
+
if (!existsSync16(info.path)) {
|
|
13622
13781
|
O2.info(`Binary cache: nothing to clear at ${info.path}`);
|
|
13623
13782
|
return result;
|
|
13624
13783
|
}
|
|
@@ -13628,10 +13787,10 @@ function clearOldBinaries() {
|
|
|
13628
13787
|
return result;
|
|
13629
13788
|
}
|
|
13630
13789
|
for (const version of stale) {
|
|
13631
|
-
const dir =
|
|
13790
|
+
const dir = join15(info.path, version);
|
|
13632
13791
|
let bytes = 0;
|
|
13633
13792
|
try {
|
|
13634
|
-
bytes =
|
|
13793
|
+
bytes = statSync11(dir).isDirectory() ? dirSize(dir) : 0;
|
|
13635
13794
|
} catch {
|
|
13636
13795
|
bytes = 0;
|
|
13637
13796
|
}
|
|
@@ -13953,7 +14112,7 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
|
|
|
13953
14112
|
if (!adapter.isInstalled() || !adapter.hasPluginEntry())
|
|
13954
14113
|
continue;
|
|
13955
14114
|
const storageDir = adapter.getStorageDir();
|
|
13956
|
-
if (
|
|
14115
|
+
if (existsSync16(storageDir))
|
|
13957
14116
|
continue;
|
|
13958
14117
|
mkdirSync3(storageDir, { recursive: true });
|
|
13959
14118
|
summary.created += 1;
|
|
@@ -14056,11 +14215,11 @@ function deriveIssueTitleFromBody(body) {
|
|
|
14056
14215
|
function writeIssueReviewFile(body) {
|
|
14057
14216
|
let reviewDir = null;
|
|
14058
14217
|
try {
|
|
14059
|
-
reviewDir = mkdtempSync(
|
|
14218
|
+
reviewDir = mkdtempSync(join15(tmpdir3(), "aft-issue-"));
|
|
14060
14219
|
if (process.platform !== "win32") {
|
|
14061
14220
|
chmodSync2(reviewDir, 448);
|
|
14062
14221
|
}
|
|
14063
|
-
const outPath =
|
|
14222
|
+
const outPath = join15(reviewDir, "issue.md");
|
|
14064
14223
|
writeFileSync2(outPath, `${body}
|
|
14065
14224
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
14066
14225
|
return { path: outPath, realPath: realpathSync4(outPath) };
|
|
@@ -14149,6 +14308,7 @@ ${scopedTail || "<no log output>"}
|
|
|
14149
14308
|
const recentErrorsSection = recentErrorLines.length === 0 ? "_No error-shaped log lines found in recent history._" : ["```", recentErrorLines.join(`
|
|
14150
14309
|
`), "```"].join(`
|
|
14151
14310
|
`);
|
|
14311
|
+
const toolFailuresSection = buildRecentAftToolFailuresSectionFromLog();
|
|
14152
14312
|
const rawBody = [
|
|
14153
14313
|
"## Description",
|
|
14154
14314
|
description,
|
|
@@ -14166,6 +14326,8 @@ ${scopedTail || "<no log output>"}
|
|
|
14166
14326
|
"## Recent errors (last 20, sanitized)",
|
|
14167
14327
|
recentErrorsSection,
|
|
14168
14328
|
"",
|
|
14329
|
+
toolFailuresSection,
|
|
14330
|
+
"",
|
|
14169
14331
|
"## Logs (last 200 lines per harness)",
|
|
14170
14332
|
logSections,
|
|
14171
14333
|
"_Usernames and home paths have been stripped from this report._"
|
|
@@ -14220,6 +14382,7 @@ var DOCTOR_CLEAR_TARGET_OPTIONS, DOCTOR_FORCE_CLEAR_TARGETS;
|
|
|
14220
14382
|
var init_doctor = __esm(async () => {
|
|
14221
14383
|
init_dist();
|
|
14222
14384
|
init_binary_cache();
|
|
14385
|
+
init_bridge_tool_failures();
|
|
14223
14386
|
init_fs_util();
|
|
14224
14387
|
init_github();
|
|
14225
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": {
|