@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
- // src/lib/paths.ts
50
- import { homedir, tmpdir } from "node:os";
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 join(process.env.AFT_CACHE_DIR, "bin");
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 || join(homedir(), "AppData", "Local");
59
- return join(base2, "aft", "bin");
1225
+ const base2 = localAppData || join2(homedir2(), "AppData", "Local");
1226
+ return join2(base2, "aft", "bin");
60
1227
  }
61
- const base = process.env.XDG_CACHE_HOME || join(homedir(), ".cache");
62
- return join(base, "aft", "bin");
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 join(process.env.AFT_CACHE_DIR, "lsp-packages");
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 || join(homedir(), "AppData", "Local");
74
- return join(base2, "aft", "lsp-packages");
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 || join(homedir(), ".cache");
77
- return join(base, "aft", "lsp-packages");
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 join(process.env.AFT_CACHE_DIR, "lsp-binaries");
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 || join(homedir(), "AppData", "Local");
86
- return join(base2, "aft", "lsp-binaries");
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 || join(homedir(), ".cache");
89
- return join(base, "aft", "lsp-binaries");
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 || homedir();
94
- return process.env.HOME || homedir();
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 || join(homeDir(), "AppData", "Local");
1267
+ return process.env.LOCALAPPDATA || process.env.APPDATA || join2(homeDir(), "AppData", "Local");
101
1268
  }
102
- return join(homeDir(), ".local", "share");
1269
+ return join2(homeDir(), ".local", "share");
103
1270
  }
104
1271
  function getCortexKitStorageRoot() {
105
- return join(dataHome(), "cortexkit", "aft");
1272
+ return join2(dataHome(), "cortexkit", "aft");
106
1273
  }
107
1274
  function getTmpLogPath(filename) {
108
- return join(tmpdir(), filename);
1275
+ return join2(tmpdir(), filename);
109
1276
  }
110
- var init_paths = () => {};
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 homedir2 } from "node:os";
117
- import { join as join2 } from "node:path";
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 (!existsSync(candidate))
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 (error) {
1368
+ } catch (error2) {
202
1369
  candidates.push({
203
1370
  path: candidate,
204
1371
  status: "error",
205
1372
  version: null,
206
- error: error instanceof Error ? error.message : String(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 (!existsSync(candidate))
1388
+ if (!existsSync2(candidate))
222
1389
  continue;
223
1390
  return candidate;
224
1391
  } catch {}
225
1392
  }
226
1393
  return null;
227
1394
  }
228
- function platformKey(platform = process.platform, arch = process.arch) {
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, join2(getAftBinaryCacheDir(), tag, getAftBinaryName()));
1407
+ pushCandidate(candidates, join3(getAftBinaryCacheDir(), tag, getAftBinaryName()));
241
1408
  }
