@cortexkit/aft 0.35.0 → 0.35.1
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.
package/dist/index.js
CHANGED
|
@@ -46,75 +46,1242 @@ var __export = (target, all) => {
|
|
|
46
46
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
47
47
|
var __promiseAll = (args) => Promise.all(args);
|
|
48
48
|
|
|
49
|
-
//
|
|
50
|
-
|
|
49
|
+
// ../aft-bridge/dist/active-logger.js
|
|
50
|
+
function loggerGlobal() {
|
|
51
|
+
return globalThis;
|
|
52
|
+
}
|
|
53
|
+
function getActiveLogger() {
|
|
54
|
+
return loggerGlobal()[ACTIVE_LOGGER_SYMBOL];
|
|
55
|
+
}
|
|
56
|
+
function getLogFilePath() {
|
|
57
|
+
try {
|
|
58
|
+
return getActiveLogger()?.getLogFilePath?.();
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error(`[aft-bridge] ERROR: active logger getLogFilePath threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function log(message, meta) {
|
|
65
|
+
const active = getActiveLogger();
|
|
66
|
+
if (active) {
|
|
67
|
+
try {
|
|
68
|
+
active.log(message, meta);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
console.error(`[aft-bridge] ERROR: active logger log threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
71
|
+
console.error(`[aft-bridge] ${message}`);
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
console.error(`[aft-bridge] ${message}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function warn(message, meta) {
|
|
78
|
+
const active = getActiveLogger();
|
|
79
|
+
if (active) {
|
|
80
|
+
try {
|
|
81
|
+
active.warn(message, meta);
|
|
82
|
+
} catch (err) {
|
|
83
|
+
console.error(`[aft-bridge] ERROR: active logger warn threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
84
|
+
console.error(`[aft-bridge] WARN: ${message}`);
|
|
85
|
+
}
|
|
86
|
+
} else {
|
|
87
|
+
console.error(`[aft-bridge] WARN: ${message}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function error(message, meta) {
|
|
91
|
+
const active = getActiveLogger();
|
|
92
|
+
if (active) {
|
|
93
|
+
try {
|
|
94
|
+
active.error(message, meta);
|
|
95
|
+
} catch (err) {
|
|
96
|
+
console.error(`[aft-bridge] ERROR: active logger error threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
97
|
+
console.error(`[aft-bridge] ERROR: ${message}`);
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
console.error(`[aft-bridge] ERROR: ${message}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
var ACTIVE_LOGGER_SYMBOL;
|
|
104
|
+
var init_active_logger = __esm(() => {
|
|
105
|
+
ACTIVE_LOGGER_SYMBOL = Symbol.for("aft-bridge-active-logger");
|
|
106
|
+
});
|
|
107
|
+
// ../aft-bridge/dist/status-bar.js
|
|
108
|
+
function parseStatusBarCounts(value) {
|
|
109
|
+
if (!value || typeof value !== "object")
|
|
110
|
+
return;
|
|
111
|
+
const record = value;
|
|
112
|
+
const num = (key) => {
|
|
113
|
+
const raw = record[key];
|
|
114
|
+
return typeof raw === "number" && Number.isFinite(raw) ? raw : 0;
|
|
115
|
+
};
|
|
116
|
+
return {
|
|
117
|
+
errors: num("errors"),
|
|
118
|
+
warnings: num("warnings"),
|
|
119
|
+
dead_code: num("dead_code"),
|
|
120
|
+
unused_exports: num("unused_exports"),
|
|
121
|
+
duplicates: num("duplicates"),
|
|
122
|
+
todos: num("todos"),
|
|
123
|
+
tier2_stale: record.tier2_stale === true
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// ../aft-bridge/dist/bridge.js
|
|
128
|
+
import { spawn } from "node:child_process";
|
|
129
|
+
import { homedir } from "node:os";
|
|
51
130
|
import { join } from "node:path";
|
|
131
|
+
import { StringDecoder } from "node:string_decoder";
|
|
132
|
+
function tagStderrLine(line) {
|
|
133
|
+
return /^\[aft(-\w+)?\] /.test(line) ? line : `[aft] ${line}`;
|
|
134
|
+
}
|
|
135
|
+
function compareSemver(a, b) {
|
|
136
|
+
const [aMain, aPre] = a.split("-", 2);
|
|
137
|
+
const [bMain, bPre] = b.split("-", 2);
|
|
138
|
+
const aParts = aMain.split(".").map(Number);
|
|
139
|
+
const bParts = bMain.split(".").map(Number);
|
|
140
|
+
for (let i = 0;i < 3; i++) {
|
|
141
|
+
if (aParts[i] !== bParts[i])
|
|
142
|
+
return (aParts[i] ?? 0) - (bParts[i] ?? 0);
|
|
143
|
+
}
|
|
144
|
+
if (!aPre && !bPre)
|
|
145
|
+
return 0;
|
|
146
|
+
if (!aPre)
|
|
147
|
+
return 1;
|
|
148
|
+
if (!bPre)
|
|
149
|
+
return -1;
|
|
150
|
+
const aIds = aPre.split(".");
|
|
151
|
+
const bIds = bPre.split(".");
|
|
152
|
+
for (let i = 0;i < Math.max(aIds.length, bIds.length); i++) {
|
|
153
|
+
const ai = aIds[i];
|
|
154
|
+
const bi = bIds[i];
|
|
155
|
+
if (ai === undefined)
|
|
156
|
+
return -1;
|
|
157
|
+
if (bi === undefined)
|
|
158
|
+
return 1;
|
|
159
|
+
const aNum = /^\d+$/.test(ai);
|
|
160
|
+
const bNum = /^\d+$/.test(bi);
|
|
161
|
+
if (aNum && bNum) {
|
|
162
|
+
const diff = Number.parseInt(ai, 10) - Number.parseInt(bi, 10);
|
|
163
|
+
if (diff !== 0)
|
|
164
|
+
return diff;
|
|
165
|
+
} else if (aNum) {
|
|
166
|
+
return -1;
|
|
167
|
+
} else if (bNum) {
|
|
168
|
+
return 1;
|
|
169
|
+
} else {
|
|
170
|
+
const cmp = ai.localeCompare(bi);
|
|
171
|
+
if (cmp !== 0)
|
|
172
|
+
return cmp;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return 0;
|
|
176
|
+
}
|
|
177
|
+
function clampSemanticTimeout(configOverrides, bridgeTimeoutMs) {
|
|
178
|
+
const semantic = configOverrides.semantic;
|
|
179
|
+
if (!semantic || typeof semantic !== "object" || Array.isArray(semantic)) {
|
|
180
|
+
return configOverrides;
|
|
181
|
+
}
|
|
182
|
+
const timeoutMs = semantic.timeout_ms;
|
|
183
|
+
if (typeof timeoutMs !== "number" || !Number.isFinite(timeoutMs)) {
|
|
184
|
+
return configOverrides;
|
|
185
|
+
}
|
|
186
|
+
const maxSemanticTimeoutMs = bridgeTimeoutMs > SEMANTIC_TIMEOUT_SAFETY_MARGIN_MS ? bridgeTimeoutMs - SEMANTIC_TIMEOUT_SAFETY_MARGIN_MS : Math.max(1, bridgeTimeoutMs - 1);
|
|
187
|
+
if (timeoutMs <= maxSemanticTimeoutMs) {
|
|
188
|
+
return configOverrides;
|
|
189
|
+
}
|
|
190
|
+
warn(`semantic.timeout_ms=${timeoutMs} exceeds bridge timeout budget; clamping to ${maxSemanticTimeoutMs}ms (bridge timeout: ${bridgeTimeoutMs}ms)`);
|
|
191
|
+
return {
|
|
192
|
+
...configOverrides,
|
|
193
|
+
semantic: {
|
|
194
|
+
...semantic,
|
|
195
|
+
timeout_ms: maxSemanticTimeoutMs
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
var DEFAULT_BRIDGE_TIMEOUT_MS = 30000, BRIDGE_HANG_TIMEOUT_THRESHOLD = 2, SEMANTIC_TIMEOUT_SAFETY_MARGIN_MS = 5000, MAX_STDOUT_BUFFER, BridgeReplacedDuringVersionCheck, BinaryBridge;
|
|
200
|
+
var init_bridge = __esm(() => {
|
|
201
|
+
init_active_logger();
|
|
202
|
+
MAX_STDOUT_BUFFER = 64 * 1024 * 1024;
|
|
203
|
+
BridgeReplacedDuringVersionCheck = class BridgeReplacedDuringVersionCheck extends Error {
|
|
204
|
+
newBinaryPath;
|
|
205
|
+
constructor(newBinaryPath) {
|
|
206
|
+
super(`Bridge binary replaced during version check: ${newBinaryPath}`);
|
|
207
|
+
this.newBinaryPath = newBinaryPath;
|
|
208
|
+
this.name = "BridgeReplacedDuringVersionCheck";
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
BinaryBridge = class BinaryBridge {
|
|
212
|
+
static RESTART_RESET_MS = 5 * 60 * 1000;
|
|
213
|
+
static STDERR_TAIL_MAX = 20;
|
|
214
|
+
binaryPath;
|
|
215
|
+
cwd;
|
|
216
|
+
process = null;
|
|
217
|
+
pending = new Map;
|
|
218
|
+
nextId = 1;
|
|
219
|
+
stdoutBuffer = "";
|
|
220
|
+
stderrBuffer = "";
|
|
221
|
+
stderrTail = [];
|
|
222
|
+
_restartCount = 0;
|
|
223
|
+
_shuttingDown = false;
|
|
224
|
+
timeoutMs;
|
|
225
|
+
maxRestarts;
|
|
226
|
+
configured = false;
|
|
227
|
+
_configurePromise = null;
|
|
228
|
+
configOverrides;
|
|
229
|
+
minVersion;
|
|
230
|
+
onVersionMismatch;
|
|
231
|
+
onConfigureWarnings;
|
|
232
|
+
onBashCompletion;
|
|
233
|
+
onBashLongRunning;
|
|
234
|
+
onBashPatternMatch;
|
|
235
|
+
cachedStatus = null;
|
|
236
|
+
statusListeners = new Set;
|
|
237
|
+
configureWarningClients = new Map;
|
|
238
|
+
restartResetTimer = null;
|
|
239
|
+
lastChildActivityAt = 0;
|
|
240
|
+
lastStatusBar;
|
|
241
|
+
consecutiveRequestTimeouts = 0;
|
|
242
|
+
errorPrefix;
|
|
243
|
+
logger;
|
|
244
|
+
childEnv;
|
|
245
|
+
constructor(binaryPath, cwd, options, configOverrides) {
|
|
246
|
+
this.binaryPath = binaryPath;
|
|
247
|
+
this.cwd = cwd;
|
|
248
|
+
this.timeoutMs = options?.timeoutMs ?? DEFAULT_BRIDGE_TIMEOUT_MS;
|
|
249
|
+
this.maxRestarts = options?.maxRestarts ?? 3;
|
|
250
|
+
this.configOverrides = clampSemanticTimeout(configOverrides ?? {}, this.timeoutMs);
|
|
251
|
+
this.minVersion = options?.minVersion;
|
|
252
|
+
this.onVersionMismatch = options?.onVersionMismatch;
|
|
253
|
+
this.onConfigureWarnings = options?.onConfigureWarnings;
|
|
254
|
+
this.onBashCompletion = options?.onBashCompletion;
|
|
255
|
+
this.onBashLongRunning = options?.onBashLongRunning;
|
|
256
|
+
this.onBashPatternMatch = options?.onBashPatternMatch;
|
|
257
|
+
this.errorPrefix = options?.errorPrefix ?? "[aft-bridge]";
|
|
258
|
+
this.logger = options?.logger;
|
|
259
|
+
this.childEnv = options?.childEnv;
|
|
260
|
+
}
|
|
261
|
+
logVia(message, meta) {
|
|
262
|
+
const logger = this.logger ?? getActiveLogger();
|
|
263
|
+
if (logger) {
|
|
264
|
+
try {
|
|
265
|
+
logger.log(message, meta);
|
|
266
|
+
} catch (err) {
|
|
267
|
+
console.error(`[aft-bridge] ERROR: logger log threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
268
|
+
console.error(`[aft-bridge] ${message}`);
|
|
269
|
+
}
|
|
270
|
+
} else {
|
|
271
|
+
log(message, meta);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
warnVia(message, meta) {
|
|
275
|
+
const logger = this.logger ?? getActiveLogger();
|
|
276
|
+
if (logger) {
|
|
277
|
+
try {
|
|
278
|
+
logger.warn(message, meta);
|
|
279
|
+
} catch (err) {
|
|
280
|
+
console.error(`[aft-bridge] ERROR: logger warn threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
281
|
+
console.error(`[aft-bridge] WARN: ${message}`);
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
warn(message, meta);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
errorVia(message, meta) {
|
|
288
|
+
const logger = this.logger ?? getActiveLogger();
|
|
289
|
+
if (logger) {
|
|
290
|
+
try {
|
|
291
|
+
logger.error(message, meta);
|
|
292
|
+
} catch (err) {
|
|
293
|
+
console.error(`[aft-bridge] ERROR: logger error threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
294
|
+
console.error(`[aft-bridge] ERROR: ${message}`);
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
error(message, meta);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
getLogFilePathVia() {
|
|
301
|
+
if (this.logger?.getLogFilePath) {
|
|
302
|
+
try {
|
|
303
|
+
return this.logger.getLogFilePath();
|
|
304
|
+
} catch (err) {
|
|
305
|
+
console.error(`[aft-bridge] ERROR: logger getLogFilePath threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
return getLogFilePath();
|
|
310
|
+
}
|
|
311
|
+
sessionLogVia(sessionId, message) {
|
|
312
|
+
this.logVia(message, sessionId ? { sessionId } : undefined);
|
|
313
|
+
}
|
|
314
|
+
sessionWarnVia(sessionId, message) {
|
|
315
|
+
this.warnVia(message, sessionId ? { sessionId } : undefined);
|
|
316
|
+
}
|
|
317
|
+
sessionErrorVia(sessionId, message) {
|
|
318
|
+
this.errorVia(message, sessionId ? { sessionId } : undefined);
|
|
319
|
+
}
|
|
320
|
+
get restartCount() {
|
|
321
|
+
return this._restartCount;
|
|
322
|
+
}
|
|
323
|
+
isAlive() {
|
|
324
|
+
return this.process !== null && this.process.exitCode === null && !this.process.killed;
|
|
325
|
+
}
|
|
326
|
+
hasPendingRequests() {
|
|
327
|
+
return this.pending.size > 0;
|
|
328
|
+
}
|
|
329
|
+
getCachedStatus() {
|
|
330
|
+
return this.cachedStatus;
|
|
331
|
+
}
|
|
332
|
+
subscribeStatus(listener) {
|
|
333
|
+
this.statusListeners.add(listener);
|
|
334
|
+
if (this.cachedStatus !== null) {
|
|
335
|
+
this.deliverStatusSnapshot(listener, this.cachedStatus);
|
|
336
|
+
}
|
|
337
|
+
return () => {
|
|
338
|
+
this.statusListeners.delete(listener);
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
cacheStatusSnapshot(snapshot) {
|
|
342
|
+
this.cachedStatus = snapshot;
|
|
343
|
+
}
|
|
344
|
+
async send(command, params = {}, options) {
|
|
345
|
+
return this.sendWithVersionMismatchRetry(command, params, options, true);
|
|
346
|
+
}
|
|
347
|
+
async sendWithVersionMismatchRetry(command, params, options, canRetryAfterVersionSwap) {
|
|
348
|
+
try {
|
|
349
|
+
if (this._shuttingDown) {
|
|
350
|
+
throw new Error(`${this.errorPrefix} Bridge is shutting down, cannot send "${command}"`);
|
|
351
|
+
}
|
|
352
|
+
if (Object.hasOwn(params, "id")) {
|
|
353
|
+
throw new Error("params cannot contain reserved key 'id'");
|
|
354
|
+
}
|
|
355
|
+
const requestSessionId = typeof params.session_id === "string" && params.session_id.length > 0 ? params.session_id : undefined;
|
|
356
|
+
this.ensureSpawned(requestSessionId);
|
|
357
|
+
if (requestSessionId && options?.configureWarningClient !== undefined) {
|
|
358
|
+
this.configureWarningClients.set(requestSessionId, options.configureWarningClient);
|
|
359
|
+
}
|
|
360
|
+
const effectiveTimeoutMs = options?.transportTimeoutMs ?? options?.timeoutMs ?? this.timeoutMs;
|
|
361
|
+
const implicitTransportOptions = {
|
|
362
|
+
...options?.transportTimeoutMs !== undefined || options?.timeoutMs !== undefined ? { transportTimeoutMs: effectiveTimeoutMs } : {},
|
|
363
|
+
markConfiguredOnSuccess: false
|
|
364
|
+
};
|
|
365
|
+
if (!this.configured) {
|
|
366
|
+
if (command !== "configure" && command !== "version") {
|
|
367
|
+
if (!this._configurePromise) {
|
|
368
|
+
const sessionIdForConfigure = typeof params.session_id === "string" ? params.session_id : undefined;
|
|
369
|
+
this._configurePromise = (async () => {
|
|
370
|
+
try {
|
|
371
|
+
const configResult = await this.send("configure", {
|
|
372
|
+
project_root: this.cwd,
|
|
373
|
+
...this.configOverrides,
|
|
374
|
+
...sessionIdForConfigure ? { session_id: sessionIdForConfigure } : {}
|
|
375
|
+
}, implicitTransportOptions);
|
|
376
|
+
if (configResult.success === false) {
|
|
377
|
+
throw new Error(`${this.errorPrefix} Configure failed: ${configResult.message ?? "unknown error"}`);
|
|
378
|
+
}
|
|
379
|
+
await this.deliverConfigureWarnings(configResult, params, options);
|
|
380
|
+
await this.checkVersion(implicitTransportOptions);
|
|
381
|
+
if (!this.isAlive()) {
|
|
382
|
+
throw new Error(`${this.errorPrefix} Bridge died during version check. Check logs: ${this.getLogFilePathVia()}`);
|
|
383
|
+
}
|
|
384
|
+
this.configured = true;
|
|
385
|
+
} finally {
|
|
386
|
+
this._configurePromise = null;
|
|
387
|
+
}
|
|
388
|
+
})();
|
|
389
|
+
}
|
|
390
|
+
await this._configurePromise;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
const id = String(this.nextId++);
|
|
394
|
+
let request;
|
|
395
|
+
if (Object.hasOwn(params, "command") || Object.hasOwn(params, "method")) {
|
|
396
|
+
const nested = { ...params };
|
|
397
|
+
const reserved = {};
|
|
398
|
+
for (const key of ["session_id", "lsp_hints"]) {
|
|
399
|
+
if (Object.hasOwn(nested, key)) {
|
|
400
|
+
reserved[key] = nested[key];
|
|
401
|
+
delete nested[key];
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
request = { id, command, ...reserved, params: nested };
|
|
405
|
+
} else {
|
|
406
|
+
request = { id, command, ...params };
|
|
407
|
+
}
|
|
408
|
+
const line = `${JSON.stringify(request)}
|
|
409
|
+
`;
|
|
410
|
+
const keepBridgeOnTimeout = options?.keepBridgeOnTimeout === true;
|
|
411
|
+
let requestSentAt = Date.now();
|
|
412
|
+
const response = await new Promise((resolve, reject) => {
|
|
413
|
+
const timer = setTimeout(() => {
|
|
414
|
+
const entry = this.pending.get(id);
|
|
415
|
+
if (!entry)
|
|
416
|
+
return;
|
|
417
|
+
this.pending.delete(id);
|
|
418
|
+
clearTimeout(entry.timer);
|
|
419
|
+
if (keepBridgeOnTimeout) {
|
|
420
|
+
const timeoutMsg2 = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`;
|
|
421
|
+
if (requestSessionId) {
|
|
422
|
+
this.sessionWarnVia(requestSessionId, timeoutMsg2);
|
|
423
|
+
} else {
|
|
424
|
+
this.warnVia(timeoutMsg2);
|
|
425
|
+
}
|
|
426
|
+
entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
const childActiveSinceRequest = this.lastChildActivityAt > requestSentAt;
|
|
430
|
+
const consecutiveTimeouts = this.consecutiveRequestTimeouts + 1;
|
|
431
|
+
this.consecutiveRequestTimeouts = consecutiveTimeouts;
|
|
432
|
+
const keepWarm = childActiveSinceRequest || consecutiveTimeouts < BRIDGE_HANG_TIMEOUT_THRESHOLD;
|
|
433
|
+
const restartSuffix = keepWarm ? " — bridge kept warm" : " — restarting bridge";
|
|
434
|
+
const timeoutMsg = `Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms${restartSuffix}`;
|
|
435
|
+
if (requestSessionId) {
|
|
436
|
+
this.sessionWarnVia(requestSessionId, timeoutMsg);
|
|
437
|
+
} else {
|
|
438
|
+
this.warnVia(timeoutMsg);
|
|
439
|
+
}
|
|
440
|
+
if (keepWarm) {
|
|
441
|
+
entry.reject(new Error(`${this.errorPrefix} request "${command}" timed out after ${effectiveTimeoutMs}ms (bridge busy/under load); bridge kept warm — retry`));
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
entry.reject(new Error(`${this.errorPrefix} Request "${command}" (id=${id}) timed out after ${effectiveTimeoutMs}ms`));
|
|
445
|
+
this.handleTimeout(requestSessionId);
|
|
446
|
+
}, effectiveTimeoutMs);
|
|
447
|
+
this.pending.set(id, { resolve, reject, timer, onProgress: options?.onProgress });
|
|
448
|
+
if (!this.process?.stdin?.writable) {
|
|
449
|
+
this.pending.delete(id);
|
|
450
|
+
clearTimeout(timer);
|
|
451
|
+
reject(new Error(`${this.errorPrefix} stdin not writable for command "${command}"`));
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
requestSentAt = Date.now();
|
|
455
|
+
this.process.stdin.write(line, (err) => {
|
|
456
|
+
if (err) {
|
|
457
|
+
const entry = this.pending.get(id);
|
|
458
|
+
if (entry) {
|
|
459
|
+
this.pending.delete(id);
|
|
460
|
+
clearTimeout(entry.timer);
|
|
461
|
+
entry.reject(new Error(`${this.errorPrefix} Failed to write to stdin: ${err.message}`));
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
});
|
|
466
|
+
if (command === "configure" && response.success === true && options?.markConfiguredOnSuccess !== false) {
|
|
467
|
+
this.configured = true;
|
|
468
|
+
}
|
|
469
|
+
return response;
|
|
470
|
+
} catch (err) {
|
|
471
|
+
if (err instanceof BridgeReplacedDuringVersionCheck && canRetryAfterVersionSwap && command !== "configure" && command !== "version") {
|
|
472
|
+
this.logVia(`Retrying request "${command}" once after coordinated binary replacement: ${err.newBinaryPath}`);
|
|
473
|
+
return this.sendWithVersionMismatchRetry(command, params, options, false);
|
|
474
|
+
}
|
|
475
|
+
throw err;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
async deliverConfigureWarnings(configResult, params, options) {
|
|
479
|
+
if (!this.onConfigureWarnings || !Array.isArray(configResult.warnings))
|
|
480
|
+
return;
|
|
481
|
+
if (configResult.warnings.length === 0)
|
|
482
|
+
return;
|
|
483
|
+
const sessionId = typeof params.session_id === "string" ? params.session_id : undefined;
|
|
484
|
+
try {
|
|
485
|
+
await this.onConfigureWarnings({
|
|
486
|
+
projectRoot: this.cwd,
|
|
487
|
+
sessionId,
|
|
488
|
+
client: options?.configureWarningClient ?? (sessionId ? this.configureWarningClients.get(sessionId) : undefined),
|
|
489
|
+
warnings: configResult.warnings
|
|
490
|
+
});
|
|
491
|
+
} catch (err) {
|
|
492
|
+
this.warnVia(`configure warning delivery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
493
|
+
} finally {
|
|
494
|
+
if (sessionId) {
|
|
495
|
+
this.configureWarningClients.delete(sessionId);
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
async handleConfigureWarningsFrame(frame) {
|
|
500
|
+
if (!this.onConfigureWarnings)
|
|
501
|
+
return;
|
|
502
|
+
const warnings = frame.warnings;
|
|
503
|
+
if (!Array.isArray(warnings) || warnings.length === 0)
|
|
504
|
+
return;
|
|
505
|
+
const projectRoot = typeof frame.project_root === "string" ? frame.project_root : this.cwd;
|
|
506
|
+
const rawSessionId = frame.session_id;
|
|
507
|
+
const sessionId = typeof rawSessionId === "string" && rawSessionId.length > 0 ? rawSessionId : null;
|
|
508
|
+
try {
|
|
509
|
+
await this.onConfigureWarnings({
|
|
510
|
+
projectRoot,
|
|
511
|
+
sessionId,
|
|
512
|
+
client: sessionId ? this.configureWarningClients.get(sessionId) : undefined,
|
|
513
|
+
warnings
|
|
514
|
+
});
|
|
515
|
+
} finally {
|
|
516
|
+
if (sessionId) {
|
|
517
|
+
this.configureWarningClients.delete(sessionId);
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
handleStatusChangedFrame(frame) {
|
|
522
|
+
const snapshot = frame.snapshot;
|
|
523
|
+
if (!snapshot || typeof snapshot !== "object" || Array.isArray(snapshot))
|
|
524
|
+
return;
|
|
525
|
+
this.cachedStatus = snapshot;
|
|
526
|
+
this.logVia("Received status_changed push frame; cached AFT status snapshot");
|
|
527
|
+
for (const listener of this.statusListeners) {
|
|
528
|
+
this.deliverStatusSnapshot(listener, this.cachedStatus);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
deliverStatusSnapshot(listener, snapshot) {
|
|
532
|
+
try {
|
|
533
|
+
listener(snapshot);
|
|
534
|
+
} catch (err) {
|
|
535
|
+
this.warnVia(`status listener threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
async shutdown() {
|
|
539
|
+
this._shuttingDown = true;
|
|
540
|
+
this.clearRestartResetTimer();
|
|
541
|
+
this.configureWarningClients.clear();
|
|
542
|
+
this.rejectAllPending(new Error(`${this.errorPrefix} Bridge shutting down`));
|
|
543
|
+
if (this.process) {
|
|
544
|
+
const proc = this.process;
|
|
545
|
+
this.process = null;
|
|
546
|
+
return new Promise((resolve) => {
|
|
547
|
+
const forceKillTimer = setTimeout(() => {
|
|
548
|
+
proc.kill("SIGKILL");
|
|
549
|
+
resolve();
|
|
550
|
+
}, 5000);
|
|
551
|
+
proc.once("exit", () => {
|
|
552
|
+
clearTimeout(forceKillTimer);
|
|
553
|
+
this.logVia("Process exited during shutdown");
|
|
554
|
+
resolve();
|
|
555
|
+
});
|
|
556
|
+
proc.kill("SIGTERM");
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async checkVersion(options) {
|
|
561
|
+
if (!this.minVersion)
|
|
562
|
+
return;
|
|
563
|
+
try {
|
|
564
|
+
const resp = await this.send("version", {}, options);
|
|
565
|
+
if (resp.success === false) {
|
|
566
|
+
throw new Error(`Binary version check failed: ${String(resp.code ?? "unknown")} — likely too old`);
|
|
567
|
+
}
|
|
568
|
+
const binaryVersion = resp.version;
|
|
569
|
+
if (typeof binaryVersion !== "string") {
|
|
570
|
+
throw new Error(`Binary did not report a version — likely too old (minVersion: ${this.minVersion})`);
|
|
571
|
+
}
|
|
572
|
+
this.logVia(`Binary version: ${binaryVersion}`);
|
|
573
|
+
if (compareSemver(binaryVersion, this.minVersion) < 0) {
|
|
574
|
+
this.warnVia(`Binary version ${binaryVersion} is older than required ${this.minVersion}`);
|
|
575
|
+
const replacementPath = await this.onVersionMismatch?.(binaryVersion, this.minVersion);
|
|
576
|
+
if (replacementPath === undefined) {
|
|
577
|
+
return;
|
|
578
|
+
}
|
|
579
|
+
if (replacementPath === null || replacementPath.length === 0) {
|
|
580
|
+
throw new Error(`Binary version ${binaryVersion} is older than required ${this.minVersion}; no compatible replacement binary was provided`);
|
|
581
|
+
}
|
|
582
|
+
await this.replaceCurrentBinary(replacementPath);
|
|
583
|
+
throw new BridgeReplacedDuringVersionCheck(replacementPath);
|
|
584
|
+
}
|
|
585
|
+
} catch (err) {
|
|
586
|
+
this.warnVia(`Version check failed: ${err.message}`);
|
|
587
|
+
throw err;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
async replaceCurrentBinary(newBinaryPath) {
|
|
591
|
+
this.binaryPath = newBinaryPath;
|
|
592
|
+
this.configured = false;
|
|
593
|
+
this.clearRestartResetTimer();
|
|
594
|
+
this.rejectAllPending(new Error(`${this.errorPrefix} Bridge restarting with updated binary: ${newBinaryPath}`));
|
|
595
|
+
if (!this.process)
|
|
596
|
+
return;
|
|
597
|
+
const proc = this.process;
|
|
598
|
+
this.process = null;
|
|
599
|
+
await new Promise((resolve) => {
|
|
600
|
+
const forceKillTimer = setTimeout(() => {
|
|
601
|
+
proc.kill("SIGKILL");
|
|
602
|
+
resolve();
|
|
603
|
+
}, 5000);
|
|
604
|
+
proc.once("exit", () => {
|
|
605
|
+
clearTimeout(forceKillTimer);
|
|
606
|
+
this.logVia("Process exited during coordinated binary replacement");
|
|
607
|
+
resolve();
|
|
608
|
+
});
|
|
609
|
+
proc.kill("SIGTERM");
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
ensureSpawned(triggeringSessionId) {
|
|
613
|
+
if (this.isAlive())
|
|
614
|
+
return;
|
|
615
|
+
this.spawnProcess(triggeringSessionId);
|
|
616
|
+
}
|
|
617
|
+
spawnProcess(triggeringSessionId) {
|
|
618
|
+
this.lastStatusBar = undefined;
|
|
619
|
+
if (triggeringSessionId) {
|
|
620
|
+
this.sessionLogVia(triggeringSessionId, `Spawning binary: ${this.binaryPath} (cwd: ${this.cwd})`);
|
|
621
|
+
} else {
|
|
622
|
+
this.logVia(`Spawning binary: ${this.binaryPath} (cwd: ${this.cwd})`);
|
|
623
|
+
}
|
|
624
|
+
const semantic = this.configOverrides.semantic;
|
|
625
|
+
const semanticBackend = (() => {
|
|
626
|
+
if (semantic && typeof semantic === "object" && !Array.isArray(semantic)) {
|
|
627
|
+
const candidate = semantic.backend;
|
|
628
|
+
return typeof candidate === "string" ? candidate : undefined;
|
|
629
|
+
}
|
|
630
|
+
return;
|
|
631
|
+
})();
|
|
632
|
+
const useFastembedBackend = semanticBackend === undefined || semanticBackend === "fastembed" || semanticBackend === "";
|
|
633
|
+
const ortDir = typeof this.configOverrides._ort_dylib_dir === "string" && useFastembedBackend ? this.configOverrides._ort_dylib_dir : null;
|
|
634
|
+
const ortLibraryPath = ortDir == null ? null : join(ortDir, process.platform === "win32" ? "onnxruntime.dll" : process.platform === "darwin" ? "libonnxruntime.dylib" : "libonnxruntime.so");
|
|
635
|
+
const envPath = process.platform === "win32" && ortDir ? `${ortDir};${process.env.PATH ?? ""}` : process.env.PATH;
|
|
636
|
+
const env = {
|
|
637
|
+
...process.env,
|
|
638
|
+
...envPath ? { PATH: envPath } : {}
|
|
639
|
+
};
|
|
640
|
+
this.logVia(`bridge.spawnProcess: useFastembedBackend=${useFastembedBackend}, ` + `parentORT=${process.env.ORT_DYLIB_PATH ?? "(unset)"}, ` + `ortLibraryPath=${ortLibraryPath ?? "(none)"}`);
|
|
641
|
+
if (useFastembedBackend) {
|
|
642
|
+
env.FASTEMBED_CACHE_DIR = process.env.FASTEMBED_CACHE_DIR || (typeof this.configOverrides.storage_dir === "string" ? join(this.configOverrides.storage_dir, "semantic", "models") : join(homedir() || "", ".cache", "fastembed"));
|
|
643
|
+
if (process.env.ORT_DYLIB_PATH) {
|
|
644
|
+
this.logVia(`ORT_DYLIB_PATH inherited from parent env: ${process.env.ORT_DYLIB_PATH}`);
|
|
645
|
+
} else if (ortLibraryPath) {
|
|
646
|
+
env.ORT_DYLIB_PATH = ortLibraryPath;
|
|
647
|
+
this.logVia(`ORT_DYLIB_PATH set from managed ONNX Runtime: ${ortLibraryPath}`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
if (this.childEnv) {
|
|
651
|
+
for (const [key, value] of Object.entries(this.childEnv)) {
|
|
652
|
+
if (value === undefined) {
|
|
653
|
+
delete env[key];
|
|
654
|
+
} else {
|
|
655
|
+
env[key] = value;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
const child = spawn(this.binaryPath, [], {
|
|
660
|
+
cwd: this.cwd,
|
|
661
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
662
|
+
env
|
|
663
|
+
});
|
|
664
|
+
const currentChild = child;
|
|
665
|
+
const stdoutDecoder = new StringDecoder("utf8");
|
|
666
|
+
child.stdout?.on("data", (chunk) => {
|
|
667
|
+
this.onStdoutData(stdoutDecoder.write(chunk));
|
|
668
|
+
});
|
|
669
|
+
child.stdout?.on("end", () => {
|
|
670
|
+
const remaining = stdoutDecoder.end();
|
|
671
|
+
if (remaining)
|
|
672
|
+
this.onStdoutData(remaining);
|
|
673
|
+
});
|
|
674
|
+
const stderrDecoder = new StringDecoder("utf8");
|
|
675
|
+
child.stderr?.on("data", (chunk) => {
|
|
676
|
+
this.onStderrData(stderrDecoder.write(chunk));
|
|
677
|
+
});
|
|
678
|
+
child.stderr?.on("end", () => {
|
|
679
|
+
const remaining = stderrDecoder.end();
|
|
680
|
+
if (remaining)
|
|
681
|
+
this.onStderrData(remaining);
|
|
682
|
+
this.flushStderrBuffer();
|
|
683
|
+
});
|
|
684
|
+
child.on("error", (err) => {
|
|
685
|
+
if (this.process !== currentChild)
|
|
686
|
+
return;
|
|
687
|
+
this.errorVia(`Process error: ${err.message}${this.formatStderrTail()}`);
|
|
688
|
+
this.handleCrash();
|
|
689
|
+
});
|
|
690
|
+
child.on("exit", (code, signal) => {
|
|
691
|
+
if (this.process !== currentChild)
|
|
692
|
+
return;
|
|
693
|
+
if (this._shuttingDown)
|
|
694
|
+
return;
|
|
695
|
+
this.logVia(`Process exited: code=${code}, signal=${signal}`);
|
|
696
|
+
if (signal === "SIGTERM" || signal === "SIGKILL" || signal === "SIGHUP" || signal === "SIGINT") {
|
|
697
|
+
this.process = null;
|
|
698
|
+
this.configured = false;
|
|
699
|
+
this.clearRestartResetTimer();
|
|
700
|
+
this.rejectAllPending(new Error(`${this.errorPrefix} Binary killed by ${signal}`));
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
this.handleCrash();
|
|
704
|
+
});
|
|
705
|
+
this.process = child;
|
|
706
|
+
this.stdoutBuffer = "";
|
|
707
|
+
this.stderrBuffer = "";
|
|
708
|
+
this.lastChildActivityAt = 0;
|
|
709
|
+
this.consecutiveRequestTimeouts = 0;
|
|
710
|
+
this.stderrTail = [];
|
|
711
|
+
}
|
|
712
|
+
pushStderrLine(line) {
|
|
713
|
+
this.stderrTail.push(line);
|
|
714
|
+
if (this.stderrTail.length > BinaryBridge.STDERR_TAIL_MAX) {
|
|
715
|
+
this.stderrTail.shift();
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
onStderrData(data) {
|
|
719
|
+
this.stderrBuffer += data;
|
|
720
|
+
let newlineIdx;
|
|
721
|
+
while ((newlineIdx = this.stderrBuffer.indexOf(`
|
|
722
|
+
`)) !== -1) {
|
|
723
|
+
const line = this.stderrBuffer.slice(0, newlineIdx).replace(/\r$/, "");
|
|
724
|
+
this.stderrBuffer = this.stderrBuffer.slice(newlineIdx + 1);
|
|
725
|
+
if (!line)
|
|
726
|
+
continue;
|
|
727
|
+
const tagged = tagStderrLine(line);
|
|
728
|
+
this.logVia(tagged);
|
|
729
|
+
this.pushStderrLine(tagged);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
flushStderrBuffer() {
|
|
733
|
+
const line = this.stderrBuffer.replace(/\r$/, "");
|
|
734
|
+
this.stderrBuffer = "";
|
|
735
|
+
if (!line)
|
|
736
|
+
return;
|
|
737
|
+
const tagged = tagStderrLine(line);
|
|
738
|
+
this.logVia(tagged);
|
|
739
|
+
this.pushStderrLine(tagged);
|
|
740
|
+
}
|
|
741
|
+
formatStderrTail() {
|
|
742
|
+
if (this.stderrTail.length === 0)
|
|
743
|
+
return "";
|
|
744
|
+
const tail = this.stderrTail.join(`
|
|
745
|
+
`);
|
|
746
|
+
return `
|
|
747
|
+
--- last ${this.stderrTail.length} stderr lines ---
|
|
748
|
+
${tail}`;
|
|
749
|
+
}
|
|
750
|
+
onStdoutData(data) {
|
|
751
|
+
this.stdoutBuffer += data;
|
|
752
|
+
if (this.stdoutBuffer.length > MAX_STDOUT_BUFFER) {
|
|
753
|
+
this.handleCrash(new Error(`aft bridge stdout buffer exceeded ${MAX_STDOUT_BUFFER} bytes — killing bridge`));
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
let newlineIdx;
|
|
757
|
+
while ((newlineIdx = this.stdoutBuffer.indexOf(`
|
|
758
|
+
`)) !== -1) {
|
|
759
|
+
const line = this.stdoutBuffer.slice(0, newlineIdx).trim();
|
|
760
|
+
this.stdoutBuffer = this.stdoutBuffer.slice(newlineIdx + 1);
|
|
761
|
+
if (!line)
|
|
762
|
+
continue;
|
|
763
|
+
try {
|
|
764
|
+
const response = JSON.parse(line);
|
|
765
|
+
this.lastChildActivityAt = Date.now();
|
|
766
|
+
if (response.type === "progress") {
|
|
767
|
+
const requestId = response.request_id;
|
|
768
|
+
const entry = requestId ? this.pending.get(requestId) : undefined;
|
|
769
|
+
const kind = response.kind === "stderr" ? "stderr" : "stdout";
|
|
770
|
+
const text = typeof response.chunk === "string" ? response.chunk : "";
|
|
771
|
+
entry?.onProgress?.({ kind, text });
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
if (response.type === "permission_ask") {
|
|
775
|
+
const requestId = response.request_id;
|
|
776
|
+
const entry = requestId ? this.pending.get(requestId) : undefined;
|
|
777
|
+
if (requestId && entry) {
|
|
778
|
+
this.pending.delete(requestId);
|
|
779
|
+
clearTimeout(entry.timer);
|
|
780
|
+
entry.resolve({
|
|
781
|
+
success: false,
|
|
782
|
+
code: "permission_required",
|
|
783
|
+
message: "bash command requires permission",
|
|
784
|
+
asks: response.asks
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
789
|
+
if (response.type === "bash_completed") {
|
|
790
|
+
this.onBashCompletion?.(response, this);
|
|
791
|
+
continue;
|
|
792
|
+
}
|
|
793
|
+
if (response.type === "bash_long_running") {
|
|
794
|
+
this.onBashLongRunning?.(response, this);
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
if (response.type === "bash_pattern_match") {
|
|
798
|
+
this.onBashPatternMatch?.(response, this);
|
|
799
|
+
continue;
|
|
800
|
+
}
|
|
801
|
+
if (response.type === "configure_warnings") {
|
|
802
|
+
this.handleConfigureWarningsFrame(response).catch((err) => {
|
|
803
|
+
this.warnVia(`configure warning delivery failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
804
|
+
});
|
|
805
|
+
continue;
|
|
806
|
+
}
|
|
807
|
+
if (response.type === "status_changed") {
|
|
808
|
+
this.handleStatusChangedFrame(response);
|
|
809
|
+
continue;
|
|
810
|
+
}
|
|
811
|
+
const id = response.id;
|
|
812
|
+
if (id && this.pending.has(id)) {
|
|
813
|
+
const entry = this.pending.get(id);
|
|
814
|
+
if (!entry)
|
|
815
|
+
continue;
|
|
816
|
+
this.pending.delete(id);
|
|
817
|
+
clearTimeout(entry.timer);
|
|
818
|
+
this.consecutiveRequestTimeouts = 0;
|
|
819
|
+
this.scheduleRestartCountReset();
|
|
820
|
+
this.captureStatusBar(response);
|
|
821
|
+
entry.resolve(response);
|
|
822
|
+
} else if (typeof response.type === "string") {
|
|
823
|
+
this.logVia(`Ignoring unknown stdout push frame type: ${response.type}`);
|
|
824
|
+
}
|
|
825
|
+
} catch (_err) {
|
|
826
|
+
this.warnVia(`Failed to parse stdout line: ${line}`);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
captureStatusBar(response) {
|
|
831
|
+
const parsed = parseStatusBarCounts(response.status_bar);
|
|
832
|
+
if (parsed)
|
|
833
|
+
this.lastStatusBar = parsed;
|
|
834
|
+
}
|
|
835
|
+
getStatusBar() {
|
|
836
|
+
return this.lastStatusBar;
|
|
837
|
+
}
|
|
838
|
+
handleTimeout(triggeringSessionId) {
|
|
839
|
+
this.consecutiveRequestTimeouts = 0;
|
|
840
|
+
this.rejectAllPending(new Error(`${this.errorPrefix} bridge killed during sibling timeout — request aborted`));
|
|
841
|
+
if (this.process) {
|
|
842
|
+
this.process.kill("SIGKILL");
|
|
843
|
+
this.process = null;
|
|
844
|
+
}
|
|
845
|
+
this.clearRestartResetTimer();
|
|
846
|
+
this.configured = false;
|
|
847
|
+
const tail = this.formatStderrTail();
|
|
848
|
+
this.stderrTail = [];
|
|
849
|
+
const killedMsg = tail ? `Bridge killed after timeout.${tail}` : `Bridge killed after timeout (see ${this.getLogFilePathVia()})`;
|
|
850
|
+
if (tail) {
|
|
851
|
+
if (triggeringSessionId) {
|
|
852
|
+
this.sessionErrorVia(triggeringSessionId, killedMsg);
|
|
853
|
+
} else {
|
|
854
|
+
this.errorVia(killedMsg);
|
|
855
|
+
}
|
|
856
|
+
} else if (triggeringSessionId) {
|
|
857
|
+
this.sessionWarnVia(triggeringSessionId, killedMsg);
|
|
858
|
+
} else {
|
|
859
|
+
this.warnVia(killedMsg);
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
handleCrash(cause) {
|
|
863
|
+
const proc = this.process;
|
|
864
|
+
this.process = null;
|
|
865
|
+
if (proc && proc.exitCode === null && !proc.killed) {
|
|
866
|
+
proc.kill("SIGKILL");
|
|
867
|
+
}
|
|
868
|
+
this.clearRestartResetTimer();
|
|
869
|
+
this.configured = false;
|
|
870
|
+
const tail = this.formatStderrTail();
|
|
871
|
+
if (tail) {
|
|
872
|
+
this.errorVia(`Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""}.${tail}`);
|
|
873
|
+
}
|
|
874
|
+
this.rejectAllPending(new Error(`${this.errorPrefix} Binary crashed (restarts: ${this._restartCount})${cause ? `: ${cause.message}` : ""} (see ${this.getLogFilePathVia()})`));
|
|
875
|
+
if (this._restartCount < this.maxRestarts) {
|
|
876
|
+
const delay = 100 * 2 ** this._restartCount;
|
|
877
|
+
this._restartCount++;
|
|
878
|
+
this.logVia(`Auto-restart #${this._restartCount} in ${delay}ms`);
|
|
879
|
+
setTimeout(() => {
|
|
880
|
+
if (!this._shuttingDown && !this.isAlive()) {
|
|
881
|
+
try {
|
|
882
|
+
this.spawnProcess();
|
|
883
|
+
} catch (err) {
|
|
884
|
+
this.errorVia(`Failed to restart: ${err.message}`);
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
}, delay);
|
|
888
|
+
this.scheduleRestartCountReset();
|
|
889
|
+
} else {
|
|
890
|
+
this.errorVia(`Max restarts (${this.maxRestarts}) reached, giving up. Logs: ${this.getLogFilePathVia()}${tail}`);
|
|
891
|
+
this.scheduleRestartCountReset();
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
rejectAllPending(error2) {
|
|
895
|
+
for (const [_id, entry] of this.pending) {
|
|
896
|
+
clearTimeout(entry.timer);
|
|
897
|
+
entry.reject(error2);
|
|
898
|
+
}
|
|
899
|
+
this.pending.clear();
|
|
900
|
+
}
|
|
901
|
+
scheduleRestartCountReset() {
|
|
902
|
+
this.clearRestartResetTimer();
|
|
903
|
+
this.restartResetTimer = setTimeout(() => {
|
|
904
|
+
this._restartCount = 0;
|
|
905
|
+
this.restartResetTimer = null;
|
|
906
|
+
}, BinaryBridge.RESTART_RESET_MS);
|
|
907
|
+
}
|
|
908
|
+
clearRestartResetTimer() {
|
|
909
|
+
if (this.restartResetTimer) {
|
|
910
|
+
clearTimeout(this.restartResetTimer);
|
|
911
|
+
this.restartResetTimer = null;
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
};
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
// ../aft-bridge/dist/platform.js
|
|
918
|
+
var init_platform = () => {};
|
|
919
|
+
|
|
920
|
+
// ../aft-bridge/dist/downloader.js
|
|
921
|
+
var MAX_DOWNLOAD_BYTES, DOWNLOAD_LOCK_STALE_MS;
|
|
922
|
+
var init_downloader = __esm(() => {
|
|
923
|
+
init_active_logger();
|
|
924
|
+
init_platform();
|
|
925
|
+
MAX_DOWNLOAD_BYTES = 200 * 1024 * 1024;
|
|
926
|
+
DOWNLOAD_LOCK_STALE_MS = 10 * 60000;
|
|
927
|
+
});
|
|
928
|
+
// ../aft-bridge/dist/paths.js
|
|
929
|
+
var init_paths = () => {};
|
|
930
|
+
|
|
931
|
+
// ../aft-bridge/dist/resolver.js
|
|
932
|
+
import { chmodSync, closeSync, copyFileSync, existsSync, mkdirSync, openSync, readSync, renameSync, unlinkSync } from "node:fs";
|
|
933
|
+
function isNativeExecutable(binaryPath) {
|
|
934
|
+
let fd = null;
|
|
935
|
+
try {
|
|
936
|
+
fd = openSync(binaryPath, "r");
|
|
937
|
+
const buf = Buffer.alloc(4);
|
|
938
|
+
const read = readSync(fd, buf, 0, 4, 0);
|
|
939
|
+
if (read < 2)
|
|
940
|
+
return false;
|
|
941
|
+
const b0 = buf[0];
|
|
942
|
+
const b1 = buf[1];
|
|
943
|
+
if (b0 === 35 && b1 === 33)
|
|
944
|
+
return false;
|
|
945
|
+
const m32 = buf.readUInt32BE(0);
|
|
946
|
+
const machO = new Set([4277009102, 4277009103, 3472551422, 3489328638, 3405691582]);
|
|
947
|
+
if (read >= 4 && machO.has(m32))
|
|
948
|
+
return true;
|
|
949
|
+
if (read >= 4 && m32 === 2135247942)
|
|
950
|
+
return true;
|
|
951
|
+
if (b0 === 77 && b1 === 90)
|
|
952
|
+
return true;
|
|
953
|
+
return false;
|
|
954
|
+
} catch {
|
|
955
|
+
return false;
|
|
956
|
+
} finally {
|
|
957
|
+
if (fd !== null) {
|
|
958
|
+
try {
|
|
959
|
+
closeSync(fd);
|
|
960
|
+
} catch {}
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
var init_resolver = __esm(() => {
|
|
965
|
+
init_active_logger();
|
|
966
|
+
init_downloader();
|
|
967
|
+
init_platform();
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
// ../aft-bridge/dist/migration.js
|
|
971
|
+
var DEFAULT_TIMEOUT_MS;
|
|
972
|
+
var init_migration = __esm(() => {
|
|
973
|
+
init_paths();
|
|
974
|
+
init_resolver();
|
|
975
|
+
DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
// ../aft-bridge/dist/onnx-runtime.js
|
|
979
|
+
var ORT_VERSION = "1.24.4", MAX_DOWNLOAD_BYTES2, MAX_EXTRACT_BYTES, STALE_LOCK_MS, ORT_PLATFORM_MAP;
|
|
980
|
+
var init_onnx_runtime = __esm(() => {
|
|
981
|
+
init_active_logger();
|
|
982
|
+
init_platform();
|
|
983
|
+
MAX_DOWNLOAD_BYTES2 = 256 * 1024 * 1024;
|
|
984
|
+
MAX_EXTRACT_BYTES = 1 * 1024 * 1024 * 1024;
|
|
985
|
+
STALE_LOCK_MS = 5 * 60 * 1000;
|
|
986
|
+
ORT_PLATFORM_MAP = {
|
|
987
|
+
darwin: {
|
|
988
|
+
arm64: {
|
|
989
|
+
assetName: `onnxruntime-osx-arm64-${ORT_VERSION}`,
|
|
990
|
+
libName: "libonnxruntime.dylib",
|
|
991
|
+
archiveType: "tgz"
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
linux: {
|
|
995
|
+
x64: {
|
|
996
|
+
assetName: `onnxruntime-linux-x64-${ORT_VERSION}`,
|
|
997
|
+
libName: "libonnxruntime.so",
|
|
998
|
+
archiveType: "tgz"
|
|
999
|
+
},
|
|
1000
|
+
arm64: {
|
|
1001
|
+
assetName: `onnxruntime-linux-aarch64-${ORT_VERSION}`,
|
|
1002
|
+
libName: "libonnxruntime.so",
|
|
1003
|
+
archiveType: "tgz"
|
|
1004
|
+
}
|
|
1005
|
+
},
|
|
1006
|
+
win32: {
|
|
1007
|
+
x64: {
|
|
1008
|
+
assetName: `onnxruntime-win-x64-${ORT_VERSION}`,
|
|
1009
|
+
libName: "onnxruntime.dll",
|
|
1010
|
+
archiveType: "zip"
|
|
1011
|
+
},
|
|
1012
|
+
arm64: {
|
|
1013
|
+
assetName: `onnxruntime-win-arm64-${ORT_VERSION}`,
|
|
1014
|
+
libName: "onnxruntime.dll",
|
|
1015
|
+
archiveType: "zip"
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
};
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
// ../aft-bridge/dist/pool.js
|
|
1022
|
+
import { realpathSync } from "node:fs";
|
|
1023
|
+
|
|
1024
|
+
class BridgePool {
|
|
1025
|
+
bridges = new Map;
|
|
1026
|
+
staleBridges = new Set;
|
|
1027
|
+
binaryPath;
|
|
1028
|
+
maxPoolSize;
|
|
1029
|
+
idleTimeoutMs;
|
|
1030
|
+
bridgeOptions;
|
|
1031
|
+
configOverrides;
|
|
1032
|
+
projectConfigLoader;
|
|
1033
|
+
logger;
|
|
1034
|
+
cleanupTimer = null;
|
|
1035
|
+
constructor(binaryPath, options = {}, configOverrides = {}) {
|
|
1036
|
+
this.binaryPath = binaryPath;
|
|
1037
|
+
this.maxPoolSize = options.maxPoolSize ?? DEFAULT_MAX_POOL_SIZE;
|
|
1038
|
+
this.idleTimeoutMs = options.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS;
|
|
1039
|
+
this.logger = options.logger;
|
|
1040
|
+
this.projectConfigLoader = options.projectConfigLoader;
|
|
1041
|
+
this.bridgeOptions = {
|
|
1042
|
+
timeoutMs: options.timeoutMs,
|
|
1043
|
+
maxRestarts: options.maxRestarts,
|
|
1044
|
+
minVersion: options.minVersion,
|
|
1045
|
+
onVersionMismatch: options.onVersionMismatch,
|
|
1046
|
+
onConfigureWarnings: options.onConfigureWarnings,
|
|
1047
|
+
onBashCompletion: options.onBashCompletion,
|
|
1048
|
+
onBashLongRunning: options.onBashLongRunning,
|
|
1049
|
+
onBashPatternMatch: options.onBashPatternMatch,
|
|
1050
|
+
errorPrefix: options.errorPrefix,
|
|
1051
|
+
logger: options.logger,
|
|
1052
|
+
childEnv: options.childEnv
|
|
1053
|
+
};
|
|
1054
|
+
this.configOverrides = configOverrides;
|
|
1055
|
+
if (Number.isFinite(this.idleTimeoutMs)) {
|
|
1056
|
+
this.cleanupTimer = setInterval(() => this.cleanup(), CLEANUP_INTERVAL_MS);
|
|
1057
|
+
this.cleanupTimer.unref();
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
getActiveBridgeForRoot(projectRoot) {
|
|
1061
|
+
const key = normalizeKey(projectRoot);
|
|
1062
|
+
const entry = this.bridges.get(key);
|
|
1063
|
+
if (!entry?.bridge.isAlive())
|
|
1064
|
+
return null;
|
|
1065
|
+
entry.lastUsed = Date.now();
|
|
1066
|
+
return entry.bridge;
|
|
1067
|
+
}
|
|
1068
|
+
getBridge(projectRoot) {
|
|
1069
|
+
const key = normalizeKey(projectRoot);
|
|
1070
|
+
const existing = this.bridges.get(key);
|
|
1071
|
+
if (existing) {
|
|
1072
|
+
existing.lastUsed = Date.now();
|
|
1073
|
+
return existing.bridge;
|
|
1074
|
+
}
|
|
1075
|
+
if (this.bridges.size >= this.maxPoolSize) {
|
|
1076
|
+
this.evictLRU();
|
|
1077
|
+
}
|
|
1078
|
+
let projectOverrides = {};
|
|
1079
|
+
if (this.projectConfigLoader) {
|
|
1080
|
+
try {
|
|
1081
|
+
projectOverrides = this.projectConfigLoader(key) ?? {};
|
|
1082
|
+
} catch (err) {
|
|
1083
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1084
|
+
this.error(`projectConfigLoader failed; using global overrides only: ${message}`);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
const mergedOverrides = { ...this.configOverrides, ...projectOverrides };
|
|
1088
|
+
const bridge = new BinaryBridge(this.binaryPath, key, this.bridgeOptions, mergedOverrides);
|
|
1089
|
+
this.bridges.set(key, { bridge, lastUsed: Date.now() });
|
|
1090
|
+
return bridge;
|
|
1091
|
+
}
|
|
1092
|
+
cleanup() {
|
|
1093
|
+
const now = Date.now();
|
|
1094
|
+
for (const [dir, entry] of this.bridges) {
|
|
1095
|
+
if (entry.bridge.hasPendingRequests())
|
|
1096
|
+
continue;
|
|
1097
|
+
if (now - entry.lastUsed > this.idleTimeoutMs) {
|
|
1098
|
+
entry.bridge.shutdown().catch((err) => this.error("cleanup shutdown failed:", err));
|
|
1099
|
+
this.bridges.delete(dir);
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
for (const bridge of this.staleBridges) {
|
|
1103
|
+
if (bridge.hasPendingRequests())
|
|
1104
|
+
continue;
|
|
1105
|
+
bridge.shutdown().catch((err) => this.error("stale cleanup shutdown failed:", err));
|
|
1106
|
+
this.staleBridges.delete(bridge);
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
evictLRU() {
|
|
1110
|
+
let oldestDir = null;
|
|
1111
|
+
let oldestTime = Infinity;
|
|
1112
|
+
for (const [dir, entry] of this.bridges) {
|
|
1113
|
+
if (entry.bridge.hasPendingRequests())
|
|
1114
|
+
continue;
|
|
1115
|
+
if (entry.lastUsed < oldestTime) {
|
|
1116
|
+
oldestTime = entry.lastUsed;
|
|
1117
|
+
oldestDir = dir;
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
if (oldestDir) {
|
|
1121
|
+
const entry = this.bridges.get(oldestDir);
|
|
1122
|
+
entry?.bridge.shutdown().catch((err) => this.error("eviction shutdown failed:", err));
|
|
1123
|
+
this.bridges.delete(oldestDir);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
async shutdown() {
|
|
1127
|
+
if (this.cleanupTimer) {
|
|
1128
|
+
clearInterval(this.cleanupTimer);
|
|
1129
|
+
this.cleanupTimer = null;
|
|
1130
|
+
}
|
|
1131
|
+
const shutdowns = [
|
|
1132
|
+
...Array.from(this.bridges.values(), (e) => e.bridge.shutdown()),
|
|
1133
|
+
...Array.from(this.staleBridges.values(), (bridge) => bridge.shutdown())
|
|
1134
|
+
];
|
|
1135
|
+
this.bridges.clear();
|
|
1136
|
+
this.staleBridges.clear();
|
|
1137
|
+
await Promise.allSettled(shutdowns);
|
|
1138
|
+
}
|
|
1139
|
+
async replaceBinary(newPath) {
|
|
1140
|
+
this.binaryPath = newPath;
|
|
1141
|
+
for (const entry of this.bridges.values()) {
|
|
1142
|
+
this.staleBridges.add(entry.bridge);
|
|
1143
|
+
}
|
|
1144
|
+
this.bridges.clear();
|
|
1145
|
+
this.log(`Binary path updated to ${newPath}. Active bridges marked stale — next calls will use the new binary.`);
|
|
1146
|
+
return newPath;
|
|
1147
|
+
}
|
|
1148
|
+
log(message, meta) {
|
|
1149
|
+
const logger = this.logger ?? getActiveLogger();
|
|
1150
|
+
if (logger) {
|
|
1151
|
+
try {
|
|
1152
|
+
logger.log(message, meta);
|
|
1153
|
+
} catch (err) {
|
|
1154
|
+
console.error(`[aft-bridge] ERROR: pool logger log threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
1155
|
+
console.error(`[aft-bridge] ${message}`);
|
|
1156
|
+
}
|
|
1157
|
+
} else
|
|
1158
|
+
log(message, meta);
|
|
1159
|
+
}
|
|
1160
|
+
error(message, meta) {
|
|
1161
|
+
const logger = this.logger ?? getActiveLogger();
|
|
1162
|
+
if (logger) {
|
|
1163
|
+
try {
|
|
1164
|
+
logger.error(message, meta);
|
|
1165
|
+
} catch (err) {
|
|
1166
|
+
console.error(`[aft-bridge] ERROR: pool logger error threw: ${err instanceof Error ? err.message : String(err)}`);
|
|
1167
|
+
console.error(`[aft-bridge] ERROR: ${message}`);
|
|
1168
|
+
}
|
|
1169
|
+
} else
|
|
1170
|
+
error(message, meta);
|
|
1171
|
+
}
|
|
1172
|
+
setConfigureOverride(key, value) {
|
|
1173
|
+
if (value === undefined) {
|
|
1174
|
+
delete this.configOverrides[key];
|
|
1175
|
+
} else {
|
|
1176
|
+
this.configOverrides[key] = value;
|
|
1177
|
+
}
|
|
1178
|
+
}
|
|
1179
|
+
get size() {
|
|
1180
|
+
return this.bridges.size;
|
|
1181
|
+
}
|
|
1182
|
+
_testGetConfigOverrides() {
|
|
1183
|
+
return { ...this.configOverrides };
|
|
1184
|
+
}
|
|
1185
|
+
_testGetBridgeOptions() {
|
|
1186
|
+
return { ...this.bridgeOptions };
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
function normalizeKey(projectRoot) {
|
|
1190
|
+
const stripped = projectRoot.replace(/[/\\]+$/, "");
|
|
1191
|
+
try {
|
|
1192
|
+
return realpathSync(stripped);
|
|
1193
|
+
} catch {
|
|
1194
|
+
return stripped;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
var DEFAULT_IDLE_TIMEOUT_MS = Infinity, DEFAULT_MAX_POOL_SIZE = 8, CLEANUP_INTERVAL_MS;
|
|
1198
|
+
var init_pool = __esm(() => {
|
|
1199
|
+
init_active_logger();
|
|
1200
|
+
init_bridge();
|
|
1201
|
+
CLEANUP_INTERVAL_MS = 60 * 1000;
|
|
1202
|
+
});
|
|
1203
|
+
// ../aft-bridge/dist/index.js
|
|
1204
|
+
var init_dist = __esm(() => {
|
|
1205
|
+
init_active_logger();
|
|
1206
|
+
init_bridge();
|
|
1207
|
+
init_downloader();
|
|
1208
|
+
init_migration();
|
|
1209
|
+
init_onnx_runtime();
|
|
1210
|
+
init_paths();
|
|
1211
|
+
init_platform();
|
|
1212
|
+
init_pool();
|
|
1213
|
+
init_resolver();
|
|
1214
|
+
});
|
|
1215
|
+
|
|
1216
|
+
// src/lib/paths.ts
|
|
1217
|
+
import { homedir as homedir2, tmpdir } from "node:os";
|
|
1218
|
+
import { join as join2 } from "node:path";
|
|
52
1219
|
function getAftBinaryCacheDir() {
|
|
53
1220
|
if (process.env.AFT_CACHE_DIR) {
|
|
54
|
-
return
|
|
1221
|
+
return join2(process.env.AFT_CACHE_DIR, "bin");
|
|
55
1222
|
}
|
|
56
1223
|
if (process.platform === "win32") {
|
|
57
1224
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
58
|
-
const base2 = localAppData ||
|
|
59
|
-
return
|
|
1225
|
+
const base2 = localAppData || join2(homedir2(), "AppData", "Local");
|
|
1226
|
+
return join2(base2, "aft", "bin");
|
|
60
1227
|
}
|
|
61
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
62
|
-
return
|
|
1228
|
+
const base = process.env.XDG_CACHE_HOME || join2(homedir2(), ".cache");
|
|
1229
|
+
return join2(base, "aft", "bin");
|
|
63
1230
|
}
|
|
64
1231
|
function getAftBinaryName() {
|
|
65
1232
|
return process.platform === "win32" ? "aft.exe" : "aft";
|
|
66
1233
|
}
|
|
67
1234
|
function getAftLspPackagesDir() {
|
|
68
1235
|
if (process.env.AFT_CACHE_DIR) {
|
|
69
|
-
return
|
|
1236
|
+
return join2(process.env.AFT_CACHE_DIR, "lsp-packages");
|
|
70
1237
|
}
|
|
71
1238
|
if (process.platform === "win32") {
|
|
72
1239
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
73
|
-
const base2 = localAppData ||
|
|
74
|
-
return
|
|
1240
|
+
const base2 = localAppData || join2(homedir2(), "AppData", "Local");
|
|
1241
|
+
return join2(base2, "aft", "lsp-packages");
|
|
75
1242
|
}
|
|
76
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
77
|
-
return
|
|
1243
|
+
const base = process.env.XDG_CACHE_HOME || join2(homedir2(), ".cache");
|
|
1244
|
+
return join2(base, "aft", "lsp-packages");
|
|
78
1245
|
}
|
|
79
1246
|
function getAftLspBinariesDir() {
|
|
80
1247
|
if (process.env.AFT_CACHE_DIR) {
|
|
81
|
-
return
|
|
1248
|
+
return join2(process.env.AFT_CACHE_DIR, "lsp-binaries");
|
|
82
1249
|
}
|
|
83
1250
|
if (process.platform === "win32") {
|
|
84
1251
|
const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
|
|
85
|
-
const base2 = localAppData ||
|
|
86
|
-
return
|
|
1252
|
+
const base2 = localAppData || join2(homedir2(), "AppData", "Local");
|
|
1253
|
+
return join2(base2, "aft", "lsp-binaries");
|
|
87
1254
|
}
|
|
88
|
-
const base = process.env.XDG_CACHE_HOME ||
|
|
89
|
-
return
|
|
1255
|
+
const base = process.env.XDG_CACHE_HOME || join2(homedir2(), ".cache");
|
|
1256
|
+
return join2(base, "aft", "lsp-binaries");
|
|
90
1257
|
}
|
|
91
1258
|
function homeDir() {
|
|
92
1259
|
if (process.platform === "win32")
|
|
93
|
-
return process.env.USERPROFILE || process.env.HOME ||
|
|
94
|
-
return process.env.HOME ||
|
|
1260
|
+
return process.env.USERPROFILE || process.env.HOME || homedir2();
|
|
1261
|
+
return process.env.HOME || homedir2();
|
|
95
1262
|
}
|
|
96
1263
|
function dataHome() {
|
|
97
1264
|
if (process.env.XDG_DATA_HOME)
|
|
98
1265
|
return process.env.XDG_DATA_HOME;
|
|
99
1266
|
if (process.platform === "win32") {
|
|
100
|
-
return process.env.LOCALAPPDATA || process.env.APPDATA ||
|
|
1267
|
+
return process.env.LOCALAPPDATA || process.env.APPDATA || join2(homeDir(), "AppData", "Local");
|
|
101
1268
|
}
|
|
102
|
-
return
|
|
1269
|
+
return join2(homeDir(), ".local", "share");
|
|
103
1270
|
}
|
|
104
1271
|
function getCortexKitStorageRoot() {
|
|
105
|
-
return
|
|
1272
|
+
return join2(dataHome(), "cortexkit", "aft");
|
|
106
1273
|
}
|
|
107
1274
|
function getTmpLogPath(filename) {
|
|
108
|
-
return
|
|
1275
|
+
return join2(tmpdir(), filename);
|
|
109
1276
|
}
|
|
110
|
-
var
|
|
1277
|
+
var init_paths2 = () => {};
|
|
111
1278
|
|
|
112
1279
|
// src/lib/binary-probe.ts
|
|
113
1280
|
import { execSync, spawnSync } from "node:child_process";
|
|
114
|
-
import { existsSync } from "node:fs";
|
|
1281
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
115
1282
|
import { createRequire } from "node:module";
|
|
116
|
-
import { homedir as
|
|
117
|
-
import { join as
|
|
1283
|
+
import { homedir as homedir3 } from "node:os";
|
|
1284
|
+
import { join as join3 } from "node:path";
|
|
118
1285
|
async function loadPluginVersion() {
|
|
119
1286
|
try {
|
|
120
1287
|
const bridgePackageName = "@cortexkit/aft-bridge";
|
|
@@ -167,7 +1334,7 @@ function probeAftBinary(preferredVersion) {
|
|
|
167
1334
|
const candidates = [];
|
|
168
1335
|
for (const candidate of aftBinaryCandidates(preferredVersion)) {
|
|
169
1336
|
try {
|
|
170
|
-
if (!
|
|
1337
|
+
if (!existsSync2(candidate))
|
|
171
1338
|
continue;
|
|
172
1339
|
const result = spawnSync(candidate, ["--version"], {
|
|
173
1340
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -198,12 +1365,12 @@ ${result.stderr ?? ""}`.trim();
|
|
|
198
1365
|
}
|
|
199
1366
|
candidates.push({ path: candidate, status: "matched", version, output });
|
|
200
1367
|
return { version, path: candidate, expectedVersion, expectedMajorMinor, candidates };
|
|
201
|
-
} catch (
|
|
1368
|
+
} catch (error2) {
|
|
202
1369
|
candidates.push({
|
|
203
1370
|
path: candidate,
|
|
204
1371
|
status: "error",
|
|
205
1372
|
version: null,
|
|
206
|
-
error:
|
|
1373
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
207
1374
|
});
|
|
208
1375
|
}
|
|
209
1376
|
}
|
|
@@ -218,14 +1385,14 @@ function pushCandidate(candidates, candidate) {
|
|
|
218
1385
|
function firstExisting(candidates) {
|
|
219
1386
|
for (const candidate of candidates) {
|
|
220
1387
|
try {
|
|
221
|
-
if (!
|
|
1388
|
+
if (!existsSync2(candidate))
|
|
222
1389
|
continue;
|
|
223
1390
|
return candidate;
|
|
224
1391
|
} catch {}
|
|
225
1392
|
}
|
|
226
1393
|
return null;
|
|
227
1394
|
}
|
|
228
|
-
function
|
|
1395
|
+
function platformKey2(platform = process.platform, arch = process.arch) {
|
|
229
1396
|
const table = {
|
|
230
1397
|
darwin: { arm64: "darwin-arm64", x64: "darwin-x64" },
|
|
231
1398
|
linux: { arm64: "linux-arm64", x64: "linux-x64" },
|
|
@@ -237,9 +1404,9 @@ function aftBinaryCandidates(preferredVersion) {
|
|
|
237
1404
|
const candidates = [];
|
|
238
1405
|
if (preferredVersion) {
|
|
239
1406
|
const tag = preferredVersion.startsWith("v") ? preferredVersion : `v${preferredVersion}`;
|
|
240
|
-
pushCandidate(candidates,
|
|
1407
|
+
pushCandidate(candidates, join3(getAftBinaryCacheDir(), tag, getAftBinaryName()));
|
|
241
1408
|
}
|
|
242
|
-
const key =
|
|
1409
|
+
const key = platformKey2();
|
|
243
1410
|
if (key) {
|
|
244
1411
|
try {
|
|
245
1412
|
const require2 = createRequire(import.meta.url);
|
|
@@ -253,11 +1420,14 @@ function aftBinaryCandidates(preferredVersion) {
|
|
|
253
1420
|
encoding: "utf-8",
|
|
254
1421
|
env: process.env
|
|
255
1422
|
}).trim();
|
|
256
|
-
|
|
257
|
-
|
|
1423
|
+
for (const line of resolved.split(/\r?\n/)) {
|
|
1424
|
+
const candidate = line.trim();
|
|
1425
|
+
if (candidate && isNativeExecutable(candidate)) {
|
|
1426
|
+
pushCandidate(candidates, candidate);
|
|
1427
|
+
}
|
|
258
1428
|
}
|
|
259
1429
|
} catch {}
|
|
260
|
-
pushCandidate(candidates,
|
|
1430
|
+
pushCandidate(candidates, join3(homedir3(), ".cargo", "bin", getAftBinaryName()));
|
|
261
1431
|
return candidates;
|
|
262
1432
|
}
|
|
263
1433
|
function findAftBinary(preferredVersion) {
|
|
@@ -265,16 +1435,17 @@ function findAftBinary(preferredVersion) {
|
|
|
265
1435
|
}
|
|
266
1436
|
var PLUGIN_VERSION, VERSION_LINE;
|
|
267
1437
|
var init_binary_probe = __esm(async () => {
|
|
268
|
-
|
|
1438
|
+
init_dist();
|
|
1439
|
+
init_paths2();
|
|
269
1440
|
PLUGIN_VERSION = await loadPluginVersion();
|
|
270
1441
|
VERSION_LINE = /^(?:aft\s+)?v?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)$/i;
|
|
271
1442
|
});
|
|
272
1443
|
|
|
273
1444
|
// src/lib/fs-util.ts
|
|
274
|
-
import { existsSync as
|
|
275
|
-
import { join as
|
|
1445
|
+
import { existsSync as existsSync3, readdirSync, statSync } from "node:fs";
|
|
1446
|
+
import { join as join4 } from "node:path";
|
|
276
1447
|
function dirSize(path) {
|
|
277
|
-
if (!
|
|
1448
|
+
if (!existsSync3(path)) {
|
|
278
1449
|
return 0;
|
|
279
1450
|
}
|
|
280
1451
|
const stat = statSync(path);
|
|
@@ -286,7 +1457,7 @@ function dirSize(path) {
|
|
|
286
1457
|
}
|
|
287
1458
|
let total = 0;
|
|
288
1459
|
for (const entry of readdirSync(path)) {
|
|
289
|
-
total += dirSize(
|
|
1460
|
+
total += dirSize(join4(path, entry));
|
|
290
1461
|
}
|
|
291
1462
|
return total;
|
|
292
1463
|
}
|
|
@@ -4840,45 +6011,45 @@ var require_esprima = __commonJS((exports, module) => {
|
|
|
4840
6011
|
this.errors = [];
|
|
4841
6012
|
this.tolerant = false;
|
|
4842
6013
|
}
|
|
4843
|
-
ErrorHandler2.prototype.recordError = function(
|
|
4844
|
-
this.errors.push(
|
|
6014
|
+
ErrorHandler2.prototype.recordError = function(error2) {
|
|
6015
|
+
this.errors.push(error2);
|
|
4845
6016
|
};
|
|
4846
|
-
ErrorHandler2.prototype.tolerate = function(
|
|
6017
|
+
ErrorHandler2.prototype.tolerate = function(error2) {
|
|
4847
6018
|
if (this.tolerant) {
|
|
4848
|
-
this.recordError(
|
|
6019
|
+
this.recordError(error2);
|
|
4849
6020
|
} else {
|
|
4850
|
-
throw
|
|
6021
|
+
throw error2;
|
|
4851
6022
|
}
|
|
4852
6023
|
};
|
|
4853
6024
|
ErrorHandler2.prototype.constructError = function(msg, column) {
|
|
4854
|
-
var
|
|
6025
|
+
var error2 = new Error(msg);
|
|
4855
6026
|
try {
|
|
4856
|
-
throw
|
|
6027
|
+
throw error2;
|
|
4857
6028
|
} catch (base) {
|
|
4858
6029
|
if (Object.create && Object.defineProperty) {
|
|
4859
|
-
|
|
4860
|
-
Object.defineProperty(
|
|
6030
|
+
error2 = Object.create(base);
|
|
6031
|
+
Object.defineProperty(error2, "column", { value: column });
|
|
4861
6032
|
}
|
|
4862
6033
|
}
|
|
4863
|
-
return
|
|
6034
|
+
return error2;
|
|
4864
6035
|
};
|
|
4865
6036
|
ErrorHandler2.prototype.createError = function(index, line, col, description) {
|
|
4866
6037
|
var msg = "Line " + line + ": " + description;
|
|
4867
|
-
var
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
return
|
|
6038
|
+
var error2 = this.constructError(msg, col);
|
|
6039
|
+
error2.index = index;
|
|
6040
|
+
error2.lineNumber = line;
|
|
6041
|
+
error2.description = description;
|
|
6042
|
+
return error2;
|
|
4872
6043
|
};
|
|
4873
6044
|
ErrorHandler2.prototype.throwError = function(index, line, col, description) {
|
|
4874
6045
|
throw this.createError(index, line, col, description);
|
|
4875
6046
|
};
|
|
4876
6047
|
ErrorHandler2.prototype.tolerateError = function(index, line, col, description) {
|
|
4877
|
-
var
|
|
6048
|
+
var error2 = this.createError(index, line, col, description);
|
|
4878
6049
|
if (this.tolerant) {
|
|
4879
|
-
this.recordError(
|
|
6050
|
+
this.recordError(error2);
|
|
4880
6051
|
} else {
|
|
4881
|
-
throw
|
|
6052
|
+
throw error2;
|
|
4882
6053
|
}
|
|
4883
6054
|
};
|
|
4884
6055
|
return ErrorHandler2;
|
|
@@ -7548,19 +8719,19 @@ var require_parse = __commonJS((exports, module) => {
|
|
|
7548
8719
|
var symbolFor = (prefix) => Symbol.for(last_prop !== UNDEFINED ? prefix + COLON + last_prop : prefix);
|
|
7549
8720
|
var transform = (k, { value, context = {} }) => reviver ? reviver(k, value, context) : value;
|
|
7550
8721
|
var unexpected = () => {
|
|
7551
|
-
const
|
|
7552
|
-
Object.assign(
|
|
8722
|
+
const error2 = new SyntaxError(`Unexpected token '${current.value.slice(0, 1)}', "${current_code}" is not valid JSON`);
|
|
8723
|
+
Object.assign(error2, current.loc.start);
|
|
7553
8724
|
free();
|
|
7554
|
-
throw
|
|
8725
|
+
throw error2;
|
|
7555
8726
|
};
|
|
7556
8727
|
var unexpected_end = () => {
|
|
7557
|
-
const
|
|
7558
|
-
Object.assign(
|
|
8728
|
+
const error2 = new SyntaxError("Unexpected end of JSON input");
|
|
8729
|
+
Object.assign(error2, last ? last.loc.end : {
|
|
7559
8730
|
line: 1,
|
|
7560
8731
|
column: 0
|
|
7561
8732
|
});
|
|
7562
8733
|
free();
|
|
7563
|
-
throw
|
|
8734
|
+
throw error2;
|
|
7564
8735
|
};
|
|
7565
8736
|
var next = () => {
|
|
7566
8737
|
const new_token = tokens[++index];
|
|
@@ -7909,10 +9080,10 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7909
9080
|
replacer = null;
|
|
7910
9081
|
indent = EMPTY;
|
|
7911
9082
|
};
|
|
7912
|
-
var
|
|
9083
|
+
var join5 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(one, gap)), gap) : two ? two.trimRight() + repeat_line_breaks(Math.max(1, count_trailing_line_breaks(two, gap)), gap) : EMPTY;
|
|
7913
9084
|
var join_content = (inside, value, gap) => {
|
|
7914
9085
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent, true);
|
|
7915
|
-
return
|
|
9086
|
+
return join5(comment, inside, gap);
|
|
7916
9087
|
};
|
|
7917
9088
|
var stringify_string = (holder, key, value) => {
|
|
7918
9089
|
const raw = get_raw_string_literal(holder, key);
|
|
@@ -7934,13 +9105,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7934
9105
|
if (i !== 0) {
|
|
7935
9106
|
inside += COMMA;
|
|
7936
9107
|
}
|
|
7937
|
-
const before =
|
|
9108
|
+
const before = join5(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
|
|
7938
9109
|
inside += before || LF + deeper_gap;
|
|
7939
9110
|
inside += stringify(i, value, deeper_gap) || STR_NULL;
|
|
7940
9111
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
7941
9112
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
7942
9113
|
}
|
|
7943
|
-
inside +=
|
|
9114
|
+
inside += join5(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7944
9115
|
return BRACKET_OPEN + join_content(inside, value, gap) + BRACKET_CLOSE;
|
|
7945
9116
|
};
|
|
7946
9117
|
var object_stringify = (value, gap) => {
|
|
@@ -7961,13 +9132,13 @@ var require_stringify = __commonJS((exports, module) => {
|
|
|
7961
9132
|
inside += COMMA;
|
|
7962
9133
|
}
|
|
7963
9134
|
first = false;
|
|
7964
|
-
const before =
|
|
9135
|
+
const before = join5(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
|
|
7965
9136
|
inside += before || LF + deeper_gap;
|
|
7966
9137
|
inside += quote(key) + process_comments(value, AFTER_PROP(key), deeper_gap) + COLON + process_comments(value, AFTER_COLON(key), deeper_gap) + SPACE + sv + process_comments(value, AFTER_VALUE(key), deeper_gap);
|
|
7967
9138
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
7968
9139
|
};
|
|
7969
9140
|
keys.forEach(iteratee);
|
|
7970
|
-
inside +=
|
|
9141
|
+
inside += join5(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
|
|
7971
9142
|
return CURLY_BRACKET_OPEN + join_content(inside, value, gap) + CURLY_BRACKET_CLOSE;
|
|
7972
9143
|
};
|
|
7973
9144
|
function stringify(key, holder, gap) {
|
|
@@ -8060,42 +9231,42 @@ var require_src2 = __commonJS((exports, module) => {
|
|
|
8060
9231
|
});
|
|
8061
9232
|
|
|
8062
9233
|
// src/lib/jsonc.ts
|
|
8063
|
-
import { existsSync as
|
|
9234
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync, writeFileSync } from "node:fs";
|
|
8064
9235
|
import { dirname } from "node:path";
|
|
8065
9236
|
function detectJsoncFile(configDir, baseName) {
|
|
8066
9237
|
const jsoncPath = `${configDir}/${baseName}.jsonc`;
|
|
8067
9238
|
const jsonPath = `${configDir}/${baseName}.json`;
|
|
8068
|
-
if (
|
|
9239
|
+
if (existsSync4(jsoncPath)) {
|
|
8069
9240
|
return { path: jsoncPath, format: "jsonc" };
|
|
8070
9241
|
}
|
|
8071
|
-
if (
|
|
9242
|
+
if (existsSync4(jsonPath)) {
|
|
8072
9243
|
return { path: jsonPath, format: "json" };
|
|
8073
9244
|
}
|
|
8074
9245
|
return { path: jsonPath, format: "none" };
|
|
8075
9246
|
}
|
|
8076
9247
|
function readJsoncFile(path) {
|
|
8077
|
-
if (!
|
|
9248
|
+
if (!existsSync4(path)) {
|
|
8078
9249
|
return { value: null };
|
|
8079
9250
|
}
|
|
8080
9251
|
try {
|
|
8081
9252
|
const raw = readFileSync(path, "utf-8");
|
|
8082
9253
|
const value = import_comment_json.parse(raw);
|
|
8083
9254
|
return { value };
|
|
8084
|
-
} catch (
|
|
9255
|
+
} catch (error2) {
|
|
8085
9256
|
return {
|
|
8086
9257
|
value: null,
|
|
8087
|
-
error:
|
|
9258
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
8088
9259
|
};
|
|
8089
9260
|
}
|
|
8090
9261
|
}
|
|
8091
9262
|
function writeJsoncFile(path, value, format = "json") {
|
|
8092
|
-
|
|
9263
|
+
mkdirSync2(dirname(path), { recursive: true });
|
|
8093
9264
|
const serialized = format === "jsonc" ? import_comment_json.stringify(value, null, 2) : JSON.stringify(value, null, 2);
|
|
8094
9265
|
writeFileSync(path, `${serialized}
|
|
8095
9266
|
`);
|
|
8096
9267
|
}
|
|
8097
9268
|
function ensureAftSchemaUrl(path, format) {
|
|
8098
|
-
const existed =
|
|
9269
|
+
const existed = existsSync4(path);
|
|
8099
9270
|
if (!existed) {
|
|
8100
9271
|
const writeFormat = format === "jsonc" ? "jsonc" : "json";
|
|
8101
9272
|
writeJsoncFile(path, { $schema: AFT_SCHEMA_URL }, writeFormat);
|
|
@@ -8104,9 +9275,9 @@ function ensureAftSchemaUrl(path, format) {
|
|
|
8104
9275
|
message: `created ${path} with $schema URL for editor autocomplete`
|
|
8105
9276
|
};
|
|
8106
9277
|
}
|
|
8107
|
-
const { value, error } = readJsoncFile(path);
|
|
9278
|
+
const { value, error: error2 } = readJsoncFile(path);
|
|
8108
9279
|
if (!value) {
|
|
8109
|
-
throw new Error(
|
|
9280
|
+
throw new Error(error2 ? `failed to parse ${path}: ${error2}` : `failed to parse ${path}`);
|
|
8110
9281
|
}
|
|
8111
9282
|
const previous = value.$schema;
|
|
8112
9283
|
if (previous === AFT_SCHEMA_URL) {
|
|
@@ -8148,26 +9319,52 @@ var init_self_version = () => {};
|
|
|
8148
9319
|
|
|
8149
9320
|
// src/adapters/opencode.ts
|
|
8150
9321
|
import { execSync as execSync2 } from "node:child_process";
|
|
8151
|
-
import { existsSync as
|
|
8152
|
-
import { homedir as
|
|
8153
|
-
import { dirname as dirname2, join as
|
|
9322
|
+
import { existsSync as existsSync5, readFileSync as readFileSync2, rmSync, statSync as statSync2 } from "node:fs";
|
|
9323
|
+
import { homedir as homedir4 } from "node:os";
|
|
9324
|
+
import { dirname as dirname2, join as join5, parse, resolve } from "node:path";
|
|
8154
9325
|
import { fileURLToPath } from "node:url";
|
|
8155
9326
|
function getOpenCodeConfigDir() {
|
|
8156
9327
|
const envDir = process.env.OPENCODE_CONFIG_DIR?.trim();
|
|
8157
9328
|
if (envDir)
|
|
8158
9329
|
return resolve(envDir);
|
|
8159
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
8160
|
-
return
|
|
9330
|
+
const xdg = process.env.XDG_CONFIG_HOME || join5(homedir4(), ".config");
|
|
9331
|
+
return join5(xdg, "opencode");
|
|
8161
9332
|
}
|
|
8162
9333
|
function getOpenCodeCacheDir() {
|
|
8163
9334
|
const xdg = process.env.XDG_CACHE_HOME;
|
|
8164
9335
|
if (xdg)
|
|
8165
|
-
return
|
|
9336
|
+
return join5(xdg, "opencode");
|
|
8166
9337
|
if (process.platform === "win32") {
|
|
8167
|
-
const localAppData = process.env.LOCALAPPDATA ??
|
|
8168
|
-
return
|
|
9338
|
+
const localAppData = process.env.LOCALAPPDATA ?? join5(homedir4(), "AppData", "Local");
|
|
9339
|
+
return join5(localAppData, "opencode");
|
|
9340
|
+
}
|
|
9341
|
+
return join5(homedir4(), ".cache", "opencode");
|
|
9342
|
+
}
|
|
9343
|
+
function hasOpenCodeCli() {
|
|
9344
|
+
try {
|
|
9345
|
+
execSync2("opencode --version", { stdio: "ignore", timeout: 5000 });
|
|
9346
|
+
return true;
|
|
9347
|
+
} catch {
|
|
9348
|
+
return false;
|
|
9349
|
+
}
|
|
9350
|
+
}
|
|
9351
|
+
function openCodeDesktopAppExists() {
|
|
9352
|
+
const candidates = [];
|
|
9353
|
+
if (process.platform === "darwin") {
|
|
9354
|
+
candidates.push("/Applications/OpenCode.app", "/Applications/OpenCode Beta.app", join5(homedir4(), "Applications", "OpenCode.app"), join5(homedir4(), "Applications", "OpenCode Beta.app"));
|
|
9355
|
+
} else if (process.platform === "win32") {
|
|
9356
|
+
const localAppData = process.env.LOCALAPPDATA ?? join5(homedir4(), "AppData", "Local");
|
|
9357
|
+
candidates.push(join5(localAppData, "Programs", "opencode"), join5(localAppData, "opencode"));
|
|
9358
|
+
} else {
|
|
9359
|
+
candidates.push("/opt/OpenCode", "/usr/lib/opencode", join5(homedir4(), ".local", "share", "applications", "opencode.desktop"));
|
|
8169
9360
|
}
|
|
8170
|
-
return
|
|
9361
|
+
return candidates.some((p) => {
|
|
9362
|
+
try {
|
|
9363
|
+
return existsSync5(p);
|
|
9364
|
+
} catch {
|
|
9365
|
+
return false;
|
|
9366
|
+
}
|
|
9367
|
+
});
|
|
8171
9368
|
}
|
|
8172
9369
|
function pathFromEntry(entry) {
|
|
8173
9370
|
if (entry.startsWith("file://")) {
|
|
@@ -8186,13 +9383,13 @@ function pathPointsToOurPlugin(entry) {
|
|
|
8186
9383
|
if (!fsPath)
|
|
8187
9384
|
return false;
|
|
8188
9385
|
try {
|
|
8189
|
-
if (!
|
|
9386
|
+
if (!existsSync5(fsPath))
|
|
8190
9387
|
return false;
|
|
8191
9388
|
let searchDir = statSync2(fsPath).isDirectory() ? fsPath : dirname2(fsPath);
|
|
8192
9389
|
let pkgJsonPath = null;
|
|
8193
9390
|
while (true) {
|
|
8194
|
-
const candidate =
|
|
8195
|
-
if (
|
|
9391
|
+
const candidate = join5(searchDir, "package.json");
|
|
9392
|
+
if (existsSync5(candidate)) {
|
|
8196
9393
|
pkgJsonPath = candidate;
|
|
8197
9394
|
break;
|
|
8198
9395
|
}
|
|
@@ -8223,16 +9420,19 @@ class OpenCodeAdapter {
|
|
|
8223
9420
|
pluginPackageName = PLUGIN_NAME;
|
|
8224
9421
|
pluginEntryWithVersion = PLUGIN_ENTRY;
|
|
8225
9422
|
isInstalled() {
|
|
8226
|
-
|
|
8227
|
-
execSync2("opencode --version", { stdio: "ignore" });
|
|
9423
|
+
if (existsSync5(getOpenCodeConfigDir()))
|
|
8228
9424
|
return true;
|
|
8229
|
-
|
|
8230
|
-
return
|
|
8231
|
-
|
|
9425
|
+
if (openCodeDesktopAppExists())
|
|
9426
|
+
return true;
|
|
9427
|
+
return hasOpenCodeCli();
|
|
8232
9428
|
}
|
|
8233
9429
|
getHostVersion() {
|
|
8234
9430
|
try {
|
|
8235
|
-
return execSync2("opencode --version", {
|
|
9431
|
+
return execSync2("opencode --version", {
|
|
9432
|
+
encoding: "utf-8",
|
|
9433
|
+
stdio: "pipe",
|
|
9434
|
+
timeout: 5000
|
|
9435
|
+
}).trim();
|
|
8236
9436
|
} catch {
|
|
8237
9437
|
return null;
|
|
8238
9438
|
}
|
|
@@ -8271,12 +9471,12 @@ class OpenCodeAdapter {
|
|
|
8271
9471
|
configPath
|
|
8272
9472
|
};
|
|
8273
9473
|
}
|
|
8274
|
-
const { value, error } = readJsoncFile(configPath);
|
|
8275
|
-
if (
|
|
9474
|
+
const { value, error: error2 } = readJsoncFile(configPath);
|
|
9475
|
+
if (error2 || !value) {
|
|
8276
9476
|
return {
|
|
8277
9477
|
ok: false,
|
|
8278
9478
|
action: "error",
|
|
8279
|
-
message: `Could not parse ${configPath}: ${
|
|
9479
|
+
message: `Could not parse ${configPath}: ${error2 ?? "unknown error"}`,
|
|
8280
9480
|
configPath
|
|
8281
9481
|
};
|
|
8282
9482
|
}
|
|
@@ -8301,11 +9501,11 @@ class OpenCodeAdapter {
|
|
|
8301
9501
|
};
|
|
8302
9502
|
}
|
|
8303
9503
|
getPluginCacheInfo() {
|
|
8304
|
-
const path =
|
|
9504
|
+
const path = join5(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY);
|
|
8305
9505
|
let cached;
|
|
8306
9506
|
try {
|
|
8307
|
-
const installedPkgPath =
|
|
8308
|
-
if (
|
|
9507
|
+
const installedPkgPath = join5(path, "node_modules", "@cortexkit", "aft-opencode", "package.json");
|
|
9508
|
+
if (existsSync5(installedPkgPath)) {
|
|
8309
9509
|
const pkg = JSON.parse(readFileSync2(installedPkgPath, "utf-8"));
|
|
8310
9510
|
cached = typeof pkg.version === "string" ? pkg.version : undefined;
|
|
8311
9511
|
}
|
|
@@ -8316,7 +9516,7 @@ class OpenCodeAdapter {
|
|
|
8316
9516
|
path,
|
|
8317
9517
|
cached,
|
|
8318
9518
|
latest: getSelfVersion(),
|
|
8319
|
-
exists:
|
|
9519
|
+
exists: existsSync5(path)
|
|
8320
9520
|
};
|
|
8321
9521
|
}
|
|
8322
9522
|
getStorageDir() {
|
|
@@ -8349,13 +9549,13 @@ class OpenCodeAdapter {
|
|
|
8349
9549
|
cached: info.cached,
|
|
8350
9550
|
latest: info.latest
|
|
8351
9551
|
};
|
|
8352
|
-
} catch (
|
|
9552
|
+
} catch (error2) {
|
|
8353
9553
|
return {
|
|
8354
9554
|
action: "error",
|
|
8355
9555
|
path: info.path,
|
|
8356
9556
|
cached: info.cached,
|
|
8357
9557
|
latest: info.latest,
|
|
8358
|
-
error:
|
|
9558
|
+
error: error2 instanceof Error ? error2.message : String(error2)
|
|
8359
9559
|
};
|
|
8360
9560
|
}
|
|
8361
9561
|
}
|
|
@@ -8365,11 +9565,11 @@ class OpenCodeAdapter {
|
|
|
8365
9565
|
describeStorageSubtrees() {
|
|
8366
9566
|
const storage = this.getStorageDir();
|
|
8367
9567
|
return {
|
|
8368
|
-
index: dirSize(
|
|
8369
|
-
semantic: dirSize(
|
|
8370
|
-
backups: dirSize(
|
|
8371
|
-
url_cache: dirSize(
|
|
8372
|
-
onnxruntime: dirSize(
|
|
9568
|
+
index: dirSize(join5(storage, "index")),
|
|
9569
|
+
semantic: dirSize(join5(storage, "semantic")),
|
|
9570
|
+
backups: dirSize(join5(storage, "backups")),
|
|
9571
|
+
url_cache: dirSize(join5(storage, "url_cache")),
|
|
9572
|
+
onnxruntime: dirSize(join5(storage, "onnxruntime"))
|
|
8373
9573
|
};
|
|
8374
9574
|
}
|
|
8375
9575
|
}
|
|
@@ -8377,24 +9577,24 @@ var PLUGIN_NAME = "@cortexkit/aft-opencode", PLUGIN_ENTRY;
|
|
|
8377
9577
|
var init_opencode = __esm(() => {
|
|
8378
9578
|
init_fs_util();
|
|
8379
9579
|
init_jsonc();
|
|
8380
|
-
|
|
9580
|
+
init_paths2();
|
|
8381
9581
|
init_self_version();
|
|
8382
9582
|
PLUGIN_ENTRY = `${PLUGIN_NAME}@latest`;
|
|
8383
9583
|
});
|
|
8384
9584
|
|
|
8385
9585
|
// src/adapters/pi.ts
|
|
8386
9586
|
import { execSync as execSync3, spawnSync as spawnSync2 } from "node:child_process";
|
|
8387
|
-
import { existsSync as
|
|
8388
|
-
import { homedir as
|
|
8389
|
-
import { join as
|
|
9587
|
+
import { existsSync as existsSync6, readFileSync as readFileSync3 } from "node:fs";
|
|
9588
|
+
import { homedir as homedir5 } from "node:os";
|
|
9589
|
+
import { join as join6 } from "node:path";
|
|
8390
9590
|
function getPiAgentDir() {
|
|
8391
9591
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
8392
|
-
const home = envHome && envHome.length > 0 ? envHome :
|
|
8393
|
-
return
|
|
9592
|
+
const home = envHome && envHome.length > 0 ? envHome : homedir5();
|
|
9593
|
+
return join6(home, ".pi", "agent");
|
|
8394
9594
|
}
|
|
8395
9595
|
function readPiExtensionIndex() {
|
|
8396
|
-
const settingsPath =
|
|
8397
|
-
if (
|
|
9596
|
+
const settingsPath = join6(getPiAgentDir(), "settings.json");
|
|
9597
|
+
if (existsSync6(settingsPath)) {
|
|
8398
9598
|
try {
|
|
8399
9599
|
const raw = readFileSync3(settingsPath, "utf-8");
|
|
8400
9600
|
const trimmed = raw.replace(/^\uFEFF/, "");
|
|
@@ -8407,13 +9607,13 @@ function readPiExtensionIndex() {
|
|
|
8407
9607
|
} catch {}
|
|
8408
9608
|
}
|
|
8409
9609
|
const candidates = [
|
|
8410
|
-
|
|
8411
|
-
|
|
8412
|
-
|
|
8413
|
-
|
|
9610
|
+
join6(getPiAgentDir(), "extensions.json"),
|
|
9611
|
+
join6(getPiAgentDir(), "extensions.jsonc"),
|
|
9612
|
+
join6(getPiAgentDir(), "config.json"),
|
|
9613
|
+
join6(getPiAgentDir(), "config.jsonc")
|
|
8414
9614
|
];
|
|
8415
9615
|
for (const path of candidates) {
|
|
8416
|
-
if (!
|
|
9616
|
+
if (!existsSync6(path))
|
|
8417
9617
|
continue;
|
|
8418
9618
|
try {
|
|
8419
9619
|
const { value } = readJsoncFile(path);
|
|
@@ -8446,15 +9646,15 @@ function piEntryMatchesAft(entry) {
|
|
|
8446
9646
|
} else if (entry.startsWith("/")) {
|
|
8447
9647
|
resolved = entry;
|
|
8448
9648
|
} else if (entry.length > 0) {
|
|
8449
|
-
resolved =
|
|
9649
|
+
resolved = join6(getPiAgentDir(), entry);
|
|
8450
9650
|
}
|
|
8451
9651
|
if (!resolved)
|
|
8452
9652
|
return false;
|
|
8453
9653
|
try {
|
|
8454
|
-
if (!
|
|
9654
|
+
if (!existsSync6(resolved))
|
|
8455
9655
|
return false;
|
|
8456
|
-
const pkgPath =
|
|
8457
|
-
if (!
|
|
9656
|
+
const pkgPath = join6(resolved, "package.json");
|
|
9657
|
+
if (!existsSync6(pkgPath))
|
|
8458
9658
|
return false;
|
|
8459
9659
|
const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
|
|
8460
9660
|
return pkg.name === PLUGIN_NAME2;
|
|
@@ -8474,7 +9674,7 @@ class PiAdapter {
|
|
|
8474
9674
|
pluginEntryWithVersion = PLUGIN_ENTRY2;
|
|
8475
9675
|
isInstalled() {
|
|
8476
9676
|
try {
|
|
8477
|
-
execSync3("pi --version", { stdio: "ignore" });
|
|
9677
|
+
execSync3("pi --version", { stdio: "ignore", timeout: 5000 });
|
|
8478
9678
|
return true;
|
|
8479
9679
|
} catch {
|
|
8480
9680
|
return false;
|
|
@@ -8484,7 +9684,8 @@ class PiAdapter {
|
|
|
8484
9684
|
try {
|
|
8485
9685
|
const result = spawnSync2("pi", ["--version"], {
|
|
8486
9686
|
stdio: ["ignore", "pipe", "pipe"],
|
|
8487
|
-
encoding: "utf-8"
|
|
9687
|
+
encoding: "utf-8",
|
|
9688
|
+
timeout: 5000
|
|
8488
9689
|
});
|
|
8489
9690
|
if (result.status !== 0)
|
|
8490
9691
|
return null;
|
|
@@ -8503,7 +9704,7 @@ class PiAdapter {
|
|
|
8503
9704
|
const aft = detectJsoncFile(configDir, "aft");
|
|
8504
9705
|
return {
|
|
8505
9706
|
configDir,
|
|
8506
|
-
harnessConfig: index.path ??
|
|
9707
|
+
harnessConfig: index.path ?? join6(configDir, "extensions.json"),
|
|
8507
9708
|
harnessConfigFormat: index.path ? "json" : "none",
|
|
8508
9709
|
aftConfig: aft.path,
|
|
8509
9710
|
aftConfigFormat: aft.format
|
|
@@ -8537,22 +9738,22 @@ class PiAdapter {
|
|
|
8537
9738
|
message: `Installed ${PLUGIN_ENTRY2} via \`pi install\``,
|
|
8538
9739
|
configPath: this.detectConfigPaths().harnessConfig
|
|
8539
9740
|
};
|
|
8540
|
-
} catch (
|
|
9741
|
+
} catch (error2) {
|
|
8541
9742
|
return {
|
|
8542
9743
|
ok: false,
|
|
8543
9744
|
action: "error",
|
|
8544
|
-
message: `Failed to run \`pi install ${PLUGIN_ENTRY2}\`: ${
|
|
9745
|
+
message: `Failed to run \`pi install ${PLUGIN_ENTRY2}\`: ${error2 instanceof Error ? error2.message : String(error2)}`,
|
|
8545
9746
|
configPath: this.detectConfigPaths().harnessConfig
|
|
8546
9747
|
};
|
|
8547
9748
|
}
|
|
8548
9749
|
}
|
|
8549
9750
|
getPluginCacheInfo() {
|
|
8550
9751
|
const candidates = [
|
|
8551
|
-
|
|
8552
|
-
|
|
9752
|
+
join6(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
|
|
9753
|
+
join6(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
|
|
8553
9754
|
];
|
|
8554
9755
|
for (const candidate of candidates) {
|
|
8555
|
-
if (!
|
|
9756
|
+
if (!existsSync6(candidate))
|
|
8556
9757
|
continue;
|
|
8557
9758
|
try {
|
|
8558
9759
|
const pkg = JSON.parse(readFileSync3(candidate, "utf-8"));
|
|
@@ -8566,7 +9767,7 @@ class PiAdapter {
|
|
|
8566
9767
|
} catch {}
|
|
8567
9768
|
}
|
|
8568
9769
|
return {
|
|
8569
|
-
path:
|
|
9770
|
+
path: join6(getPiAgentDir(), "extensions"),
|
|
8570
9771
|
exists: false
|
|
8571
9772
|
};
|
|
8572
9773
|
}
|
|
@@ -8588,11 +9789,11 @@ class PiAdapter {
|
|
|
8588
9789
|
describeStorageSubtrees() {
|
|
8589
9790
|
const storage = this.getStorageDir();
|
|
8590
9791
|
return {
|
|
8591
|
-
index: dirSize(
|
|
8592
|
-
semantic: dirSize(
|
|
8593
|
-
backups: dirSize(
|
|
8594
|
-
url_cache: dirSize(
|
|
8595
|
-
onnxruntime: dirSize(
|
|
9792
|
+
index: dirSize(join6(storage, "index")),
|
|
9793
|
+
semantic: dirSize(join6(storage, "semantic")),
|
|
9794
|
+
backups: dirSize(join6(storage, "backups")),
|
|
9795
|
+
url_cache: dirSize(join6(storage, "url_cache")),
|
|
9796
|
+
onnxruntime: dirSize(join6(storage, "onnxruntime"))
|
|
8596
9797
|
};
|
|
8597
9798
|
}
|
|
8598
9799
|
}
|
|
@@ -8600,7 +9801,7 @@ var PLUGIN_NAME2 = "@cortexkit/aft-pi", PLUGIN_ENTRY2;
|
|
|
8600
9801
|
var init_pi = __esm(() => {
|
|
8601
9802
|
init_fs_util();
|
|
8602
9803
|
init_jsonc();
|
|
8603
|
-
|
|
9804
|
+
init_paths2();
|
|
8604
9805
|
PLUGIN_ENTRY2 = `npm:${PLUGIN_NAME2}`;
|
|
8605
9806
|
});
|
|
8606
9807
|
|
|
@@ -8778,7 +9979,7 @@ var ANSI_RE, CONTROL_RE, TAB_RE, EMOJI_RE, LATIN_RE, MODIFIER_RE, NO_TRUNCATION,
|
|
|
8778
9979
|
ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
|
|
8779
9980
|
};
|
|
8780
9981
|
}, dist_default;
|
|
8781
|
-
var
|
|
9982
|
+
var init_dist2 = __esm(() => {
|
|
8782
9983
|
init_utils();
|
|
8783
9984
|
ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/y;
|
|
8784
9985
|
CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
|
|
@@ -8794,8 +9995,8 @@ var init_dist = __esm(() => {
|
|
|
8794
9995
|
var NO_TRUNCATION2, fastStringWidth = (input, options = {}) => {
|
|
8795
9996
|
return dist_default(input, NO_TRUNCATION2, options).width;
|
|
8796
9997
|
}, dist_default2;
|
|
8797
|
-
var
|
|
8798
|
-
|
|
9998
|
+
var init_dist3 = __esm(() => {
|
|
9999
|
+
init_dist2();
|
|
8799
10000
|
NO_TRUNCATION2 = {
|
|
8800
10001
|
limit: Infinity,
|
|
8801
10002
|
ellipsis: "",
|
|
@@ -8998,7 +10199,7 @@ var ESC = "\x1B", CSI = "", END_CODE = 39, ANSI_ESCAPE_BELL = "\x07", ANSI_CSI
|
|
|
8998
10199
|
return returnValue;
|
|
8999
10200
|
}, CRLF_OR_LF;
|
|
9000
10201
|
var init_main = __esm(() => {
|
|
9001
|
-
|
|
10202
|
+
init_dist3();
|
|
9002
10203
|
ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
|
|
9003
10204
|
GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
|
|
9004
10205
|
CRLF_OR_LF = /\r?\n/;
|
|
@@ -9278,7 +10479,7 @@ var import_sisteransi, E, G, u, Y, C, O = (r) => ("columns" in r) && typeof r.co
|
|
|
9278
10479
|
}
|
|
9279
10480
|
}
|
|
9280
10481
|
}, H, Q, X, et, st, it, nt, at;
|
|
9281
|
-
var
|
|
10482
|
+
var init_dist4 = __esm(() => {
|
|
9282
10483
|
init_main();
|
|
9283
10484
|
import_sisteransi = __toESM(require_src3(), 1);
|
|
9284
10485
|
E = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
@@ -9900,11 +11101,11 @@ ${c2}
|
|
|
9900
11101
|
}
|
|
9901
11102
|
}
|
|
9902
11103
|
} }).prompt();
|
|
9903
|
-
var
|
|
9904
|
-
|
|
9905
|
-
|
|
11104
|
+
var init_dist5 = __esm(() => {
|
|
11105
|
+
init_dist4();
|
|
11106
|
+
init_dist4();
|
|
9906
11107
|
init_main();
|
|
9907
|
-
|
|
11108
|
+
init_dist3();
|
|
9908
11109
|
import_sisteransi2 = __toESM(require_src3(), 1);
|
|
9909
11110
|
ee = Ze();
|
|
9910
11111
|
_e = w2("◆", "*");
|
|
@@ -10014,7 +11215,7 @@ async function text(message, options = {}) {
|
|
|
10014
11215
|
return result;
|
|
10015
11216
|
}
|
|
10016
11217
|
var init_prompts = __esm(() => {
|
|
10017
|
-
|
|
11218
|
+
init_dist5();
|
|
10018
11219
|
});
|
|
10019
11220
|
|
|
10020
11221
|
// src/lib/harness-select.ts
|
|
@@ -10162,8 +11363,8 @@ async function runSetup(argv) {
|
|
|
10162
11363
|
if (schemaResult.action === "added" || schemaResult.action === "updated") {
|
|
10163
11364
|
O2.success(`${adapter.displayName}: ${schemaResult.message}`);
|
|
10164
11365
|
}
|
|
10165
|
-
} catch (
|
|
10166
|
-
O2.warn(`${adapter.displayName}: could not set $schema on aft.jsonc: ${
|
|
11366
|
+
} catch (error2) {
|
|
11367
|
+
O2.warn(`${adapter.displayName}: could not set $schema on aft.jsonc: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
10167
11368
|
}
|
|
10168
11369
|
printNextSteps(adapter);
|
|
10169
11370
|
}
|
|
@@ -10198,7 +11399,7 @@ var init_setup = __esm(() => {
|
|
|
10198
11399
|
});
|
|
10199
11400
|
|
|
10200
11401
|
// src/lib/aft-bridge.ts
|
|
10201
|
-
import { spawn } from "node:child_process";
|
|
11402
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
10202
11403
|
function isResponseForRequest(parsed, expectedIds) {
|
|
10203
11404
|
if (!parsed || typeof parsed !== "object")
|
|
10204
11405
|
return false;
|
|
@@ -10210,7 +11411,7 @@ function isResponseForRequest(parsed, expectedIds) {
|
|
|
10210
11411
|
}
|
|
10211
11412
|
async function sendAftRequests(binaryPath, requests) {
|
|
10212
11413
|
return new Promise((resolve2, reject) => {
|
|
10213
|
-
const child =
|
|
11414
|
+
const child = spawn2(binaryPath, [], {
|
|
10214
11415
|
stdio: ["pipe", "pipe", "pipe"]
|
|
10215
11416
|
});
|
|
10216
11417
|
const responses = [];
|
|
@@ -10268,8 +11469,8 @@ async function sendAftRequests(binaryPath, requests) {
|
|
|
10268
11469
|
child.stderr.on("data", (chunk) => {
|
|
10269
11470
|
stderr += chunk;
|
|
10270
11471
|
});
|
|
10271
|
-
child.on("error", (
|
|
10272
|
-
finish(() => reject(
|
|
11472
|
+
child.on("error", (error2) => {
|
|
11473
|
+
finish(() => reject(error2));
|
|
10273
11474
|
});
|
|
10274
11475
|
child.on("close", (code) => {
|
|
10275
11476
|
if (settled)
|
|
@@ -10321,20 +11522,20 @@ __export(exports_lsp, {
|
|
|
10321
11522
|
printLspDoctorHelp: () => printLspDoctorHelp,
|
|
10322
11523
|
findProjectRootForFile: () => findProjectRootForFile
|
|
10323
11524
|
});
|
|
10324
|
-
import { existsSync as
|
|
10325
|
-
import { dirname as dirname3, join as
|
|
11525
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
|
|
11526
|
+
import { dirname as dirname3, join as join7, resolve as resolve2 } from "node:path";
|
|
10326
11527
|
function findProjectRootForFile(filePath, fallbackCwd = process.cwd()) {
|
|
10327
11528
|
const resolvedFile = resolve2(fallbackCwd, filePath);
|
|
10328
11529
|
let dir = dirname3(resolvedFile);
|
|
10329
11530
|
try {
|
|
10330
|
-
if (
|
|
11531
|
+
if (existsSync7(resolvedFile) && statSync3(resolvedFile).isDirectory()) {
|
|
10331
11532
|
dir = resolvedFile;
|
|
10332
11533
|
}
|
|
10333
11534
|
} catch {
|
|
10334
11535
|
dir = dirname3(resolvedFile);
|
|
10335
11536
|
}
|
|
10336
11537
|
while (true) {
|
|
10337
|
-
if (PROJECT_ROOT_MARKERS.some((marker) =>
|
|
11538
|
+
if (PROJECT_ROOT_MARKERS.some((marker) => existsSync7(join7(dir, marker)))) {
|
|
10338
11539
|
return dir;
|
|
10339
11540
|
}
|
|
10340
11541
|
const parent = dirname3(dir);
|
|
@@ -10364,8 +11565,8 @@ async function runLspDoctor(options) {
|
|
|
10364
11565
|
O2.error("No harness selected.");
|
|
10365
11566
|
return 1;
|
|
10366
11567
|
}
|
|
10367
|
-
const
|
|
10368
|
-
const binary =
|
|
11568
|
+
const findBinary2 = options.findBinary ?? findAftBinary;
|
|
11569
|
+
const binary = findBinary2(getSelfVersion());
|
|
10369
11570
|
if (!binary) {
|
|
10370
11571
|
O2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
|
|
10371
11572
|
return 1;
|
|
@@ -10472,11 +11673,11 @@ function buildConfigureParams(adapter, projectRoot) {
|
|
|
10472
11673
|
}
|
|
10473
11674
|
function readProjectConfig(kind, projectRoot) {
|
|
10474
11675
|
const dir = kind === "pi" ? ".pi" : ".opencode";
|
|
10475
|
-
const jsonc =
|
|
10476
|
-
const json =
|
|
10477
|
-
if (
|
|
11676
|
+
const jsonc = join7(projectRoot, dir, "aft.jsonc");
|
|
11677
|
+
const json = join7(projectRoot, dir, "aft.json");
|
|
11678
|
+
if (existsSync7(jsonc))
|
|
10478
11679
|
return readJsoncFile(jsonc).value ?? {};
|
|
10479
|
-
if (
|
|
11680
|
+
if (existsSync7(json))
|
|
10480
11681
|
return readJsoncFile(json).value ?? {};
|
|
10481
11682
|
return {};
|
|
10482
11683
|
}
|
|
@@ -10539,18 +11740,18 @@ function resolveCustomServers(servers) {
|
|
|
10539
11740
|
function inferLspPathsExtra(_lsp) {
|
|
10540
11741
|
const paths = new Set;
|
|
10541
11742
|
for (const entry of childDirs(getAftLspPackagesDir())) {
|
|
10542
|
-
paths.add(
|
|
11743
|
+
paths.add(join7(entry, "node_modules", ".bin"));
|
|
10543
11744
|
}
|
|
10544
11745
|
for (const entry of childDirs(getAftLspBinariesDir())) {
|
|
10545
|
-
paths.add(
|
|
11746
|
+
paths.add(join7(entry, "bin"));
|
|
10546
11747
|
}
|
|
10547
11748
|
return [...paths];
|
|
10548
11749
|
}
|
|
10549
11750
|
function childDirs(path) {
|
|
10550
|
-
if (!
|
|
11751
|
+
if (!existsSync7(path))
|
|
10551
11752
|
return [];
|
|
10552
11753
|
try {
|
|
10553
|
-
return readdirSync2(path).map((entry) =>
|
|
11754
|
+
return readdirSync2(path).map((entry) => join7(path, entry)).filter((entry) => {
|
|
10554
11755
|
try {
|
|
10555
11756
|
return statSync3(entry).isDirectory();
|
|
10556
11757
|
} catch {
|
|
@@ -10600,7 +11801,7 @@ var init_lsp = __esm(async () => {
|
|
|
10600
11801
|
init_aft_bridge();
|
|
10601
11802
|
init_harness_select();
|
|
10602
11803
|
init_jsonc();
|
|
10603
|
-
|
|
11804
|
+
init_paths2();
|
|
10604
11805
|
init_prompts();
|
|
10605
11806
|
init_self_version();
|
|
10606
11807
|
await init_binary_probe();
|
|
@@ -10630,8 +11831,8 @@ __export(exports_doctor_filters, {
|
|
|
10630
11831
|
renderFilterList: () => renderFilterList,
|
|
10631
11832
|
printDoctorFiltersHelp: () => printDoctorFiltersHelp
|
|
10632
11833
|
});
|
|
10633
|
-
import { existsSync as
|
|
10634
|
-
import { homedir as
|
|
11834
|
+
import { existsSync as existsSync8 } from "node:fs";
|
|
11835
|
+
import { homedir as homedir6 } from "node:os";
|
|
10635
11836
|
import { relative, resolve as resolve3 } from "node:path";
|
|
10636
11837
|
function printDoctorFiltersHelp() {
|
|
10637
11838
|
console.log("Usage: aft doctor filters [--show <name>] [trust|untrust]");
|
|
@@ -10661,8 +11862,8 @@ async function runDoctorFilters(options) {
|
|
|
10661
11862
|
O2.error("No harness selected.");
|
|
10662
11863
|
return 1;
|
|
10663
11864
|
}
|
|
10664
|
-
const
|
|
10665
|
-
const binary =
|
|
11865
|
+
const findBinary2 = options.findBinary ?? findAftBinary;
|
|
11866
|
+
const binary = findBinary2(getSelfVersion());
|
|
10666
11867
|
if (!binary) {
|
|
10667
11868
|
O2.error("Could not find the aft binary in the cache, platform package, PATH, or ~/.cargo/bin.");
|
|
10668
11869
|
return 1;
|
|
@@ -10673,7 +11874,7 @@ async function runDoctorFilters(options) {
|
|
|
10673
11874
|
O2.error(list.message ?? list.code ?? "list_filters failed");
|
|
10674
11875
|
return 1;
|
|
10675
11876
|
}
|
|
10676
|
-
list.project_dir_exists = list.project_dir ?
|
|
11877
|
+
list.project_dir_exists = list.project_dir ? existsSync8(list.project_dir) : false;
|
|
10677
11878
|
if (mode.kind === "list") {
|
|
10678
11879
|
console.log(renderFilterList(list, projectRoot));
|
|
10679
11880
|
return 0;
|
|
@@ -10849,7 +12050,7 @@ function truncate(value) {
|
|
|
10849
12050
|
return value.length <= 80 ? value : `${value.slice(0, 77)}…`;
|
|
10850
12051
|
}
|
|
10851
12052
|
function formatHome(path) {
|
|
10852
|
-
const home =
|
|
12053
|
+
const home = homedir6();
|
|
10853
12054
|
return path.startsWith(home) ? `~${path.slice(home.length)}` : path;
|
|
10854
12055
|
}
|
|
10855
12056
|
function formatProjectPath(path, projectRoot) {
|
|
@@ -10872,11 +12073,11 @@ var init_doctor_filters = __esm(async () => {
|
|
|
10872
12073
|
});
|
|
10873
12074
|
|
|
10874
12075
|
// src/lib/binary-cache.ts
|
|
10875
|
-
import { existsSync as
|
|
10876
|
-
import { join as
|
|
12076
|
+
import { existsSync as existsSync9, readdirSync as readdirSync3, statSync as statSync4 } from "node:fs";
|
|
12077
|
+
import { join as join8 } from "node:path";
|
|
10877
12078
|
function getBinaryCacheInfo(activeVersion) {
|
|
10878
12079
|
const path = getAftBinaryCacheDir();
|
|
10879
|
-
if (!
|
|
12080
|
+
if (!existsSync9(path)) {
|
|
10880
12081
|
return {
|
|
10881
12082
|
versions: [],
|
|
10882
12083
|
activeVersion: null,
|
|
@@ -10886,7 +12087,7 @@ function getBinaryCacheInfo(activeVersion) {
|
|
|
10886
12087
|
}
|
|
10887
12088
|
const versions = readdirSync3(path).filter((entry) => {
|
|
10888
12089
|
try {
|
|
10889
|
-
return statSync4(
|
|
12090
|
+
return statSync4(join8(path, entry)).isDirectory();
|
|
10890
12091
|
} catch {
|
|
10891
12092
|
return false;
|
|
10892
12093
|
}
|
|
@@ -10902,14 +12103,14 @@ function getBinaryCacheInfo(activeVersion) {
|
|
|
10902
12103
|
}
|
|
10903
12104
|
var init_binary_cache = __esm(() => {
|
|
10904
12105
|
init_fs_util();
|
|
10905
|
-
|
|
12106
|
+
init_paths2();
|
|
10906
12107
|
});
|
|
10907
12108
|
|
|
10908
12109
|
// src/lib/lsp-cache.ts
|
|
10909
|
-
import { existsSync as
|
|
10910
|
-
import { join as
|
|
12110
|
+
import { existsSync as existsSync10, readdirSync as readdirSync4, rmSync as rmSync2, statSync as statSync5 } from "node:fs";
|
|
12111
|
+
import { join as join9 } from "node:path";
|
|
10911
12112
|
function inspectDir(path) {
|
|
10912
|
-
if (!
|
|
12113
|
+
if (!existsSync10(path)) {
|
|
10913
12114
|
return { entries: [], totalSize: 0 };
|
|
10914
12115
|
}
|
|
10915
12116
|
const entries = [];
|
|
@@ -10921,7 +12122,7 @@ function inspectDir(path) {
|
|
|
10921
12122
|
return { entries: [], totalSize: 0 };
|
|
10922
12123
|
}
|
|
10923
12124
|
for (const name of names) {
|
|
10924
|
-
const full =
|
|
12125
|
+
const full = join9(path, name);
|
|
10925
12126
|
try {
|
|
10926
12127
|
if (!statSync5(full).isDirectory())
|
|
10927
12128
|
continue;
|
|
@@ -10975,12 +12176,12 @@ function clearLspCaches() {
|
|
|
10975
12176
|
}
|
|
10976
12177
|
var init_lsp_cache = __esm(() => {
|
|
10977
12178
|
init_fs_util();
|
|
10978
|
-
|
|
12179
|
+
init_paths2();
|
|
10979
12180
|
});
|
|
10980
12181
|
|
|
10981
12182
|
// src/lib/onnx.ts
|
|
10982
|
-
import { existsSync as
|
|
10983
|
-
import { basename, isAbsolute, join as
|
|
12183
|
+
import { existsSync as existsSync11, readdirSync as readdirSync5, readlinkSync, realpathSync as realpathSync2, statSync as statSync6 } from "node:fs";
|
|
12184
|
+
import { basename, isAbsolute, join as join10, resolve as resolve4, win32 } from "node:path";
|
|
10984
12185
|
function getOnnxLibraryName() {
|
|
10985
12186
|
if (process.platform === "darwin")
|
|
10986
12187
|
return "libonnxruntime.dylib";
|
|
@@ -10988,7 +12189,7 @@ function getOnnxLibraryName() {
|
|
|
10988
12189
|
return "onnxruntime.dll";
|
|
10989
12190
|
return "libonnxruntime.so";
|
|
10990
12191
|
}
|
|
10991
|
-
function
|
|
12192
|
+
function getManualInstallHint2() {
|
|
10992
12193
|
const p2 = process.platform;
|
|
10993
12194
|
const a = process.arch;
|
|
10994
12195
|
if (p2 === "darwin") {
|
|
@@ -11043,13 +12244,13 @@ function findSystemOnnxRuntime() {
|
|
|
11043
12244
|
searchPaths.push(...pathEntriesForPlatform());
|
|
11044
12245
|
const programFiles = process.env.ProgramFiles ?? "C:\\Program Files";
|
|
11045
12246
|
const programFilesX86 = process.env["ProgramFiles(x86)"] ?? "C:\\Program Files (x86)";
|
|
11046
|
-
searchPaths.push(
|
|
12247
|
+
searchPaths.push(join10(programFiles, "onnxruntime", "lib"), join10(programFiles, "Microsoft ONNX Runtime", "lib"), join10(programFiles, "Microsoft Machine Learning", "lib"), join10(programFilesX86, "onnxruntime", "lib"), ...(() => {
|
|
11047
12248
|
const nugetPaths = [];
|
|
11048
12249
|
const userProfile = process.env.USERPROFILE ?? "";
|
|
11049
12250
|
if (!userProfile)
|
|
11050
12251
|
return nugetPaths;
|
|
11051
|
-
const nugetPackageDir =
|
|
11052
|
-
if (!
|
|
12252
|
+
const nugetPackageDir = join10(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
|
|
12253
|
+
if (!existsSync11(nugetPackageDir))
|
|
11053
12254
|
return nugetPaths;
|
|
11054
12255
|
try {
|
|
11055
12256
|
for (const entry of readdirSync5(nugetPackageDir, { withFileTypes: true })) {
|
|
@@ -11057,7 +12258,7 @@ function findSystemOnnxRuntime() {
|
|
|
11057
12258
|
continue;
|
|
11058
12259
|
if (entry.name === "__globalPackagesFolder" || entry.name.startsWith("."))
|
|
11059
12260
|
continue;
|
|
11060
|
-
nugetPaths.push(
|
|
12261
|
+
nugetPaths.push(join10(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join10(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
|
|
11061
12262
|
}
|
|
11062
12263
|
} catch {}
|
|
11063
12264
|
return nugetPaths;
|
|
@@ -11087,12 +12288,12 @@ function findSystemOnnxRuntime() {
|
|
|
11087
12288
|
return unknownVersionPaths[0] ?? null;
|
|
11088
12289
|
}
|
|
11089
12290
|
function findCachedOnnxRuntime(storageDir) {
|
|
11090
|
-
const ortDir =
|
|
12291
|
+
const ortDir = join10(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
|
|
11091
12292
|
const libName = getOnnxLibraryName();
|
|
11092
|
-
if (
|
|
12293
|
+
if (existsSync11(join10(ortDir, libName)))
|
|
11093
12294
|
return ortDir;
|
|
11094
|
-
const libSubdir =
|
|
11095
|
-
if (
|
|
12295
|
+
const libSubdir = join10(ortDir, "lib");
|
|
12296
|
+
if (existsSync11(join10(libSubdir, libName)))
|
|
11096
12297
|
return libSubdir;
|
|
11097
12298
|
return null;
|
|
11098
12299
|
}
|
|
@@ -11113,7 +12314,7 @@ function parseOrtVersionFromDirectoryPath(value) {
|
|
|
11113
12314
|
return null;
|
|
11114
12315
|
}
|
|
11115
12316
|
function detectOrtVersion(libDir) {
|
|
11116
|
-
if (!
|
|
12317
|
+
if (!existsSync11(libDir))
|
|
11117
12318
|
return null;
|
|
11118
12319
|
const libName = getOnnxLibraryName();
|
|
11119
12320
|
try {
|
|
@@ -11128,10 +12329,10 @@ function detectOrtVersion(libDir) {
|
|
|
11128
12329
|
if (version)
|
|
11129
12330
|
return version;
|
|
11130
12331
|
}
|
|
11131
|
-
const base =
|
|
11132
|
-
if (
|
|
12332
|
+
const base = join10(libDir, libName);
|
|
12333
|
+
if (existsSync11(base)) {
|
|
11133
12334
|
try {
|
|
11134
|
-
const real =
|
|
12335
|
+
const real = realpathSync2(base);
|
|
11135
12336
|
const version = parseOrtVersionFromPath(real) ?? parseOrtVersionFromDirectoryPath(real);
|
|
11136
12337
|
if (version)
|
|
11137
12338
|
return version;
|
|
@@ -11160,14 +12361,14 @@ var ONNX_RUNTIME_VERSION = "1.24.4", INVALID_ORT_VERSION = "<invalid>", REQUIRED
|
|
|
11160
12361
|
var init_onnx = () => {};
|
|
11161
12362
|
|
|
11162
12363
|
// src/lib/sanitize.ts
|
|
11163
|
-
import { realpathSync as
|
|
11164
|
-
import { homedir as
|
|
12364
|
+
import { realpathSync as realpathSync3 } from "node:fs";
|
|
12365
|
+
import { homedir as homedir7, userInfo } from "node:os";
|
|
11165
12366
|
function escapeRegex(value) {
|
|
11166
12367
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
11167
12368
|
}
|
|
11168
12369
|
function safeRealpath(p2) {
|
|
11169
12370
|
try {
|
|
11170
|
-
return
|
|
12371
|
+
return realpathSync3(p2);
|
|
11171
12372
|
} catch {
|
|
11172
12373
|
return null;
|
|
11173
12374
|
}
|
|
@@ -11192,7 +12393,7 @@ function redactSecrets(content) {
|
|
|
11192
12393
|
}
|
|
11193
12394
|
function sanitizeContent(content) {
|
|
11194
12395
|
const username = userInfo().username;
|
|
11195
|
-
const home =
|
|
12396
|
+
const home = homedir7();
|
|
11196
12397
|
let sanitized = redactSecrets(content);
|
|
11197
12398
|
const cwd = process.cwd();
|
|
11198
12399
|
for (const candidate of new Set([cwd, safeRealpath(cwd)])) {
|
|
@@ -11239,11 +12440,11 @@ var init_sanitize = __esm(() => {
|
|
|
11239
12440
|
// src/lib/diagnostics.ts
|
|
11240
12441
|
import {
|
|
11241
12442
|
accessSync,
|
|
11242
|
-
closeSync,
|
|
12443
|
+
closeSync as closeSync2,
|
|
11243
12444
|
constants,
|
|
11244
|
-
existsSync as
|
|
11245
|
-
openSync,
|
|
11246
|
-
readSync,
|
|
12445
|
+
existsSync as existsSync12,
|
|
12446
|
+
openSync as openSync2,
|
|
12447
|
+
readSync as readSync2,
|
|
11247
12448
|
statSync as statSync7
|
|
11248
12449
|
} from "node:fs";
|
|
11249
12450
|
async function collectDiagnostics(adapters) {
|
|
@@ -11273,7 +12474,7 @@ async function diagnoseHarness(adapter) {
|
|
|
11273
12474
|
const logPath = adapter.getLogFile();
|
|
11274
12475
|
const pluginCache = adapter.getPluginCacheInfo();
|
|
11275
12476
|
const storageAccessible = (() => {
|
|
11276
|
-
if (!
|
|
12477
|
+
if (!existsSync12(storage))
|
|
11277
12478
|
return false;
|
|
11278
12479
|
try {
|
|
11279
12480
|
accessSync(storage, constants.R_OK | constants.W_OK);
|
|
@@ -11296,14 +12497,14 @@ async function diagnoseHarness(adapter) {
|
|
|
11296
12497
|
pluginRegistered: adapter.hasPluginEntry(),
|
|
11297
12498
|
configPaths,
|
|
11298
12499
|
aftConfig: {
|
|
11299
|
-
exists:
|
|
12500
|
+
exists: existsSync12(configPaths.aftConfig),
|
|
11300
12501
|
...aftConfigRead.error ? { parseError: aftConfigRead.error } : {},
|
|
11301
12502
|
flags: aftFlags
|
|
11302
12503
|
},
|
|
11303
12504
|
pluginCache,
|
|
11304
12505
|
storageDir: {
|
|
11305
12506
|
path: storage,
|
|
11306
|
-
exists:
|
|
12507
|
+
exists: existsSync12(storage),
|
|
11307
12508
|
accessible: storageAccessible,
|
|
11308
12509
|
sizesByKey: describeStorage
|
|
11309
12510
|
},
|
|
@@ -11316,13 +12517,13 @@ async function diagnoseHarness(adapter) {
|
|
|
11316
12517
|
cachedVersion,
|
|
11317
12518
|
cachedCompatible: cachedVersion ? isOrtVersionCompatible(cachedVersion) : null,
|
|
11318
12519
|
platform: `${process.platform}-${process.arch}`,
|
|
11319
|
-
installHint:
|
|
12520
|
+
installHint: getManualInstallHint2(),
|
|
11320
12521
|
requirement: `>=${REQUIRED_ORT_MAJOR}.${REQUIRED_ORT_MIN_MINOR}`
|
|
11321
12522
|
},
|
|
11322
12523
|
logFile: {
|
|
11323
12524
|
path: logPath,
|
|
11324
|
-
exists:
|
|
11325
|
-
sizeKb:
|
|
12525
|
+
exists: existsSync12(logPath),
|
|
12526
|
+
sizeKb: existsSync12(logPath) ? Math.round(statSync7(logPath).size / 1024) : 0
|
|
11326
12527
|
}
|
|
11327
12528
|
};
|
|
11328
12529
|
}
|
|
@@ -11516,7 +12717,7 @@ function formatDiagnosticIssuesSection(report) {
|
|
|
11516
12717
|
return lines;
|
|
11517
12718
|
}
|
|
11518
12719
|
function tailLogFile(path, lines) {
|
|
11519
|
-
if (!
|
|
12720
|
+
if (!existsSync12(path))
|
|
11520
12721
|
return "";
|
|
11521
12722
|
if (lines <= 0)
|
|
11522
12723
|
return "";
|
|
@@ -11524,7 +12725,7 @@ function tailLogFile(path, lines) {
|
|
|
11524
12725
|
let fd = null;
|
|
11525
12726
|
try {
|
|
11526
12727
|
const size = statSync7(path).size;
|
|
11527
|
-
fd =
|
|
12728
|
+
fd = openSync2(path, "r");
|
|
11528
12729
|
const chunks = [];
|
|
11529
12730
|
let position = size;
|
|
11530
12731
|
let newlineCount = 0;
|
|
@@ -11532,7 +12733,7 @@ function tailLogFile(path, lines) {
|
|
|
11532
12733
|
const readLength = Math.min(chunkSize, position);
|
|
11533
12734
|
position -= readLength;
|
|
11534
12735
|
const buffer = Buffer.allocUnsafe(readLength);
|
|
11535
|
-
const bytesRead =
|
|
12736
|
+
const bytesRead = readSync2(fd, buffer, 0, readLength, position);
|
|
11536
12737
|
const chunk = bytesRead === readLength ? buffer : buffer.subarray(0, bytesRead);
|
|
11537
12738
|
chunks.unshift(chunk);
|
|
11538
12739
|
for (let i = chunk.length - 1;i >= 0; i -= 1) {
|
|
@@ -11547,7 +12748,7 @@ function tailLogFile(path, lines) {
|
|
|
11547
12748
|
} finally {
|
|
11548
12749
|
if (fd !== null) {
|
|
11549
12750
|
try {
|
|
11550
|
-
|
|
12751
|
+
closeSync2(fd);
|
|
11551
12752
|
} catch {}
|
|
11552
12753
|
}
|
|
11553
12754
|
}
|
|
@@ -11643,7 +12844,7 @@ function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
|
11643
12844
|
const logBlockStart = headingEol + 1;
|
|
11644
12845
|
const logBlockEnd = nextSectionIdx === -1 ? body.length : nextSectionIdx;
|
|
11645
12846
|
const head = body.slice(0, logBlockStart);
|
|
11646
|
-
const
|
|
12847
|
+
const log2 = body.slice(logBlockStart, logBlockEnd);
|
|
11647
12848
|
const tail = body.slice(logBlockEnd);
|
|
11648
12849
|
const overheadBytes = Buffer.byteLength(head, "utf8") + Buffer.byteLength(tail, "utf8");
|
|
11649
12850
|
const truncationMarker = `[truncated for GitHub 64KB limit — older log lines dropped]
|
|
@@ -11653,7 +12854,7 @@ function capBodyToGithubLimit(body, maxBytes = MAX_GITHUB_BODY_BYTES) {
|
|
|
11653
12854
|
if (logBudget <= 0) {
|
|
11654
12855
|
return `${head}${truncationMarker}${tail}`;
|
|
11655
12856
|
}
|
|
11656
|
-
const lines =
|
|
12857
|
+
const lines = log2.split(`
|
|
11657
12858
|
`);
|
|
11658
12859
|
let keepLines = lines;
|
|
11659
12860
|
let kept = keepLines.join(`
|
|
@@ -11702,8 +12903,8 @@ var init_issue_body = __esm(() => {
|
|
|
11702
12903
|
});
|
|
11703
12904
|
|
|
11704
12905
|
// src/lib/onnx-fix.ts
|
|
11705
|
-
import { existsSync as
|
|
11706
|
-
import { join as
|
|
12906
|
+
import { existsSync as existsSync13, rmSync as rmSync3 } from "node:fs";
|
|
12907
|
+
import { join as join11 } from "node:path";
|
|
11707
12908
|
function findOnnxFixCandidates(report) {
|
|
11708
12909
|
const candidates = [];
|
|
11709
12910
|
for (const harness of report.harnesses) {
|
|
@@ -11711,7 +12912,7 @@ function findOnnxFixCandidates(report) {
|
|
|
11711
12912
|
continue;
|
|
11712
12913
|
if (!harness.storageDir.exists)
|
|
11713
12914
|
continue;
|
|
11714
|
-
const storageOnnxDir =
|
|
12915
|
+
const storageOnnxDir = join11(harness.storageDir.path, "onnxruntime");
|
|
11715
12916
|
const systemTooOld = harness.onnxRuntime.systemPath !== null && harness.onnxRuntime.systemCompatible === false;
|
|
11716
12917
|
const cachedTooOld = harness.onnxRuntime.cachedPath !== null && harness.onnxRuntime.cachedCompatible === false;
|
|
11717
12918
|
const hasCompatibleCached = harness.onnxRuntime.cachedCompatible === true;
|
|
@@ -11720,7 +12921,7 @@ function findOnnxFixCandidates(report) {
|
|
|
11720
12921
|
harness,
|
|
11721
12922
|
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.`,
|
|
11722
12923
|
storageOnnxDir,
|
|
11723
|
-
storageOnnxBytes:
|
|
12924
|
+
storageOnnxBytes: existsSync13(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
11724
12925
|
});
|
|
11725
12926
|
continue;
|
|
11726
12927
|
}
|
|
@@ -11729,7 +12930,7 @@ function findOnnxFixCandidates(report) {
|
|
|
11729
12930
|
harness,
|
|
11730
12931
|
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.`,
|
|
11731
12932
|
storageOnnxDir,
|
|
11732
|
-
storageOnnxBytes:
|
|
12933
|
+
storageOnnxBytes: existsSync13(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
|
|
11733
12934
|
});
|
|
11734
12935
|
}
|
|
11735
12936
|
}
|
|
@@ -11759,7 +12960,7 @@ async function runOnnxFix(adapters, report, options = {}) {
|
|
|
11759
12960
|
const result = { cleared: 0, bytesReclaimed: 0, errors: [] };
|
|
11760
12961
|
const rmFn = options.rmFn ?? rmSync3;
|
|
11761
12962
|
for (const c2 of candidates) {
|
|
11762
|
-
if (!
|
|
12963
|
+
if (!existsSync13(c2.storageOnnxDir)) {
|
|
11763
12964
|
O2.success(`${c2.harness.displayName}: no cached state to clear; restart your harness to trigger a fresh ONNX download`);
|
|
11764
12965
|
continue;
|
|
11765
12966
|
}
|
|
@@ -11785,10 +12986,10 @@ var init_onnx_fix = __esm(() => {
|
|
|
11785
12986
|
});
|
|
11786
12987
|
|
|
11787
12988
|
// src/lib/sessions.ts
|
|
11788
|
-
import { existsSync as
|
|
12989
|
+
import { existsSync as existsSync14, readdirSync as readdirSync6, readFileSync as readFileSync4, statSync as statSync8 } from "node:fs";
|
|
11789
12990
|
import { createRequire as createRequire3 } from "node:module";
|
|
11790
|
-
import { homedir as
|
|
11791
|
-
import { basename as basename2, join as
|
|
12991
|
+
import { homedir as homedir8 } from "node:os";
|
|
12992
|
+
import { basename as basename2, join as join12 } from "node:path";
|
|
11792
12993
|
function listRecentSessions(adapter) {
|
|
11793
12994
|
try {
|
|
11794
12995
|
if (adapter.kind === "opencode")
|
|
@@ -11817,8 +13018,8 @@ function mapOpenCodeSessionRows(rows) {
|
|
|
11817
13018
|
}).filter((session) => session !== null).sort((a, b) => b.lastActivity - a.lastActivity).slice(0, MAX_RECENT_SESSIONS);
|
|
11818
13019
|
}
|
|
11819
13020
|
function listRecentOpenCodeSessions() {
|
|
11820
|
-
const dbPath =
|
|
11821
|
-
if (!
|
|
13021
|
+
const dbPath = join12(getXdgDataHome(), "opencode", "opencode.db");
|
|
13022
|
+
if (!existsSync14(dbPath))
|
|
11822
13023
|
return [];
|
|
11823
13024
|
let db = null;
|
|
11824
13025
|
try {
|
|
@@ -11837,18 +13038,18 @@ function listRecentOpenCodeSessions() {
|
|
|
11837
13038
|
}
|
|
11838
13039
|
function getXdgDataHome() {
|
|
11839
13040
|
const xdgDataHome = process.env.XDG_DATA_HOME;
|
|
11840
|
-
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome :
|
|
13041
|
+
return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join12(homedir8(), ".local", "share");
|
|
11841
13042
|
}
|
|
11842
13043
|
function listRecentPiSessions() {
|
|
11843
|
-
return listPiSessionsFromDir(
|
|
13044
|
+
return listPiSessionsFromDir(join12(getHomeDir(), ".pi", "agent", "sessions"));
|
|
11844
13045
|
}
|
|
11845
13046
|
function getHomeDir() {
|
|
11846
13047
|
const envHome = process.platform === "win32" ? process.env.USERPROFILE : process.env.HOME;
|
|
11847
|
-
return envHome && envHome.length > 0 ? envHome :
|
|
13048
|
+
return envHome && envHome.length > 0 ? envHome : homedir8();
|
|
11848
13049
|
}
|
|
11849
13050
|
function listPiSessionsFromDir(sessionsDir) {
|
|
11850
13051
|
try {
|
|
11851
|
-
if (!
|
|
13052
|
+
if (!existsSync14(sessionsDir))
|
|
11852
13053
|
return [];
|
|
11853
13054
|
const files = collectJsonlFiles(sessionsDir).map((filePath) => {
|
|
11854
13055
|
try {
|
|
@@ -11886,7 +13087,7 @@ function collectJsonlFiles(root) {
|
|
|
11886
13087
|
continue;
|
|
11887
13088
|
}
|
|
11888
13089
|
for (const entry of entries) {
|
|
11889
|
-
const path =
|
|
13090
|
+
const path = join12(dir, entry.name);
|
|
11890
13091
|
if (entry.isDirectory()) {
|
|
11891
13092
|
stack.push(path);
|
|
11892
13093
|
} else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
@@ -11984,18 +13185,18 @@ __export(exports_doctor, {
|
|
|
11984
13185
|
DOCTOR_CLEAR_TARGET_OPTIONS: () => DOCTOR_CLEAR_TARGET_OPTIONS
|
|
11985
13186
|
});
|
|
11986
13187
|
import {
|
|
11987
|
-
chmodSync,
|
|
11988
|
-
existsSync as
|
|
11989
|
-
mkdirSync as
|
|
13188
|
+
chmodSync as chmodSync2,
|
|
13189
|
+
existsSync as existsSync15,
|
|
13190
|
+
mkdirSync as mkdirSync3,
|
|
11990
13191
|
mkdtempSync,
|
|
11991
13192
|
readFileSync as readFileSync5,
|
|
11992
|
-
realpathSync as
|
|
13193
|
+
realpathSync as realpathSync4,
|
|
11993
13194
|
rmSync as rmSync4,
|
|
11994
13195
|
statSync as statSync9,
|
|
11995
13196
|
writeFileSync as writeFileSync2
|
|
11996
13197
|
} from "node:fs";
|
|
11997
13198
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
11998
|
-
import { join as
|
|
13199
|
+
import { join as join13 } from "node:path";
|
|
11999
13200
|
async function runDoctor(options) {
|
|
12000
13201
|
if (options.issue) {
|
|
12001
13202
|
return runIssueFlow(options.argv);
|
|
@@ -12149,7 +13350,7 @@ function clearOldBinaries() {
|
|
|
12149
13350
|
errors: [],
|
|
12150
13351
|
keptVersion: keepTag
|
|
12151
13352
|
};
|
|
12152
|
-
if (!
|
|
13353
|
+
if (!existsSync15(info.path)) {
|
|
12153
13354
|
O2.info(`Binary cache: nothing to clear at ${info.path}`);
|
|
12154
13355
|
return result;
|
|
12155
13356
|
}
|
|
@@ -12159,7 +13360,7 @@ function clearOldBinaries() {
|
|
|
12159
13360
|
return result;
|
|
12160
13361
|
}
|
|
12161
13362
|
for (const version of stale) {
|
|
12162
|
-
const dir =
|
|
13363
|
+
const dir = join13(info.path, version);
|
|
12163
13364
|
let bytes = 0;
|
|
12164
13365
|
try {
|
|
12165
13366
|
bytes = statSync9(dir).isDirectory() ? dirSize(dir) : 0;
|
|
@@ -12211,9 +13412,9 @@ function applySchemaFixes(targets) {
|
|
|
12211
13412
|
changed += 1;
|
|
12212
13413
|
O2.success(`${target.adapter.displayName}: ${result.message}`);
|
|
12213
13414
|
}
|
|
12214
|
-
} catch (
|
|
13415
|
+
} catch (error2) {
|
|
12215
13416
|
errors += 1;
|
|
12216
|
-
O2.warn(`${target.adapter.displayName}: could not set $schema on ${target.aftConfig}: ${
|
|
13417
|
+
O2.warn(`${target.adapter.displayName}: could not set $schema on ${target.aftConfig}: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
|
12217
13418
|
}
|
|
12218
13419
|
}
|
|
12219
13420
|
return { changed, errors };
|
|
@@ -12343,8 +13544,8 @@ async function runFixFlow(argv) {
|
|
|
12343
13544
|
O2.info("AFT binary not found. Downloading…");
|
|
12344
13545
|
try {
|
|
12345
13546
|
const bridgePackageName = "@cortexkit/aft-bridge";
|
|
12346
|
-
const { ensureBinary } = await import(bridgePackageName);
|
|
12347
|
-
const path = await
|
|
13547
|
+
const { ensureBinary: ensureBinary2 } = await import(bridgePackageName);
|
|
13548
|
+
const path = await ensureBinary2(`v${report.cliVersion}`);
|
|
12348
13549
|
if (path) {
|
|
12349
13550
|
O2.success(`AFT binary installed at ${path}`);
|
|
12350
13551
|
binaryDownloaded = true;
|
|
@@ -12423,9 +13624,9 @@ function ensureStorageDirsForRegisteredPlugins(adapters) {
|
|
|
12423
13624
|
if (!adapter.isInstalled() || !adapter.hasPluginEntry())
|
|
12424
13625
|
continue;
|
|
12425
13626
|
const storageDir = adapter.getStorageDir();
|
|
12426
|
-
if (
|
|
13627
|
+
if (existsSync15(storageDir))
|
|
12427
13628
|
continue;
|
|
12428
|
-
|
|
13629
|
+
mkdirSync3(storageDir, { recursive: true });
|
|
12429
13630
|
summary.created += 1;
|
|
12430
13631
|
O2.success(`${adapter.displayName}: created AFT storage directory at ${storageDir}`);
|
|
12431
13632
|
} catch (err) {
|
|
@@ -12526,14 +13727,14 @@ function deriveIssueTitleFromBody(body) {
|
|
|
12526
13727
|
function writeIssueReviewFile(body) {
|
|
12527
13728
|
let reviewDir = null;
|
|
12528
13729
|
try {
|
|
12529
|
-
reviewDir = mkdtempSync(
|
|
13730
|
+
reviewDir = mkdtempSync(join13(tmpdir2(), "aft-issue-"));
|
|
12530
13731
|
if (process.platform !== "win32") {
|
|
12531
|
-
|
|
13732
|
+
chmodSync2(reviewDir, 448);
|
|
12532
13733
|
}
|
|
12533
|
-
const outPath =
|
|
13734
|
+
const outPath = join13(reviewDir, "issue.md");
|
|
12534
13735
|
writeFileSync2(outPath, `${body}
|
|
12535
13736
|
`, { encoding: "utf8", mode: 384, flag: "wx" });
|
|
12536
|
-
return { path: outPath, realPath:
|
|
13737
|
+
return { path: outPath, realPath: realpathSync4(outPath) };
|
|
12537
13738
|
} catch (err) {
|
|
12538
13739
|
if (reviewDir) {
|
|
12539
13740
|
try {
|
|
@@ -12546,7 +13747,7 @@ function writeIssueReviewFile(body) {
|
|
|
12546
13747
|
}
|
|
12547
13748
|
function readReviewedIssueFile(reviewFile) {
|
|
12548
13749
|
try {
|
|
12549
|
-
const realPath =
|
|
13750
|
+
const realPath = realpathSync4(reviewFile.path);
|
|
12550
13751
|
if (realPath !== reviewFile.realPath) {
|
|
12551
13752
|
O2.error(`Review file path changed before filing; refusing to read ${reviewFile.path}.`);
|
|
12552
13753
|
return null;
|