242
- const key = platformKey();
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
- if (resolved) {
257
- pushCandidate(candidates, resolved.split(/\r?\n/)[0]);
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, join2(homedir2(), ".cargo", "bin", getAftBinaryName()));
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
- init_paths();
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 existsSync2, readdirSync, statSync } from "node:fs";
275
- import { join as join3 } from "node:path";
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 (!existsSync2(path)) {
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(join3(path, entry));
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(error) {
4844
- this.errors.push(error);
6014
+ ErrorHandler2.prototype.recordError = function(error2) {
6015
+ this.errors.push(error2);
4845
6016
  };
4846
- ErrorHandler2.prototype.tolerate = function(error) {
6017
+ ErrorHandler2.prototype.tolerate = function(error2) {
4847
6018
  if (this.tolerant) {
4848
- this.recordError(error);
6019
+ this.recordError(error2);
4849
6020
  } else {
4850
- throw error;
6021
+ throw error2;
4851
6022
  }
4852
6023
  };
4853
6024
  ErrorHandler2.prototype.constructError = function(msg, column) {
4854
- var error = new Error(msg);
6025
+ var error2 = new Error(msg);
4855
6026
  try {
4856
- throw error;
6027
+ throw error2;
4857
6028
  } catch (base) {
4858
6029
  if (Object.create && Object.defineProperty) {
4859
- error = Object.create(base);
4860
- Object.defineProperty(error, "column", { value: column });
6030
+ error2 = Object.create(base);
6031
+ Object.defineProperty(error2, "column", { value: column });
4861
6032
  }
4862
6033
  }
4863
- return error;
6034
+ return error2;
4864
6035
  };
4865
6036
  ErrorHandler2.prototype.createError = function(index, line, col, description) {
4866
6037
  var msg = "Line " + line + ": " + description;
4867
- var error = this.constructError(msg, col);
4868
- error.index = index;
4869
- error.lineNumber = line;
4870
- error.description = description;
4871
- return error;
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 error = this.createError(index, line, col, description);
6048
+ var error2 = this.createError(index, line, col, description);
4878
6049
  if (this.tolerant) {
4879
- this.recordError(error);
6050
+ this.recordError(error2);
4880
6051
  } else {
4881
- throw error;
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 error = new SyntaxError(`Unexpected token '${current.value.slice(0, 1)}', "${current_code}" is not valid JSON`);
7552
- Object.assign(error, current.loc.start);
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 error;
8725
+ throw error2;
7555
8726
  };
7556
8727
  var unexpected_end = () => {
7557
- const error = new SyntaxError("Unexpected end of JSON input");
7558
- Object.assign(error, last ? last.loc.end : {
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 error;
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 join4 = (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;
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 join4(comment, inside, gap);
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 = join4(after_comma, process_comments(value, BEFORE(i), deeper_gap), deeper_gap);
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 += join4(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
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 = join4(after_comma, process_comments(value, BEFORE(key), deeper_gap), deeper_gap);
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 += join4(after_comma, process_comments(value, PREFIX_AFTER, deeper_gap), deeper_gap);
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 existsSync3, mkdirSync, readFileSync, writeFileSync } from "node:fs";
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 (existsSync3(jsoncPath)) {
9239
+ if (existsSync4(jsoncPath)) {
8069
9240
  return { path: jsoncPath, format: "jsonc" };
8070
9241
  }
8071
- if (existsSync3(jsonPath)) {
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 (!existsSync3(path)) {
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 (error) {
9255
+ } catch (error2) {
8085
9256
  return {
8086
9257
  value: null,
8087
- error: error instanceof Error ? error.message : String(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
- mkdirSync(dirname(path), { recursive: true });
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 = existsSync3(path);
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(error ? `failed to parse ${path}: ${error}` : `failed to parse ${path}`);
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 existsSync4, readFileSync as readFileSync2, rmSync, statSync as statSync2 } from "node:fs";
8152
- import { homedir as homedir3 } from "node:os";
8153
- import { dirname as dirname2, join as join4, parse, resolve } from "node:path";
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 || join4(homedir3(), ".config");
8160
- return join4(xdg, "opencode");
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 join4(xdg, "opencode");
9336
+ return join5(xdg, "opencode");
8166
9337
  if (process.platform === "win32") {
8167
- const localAppData = process.env.LOCALAPPDATA ?? join4(homedir3(), "AppData", "Local");
8168
- return join4(localAppData, "opencode");
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 join4(homedir3(), ".cache", "opencode");
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 (!existsSync4(fsPath))
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 = join4(searchDir, "package.json");
8195
- if (existsSync4(candidate)) {
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
- try {
8227
- execSync2("opencode --version", { stdio: "ignore" });
9423
+ if (existsSync5(getOpenCodeConfigDir()))
8228
9424
  return true;
8229
- } catch {
8230
- return false;
8231
- }
9425
+ if (openCodeDesktopAppExists())
9426
+ return true;
9427
+ return hasOpenCodeCli();
8232
9428
  }
8233
9429
  getHostVersion() {
8234
9430
  try {
8235
- return execSync2("opencode --version", { encoding: "utf-8", stdio: "pipe" }).trim();
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 (error || !value) {
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}: ${error ?? "unknown error"}`,
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 = join4(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY);
9504
+ const path = join5(getOpenCodeCacheDir(), "packages", PLUGIN_ENTRY);
8305
9505
  let cached;
8306
9506
  try {
8307
- const installedPkgPath = join4(path, "node_modules", "@cortexkit", "aft-opencode", "package.json");
8308
- if (existsSync4(installedPkgPath)) {
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: existsSync4(path)
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 (error) {
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: error instanceof Error ? error.message : String(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(join4(storage, "index")),
8369
- semantic: dirSize(join4(storage, "semantic")),
8370
- backups: dirSize(join4(storage, "backups")),
8371
- url_cache: dirSize(join4(storage, "url_cache")),
8372
- onnxruntime: dirSize(join4(storage, "onnxruntime"))
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
- init_paths();
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 existsSync5, readFileSync as readFileSync3 } from "node:fs";
8388
- import { homedir as homedir4 } from "node:os";
8389
- import { join as join5 } from "node:path";
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 : homedir4();
8393
- return join5(home, ".pi", "agent");
9592
+ const home = envHome && envHome.length > 0 ? envHome : homedir5();
9593
+ return join6(home, ".pi", "agent");
8394
9594
  }
8395
9595
  function readPiExtensionIndex() {
8396
- const settingsPath = join5(getPiAgentDir(), "settings.json");
8397
- if (existsSync5(settingsPath)) {
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
- join5(getPiAgentDir(), "extensions.json"),
8411
- join5(getPiAgentDir(), "extensions.jsonc"),
8412
- join5(getPiAgentDir(), "config.json"),
8413
- join5(getPiAgentDir(), "config.jsonc")
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 (!existsSync5(path))
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 = join5(getPiAgentDir(), entry);
9649
+ resolved = join6(getPiAgentDir(), entry);
8450
9650
  }
8451
9651
  if (!resolved)
8452
9652
  return false;
8453
9653
  try {
8454
- if (!existsSync5(resolved))
9654
+ if (!existsSync6(resolved))
8455
9655
  return false;
8456
- const pkgPath = join5(resolved, "package.json");
8457
- if (!existsSync5(pkgPath))
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 ?? join5(configDir, "extensions.json"),
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 (error) {
9741
+ } catch (error2) {
8541
9742
  return {
8542
9743
  ok: false,
8543
9744
  action: "error",
8544
- message: `Failed to run \`pi install ${PLUGIN_ENTRY2}\`: ${error instanceof Error ? error.message : String(error)}`,
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
- join5(getPiAgentDir(), "node_modules", "@cortexkit", "aft-pi", "package.json"),
8552
- join5(getPiAgentDir(), "extensions", "node_modules", "@cortexkit", "aft-pi", "package.json")
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 (!existsSync5(candidate))
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: join5(getPiAgentDir(), "extensions"),
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(join5(storage, "index")),
8592
- semantic: dirSize(join5(storage, "semantic")),
8593
- backups: dirSize(join5(storage, "backups")),
8594
- url_cache: dirSize(join5(storage, "url_cache")),
8595
- onnxruntime: dirSize(join5(storage, "onnxruntime"))
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
- init_paths();
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 init_dist = __esm(() => {
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 init_dist2 = __esm(() => {
8798
- init_dist();
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
- init_dist2();
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 init_dist3 = __esm(() => {
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 init_dist4 = __esm(() => {
9904
- init_dist3();
9905
- init_dist3();
11104
+ var init_dist5 = __esm(() => {
11105
+ init_dist4();
11106
+ init_dist4();
9906
11107
  init_main();
9907
- init_dist2();
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
- init_dist4();
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 (error) {
10166
- O2.warn(`${adapter.displayName}: could not set $schema on aft.jsonc: ${error instanceof Error ? error.message : String(error)}`);
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 = spawn(binaryPath, [], {
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", (error) => {
10272
- finish(() => reject(error));
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 existsSync6, readdirSync as readdirSync2, statSync as statSync3 } from "node:fs";
10325
- import { dirname as dirname3, join as join6, resolve as resolve2 } from "node:path";
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 (existsSync6(resolvedFile) && statSync3(resolvedFile).isDirectory()) {
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) => existsSync6(join6(dir, 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 findBinary = options.findBinary ?? findAftBinary;
10368
- const binary = findBinary(getSelfVersion());
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 = join6(projectRoot, dir, "aft.jsonc");
10476
- const json = join6(projectRoot, dir, "aft.json");
10477
- if (existsSync6(jsonc))
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 (existsSync6(json))
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(join6(entry, "node_modules", ".bin"));
11743
+ paths.add(join7(entry, "node_modules", ".bin"));
10543
11744
  }
10544
11745
  for (const entry of childDirs(getAftLspBinariesDir())) {
10545
- paths.add(join6(entry, "bin"));
11746
+ paths.add(join7(entry, "bin"));
10546
11747
  }
10547
11748
  return [...paths];
10548
11749
  }
10549
11750
  function childDirs(path) {
10550
- if (!existsSync6(path))
11751
+ if (!existsSync7(path))
10551
11752
  return [];
10552
11753
  try {
10553
- return readdirSync2(path).map((entry) => join6(path, entry)).filter((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
- init_paths();
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 existsSync7 } from "node:fs";
10634
- import { homedir as homedir5 } from "node:os";
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 findBinary = options.findBinary ?? findAftBinary;
10665
- const binary = findBinary(getSelfVersion());
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 ? existsSync7(list.project_dir) : false;
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 = homedir5();
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 existsSync8, readdirSync as readdirSync3, statSync as statSync4 } from "node:fs";
10876
- import { join as join7 } from "node:path";
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 (!existsSync8(path)) {
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(join7(path, entry)).isDirectory();
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
- init_paths();
12106
+ init_paths2();
10906
12107
  });
10907
12108
 
10908
12109
  // src/lib/lsp-cache.ts
10909
- import { existsSync as existsSync9, readdirSync as readdirSync4, rmSync as rmSync2, statSync as statSync5 } from "node:fs";
10910
- import { join as join8 } from "node:path";
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 (!existsSync9(path)) {
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 = join8(path, name);
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
- init_paths();
12179
+ init_paths2();
10979
12180
  });
10980
12181
 
10981
12182
  // src/lib/onnx.ts
10982
- import { existsSync as existsSync10, readdirSync as readdirSync5, readlinkSync, realpathSync, statSync as statSync6 } from "node:fs";
10983
- import { basename, isAbsolute, join as join9, resolve as resolve4, win32 } from "node:path";
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 getManualInstallHint() {
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(join9(programFiles, "onnxruntime", "lib"), join9(programFiles, "Microsoft ONNX Runtime", "lib"), join9(programFiles, "Microsoft Machine Learning", "lib"), join9(programFilesX86, "onnxruntime", "lib"), ...(() => {
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 = join9(userProfile, ".nuget", "packages", "microsoft.ml.onnxruntime");
11052
- if (!existsSync10(nugetPackageDir))
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(join9(nugetPackageDir, entry.name, "runtimes", "win-x64", "native"), join9(nugetPackageDir, entry.name, "runtimes", "win-arm64", "native"));
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 = join9(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
12291
+ const ortDir = join10(storageDir, "onnxruntime", ONNX_RUNTIME_VERSION);
11091
12292
  const libName = getOnnxLibraryName();
11092
- if (existsSync10(join9(ortDir, libName)))
12293
+ if (existsSync11(join10(ortDir, libName)))
11093
12294
  return ortDir;
11094
- const libSubdir = join9(ortDir, "lib");
11095
- if (existsSync10(join9(libSubdir, libName)))
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 (!existsSync10(libDir))
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 = join9(libDir, libName);
11132
- if (existsSync10(base)) {
12332
+ const base = join10(libDir, libName);
12333
+ if (existsSync11(base)) {
11133
12334
  try {
11134
- const real = realpathSync(base);
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 realpathSync2 } from "node:fs";
11164
- import { homedir as homedir6, userInfo } from "node:os";
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 realpathSync2(p2);
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 = homedir6();
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 existsSync11,
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 (!existsSync11(storage))
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: existsSync11(configPaths.aftConfig),
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: existsSync11(storage),
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: getManualInstallHint(),
12520
+ installHint: getManualInstallHint2(),
11320
12521
  requirement: `>=${REQUIRED_ORT_MAJOR}.${REQUIRED_ORT_MIN_MINOR}`
11321
12522
  },
11322
12523
  logFile: {
11323
12524
  path: logPath,
11324
- exists: existsSync11(logPath),
11325
- sizeKb: existsSync11(logPath) ? Math.round(statSync7(logPath).size / 1024) : 0
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 (!existsSync11(path))
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 = openSync(path, "r");
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 = readSync(fd, buffer, 0, readLength, position);
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
- closeSync(fd);
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 log = body.slice(logBlockStart, logBlockEnd);
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 = log.split(`
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 existsSync12, rmSync as rmSync3 } from "node:fs";
11706
- import { join as join10 } from "node:path";
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 = join10(harness.storageDir.path, "onnxruntime");
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: existsSync12(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
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: existsSync12(storageOnnxDir) ? dirSize(storageOnnxDir) : 0
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 (!existsSync12(c2.storageOnnxDir)) {
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 existsSync13, readdirSync as readdirSync6, readFileSync as readFileSync4, statSync as statSync8 } from "node:fs";
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 homedir7 } from "node:os";
11791
- import { basename as basename2, join as join11 } from "node:path";
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 = join11(getXdgDataHome(), "opencode", "opencode.db");
11821
- if (!existsSync13(dbPath))
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 : join11(homedir7(), ".local", "share");
13041
+ return xdgDataHome && xdgDataHome.length > 0 ? xdgDataHome : join12(homedir8(), ".local", "share");
11841
13042
  }
11842
13043
  function listRecentPiSessions() {
11843
- return listPiSessionsFromDir(join11(getHomeDir(), ".pi", "agent", "sessions"));
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 : homedir7();
13048
+ return envHome && envHome.length > 0 ? envHome : homedir8();
11848
13049
  }
11849
13050
  function listPiSessionsFromDir(sessionsDir) {
11850
13051
  try {
11851
- if (!existsSync13(sessionsDir))
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 = join11(dir, entry.name);
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 existsSync14,
11989
- mkdirSync as mkdirSync2,
13188
+ chmodSync as chmodSync2,
13189
+ existsSync as existsSync15,
13190
+ mkdirSync as mkdirSync3,
11990
13191
  mkdtempSync,
11991
13192
  readFileSync as readFileSync5,
11992
- realpathSync as realpathSync3,
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 join12 } from "node:path";
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 (!existsSync14(info.path)) {
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 = join12(info.path, version);
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 (error) {
13415
+ } catch (error2) {
12215
13416
  errors += 1;
12216
- O2.warn(`${target.adapter.displayName}: could not set $schema on ${target.aftConfig}: ${error instanceof Error ? error.message : String(error)}`);
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 ensureBinary(`v${report.cliVersion}`);
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 (existsSync14(storageDir))
13627
+ if (existsSync15(storageDir))
12427
13628
  continue;
12428
- mkdirSync2(storageDir, { recursive: true });
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(join12(tmpdir2(), "aft-issue-"));
13730
+ reviewDir = mkdtempSync(join13(tmpdir2(), "aft-issue-"));
12530
13731
  if (process.platform !== "win32") {
12531
- chmodSync(reviewDir, 448);
13732
+ chmodSync2(reviewDir, 448);
12532
13733
  }
12533
- const outPath = join12(reviewDir, "issue.md");
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: realpathSync3(outPath) };
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 = realpathSync3(reviewFile.path);
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;